@prosopo/types-database 4.0.6 → 4.8.0

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 (46) hide show
  1. package/.turbo/turbo-build$colon$cjs.log +16 -12
  2. package/.turbo/turbo-build$colon$tsc.log +44 -0
  3. package/.turbo/turbo-build.log +21 -13
  4. package/CHANGELOG.md +581 -0
  5. package/dist/cjs/index.cjs +6 -7
  6. package/dist/cjs/types/bannedDomain.cjs +8 -0
  7. package/dist/cjs/types/client.cjs +77 -5
  8. package/dist/cjs/types/index.cjs +6 -7
  9. package/dist/cjs/types/provider.cjs +312 -86
  10. package/dist/cjs/types/spamEmailDomain.cjs +8 -0
  11. package/dist/index.d.ts +2 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +8 -9
  14. package/dist/index.js.map +1 -0
  15. package/dist/types/bannedDomain.d.ts +15 -0
  16. package/dist/types/bannedDomain.d.ts.map +1 -0
  17. package/dist/types/bannedDomain.js +8 -0
  18. package/dist/types/bannedDomain.js.map +1 -0
  19. package/dist/types/captcha.d.ts +18 -0
  20. package/dist/types/captcha.d.ts.map +1 -0
  21. package/dist/types/captcha.js.map +1 -0
  22. package/dist/types/client.d.ts +370 -0
  23. package/dist/types/client.d.ts.map +1 -0
  24. package/dist/types/client.js +78 -6
  25. package/dist/types/client.js.map +1 -0
  26. package/dist/types/index.d.ts +8 -0
  27. package/dist/types/index.d.ts.map +1 -0
  28. package/dist/types/index.js +8 -9
  29. package/dist/types/index.js.map +1 -0
  30. package/dist/types/mongo.d.ts +13 -0
  31. package/dist/types/mongo.d.ts.map +1 -0
  32. package/dist/types/mongo.js.map +1 -0
  33. package/dist/types/provider.d.ts +298 -0
  34. package/dist/types/provider.d.ts.map +1 -0
  35. package/dist/types/provider.js +314 -88
  36. package/dist/types/provider.js.map +1 -0
  37. package/dist/types/spamEmailDomain.d.ts +15 -0
  38. package/dist/types/spamEmailDomain.d.ts.map +1 -0
  39. package/dist/types/spamEmailDomain.js +8 -0
  40. package/dist/types/spamEmailDomain.js.map +1 -0
  41. package/dist/types/userAgent.d.ts +31 -0
  42. package/dist/types/userAgent.d.ts.map +1 -0
  43. package/dist/types/userAgent.js.map +1 -0
  44. package/package.json +11 -8
  45. package/vite.cjs.config.ts +1 -1
  46. package/vite.esm.config.ts +1 -1
@@ -3,6 +3,11 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const types = require("@prosopo/types");
4
4
  const mongoose = require("mongoose");
5
5
  const IPValidationRulesSchema = new mongoose.Schema({
6
+ enabled: {
7
+ type: Boolean,
8
+ default: false,
9
+ required: true
10
+ },
6
11
  actions: {
7
12
  countryChangeAction: {
8
13
  type: mongoose.Schema.Types.Mixed,
@@ -61,12 +66,34 @@ const IPValidationRulesSchema = new mongoose.Schema({
61
66
  }
62
67
  });
63
68
  const UserSettingsSchema = new mongoose.Schema({
64
- captchaType: String,
65
- frictionlessThreshold: Number,
66
- powDifficulty: Number,
67
- imageThreshold: Number,
69
+ captchaType: {
70
+ type: String,
71
+ enum: types.CaptchaType,
72
+ default: types.captchaTypeDefault
73
+ },
74
+ frictionlessThreshold: {
75
+ type: Number,
76
+ default: types.frictionlessThresholdDefault
77
+ },
78
+ powDifficulty: { type: Number, default: types.powDifficultyDefault },
79
+ imageThreshold: {
80
+ type: Number,
81
+ default: types.imageThresholdDefault
82
+ },
83
+ imageMaxRounds: {
84
+ type: Number,
85
+ default: types.imageMaxRoundsDefault,
86
+ required: false
87
+ },
88
+ puzzleTolerance: {
89
+ type: Number,
90
+ required: false
91
+ },
68
92
  ipValidationRules: IPValidationRulesSchema,
69
- domains: [String],
93
+ domains: {
94
+ type: [String],
95
+ default: types.domainsDefault
96
+ },
70
97
  disallowWebView: {
71
98
  type: Boolean,
72
99
  default: false
@@ -86,6 +113,51 @@ const UserSettingsSchema = new mongoose.Schema({
86
113
  }
87
114
  }
88
115
  }
116
+ },
117
+ spamEmailDomainCheckEnabled: {
118
+ type: Boolean,
119
+ default: false,
120
+ required: false
121
+ },
122
+ autoBanScoreThreshold: {
123
+ type: Number,
124
+ min: 0,
125
+ required: false
126
+ },
127
+ spamFilter: {
128
+ enabled: { type: Boolean, default: false },
129
+ emailRules: {
130
+ enabled: { type: Boolean, default: false },
131
+ maxLocalPartDots: { type: Number, required: false },
132
+ normaliseGmail: { type: Boolean, default: false },
133
+ useDefaultPatterns: { type: Boolean, default: false },
134
+ customRegexBlocklist: { type: [String], default: [] }
135
+ }
136
+ },
137
+ trafficFilter: {
138
+ blockVpn: { type: Boolean, default: false },
139
+ blockProxy: { type: Boolean, default: false },
140
+ blockTor: { type: Boolean, default: false },
141
+ blockAbuser: { type: Boolean, default: true },
142
+ abuserScoreThreshold: { type: Number, min: 0, max: 1, default: 0 },
143
+ blockDatacenter: { type: Boolean, default: false },
144
+ blockMobile: { type: Boolean, default: false },
145
+ blockSatellite: { type: Boolean, default: false },
146
+ blockCrawler: { type: Boolean, default: false }
147
+ },
148
+ storeMetadata: {
149
+ type: Boolean,
150
+ default: false,
151
+ required: false
152
+ },
153
+ honeypot: {
154
+ enabled: { type: Boolean, default: false },
155
+ question: { type: String, required: false },
156
+ encodingType: {
157
+ type: String,
158
+ enum: ["morse", "semaphore"],
159
+ default: "morse"
160
+ }
89
161
  }
90
162
  });
91
163
  const UserDataSchema = new mongoose.Schema({
@@ -5,26 +5,23 @@ const provider = require("./provider.cjs");
5
5
  const client = require("./client.cjs");
6
6
  const captcha = require("./captcha.cjs");
7
7
  require("./userAgent.cjs");
8
+ const spamEmailDomain = require("./spamEmailDomain.cjs");
9
+ const bannedDomain = require("./bannedDomain.cjs");
8
10
  exports.CaptchaRecordSchema = provider.CaptchaRecordSchema;
9
11
  exports.ClientContextEntropyRecordSchema = provider.ClientContextEntropyRecordSchema;
10
12
  exports.ClientRecordSchema = provider.ClientRecordSchema;
11
13
  exports.CompositeIpAddressRecordSchemaObj = provider.CompositeIpAddressRecordSchemaObj;
12
- exports.CompositeIpAddressSchema = provider.CompositeIpAddressSchema;
13
14
  exports.DatasetRecordSchema = provider.DatasetRecordSchema;
15
+ exports.DecisionMachineArtifactRecordSchema = provider.DecisionMachineArtifactRecordSchema;
14
16
  exports.DetectorRecordSchema = provider.DetectorRecordSchema;
15
- exports.IpAddressType = provider.IpAddressType;
16
- exports.PendingRecordSchema = provider.PendingRecordSchema;
17
17
  exports.PoWCaptchaRecordSchema = provider.PoWCaptchaRecordSchema;
18
+ exports.PuzzleCaptchaRecordSchema = provider.PuzzleCaptchaRecordSchema;
18
19
  exports.ScheduledTaskRecordSchema = provider.ScheduledTaskRecordSchema;
19
20
  exports.ScheduledTaskSchema = provider.ScheduledTaskSchema;
20
21
  exports.SessionRecordSchema = provider.SessionRecordSchema;
21
22
  exports.SolutionRecordSchema = provider.SolutionRecordSchema;
22
23
  exports.UserCommitmentRecordSchema = provider.UserCommitmentRecordSchema;
23
- exports.UserCommitmentSchema = provider.UserCommitmentSchema;
24
- exports.UserCommitmentWithSolutionsSchema = provider.UserCommitmentWithSolutionsSchema;
25
24
  exports.UserSolutionRecordSchema = provider.UserSolutionRecordSchema;
26
- exports.UserSolutionSchema = provider.UserSolutionSchema;
27
- exports.parseMongooseCompositeIpAddress = provider.parseMongooseCompositeIpAddress;
28
25
  exports.AccountSchema = client.AccountSchema;
29
26
  exports.IPValidationRulesSchema = client.IPValidationRulesSchema;
30
27
  exports.TableNames = client.TableNames;
@@ -33,3 +30,5 @@ exports.UserSettingsSchema = client.UserSettingsSchema;
33
30
  exports.StoredPoWCaptchaRecordSchema = captcha.StoredPoWCaptchaRecordSchema;
34
31
  exports.StoredSessionRecordSchema = captcha.StoredSessionRecordSchema;
35
32
  exports.StoredUserCommitmentRecordSchema = captcha.StoredUserCommitmentRecordSchema;
33
+ exports.SpamEmailDomainRecordSchema = spamEmailDomain.SpamEmailDomainRecordSchema;
34
+ exports.BannedDomainRecordSchema = bannedDomain.BannedDomainRecordSchema;
@@ -9,23 +9,12 @@ const ONE_HOUR = 60 * 60;
9
9
  const ONE_DAY = ONE_HOUR * 24;
10
10
  const ONE_WEEK = ONE_DAY * 7;
11
11
  const ONE_MONTH = ONE_WEEK * 4;
12
- const TEN_MINUTES = 10 * 60;
13
12
  const ClientRecordSchema = new mongoose.Schema({
14
13
  account: String,
15
14
  settings: client.UserSettingsSchema,
16
15
  tier: { type: String, enum: types.Tier, required: true }
17
16
  });
18
17
  ClientRecordSchema.index({ account: 1 });
19
- var IpAddressType = /* @__PURE__ */ ((IpAddressType2) => {
20
- IpAddressType2["v4"] = "v4";
21
- IpAddressType2["v6"] = "v6";
22
- return IpAddressType2;
23
- })(IpAddressType || {});
24
- const CompositeIpAddressSchema = zod.object({
25
- lower: zod.bigint(),
26
- upper: zod.bigint().optional(),
27
- type: zod.nativeEnum(IpAddressType)
28
- });
29
18
  const CompositeIpAddressRecordSchemaObj = {
30
19
  lower: {
31
20
  // INT64 isn't enough capable - it reserves extra bits for the sign bit, etc, so Decimal128 guarantees no overflow
@@ -41,40 +30,8 @@ const CompositeIpAddressRecordSchemaObj = {
41
30
  // without casting to string Mongoose not able to set bigint to Decimal128
42
31
  set: (value) => "bigint" === typeof value ? value.toString() : value
43
32
  },
44
- type: { type: String, enum: IpAddressType, required: true }
45
- };
46
- const parseMongooseCompositeIpAddress = (ip) => {
47
- return {
48
- lower: BigInt(ip.lower.$numberDecimal ?? ip.lower),
49
- upper: ip.upper ? BigInt(ip.upper?.$numberDecimal ?? ip.upper) : void 0,
50
- type: ip.type
51
- };
33
+ type: { type: String, enum: types.IpAddressType, required: true }
52
34
  };
53
- const CaptchaResultSchema = zod.object({
54
- status: zod.nativeEnum(types.CaptchaStatus),
55
- reason: locale.TranslationKeysSchema.optional(),
56
- error: zod.string().optional()
57
- });
58
- const UserCommitmentSchema = zod.object({
59
- userAccount: zod.string(),
60
- dappAccount: zod.string(),
61
- datasetId: zod.string(),
62
- providerAccount: zod.string(),
63
- id: zod.string(),
64
- result: CaptchaResultSchema,
65
- userSignature: zod.string(),
66
- ipAddress: CompositeIpAddressSchema,
67
- providedIp: CompositeIpAddressSchema.optional(),
68
- headers: zod.object({}).catchall(zod.string()),
69
- ja4: zod.string(),
70
- userSubmitted: zod.boolean(),
71
- serverChecked: zod.boolean(),
72
- storedAtTimestamp: zod.date().optional(),
73
- requestedAtTimestamp: zod.date(),
74
- lastUpdatedTimestamp: zod.date().optional(),
75
- sessionId: zod.string().optional(),
76
- coords: zod.array(zod.array(zod.array(zod.number()))).optional()
77
- });
78
35
  const CaptchaRecordSchema = new mongoose.Schema({
79
36
  captchaId: { type: String, required: true },
80
37
  captchaContentId: { type: String, required: true },
@@ -122,26 +79,171 @@ const PoWCaptchaRecordSchema = new mongoose.Schema({
122
79
  type: new mongoose.Schema(CompositeIpAddressRecordSchemaObj, { _id: false }),
123
80
  required: false
124
81
  },
82
+ metadata: {
83
+ type: new mongoose.Schema(
84
+ { email: { type: String, required: false } },
85
+ { _id: false }
86
+ ),
87
+ required: false
88
+ },
89
+ clientMetaData: {
90
+ type: new mongoose.Schema({ hp: { type: String, required: false } }, { _id: false }),
91
+ required: false
92
+ },
125
93
  headers: { type: Object, required: true },
126
94
  ja4: { type: String, required: true },
127
95
  userSignature: { type: String, required: false },
128
96
  userSubmitted: { type: Boolean, required: true },
129
97
  serverChecked: { type: Boolean, required: true },
130
98
  storedAtTimestamp: { type: Date, required: false, expires: ONE_MONTH },
131
- geolocation: { type: String, required: false },
132
- vpn: { type: Boolean, required: false },
99
+ // See `StoredCaptcha.pendingStage` `true` while the record has
100
+ // unstaged changes. Indexed via a tiny partial index so the
101
+ // StoreCommitmentsExternal sweep scans only pending rows instead of
102
+ // the whole collection.
103
+ pendingStage: { type: Boolean, required: false },
104
+ // Full ipinfo payload. Replaces the flat `vpn`, `countryCode`,
105
+ // `geolocation` and other per-flag fields — consumers narrow on
106
+ // `ipInfo.isValid` and read whichever sub-field they need.
107
+ ipInfo: { type: Object, required: false },
133
108
  parsedUserAgentInfo: { type: Object, required: false },
134
109
  sessionId: {
135
110
  type: String,
136
111
  required: false
137
112
  },
138
- coords: { type: [[[Number]]], required: false }
113
+ coords: { type: [[[Number]]], required: false },
114
+ // Current behavioral data storage format (packed)
115
+ deviceCapability: { type: String, required: false },
116
+ behavioralDataPacked: {
117
+ type: {
118
+ c1: { type: [mongoose.Schema.Types.Mixed], required: true },
119
+ c2: { type: [mongoose.Schema.Types.Mixed], required: true },
120
+ c3: { type: [mongoose.Schema.Types.Mixed], required: true },
121
+ d: { type: String, required: true }
122
+ },
123
+ required: false
124
+ },
125
+ providerSignature: { type: String, required: true },
126
+ // Internal ML labelling applied by superadmins via the audit page.
127
+ label: { type: String, enum: Object.values(types.CaptchaLabel), required: false },
128
+ labelReason: { type: String, required: false },
129
+ labelledBy: { type: String, required: false },
130
+ labelledAt: { type: Date, required: false }
139
131
  });
140
132
  PoWCaptchaRecordSchema.index({ challenge: 1 });
141
- PoWCaptchaRecordSchema.index({ storedAtTimestamp: 1, lastUpdatedTimestamp: 1 });
133
+ PoWCaptchaRecordSchema.index({ label: 1, dappAccount: 1 });
134
+ PoWCaptchaRecordSchema.index({ lastUpdatedTimestamp: 1 });
142
135
  PoWCaptchaRecordSchema.index({ dappAccount: 1, requestedAtTimestamp: 1 });
143
136
  PoWCaptchaRecordSchema.index({ "ipAddress.lower": 1 });
144
137
  PoWCaptchaRecordSchema.index({ "ipAddress.upper": 1 });
138
+ PoWCaptchaRecordSchema.index({ "result.reason": 1 });
139
+ PoWCaptchaRecordSchema.index({ "ipInfo.countryCode": 1 });
140
+ PoWCaptchaRecordSchema.index({ "ipInfo.isVPN": 1 });
141
+ PoWCaptchaRecordSchema.index({ ipInfo: 1 });
142
+ PoWCaptchaRecordSchema.index({ parsedUserAgentInfo: 1 });
143
+ PoWCaptchaRecordSchema.index(
144
+ { pendingStage: 1 },
145
+ {
146
+ name: "pendingStage_partial",
147
+ partialFilterExpression: { pendingStage: true }
148
+ }
149
+ );
150
+ const PuzzleCaptchaRecordSchema = new mongoose.Schema({
151
+ challenge: { type: String, required: true },
152
+ dappAccount: { type: String, required: true },
153
+ userAccount: { type: String, required: true },
154
+ requestedAtTimestamp: { type: Date, required: true },
155
+ lastUpdatedTimestamp: { type: Date, required: false },
156
+ result: {
157
+ status: { type: String, enum: types.CaptchaStatus, required: true },
158
+ reason: {
159
+ type: String,
160
+ enum: locale.TranslationKeysSchema.options,
161
+ required: false
162
+ },
163
+ error: { type: String, required: false }
164
+ },
165
+ targetX: { type: Number, required: true },
166
+ targetY: { type: Number, required: true },
167
+ originX: { type: Number, required: true },
168
+ originY: { type: Number, required: true },
169
+ tolerance: { type: Number, required: true },
170
+ puzzleEvents: {
171
+ type: [
172
+ new mongoose.Schema(
173
+ {
174
+ x: { type: Number, required: true },
175
+ y: { type: Number, required: true },
176
+ t: { type: Number, required: true }
177
+ },
178
+ { _id: false }
179
+ )
180
+ ],
181
+ required: false
182
+ },
183
+ ipAddress: CompositeIpAddressRecordSchemaObj,
184
+ providedIp: {
185
+ type: new mongoose.Schema(CompositeIpAddressRecordSchemaObj, { _id: false }),
186
+ required: false
187
+ },
188
+ metadata: {
189
+ type: new mongoose.Schema(
190
+ { email: { type: String, required: false } },
191
+ { _id: false }
192
+ ),
193
+ required: false
194
+ },
195
+ clientMetaData: {
196
+ type: new mongoose.Schema({ hp: { type: String, required: false } }, { _id: false }),
197
+ required: false
198
+ },
199
+ headers: { type: Object, required: true },
200
+ ja4: { type: String, required: true },
201
+ userSignature: { type: String, required: false },
202
+ userSubmitted: { type: Boolean, required: true },
203
+ serverChecked: { type: Boolean, required: true },
204
+ storedAtTimestamp: { type: Date, required: false, expires: ONE_MONTH },
205
+ // See `StoredCaptcha.pendingStage`.
206
+ pendingStage: { type: Boolean, required: false },
207
+ // Full ipinfo payload. Replaces the flat `vpn`, `countryCode`,
208
+ // `geolocation` and other per-flag fields — consumers narrow on
209
+ // `ipInfo.isValid` and read whichever sub-field they need.
210
+ ipInfo: { type: Object, required: false },
211
+ parsedUserAgentInfo: { type: Object, required: false },
212
+ sessionId: {
213
+ type: String,
214
+ required: false
215
+ },
216
+ coords: { type: [[[Number]]], required: false },
217
+ // Current behavioral data storage format (packed)
218
+ deviceCapability: { type: String, required: false },
219
+ behavioralDataPacked: {
220
+ type: {
221
+ c1: { type: [mongoose.Schema.Types.Mixed], required: true },
222
+ c2: { type: [mongoose.Schema.Types.Mixed], required: true },
223
+ c3: { type: [mongoose.Schema.Types.Mixed], required: true },
224
+ d: { type: String, required: true }
225
+ },
226
+ required: false
227
+ },
228
+ providerSignature: { type: String, required: true }
229
+ });
230
+ PuzzleCaptchaRecordSchema.index({ challenge: 1 });
231
+ PuzzleCaptchaRecordSchema.index({ lastUpdatedTimestamp: 1 });
232
+ PuzzleCaptchaRecordSchema.index({ dappAccount: 1, requestedAtTimestamp: 1 });
233
+ PuzzleCaptchaRecordSchema.index({ "ipAddress.lower": 1 });
234
+ PuzzleCaptchaRecordSchema.index({ "ipAddress.upper": 1 });
235
+ PuzzleCaptchaRecordSchema.index({ "result.reason": 1 });
236
+ PuzzleCaptchaRecordSchema.index({ "ipInfo.countryCode": 1 });
237
+ PuzzleCaptchaRecordSchema.index({ "ipInfo.isVPN": 1 });
238
+ PuzzleCaptchaRecordSchema.index({ ipInfo: 1 });
239
+ PuzzleCaptchaRecordSchema.index({ parsedUserAgentInfo: 1 });
240
+ PuzzleCaptchaRecordSchema.index(
241
+ { pendingStage: 1 },
242
+ {
243
+ name: "pendingStage_partial",
244
+ partialFilterExpression: { pendingStage: true }
245
+ }
246
+ );
145
247
  const UserCommitmentRecordSchema = new mongoose.Schema({
146
248
  userAccount: { type: String, required: true },
147
249
  dappAccount: { type: String, required: true },
@@ -162,6 +264,17 @@ const UserCommitmentRecordSchema = new mongoose.Schema({
162
264
  type: new mongoose.Schema(CompositeIpAddressRecordSchemaObj, { _id: false }),
163
265
  required: false
164
266
  },
267
+ metadata: {
268
+ type: new mongoose.Schema(
269
+ { email: { type: String, required: false } },
270
+ { _id: false }
271
+ ),
272
+ required: false
273
+ },
274
+ clientMetaData: {
275
+ type: new mongoose.Schema({ hp: { type: String, required: false } }, { _id: false }),
276
+ required: false
277
+ },
165
278
  headers: { type: Object, required: true },
166
279
  ja4: { type: String, required: true },
167
280
  userSignature: { type: String, required: true },
@@ -170,23 +283,63 @@ const UserCommitmentRecordSchema = new mongoose.Schema({
170
283
  storedAtTimestamp: { type: Date, required: false, expires: ONE_MONTH },
171
284
  requestedAtTimestamp: { type: Date, required: true },
172
285
  lastUpdatedTimestamp: { type: Date, required: false },
173
- geolocation: { type: String, required: false },
174
- vpn: { type: Boolean, required: false },
286
+ // See `StoredCaptcha.pendingStage`.
287
+ pendingStage: { type: Boolean, required: false },
288
+ // Full ipinfo payload. Replaces the flat `vpn`, `countryCode`,
289
+ // `geolocation` and other per-flag fields — consumers narrow on
290
+ // `ipInfo.isValid` and read whichever sub-field they need.
291
+ ipInfo: { type: Object, required: false },
175
292
  parsedUserAgentInfo: { type: Object, required: false },
176
293
  sessionId: {
177
294
  type: String,
178
295
  required: false
179
296
  },
180
- coords: { type: [[[Number]]], required: false }
297
+ coords: { type: [[[Number]]], required: false },
298
+ // Pending request fields for image captcha workflow
299
+ pending: { type: Boolean, required: true },
300
+ salt: { type: String, required: true },
301
+ requestHash: { type: String, required: true },
302
+ deadlineTimestamp: { type: Date, required: true },
303
+ threshold: { type: Number, required: true },
304
+ // Current behavioral data storage format (packed)
305
+ deviceCapability: { type: String, required: false },
306
+ behavioralDataPacked: {
307
+ type: {
308
+ c1: { type: [mongoose.Schema.Types.Mixed], required: true },
309
+ c2: { type: [mongoose.Schema.Types.Mixed], required: true },
310
+ c3: { type: [mongoose.Schema.Types.Mixed], required: true },
311
+ d: { type: String, required: true }
312
+ },
313
+ required: false
314
+ },
315
+ // Internal ML labelling applied by superadmins via the audit page.
316
+ label: { type: String, enum: Object.values(types.CaptchaLabel), required: false },
317
+ labelReason: { type: String, required: false },
318
+ labelledBy: { type: String, required: false },
319
+ labelledAt: { type: Date, required: false }
181
320
  });
182
321
  UserCommitmentRecordSchema.index({ id: -1 });
322
+ UserCommitmentRecordSchema.index({ label: 1, dappAccount: 1 });
183
323
  UserCommitmentRecordSchema.index({
184
- storedAtTimestamp: 1,
185
324
  lastUpdatedTimestamp: 1
186
325
  });
187
326
  UserCommitmentRecordSchema.index({ userAccount: 1, dappAccount: 1 });
188
327
  UserCommitmentRecordSchema.index({ "ipAddress.lower": 1 });
189
328
  UserCommitmentRecordSchema.index({ "ipAddress.upper": 1 });
329
+ UserCommitmentRecordSchema.index({ "result.reason": 1 });
330
+ UserCommitmentRecordSchema.index({ "ipInfo.countryCode": 1 });
331
+ UserCommitmentRecordSchema.index({ "ipInfo.isVPN": 1 });
332
+ UserCommitmentRecordSchema.index({ requestHash: -1 });
333
+ UserCommitmentRecordSchema.index({ pending: 1 });
334
+ UserCommitmentRecordSchema.index({ ipInfo: 1 });
335
+ UserCommitmentRecordSchema.index({ parsedUserAgentInfo: 1 });
336
+ UserCommitmentRecordSchema.index(
337
+ { pendingStage: 1 },
338
+ {
339
+ name: "pendingStage_partial",
340
+ partialFilterExpression: { pendingStage: true }
341
+ }
342
+ );
190
343
  const DatasetRecordSchema = new mongoose.Schema({
191
344
  contentTree: { type: [[String]], required: true },
192
345
  datasetContentId: { type: String, required: true },
@@ -204,12 +357,6 @@ const SolutionRecordSchema = new mongoose.Schema({
204
357
  solution: { type: [String], required: true }
205
358
  });
206
359
  SolutionRecordSchema.index({ captchaId: 1 });
207
- const UserSolutionSchema = types.CaptchaSolutionSchema.extend({
208
- processed: zod.boolean(),
209
- checked: zod.boolean(),
210
- commitmentId: zod.string(),
211
- createdAt: zod.date()
212
- });
213
360
  const UserSolutionRecordSchema = new mongoose.Schema(
214
361
  {
215
362
  captchaId: { type: String, required: true },
@@ -225,25 +372,6 @@ const UserSolutionRecordSchema = new mongoose.Schema(
225
372
  );
226
373
  UserSolutionRecordSchema.index({ captchaId: 1 });
227
374
  UserSolutionRecordSchema.index({ commitmentId: -1 });
228
- const UserCommitmentWithSolutionsSchema = UserCommitmentSchema.extend({
229
- captchas: zod.array(UserSolutionSchema)
230
- });
231
- const PendingRecordSchema = new mongoose.Schema({
232
- accountId: { type: String, required: true },
233
- pending: { type: Boolean, required: true },
234
- salt: { type: String, required: true },
235
- requestHash: { type: String, required: true },
236
- deadlineTimestamp: { type: Number, required: true },
237
- // unix timestamp
238
- requestedAtTimestamp: { type: Date, required: true, expires: ONE_WEEK },
239
- ipAddress: CompositeIpAddressRecordSchemaObj,
240
- sessionId: {
241
- type: String,
242
- required: false
243
- },
244
- threshold: { type: Number, required: true, default: 0.8 }
245
- });
246
- PendingRecordSchema.index({ requestHash: -1 });
247
375
  const ScheduledTaskSchema = zod.object({
248
376
  processName: zod.nativeEnum(types.ScheduledTaskNames),
249
377
  datetime: zod.date(),
@@ -285,28 +413,98 @@ const SessionRecordSchema = new mongoose.Schema({
285
413
  timeout: { type: Number, required: false },
286
414
  accessPolicy: { type: Number, required: false },
287
415
  unverifiedHost: { type: Number, required: false },
288
- webView: { type: Number, required: false }
416
+ webView: { type: Number, required: false },
417
+ triggeredDetectors: { type: [Number], required: false }
289
418
  },
290
419
  providerSelectEntropy: { type: Number, required: true },
291
420
  ipAddress: CompositeIpAddressRecordSchemaObj,
292
421
  captchaType: { type: String, enum: types.CaptchaType, required: true },
422
+ mode: { type: String, enum: types.ModeEnum, required: false },
293
423
  solvedImagesCount: { type: Number, required: false },
294
424
  powDifficulty: { type: Number, required: false },
295
425
  storedAtTimestamp: { type: Date, required: false, expires: ONE_DAY },
296
426
  lastUpdatedTimestamp: { type: Date, required: false },
427
+ // See `StoredCaptcha.pendingStage` — same semantics on Session records.
428
+ pendingStage: { type: Boolean, required: false },
297
429
  deleted: { type: Boolean, required: false },
298
430
  userSitekeyIpHash: { type: String, required: false },
299
431
  webView: { type: Boolean, required: true, default: false },
300
432
  iFrame: { type: Boolean, required: true, default: false },
301
433
  decryptedHeadHash: { type: String, required: false, default: "" },
302
- reason: { type: String, required: false }
434
+ siteKey: { type: String, required: false },
435
+ reason: { type: String, required: false },
436
+ blocked: { type: Boolean, required: false },
437
+ // Full ipinfo payload — replaces flat `countryCode` / `geolocation`
438
+ // fields. Mirrors the captcha record schemas (PoW / Puzzle /
439
+ // UserCommitment).
440
+ ipInfo: { type: Object, required: false },
441
+ headers: { type: Object, required: false },
442
+ result: {
443
+ type: new mongoose.Schema(
444
+ {
445
+ status: {
446
+ type: String,
447
+ enum: Object.values(types.CaptchaStatus),
448
+ required: true
449
+ },
450
+ reason: { type: String, required: false },
451
+ error: { type: String, required: false }
452
+ },
453
+ { _id: false }
454
+ ),
455
+ required: false
456
+ },
457
+ userSubmitted: { type: Boolean, required: false },
458
+ serverChecked: { type: Boolean, required: false },
459
+ // WASM SIMD CPU fingerprint readings collected by the catcher client.
460
+ // Stored as a free-form Mixed sub-document because the shape is a
461
+ // discriminated union and the dataset is still evolving — Zod validates
462
+ // at the boundary, Mongoose just persists it.
463
+ simdReadings: { type: mongoose.Schema.Types.Mixed, required: false },
464
+ // Stage at which the SIMD readings first arrived on this session
465
+ // (frictionless / challenge / submit). First-hop-wins.
466
+ simdReadingsStage: { type: String, required: false },
467
+ // DNS observation merge target. Populated by
468
+ // POST /v1/prosopo/provider/admin/dns/event from the dns-event
469
+ // sidecar (see types/provider/database.ts → Session.dnsEvent).
470
+ dnsEvent: {
471
+ type: new mongoose.Schema(
472
+ {
473
+ resolverIp: { type: String, required: false },
474
+ peerIp: { type: String, required: false },
475
+ pathValid: { type: Boolean, required: false },
476
+ receivedAt: { type: Date, required: true }
477
+ },
478
+ { _id: false }
479
+ ),
480
+ required: false
481
+ }
303
482
  });
304
483
  SessionRecordSchema.index({ createdAt: 1 });
305
484
  SessionRecordSchema.index({ deleted: 1 });
485
+ SessionRecordSchema.index({ blocked: 1 });
306
486
  SessionRecordSchema.index({ sessionId: 1 }, { unique: true });
307
487
  SessionRecordSchema.index({ userSitekeyIpHash: 1 });
308
488
  SessionRecordSchema.index({ providerSelectEntropy: 1 });
309
489
  SessionRecordSchema.index({ token: 1 });
490
+ SessionRecordSchema.index({ siteKey: 1 }, { background: true, sparse: true });
491
+ SessionRecordSchema.index({
492
+ createdAt: 1,
493
+ captchaType: 1,
494
+ "scoreComponents.baseScore": 1
495
+ });
496
+ SessionRecordSchema.index({ createdAt: 1, deleted: 1 });
497
+ SessionRecordSchema.index(
498
+ { "result.status": 1 },
499
+ { background: true, sparse: true }
500
+ );
501
+ SessionRecordSchema.index(
502
+ { pendingStage: 1 },
503
+ {
504
+ name: "pendingStage_partial",
505
+ partialFilterExpression: { pendingStage: true }
506
+ }
507
+ );
310
508
  const DetectorRecordSchema = new mongoose.Schema({
311
509
  createdAt: { type: Date, required: true },
312
510
  detectorKey: { type: String, required: true },
@@ -314,6 +512,39 @@ const DetectorRecordSchema = new mongoose.Schema({
314
512
  });
315
513
  DetectorRecordSchema.index({ createdAt: 1 }, { unique: true });
316
514
  DetectorRecordSchema.index({ expiresAt: 1 }, { expireAfterSeconds: 0 });
515
+ const DecisionMachineArtifactRecordSchema = new mongoose.Schema({
516
+ scope: {
517
+ type: String,
518
+ enum: Object.values(types.DecisionMachineScope),
519
+ required: true
520
+ },
521
+ dappAccount: { type: String, required: false },
522
+ runtime: {
523
+ type: String,
524
+ enum: Object.values(types.DecisionMachineRuntime),
525
+ required: true
526
+ },
527
+ language: {
528
+ type: String,
529
+ enum: Object.values(types.DecisionMachineLanguage),
530
+ required: false
531
+ },
532
+ source: { type: String, required: true },
533
+ name: { type: String, required: false },
534
+ version: { type: String, required: false },
535
+ captchaType: {
536
+ type: String,
537
+ enum: [types.CaptchaType.pow, types.CaptchaType.image],
538
+ required: false
539
+ },
540
+ createdAt: { type: Date, required: true },
541
+ updatedAt: { type: Date, required: true }
542
+ });
543
+ DecisionMachineArtifactRecordSchema.index(
544
+ { scope: 1, dappAccount: 1 },
545
+ { unique: true }
546
+ );
547
+ DecisionMachineArtifactRecordSchema.index({ updatedAt: -1 });
317
548
  const ClientContextEntropyRecordSchema = new mongoose.Schema(
318
549
  {
319
550
  account: { type: String, required: true },
@@ -334,19 +565,14 @@ exports.CaptchaRecordSchema = CaptchaRecordSchema;
334
565
  exports.ClientContextEntropyRecordSchema = ClientContextEntropyRecordSchema;
335
566
  exports.ClientRecordSchema = ClientRecordSchema;
336
567
  exports.CompositeIpAddressRecordSchemaObj = CompositeIpAddressRecordSchemaObj;
337
- exports.CompositeIpAddressSchema = CompositeIpAddressSchema;
338
568
  exports.DatasetRecordSchema = DatasetRecordSchema;
569
+ exports.DecisionMachineArtifactRecordSchema = DecisionMachineArtifactRecordSchema;
339
570
  exports.DetectorRecordSchema = DetectorRecordSchema;
340
- exports.IpAddressType = IpAddressType;
341
- exports.PendingRecordSchema = PendingRecordSchema;
342
571
  exports.PoWCaptchaRecordSchema = PoWCaptchaRecordSchema;
572
+ exports.PuzzleCaptchaRecordSchema = PuzzleCaptchaRecordSchema;
343
573
  exports.ScheduledTaskRecordSchema = ScheduledTaskRecordSchema;
344
574
  exports.ScheduledTaskSchema = ScheduledTaskSchema;
345
575
  exports.SessionRecordSchema = SessionRecordSchema;
346
576
  exports.SolutionRecordSchema = SolutionRecordSchema;
347
577
  exports.UserCommitmentRecordSchema = UserCommitmentRecordSchema;
348
- exports.UserCommitmentSchema = UserCommitmentSchema;
349
- exports.UserCommitmentWithSolutionsSchema = UserCommitmentWithSolutionsSchema;
350
578
  exports.UserSolutionRecordSchema = UserSolutionRecordSchema;
351
- exports.UserSolutionSchema = UserSolutionSchema;
352
- exports.parseMongooseCompositeIpAddress = parseMongooseCompositeIpAddress;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const mongoose = require("mongoose");
4
+ const SpamEmailDomainRecordSchema = new mongoose.Schema({
5
+ domain: { type: String, required: true, unique: true }
6
+ });
7
+ SpamEmailDomainRecordSchema.index({ domain: 1 });
8
+ exports.SpamEmailDomainRecordSchema = SpamEmailDomainRecordSchema;
@@ -0,0 +1,2 @@
1
+ export * from "./types/index.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,cAAc,kBAAkB,CAAC"}