@prosopo/user-access-policy 3.8.1 → 3.9.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.
Files changed (63) hide show
  1. package/.turbo/turbo-build$colon$cjs.log +8 -8
  2. package/.turbo/turbo-build$colon$tsc.log +14 -14
  3. package/.turbo/turbo-build.log +9 -9
  4. package/CHANGELOG.md +33 -0
  5. package/dist/api/read/fetchRules.d.ts +1 -30
  6. package/dist/api/read/fetchRules.d.ts.map +1 -1
  7. package/dist/api/read/fetchRules.js.map +1 -1
  8. package/dist/api/write/insertRules.d.ts +2 -2
  9. package/dist/api/write/insertRules.d.ts.map +1 -1
  10. package/dist/api/write/insertRules.js.map +1 -1
  11. package/dist/cjs/mongoose/mongooseRuleSchema.cjs +2 -1
  12. package/dist/cjs/redis/reader/redisAggregate.cjs +22 -4
  13. package/dist/cjs/redis/reader/redisRulesReader.cjs +22 -27
  14. package/dist/cjs/ruleInput/policyInput.cjs +5 -1
  15. package/dist/cjs/ruleInput/userScopeInput.cjs +1 -1
  16. package/dist/cjs/transformRule.cjs +2 -1
  17. package/dist/mongoose/mongooseRuleSchema.d.ts.map +1 -1
  18. package/dist/mongoose/mongooseRuleSchema.js +2 -1
  19. package/dist/mongoose/mongooseRuleSchema.js.map +1 -1
  20. package/dist/redis/reader/redisAggregate.d.ts +1 -1
  21. package/dist/redis/reader/redisAggregate.d.ts.map +1 -1
  22. package/dist/redis/reader/redisAggregate.js +22 -4
  23. package/dist/redis/reader/redisAggregate.js.map +1 -1
  24. package/dist/redis/reader/redisRulesReader.d.ts +1 -0
  25. package/dist/redis/reader/redisRulesReader.d.ts.map +1 -1
  26. package/dist/redis/reader/redisRulesReader.js +24 -29
  27. package/dist/redis/reader/redisRulesReader.js.map +1 -1
  28. package/dist/redis/redisClient.d.ts +2 -2
  29. package/dist/redis/redisClient.d.ts.map +1 -1
  30. package/dist/redis/redisClient.js.map +1 -1
  31. package/dist/rule.d.ts +1 -0
  32. package/dist/rule.d.ts.map +1 -1
  33. package/dist/ruleInput/policyInput.d.ts +3 -0
  34. package/dist/ruleInput/policyInput.d.ts.map +1 -1
  35. package/dist/ruleInput/policyInput.js +5 -1
  36. package/dist/ruleInput/policyInput.js.map +1 -1
  37. package/dist/ruleInput/ruleInput.d.ts +3 -16
  38. package/dist/ruleInput/ruleInput.d.ts.map +1 -1
  39. package/dist/ruleInput/ruleInput.js.map +1 -1
  40. package/dist/ruleInput/userScopeInput.js +2 -2
  41. package/dist/ruleInput/userScopeInput.js.map +1 -1
  42. package/dist/tests/redis/redisRulesStorage.integration.test.js +31 -0
  43. package/dist/tests/redis/redisRulesStorage.integration.test.js.map +1 -1
  44. package/dist/tests/transformRule.unit.test.js +45 -1
  45. package/dist/tests/transformRule.unit.test.js.map +1 -1
  46. package/dist/transformRule.d.ts.map +1 -1
  47. package/dist/transformRule.js +3 -2
  48. package/dist/transformRule.js.map +1 -1
  49. package/package.json +3 -3
  50. package/src/api/read/fetchRules.ts +10 -2
  51. package/src/api/write/insertRules.ts +4 -2
  52. package/src/mongoose/mongooseRuleSchema.ts +1 -0
  53. package/src/redis/reader/redisAggregate.ts +27 -1
  54. package/src/redis/reader/redisRulesReader.ts +42 -40
  55. package/src/redis/redisClient.ts +7 -2
  56. package/src/rule.ts +12 -0
  57. package/src/ruleInput/policyInput.ts +12 -1
  58. package/src/ruleInput/ruleInput.ts +11 -6
  59. package/src/ruleInput/userScopeInput.ts +7 -7
  60. package/src/tests/redis/redisRulesStorage.integration.test.ts +52 -0
  61. package/src/tests/transformRule.unit.test.ts +68 -1
  62. package/src/transformRule.ts +7 -2
  63. package/tsconfig.tsbuildinfo +1 -1
@@ -1,5 +1,5 @@
1
1
 
2
- > @prosopo/user-access-policy@3.8.1 build:cjs
2
+ > @prosopo/user-access-policy@3.9.1 build:cjs
3
3
  > NODE_ENV=${NODE_ENV:-development}; vite build --config vite.cjs.config.ts --mode $NODE_ENV
4
4
 
5
5
  ViteCommonJSConfig: .
@@ -50,22 +50,22 @@ rendering chunks...
50
50
  dist/cjs/api/read/fetchRules.cjs 1.22 kB
51
51
  dist/cjs/.export.cjs 1.24 kB
52
52
  dist/cjs/redis/redisRulesStorage.cjs 1.35 kB
53
- dist/cjs/ruleInput/policyInput.cjs 1.40 kB
54
- dist/cjs/mongoose/mongooseRuleSchema.cjs 1.42 kB
53
+ dist/cjs/mongoose/mongooseRuleSchema.cjs 1.48 kB
55
54
  dist/cjs/api/delete/deleteRules.cjs 1.51 kB
56
55
  dist/cjs/api/delete/deleteRuleGroups.cjs 1.57 kB
57
56
  dist/cjs/api/write/rehashRules.cjs 1.64 kB
58
57
  dist/cjs/api/read/findRuleIds.cjs 1.65 kB
59
- dist/cjs/redis/reader/redisAggregate.cjs 1.95 kB
58
+ dist/cjs/ruleInput/policyInput.cjs 1.70 kB
60
59
  dist/cjs/ruleInput/ruleInput.cjs 2.07 kB
61
60
  dist/cjs/redis/redisClient.cjs 2.09 kB
62
- dist/cjs/ruleInput/userScopeInput.cjs 2.38 kB
61
+ dist/cjs/ruleInput/userScopeInput.cjs 2.45 kB
63
62
  dist/cjs/redis/redisRuleIndex.cjs 2.46 kB
64
63
  dist/cjs/api/rulesApiClient.cjs 2.60 kB
65
- dist/cjs/transformRule.cjs 2.91 kB
64
+ dist/cjs/redis/reader/redisAggregate.cjs 2.61 kB
65
+ dist/cjs/transformRule.cjs 3.05 kB
66
66
  dist/cjs/api/write/insertRules.cjs 3.38 kB
67
67
  dist/cjs/redis/redisRulesWriter.cjs 3.44 kB
68
68
  dist/cjs/redis/reader/redisRulesQuery.cjs 4.34 kB
69
69
  dist/cjs/api/ruleApiRoutes.cjs 4.55 kB
70
- dist/cjs/redis/reader/redisRulesReader.cjs 7.01 kB
71
- ✓ built in 454ms
70
+ dist/cjs/redis/reader/redisRulesReader.cjs 6.87 kB
71
+ ✓ built in 451ms
@@ -1,8 +1,8 @@
1
1
 
2
- > @prosopo/user-access-policy@3.8.1 build:tsc
2
+ > @prosopo/user-access-policy@3.9.1 build:tsc
3
3
  > tsc --build --verbose
4
4
 
5
- 5:56:01 PM - Projects in this build:
5
+ 1:19:54 PM - Projects in this build:
6
6
  * ../../dev/config/tsconfig.json
7
7
  * ../locale/tsconfig.json
8
8
  * ../util/tsconfig.json
@@ -15,27 +15,27 @@
15
15
  * ../api/tsconfig.json
16
16
  * tsconfig.json
17
17
 
18
- 5:56:01 PM - Project '../../dev/config/tsconfig.json' is up to date because newest input '../../dev/config/src/webpack/webpack.config.ts' is older than output '../../dev/config/tsconfig.tsbuildinfo'
18
+ 1:19:54 PM - Project '../../dev/config/tsconfig.json' is up to date because newest input '../../dev/config/src/webpack/webpack.config.ts' is older than output '../../dev/config/tsconfig.tsbuildinfo'
19
19
 
20
- 5:56:01 PM - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/translationKey.ts' is older than output '../locale/tsconfig.tsbuildinfo'
20
+ 1:19:54 PM - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/translationKey.ts' is older than output '../locale/tsconfig.tsbuildinfo'
21
21
 
22
- 5:56:01 PM - Project '../util/tsconfig.json' is up to date because newest input '../util/src/url.ts' is older than output '../util/tsconfig.tsbuildinfo'
22
+ 1:19:54 PM - Project '../util/tsconfig.json' is up to date because newest input '../util/src/url.ts' is older than output '../util/tsconfig.tsbuildinfo'
23
23
 
24
- 5:56:01 PM - Project '../logger/tsconfig.json' is up to date because newest input '../logger/src/index.ts' is older than output '../logger/tsconfig.tsbuildinfo'
24
+ 1:19:54 PM - Project '../logger/tsconfig.json' is up to date because newest input '../logger/src/index.ts' is older than output '../logger/tsconfig.tsbuildinfo'
25
25
 
26
- 5:56:01 PM - Project '../util-crypto/tsconfig.json' is up to date because newest input '../util-crypto/src/types.ts' is older than output '../util-crypto/tsconfig.tsbuildinfo'
26
+ 1:19:54 PM - Project '../util-crypto/tsconfig.json' is up to date because newest input '../util-crypto/src/types.ts' is older than output '../util-crypto/tsconfig.tsbuildinfo'
27
27
 
28
- 5:56:01 PM - Project '../types/tsconfig.json' is up to date because newest input '../types/src/provider/api.ts' is older than output '../types/tsconfig.tsbuildinfo'
28
+ 1:19:55 PM - Project '../types/tsconfig.json' is up to date because newest input '../types/src/keyring/keyring/types.ts' is older than output '../types/tsconfig.tsbuildinfo'
29
29
 
30
- 5:56:01 PM - Project '../common/tsconfig.json' is up to date because newest input '../common/src/index.ts' is older than output '../common/tsconfig.tsbuildinfo'
30
+ 1:19:55 PM - Project '../common/tsconfig.json' is up to date because newest input '../common/src/index.ts' is older than output '../common/tsconfig.tsbuildinfo'
31
31
 
32
- 5:56:01 PM - Project '../api-route/tsconfig.json' is up to date because newest input '../api-route/src/apiRoutes.ts' is older than output '../api-route/tsconfig.tsbuildinfo'
32
+ 1:19:55 PM - Project '../api-route/tsconfig.json' is up to date because newest input '../api-route/src/apiRoutes.ts' is older than output '../api-route/tsconfig.tsbuildinfo'
33
33
 
34
- 5:56:01 PM - Project '../redis-client/tsconfig.json' is up to date because newest input '../redis-client/src/index.ts' is older than output '../redis-client/tsconfig.tsbuildinfo'
34
+ 1:19:55 PM - Project '../redis-client/tsconfig.json' is up to date because newest input '../redis-client/src/index.ts' is older than output '../redis-client/tsconfig.tsbuildinfo'
35
35
 
36
- 5:56:01 PM - Project '../api/tsconfig.json' is up to date because newest input '../api/src/index.ts' is older than output '../api/tsconfig.tsbuildinfo'
36
+ 1:19:55 PM - Project '../api/tsconfig.json' is up to date because newest input '../api/src/index.ts' is older than output '../api/tsconfig.tsbuildinfo'
37
37
 
38
- 5:56:01 PM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
38
+ 1:19:55 PM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
39
39
 
40
- 5:56:01 PM - Building project '/home/runner/work/captcha/captcha/packages/user-access-policy/tsconfig.json'...
40
+ 1:19:55 PM - Building project '/home/runner/work/captcha/captcha/packages/user-access-policy/tsconfig.json'...
41
41
 
@@ -1,9 +1,9 @@
1
1
 
2
- > @prosopo/user-access-policy@3.8.1 build
2
+ > @prosopo/user-access-policy@3.9.1 build
3
3
  > npm run build:cross-env -- --mode ${NODE_ENV:-development}
4
4
 
5
5
 
6
- > @prosopo/user-access-policy@3.8.1 build:cross-env
6
+ > @prosopo/user-access-policy@3.9.1 build:cross-env
7
7
  > vite build --config vite.esm.config.ts --mode production
8
8
 
9
9
  ViteEsmConfig: .
@@ -53,23 +53,23 @@ rendering chunks...
53
53
  dist/.export.js 0.85 kB
54
54
  dist/api/read/getMissingIds.js 1.01 kB
55
55
  dist/api/read/fetchRules.js 1.08 kB
56
- dist/ruleInput/policyInput.js 1.20 kB
57
56
  dist/redis/redisRulesStorage.js 1.21 kB
58
- dist/mongoose/mongooseRuleSchema.js 1.31 kB
57
+ dist/mongoose/mongooseRuleSchema.js 1.37 kB
59
58
  dist/api/delete/deleteRules.js 1.44 kB
60
59
  dist/api/delete/deleteRuleGroups.js 1.44 kB
60
+ dist/ruleInput/policyInput.js 1.50 kB
61
61
  dist/api/read/findRuleIds.js 1.54 kB
62
62
  dist/api/write/rehashRules.js 1.54 kB
63
63
  dist/ruleInput/ruleInput.js 1.72 kB
64
- dist/redis/reader/redisAggregate.js 1.80 kB
65
64
  dist/redis/redisClient.js 1.90 kB
66
65
  dist/redis/redisRuleIndex.js 2.01 kB
67
- dist/ruleInput/userScopeInput.js 2.16 kB
66
+ dist/ruleInput/userScopeInput.js 2.22 kB
68
67
  dist/api/rulesApiClient.js 2.36 kB
69
- dist/transformRule.js 2.63 kB
68
+ dist/redis/reader/redisAggregate.js 2.46 kB
69
+ dist/transformRule.js 2.76 kB
70
70
  dist/api/write/insertRules.js 3.22 kB
71
71
  dist/redis/redisRulesWriter.js 3.22 kB
72
72
  dist/redis/reader/redisRulesQuery.js 4.15 kB
73
73
  dist/api/ruleApiRoutes.js 4.33 kB
74
- dist/redis/reader/redisRulesReader.js 6.23 kB
75
- ✓ built in 516ms
74
+ dist/redis/reader/redisRulesReader.js 6.02 kB
75
+ ✓ built in 473ms
package/CHANGELOG.md CHANGED
@@ -1,5 +1,38 @@
1
1
  # @prosopo/user-access-policy
2
2
 
3
+ ## 3.9.1
4
+ ### Patch Changes
5
+
6
+ - b520cd9: Paginate the greedy `findRules` RediSearch query via `FT.AGGREGATE WITHCURSOR` so the candidate set is no longer truncated at `REDIS_BATCH_SIZE` (1000). Under high-volume bot traffic, a single popular ja4 fingerprint can be carried by thousands of rules; the OR-style greedy query returned > 1000 candidates and `FT.SEARCH`'s LIMIT silently dropped the tail — block rules emitted by less-frequent detectors sat past offset 1000 and never reached the JS-side specificity sort, letting matching requests through. Aggregation cursors return the full result set, so ranking sees every candidate.
7
+
8
+ ## 3.9.0
9
+ ### Minor Changes
10
+
11
+ - 4da8941: Add `deferToVerify` flag on `AccessPolicy` so a Block policy can skip the request-time `blockMiddleware` (no 401 at the captcha endpoint) and fire instead at the verify step. The behaviour mirrors the existing coords-rule deferral pattern: today the middleware blanks out coords from the userScope, so coords-only rules can only ever match in the verify path. `deferToVerify` is the explicit version of that for other signals (ja4Hash, headersHash, etc.) — useful when you want the attacker to pay the captcha-solving cost and the dApp to silently receive `{verified: false}` instead of the bot's frontend seeing a 401.
12
+
13
+ Wiring:
14
+
15
+ - `BlacklistRequestInspector.shouldAbortRequest` filters out matching policies that have `deferToVerify` before picking the top hit. Those policies never short-circuit the middleware.
16
+ - `CaptchaManager.findHardBlockPolicy` widens its matcher: a Block policy now counts as a hard block when it has either no `captchaType` (existing behaviour) **or** `deferToVerify === true`. The check is invoked from `imgCaptchaTasks.dappUserSolution`, `powTasks.serverVerifyPowCaptcha`, and `puzzleTasks.verifyPuzzleCaptchaSolution`, so the deferral applies to all three captcha types.
17
+ - Persistence: `deferToVerify` lands on the mongo `accessPolicySchema` (Boolean) and the zod `accessPolicyInput` (with a string→boolean preprocess so the Redis round-trip works).
18
+
19
+ Motivating use case: a set of spoofed-JA4 hard-block rules pushed 2026-06-12. Marking those `deferToVerify: true` would still reject the attacker at verify but force them to complete N image captcha rounds and surface behavioural data on the commitment record before the rejection — useful for both telemetry and operator-side friction.
20
+
21
+ ### Patch Changes
22
+
23
+ - 70ef67a: Add explicit `ZodType<T, ZodTypeDef, unknown>` annotations to `accessRuleInput`, `ruleEntryInput`, and `fetchRulesResponse`. The `z.preprocess` on `deferToVerify` widens the input position to `unknown`; without an explicit annotation TS emits an unnameable inferred type and parent repos that import these schemas fail typecheck with TS2742.
24
+ - 4226c59: Support IPv6 in access rule input transforms.
25
+
26
+ The portal-side ticket [prosopo/captcha-private#3379](https://github.com/prosopo/captcha-private/issues/3379) enables IPv6 rule creation. The CIDR parser in `userScopeInput` and the numeric→string reverse path in `transformRule` were both IPv4-only and would crash or produce wrong addresses when an IPv6 rule reached the provider.
27
+
28
+ - `userScopeInput.ts`: dispatch CIDR parsing to `Address4` vs `Address6` via `Address4.isValid`; both expose `startAddress()/endAddress().bigInt()`.
29
+ - `transformRule.ts`: `getStringIpFromNumeric` now uses `Address6.fromBigInt(...).correctForm()` for numeric values above `2^32 - 1`, keeping `Address4.fromInteger(...)` for IPv4 range.
30
+ - Adds a round-trip unit test for `2001:db8::1` + `/32` mask, plus three IPv6 CIDR cases (`/32`, `/64`, `/10`) alongside the existing IPv4 set.
31
+ - Updated dependencies [f69724f]
32
+ - Updated dependencies [3973078]
33
+ - @prosopo/types@4.4.1
34
+ - @prosopo/api@3.4.11
35
+
3
36
  ## 3.8.1
4
37
  ### Patch Changes
5
38
 
@@ -9,36 +9,7 @@ type FetchRulesSchema = ZodType<FetchRulesOptions>;
9
9
  export type FetchRulesResponse = {
10
10
  ruleEntries: AccessRuleEntry[];
11
11
  };
12
- export declare const fetchRulesResponse: z.ZodObject<{
13
- ruleEntries: z.ZodArray<z.ZodObject<{
14
- rule: ZodType<import("../../rule.js").AccessRule, z.ZodTypeDef, import("../../rule.js").AccessRule>;
15
- expiresUnixTimestamp: z.ZodOptional<z.ZodNumber>;
16
- }, "strip", z.ZodTypeAny, {
17
- rule: import("../../rule.js").AccessPolicy & import("../../rule.js").PolicyScope & import("../../rule.js").UserAttributes & import("../../rule.js").UserIp & {
18
- groupId?: string;
19
- };
20
- expiresUnixTimestamp?: number | undefined;
21
- }, {
22
- rule: import("../../rule.js").AccessPolicy & import("../../rule.js").PolicyScope & import("../../rule.js").UserAttributes & import("../../rule.js").UserIp & {
23
- groupId?: string;
24
- };
25
- expiresUnixTimestamp?: number | undefined;
26
- }>, "many">;
27
- }, "strip", z.ZodTypeAny, {
28
- ruleEntries: {
29
- rule: import("../../rule.js").AccessPolicy & import("../../rule.js").PolicyScope & import("../../rule.js").UserAttributes & import("../../rule.js").UserIp & {
30
- groupId?: string;
31
- };
32
- expiresUnixTimestamp?: number | undefined;
33
- }[];
34
- }, {
35
- ruleEntries: {
36
- rule: import("../../rule.js").AccessPolicy & import("../../rule.js").PolicyScope & import("../../rule.js").UserAttributes & import("../../rule.js").UserIp & {
37
- groupId?: string;
38
- };
39
- expiresUnixTimestamp?: number | undefined;
40
- }[];
41
- }>;
12
+ export declare const fetchRulesResponse: ZodType<FetchRulesResponse, z.ZodTypeDef, unknown>;
42
13
  export type FetchRulesEndpointResponse = ApiEndpointResponse & {
43
14
  data?: FetchRulesResponse;
44
15
  };
@@ -1 +1 @@
1
- {"version":3,"file":"fetchRules.d.ts","sourceRoot":"","sources":["../../../src/api/read/fetchRules.ts"],"names":[],"mappings":"AAcA,OAAO,EACN,KAAK,WAAW,EAChB,KAAK,mBAAmB,EAExB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,KAAK,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAEtC,OAAO,KAAK,EACX,eAAe,EACf,kBAAkB,EAClB,MAAM,yBAAyB,CAAC;AAEjC,MAAM,MAAM,iBAAiB,GAAG;IAC/B,GAAG,EAAE,MAAM,EAAE,CAAC;CACd,CAAC;AAEF,KAAK,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAEnD,MAAM,MAAM,kBAAkB,GAAG;IAChC,WAAW,EAAE,eAAe,EAAE,CAAC;CAC/B,CAAC;AAEF,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAE+C,CAAC;AAE/E,MAAM,MAAM,0BAA0B,GAAG,mBAAmB,GAAG;IAC9D,IAAI,CAAC,EAAE,kBAAkB,CAAC;CAC1B,CAAC;AAEF,qBAAa,kBAAmB,YAAW,WAAW,CAAC,gBAAgB,CAAC;IAEtE,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,MAAM;gBADN,kBAAkB,EAAE,kBAAkB,EACtC,MAAM,EAAE,MAAM;IAGzB,oBAAoB,IAAI,gBAAgB;IAMzC,cAAc,CACnB,IAAI,EAAE,iBAAiB,EACvB,MAAM,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,0BAA0B,CAAC;CA0BtC"}
1
+ {"version":3,"file":"fetchRules.d.ts","sourceRoot":"","sources":["../../../src/api/read/fetchRules.ts"],"names":[],"mappings":"AAcA,OAAO,EACN,KAAK,WAAW,EAChB,KAAK,mBAAmB,EAExB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,KAAK,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAEtC,OAAO,KAAK,EACX,eAAe,EACf,kBAAkB,EAClB,MAAM,yBAAyB,CAAC;AAEjC,MAAM,MAAM,iBAAiB,GAAG;IAC/B,GAAG,EAAE,MAAM,EAAE,CAAC;CACd,CAAC;AAEF,KAAK,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAEnD,MAAM,MAAM,kBAAkB,GAAG;IAChC,WAAW,EAAE,eAAe,EAAE,CAAC;CAC/B,CAAC;AAMF,eAAO,MAAM,kBAAkB,EAAE,OAAO,CACvC,kBAAkB,EAClB,CAAC,CAAC,UAAU,EACZ,OAAO,CAGgC,CAAC;AAEzC,MAAM,MAAM,0BAA0B,GAAG,mBAAmB,GAAG;IAC9D,IAAI,CAAC,EAAE,kBAAkB,CAAC;CAC1B,CAAC;AAEF,qBAAa,kBAAmB,YAAW,WAAW,CAAC,gBAAgB,CAAC;IAEtE,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,MAAM;gBADN,kBAAkB,EAAE,kBAAkB,EACtC,MAAM,EAAE,MAAM;IAGzB,oBAAoB,IAAI,gBAAgB;IAMzC,cAAc,CACnB,IAAI,EAAE,iBAAiB,EACvB,MAAM,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,0BAA0B,CAAC;CA0BtC"}
@@ -1 +1 @@
1
- {"version":3,"file":"fetchRules.js","sourceRoot":"","sources":["../../../src/api/read/fetchRules.ts"],"names":[],"mappings":"AAcA,OAAO,EAGN,yBAAyB,GACzB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAgB,CAAC,EAAE,MAAM,KAAK,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAgBhE,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,WAAW,EAAE,cAAc,CAAC,KAAK,EAAE;CACG,CAAuC,CAAC;AAM/E,MAAM,OAAO,kBAAkB;IAC9B,YACkB,kBAAsC,EACtC,MAAc;QADd,uBAAkB,GAAlB,kBAAkB,CAAoB;QACtC,WAAM,GAAN,MAAM,CAAQ;IAC7B,CAAC;IAEG,oBAAoB;QAC1B,OAAO,CAAC,CAAC,MAAM,CAAC;YACf,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE;SACc,CAAC,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,cAAc,CACnB,IAAuB,EACvB,MAAe;QAEf,MAAM,GAAG,GAAG,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC;QAClC,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAEvE,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;YACf,GAAG,EAAE,wBAAwB;YAC7B,IAAI,EAAE;gBACL,cAAc,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM;gBAC/B,UAAU,EAAE,WAAW,CAAC,MAAM;aAC9B;SACD,CAAC,CAAC,CAAC;QAEJ,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;YAChB,GAAG,EAAE,sBAAsB;YAC3B,IAAI,EAAE;gBACL,WAAW,EAAE,WAAW;aACxB;SACD,CAAC,CAAC,CAAC;QAEJ,OAAO;YACN,MAAM,EAAE,yBAAyB,CAAC,OAAO;YACzC,IAAI,EAAE;gBACL,WAAW,EAAE,WAAW;aACxB;SACD,CAAC;IACH,CAAC;CACD"}
1
+ {"version":3,"file":"fetchRules.js","sourceRoot":"","sources":["../../../src/api/read/fetchRules.ts"],"names":[],"mappings":"AAcA,OAAO,EAGN,yBAAyB,GACzB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAgB,CAAC,EAAE,MAAM,KAAK,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAoBhE,MAAM,CAAC,MAAM,kBAAkB,GAI3B,CAAC,CAAC,MAAM,CAAC;IACZ,WAAW,EAAE,cAAc,CAAC,KAAK,EAAE;CACG,CAAC,CAAC;AAMzC,MAAM,OAAO,kBAAkB;IAC9B,YACkB,kBAAsC,EACtC,MAAc;QADd,uBAAkB,GAAlB,kBAAkB,CAAoB;QACtC,WAAM,GAAN,MAAM,CAAQ;IAC7B,CAAC;IAEG,oBAAoB;QAC1B,OAAO,CAAC,CAAC,MAAM,CAAC;YACf,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE;SACc,CAAC,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,cAAc,CACnB,IAAuB,EACvB,MAAe;QAEf,MAAM,GAAG,GAAG,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC;QAClC,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAEvE,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;YACf,GAAG,EAAE,wBAAwB;YAC7B,IAAI,EAAE;gBACL,cAAc,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM;gBAC/B,UAAU,EAAE,WAAW,CAAC,MAAM;aAC9B;SACD,CAAC,CAAC,CAAC;QAEJ,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;YAChB,GAAG,EAAE,sBAAsB;YAC3B,IAAI,EAAE;gBACL,WAAW,EAAE,WAAW;aACxB;SACD,CAAC,CAAC,CAAC;QAEJ,OAAO;YACN,MAAM,EAAE,yBAAyB,CAAC,OAAO;YACzC,IAAI,EAAE;gBACL,WAAW,EAAE,WAAW;aACxB;SACD,CAAC;IACH,CAAC;CACD"}
@@ -1,6 +1,6 @@
1
1
  import { type ApiEndpoint, type ApiEndpointResponse } from "@prosopo/api-route";
2
2
  import { type Logger } from "@prosopo/logger";
3
- import { type ZodType } from "zod";
3
+ import { type ZodType, type ZodTypeDef } from "zod";
4
4
  import type { AccessPolicy, PolicyScope, UserScope } from "#policy/rule.js";
5
5
  import { type UserScopeInput } from "#policy/ruleInput/userScopeInput.js";
6
6
  import type { AccessRulesWriter } from "#policy/rulesStorage.js";
@@ -15,7 +15,7 @@ type ParsedInsertRulesGroup = InsertRulesGroup & {
15
15
  userScopes: UserScope[];
16
16
  };
17
17
  type ParsedInsertRuleGroups = ParsedInsertRulesGroup[];
18
- type InsertRulesSchema = ZodType<InsertRulesGroup[]>;
18
+ type InsertRulesSchema = ZodType<InsertRulesGroup[], ZodTypeDef, unknown>;
19
19
  export declare class InsertRulesEndpoint implements ApiEndpoint<InsertRulesSchema> {
20
20
  private readonly accessRulesWriter;
21
21
  private readonly logger;
@@ -1 +1 @@
1
- {"version":3,"file":"insertRules.d.ts","sourceRoot":"","sources":["../../../src/api/write/insertRules.ts"],"names":[],"mappings":"AAcA,OAAO,EACN,KAAK,WAAW,EAChB,KAAK,mBAAmB,EAExB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAY,KAAK,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,KAAK,OAAO,EAAK,MAAM,KAAK,CAAC;AACtC,OAAO,KAAK,EACX,YAAY,EAEZ,WAAW,EACX,SAAS,EACT,MAAM,iBAAiB,CAAC;AAMzB,OAAO,EACN,KAAK,cAAc,EAEnB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,KAAK,EAEX,iBAAiB,EACjB,MAAM,yBAAyB,CAAC;AAEjC,MAAM,MAAM,gBAAgB,GAAG;IAC9B,YAAY,EAAE,YAAY,CAAC;IAC3B,UAAU,EAAE,cAAc,EAAE,CAAC;IAG7B,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF,KAAK,sBAAsB,GAAG,gBAAgB,GAAG;IAChD,UAAU,EAAE,SAAS,EAAE,CAAC;CACxB,CAAC;AAEF,KAAK,sBAAsB,GAAG,sBAAsB,EAAE,CAAC;AAEvD,KAAK,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;AAErD,qBAAa,mBAAoB,YAAW,WAAW,CAAC,iBAAiB,CAAC;IAExE,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM;gBADN,iBAAiB,EAAE,iBAAiB,EACpC,MAAM,EAAE,MAAM;IAGzB,oBAAoB,IAAI,iBAAiB;IAY1C,cAAc,CACnB,IAAI,EAAE,sBAAsB,EAC5B,MAAM,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,mBAAmB,CAAC;cAwDf,gBAAgB,CAC/B,MAAM,EAAE,sBAAsB,GAC5B,OAAO,CAAC,MAAM,EAAE,CAAC;cAQJ,gBAAgB,CAC/B,KAAK,EAAE,sBAAsB,GAC3B,OAAO,CAAC,MAAM,EAAE,CAAC;CAiCpB"}
1
+ {"version":3,"file":"insertRules.d.ts","sourceRoot":"","sources":["../../../src/api/write/insertRules.ts"],"names":[],"mappings":"AAcA,OAAO,EACN,KAAK,WAAW,EAChB,KAAK,mBAAmB,EAExB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAY,KAAK,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,UAAU,EAAK,MAAM,KAAK,CAAC;AACvD,OAAO,KAAK,EACX,YAAY,EAEZ,WAAW,EACX,SAAS,EACT,MAAM,iBAAiB,CAAC;AAMzB,OAAO,EACN,KAAK,cAAc,EAEnB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,KAAK,EAEX,iBAAiB,EACjB,MAAM,yBAAyB,CAAC;AAEjC,MAAM,MAAM,gBAAgB,GAAG;IAC9B,YAAY,EAAE,YAAY,CAAC;IAC3B,UAAU,EAAE,cAAc,EAAE,CAAC;IAG7B,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF,KAAK,sBAAsB,GAAG,gBAAgB,GAAG;IAChD,UAAU,EAAE,SAAS,EAAE,CAAC;CACxB,CAAC;AAEF,KAAK,sBAAsB,GAAG,sBAAsB,EAAE,CAAC;AAIvD,KAAK,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,EAAE,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;AAE1E,qBAAa,mBAAoB,YAAW,WAAW,CAAC,iBAAiB,CAAC;IAExE,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM;gBADN,iBAAiB,EAAE,iBAAiB,EACpC,MAAM,EAAE,MAAM;IAGzB,oBAAoB,IAAI,iBAAiB;IAY1C,cAAc,CACnB,IAAI,EAAE,sBAAsB,EAC5B,MAAM,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,mBAAmB,CAAC;cAwDf,gBAAgB,CAC/B,MAAM,EAAE,sBAAsB,GAC5B,OAAO,CAAC,MAAM,EAAE,CAAC;cAQJ,gBAAgB,CAC/B,KAAK,EAAE,sBAAsB,GAC3B,OAAO,CAAC,MAAM,EAAE,CAAC;CAiCpB"}
@@ -1 +1 @@
1
- {"version":3,"file":"insertRules.js","sourceRoot":"","sources":["../../../src/api/write/insertRules.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"insertRules.js","sourceRoot":"","sources":["../../../src/api/write/insertRules.ts"],"names":[],"mappings":"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"}
@@ -29,7 +29,8 @@ const accessPolicySchema = {
29
29
  imageThreshold: { type: Number, required: false },
30
30
  powDifficulty: { type: Number, required: false },
31
31
  unsolvedImagesCount: { type: Number, required: false },
32
- frictionlessScore: { type: Number, required: false }
32
+ frictionlessScore: { type: Number, required: false },
33
+ deferToVerify: { type: Boolean, required: false }
33
34
  };
34
35
  const accessRuleMongooseSchema = {
35
36
  ...accessPolicySchema,
@@ -4,19 +4,36 @@ const zod = require("zod");
4
4
  const redisRulesQuery = require("./redisRulesQuery.cjs");
5
5
  const redisClient = require("../redisClient.cjs");
6
6
  const redisRuleIndex = require("../redisRuleIndex.cjs");
7
- const aggregateRedisKeys = async (client, query, logger, batchHandler) => {
7
+ const aggregateRedisKeys = async (client, query, logger, batchHandler, maxKeys) => {
8
8
  const keyField = "__key";
9
9
  const recordSchema = zod.z.object({
10
10
  // it's a reserved name for the record key
11
11
  [keyField]: zod.z.string()
12
12
  });
13
13
  const foundKeys = [];
14
+ let stopRequested = false;
14
15
  const addRecordKeys = async (records) => {
16
+ if (stopRequested) {
17
+ return;
18
+ }
15
19
  const parsedRecords = redisClient.parseRedisRecords(records, recordSchema, logger);
16
20
  const recordKeys = parsedRecords.map((record) => record[keyField]);
17
21
  if (batchHandler) {
18
22
  await batchHandler(recordKeys);
19
23
  } else {
24
+ if (maxKeys !== void 0 && foundKeys.length + recordKeys.length > maxKeys) {
25
+ const remaining = Math.max(0, maxKeys - foundKeys.length);
26
+ foundKeys.push(...recordKeys.slice(0, remaining));
27
+ stopRequested = true;
28
+ logger.warn(() => ({
29
+ msg: "Redis aggregation candidate cap hit; truncating result set. This can suppress less-frequent rules and should be investigated.",
30
+ data: {
31
+ maxKeys,
32
+ query
33
+ }
34
+ }));
35
+ return;
36
+ }
20
37
  foundKeys.push(...recordKeys);
21
38
  logger.debug(() => ({
22
39
  msg: "Processed aggregation batch",
@@ -35,11 +52,12 @@ const aggregateRedisKeys = async (client, query, logger, batchHandler) => {
35
52
  COUNT: redisClient.REDIS_BATCH_SIZE,
36
53
  LOAD: `@${keyField}`
37
54
  },
38
- addRecordKeys
55
+ addRecordKeys,
56
+ () => stopRequested
39
57
  );
40
58
  return foundKeys;
41
59
  };
42
- const executeAggregation = async (client, query, aggregateOptions, handleBatch) => {
60
+ const executeAggregation = async (client, query, aggregateOptions, handleBatch, shouldStop) => {
43
61
  const initialReply = await client.ft.aggregateWithCursor(
44
62
  redisRuleIndex.ACCESS_RULES_REDIS_INDEX_NAME,
45
63
  query,
@@ -47,7 +65,7 @@ const executeAggregation = async (client, query, aggregateOptions, handleBatch)
47
65
  );
48
66
  await handleBatch(initialReply.results);
49
67
  let cursor = initialReply.cursor;
50
- while (0 !== cursor) {
68
+ while (0 !== cursor && !shouldStop?.()) {
51
69
  const batchReply = await client.ft.cursorRead(
52
70
  redisRuleIndex.ACCESS_RULES_REDIS_INDEX_NAME,
53
71
  cursor,
@@ -24,6 +24,7 @@ function _interopNamespaceDefault(e) {
24
24
  return Object.freeze(n);
25
25
  }
26
26
  const util__namespace = /* @__PURE__ */ _interopNamespaceDefault(util);
27
+ const FIND_RULES_MAX_CANDIDATES = redisClient.REDIS_BATCH_SIZE * 10;
27
28
  class RedisRulesReader {
28
29
  constructor(client, logger) {
29
30
  this.client = client;
@@ -53,39 +54,32 @@ class RedisRulesReader {
53
54
  return [];
54
55
  }
55
56
  try {
56
- const searchReply = await this.client.ft.searchNoContent(
57
- redisRuleIndex.ACCESS_RULES_REDIS_INDEX_NAME,
57
+ const ruleKeys = await redisAggregate.aggregateRedisKeys(
58
+ this.client,
58
59
  query,
59
- {
60
- DIALECT: redisRulesQuery.REDIS_QUERY_DIALECT,
61
- // FT.search doesn't support "unlimited" selects
62
- LIMIT: {
63
- from: 0,
64
- size: redisClient.REDIS_BATCH_SIZE
65
- }
66
- }
60
+ this.logger,
61
+ void 0,
62
+ FIND_RULES_MAX_CANDIDATES
67
63
  );
68
- if (searchReply.total > 0) {
69
- this.logger.debug(() => ({
70
- msg: "Executed search query",
71
- data: {
72
- inspect: util__namespace.inspect(
73
- {
74
- filter,
75
- searchReply,
76
- query
77
- },
78
- { depth: null }
79
- )
80
- }
81
- }));
82
- }
83
- if (searchReply.documents.length === 0) {
64
+ if (ruleKeys.length === 0) {
84
65
  return [];
85
66
  }
67
+ this.logger.debug(() => ({
68
+ msg: "Executed search query",
69
+ data: {
70
+ inspect: util__namespace.inspect(
71
+ {
72
+ filter,
73
+ foundCount: ruleKeys.length,
74
+ query
75
+ },
76
+ { depth: null }
77
+ )
78
+ }
79
+ }));
86
80
  const { records } = await redisClient.fetchRedisHashRecords(
87
81
  this.client,
88
- searchReply.documents,
82
+ ruleKeys,
89
83
  this.logger
90
84
  );
91
85
  const nonEmptyRecords = records.filter(
@@ -236,4 +230,5 @@ class DummyRedisRulesReader {
236
230
  }
237
231
  }
238
232
  exports.DummyRedisRulesReader = DummyRedisRulesReader;
233
+ exports.FIND_RULES_MAX_CANDIDATES = FIND_RULES_MAX_CANDIDATES;
239
234
  exports.RedisRulesReader = RedisRulesReader;
@@ -16,7 +16,11 @@ const accessPolicyInput = zod.z.object({
16
16
  // the number of unsolved image CAPTCHA challenges to serve
17
17
  unsolvedImagesCount: zod.z.coerce.number().optional(),
18
18
  // used to increase the user's score
19
- frictionlessScore: zod.z.coerce.number().optional()
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()
20
24
  });
21
25
  const sanitizeAccessPolicy = (policy) => {
22
26
  if (policy.type === rule.AccessPolicyType.Block) {
@@ -41,7 +41,7 @@ const userIpInput = zod.z.object({
41
41
  numericUserIp.numericIp = util.getIPAddress(ip).bigInt();
42
42
  }
43
43
  if ("string" === typeof ipMask) {
44
- const ipObject = new ipAddress.Address4(ipMask);
44
+ const ipObject = ipAddress.Address4.isValid(ipMask) ? new ipAddress.Address4(ipMask) : new ipAddress.Address6(ipMask);
45
45
  numericUserIp.numericIpMaskMin = ipObject.startAddress().bigInt();
46
46
  numericUserIp.numericIpMaskMax = ipObject.endAddress().bigInt();
47
47
  }
@@ -8,6 +8,7 @@ const policyInput = require("./ruleInput/policyInput.cjs");
8
8
  const ruleInput = require("./ruleInput/ruleInput.cjs");
9
9
  const userScopeInput = require("./ruleInput/userScopeInput.cjs");
10
10
  const RULE_HASH_ALGORITHM = "md5";
11
+ const MAX_IPV4_NUMERIC = (1n << 32n) - 1n;
11
12
  const makeAccessRuleHash = (rule) => {
12
13
  const valueProperties = Object.entries(rule).filter(
13
14
  ([key, value]) => "undefined" !== typeof value
@@ -62,7 +63,7 @@ const hashObject = (object, algorithm) => crypto.createHash(algorithm).update(
62
63
  )
63
64
  )
64
65
  ).digest("hex");
65
- const getStringIpFromNumeric = (numericIp) => ipAddress.Address4.fromInteger(Number(numericIp)).address;
66
+ const getStringIpFromNumeric = (numericIp) => numericIp > MAX_IPV4_NUMERIC ? ipAddress.Address6.fromBigInt(numericIp).correctForm() : ipAddress.Address4.fromInteger(Number(numericIp)).address;
66
67
  const getCidrFromNumericIpRange = (startIp, endIp) => {
67
68
  const ipRange = new cidrCalc.IpRange(
68
69
  cidrCalc.IpAddress.of(getStringIpFromNumeric(startIp)),
@@ -1 +1 @@
1
- {"version":3,"file":"mongooseRuleSchema.d.ts","sourceRoot":"","sources":["../../src/mongoose/mongooseRuleSchema.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAEjD,OAAO,KAAK,EACX,gBAAgB,EAIhB,MAAM,uBAAuB,CAAC;AAsC/B,eAAO,MAAM,wBAAwB,EAAE,gBAAgB,CAAC,gBAAgB,CAKtC,CAAC"}
1
+ {"version":3,"file":"mongooseRuleSchema.d.ts","sourceRoot":"","sources":["../../src/mongoose/mongooseRuleSchema.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAEjD,OAAO,KAAK,EACX,gBAAgB,EAIhB,MAAM,uBAAuB,CAAC;AAuC/B,eAAO,MAAM,wBAAwB,EAAE,gBAAgB,CAAC,gBAAgB,CAKtC,CAAC"}
@@ -27,7 +27,8 @@ const accessPolicySchema = {
27
27
  imageThreshold: { type: Number, required: false },
28
28
  powDifficulty: { type: Number, required: false },
29
29
  unsolvedImagesCount: { type: Number, required: false },
30
- frictionlessScore: { type: Number, required: false }
30
+ frictionlessScore: { type: Number, required: false },
31
+ deferToVerify: { type: Boolean, required: false }
31
32
  };
32
33
  const accessRuleMongooseSchema = {
33
34
  ...accessPolicySchema,
@@ -1 +1 @@
1
- {"version":3,"file":"mongooseRuleSchema.js","sourceRoot":"","sources":["../../src/mongoose/mongooseRuleSchema.ts"],"names":[],"mappings":"AAwBA,MAAM,oBAAoB,GAA2C;IACpE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;IACzC,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;IAC1C,SAAS,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;IAC5C,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;IAC9C,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;IAC3C,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;IACzC,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;IAC9C,GAAG,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;CACE,CAAC;AAE1C,MAAM,YAAY,GAAmC;IACpD,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;IACrC,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;CACT,CAAC;AAElC,MAAM,eAAe,GAAsC;IAC1D,GAAG,oBAAoB;IACvB,GAAG,YAAY;CACiB,CAAC;AAElC,MAAM,iBAAiB,GAAkC;IACxD,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;CACZ,CAAC;AAEjC,MAAM,kBAAkB,GAAmC;IAC1D,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE;IACtC,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;IAC9C,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;IAC9C,iBAAiB,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;IACpD,cAAc,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;IACjD,aAAa,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;IAChD,mBAAmB,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;IACtD,iBAAiB,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;CACpB,CAAC;AAElC,MAAM,CAAC,MAAM,wBAAwB,GAAuC;IAC3E,GAAG,kBAAkB;IACrB,GAAG,iBAAiB;IACpB,GAAG,eAAe;IAClB,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;CACb,CAAC"}
1
+ {"version":3,"file":"mongooseRuleSchema.js","sourceRoot":"","sources":["../../src/mongoose/mongooseRuleSchema.ts"],"names":[],"mappings":"AAwBA,MAAM,oBAAoB,GAA2C;IACpE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;IACzC,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;IAC1C,SAAS,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;IAC5C,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;IAC9C,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;IAC3C,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;IACzC,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;IAC9C,GAAG,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;CACE,CAAC;AAE1C,MAAM,YAAY,GAAmC;IACpD,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;IACrC,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;CACT,CAAC;AAElC,MAAM,eAAe,GAAsC;IAC1D,GAAG,oBAAoB;IACvB,GAAG,YAAY;CACiB,CAAC;AAElC,MAAM,iBAAiB,GAAkC;IACxD,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;CACZ,CAAC;AAEjC,MAAM,kBAAkB,GAAmC;IAC1D,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE;IACtC,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;IAC9C,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;IAC9C,iBAAiB,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;IACpD,cAAc,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;IACjD,aAAa,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;IAChD,mBAAmB,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;IACtD,iBAAiB,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;IACpD,aAAa,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE;CACjB,CAAC;AAElC,MAAM,CAAC,MAAM,wBAAwB,GAAuC;IAC3E,GAAG,kBAAkB;IACrB,GAAG,iBAAiB;IACpB,GAAG,eAAe;IAClB,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;CACb,CAAC"}
@@ -1,4 +1,4 @@
1
1
  import type { Logger } from "@prosopo/logger";
2
2
  import type { RedisClientType } from "redis";
3
- export declare const aggregateRedisKeys: (client: RedisClientType, query: string, logger: Logger, batchHandler?: (keys: string[]) => Promise<void>) => Promise<string[]>;
3
+ export declare const aggregateRedisKeys: (client: RedisClientType, query: string, logger: Logger, batchHandler?: (keys: string[]) => Promise<void>, maxKeys?: number) => Promise<string[]>;
4
4
  //# sourceMappingURL=redisAggregate.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"redisAggregate.d.ts","sourceRoot":"","sources":["../../../src/redis/reader/redisAggregate.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAE9C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,OAAO,CAAC;AAU7C,eAAO,MAAM,kBAAkB,WACtB,eAAe,SAChB,MAAM,UACL,MAAM,iBACC,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,KAC9C,OAAO,CAAC,MAAM,EAAE,CA0ClB,CAAC"}
1
+ {"version":3,"file":"redisAggregate.d.ts","sourceRoot":"","sources":["../../../src/redis/reader/redisAggregate.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAE9C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,OAAO,CAAC;AAU7C,eAAO,MAAM,kBAAkB,WACtB,eAAe,SAChB,MAAM,UACL,MAAM,iBACC,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,YACtC,MAAM,KACd,OAAO,CAAC,MAAM,EAAE,CAkElB,CAAC"}
@@ -2,19 +2,36 @@ import { z } from "zod";
2
2
  import { REDIS_QUERY_DIALECT } from "./redisRulesQuery.js";
3
3
  import { parseRedisRecords, REDIS_BATCH_SIZE } from "../redisClient.js";
4
4
  import { ACCESS_RULES_REDIS_INDEX_NAME } from "../redisRuleIndex.js";
5
- const aggregateRedisKeys = async (client, query, logger, batchHandler) => {
5
+ const aggregateRedisKeys = async (client, query, logger, batchHandler, maxKeys) => {
6
6
  const keyField = "__key";
7
7
  const recordSchema = z.object({
8
8
  // it's a reserved name for the record key
9
9
  [keyField]: z.string()
10
10
  });
11
11
  const foundKeys = [];
12
+ let stopRequested = false;
12
13
  const addRecordKeys = async (records) => {
14
+ if (stopRequested) {
15
+ return;
16
+ }
13
17
  const parsedRecords = parseRedisRecords(records, recordSchema, logger);
14
18
  const recordKeys = parsedRecords.map((record) => record[keyField]);
15
19
  if (batchHandler) {
16
20
  await batchHandler(recordKeys);
17
21
  } else {
22
+ if (maxKeys !== void 0 && foundKeys.length + recordKeys.length > maxKeys) {
23
+ const remaining = Math.max(0, maxKeys - foundKeys.length);
24
+ foundKeys.push(...recordKeys.slice(0, remaining));
25
+ stopRequested = true;
26
+ logger.warn(() => ({
27
+ msg: "Redis aggregation candidate cap hit; truncating result set. This can suppress less-frequent rules and should be investigated.",
28
+ data: {
29
+ maxKeys,
30
+ query
31
+ }
32
+ }));
33
+ return;
34
+ }
18
35
  foundKeys.push(...recordKeys);
19
36
  logger.debug(() => ({
20
37
  msg: "Processed aggregation batch",
@@ -33,11 +50,12 @@ const aggregateRedisKeys = async (client, query, logger, batchHandler) => {
33
50
  COUNT: REDIS_BATCH_SIZE,
34
51
  LOAD: `@${keyField}`
35
52
  },
36
- addRecordKeys
53
+ addRecordKeys,
54
+ () => stopRequested
37
55
  );
38
56
  return foundKeys;
39
57
  };
40
- const executeAggregation = async (client, query, aggregateOptions, handleBatch) => {
58
+ const executeAggregation = async (client, query, aggregateOptions, handleBatch, shouldStop) => {
41
59
  const initialReply = await client.ft.aggregateWithCursor(
42
60
  ACCESS_RULES_REDIS_INDEX_NAME,
43
61
  query,
@@ -45,7 +63,7 @@ const executeAggregation = async (client, query, aggregateOptions, handleBatch)
45
63
  );
46
64
  await handleBatch(initialReply.results);
47
65
  let cursor = initialReply.cursor;
48
- while (0 !== cursor) {
66
+ while (0 !== cursor && !shouldStop?.()) {
49
67
  const batchReply = await client.ft.cursorRead(
50
68
  ACCESS_RULES_REDIS_INDEX_NAME,
51
69
  cursor,
@@ -1 +1 @@
1
- {"version":3,"file":"redisAggregate.js","sourceRoot":"","sources":["../../../src/redis/reader/redisAggregate.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AAC9E,OAAO,EACN,gBAAgB,EAChB,iBAAiB,GACjB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,6BAA6B,EAAE,MAAM,iCAAiC,CAAC;AAGhF,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,EACtC,MAAuB,EACvB,KAAa,EACb,MAAc,EACd,YAAgD,EAC5B,EAAE;IACtB,MAAM,QAAQ,GAAG,OAAO,CAAC;IAEzB,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;QAE7B,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE;KACtB,CAAC,CAAC;IAEH,MAAM,SAAS,GAAa,EAAE,CAAC;IAE/B,MAAM,aAAa,GAAG,KAAK,EAAE,OAAiB,EAAE,EAAE;QACjD,MAAM,aAAa,GAAG,iBAAiB,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,CAAC,CAAC;QAEvE,MAAM,UAAU,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QAEnE,IAAI,YAAY,EAAE,CAAC;YAClB,MAAM,YAAY,CAAC,UAAU,CAAC,CAAC;QAChC,CAAC;aAAM,CAAC;YACP,SAAS,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,CAAC;YAE9B,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;gBACnB,GAAG,EAAE,6BAA6B;gBAClC,IAAI,EAAE;oBACL,IAAI,EAAE,UAAU,CAAC,MAAM;iBACvB;aACD,CAAC,CAAC,CAAC;QACL,CAAC;IACF,CAAC,CAAC;IAEF,MAAM,kBAAkB,CACvB,MAAM,EACN,KAAK,EACL;QAEC,OAAO,EAAE,mBAAmB;QAC5B,KAAK,EAAE,gBAAgB;QACvB,IAAI,EAAE,IAAI,QAAQ,EAAE;KACpB,EACD,aAAa,CACb,CAAC;IAEF,OAAO,SAAS,CAAC;AAClB,CAAC,CAAC;AAEF,MAAM,kBAAkB,GAAG,KAAK,EAC/B,MAAuB,EACvB,KAAa,EACb,gBAA8C,EAC9C,WAAiD,EACjC,EAAE;IAClB,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,EAAE,CAAC,mBAAmB,CACvD,6BAA6B,EAC7B,KAAK,EACL,gBAAgB,CAChB,CAAC;IAEF,MAAM,WAAW,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IAExC,IAAI,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC;IAEjC,OAAO,CAAC,KAAK,MAAM,EAAE,CAAC;QACrB,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,EAAE,CAAC,UAAU,CAC5C,6BAA6B,EAC7B,MAAM,EACN,EAAE,KAAK,EAAE,gBAAgB,CAAC,KAAK,EAAE,CACjC,CAAC;QAEF,MAAM,WAAW,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAEtC,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC;IAC5B,CAAC;AACF,CAAC,CAAC"}
1
+ {"version":3,"file":"redisAggregate.js","sourceRoot":"","sources":["../../../src/redis/reader/redisAggregate.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@ import type { Logger } from "@prosopo/logger";
2
2
  import type { RedisClientType } from "redis";
3
3
  import type { AccessRule } from "#policy/rule.js";
4
4
  import type { AccessRuleEntry, AccessRulesFilter, AccessRulesReader } from "#policy/rulesStorage.js";
5
+ export declare const FIND_RULES_MAX_CANDIDATES: number;
5
6
  export declare class RedisRulesReader implements AccessRulesReader {
6
7
  private readonly client;
7
8
  private readonly logger;
@@ -1 +1 @@
1
- {"version":3,"file":"redisRulesReader.d.ts","sourceRoot":"","sources":["../../../src/redis/reader/redisRulesReader.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,OAAO,CAAC;AAe7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,OAAO,KAAK,EACX,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,MAAM,yBAAyB,CAAC;AAGjC,qBAAa,gBAAiB,YAAW,iBAAiB;IAExD,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBADN,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,MAAM;IAG1B,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAcvD,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAazD,SAAS,CACd,MAAM,EAAE,iBAAiB,EACzB,kBAAkB,UAAQ,EAC1B,mBAAmB,UAAO,GACxB,OAAO,CAAC,UAAU,EAAE,CAAC;IA8ElB,WAAW,CAChB,MAAM,EAAE,iBAAiB,EACzB,kBAAkB,UAAQ,GACxB,OAAO,CAAC,MAAM,EAAE,CAAC;IAgDd,eAAe,CACpB,YAAY,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,GAChD,OAAO,CAAC,IAAI,CAAC;cAYA,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IA8B5E,SAAS,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE;CAGlD;AAED,qBAAa,qBAAsB,YAAW,iBAAiB;IAClD,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,MAAM;IAErC,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAWvD,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAWzD,SAAS,CACd,MAAM,EAAE,iBAAiB,EACzB,kBAAkB,UAAQ,EAC1B,mBAAmB,UAAO,GACxB,OAAO,CAAC,UAAU,EAAE,CAAC;IAWlB,WAAW,CAChB,MAAM,EAAE,iBAAiB,EACzB,kBAAkB,UAAQ,GACxB,OAAO,CAAC,MAAM,EAAE,CAAC;IAWd,eAAe,CACpB,YAAY,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,GAChD,OAAO,CAAC,IAAI,CAAC;CAKhB"}
1
+ {"version":3,"file":"redisRulesReader.d.ts","sourceRoot":"","sources":["../../../src/redis/reader/redisRulesReader.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,OAAO,CAAC;AAS7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,OAAO,KAAK,EACX,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,MAAM,yBAAyB,CAAC;AAUjC,eAAO,MAAM,yBAAyB,QAAwB,CAAC;AAE/D,qBAAa,gBAAiB,YAAW,iBAAiB;IAExD,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBADN,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,MAAM;IAG1B,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAcvD,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAazD,SAAS,CACd,MAAM,EAAE,iBAAiB,EACzB,kBAAkB,UAAQ,EAC1B,mBAAmB,UAAO,GACxB,OAAO,CAAC,UAAU,EAAE,CAAC;IA6ElB,WAAW,CAChB,MAAM,EAAE,iBAAiB,EACzB,kBAAkB,UAAQ,GACxB,OAAO,CAAC,MAAM,EAAE,CAAC;IAgDd,eAAe,CACpB,YAAY,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,GAChD,OAAO,CAAC,IAAI,CAAC;cAYA,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IA8B5E,SAAS,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE;CAGlD;AAED,qBAAa,qBAAsB,YAAW,iBAAiB;IAClD,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,MAAM;IAErC,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAWvD,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAWzD,SAAS,CACd,MAAM,EAAE,iBAAiB,EACzB,kBAAkB,UAAQ,EAC1B,mBAAmB,UAAO,GACxB,OAAO,CAAC,UAAU,EAAE,CAAC;IAWlB,WAAW,CAChB,MAAM,EAAE,iBAAiB,EACzB,kBAAkB,UAAQ,GACxB,OAAO,CAAC,MAAM,EAAE,CAAC;IAWd,eAAe,CACpB,YAAY,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,GAChD,OAAO,CAAC,IAAI,CAAC;CAKhB"}