@prosopo/provider 3.13.0 → 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.
@@ -249,6 +249,7 @@ class FrictionlessManager extends captchaManager.CaptchaManager {
249
249
  let webView;
250
250
  let iFrame;
251
251
  let decryptedHeadHash = "";
252
+ let decryptionFailed = false;
252
253
  for (const [keyIndex, key] of decryptKeys.entries()) {
253
254
  try {
254
255
  this.logger.info(() => ({
@@ -296,6 +297,7 @@ class FrictionlessManager extends captchaManager.CaptchaManager {
296
297
  timestamp = 0;
297
298
  providerSelectEntropy = DEFAULT_ENTROPY + 1;
298
299
  decryptedHeadHash = "";
300
+ decryptionFailed = true;
299
301
  }
300
302
  }
301
303
  }
@@ -311,6 +313,7 @@ class FrictionlessManager extends captchaManager.CaptchaManager {
311
313
  timestamp = 0;
312
314
  providerSelectEntropy = DEFAULT_ENTROPY - undefinedCount;
313
315
  decryptedHeadHash = "";
316
+ decryptionFailed = true;
314
317
  }
315
318
  this.logger.info(() => ({
316
319
  msg: "decryptPayload result",
@@ -322,7 +325,8 @@ class FrictionlessManager extends captchaManager.CaptchaManager {
322
325
  userAgent,
323
326
  webView,
324
327
  iFrame,
325
- decryptedHeadHash
328
+ decryptedHeadHash,
329
+ decryptionFailed
326
330
  }
327
331
  }));
328
332
  return {
@@ -333,11 +337,12 @@ class FrictionlessManager extends captchaManager.CaptchaManager {
333
337
  userAgent,
334
338
  webView: webView || false,
335
339
  iFrame: iFrame || false,
336
- decryptedHeadHash
340
+ decryptedHeadHash,
341
+ decryptionFailed
337
342
  };
338
343
  }
339
- async getClientEntropy(siteKey) {
340
- return this.db.getClientEntropy(siteKey);
344
+ async getClientContextEntropy(siteKey, contextType) {
345
+ return this.db.getClientContextEntropy(siteKey, contextType);
341
346
  }
342
347
  }
343
348
  exports.DEFAULT_ENTROPY = DEFAULT_ENTROPY;
@@ -8,7 +8,10 @@ const computeFrictionlessScore = (scoreComponents) => {
8
8
  ).toFixed(2)
9
9
  );
10
10
  };
11
- const timestampDecayFunction = (timestamp) => {
11
+ const timestampDecayFunction = (timestamp, decryptionFailed) => {
12
+ if (decryptionFailed) {
13
+ return 6;
14
+ }
12
15
  const max = (/* @__PURE__ */ new Date()).getTime();
13
16
  if (max - timestamp > 36e5) {
14
17
  return 12;
@@ -1,9 +1,10 @@
1
1
  import { createPrivateKey } from "node:crypto";
2
2
  import { ProsopoApiError } from "@prosopo/common";
3
3
  import { CaptchaDatabase, ClientDatabase } from "@prosopo/database";
4
- import { ScheduledTaskNames, ScheduledTaskStatus } from "@prosopo/types";
4
+ import { ScheduledTaskNames, ScheduledTaskStatus, Tier } from "@prosopo/types";
5
5
  import { majorityAverage, parseUrl } from "@prosopo/util";
6
6
  import { validateSiteKey } from "../../api/validateAddress.js";
7
+ const SAMPLE_SIZE = 100;
7
8
  const isValidPrivateKey = (privateKeyString) => {
8
9
  const privateKey = Buffer.from(privateKeyString, "base64").toString("ascii");
9
10
  try {
@@ -161,7 +162,13 @@ class ClientTaskManager {
161
162
  this.logger
162
163
  );
163
164
  const tenMinuteWindow = 10 * 60 * 1e3;
164
- const updatedAtTimestamp = lastTask?.updated ? lastTask.updated.getTime() - tenMinuteWindow || 0 : 0;
165
+ const updatedAtTimestamp = (() => {
166
+ const raw = lastTask?.updated;
167
+ if (!raw) return 0;
168
+ const ts = raw instanceof Date ? raw.getTime() : Date.parse(String(raw));
169
+ if (Number.isNaN(ts)) return 0;
170
+ return Math.max(ts - tenMinuteWindow, 0);
171
+ })();
165
172
  this.logger.info(() => ({
166
173
  msg: `Getting updated client records since ${new Date(updatedAtTimestamp).toDateString()}`
167
174
  }));
@@ -199,14 +206,71 @@ class ClientTaskManager {
199
206
  * @returns Promise<void>
200
207
  */
201
208
  async calculateClientEntropy() {
202
- const clients = await this.providerDB.getAllClientRecords();
203
- for (const client of clients) {
204
- const sampleEntropies = await this.providerDB.sampleEntropy(
205
- 100,
206
- client.account
209
+ const taskID = await this.providerDB.createScheduledTaskStatus(
210
+ ScheduledTaskNames.SetClientEntropy,
211
+ ScheduledTaskStatus.Running
212
+ );
213
+ try {
214
+ let clients = await this.providerDB.getAllClientRecords();
215
+ clients = clients.filter((client) => client.tier !== Tier.Free);
216
+ this.logger.info(() => ({
217
+ msg: `Calculating entropies for ${clients.length} clients`
218
+ }));
219
+ for (const client of clients) {
220
+ if (client.settings?.contextAware?.enabled) {
221
+ const contextTypes = Object.keys(
222
+ client.settings.contextAware.contexts ?? {}
223
+ );
224
+ for (const contextType of contextTypes) {
225
+ const contextSamples = await this.providerDB.sampleContextEntropy(
226
+ SAMPLE_SIZE,
227
+ client.account,
228
+ contextType
229
+ );
230
+ if (contextSamples.length < SAMPLE_SIZE) {
231
+ this.logger.info(() => ({
232
+ msg: `Skipping ${contextType} entropy calculation for client ${client.account} due to insufficient samples (${contextSamples.length}/${SAMPLE_SIZE})`
233
+ }));
234
+ continue;
235
+ }
236
+ const contextAvgEntropy = majorityAverage(contextSamples);
237
+ this.logger.info(() => ({
238
+ msg: `Calculated ${contextType} entropy for client ${client.account}: ${contextAvgEntropy}`
239
+ }));
240
+ await this.providerDB.setClientContextEntropy(
241
+ client.account,
242
+ contextType,
243
+ contextAvgEntropy
244
+ );
245
+ }
246
+ }
247
+ }
248
+ await this.providerDB.updateScheduledTaskStatus(
249
+ taskID,
250
+ ScheduledTaskStatus.Completed,
251
+ {
252
+ data: {
253
+ clientRecords: clients.length
254
+ }
255
+ }
256
+ );
257
+ } catch (e) {
258
+ const calculateClientEntropiesError = new ProsopoApiError(
259
+ "DATABASE.UNKNOWN",
260
+ {
261
+ context: { error: e },
262
+ logger: this.logger
263
+ }
264
+ );
265
+ this.logger.error(() => ({
266
+ err: calculateClientEntropiesError,
267
+ msg: "Error calculating client entropy"
268
+ }));
269
+ await this.providerDB.updateScheduledTaskStatus(
270
+ taskID,
271
+ ScheduledTaskStatus.Failed,
272
+ { error: String(e) }
207
273
  );
208
- const avgEntropy = majorityAverage(sampleEntropies);
209
- await this.providerDB.setClientEntropy(client.account, avgEntropy);
210
274
  }
211
275
  }
212
276
  async registerSiteKey(siteKey, tier, settings) {