@prosopo/provider 3.13.6 → 3.13.7

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.
@@ -0,0 +1,103 @@
1
+
2
+ > @prosopo/provider@3.13.7 build:cjs
3
+ > NODE_ENV=${NODE_ENV:-development}; vite build --config vite.cjs.config.ts --mode $NODE_ENV
4
+
5
+ ViteCommonJSConfig: .
6
+ {
7
+ tsConfigPaths: [
8
+ '/home/runner/work/captcha/captcha/packages/api-route/tsconfig.json',
9
+ '/home/runner/work/captcha/captcha/packages/common/tsconfig.json',
10
+ '/home/runner/work/captcha/captcha/packages/locale/tsconfig.json',
11
+ '/home/runner/work/captcha/captcha/packages/types/tsconfig.json',
12
+ '/home/runner/work/captcha/captcha/packages/util/tsconfig.json',
13
+ '/home/runner/work/captcha/captcha/packages/util-crypto/tsconfig.json',
14
+ '/home/runner/work/captcha/captcha/packages/api-express-router/tsconfig.json',
15
+ '/home/runner/work/captcha/captcha/packages/env/tsconfig.json',
16
+ '/home/runner/work/captcha/captcha/packages/database/tsconfig.json',
17
+ '/home/runner/work/captcha/captcha/packages/types-database/tsconfig.json',
18
+ '/home/runner/work/captcha/captcha/packages/user-access-policy/tsconfig.json',
19
+ '/home/runner/work/captcha/captcha/packages/redis-client/tsconfig.json',
20
+ '/home/runner/work/captcha/captcha/packages/api/tsconfig.json',
21
+ '/home/runner/work/captcha/captcha/packages/types-env/tsconfig.json',
22
+ '/home/runner/work/captcha/captcha/packages/keyring/tsconfig.json',
23
+ '/home/runner/work/captcha/captcha/packages/datasets/tsconfig.json',
24
+ '/home/runner/work/captcha/captcha/packages/load-balancer/tsconfig.json'
25
+ ]
26
+ }
27
+ {
28
+ externals: [
29
+ '@prosopo/api-route',
30
+ '@prosopo/common',
31
+ '@prosopo/locale',
32
+ '@prosopo/types',
33
+ '@prosopo/util',
34
+ '@prosopo/util-crypto',
35
+ '@prosopo/api-express-router',
36
+ '@prosopo/env',
37
+ '@prosopo/database',
38
+ '@prosopo/types-database',
39
+ '@prosopo/user-access-policy',
40
+ '@prosopo/redis-client',
41
+ '@prosopo/api',
42
+ '@prosopo/types-env',
43
+ '@prosopo/keyring',
44
+ '@prosopo/datasets',
45
+ '@prosopo/load-balancer'
46
+ ]
47
+ }
48
+ vite v6.4.1 building SSR bundle for production...
49
+ Bundle build started
50
+ transforming...
51
+ Build end
52
+ ✓ 49 modules transformed.
53
+ rendering chunks...
54
+ dist/cjs/tasks/index.cjs  0.15 kB
55
+ dist/cjs/utils/hashUserIp.cjs  0.34 kB
56
+ dist/cjs/utils/hashUserAgent.cjs  0.36 kB
57
+ dist/cjs/api/robotsMiddleware.cjs  0.43 kB
58
+ dist/cjs/rules/lang.cjs  0.48 kB
59
+ dist/cjs/api/ignoreMiddleware.cjs  0.49 kB
60
+ dist/cjs/api/admin/createApiAdminRoutesProvider.cjs  0.50 kB
61
+ dist/cjs/api/block.cjs  0.71 kB
62
+ dist/cjs/api/captcha/contextAwareValidation.cjs  0.75 kB
63
+ dist/cjs/tasks/imgCaptcha/imgCaptchaTasksUtils.cjs  0.84 kB
64
+ dist/cjs/api/validateAddress.cjs  0.84 kB
65
+ dist/cjs/pairs.cjs  0.87 kB
66
+ dist/cjs/tasks/frictionless/frictionlessTasksUtils.cjs  0.94 kB
67
+ dist/cjs/tasks/dataset/datasetTasks.cjs  0.96 kB
68
+ dist/cjs/tasks/detection/getBotScore.cjs  1.02 kB
69
+ dist/cjs/api/headerCheckMiddleware.cjs  1.07 kB
70
+ dist/cjs/tasks/powCaptcha/powTasksUtils.cjs  1.13 kB
71
+ dist/cjs/schedulers/getClientList.cjs  1.21 kB
72
+ dist/cjs/api/admin/apiAdminRoutesProvider.cjs  1.23 kB
73
+ dist/cjs/schedulers/setClientEntropy.cjs  1.24 kB
74
+ dist/cjs/schedulers/captchaScheduler.cjs  1.28 kB
75
+ dist/cjs/api/admin/apiUpdateDetectorKeyEndpoint.cjs  1.30 kB
76
+ dist/cjs/api/admin/apiRegisterSiteKeyEndpoint.cjs  1.33 kB
77
+ dist/cjs/tasks/dataset/datasetTasksUtils.cjs  1.50 kB
78
+ dist/cjs/compositeIpAddress.cjs  1.70 kB
79
+ dist/cjs/api/admin/apiToggleMaintenanceModeEndpoint.cjs  1.71 kB
80
+ dist/cjs/api/public.cjs  1.74 kB
81
+ dist/cjs/api/captcha.cjs  1.74 kB
82
+ dist/cjs/api/admin/apiRemoveDetectorKeyEndpoint.cjs  1.82 kB
83
+ dist/cjs/tasks/tasks.cjs  1.91 kB
84
+ dist/cjs/api/captcha/submitPoWCaptchaSolution.cjs  2.31 kB
85
+ dist/cjs/services/ipInfo.cjs  2.49 kB
86
+ dist/cjs/api/captcha/submitImageCaptchaSolution.cjs  2.64 kB
87
+ dist/cjs/index.cjs  2.69 kB
88
+ dist/cjs/api/ja4Middleware.cjs  2.72 kB
89
+ dist/cjs/api/domainMiddleware.cjs  2.89 kB
90
+ dist/cjs/services/ipComparison.cjs  4.17 kB
91
+ dist/cjs/api/captcha/getImageCaptchaChallenge.cjs  4.35 kB
92
+ dist/cjs/api/blacklistRequestInspector.cjs  4.43 kB
93
+ dist/cjs/api/captcha/getPoWCaptchaChallenge.cjs  4.45 kB
94
+ dist/cjs/tasks/captchaManager.cjs  5.07 kB
95
+ dist/cjs/api/verify.cjs  6.05 kB
96
+ dist/cjs/tasks/powCaptcha/powTasks.cjs  7.46 kB
97
+ dist/cjs/tasks/frictionless/frictionlessTasks.cjs 11.88 kB
98
+ dist/cjs/tasks/client/clientTasks.cjs 12.25 kB
99
+ dist/cjs/util.cjs 12.27 kB
100
+ dist/cjs/api/captcha/getFrictionlessCaptchaChallenge.cjs 12.38 kB
101
+ dist/cjs/tasks/imgCaptcha/imgCaptchaTasks.cjs 15.66 kB
102
+ dist/cjs/tasks/detection/decodePayload.cjs 42.44 kB
103
+ ✓ built in 450ms
@@ -0,0 +1,103 @@
1
+
2
+ > @prosopo/provider@3.13.7 build
3
+ > NODE_ENV=${NODE_ENV:-development}; vite build --config vite.esm.config.ts --mode $NODE_ENV
4
+
5
+ ViteEsmConfig: .
6
+ {
7
+ tsConfigPaths: [
8
+ '/home/runner/work/captcha/captcha/packages/api-route/tsconfig.json',
9
+ '/home/runner/work/captcha/captcha/packages/common/tsconfig.json',
10
+ '/home/runner/work/captcha/captcha/packages/locale/tsconfig.json',
11
+ '/home/runner/work/captcha/captcha/packages/types/tsconfig.json',
12
+ '/home/runner/work/captcha/captcha/packages/util/tsconfig.json',
13
+ '/home/runner/work/captcha/captcha/packages/util-crypto/tsconfig.json',
14
+ '/home/runner/work/captcha/captcha/packages/api-express-router/tsconfig.json',
15
+ '/home/runner/work/captcha/captcha/packages/env/tsconfig.json',
16
+ '/home/runner/work/captcha/captcha/packages/database/tsconfig.json',
17
+ '/home/runner/work/captcha/captcha/packages/types-database/tsconfig.json',
18
+ '/home/runner/work/captcha/captcha/packages/user-access-policy/tsconfig.json',
19
+ '/home/runner/work/captcha/captcha/packages/redis-client/tsconfig.json',
20
+ '/home/runner/work/captcha/captcha/packages/api/tsconfig.json',
21
+ '/home/runner/work/captcha/captcha/packages/types-env/tsconfig.json',
22
+ '/home/runner/work/captcha/captcha/packages/keyring/tsconfig.json',
23
+ '/home/runner/work/captcha/captcha/packages/datasets/tsconfig.json',
24
+ '/home/runner/work/captcha/captcha/packages/load-balancer/tsconfig.json'
25
+ ]
26
+ }
27
+ {
28
+ externals: [
29
+ '@prosopo/api-route',
30
+ '@prosopo/common',
31
+ '@prosopo/locale',
32
+ '@prosopo/types',
33
+ '@prosopo/util',
34
+ '@prosopo/util-crypto',
35
+ '@prosopo/api-express-router',
36
+ '@prosopo/env',
37
+ '@prosopo/database',
38
+ '@prosopo/types-database',
39
+ '@prosopo/user-access-policy',
40
+ '@prosopo/redis-client',
41
+ '@prosopo/api',
42
+ '@prosopo/types-env',
43
+ '@prosopo/keyring',
44
+ '@prosopo/datasets',
45
+ '@prosopo/load-balancer'
46
+ ]
47
+ }
48
+ vite v6.4.1 building SSR bundle for production...
49
+ Bundle build started
50
+ transforming...
51
+ Build end
52
+ ✓ 49 modules transformed.
53
+ rendering chunks...
54
+ dist/tasks/index.js  0.06 kB
55
+ dist/utils/hashUserIp.js  0.23 kB
56
+ dist/utils/hashUserAgent.js  0.25 kB
57
+ dist/api/robotsMiddleware.js  0.33 kB
58
+ dist/api/admin/createApiAdminRoutesProvider.js  0.35 kB
59
+ dist/rules/lang.js  0.38 kB
60
+ dist/api/ignoreMiddleware.js  0.39 kB
61
+ dist/api/block.js  0.58 kB
62
+ dist/api/captcha/contextAwareValidation.js  0.63 kB
63
+ dist/api/validateAddress.js  0.71 kB
64
+ dist/pairs.js  0.72 kB
65
+ dist/tasks/imgCaptcha/imgCaptchaTasksUtils.js  0.74 kB
66
+ dist/tasks/frictionless/frictionlessTasksUtils.js  0.80 kB
67
+ dist/tasks/dataset/datasetTasks.js  0.85 kB
68
+ dist/api/admin/apiRegisterSiteKeyEndpoint.js  0.90 kB
69
+ dist/tasks/detection/getBotScore.js  0.91 kB
70
+ dist/api/headerCheckMiddleware.js  0.92 kB
71
+ dist/api/admin/apiAdminRoutesProvider.js  0.98 kB
72
+ dist/tasks/powCaptcha/powTasksUtils.js  0.99 kB
73
+ dist/api/admin/apiRemoveDetectorKeyEndpoint.js  1.09 kB
74
+ dist/schedulers/getClientList.js  1.10 kB
75
+ dist/schedulers/setClientEntropy.js  1.13 kB
76
+ dist/schedulers/captchaScheduler.js  1.16 kB
77
+ dist/api/admin/apiUpdateDetectorKeyEndpoint.js  1.18 kB
78
+ dist/api/admin/apiToggleMaintenanceModeEndpoint.js  1.19 kB
79
+ dist/tasks/dataset/datasetTasksUtils.js  1.36 kB
80
+ dist/compositeIpAddress.js  1.45 kB
81
+ dist/api/captcha.js  1.57 kB
82
+ dist/api/public.js  1.60 kB
83
+ dist/tasks/tasks.js  1.78 kB
84
+ dist/index.js  1.81 kB
85
+ dist/api/ja4Middleware.js  2.19 kB
86
+ dist/api/captcha/submitPoWCaptchaSolution.js  2.23 kB
87
+ dist/services/ipInfo.js  2.39 kB
88
+ dist/api/captcha/submitImageCaptchaSolution.js  2.52 kB
89
+ dist/api/domainMiddleware.js  2.72 kB
90
+ dist/services/ipComparison.js  4.05 kB
91
+ dist/api/captcha/getImageCaptchaChallenge.js  4.22 kB
92
+ dist/api/blacklistRequestInspector.js  4.22 kB
93
+ dist/api/captcha/getPoWCaptchaChallenge.js  4.30 kB
94
+ dist/tasks/captchaManager.js  4.59 kB
95
+ dist/api/verify.js  5.76 kB
96
+ dist/tasks/powCaptcha/powTasks.js  7.28 kB
97
+ dist/tasks/frictionless/frictionlessTasks.js 11.64 kB
98
+ dist/util.js 11.85 kB
99
+ dist/api/captcha/getFrictionlessCaptchaChallenge.js 11.95 kB
100
+ dist/tasks/client/clientTasks.js 12.05 kB
101
+ dist/tasks/imgCaptcha/imgCaptchaTasks.js 15.41 kB
102
+ dist/tasks/detection/decodePayload.js 42.41 kB
103
+ ✓ built in 557ms
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # @prosopo/provider
2
2
 
3
+ ## 3.13.7
4
+ ### Patch Changes
5
+
6
+ - 7d5eb3f: bump
7
+ - Updated dependencies [7d5eb3f]
8
+ - @prosopo/api@3.1.37
9
+ - @prosopo/api-express-router@3.0.40
10
+ - @prosopo/api-route@2.6.34
11
+ - @prosopo/common@3.1.26
12
+ - @prosopo/database@3.5.6
13
+ - @prosopo/datasets@3.0.49
14
+ - @prosopo/env@3.2.28
15
+ - @prosopo/keyring@2.8.40
16
+ - @prosopo/load-balancer@2.8.13
17
+ - @prosopo/locale@3.1.26
18
+ - @prosopo/types@3.6.4
19
+ - @prosopo/types-database@4.0.6
20
+ - @prosopo/types-env@2.7.53
21
+ - @prosopo/user-access-policy@3.5.32
22
+ - @prosopo/util@3.2.4
23
+ - @prosopo/util-crypto@13.5.28
24
+
3
25
  ## 3.13.6
4
26
  ### Patch Changes
5
27
 
@@ -0,0 +1,20 @@
1
+ import { ContextType, contextAwareThresholdDefault } from "@prosopo/types";
2
+ function determineContextType(webView) {
3
+ return webView ? ContextType.Webview : ContextType.Default;
4
+ }
5
+ function getContextThreshold(settings, contextType) {
6
+ const contextAware = settings.contextAware;
7
+ if (contextAware === void 0) {
8
+ return contextAwareThresholdDefault;
9
+ }
10
+ const contexts = contextAware.contexts;
11
+ let contextConfig;
12
+ if (contexts !== void 0) {
13
+ contextConfig = contexts[contextType];
14
+ }
15
+ return contextConfig?.threshold ?? contextAwareThresholdDefault;
16
+ }
17
+ export {
18
+ determineContextType,
19
+ getContextThreshold
20
+ };
@@ -1,5 +1,5 @@
1
1
  import { ProsopoApiError } from "@prosopo/common";
2
- import { GetFrictionlessCaptchaChallengeRequestBody, ApiParams, CaptchaType } from "@prosopo/types";
2
+ import { GetFrictionlessCaptchaChallengeRequestBody, ApiParams, CaptchaType, ContextType } from "@prosopo/types";
3
3
  import { flatten, compareBinaryStrings } from "@prosopo/util";
4
4
  import { getCompositeIpAddress } from "../../compositeIpAddress.js";
5
5
  import { FrictionlessReason, FrictionlessManager } from "../../tasks/frictionless/frictionlessTasks.js";
@@ -9,6 +9,7 @@ import { hashUserAgent } from "../../utils/hashUserAgent.js";
9
9
  import { hashUserIp } from "../../utils/hashUserIp.js";
10
10
  import { getMaintenanceMode } from "../admin/apiToggleMaintenanceModeEndpoint.js";
11
11
  import { getRequestUserScope } from "../blacklistRequestInspector.js";
12
+ import { determineContextType, getContextThreshold } from "./contextAwareValidation.js";
12
13
  import { Tasks } from "../../tasks/tasks.js";
13
14
  const DEFAULT_FRICTIONLESS_THRESHOLD = 0.5;
14
15
  const getRoundsFromSimScore = (simScore) => {
@@ -216,36 +217,56 @@ const getFrictionlessCaptchaChallenge = (env, userAccessRulesStorage) => async (
216
217
  );
217
218
  }
218
219
  if (clientRecord.settings.contextAware?.enabled) {
219
- const clientEntropy = await tasks.frictionlessManager.getClientEntropy(
220
- clientRecord.account
221
- );
222
- if (clientEntropy) {
223
- if (!decryptedHeadHash) {
224
- tasks.logger.info(() => ({
225
- msg: "No decryptedHeadHash in session for context aware client"
226
- }));
227
- return next(
228
- new ProsopoApiError("API.BAD_REQUEST", {
229
- context: {
230
- code: 400,
231
- siteKey: dapp,
232
- user
233
- },
234
- i18n: req.i18n,
235
- logger: req.logger
236
- })
237
- );
238
- }
239
- const sim = compareBinaryStrings(decryptedHeadHash, clientEntropy);
240
- const isValidContext = sim >= clientRecord.settings.contextAware.threshold;
241
- if (!isValidContext) {
242
- return res.json(
243
- await tasks.frictionlessManager.sendImageCaptcha({
244
- solvedImagesCount: getRoundsFromSimScore(sim),
245
- userSitekeyIpHash,
246
- reason: FrictionlessReason.CONTEXT_AWARE_VALIDATION_FAILED
247
- })
220
+ const contexts = clientRecord.settings.contextAware?.contexts || {};
221
+ const hasDefault = contexts[ContextType.Default] !== void 0;
222
+ const hasWebview = contexts[ContextType.Webview] !== void 0;
223
+ let contextType;
224
+ if (hasDefault && hasWebview) {
225
+ contextType = determineContextType(webView);
226
+ } else if (hasDefault) {
227
+ contextType = ContextType.Default;
228
+ } else if (hasWebview) {
229
+ contextType = ContextType.Webview;
230
+ } else {
231
+ contextType = void 0;
232
+ }
233
+ if (contextType) {
234
+ const clientEntropy = await tasks.frictionlessManager.getClientContextEntropy(
235
+ clientRecord.account,
236
+ contextType
237
+ );
238
+ if (clientEntropy) {
239
+ if (!decryptedHeadHash) {
240
+ tasks.logger.info(() => ({
241
+ msg: "No decryptedHeadHash in session for context aware client"
242
+ }));
243
+ return next(
244
+ new ProsopoApiError("API.BAD_REQUEST", {
245
+ context: {
246
+ code: 400,
247
+ siteKey: dapp,
248
+ user
249
+ },
250
+ i18n: req.i18n,
251
+ logger: req.logger
252
+ })
253
+ );
254
+ }
255
+ const threshold = getContextThreshold(
256
+ clientRecord.settings,
257
+ contextType
248
258
  );
259
+ const sim = compareBinaryStrings(decryptedHeadHash, clientEntropy);
260
+ const isValidContext = sim >= threshold;
261
+ if (!isValidContext) {
262
+ return res.json(
263
+ await tasks.frictionlessManager.sendImageCaptcha({
264
+ solvedImagesCount: getRoundsFromSimScore(sim),
265
+ userSitekeyIpHash,
266
+ reason: FrictionlessReason.CONTEXT_AWARE_VALIDATION_FAILED
267
+ })
268
+ );
269
+ }
249
270
  }
250
271
  }
251
272
  }
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const types = require("@prosopo/types");
4
+ function determineContextType(webView) {
5
+ return webView ? types.ContextType.Webview : types.ContextType.Default;
6
+ }
7
+ function getContextThreshold(settings, contextType) {
8
+ const contextAware = settings.contextAware;
9
+ if (contextAware === void 0) {
10
+ return types.contextAwareThresholdDefault;
11
+ }
12
+ const contexts = contextAware.contexts;
13
+ let contextConfig;
14
+ if (contexts !== void 0) {
15
+ contextConfig = contexts[contextType];
16
+ }
17
+ return contextConfig?.threshold ?? types.contextAwareThresholdDefault;
18
+ }
19
+ exports.determineContextType = determineContextType;
20
+ exports.getContextThreshold = getContextThreshold;
@@ -10,6 +10,7 @@ const hashUserAgent = require("../../utils/hashUserAgent.cjs");
10
10
  const hashUserIp = require("../../utils/hashUserIp.cjs");
11
11
  const apiToggleMaintenanceModeEndpoint = require("../admin/apiToggleMaintenanceModeEndpoint.cjs");
12
12
  const blacklistRequestInspector = require("../blacklistRequestInspector.cjs");
13
+ const contextAwareValidation = require("./contextAwareValidation.cjs");
13
14
  const tasks = require("../../tasks/tasks.cjs");
14
15
  const DEFAULT_FRICTIONLESS_THRESHOLD = 0.5;
15
16
  const getRoundsFromSimScore = (simScore) => {
@@ -217,36 +218,56 @@ const getFrictionlessCaptchaChallenge = (env, userAccessRulesStorage) => async (
217
218
  );
218
219
  }
219
220
  if (clientRecord.settings.contextAware?.enabled) {
220
- const clientEntropy = await tasks$1.frictionlessManager.getClientEntropy(
221
- clientRecord.account
222
- );
223
- if (clientEntropy) {
224
- if (!decryptedHeadHash) {
225
- tasks$1.logger.info(() => ({
226
- msg: "No decryptedHeadHash in session for context aware client"
227
- }));
228
- return next(
229
- new common.ProsopoApiError("API.BAD_REQUEST", {
230
- context: {
231
- code: 400,
232
- siteKey: dapp,
233
- user
234
- },
235
- i18n: req.i18n,
236
- logger: req.logger
237
- })
238
- );
239
- }
240
- const sim = util.compareBinaryStrings(decryptedHeadHash, clientEntropy);
241
- const isValidContext = sim >= clientRecord.settings.contextAware.threshold;
242
- if (!isValidContext) {
243
- return res.json(
244
- await tasks$1.frictionlessManager.sendImageCaptcha({
245
- solvedImagesCount: getRoundsFromSimScore(sim),
246
- userSitekeyIpHash,
247
- reason: frictionlessTasks.FrictionlessReason.CONTEXT_AWARE_VALIDATION_FAILED
248
- })
221
+ const contexts = clientRecord.settings.contextAware?.contexts || {};
222
+ const hasDefault = contexts[types.ContextType.Default] !== void 0;
223
+ const hasWebview = contexts[types.ContextType.Webview] !== void 0;
224
+ let contextType;
225
+ if (hasDefault && hasWebview) {
226
+ contextType = contextAwareValidation.determineContextType(webView);
227
+ } else if (hasDefault) {
228
+ contextType = types.ContextType.Default;
229
+ } else if (hasWebview) {
230
+ contextType = types.ContextType.Webview;
231
+ } else {
232
+ contextType = void 0;
233
+ }
234
+ if (contextType) {
235
+ const clientEntropy = await tasks$1.frictionlessManager.getClientContextEntropy(
236
+ clientRecord.account,
237
+ contextType
238
+ );
239
+ if (clientEntropy) {
240
+ if (!decryptedHeadHash) {
241
+ tasks$1.logger.info(() => ({
242
+ msg: "No decryptedHeadHash in session for context aware client"
243
+ }));
244
+ return next(
245
+ new common.ProsopoApiError("API.BAD_REQUEST", {
246
+ context: {
247
+ code: 400,
248
+ siteKey: dapp,
249
+ user
250
+ },
251
+ i18n: req.i18n,
252
+ logger: req.logger
253
+ })
254
+ );
255
+ }
256
+ const threshold = contextAwareValidation.getContextThreshold(
257
+ clientRecord.settings,
258
+ contextType
249
259
  );
260
+ const sim = util.compareBinaryStrings(decryptedHeadHash, clientEntropy);
261
+ const isValidContext = sim >= threshold;
262
+ if (!isValidContext) {
263
+ return res.json(
264
+ await tasks$1.frictionlessManager.sendImageCaptcha({
265
+ solvedImagesCount: getRoundsFromSimScore(sim),
266
+ userSitekeyIpHash,
267
+ reason: frictionlessTasks.FrictionlessReason.CONTEXT_AWARE_VALIDATION_FAILED
268
+ })
269
+ );
270
+ }
250
271
  }
251
272
  }
252
273
  }
@@ -6,6 +6,7 @@ const database = require("@prosopo/database");
6
6
  const types = require("@prosopo/types");
7
7
  const util = require("@prosopo/util");
8
8
  const validateAddress = require("../../api/validateAddress.cjs");
9
+ const SAMPLE_SIZE = 100;
9
10
  const isValidPrivateKey = (privateKeyString) => {
10
11
  const privateKey = Buffer.from(privateKeyString, "base64").toString("ascii");
11
12
  try {
@@ -212,14 +213,39 @@ class ClientTaskManager {
212
213
  types.ScheduledTaskStatus.Running
213
214
  );
214
215
  try {
215
- const clients = await this.providerDB.getAllClientRecords();
216
+ let clients = await this.providerDB.getAllClientRecords();
217
+ clients = clients.filter((client) => client.tier !== types.Tier.Free);
218
+ this.logger.info(() => ({
219
+ msg: `Calculating entropies for ${clients.length} clients`
220
+ }));
216
221
  for (const client of clients) {
217
- const sampleEntropies = await this.providerDB.sampleEntropy(
218
- 100,
219
- client.account
220
- );
221
- const avgEntropy = util.majorityAverage(sampleEntropies);
222
- await this.providerDB.setClientEntropy(client.account, avgEntropy);
222
+ if (client.settings?.contextAware?.enabled) {
223
+ const contextTypes = Object.keys(
224
+ client.settings.contextAware.contexts ?? {}
225
+ );
226
+ for (const contextType of contextTypes) {
227
+ const contextSamples = await this.providerDB.sampleContextEntropy(
228
+ SAMPLE_SIZE,
229
+ client.account,
230
+ contextType
231
+ );
232
+ if (contextSamples.length < SAMPLE_SIZE) {
233
+ this.logger.info(() => ({
234
+ msg: `Skipping ${contextType} entropy calculation for client ${client.account} due to insufficient samples (${contextSamples.length}/${SAMPLE_SIZE})`
235
+ }));
236
+ continue;
237
+ }
238
+ const contextAvgEntropy = util.majorityAverage(contextSamples);
239
+ this.logger.info(() => ({
240
+ msg: `Calculated ${contextType} entropy for client ${client.account}: ${contextAvgEntropy}`
241
+ }));
242
+ await this.providerDB.setClientContextEntropy(
243
+ client.account,
244
+ contextType,
245
+ contextAvgEntropy
246
+ );
247
+ }
248
+ }
223
249
  }
224
250
  await this.providerDB.updateScheduledTaskStatus(
225
251
  taskID,