@prosopo/user-access-policy 3.12.7 → 3.12.9

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 (96) hide show
  1. package/.turbo/turbo-build$colon$cjs.log +45 -41
  2. package/.turbo/turbo-build$colon$tsc.log +14 -14
  3. package/.turbo/turbo-build.log +46 -42
  4. package/CHANGELOG.md +40 -0
  5. package/dist/.export.js +7 -21
  6. package/dist/_virtual/_rolldown/runtime.js +3 -0
  7. package/dist/api/.export.js +2 -9
  8. package/dist/api/accessRulesApiClient.js +1 -1
  9. package/dist/api/delete/.export.js +2 -1
  10. package/dist/api/delete/deleteAllRules.js +22 -24
  11. package/dist/api/delete/deleteRuleGroups.js +39 -51
  12. package/dist/api/delete/deleteRules.js +37 -41
  13. package/dist/api/read/.export.js +2 -1
  14. package/dist/api/read/fetchRules.js +34 -42
  15. package/dist/api/read/findRuleIds.js +35 -48
  16. package/dist/api/read/getMissingIds.js +36 -40
  17. package/dist/api/ruleApiRoutes.js +62 -120
  18. package/dist/api/rulesApiClient.js +51 -87
  19. package/dist/api/write/.export.js +2 -1
  20. package/dist/api/write/insertRules.js +84 -102
  21. package/dist/api/write/rehashRules.js +48 -56
  22. package/dist/cjs/.export.cjs +21 -23
  23. package/dist/cjs/_virtual/_rolldown/runtime.cjs +23 -0
  24. package/dist/cjs/api/.export.cjs +6 -10
  25. package/dist/cjs/api/accessRulesApiClient.cjs +0 -0
  26. package/dist/cjs/api/delete/.export.cjs +0 -1
  27. package/dist/cjs/api/delete/deleteAllRules.cjs +22 -24
  28. package/dist/cjs/api/delete/deleteRuleGroups.cjs +39 -51
  29. package/dist/cjs/api/delete/deleteRules.cjs +41 -42
  30. package/dist/cjs/api/read/.export.cjs +0 -1
  31. package/dist/cjs/api/read/fetchRules.cjs +34 -41
  32. package/dist/cjs/api/read/findRuleIds.cjs +37 -48
  33. package/dist/cjs/api/read/getMissingIds.cjs +36 -39
  34. package/dist/cjs/api/ruleApiRoutes.cjs +69 -125
  35. package/dist/cjs/api/rulesApiClient.cjs +54 -90
  36. package/dist/cjs/api/write/.export.cjs +0 -1
  37. package/dist/cjs/api/write/insertRules.cjs +85 -103
  38. package/dist/cjs/api/write/rehashRules.cjs +48 -56
  39. package/dist/cjs/classifyOs.cjs +46 -26
  40. package/dist/cjs/mongoose/.export.cjs +2 -3
  41. package/dist/cjs/mongoose/mongooseRuleSchema.cjs +97 -36
  42. package/dist/cjs/redis/.export.cjs +4 -5
  43. package/dist/cjs/redis/reader/redisAggregate.cjs +59 -84
  44. package/dist/cjs/redis/reader/redisRulesQuery.cjs +74 -116
  45. package/dist/cjs/redis/reader/redisRulesReader.cjs +322 -503
  46. package/dist/cjs/redis/reader/redisRulesSplitQuery.cjs +94 -72
  47. package/dist/cjs/redis/redisClient.cjs +53 -58
  48. package/dist/cjs/redis/redisRuleIndex.cjs +93 -49
  49. package/dist/cjs/redis/redisRulesStorage.cjs +21 -30
  50. package/dist/cjs/redis/redisRulesWriter.cjs +86 -112
  51. package/dist/cjs/rule.cjs +8 -7
  52. package/dist/cjs/ruleInput/.export.cjs +7 -8
  53. package/dist/cjs/ruleInput/policyInput.cjs +36 -39
  54. package/dist/cjs/ruleInput/ruleInput.cjs +37 -42
  55. package/dist/cjs/ruleInput/userScopeInput.cjs +47 -55
  56. package/dist/cjs/ruleRecord.cjs +15 -22
  57. package/dist/cjs/rulesStorage.cjs +7 -6
  58. package/dist/cjs/transformRule.cjs +36 -70
  59. package/dist/classifyOs.js +48 -29
  60. package/dist/mongoose/.export.js +2 -3
  61. package/dist/mongoose/mongooseRuleSchema.js +99 -38
  62. package/dist/redis/.export.js +3 -5
  63. package/dist/redis/reader/redisAggregate.js +60 -86
  64. package/dist/redis/reader/redisRulesQuery.js +75 -118
  65. package/dist/redis/reader/redisRulesReader.js +312 -487
  66. package/dist/redis/reader/redisRulesSplitQuery.js +96 -75
  67. package/dist/redis/redisClient.js +54 -62
  68. package/dist/redis/redisRuleIndex.js +93 -58
  69. package/dist/redis/redisRulesStorage.js +21 -30
  70. package/dist/redis/redisRulesWriter.js +82 -113
  71. package/dist/rule.js +10 -10
  72. package/dist/ruleInput/.export.js +3 -7
  73. package/dist/ruleInput/policyInput.d.ts +52 -1
  74. package/dist/ruleInput/policyInput.d.ts.map +1 -1
  75. package/dist/ruleInput/policyInput.js +35 -41
  76. package/dist/ruleInput/policyInput.js.map +1 -1
  77. package/dist/ruleInput/ruleInput.d.ts.map +1 -1
  78. package/dist/ruleInput/ruleInput.js +36 -44
  79. package/dist/ruleInput/ruleInput.js.map +1 -1
  80. package/dist/ruleInput/userScopeInput.js +44 -55
  81. package/dist/ruleRecord.js +17 -27
  82. package/dist/rulesStorage.js +9 -8
  83. package/dist/tests/policyInput.unit.test.js +50 -1
  84. package/dist/tests/policyInput.unit.test.js.map +1 -1
  85. package/dist/tests/redis/redisRulesStorage.integration.test.js +22 -3
  86. package/dist/tests/redis/redisRulesStorage.integration.test.js.map +1 -1
  87. package/dist/transformRule.js +34 -73
  88. package/dist/transformRule.js.map +1 -1
  89. package/entries.ts +25 -6
  90. package/package.json +13 -12
  91. package/src/ruleInput/policyInput.ts +45 -2
  92. package/src/ruleInput/ruleInput.ts +10 -3
  93. package/src/tests/policyInput.unit.test.ts +69 -1
  94. package/src/tests/redis/redisRulesStorage.integration.test.ts +191 -148
  95. package/src/transformRule.ts +2 -2
  96. package/tsconfig.tsbuildinfo +1 -1
@@ -1,117 +1,91 @@
1
- "use strict";
2
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const common = require("@prosopo/common");
4
- const redisClient = require("./redisClient.cjs");
5
- const rule = require("../rule.cjs");
6
- const redisRuleIndex = require("./redisRuleIndex.cjs");
7
- class RedisRulesWriter {
8
- constructor(client, logger) {
9
- this.client = client;
10
- this.logger = logger;
11
- }
12
- async insertRules(ruleEntries) {
13
- const entryBatches = common.chunkIntoBatches(ruleEntries, redisClient.REDIS_BATCH_SIZE);
14
- const keyBatches = await common.executeBatchesSequentially(
15
- entryBatches,
16
- async (entriesBatch) => this.insertRuleEntries(entriesBatch)
17
- );
18
- return keyBatches.flatMap(
19
- (ruleKey) => ruleKey.slice(redisRuleIndex.ACCESS_RULE_REDIS_KEY_PREFIX.length)
20
- );
21
- }
22
- async deleteRules(ruleIds) {
23
- const ruleKeys = ruleIds.map(
24
- (ruleId) => redisRuleIndex.ACCESS_RULE_REDIS_KEY_PREFIX + ruleId
25
- );
26
- const keyBatches = common.chunkIntoBatches(ruleKeys, redisClient.REDIS_BATCH_SIZE);
27
- await common.executeBatchesSequentially(keyBatches, async (keysBatch) => {
28
- const queries = this.client.multi();
29
- for (const ruleKey of keysBatch) {
30
- queries.del(ruleKey);
31
- }
32
- await queries.exec();
33
- });
34
- }
35
- async deleteAllRules() {
36
- let cursor = "0";
37
- let total = 0;
38
- do {
39
- const reply = await this.client.scan(cursor, {
40
- MATCH: `${redisRuleIndex.ACCESS_RULE_REDIS_KEY_PREFIX}*`,
41
- COUNT: redisClient.REDIS_BATCH_SIZE
42
- });
43
- const ids = reply.keys.map(
44
- (key) => key.slice(redisRuleIndex.ACCESS_RULE_REDIS_KEY_PREFIX.length)
45
- );
46
- await this.deleteRules(ids);
47
- total += ids.length;
48
- cursor = reply.cursor;
49
- } while ("0" !== cursor);
50
- return total;
51
- }
52
- async insertRuleEntries(ruleEntries) {
53
- const queries = this.client.multi();
54
- const ruleKeys = ruleEntries.map((ruleEntry) => {
55
- const { rule: rule2, expiresUnixTimestamp } = ruleEntry;
56
- const ruleKey = redisRuleIndex.getAccessRuleRedisKey(rule2);
57
- const ruleValue = getRedisRuleValue(rule2);
58
- queries.hSet(ruleKey, ruleValue);
59
- if (expiresUnixTimestamp) {
60
- const MILLISECOND_THRESHOLD = 1e10;
61
- if (expiresUnixTimestamp > MILLISECOND_THRESHOLD) {
62
- throw new Error(
63
- `Invalid expiry timestamp: ${expiresUnixTimestamp}. Timestamp must be in seconds, not milliseconds.`
64
- );
65
- }
66
- queries.expireAt(ruleKey, expiresUnixTimestamp);
67
- }
68
- return ruleKey;
69
- });
70
- await queries.exec();
71
- return ruleKeys;
72
- }
73
- }
74
- const getRedisRuleValue = (rule$1) => {
75
- const record = {};
76
- for (const [key, value] of Object.entries(rule$1)) {
77
- if (value === void 0) {
78
- continue;
79
- }
80
- record[key] = String(value);
81
- }
82
- if (record.clientId === void 0) {
83
- record.clientId = rule.GLOBAL_CLIENT_SCOPE_SENTINEL;
84
- }
85
- return record;
2
+ const require_rule = require("../rule.cjs");
3
+ const require_redis_redisClient = require("./redisClient.cjs");
4
+ const require_redis_redisRuleIndex = require("./redisRuleIndex.cjs");
5
+ let _prosopo_common = require("@prosopo/common");
6
+ //#region src/redis/redisRulesWriter.ts
7
+ var RedisRulesWriter = class {
8
+ constructor(client, logger) {
9
+ this.client = client;
10
+ this.logger = logger;
11
+ }
12
+ async insertRules(ruleEntries) {
13
+ const entryBatches = (0, _prosopo_common.chunkIntoBatches)(ruleEntries, require_redis_redisClient.REDIS_BATCH_SIZE);
14
+ return (await (0, _prosopo_common.executeBatchesSequentially)(entryBatches, async (entriesBatch) => this.insertRuleEntries(entriesBatch))).flatMap((ruleKey) => ruleKey.slice(require_redis_redisRuleIndex.ACCESS_RULE_REDIS_KEY_PREFIX.length));
15
+ }
16
+ async deleteRules(ruleIds) {
17
+ const ruleKeys = ruleIds.map((ruleId) => require_redis_redisRuleIndex.ACCESS_RULE_REDIS_KEY_PREFIX + ruleId);
18
+ const keyBatches = (0, _prosopo_common.chunkIntoBatches)(ruleKeys, require_redis_redisClient.REDIS_BATCH_SIZE);
19
+ await (0, _prosopo_common.executeBatchesSequentially)(keyBatches, async (keysBatch) => {
20
+ const queries = this.client.multi();
21
+ for (const ruleKey of keysBatch) queries.del(ruleKey);
22
+ await queries.exec();
23
+ });
24
+ }
25
+ async deleteAllRules() {
26
+ let cursor = "0";
27
+ let total = 0;
28
+ do {
29
+ const reply = await this.client.scan(cursor, {
30
+ MATCH: `${require_redis_redisRuleIndex.ACCESS_RULE_REDIS_KEY_PREFIX}*`,
31
+ COUNT: require_redis_redisClient.REDIS_BATCH_SIZE
32
+ });
33
+ const ids = reply.keys.map((key) => key.slice(require_redis_redisRuleIndex.ACCESS_RULE_REDIS_KEY_PREFIX.length));
34
+ await this.deleteRules(ids);
35
+ total += ids.length;
36
+ cursor = reply.cursor;
37
+ } while ("0" !== cursor);
38
+ return total;
39
+ }
40
+ async insertRuleEntries(ruleEntries) {
41
+ const queries = this.client.multi();
42
+ const ruleKeys = ruleEntries.map((ruleEntry) => {
43
+ const { rule, expiresUnixTimestamp } = ruleEntry;
44
+ const ruleKey = require_redis_redisRuleIndex.getAccessRuleRedisKey(rule);
45
+ const ruleValue = getRedisRuleValue(rule);
46
+ queries.hSet(ruleKey, ruleValue);
47
+ if (expiresUnixTimestamp) {
48
+ if (expiresUnixTimestamp > 1e10) throw new Error(`Invalid expiry timestamp: ${expiresUnixTimestamp}. Timestamp must be in seconds, not milliseconds.`);
49
+ queries.expireAt(ruleKey, expiresUnixTimestamp);
50
+ }
51
+ return ruleKey;
52
+ });
53
+ await queries.exec();
54
+ return ruleKeys;
55
+ }
86
56
  };
87
- class DummyRedisRulesWriter {
88
- constructor(logger) {
89
- this.logger = logger;
90
- }
91
- async insertRules(ruleEntries) {
92
- this.logger.info(() => ({
93
- msg: "Dummy insertRules() has no effect (redis is not ready)",
94
- data: {
95
- ruleEntries
96
- }
97
- }));
98
- return [];
99
- }
100
- async deleteRules(ruleIds) {
101
- this.logger.info(() => ({
102
- msg: "Dummy deleteRules() has no effect (redis is not ready)",
103
- data: {
104
- ruleIds
105
- }
106
- }));
107
- }
108
- async deleteAllRules() {
109
- this.logger.info(() => ({
110
- msg: "Dummy deleteAllRules() has no effect (redis is not ready)"
111
- }));
112
- return 0;
113
- }
114
- }
57
+ var getRedisRuleValue = (rule) => {
58
+ const record = {};
59
+ for (const [key, value] of Object.entries(rule)) {
60
+ if (value === void 0) continue;
61
+ record[key] = String(value);
62
+ }
63
+ if (record.clientId === void 0) record.clientId = require_rule.GLOBAL_CLIENT_SCOPE_SENTINEL;
64
+ return record;
65
+ };
66
+ var DummyRedisRulesWriter = class {
67
+ constructor(logger) {
68
+ this.logger = logger;
69
+ }
70
+ async insertRules(ruleEntries) {
71
+ this.logger.info(() => ({
72
+ msg: "Dummy insertRules() has no effect (redis is not ready)",
73
+ data: { ruleEntries }
74
+ }));
75
+ return [];
76
+ }
77
+ async deleteRules(ruleIds) {
78
+ this.logger.info(() => ({
79
+ msg: "Dummy deleteRules() has no effect (redis is not ready)",
80
+ data: { ruleIds }
81
+ }));
82
+ }
83
+ async deleteAllRules() {
84
+ this.logger.info(() => ({ msg: "Dummy deleteAllRules() has no effect (redis is not ready)" }));
85
+ return 0;
86
+ }
87
+ };
88
+ //#endregion
115
89
  exports.DummyRedisRulesWriter = DummyRedisRulesWriter;
116
90
  exports.RedisRulesWriter = RedisRulesWriter;
117
91
  exports.getRedisRuleValue = getRedisRuleValue;
package/dist/cjs/rule.cjs CHANGED
@@ -1,10 +1,11 @@
1
- "use strict";
2
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- var AccessPolicyType = /* @__PURE__ */ ((AccessPolicyType2) => {
4
- AccessPolicyType2["Block"] = "block";
5
- AccessPolicyType2["Restrict"] = "restrict";
6
- return AccessPolicyType2;
7
- })(AccessPolicyType || {});
8
- const GLOBAL_CLIENT_SCOPE_SENTINEL = "global";
2
+ //#region src/rule.ts
3
+ var AccessPolicyType = /* @__PURE__ */ function(AccessPolicyType) {
4
+ AccessPolicyType["Block"] = "block";
5
+ AccessPolicyType["Restrict"] = "restrict";
6
+ return AccessPolicyType;
7
+ }({});
8
+ var GLOBAL_CLIENT_SCOPE_SENTINEL = "global";
9
+ //#endregion
9
10
  exports.AccessPolicyType = AccessPolicyType;
10
11
  exports.GLOBAL_CLIENT_SCOPE_SENTINEL = GLOBAL_CLIENT_SCOPE_SENTINEL;
@@ -1,9 +1,8 @@
1
- "use strict";
2
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const ruleInput = require("./ruleInput.cjs");
4
- const policyInput = require("./policyInput.cjs");
5
- const userScopeInput = require("./userScopeInput.cjs");
6
- exports.accessRuleInput = ruleInput.accessRuleInput;
7
- exports.accessPolicyInput = policyInput.accessPolicyInput;
8
- exports.policyScopeInput = policyInput.policyScopeInput;
9
- exports.userScopeInput = userScopeInput.userScopeInput;
2
+ const require_ruleInput_policyInput = require("./policyInput.cjs");
3
+ const require_ruleInput_userScopeInput = require("./userScopeInput.cjs");
4
+ const require_ruleInput_ruleInput = require("./ruleInput.cjs");
5
+ exports.accessPolicyInput = require_ruleInput_policyInput.accessPolicyInput;
6
+ exports.accessRuleInput = require_ruleInput_ruleInput.accessRuleInput;
7
+ exports.policyScopeInput = require_ruleInput_policyInput.policyScopeInput;
8
+ exports.userScopeInput = require_ruleInput_userScopeInput.userScopeInput;
@@ -1,45 +1,42 @@
1
- "use strict";
2
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const types = require("@prosopo/types");
4
- const zod = require("zod");
5
- const rule = require("../rule.cjs");
6
- const accessPolicyInput = zod.z.object({
7
- type: zod.z.nativeEnum(rule.AccessPolicyType),
8
- captchaType: types.CaptchaTypeSchema.optional(),
9
- description: zod.z.coerce.string().optional(),
10
- // Redis stores values as strings, so coerce is needed to parse properly
11
- solvedImagesCount: zod.z.coerce.number().optional(),
12
- // the percentage of image panels that must be solved per image CAPTCHA
13
- imageThreshold: zod.z.coerce.number().optional(),
14
- // the Proof-of-Work difficulty level
15
- powDifficulty: zod.z.coerce.number().optional(),
16
- // the number of unsolved image CAPTCHA challenges to serve
17
- unsolvedImagesCount: zod.z.coerce.number().optional(),
18
- // used to increase the user's score
19
- frictionlessScore: zod.z.coerce.number().optional(),
20
- // Skip the request-time block middleware and only fire at verify.
21
- // Redis stores booleans as strings — preprocess so "true"/"false"
22
- // round-trip to the JS boolean the matcher expects.
23
- deferToVerify: zod.z.preprocess((v) => typeof v === "string" ? v === "true" : v, zod.z.boolean()).optional()
2
+ const require_rule = require("../rule.cjs");
3
+ let zod = require("zod");
4
+ let _prosopo_types = require("@prosopo/types");
5
+ //#region src/ruleInput/policyInput.ts
6
+ var accessPolicyInputShape = zod.z.object({
7
+ type: zod.z.nativeEnum(require_rule.AccessPolicyType),
8
+ captchaType: _prosopo_types.CaptchaTypeSchema.optional(),
9
+ description: zod.z.coerce.string().optional(),
10
+ solvedImagesCount: zod.z.coerce.number().optional(),
11
+ imageThreshold: zod.z.coerce.number().optional(),
12
+ powDifficulty: zod.z.coerce.number().optional(),
13
+ unsolvedImagesCount: zod.z.coerce.number().optional(),
14
+ frictionlessScore: zod.z.coerce.number().optional(),
15
+ deferToVerify: zod.z.preprocess((v) => typeof v === "string" ? v === "true" : v, zod.z.boolean()).optional()
24
16
  });
25
- const sanitizeAccessPolicy = (policy) => {
26
- if (policy.type === rule.AccessPolicyType.Block) {
27
- const { captchaType, solvedImagesCount, ...blockPolicy } = policy;
28
- return blockPolicy;
29
- }
30
- return policy;
31
- };
32
- const policyScopeInput = zod.z.object({
33
- // `getRedisRuleValue` stamps a sentinel string on global rules so the
34
- // read-time query can probe `@clientId:{global}` cheaply. Undo the
35
- // stamp here so consumers (rankCandidateRules, response payloads,
36
- // tests) continue to see `undefined` for global rules — the mongoose
37
- // side and the API input side never emit the sentinel.
38
- clientId: zod.z.preprocess(
39
- (v) => v === rule.GLOBAL_CLIENT_SCOPE_SENTINEL ? void 0 : v,
40
- zod.z.coerce.string().optional()
41
- )
17
+ var accessPolicyInput = accessPolicyInputShape.superRefine((policy, ctx) => {
18
+ if (policy.type !== require_rule.AccessPolicyType.Block) return;
19
+ if (policy.captchaType !== void 0) ctx.addIssue({
20
+ code: zod.z.ZodIssueCode.custom,
21
+ path: ["captchaType"],
22
+ message: "Block policies cannot pin a captchaType — Block always applies to every captcha type. Use a Restrict policy if you want to narrow the effect to one captcha type."
23
+ });
24
+ if (policy.solvedImagesCount !== void 0) ctx.addIssue({
25
+ code: zod.z.ZodIssueCode.custom,
26
+ path: ["solvedImagesCount"],
27
+ message: "Block policies cannot set solvedImagesCount — the field only applies to Restrict policies that adjust image-captcha rounds."
28
+ });
42
29
  });
30
+ var sanitizeAccessPolicy = (policy) => {
31
+ if (policy.type === require_rule.AccessPolicyType.Block) {
32
+ const { captchaType, solvedImagesCount, ...blockPolicy } = policy;
33
+ return blockPolicy;
34
+ }
35
+ return policy;
36
+ };
37
+ var policyScopeInput = zod.z.object({ clientId: zod.z.preprocess((v) => v === "global" ? void 0 : v, zod.z.coerce.string().optional()) });
38
+ //#endregion
43
39
  exports.accessPolicyInput = accessPolicyInput;
40
+ exports.accessPolicyInputShape = accessPolicyInputShape;
44
41
  exports.policyScopeInput = policyScopeInput;
45
42
  exports.sanitizeAccessPolicy = sanitizeAccessPolicy;
@@ -1,50 +1,45 @@
1
- "use strict";
2
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const zod = require("zod");
4
- const rulesStorage = require("../rulesStorage.cjs");
5
- const policyInput = require("./policyInput.cjs");
6
- const userScopeInput = require("./userScopeInput.cjs");
7
- const ruleGroupInput = zod.z.object({
8
- groupId: zod.z.coerce.string().optional(),
9
- ruleGroupId: zod.z.coerce.string().optional()
10
- }).transform((ruleGroupInput2) => {
11
- const { ruleGroupId, ...ruleGroup } = ruleGroupInput2;
12
- if ("string" === typeof ruleGroupId) {
13
- ruleGroup.groupId = ruleGroupId;
14
- }
15
- return ruleGroup;
2
+ const require_rulesStorage = require("../rulesStorage.cjs");
3
+ const require_ruleInput_policyInput = require("./policyInput.cjs");
4
+ const require_ruleInput_userScopeInput = require("./userScopeInput.cjs");
5
+ let zod = require("zod");
6
+ //#region src/ruleInput/ruleInput.ts
7
+ var ruleGroupInput = zod.z.object({
8
+ groupId: zod.z.coerce.string().optional(),
9
+ ruleGroupId: zod.z.coerce.string().optional()
10
+ }).transform((ruleGroupInput) => {
11
+ const { ruleGroupId, ...ruleGroup } = ruleGroupInput;
12
+ if ("string" === typeof ruleGroupId) ruleGroup.groupId = ruleGroupId;
13
+ return ruleGroup;
16
14
  });
17
- const accessRuleInput = zod.z.object({
18
- ...policyInput.accessPolicyInput.shape,
19
- ...policyInput.policyScopeInput.shape
20
- }).and(userScopeInput.userScopeInput).and(ruleGroupInput).transform((ruleInput) => ruleInput);
21
- const ruleEntryInput = zod.z.object({
22
- rule: accessRuleInput,
23
- expiresUnixTimestamp: zod.z.coerce.number().optional()
15
+ var accessRuleInput = zod.z.object({
16
+ ...require_ruleInput_policyInput.accessPolicyInputShape.shape,
17
+ ...require_ruleInput_policyInput.policyScopeInput.shape
18
+ }).and(require_ruleInput_userScopeInput.userScopeInput).and(ruleGroupInput).transform((ruleInput) => ruleInput);
19
+ var ruleEntryInput = zod.z.object({
20
+ rule: accessRuleInput,
21
+ expiresUnixTimestamp: zod.z.coerce.number().optional()
24
22
  });
25
- const accessRulesFilterInput = zod.z.object({
26
- policyScope: policyInput.policyScopeInput.optional(),
27
- policyScopes: zod.z.array(policyInput.policyScopeInput).optional(),
28
- policyScopeMatch: zod.z.nativeEnum(rulesStorage.FilterScopeMatch).default(rulesStorage.FilterScopeMatch.Exact),
29
- userScope: userScopeInput.userScopeInput.optional(),
30
- userScopeMatch: zod.z.nativeEnum(rulesStorage.FilterScopeMatch).default(rulesStorage.FilterScopeMatch.Exact),
31
- groupId: zod.z.string().optional(),
32
- blockOnly: zod.z.boolean().optional()
23
+ var accessRulesFilterInput = zod.z.object({
24
+ policyScope: require_ruleInput_policyInput.policyScopeInput.optional(),
25
+ policyScopes: zod.z.array(require_ruleInput_policyInput.policyScopeInput).optional(),
26
+ policyScopeMatch: zod.z.nativeEnum(require_rulesStorage.FilterScopeMatch).default(require_rulesStorage.FilterScopeMatch.Exact),
27
+ userScope: require_ruleInput_userScopeInput.userScopeInput.optional(),
28
+ userScopeMatch: zod.z.nativeEnum(require_rulesStorage.FilterScopeMatch).default(require_rulesStorage.FilterScopeMatch.Exact),
29
+ groupId: zod.z.string().optional(),
30
+ blockOnly: zod.z.boolean().optional()
33
31
  });
34
- const getAccessRuleFiltersFromInput = (filterInput) => {
35
- const { policyScopes, policyScope, ...filterBase } = filterInput;
36
- const allPolicyScopes = policyScopes || [];
37
- if (policyScope) {
38
- allPolicyScopes.push(policyScope);
39
- }
40
- if (allPolicyScopes.length > 0) {
41
- return allPolicyScopes.map((policyScope2) => ({
42
- ...filterBase,
43
- policyScope: policyScope2
44
- }));
45
- }
46
- return [filterBase];
32
+ var getAccessRuleFiltersFromInput = (filterInput) => {
33
+ const { policyScopes, policyScope, ...filterBase } = filterInput;
34
+ const allPolicyScopes = policyScopes || [];
35
+ if (policyScope) allPolicyScopes.push(policyScope);
36
+ if (allPolicyScopes.length > 0) return allPolicyScopes.map((policyScope) => ({
37
+ ...filterBase,
38
+ policyScope
39
+ }));
40
+ return [filterBase];
47
41
  };
42
+ //#endregion
48
43
  exports.accessRuleInput = accessRuleInput;
49
44
  exports.accessRulesFilterInput = accessRulesFilterInput;
50
45
  exports.getAccessRuleFiltersFromInput = getAccessRuleFiltersFromInput;
@@ -1,63 +1,55 @@
1
- "use strict";
2
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const crypto = require("node:crypto");
4
- const util = require("@prosopo/util");
5
- const ipAddress = require("ip-address");
6
- const zod = require("zod");
7
- const userAttributesSchema = zod.z.object({
8
- // coerce is used for safety, as e.g., incoming userId can be digital
9
- userId: zod.z.coerce.string().optional(),
10
- ja4Hash: zod.z.coerce.string().optional(),
11
- headersHash: zod.z.coerce.string().optional(),
12
- userAgentHash: zod.z.coerce.string().optional(),
13
- headHash: zod.z.coerce.string().optional(),
14
- coords: zod.z.coerce.string().optional(),
15
- countryCode: zod.z.coerce.string().optional(),
16
- asn: zod.z.coerce.number().int().nonnegative().optional(),
17
- // Plain lowercase OS tag (see `classifyOs`). Loose `string` like
18
- // countryCode: a stale/unknown value just never matches a request rather
19
- // than failing the whole rule parse.
20
- os: zod.z.coerce.string().optional()
2
+ const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
3
+ let zod = require("zod");
4
+ let node_crypto = require("node:crypto");
5
+ node_crypto = require_runtime.__toESM(node_crypto, 1);
6
+ let _prosopo_util = require("@prosopo/util");
7
+ let ip_address = require("ip-address");
8
+ //#region src/ruleInput/userScopeInput.ts
9
+ var userAttributesSchema = zod.z.object({
10
+ userId: zod.z.coerce.string().optional(),
11
+ ja4Hash: zod.z.coerce.string().optional(),
12
+ headersHash: zod.z.coerce.string().optional(),
13
+ userAgentHash: zod.z.coerce.string().optional(),
14
+ headHash: zod.z.coerce.string().optional(),
15
+ coords: zod.z.coerce.string().optional(),
16
+ countryCode: zod.z.coerce.string().optional(),
17
+ asn: zod.z.coerce.number().int().nonnegative().optional(),
18
+ os: zod.z.coerce.string().optional()
21
19
  });
22
- const userAttributesInput = zod.z.object({
23
- ...userAttributesSchema.shape,
24
- userAgent: zod.z.coerce.string().optional()
25
- }).transform((userAttributesInput2) => {
26
- const { userAgent, ...userScope } = userAttributesInput2;
27
- if ("string" === typeof userAgent) {
28
- userScope.userAgentHash = hashUserAgent(userAgent);
29
- }
30
- return userScope;
20
+ var userAttributesInput = zod.z.object({
21
+ ...userAttributesSchema.shape,
22
+ userAgent: zod.z.coerce.string().optional()
23
+ }).transform((userAttributesInput) => {
24
+ const { userAgent, ...userScope } = userAttributesInput;
25
+ if ("string" === typeof userAgent) userScope.userAgentHash = hashUserAgent(userAgent);
26
+ return userScope;
31
27
  });
32
- const hashUserAgent = (userAgent) => crypto.createHash("sha256").update(userAgent).digest("hex");
33
- const userIpSchema = zod.z.object({
34
- numericIp: zod.z.coerce.bigint().optional(),
35
- numericIpMaskMin: zod.z.coerce.bigint().optional(),
36
- numericIpMaskMax: zod.z.coerce.bigint().optional()
28
+ var hashUserAgent = (userAgent) => node_crypto.default.createHash("sha256").update(userAgent).digest("hex");
29
+ var userIpSchema = zod.z.object({
30
+ numericIp: zod.z.coerce.bigint().optional(),
31
+ numericIpMaskMin: zod.z.coerce.bigint().optional(),
32
+ numericIpMaskMax: zod.z.coerce.bigint().optional()
37
33
  });
38
- const userIpInput = zod.z.object({
39
- ...userIpSchema.shape,
40
- ip: zod.z.string().optional(),
41
- ipMask: zod.z.string().optional()
42
- }).transform((userIpInput2) => {
43
- const { ip, ipMask, ...numericUserIp } = userIpInput2;
44
- if ("string" === typeof ip) {
45
- numericUserIp.numericIp = util.getIPAddress(ip).bigInt();
46
- }
47
- if ("string" === typeof ipMask) {
48
- const ipObject = ipAddress.Address4.isValid(ipMask) ? new ipAddress.Address4(ipMask) : new ipAddress.Address6(ipMask);
49
- numericUserIp.numericIpMaskMin = ipObject.startAddress().bigInt();
50
- numericUserIp.numericIpMaskMax = ipObject.endAddress().bigInt();
51
- }
52
- return numericUserIp;
34
+ var userIpInput = zod.z.object({
35
+ ...userIpSchema.shape,
36
+ ip: zod.z.string().optional(),
37
+ ipMask: zod.z.string().optional()
38
+ }).transform((userIpInput) => {
39
+ const { ip, ipMask, ...numericUserIp } = userIpInput;
40
+ if ("string" === typeof ip) numericUserIp.numericIp = (0, _prosopo_util.getIPAddress)(ip).bigInt();
41
+ if ("string" === typeof ipMask) {
42
+ const ipObject = ip_address.Address4.isValid(ipMask) ? new ip_address.Address4(ipMask) : new ip_address.Address6(ipMask);
43
+ numericUserIp.numericIpMaskMin = ipObject.startAddress().bigInt();
44
+ numericUserIp.numericIpMaskMax = ipObject.endAddress().bigInt();
45
+ }
46
+ return numericUserIp;
53
47
  });
54
- const userScopeSchema = zod.z.object({
55
- ...userIpSchema.shape,
56
- ...userAttributesSchema.shape
48
+ var userScopeSchema = zod.z.object({
49
+ ...userIpSchema.shape,
50
+ ...userAttributesSchema.shape
57
51
  });
58
- const userScopeInput = zod.z.object({}).and(userIpInput).and(userAttributesInput).transform(
59
- // transform is used for type safety only - plain "satisfies ZodType<x>" doesn't work after ".and()"
60
- (userScopeInput2) => userScopeInput2
61
- );
52
+ var userScopeInput = zod.z.object({}).and(userIpInput).and(userAttributesInput).transform((userScopeInput) => userScopeInput);
53
+ //#endregion
62
54
  exports.userScopeInput = userScopeInput;
63
55
  exports.userScopeSchema = userScopeSchema;
@@ -1,27 +1,20 @@
1
- "use strict";
2
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const userAttributesRecordFields = [
4
- "userId",
5
- "ja4Hash",
6
- "headersHash",
7
- "userAgent",
8
- "headHash",
9
- "coords",
10
- "countryCode",
11
- "asn",
12
- "os"
2
+ //#region src/ruleRecord.ts
3
+ var userAttributesRecordFields = [
4
+ "userId",
5
+ "ja4Hash",
6
+ "headersHash",
7
+ "userAgent",
8
+ "headHash",
9
+ "coords",
10
+ "countryCode",
11
+ "asn",
12
+ "os"
13
13
  ];
14
- const userIpRecordFields = [
15
- "ip",
16
- "ipMask"
17
- ];
18
- const userScopeRecordFields = [
19
- ...userAttributesRecordFields,
20
- ...userIpRecordFields
21
- ];
22
- const getUserScopeRecordFromAccessRuleRecord = (ruleRecord) => Object.fromEntries(
23
- userScopeRecordFields.map((field) => [field, ruleRecord[field]]).filter(([, value]) => value !== void 0)
24
- );
14
+ var userIpRecordFields = ["ip", "ipMask"];
15
+ var userScopeRecordFields = [...userAttributesRecordFields, ...userIpRecordFields];
16
+ var getUserScopeRecordFromAccessRuleRecord = (ruleRecord) => Object.fromEntries(userScopeRecordFields.map((field) => [field, ruleRecord[field]]).filter(([, value]) => value !== void 0));
17
+ //#endregion
25
18
  exports.getUserScopeRecordFromAccessRuleRecord = getUserScopeRecordFromAccessRuleRecord;
26
19
  exports.userAttributesRecordFields = userAttributesRecordFields;
27
20
  exports.userIpRecordFields = userIpRecordFields;
@@ -1,8 +1,9 @@
1
- "use strict";
2
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- var FilterScopeMatch = /* @__PURE__ */ ((FilterScopeMatch2) => {
4
- FilterScopeMatch2["Exact"] = "exact";
5
- FilterScopeMatch2["Greedy"] = "greedy";
6
- return FilterScopeMatch2;
7
- })(FilterScopeMatch || {});
2
+ //#region src/rulesStorage.ts
3
+ var FilterScopeMatch = /* @__PURE__ */ function(FilterScopeMatch) {
4
+ FilterScopeMatch["Exact"] = "exact";
5
+ FilterScopeMatch["Greedy"] = "greedy";
6
+ return FilterScopeMatch;
7
+ }({});
8
+ //#endregion
8
9
  exports.FilterScopeMatch = FilterScopeMatch;