@prosopo/provider 2.3.1 → 2.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/dist/api/admin/apiAdminRoutesProvider.d.ts +9 -0
  2. package/dist/api/admin/apiAdminRoutesProvider.d.ts.map +1 -0
  3. package/dist/api/admin/apiAdminRoutesProvider.js +17 -0
  4. package/dist/api/admin/apiAdminRoutesProvider.js.map +1 -0
  5. package/dist/api/admin/apiRegisterSiteKeyEndpoint.d.ts +13 -0
  6. package/dist/api/admin/apiRegisterSiteKeyEndpoint.d.ts.map +1 -0
  7. package/dist/api/admin/apiRegisterSiteKeyEndpoint.js +20 -0
  8. package/dist/api/admin/apiRegisterSiteKeyEndpoint.js.map +1 -0
  9. package/dist/api/admin/createApiAdminRoutesProvider.d.ts +4 -0
  10. package/dist/api/admin/createApiAdminRoutesProvider.d.ts.map +1 -0
  11. package/dist/api/admin/createApiAdminRoutesProvider.js +7 -0
  12. package/dist/api/admin/createApiAdminRoutesProvider.js.map +1 -0
  13. package/dist/api/authMiddleware.d.ts.map +1 -1
  14. package/dist/api/authMiddleware.js +4 -1
  15. package/dist/api/authMiddleware.js.map +1 -1
  16. package/dist/api/blacklistRequestInspector.d.ts +19 -0
  17. package/dist/api/blacklistRequestInspector.d.ts.map +1 -0
  18. package/dist/api/blacklistRequestInspector.js +61 -0
  19. package/dist/api/blacklistRequestInspector.js.map +1 -0
  20. package/dist/api/block.d.ts +1 -2
  21. package/dist/api/block.d.ts.map +1 -1
  22. package/dist/api/block.js +13 -38
  23. package/dist/api/block.js.map +1 -1
  24. package/dist/api/captcha.d.ts.map +1 -1
  25. package/dist/api/captcha.js +85 -88
  26. package/dist/api/captcha.js.map +1 -1
  27. package/dist/api/domainMiddleware.d.ts.map +1 -1
  28. package/dist/api/domainMiddleware.js +7 -6
  29. package/dist/api/domainMiddleware.js.map +1 -1
  30. package/dist/api/headerCheckMiddleware.d.ts.map +1 -1
  31. package/dist/api/headerCheckMiddleware.js +5 -1
  32. package/dist/api/headerCheckMiddleware.js.map +1 -1
  33. package/dist/api/public.d.ts.map +1 -1
  34. package/dist/api/public.js +1 -2
  35. package/dist/api/public.js.map +1 -1
  36. package/dist/api/validateAddress.d.ts +4 -0
  37. package/dist/api/validateAddress.d.ts.map +1 -0
  38. package/dist/api/validateAddress.js +16 -0
  39. package/dist/api/validateAddress.js.map +1 -0
  40. package/dist/api/verify.d.ts.map +1 -1
  41. package/dist/api/verify.js +6 -14
  42. package/dist/api/verify.js.map +1 -1
  43. package/dist/index.d.ts +1 -2
  44. package/dist/index.d.ts.map +1 -1
  45. package/dist/index.js +1 -2
  46. package/dist/index.js.map +1 -1
  47. package/dist/tasks/captchaManager.d.ts +25 -0
  48. package/dist/tasks/captchaManager.d.ts.map +1 -0
  49. package/dist/tasks/captchaManager.js +81 -0
  50. package/dist/tasks/captchaManager.js.map +1 -0
  51. package/dist/tasks/client/clientTasks.d.ts +2 -7
  52. package/dist/tasks/client/clientTasks.d.ts.map +1 -1
  53. package/dist/tasks/client/clientTasks.js +5 -63
  54. package/dist/tasks/client/clientTasks.js.map +1 -1
  55. package/dist/tasks/frictionless/frictionlessTasks.d.ts +13 -9
  56. package/dist/tasks/frictionless/frictionlessTasks.d.ts.map +1 -1
  57. package/dist/tasks/frictionless/frictionlessTasks.js +54 -23
  58. package/dist/tasks/frictionless/frictionlessTasks.js.map +1 -1
  59. package/dist/tasks/frictionless/frictionlessTasksUtils.d.ts +5 -0
  60. package/dist/tasks/frictionless/frictionlessTasksUtils.d.ts.map +1 -0
  61. package/dist/tasks/frictionless/frictionlessTasksUtils.js +6 -0
  62. package/dist/tasks/frictionless/frictionlessTasksUtils.js.map +1 -0
  63. package/dist/tasks/imgCaptcha/imgCaptchaTasks.d.ts +7 -8
  64. package/dist/tasks/imgCaptcha/imgCaptchaTasks.d.ts.map +1 -1
  65. package/dist/tasks/imgCaptcha/imgCaptchaTasks.js +32 -12
  66. package/dist/tasks/imgCaptcha/imgCaptchaTasks.js.map +1 -1
  67. package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.d.ts +1 -3
  68. package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.d.ts.map +1 -1
  69. package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.js +0 -29
  70. package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.js.map +1 -1
  71. package/dist/tasks/powCaptcha/powTasks.d.ts +8 -5
  72. package/dist/tasks/powCaptcha/powTasks.d.ts.map +1 -1
  73. package/dist/tasks/powCaptcha/powTasks.js +22 -15
  74. package/dist/tasks/powCaptcha/powTasks.js.map +1 -1
  75. package/dist/tasks/tasks.d.ts.map +1 -1
  76. package/dist/tasks/tasks.js +3 -3
  77. package/dist/tasks/tasks.js.map +1 -1
  78. package/dist/tests/integration/imgCaptcha.integration.test.js +59 -7
  79. package/dist/tests/integration/imgCaptcha.integration.test.js.map +1 -1
  80. package/dist/tests/integration/powCaptcha.integration.test.js +57 -13
  81. package/dist/tests/integration/powCaptcha.integration.test.js.map +1 -1
  82. package/dist/tests/integration/registerSitekey.d.ts +2 -1
  83. package/dist/tests/integration/registerSitekey.d.ts.map +1 -1
  84. package/dist/tests/integration/registerSitekey.js +2 -2
  85. package/dist/tests/integration/registerSitekey.js.map +1 -1
  86. package/dist/tests/unit/api/authMiddleware.unit.test.js +7 -1
  87. package/dist/tests/unit/api/authMiddleware.unit.test.js.map +1 -1
  88. package/dist/tests/unit/tasks/captchaManager.unit.test.d.ts +2 -0
  89. package/dist/tests/unit/tasks/captchaManager.unit.test.d.ts.map +1 -0
  90. package/dist/tests/unit/tasks/captchaManager.unit.test.js +229 -0
  91. package/dist/tests/unit/tasks/captchaManager.unit.test.js.map +1 -0
  92. package/dist/tests/unit/tasks/frictionless/frictionlessTasks.unit.test.js +39 -64
  93. package/dist/tests/unit/tasks/frictionless/frictionlessTasks.unit.test.js.map +1 -1
  94. package/dist/tests/unit/tasks/frictionless/frictionlessTasksUtils.unit.test.d.ts +2 -0
  95. package/dist/tests/unit/tasks/frictionless/frictionlessTasksUtils.unit.test.d.ts.map +1 -0
  96. package/dist/tests/unit/tasks/frictionless/frictionlessTasksUtils.unit.test.js +37 -0
  97. package/dist/tests/unit/tasks/frictionless/frictionlessTasksUtils.unit.test.js.map +1 -0
  98. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.unit.test.js +4 -4
  99. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.unit.test.js.map +1 -1
  100. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.unit.test.js +1 -101
  101. package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.unit.test.js.map +1 -1
  102. package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.js +5 -10
  103. package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.js.map +1 -1
  104. package/package.json +14 -11
  105. package/dist/api/admin.d.ts +0 -4
  106. package/dist/api/admin.d.ts.map +0 -1
  107. package/dist/api/admin.js +0 -87
  108. package/dist/api/admin.js.map +0 -1
  109. package/dist/api/errorHandler.d.ts +0 -5
  110. package/dist/api/errorHandler.d.ts.map +0 -1
  111. package/dist/api/errorHandler.js +0 -10
  112. package/dist/api/errorHandler.js.map +0 -1
  113. package/dist/rules/ip.d.ts +0 -4
  114. package/dist/rules/ip.d.ts.map +0 -1
  115. package/dist/rules/ip.js +0 -19
  116. package/dist/rules/ip.js.map +0 -1
  117. package/dist/rules/user.d.ts +0 -4
  118. package/dist/rules/user.d.ts.map +0 -1
  119. package/dist/rules/user.js +0 -10
  120. package/dist/rules/user.js.map +0 -1
  121. package/dist/tests/unit/api/errorHandler.unit.test.d.ts +0 -2
  122. package/dist/tests/unit/api/errorHandler.unit.test.d.ts.map +0 -1
  123. package/dist/tests/unit/api/errorHandler.unit.test.js +0 -105
  124. package/dist/tests/unit/api/errorHandler.unit.test.js.map +0 -1
@@ -0,0 +1,9 @@
1
+ import type { ApiRoute, ApiRoutesProvider } from "@prosopo/api-route";
2
+ import type { Tasks } from "../../tasks/index.js";
3
+ declare class ApiAdminRoutesProvider implements ApiRoutesProvider {
4
+ private readonly tasks;
5
+ constructor(tasks: Tasks);
6
+ getRoutes(): ApiRoute[];
7
+ }
8
+ export { ApiAdminRoutesProvider };
9
+ //# sourceMappingURL=apiAdminRoutesProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apiAdminRoutesProvider.d.ts","sourceRoot":"","sources":["../../../src/api/admin/apiAdminRoutesProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAetE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAGlD,cAAM,sBAAuB,YAAW,iBAAiB;IACrC,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,KAAK;IAEzC,SAAS,IAAI,QAAQ,EAAE;CAQ9B;AAED,OAAO,EAAE,sBAAsB,EAAE,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { AdminApiPaths } from "@prosopo/types";
2
+ import { ApiRegisterSiteKeyEndpoint } from "./apiRegisterSiteKeyEndpoint.js";
3
+ class ApiAdminRoutesProvider {
4
+ constructor(tasks) {
5
+ this.tasks = tasks;
6
+ }
7
+ getRoutes() {
8
+ return [
9
+ {
10
+ path: AdminApiPaths.SiteKeyRegister,
11
+ endpoint: new ApiRegisterSiteKeyEndpoint(this.tasks.clientTaskManager),
12
+ },
13
+ ];
14
+ }
15
+ }
16
+ export { ApiAdminRoutesProvider };
17
+ //# sourceMappingURL=apiAdminRoutesProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apiAdminRoutesProvider.js","sourceRoot":"","sources":["../../../src/api/admin/apiAdminRoutesProvider.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AAE7E,MAAM,sBAAsB;IAC3B,YAAoC,KAAY;QAAZ,UAAK,GAAL,KAAK,CAAO;IAAG,CAAC;IAE7C,SAAS;QACf,OAAO;YACN;gBACC,IAAI,EAAE,aAAa,CAAC,eAAe;gBACnC,QAAQ,EAAE,IAAI,0BAA0B,CAAC,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC;aACtE;SACD,CAAC;IACH,CAAC;CACD;AAED,OAAO,EAAE,sBAAsB,EAAE,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { type ApiEndpoint, type ApiEndpointResponse } from "@prosopo/api-route";
2
+ import { RegisterSitekeyBody } from "@prosopo/types";
3
+ import type { z } from "zod";
4
+ import type { ClientTaskManager } from "../../tasks/client/clientTasks.js";
5
+ type RegisterSitekeyBodyType = typeof RegisterSitekeyBody;
6
+ declare class ApiRegisterSiteKeyEndpoint implements ApiEndpoint<RegisterSitekeyBodyType> {
7
+ private readonly clientTaskManager;
8
+ constructor(clientTaskManager: ClientTaskManager);
9
+ processRequest(args: z.infer<RegisterSitekeyBodyType>): Promise<ApiEndpointResponse>;
10
+ getRequestArgsSchema(): RegisterSitekeyBodyType;
11
+ }
12
+ export { ApiRegisterSiteKeyEndpoint };
13
+ //# sourceMappingURL=apiRegisterSiteKeyEndpoint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apiRegisterSiteKeyEndpoint.d.ts","sourceRoot":"","sources":["../../../src/api/admin/apiRegisterSiteKeyEndpoint.ts"],"names":[],"mappings":"AAcA,OAAO,EACN,KAAK,WAAW,EAChB,KAAK,mBAAmB,EAExB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAwB,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC3E,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAE3E,KAAK,uBAAuB,GAAG,OAAO,mBAAmB,CAAC;AAE1D,cAAM,0BACL,YAAW,WAAW,CAAC,uBAAuB,CAAC;IAE5B,OAAO,CAAC,QAAQ,CAAC,iBAAiB;gBAAjB,iBAAiB,EAAE,iBAAiB;IAElE,cAAc,CACnB,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,uBAAuB,CAAC,GACpC,OAAO,CAAC,mBAAmB,CAAC;IAYxB,oBAAoB,IAAI,uBAAuB;CAGtD;AAED,OAAO,EAAE,0BAA0B,EAAE,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { ApiEndpointResponseStatus, } from "@prosopo/api-route";
2
+ import { ClientSettingsSchema, RegisterSitekeyBody } from "@prosopo/types";
3
+ class ApiRegisterSiteKeyEndpoint {
4
+ constructor(clientTaskManager) {
5
+ this.clientTaskManager = clientTaskManager;
6
+ }
7
+ async processRequest(args) {
8
+ const { siteKey, tier, settings } = args;
9
+ const temp = settings || ClientSettingsSchema.parse({});
10
+ await this.clientTaskManager.registerSiteKey(siteKey, tier, temp);
11
+ return {
12
+ status: ApiEndpointResponseStatus.SUCCESS,
13
+ };
14
+ }
15
+ getRequestArgsSchema() {
16
+ return RegisterSitekeyBody;
17
+ }
18
+ }
19
+ export { ApiRegisterSiteKeyEndpoint };
20
+ //# sourceMappingURL=apiRegisterSiteKeyEndpoint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apiRegisterSiteKeyEndpoint.js","sourceRoot":"","sources":["../../../src/api/admin/apiRegisterSiteKeyEndpoint.ts"],"names":[],"mappings":"AAcA,OAAO,EAGN,yBAAyB,GACzB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAM3E,MAAM,0BAA0B;IAG/B,YAAoC,iBAAoC;QAApC,sBAAiB,GAAjB,iBAAiB,CAAmB;IAAG,CAAC;IAE5E,KAAK,CAAC,cAAc,CACnB,IAAsC;QAEtC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;QAEzC,MAAM,IAAI,GAAG,QAAQ,IAAI,oBAAoB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAExD,MAAM,IAAI,CAAC,iBAAiB,CAAC,eAAe,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAElE,OAAO;YACN,MAAM,EAAE,yBAAyB,CAAC,OAAO;SACzC,CAAC;IACH,CAAC;IAEM,oBAAoB;QAC1B,OAAO,mBAAmB,CAAC;IAC5B,CAAC;CACD;AAED,OAAO,EAAE,0BAA0B,EAAE,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { ApiRoutesProvider } from "@prosopo/api-route";
2
+ import type { ProviderEnvironment } from "@prosopo/types-env";
3
+ export declare const createApiAdminRoutesProvider: (providerEnvironment: ProviderEnvironment) => ApiRoutesProvider;
4
+ //# sourceMappingURL=createApiAdminRoutesProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createApiAdminRoutesProvider.d.ts","sourceRoot":"","sources":["../../../src/api/admin/createApiAdminRoutesProvider.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAI9D,eAAO,MAAM,4BAA4B,wBACnB,mBAAmB,KACtC,iBAIF,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { Tasks } from "../../tasks/index.js";
2
+ import { ApiAdminRoutesProvider } from "./apiAdminRoutesProvider.js";
3
+ export const createApiAdminRoutesProvider = (providerEnvironment) => {
4
+ const tasks = new Tasks(providerEnvironment);
5
+ return new ApiAdminRoutesProvider(tasks);
6
+ };
7
+ //# sourceMappingURL=createApiAdminRoutesProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createApiAdminRoutesProvider.js","sourceRoot":"","sources":["../../../src/api/admin/createApiAdminRoutesProvider.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAC7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAErE,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAC3C,mBAAwC,EACpB,EAAE;IACtB,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;IAE7C,OAAO,IAAI,sBAAsB,CAAC,KAAK,CAAC,CAAC;AAC1C,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"authMiddleware.d.ts","sourceRoot":"","sources":["../../src/api/authMiddleware.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAI3D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAE/D,eAAO,MAAM,cAAc,QAAS,mBAAmB,WACnC,OAAO,OAAO,QAAQ,QAAQ,YAAY,kBAiC7D,CAAC;AAyCF,eAAO,MAAM,eAAe,cAChB,MAAM,aACN,MAAM,QACX,WAAW,SAajB,CAAC"}
1
+ {"version":3,"file":"authMiddleware.d.ts","sourceRoot":"","sources":["../../src/api/authMiddleware.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAI3D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAE/D,eAAO,MAAM,cAAc,QAAS,mBAAmB,WACnC,OAAO,OAAO,QAAQ,QAAQ,YAAY,kBAoC7D,CAAC;AAyCF,eAAO,MAAM,eAAe,cAChB,MAAM,aACN,MAAM,QACX,WAAW,SAajB,CAAC"}
@@ -4,7 +4,10 @@ import { ApiPrefix } from "@prosopo/types";
4
4
  export const authMiddleware = (env) => {
5
5
  return async (req, res, next) => {
6
6
  try {
7
- if (req.url.indexOf(ApiPrefix) === -1) {
7
+ if (req.originalUrl.indexOf(ApiPrefix) === -1) {
8
+ env.logger.info({
9
+ message: "Non-api route, skipping auth middleware",
10
+ });
8
11
  next();
9
12
  return;
10
13
  }
@@ -1 +1 @@
1
- {"version":3,"file":"authMiddleware.js","sourceRoot":"","sources":["../../src/api/authMiddleware.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"authMiddleware.js","sourceRoot":"","sources":["../../src/api/authMiddleware.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { Logger } from "@prosopo/common";
2
+ import type { BlacklistInspector } from "@prosopo/user-access-policy";
3
+ import type { NextFunction, Request, Response } from "express";
4
+ declare class BlacklistRequestInspector {
5
+ private readonly blacklistInspector;
6
+ private readonly environmentReadinessWaiter;
7
+ private readonly logger;
8
+ constructor(blacklistInspector: BlacklistInspector, environmentReadinessWaiter: () => Promise<void>, logger: Logger);
9
+ abortRequestForBlockedUsers(request: Request, res: Response, next: NextFunction): Promise<void>;
10
+ shouldAbortRequest(requestedRoute: string, rawIp: string, requestHeaders: Record<string, unknown>, requestBody: Record<string, unknown>): Promise<boolean>;
11
+ protected isApiUnrelatedRoute(url: string): boolean;
12
+ protected extractIdsFromRequest(requestHeaders: Record<string, unknown>, requestBody: Record<string, unknown>): {
13
+ userId: string;
14
+ clientId: string;
15
+ };
16
+ protected getObjectValue(object: Record<string, unknown>, key: string): unknown;
17
+ }
18
+ export { BlacklistRequestInspector };
19
+ //# sourceMappingURL=blacklistRequestInspector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blacklistRequestInspector.d.ts","sourceRoot":"","sources":["../../src/api/blacklistRequestInspector.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAE9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAG/D,cAAM,yBAAyB;IAE7B,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,0BAA0B;IAC3C,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAFN,kBAAkB,EAAE,kBAAkB,EACtC,0BAA0B,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EAC/C,MAAM,EAAE,MAAM;IAGnB,2BAA2B,CACvC,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GAChB,OAAO,CAAC,IAAI,CAAC;IAkBH,kBAAkB,CAC9B,cAAc,EAAE,MAAM,EACtB,KAAK,EAAE,MAAM,EACb,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACvC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAClC,OAAO,CAAC,OAAO,CAAC;IAuCnB,SAAS,CAAC,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAInD,SAAS,CAAC,qBAAqB,CAC9B,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACvC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAClC;QACF,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;KACjB;IAgBD,SAAS,CAAC,cAAc,CACvB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,GAAG,EAAE,MAAM,GACT,OAAO;CAGV;AAED,OAAO,EAAE,yBAAyB,EAAE,CAAC"}
@@ -0,0 +1,61 @@
1
+ import { ApiPrefix } from "@prosopo/types";
2
+ import { getIPAddress } from "../util.js";
3
+ class BlacklistRequestInspector {
4
+ constructor(blacklistInspector, environmentReadinessWaiter, logger) {
5
+ this.blacklistInspector = blacklistInspector;
6
+ this.environmentReadinessWaiter = environmentReadinessWaiter;
7
+ this.logger = logger;
8
+ }
9
+ async abortRequestForBlockedUsers(request, res, next) {
10
+ const rawIp = request.ip || "";
11
+ const shouldAbortRequest = await this.shouldAbortRequest(request.url, rawIp, request.headers, request.body);
12
+ if (shouldAbortRequest) {
13
+ res.status(401).json({ error: "Unauthorized" });
14
+ return;
15
+ }
16
+ next();
17
+ }
18
+ async shouldAbortRequest(requestedRoute, rawIp, requestHeaders, requestBody) {
19
+ if (this.isApiUnrelatedRoute(requestedRoute)) {
20
+ return false;
21
+ }
22
+ if (!rawIp) {
23
+ this.logger.info("Request without IP", {
24
+ requestedRoute: requestedRoute,
25
+ requestHeaders: requestHeaders,
26
+ requestBody: requestBody,
27
+ });
28
+ return true;
29
+ }
30
+ await this.environmentReadinessWaiter();
31
+ try {
32
+ const userIpAddress = getIPAddress(rawIp);
33
+ const { userId, clientId } = this.extractIdsFromRequest(requestHeaders, requestBody);
34
+ return await this.blacklistInspector.isUserBlacklisted(clientId, userIpAddress, userId);
35
+ }
36
+ catch (err) {
37
+ this.logger.error("Block Middleware Error:", err);
38
+ return true;
39
+ }
40
+ }
41
+ isApiUnrelatedRoute(url) {
42
+ return !url.includes(ApiPrefix);
43
+ }
44
+ extractIdsFromRequest(requestHeaders, requestBody) {
45
+ const userId = this.getObjectValue(requestHeaders, "Prosopo-User") ||
46
+ this.getObjectValue(requestBody, "user") ||
47
+ "";
48
+ const clientId = this.getObjectValue(requestHeaders, "Prosopo-Site-Key") ||
49
+ this.getObjectValue(requestBody, "dapp") ||
50
+ "";
51
+ return {
52
+ userId: "string" === typeof userId ? userId : "",
53
+ clientId: "string" === typeof clientId ? clientId : "",
54
+ };
55
+ }
56
+ getObjectValue(object, key) {
57
+ return object[key];
58
+ }
59
+ }
60
+ export { BlacklistRequestInspector };
61
+ //# sourceMappingURL=blacklistRequestInspector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blacklistRequestInspector.js","sourceRoot":"","sources":["../../src/api/blacklistRequestInspector.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAG3C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,yBAAyB;IAC9B,YACkB,kBAAsC,EACtC,0BAA+C,EAC/C,MAAc;QAFd,uBAAkB,GAAlB,kBAAkB,CAAoB;QACtC,+BAA0B,GAA1B,0BAA0B,CAAqB;QAC/C,WAAM,GAAN,MAAM,CAAQ;IAC7B,CAAC;IAEG,KAAK,CAAC,2BAA2B,CACvC,OAAgB,EAChB,GAAa,EACb,IAAkB;QAElB,MAAM,KAAK,GAAG,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC;QAE/B,MAAM,kBAAkB,GAAG,MAAM,IAAI,CAAC,kBAAkB,CACvD,OAAO,CAAC,GAAG,EACX,KAAK,EACL,OAAO,CAAC,OAAO,EACf,OAAO,CAAC,IAAI,CACZ,CAAC;QAEF,IAAI,kBAAkB,EAAE,CAAC;YACxB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;YAChD,OAAO;QACR,CAAC;QAED,IAAI,EAAE,CAAC;IACR,CAAC;IAEM,KAAK,CAAC,kBAAkB,CAC9B,cAAsB,EACtB,KAAa,EACb,cAAuC,EACvC,WAAoC;QAGpC,IAAI,IAAI,CAAC,mBAAmB,CAAC,cAAc,CAAC,EAAE,CAAC;YAC9C,OAAO,KAAK,CAAC;QACd,CAAC;QAGD,IAAI,CAAC,KAAK,EAAE,CAAC;YACZ,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,oBAAoB,EAAE;gBACtC,cAAc,EAAE,cAAc;gBAC9B,cAAc,EAAE,cAAc;gBAC9B,WAAW,EAAE,WAAW;aACxB,CAAC,CAAC;YAEH,OAAO,IAAI,CAAC;QACb,CAAC;QAED,MAAM,IAAI,CAAC,0BAA0B,EAAE,CAAC;QAExC,IAAI,CAAC;YACJ,MAAM,aAAa,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAE1C,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,qBAAqB,CACtD,cAAc,EACd,WAAW,CACX,CAAC;YAEF,OAAO,MAAM,IAAI,CAAC,kBAAkB,CAAC,iBAAiB,CACrD,QAAQ,EACR,aAAa,EACb,MAAM,CACN,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,yBAAyB,EAAE,GAAG,CAAC,CAAC;YAElD,OAAO,IAAI,CAAC;QACb,CAAC;IACF,CAAC;IAES,mBAAmB,CAAC,GAAW;QACxC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IACjC,CAAC;IAES,qBAAqB,CAC9B,cAAuC,EACvC,WAAoC;QAKpC,MAAM,MAAM,GACX,IAAI,CAAC,cAAc,CAAC,cAAc,EAAE,cAAc,CAAC;YACnD,IAAI,CAAC,cAAc,CAAC,WAAW,EAAE,MAAM,CAAC;YACxC,EAAE,CAAC;QACJ,MAAM,QAAQ,GACb,IAAI,CAAC,cAAc,CAAC,cAAc,EAAE,kBAAkB,CAAC;YACvD,IAAI,CAAC,cAAc,CAAC,WAAW,EAAE,MAAM,CAAC;YACxC,EAAE,CAAC;QAEJ,OAAO;YACN,MAAM,EAAE,QAAQ,KAAK,OAAO,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;YAChD,QAAQ,EAAE,QAAQ,KAAK,OAAO,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE;SACtD,CAAC;IACH,CAAC;IAES,cAAc,CACvB,MAA+B,EAC/B,GAAW;QAEX,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;IACpB,CAAC;CACD;AAED,OAAO,EAAE,yBAAyB,EAAE,CAAC"}
@@ -1,4 +1,3 @@
1
1
  import type { ProviderEnvironment } from "@prosopo/types-env";
2
- import type { NextFunction, Request, Response } from "express";
3
- export declare const blockMiddleware: (env: ProviderEnvironment) => (req: Request, res: Response, next: NextFunction) => Promise<Response<any, Record<string, any>> | undefined>;
2
+ export declare const blockMiddleware: (providerEnvironment: ProviderEnvironment) => (request: import("express").Request, res: import("express").Response, next: import("express").NextFunction) => Promise<void>;
4
3
  //# sourceMappingURL=block.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"block.d.ts","sourceRoot":"","sources":["../../src/api/block.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAO/D,eAAO,MAAM,eAAe,QAAS,mBAAmB,WACpC,OAAO,OAAO,QAAQ,QAAQ,YAAY,4DAgD7D,CAAC"}
1
+ {"version":3,"file":"block.d.ts","sourceRoot":"","sources":["../../src/api/block.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAI9D,eAAO,MAAM,eAAe,wBAAyB,mBAAmB,iIAyBvE,CAAC"}
package/dist/api/block.js CHANGED
@@ -1,40 +1,15 @@
1
- import { getLoggerDefault } from "@prosopo/common";
2
- import { ApiPrefix } from "@prosopo/types";
3
- import { checkIpRules } from "../rules/ip.js";
4
- import { checkUserRules } from "../rules/user.js";
5
- import { getIPAddress } from "../util.js";
6
- const logger = getLoggerDefault();
7
- export const blockMiddleware = (env) => {
8
- return async (req, res, next) => {
9
- try {
10
- if (req.url.indexOf(ApiPrefix) === -1) {
11
- next();
12
- return;
13
- }
14
- if (!req.ip) {
15
- logger.info("No IP", req.ip);
16
- return res.status(401).json({ error: "Unauthorized" });
17
- }
18
- await env.isReady();
19
- const ipAddress = getIPAddress(req.ip || "");
20
- const userAccount = req.headers["Prosopo-User"] || req.body.user;
21
- const dappAccount = req.headers["Prosopo-Site-Key"] || req.body.dapp;
22
- const rule = await checkIpRules(env.getDb(), ipAddress, dappAccount);
23
- if (rule?.hardBlock) {
24
- return res.status(401).json({ error: "Unauthorized" });
25
- }
26
- const userRule = await checkUserRules(env.getDb(), userAccount, dappAccount);
27
- if (userRule?.hardBlock) {
28
- return res.status(401).json({ error: "Unauthorized" });
29
- }
30
- next();
31
- return;
32
- }
33
- catch (err) {
34
- logger.error("Block Middleware Error:", err);
35
- res.status(401).json({ error: "Unauthorized" });
36
- return;
37
- }
38
- };
1
+ import { getLogger } from "@prosopo/common";
2
+ import { createBlacklistInspector } from "@prosopo/user-access-policy";
3
+ import { BlacklistRequestInspector } from "./blacklistRequestInspector.js";
4
+ export const blockMiddleware = (providerEnvironment) => {
5
+ const logLevel = providerEnvironment.config.logLevel;
6
+ const logger = getLogger(logLevel, "blockMiddleware");
7
+ const userAccessRulesStorage = providerEnvironment
8
+ .getDb()
9
+ .getUserAccessRulesStorage();
10
+ const environmentReadinessWaiter = providerEnvironment.isReady.bind(providerEnvironment);
11
+ const blacklistInspector = createBlacklistInspector(userAccessRulesStorage, logger);
12
+ const blacklistRequestInspector = new BlacklistRequestInspector(blacklistInspector, environmentReadinessWaiter, logger);
13
+ return blacklistRequestInspector.abortRequestForBlockedUsers.bind(blacklistRequestInspector);
39
14
  };
40
15
  //# sourceMappingURL=block.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"block.js","sourceRoot":"","sources":["../../src/api/block.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAG3C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;AAElC,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,GAAwB,EAAE,EAAE;IAC3D,OAAO,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;QAChE,IAAI,CAAC;YAEJ,IAAI,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;gBACvC,IAAI,EAAE,CAAC;gBACP,OAAO;YACR,CAAC;YAGD,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACb,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;gBAC7B,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;YACxD,CAAC;YAED,MAAM,GAAG,CAAC,OAAO,EAAE,CAAC;YAEpB,MAAM,SAAS,GAAG,YAAY,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;YAC7C,MAAM,WAAW,GAAG,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;YACjE,MAAM,WAAW,GAAG,GAAG,CAAC,OAAO,CAAC,kBAAkB,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;YAGrE,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;YAGrE,IAAI,IAAI,EAAE,SAAS,EAAE,CAAC;gBACrB,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;YACxD,CAAC;YAGD,MAAM,QAAQ,GAAG,MAAM,cAAc,CACpC,GAAG,CAAC,KAAK,EAAE,EACX,WAAW,EACX,WAAW,CACX,CAAC;YAGF,IAAI,QAAQ,EAAE,SAAS,EAAE,CAAC;gBACzB,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;YACxD,CAAC;YAED,IAAI,EAAE,CAAC;YACP,OAAO;QACR,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,MAAM,CAAC,KAAK,CAAC,yBAAyB,EAAE,GAAG,CAAC,CAAC;YAC7C,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;YAChD,OAAO;QACR,CAAC;IACF,CAAC,CAAC;AACH,CAAC,CAAC"}
1
+ {"version":3,"file":"block.js","sourceRoot":"","sources":["../../src/api/block.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,SAAS,EAAoB,MAAM,iBAAiB,CAAC;AAE9D,OAAO,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AACvE,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAE3E,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,mBAAwC,EAAE,EAAE;IAC3E,MAAM,QAAQ,GAAG,mBAAmB,CAAC,MAAM,CAAC,QAAQ,CAAC;IACrD,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC;IAEtD,MAAM,sBAAsB,GAAG,mBAAmB;SAChD,KAAK,EAAE;SACP,yBAAyB,EAAE,CAAC;IAE9B,MAAM,0BAA0B,GAC/B,mBAAmB,CAAC,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IAEvD,MAAM,kBAAkB,GAAG,wBAAwB,CAClD,sBAAsB,EACtB,MAAM,CACN,CAAC;IAEF,MAAM,yBAAyB,GAAG,IAAI,yBAAyB,CAC9D,kBAAkB,EAClB,0BAA0B,EAC1B,MAAM,CACN,CAAC;IAEF,OAAO,yBAAyB,CAAC,2BAA2B,CAAC,IAAI,CAChE,yBAAyB,CACzB,CAAC;AACH,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"captcha.d.ts","sourceRoot":"","sources":["../../src/api/captcha.ts"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAE9D,OAAgB,EAAE,KAAK,MAAM,EAAE,MAAM,SAAS,CAAC;AAgB/C,wBAAgB,aAAa,CAAC,GAAG,EAAE,mBAAmB,GAAG,MAAM,CAge9D"}
1
+ {"version":3,"file":"captcha.d.ts","sourceRoot":"","sources":["../../src/api/captcha.ts"],"names":[],"mappings":"AAqCA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAG9D,OAAgB,EAAE,KAAK,MAAM,EAAE,MAAM,SAAS,CAAC;AAgB/C,wBAAgB,aAAa,CAAC,GAAG,EAAE,mBAAmB,GAAG,MAAM,CAwgB9D"}
@@ -1,19 +1,21 @@
1
- import { validateAddress } from "@polkadot/util-crypto/address";
1
+ import { handleErrors } from "@prosopo/api-express-router";
2
2
  import { ProsopoApiError } from "@prosopo/common";
3
3
  import { parseCaptchaAssets } from "@prosopo/datasets";
4
- import { ApiParams, ApiPaths, CaptchaRequestBody, CaptchaSolutionBody, GetFrictionlessCaptchaChallengeRequestBody, GetPowCaptchaChallengeRequestBody, SubmitPowCaptchaSolutionBody, } from "@prosopo/types";
4
+ import { ApiParams, ApiPaths, CaptchaRequestBody, CaptchaSolutionBody, CaptchaType, GetFrictionlessCaptchaChallengeRequestBody, GetPowCaptchaChallengeRequestBody, SubmitPowCaptchaSolutionBody, } from "@prosopo/types";
5
+ import { createImageCaptchaConfigResolver } from "@prosopo/user-access-policy";
5
6
  import { flatten } from "@prosopo/util";
6
7
  import express from "express";
7
8
  import { getBotScore } from "../tasks/detection/getBotScore.js";
8
- import { getCaptchaConfig } from "../tasks/imgCaptcha/imgCaptchaTasksUtils.js";
9
+ import { FrictionlessManager } from "../tasks/frictionless/frictionlessTasks.js";
9
10
  import { Tasks } from "../tasks/tasks.js";
10
11
  import { getIPAddress } from "../util.js";
11
- import { handleErrors } from "./errorHandler.js";
12
+ import { validateAddr, validiateSiteKey } from "./validateAddress.js";
12
13
  const DEFAULT_FRICTIONLESS_THRESHOLD = 0.5;
13
- const TEN_MINUTES = 60 * 10 * 1000;
14
14
  export function prosopoRouter(env) {
15
15
  const router = express.Router();
16
16
  const tasks = new Tasks(env);
17
+ const userAccessRulesStorage = env.getDb().getUserAccessRulesStorage();
18
+ const imageCaptchaConfigResolver = createImageCaptchaConfigResolver(userAccessRulesStorage, env.logger);
17
19
  router.post(ApiPaths.GetImageCaptchaChallenge, async (req, res, next) => {
18
20
  let parsed;
19
21
  if (!req.ip) {
@@ -30,25 +32,28 @@ export function prosopoRouter(env) {
30
32
  context: { code: 400, error: err },
31
33
  }));
32
34
  }
33
- const { datasetId, user, dapp } = parsed;
35
+ const { datasetId, user, dapp, sessionId } = parsed;
36
+ validiateSiteKey(dapp);
37
+ validateAddr(user);
34
38
  try {
35
- validateAddress(dapp, false, 42);
36
- }
37
- catch (err) {
38
- return next(new ProsopoApiError("API.INVALID_SITE_KEY", {
39
- context: { code: 400, error: err, siteKey: dapp },
40
- }));
41
- }
42
- try {
43
- validateAddress(user, false, 42);
44
39
  const clientRecord = await tasks.db.getClientRecord(dapp);
45
40
  if (!clientRecord) {
46
41
  return next(new ProsopoApiError("API.SITE_KEY_NOT_REGISTERED", {
47
42
  context: { code: 400, siteKey: dapp },
48
43
  }));
49
44
  }
50
- const captchaConfig = await getCaptchaConfig(tasks.db, env.config, ipAddress, user, dapp);
51
- const taskData = await tasks.imgCaptchaManager.getRandomCaptchasAndRequestHash(datasetId, user, ipAddress, flatten(req.headers), captchaConfig);
45
+ const captchaConfig = await imageCaptchaConfigResolver.resolveConfig(env.config.captchas, ipAddress, user, dapp);
46
+ const { valid, reason, frictionlessTokenId } = await tasks.imgCaptchaManager.isValidRequest(clientRecord, CaptchaType.image, sessionId);
47
+ if (!valid) {
48
+ return next(new ProsopoApiError(reason || "API.BAD_REQUEST", {
49
+ context: {
50
+ code: 400,
51
+ siteKey: dapp,
52
+ user,
53
+ },
54
+ }));
55
+ }
56
+ const taskData = await tasks.imgCaptchaManager.getRandomCaptchasAndRequestHash(datasetId, user, ipAddress, flatten(req.headers), captchaConfig, frictionlessTokenId);
52
57
  const captchaResponse = {
53
58
  [ApiParams.status]: "ok",
54
59
  [ApiParams.captchas]: taskData.captchas.map((captcha) => ({
@@ -72,6 +77,7 @@ export function prosopoRouter(env) {
72
77
  error: err,
73
78
  code: 500,
74
79
  params: req.params,
80
+ context: err,
75
81
  },
76
82
  }));
77
83
  }
@@ -87,16 +93,9 @@ export function prosopoRouter(env) {
87
93
  }));
88
94
  }
89
95
  const { user, dapp } = parsed;
96
+ validiateSiteKey(dapp);
97
+ validateAddr(user);
90
98
  try {
91
- validateAddress(dapp, false, 42);
92
- }
93
- catch (err) {
94
- return next(new ProsopoApiError("API.INVALID_SITE_KEY", {
95
- context: { code: 400, error: err, siteKey: dapp },
96
- }));
97
- }
98
- try {
99
- validateAddress(user, false, 42);
100
99
  const clientRecord = await tasks.db.getClientRecord(parsed.dapp);
101
100
  if (!clientRecord) {
102
101
  return next(new ProsopoApiError("API.SITE_KEY_NOT_REGISTERED", {
@@ -113,7 +112,7 @@ export function prosopoRouter(env) {
113
112
  catch (err) {
114
113
  tasks.logger.error({ err, body: req.body });
115
114
  return next(new ProsopoApiError("API.BAD_REQUEST", {
116
- context: { code: 500, siteKey: req.body.dapp },
115
+ context: { code: 500, siteKey: req.body.dapp, error: err },
117
116
  }));
118
117
  }
119
118
  });
@@ -128,39 +127,23 @@ export function prosopoRouter(env) {
128
127
  }));
129
128
  }
130
129
  const { user, dapp, sessionId } = parsed;
130
+ validiateSiteKey(dapp);
131
+ validateAddr(user);
131
132
  try {
132
- validateAddress(dapp, false, 42);
133
- }
134
- catch (err) {
135
- return next(new ProsopoApiError("API.INVALID_SITE_KEY", {
136
- context: { code: 400, error: err, siteKey: dapp },
137
- }));
138
- }
139
- try {
140
- validateAddress(user, false, 42);
141
133
  const clientSettings = await tasks.db.getClientRecord(dapp);
142
- const clientRecord = await tasks.db.getClientRecord(dapp);
143
- if (!clientRecord) {
134
+ if (!clientSettings) {
144
135
  return next(new ProsopoApiError("API.SITE_KEY_NOT_REGISTERED", {
145
136
  context: { code: 400, siteKey: dapp },
146
137
  }));
147
138
  }
148
- if (sessionId) {
149
- const sessionRecord = await tasks.db.checkAndRemoveSession(sessionId);
150
- if (!sessionRecord) {
151
- return next(new ProsopoApiError("API.BAD_REQUEST", {
152
- context: {
153
- error: "Session ID not found",
154
- code: 400,
155
- siteKey: dapp,
156
- user,
157
- },
158
- }));
159
- }
160
- }
161
- else if (!(clientSettings?.settings?.captchaType === "pow")) {
162
- return next(new ProsopoApiError("API.INCORRECT_CAPTCHA_TYPE", {
163
- context: { code: 400, siteKey: dapp, user },
139
+ const { valid, reason, frictionlessTokenId } = await tasks.powCaptchaManager.isValidRequest(clientSettings, CaptchaType.pow, sessionId);
140
+ if (!valid) {
141
+ return next(new ProsopoApiError(reason || "API.BAD_REQUEST", {
142
+ context: {
143
+ code: 400,
144
+ siteKey: dapp,
145
+ user,
146
+ },
164
147
  }));
165
148
  }
166
149
  const origin = req.headers.origin;
@@ -179,7 +162,7 @@ export function prosopoRouter(env) {
179
162
  requestedAtTimestamp: challenge.requestedAtTimestamp,
180
163
  userAccount: user,
181
164
  dappAccount: dapp,
182
- }, challenge.difficulty, challenge.providerSignature, getIPAddress(req.ip || "").bigInt(), flatten(req.headers));
165
+ }, challenge.difficulty, challenge.providerSignature, getIPAddress(req.ip || "").bigInt(), flatten(req.headers), frictionlessTokenId);
183
166
  const getPowCaptchaResponse = {
184
167
  [ApiParams.status]: "ok",
185
168
  [ApiParams.challenge]: challenge.challenge,
@@ -200,6 +183,7 @@ export function prosopoRouter(env) {
200
183
  code: 500,
201
184
  siteKey: req.body.dapp,
202
185
  user: req.body.user,
186
+ error: err,
203
187
  },
204
188
  }));
205
189
  }
@@ -215,17 +199,9 @@ export function prosopoRouter(env) {
215
199
  }));
216
200
  }
217
201
  const { challenge, difficulty, signature, nonce, verifiedTimeout, dapp, user, } = parsed;
202
+ validiateSiteKey(dapp);
203
+ validateAddr(user);
218
204
  try {
219
- validateAddress(dapp, false, 42);
220
- }
221
- catch (err) {
222
- return next(new ProsopoApiError("API.INVALID_SITE_KEY", {
223
- context: { code: 400, error: err, siteKey: dapp },
224
- }));
225
- }
226
- try {
227
- validateAddress(user, false, 42);
228
- validateAddress(dapp, false, 42);
229
205
  const clientRecord = await tasks.db.getClientRecord(dapp);
230
206
  if (!clientRecord) {
231
207
  return next(new ProsopoApiError("API.SITE_KEY_NOT_REGISTERED", {
@@ -242,6 +218,7 @@ export function prosopoRouter(env) {
242
218
  context: {
243
219
  code: 500,
244
220
  siteKey: req.body.dapp,
221
+ error: err,
245
222
  },
246
223
  }));
247
224
  }
@@ -249,41 +226,61 @@ export function prosopoRouter(env) {
249
226
  router.post(ApiPaths.GetFrictionlessCaptchaChallenge, async (req, res, next) => {
250
227
  try {
251
228
  const { token, dapp, user } = GetFrictionlessCaptchaChallengeRequestBody.parse(req.body);
252
- const isTokenUsed = await tasks.db.checkFrictionlessTokenRecord(token);
253
- if (isTokenUsed) {
254
- tasks.logger.info("Token has already been used");
255
- return res.json(tasks.frictionlessManager.sendImageCaptcha());
229
+ const existingToken = await tasks.db.getFrictionlessTokenRecordByToken(token);
230
+ if (existingToken) {
231
+ tasks.logger.info(`Token ${existingToken} has already been used`);
232
+ return res.json(await tasks.frictionlessManager.sendImageCaptcha(existingToken._id));
256
233
  }
257
234
  const lScore = tasks.frictionlessManager.checkLangRules(req.headers["accept-language"] || "");
258
235
  const { baseBotScore, timestamp } = await getBotScore(token);
259
- if (timestamp < Date.now() - TEN_MINUTES) {
260
- tasks.logger.info("Timestamp is older than 10 minutes", new Date(timestamp));
261
- return res.json(tasks.frictionlessManager.sendImageCaptcha());
262
- }
263
236
  const botScore = baseBotScore + lScore;
264
- const clientConfig = await tasks.db.getClientRecord(dapp);
265
- const botThreshold = clientConfig?.settings?.frictionlessThreshold ||
237
+ const clientRecord = await tasks.db.getClientRecord(dapp);
238
+ if (!clientRecord) {
239
+ return next(new ProsopoApiError("API.SITE_KEY_NOT_REGISTERED", {
240
+ context: { code: 400, siteKey: dapp },
241
+ }));
242
+ }
243
+ const { valid, reason } = await tasks.frictionlessManager.isValidRequest(clientRecord, CaptchaType.frictionless);
244
+ if (!valid) {
245
+ return next(new ProsopoApiError(reason || "API.BAD_REQUEST", {
246
+ context: {
247
+ code: 400,
248
+ siteKey: dapp,
249
+ user,
250
+ },
251
+ }));
252
+ }
253
+ const botThreshold = clientRecord.settings?.frictionlessThreshold ||
266
254
  DEFAULT_FRICTIONLESS_THRESHOLD;
267
- const ipAddress = getIPAddress(req.ip || "");
268
- const isIpBlocked = await tasks.frictionlessManager.checkIpRules(ipAddress, dapp);
269
- if (isIpBlocked)
270
- return res.json(tasks.frictionlessManager.sendImageCaptcha());
271
- const isUserBlocked = await tasks.frictionlessManager.checkUserRules(user, dapp);
272
- if (isUserBlocked)
273
- return res.json(tasks.frictionlessManager.sendImageCaptcha());
274
- if (Number(botScore) > botThreshold)
275
- return res.json(tasks.frictionlessManager.sendImageCaptcha());
276
255
  const tokenId = await tasks.db.storeFrictionlessTokenRecord({
277
256
  token,
278
257
  score: botScore,
279
258
  threshold: botThreshold,
259
+ scoreComponents: {
260
+ baseScore: baseBotScore,
261
+ ...(lScore && { lScore }),
262
+ },
280
263
  });
281
- const response = await tasks.frictionlessManager.sendPowCaptcha(tokenId);
282
- return res.json(response);
264
+ if (FrictionlessManager.timestampTooOld(timestamp)) {
265
+ await tasks.frictionlessManager.scoreIncreaseTimestamp(timestamp, baseBotScore, botScore, tokenId);
266
+ return res.json(await tasks.frictionlessManager.sendImageCaptcha(tokenId));
267
+ }
268
+ const ipAddress = getIPAddress(req.ip || "");
269
+ const imageCaptchaConfigDefined = await imageCaptchaConfigResolver.isConfigDefined(dapp, ipAddress, user);
270
+ if (imageCaptchaConfigDefined) {
271
+ await tasks.frictionlessManager.scoreIncreaseAccessPolicy(imageCaptchaConfigResolver.accessRule, baseBotScore, botScore, tokenId);
272
+ return res.json(await tasks.frictionlessManager.sendImageCaptcha(tokenId));
273
+ }
274
+ if (Number(botScore) > botThreshold) {
275
+ tasks.logger.info({
276
+ message: `Bot score ${botScore} is greater than threshold ${botThreshold}`,
277
+ });
278
+ return res.json(await tasks.frictionlessManager.sendImageCaptcha(tokenId));
279
+ }
280
+ return res.json(await tasks.frictionlessManager.sendPowCaptcha(tokenId));
283
281
  }
284
282
  catch (err) {
285
- console.error("Error in frictionless captcha challenge:", err);
286
- tasks.logger.error(err);
283
+ tasks.logger.error("Error in frictionless captcha challenge:", err);
287
284
  return next(new ProsopoApiError("API.BAD_REQUEST", {
288
285
  context: { code: 400, error: err },
289
286
  }));