@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.
- package/dist/api/admin/apiAdminRoutesProvider.d.ts +9 -0
- package/dist/api/admin/apiAdminRoutesProvider.d.ts.map +1 -0
- package/dist/api/admin/apiAdminRoutesProvider.js +17 -0
- package/dist/api/admin/apiAdminRoutesProvider.js.map +1 -0
- package/dist/api/admin/apiRegisterSiteKeyEndpoint.d.ts +13 -0
- package/dist/api/admin/apiRegisterSiteKeyEndpoint.d.ts.map +1 -0
- package/dist/api/admin/apiRegisterSiteKeyEndpoint.js +20 -0
- package/dist/api/admin/apiRegisterSiteKeyEndpoint.js.map +1 -0
- package/dist/api/admin/createApiAdminRoutesProvider.d.ts +4 -0
- package/dist/api/admin/createApiAdminRoutesProvider.d.ts.map +1 -0
- package/dist/api/admin/createApiAdminRoutesProvider.js +7 -0
- package/dist/api/admin/createApiAdminRoutesProvider.js.map +1 -0
- package/dist/api/authMiddleware.d.ts.map +1 -1
- package/dist/api/authMiddleware.js +4 -1
- package/dist/api/authMiddleware.js.map +1 -1
- package/dist/api/blacklistRequestInspector.d.ts +19 -0
- package/dist/api/blacklistRequestInspector.d.ts.map +1 -0
- package/dist/api/blacklistRequestInspector.js +61 -0
- package/dist/api/blacklistRequestInspector.js.map +1 -0
- package/dist/api/block.d.ts +1 -2
- package/dist/api/block.d.ts.map +1 -1
- package/dist/api/block.js +13 -38
- package/dist/api/block.js.map +1 -1
- package/dist/api/captcha.d.ts.map +1 -1
- package/dist/api/captcha.js +85 -88
- package/dist/api/captcha.js.map +1 -1
- package/dist/api/domainMiddleware.d.ts.map +1 -1
- package/dist/api/domainMiddleware.js +7 -6
- package/dist/api/domainMiddleware.js.map +1 -1
- package/dist/api/headerCheckMiddleware.d.ts.map +1 -1
- package/dist/api/headerCheckMiddleware.js +5 -1
- package/dist/api/headerCheckMiddleware.js.map +1 -1
- package/dist/api/public.d.ts.map +1 -1
- package/dist/api/public.js +1 -2
- package/dist/api/public.js.map +1 -1
- package/dist/api/validateAddress.d.ts +4 -0
- package/dist/api/validateAddress.d.ts.map +1 -0
- package/dist/api/validateAddress.js +16 -0
- package/dist/api/validateAddress.js.map +1 -0
- package/dist/api/verify.d.ts.map +1 -1
- package/dist/api/verify.js +6 -14
- package/dist/api/verify.js.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -2
- package/dist/index.js.map +1 -1
- package/dist/tasks/captchaManager.d.ts +25 -0
- package/dist/tasks/captchaManager.d.ts.map +1 -0
- package/dist/tasks/captchaManager.js +81 -0
- package/dist/tasks/captchaManager.js.map +1 -0
- package/dist/tasks/client/clientTasks.d.ts +2 -7
- package/dist/tasks/client/clientTasks.d.ts.map +1 -1
- package/dist/tasks/client/clientTasks.js +5 -63
- package/dist/tasks/client/clientTasks.js.map +1 -1
- package/dist/tasks/frictionless/frictionlessTasks.d.ts +13 -9
- package/dist/tasks/frictionless/frictionlessTasks.d.ts.map +1 -1
- package/dist/tasks/frictionless/frictionlessTasks.js +54 -23
- package/dist/tasks/frictionless/frictionlessTasks.js.map +1 -1
- package/dist/tasks/frictionless/frictionlessTasksUtils.d.ts +5 -0
- package/dist/tasks/frictionless/frictionlessTasksUtils.d.ts.map +1 -0
- package/dist/tasks/frictionless/frictionlessTasksUtils.js +6 -0
- package/dist/tasks/frictionless/frictionlessTasksUtils.js.map +1 -0
- package/dist/tasks/imgCaptcha/imgCaptchaTasks.d.ts +7 -8
- package/dist/tasks/imgCaptcha/imgCaptchaTasks.d.ts.map +1 -1
- package/dist/tasks/imgCaptcha/imgCaptchaTasks.js +32 -12
- package/dist/tasks/imgCaptcha/imgCaptchaTasks.js.map +1 -1
- package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.d.ts +1 -3
- package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.d.ts.map +1 -1
- package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.js +0 -29
- package/dist/tasks/imgCaptcha/imgCaptchaTasksUtils.js.map +1 -1
- package/dist/tasks/powCaptcha/powTasks.d.ts +8 -5
- package/dist/tasks/powCaptcha/powTasks.d.ts.map +1 -1
- package/dist/tasks/powCaptcha/powTasks.js +22 -15
- package/dist/tasks/powCaptcha/powTasks.js.map +1 -1
- package/dist/tasks/tasks.d.ts.map +1 -1
- package/dist/tasks/tasks.js +3 -3
- package/dist/tasks/tasks.js.map +1 -1
- package/dist/tests/integration/imgCaptcha.integration.test.js +59 -7
- package/dist/tests/integration/imgCaptcha.integration.test.js.map +1 -1
- package/dist/tests/integration/powCaptcha.integration.test.js +57 -13
- package/dist/tests/integration/powCaptcha.integration.test.js.map +1 -1
- package/dist/tests/integration/registerSitekey.d.ts +2 -1
- package/dist/tests/integration/registerSitekey.d.ts.map +1 -1
- package/dist/tests/integration/registerSitekey.js +2 -2
- package/dist/tests/integration/registerSitekey.js.map +1 -1
- package/dist/tests/unit/api/authMiddleware.unit.test.js +7 -1
- package/dist/tests/unit/api/authMiddleware.unit.test.js.map +1 -1
- package/dist/tests/unit/tasks/captchaManager.unit.test.d.ts +2 -0
- package/dist/tests/unit/tasks/captchaManager.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/tasks/captchaManager.unit.test.js +229 -0
- package/dist/tests/unit/tasks/captchaManager.unit.test.js.map +1 -0
- package/dist/tests/unit/tasks/frictionless/frictionlessTasks.unit.test.js +39 -64
- package/dist/tests/unit/tasks/frictionless/frictionlessTasks.unit.test.js.map +1 -1
- package/dist/tests/unit/tasks/frictionless/frictionlessTasksUtils.unit.test.d.ts +2 -0
- package/dist/tests/unit/tasks/frictionless/frictionlessTasksUtils.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/tasks/frictionless/frictionlessTasksUtils.unit.test.js +37 -0
- package/dist/tests/unit/tasks/frictionless/frictionlessTasksUtils.unit.test.js.map +1 -0
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.unit.test.js +4 -4
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.unit.test.js.map +1 -1
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.unit.test.js +1 -101
- package/dist/tests/unit/tasks/imgCaptcha/imgCaptchaTasksUtils.unit.test.js.map +1 -1
- package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.js +5 -10
- package/dist/tests/unit/tasks/powCaptcha/powTasks.unit.test.js.map +1 -1
- package/package.json +14 -11
- package/dist/api/admin.d.ts +0 -4
- package/dist/api/admin.d.ts.map +0 -1
- package/dist/api/admin.js +0 -87
- package/dist/api/admin.js.map +0 -1
- package/dist/api/errorHandler.d.ts +0 -5
- package/dist/api/errorHandler.d.ts.map +0 -1
- package/dist/api/errorHandler.js +0 -10
- package/dist/api/errorHandler.js.map +0 -1
- package/dist/rules/ip.d.ts +0 -4
- package/dist/rules/ip.d.ts.map +0 -1
- package/dist/rules/ip.js +0 -19
- package/dist/rules/ip.js.map +0 -1
- package/dist/rules/user.d.ts +0 -4
- package/dist/rules/user.d.ts.map +0 -1
- package/dist/rules/user.js +0 -10
- package/dist/rules/user.js.map +0 -1
- package/dist/tests/unit/api/errorHandler.unit.test.d.ts +0 -2
- package/dist/tests/unit/api/errorHandler.unit.test.d.ts.map +0 -1
- package/dist/tests/unit/api/errorHandler.unit.test.js +0 -105
- 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,
|
|
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.
|
|
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":"AAcA,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAI3C,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,GAAwB,EAAE,EAAE;IAC1D,OAAO,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;QAChE,IAAI,CAAC;YAEJ,IAAI,GAAG,CAAC,
|
|
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":"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"}
|
package/dist/api/block.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
import type { ProviderEnvironment } from "@prosopo/types-env";
|
|
2
|
-
|
|
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
|
package/dist/api/block.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block.d.ts","sourceRoot":"","sources":["../../src/api/block.ts"],"names":[],"mappings":"
|
|
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 {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const logger =
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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
|
package/dist/api/block.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block.js","sourceRoot":"","sources":["../../src/api/block.ts"],"names":[],"mappings":"
|
|
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":"
|
|
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"}
|
package/dist/api/captcha.js
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
|
-
import {
|
|
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 {
|
|
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 {
|
|
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
|
|
51
|
-
const
|
|
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
|
-
|
|
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
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
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
|
|
253
|
-
if (
|
|
254
|
-
tasks.logger.info(
|
|
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
|
|
265
|
-
|
|
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
|
-
|
|
282
|
-
|
|
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
|
-
|
|
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
|
}));
|