@prosopo/user-access-policy 3.9.1 → 3.10.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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @prosopo/user-access-policy@3.9.1 build:cjs
2
+ > @prosopo/user-access-policy@3.10.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: .
@@ -35,37 +35,37 @@ transforming...
35
35
  Build end
36
36
  ✓ 33 modules transformed.
37
37
  rendering chunks...
38
- dist/cjs/api/delete/.export.cjs 0.01 kB
39
- dist/cjs/api/read/.export.cjs 0.01 kB
40
- dist/cjs/api/write/.export.cjs 0.01 kB
41
- dist/cjs/mongoose/.export.cjs 0.23 kB
42
- dist/cjs/rulesStorage.cjs 0.34 kB
43
- dist/cjs/rule.cjs 0.34 kB
44
- dist/cjs/redis/.export.cjs 0.36 kB
45
- dist/cjs/ruleInput/.export.cjs 0.46 kB
46
- dist/cjs/api/.export.cjs 0.57 kB
47
- dist/cjs/api/delete/deleteAllRules.cjs 0.77 kB
48
- dist/cjs/ruleRecord.cjs 0.83 kB
49
- dist/cjs/api/read/getMissingIds.cjs 1.15 kB
50
- dist/cjs/api/read/fetchRules.cjs 1.22 kB
51
- dist/cjs/.export.cjs 1.24 kB
52
- dist/cjs/redis/redisRulesStorage.cjs 1.35 kB
53
- dist/cjs/mongoose/mongooseRuleSchema.cjs 1.48 kB
54
- dist/cjs/api/delete/deleteRules.cjs 1.51 kB
55
- dist/cjs/api/delete/deleteRuleGroups.cjs 1.57 kB
56
- dist/cjs/api/write/rehashRules.cjs 1.64 kB
57
- dist/cjs/api/read/findRuleIds.cjs 1.65 kB
58
- dist/cjs/ruleInput/policyInput.cjs 1.70 kB
59
- dist/cjs/ruleInput/ruleInput.cjs 2.07 kB
60
- dist/cjs/redis/redisClient.cjs 2.09 kB
61
- dist/cjs/ruleInput/userScopeInput.cjs 2.45 kB
62
- dist/cjs/redis/redisRuleIndex.cjs 2.46 kB
63
- dist/cjs/api/rulesApiClient.cjs 2.60 kB
64
- dist/cjs/redis/reader/redisAggregate.cjs 2.61 kB
65
- dist/cjs/transformRule.cjs 3.05 kB
66
- dist/cjs/api/write/insertRules.cjs 3.38 kB
67
- dist/cjs/redis/redisRulesWriter.cjs 3.44 kB
68
- dist/cjs/redis/reader/redisRulesQuery.cjs 4.34 kB
69
- dist/cjs/api/ruleApiRoutes.cjs 4.55 kB
70
- dist/cjs/redis/reader/redisRulesReader.cjs 6.87 kB
71
- ✓ built in 451ms
38
+ dist/cjs/api/delete/.export.cjs  0.01 kB
39
+ dist/cjs/api/read/.export.cjs  0.01 kB
40
+ dist/cjs/api/write/.export.cjs  0.01 kB
41
+ dist/cjs/mongoose/.export.cjs  0.23 kB
42
+ dist/cjs/rulesStorage.cjs  0.34 kB
43
+ dist/cjs/rule.cjs  0.34 kB
44
+ dist/cjs/redis/.export.cjs  0.36 kB
45
+ dist/cjs/ruleInput/.export.cjs  0.46 kB
46
+ dist/cjs/api/.export.cjs  0.57 kB
47
+ dist/cjs/api/delete/deleteAllRules.cjs  0.77 kB
48
+ dist/cjs/ruleRecord.cjs  0.83 kB
49
+ dist/cjs/api/read/getMissingIds.cjs  1.15 kB
50
+ dist/cjs/api/read/fetchRules.cjs  1.22 kB
51
+ dist/cjs/.export.cjs  1.24 kB
52
+ dist/cjs/redis/redisRulesStorage.cjs  1.35 kB
53
+ dist/cjs/mongoose/mongooseRuleSchema.cjs  1.48 kB
54
+ dist/cjs/api/delete/deleteRules.cjs  1.51 kB
55
+ dist/cjs/api/delete/deleteRuleGroups.cjs  1.57 kB
56
+ dist/cjs/api/write/rehashRules.cjs  1.64 kB
57
+ dist/cjs/api/read/findRuleIds.cjs  1.65 kB
58
+ dist/cjs/ruleInput/policyInput.cjs  1.70 kB
59
+ dist/cjs/ruleInput/ruleInput.cjs  2.07 kB
60
+ dist/cjs/redis/redisClient.cjs  2.09 kB
61
+ dist/cjs/ruleInput/userScopeInput.cjs  2.45 kB
62
+ dist/cjs/redis/redisRuleIndex.cjs  2.46 kB
63
+ dist/cjs/api/rulesApiClient.cjs  2.60 kB
64
+ dist/cjs/redis/reader/redisAggregate.cjs  2.61 kB
65
+ dist/cjs/transformRule.cjs  3.05 kB
66
+ dist/cjs/api/write/insertRules.cjs  3.38 kB
67
+ dist/cjs/redis/redisRulesWriter.cjs  3.44 kB
68
+ dist/cjs/redis/reader/redisRulesQuery.cjs  4.34 kB
69
+ dist/cjs/api/ruleApiRoutes.cjs  4.55 kB
70
+ dist/cjs/redis/reader/redisRulesReader.cjs 10.28 kB
71
+ ✓ built in 437ms
@@ -1,8 +1,8 @@
1
1
 
2
- > @prosopo/user-access-policy@3.9.1 build:tsc
2
+ > @prosopo/user-access-policy@3.10.1 build:tsc
3
3
  > tsc --build --verbose
4
4
 
5
- 1:19:54 PM - Projects in this build:
5
+ 7:45:31 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
- 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'
18
+ 7:45:31 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
- 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'
20
+ 7:45:31 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
- 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'
22
+ 7:45:31 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
- 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'
24
+ 7:45:31 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
- 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'
26
+ 7:45:31 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
- 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'
28
+ 7:45:31 PM - Project '../types/tsconfig.json' is up to date because newest input '../types/src/procaptcha/behavioral.ts' is older than output '../types/tsconfig.tsbuildinfo'
29
29
 
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'
30
+ 7:45:31 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
- 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'
32
+ 7:45:31 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
- 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'
34
+ 7:45:31 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
- 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'
36
+ 7:45:31 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
- 1:19:55 PM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
38
+ 7:45:31 PM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
39
39
 
40
- 1:19:55 PM - Building project '/home/runner/work/captcha/captcha/packages/user-access-policy/tsconfig.json'...
40
+ 7:45:31 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.9.1 build
2
+ > @prosopo/user-access-policy@3.10.1 build
3
3
  > npm run build:cross-env -- --mode ${NODE_ENV:-development}
4
4
 
5
5
 
6
- > @prosopo/user-access-policy@3.9.1 build:cross-env
6
+ > @prosopo/user-access-policy@3.10.1 build:cross-env
7
7
  > vite build --config vite.esm.config.ts --mode production
8
8
 
9
9
  ViteEsmConfig: .
@@ -71,5 +71,5 @@ rendering chunks...
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.02 kB
75
- ✓ built in 473ms
74
+ dist/redis/reader/redisRulesReader.js 9.40 kB
75
+ ✓ built in 467ms
package/CHANGELOG.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # @prosopo/user-access-policy
2
2
 
3
+ ## 3.10.1
4
+ ### Patch Changes
5
+
6
+ - Updated dependencies [55b1388]
7
+ - @prosopo/util@3.3.0
8
+ - @prosopo/types@4.6.0
9
+ - @prosopo/logger@1.0.3
10
+ - @prosopo/api@3.4.13
11
+ - @prosopo/common@3.1.39
12
+ - @prosopo/api-route@2.6.47
13
+ - @prosopo/redis-client@1.0.24
14
+
15
+ ## 3.10.0
16
+ ### Minor Changes
17
+
18
+ - c1c7998: Server-side specificity rank for the access-rule lookup. Strict-match callers (the `blockMiddleware` and the verify-time `checkForHardBlock`) now issue one `FT.AGGREGATE` with `APPLY exists()` for specificity, `APPLY @type == "block"` for the severity tiebreak, `SORTBY @_rank DESC`, and `LIMIT 0 20`. Node receives at most 20 fully-populated rules — no follow-up HGETALL per candidate, no JS-side rank, no silent truncation past the LIMIT (which only applies after Redis has scored every candidate the strict filter returned).
19
+
20
+ Supersedes both the v3.6.38 regression (`b520cd94c` — FT.AGGREGATE WITHCURSOR materialising ~1190 hashes per request, pegged provider1 at ~125% CPU on pronode10) and the 3.6.38-hotfix1 shape that reverted to FT.SEARCH (re-opened the 1000-candidate silent-truncation bug). The greedy/admin path (`matchingFieldsOnly=false`) keeps the FT.AGGREGATE+CURSOR approach with a generous `GREEDY_MAX_CANDIDATES` cap since those callers do not run on the per-request hot path.
21
+
22
+ `packages/provider/src/api/blacklistRequestInspector.ts` flips `getPrioritisedAccessRule` to `matchingFieldsOnly: true` to engage the new path. The defensive JS `rankCandidateRules` is kept so any drift between the Redis-side score and the JS semantics surfaces as ordering, not as letting traffic through. New benchmark integration test seeds 10k rules across a realistic specificity distribution and asserts p50 < 80ms / p99 < 250ms over 200 lookups; local measurement is steady at p50 ≈ 20ms, p99 ≈ 24ms.
23
+
24
+ ### Patch Changes
25
+
26
+ - Updated dependencies [9b91e85]
27
+ - Updated dependencies [c80a05b]
28
+ - @prosopo/types@4.5.0
29
+ - @prosopo/api@3.4.12
30
+
3
31
  ## 3.9.1
4
32
  ### Patch Changes
5
33
 
@@ -5,6 +5,7 @@ const common = require("@prosopo/common");
5
5
  const redisRulesQuery = require("./redisRulesQuery.cjs");
6
6
  const redisClient = require("../redisClient.cjs");
7
7
  const redisRuleIndex = require("../redisRuleIndex.cjs");
8
+ const rule = require("../../rule.cjs");
8
9
  const ruleInput = require("../../ruleInput/ruleInput.cjs");
9
10
  const redisAggregate = require("./redisAggregate.cjs");
10
11
  function _interopNamespaceDefault(e) {
@@ -24,7 +25,48 @@ function _interopNamespaceDefault(e) {
24
25
  return Object.freeze(n);
25
26
  }
26
27
  const util__namespace = /* @__PURE__ */ _interopNamespaceDefault(util);
27
- const FIND_RULES_MAX_CANDIDATES = redisClient.REDIS_BATCH_SIZE * 10;
28
+ const SERVER_SIDE_RANK_TOP_N = 20;
29
+ const GREEDY_MAX_CANDIDATES = redisClient.REDIS_BATCH_SIZE * 10;
30
+ const SPECIFICITY_EXPR = [
31
+ "exists(@clientId)",
32
+ "exists(@userId)",
33
+ "exists(@ja4Hash)",
34
+ "exists(@headersHash)",
35
+ "exists(@userAgentHash)",
36
+ "exists(@headHash)",
37
+ "exists(@coords)",
38
+ "exists(@countryCode)",
39
+ "exists(@asn)",
40
+ "exists(@numericIp)",
41
+ "exists(@numericIpMaskMin)"
42
+ ].join(" + ");
43
+ const SEVERITY_EXPR = `(@type == "${rule.AccessPolicyType.Block}")`;
44
+ const RANK_EXPR = "(@_spec * 2) + @_sev";
45
+ const RULE_LOAD_FIELDS = [
46
+ "@__key",
47
+ "@type",
48
+ "@captchaType",
49
+ "@description",
50
+ "@solvedImagesCount",
51
+ "@imageThreshold",
52
+ "@powDifficulty",
53
+ "@unsolvedImagesCount",
54
+ "@frictionlessScore",
55
+ "@deferToVerify",
56
+ "@clientId",
57
+ "@groupId",
58
+ "@userId",
59
+ "@ja4Hash",
60
+ "@headersHash",
61
+ "@userAgentHash",
62
+ "@headHash",
63
+ "@coords",
64
+ "@countryCode",
65
+ "@asn",
66
+ "@numericIp",
67
+ "@numericIpMaskMin",
68
+ "@numericIpMaskMax"
69
+ ];
28
70
  class RedisRulesReader {
29
71
  constructor(client, logger) {
30
72
  this.client = client;
@@ -53,19 +95,88 @@ class RedisRulesReader {
53
95
  if (skipEmptyUserScopes && query === "ismissing(@clientId)") {
54
96
  return [];
55
97
  }
98
+ if (matchingFieldsOnly) {
99
+ return this.findRulesRanked(filter, query);
100
+ }
101
+ return this.findRulesGreedy(filter, query);
102
+ }
103
+ async findRulesRanked(filter, query) {
104
+ try {
105
+ const reply = await this.client.ft.aggregate(
106
+ redisRuleIndex.ACCESS_RULES_REDIS_INDEX_NAME,
107
+ query,
108
+ {
109
+ DIALECT: redisRulesQuery.REDIS_QUERY_DIALECT,
110
+ LOAD: [...RULE_LOAD_FIELDS],
111
+ STEPS: [
112
+ { type: "APPLY", expression: SPECIFICITY_EXPR, AS: "_spec" },
113
+ { type: "APPLY", expression: SEVERITY_EXPR, AS: "_sev" },
114
+ { type: "APPLY", expression: RANK_EXPR, AS: "_rank" },
115
+ {
116
+ type: "SORTBY",
117
+ BY: [{ BY: "@_rank", DIRECTION: "DESC" }]
118
+ // SORTBY MAX would let RediSearch keep only the
119
+ // top-N in a bounded heap rather than fully
120
+ // sorting, but the @redis/search client
121
+ // serialises MAX *before* DESC and RediSearch
122
+ // rejects that order ("MISSING ASC or DESC
123
+ // after sort field (MAX)"). LIMIT below still
124
+ // trims; SORTBY does a full sort. Acceptable
125
+ // because the strict-match filter already
126
+ // keeps the candidate set small in practice.
127
+ },
128
+ { type: "LIMIT", from: 0, size: SERVER_SIDE_RANK_TOP_N }
129
+ ]
130
+ }
131
+ );
132
+ if (reply.results.length === 0) {
133
+ return [];
134
+ }
135
+ this.logger.debug(() => ({
136
+ msg: "Executed ranked search query",
137
+ data: {
138
+ inspect: util__namespace.inspect(
139
+ {
140
+ filter,
141
+ foundCount: reply.results.length,
142
+ query
143
+ },
144
+ { depth: null }
145
+ )
146
+ }
147
+ }));
148
+ return redisClient.parseRedisRecords(reply.results, ruleInput.accessRuleInput, this.logger);
149
+ } catch (e) {
150
+ this.logger.error(() => ({
151
+ err: e,
152
+ data: {
153
+ inspect: util__namespace.inspect({ query, filter }, { depth: null })
154
+ },
155
+ msg: "failed to execute ranked search query"
156
+ }));
157
+ return [];
158
+ }
159
+ }
160
+ // Used only by admin / internal callers (matchingFieldsOnly=false).
161
+ // Not on the per-request blockMiddleware path any more, so the CPU
162
+ // cost of the HGETALL fanout is acceptable. Same shape as #2689's
163
+ // aggregate-with-cursor: returns every candidate up to
164
+ // GREEDY_MAX_CANDIDATES so we don't silently drop matches that
165
+ // admin tools depend on (e.g. ASN-wide rule listings).
166
+ async findRulesGreedy(filter, query) {
56
167
  try {
57
168
  const ruleKeys = await redisAggregate.aggregateRedisKeys(
58
169
  this.client,
59
170
  query,
60
171
  this.logger,
61
172
  void 0,
62
- FIND_RULES_MAX_CANDIDATES
173
+ GREEDY_MAX_CANDIDATES
63
174
  );
64
175
  if (ruleKeys.length === 0) {
65
176
  return [];
66
177
  }
67
178
  this.logger.debug(() => ({
68
- msg: "Executed search query",
179
+ msg: "Executed greedy search query",
69
180
  data: {
70
181
  inspect: util__namespace.inspect(
71
182
  {
@@ -90,17 +201,9 @@ class RedisRulesReader {
90
201
  this.logger.error(() => ({
91
202
  err: e,
92
203
  data: {
93
- inspect: util__namespace.inspect(
94
- {
95
- query,
96
- filter
97
- },
98
- {
99
- depth: null
100
- }
101
- )
204
+ inspect: util__namespace.inspect({ query, filter }, { depth: null })
102
205
  },
103
- msg: "failed to execute search query"
206
+ msg: "failed to execute greedy search query"
104
207
  }));
105
208
  return [];
106
209
  }
@@ -164,14 +267,14 @@ class RedisRulesReader {
164
267
  for (const [index, ruleData] of records.entries()) {
165
268
  const isRulePresent = Object.keys(ruleData).length > 0;
166
269
  if (isRulePresent) {
167
- const rule = redisClient.parseRedisRecords(
270
+ const rule2 = redisClient.parseRedisRecords(
168
271
  [ruleData],
169
272
  ruleInput.accessRuleInput,
170
273
  this.logger
171
274
  )[0];
172
- if (rule) {
275
+ if (rule2) {
173
276
  entries.push({
174
- rule,
277
+ rule: rule2,
175
278
  expiresUnixTimestamp: expirations[index]
176
279
  });
177
280
  }
@@ -230,5 +333,5 @@ class DummyRedisRulesReader {
230
333
  }
231
334
  }
232
335
  exports.DummyRedisRulesReader = DummyRedisRulesReader;
233
- exports.FIND_RULES_MAX_CANDIDATES = FIND_RULES_MAX_CANDIDATES;
234
336
  exports.RedisRulesReader = RedisRulesReader;
337
+ exports.SERVER_SIDE_RANK_TOP_N = SERVER_SIDE_RANK_TOP_N;
@@ -1,8 +1,8 @@
1
1
  import type { Logger } from "@prosopo/logger";
2
2
  import type { RedisClientType } from "redis";
3
- import type { AccessRule } from "#policy/rule.js";
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
+ export declare const SERVER_SIDE_RANK_TOP_N = 20;
6
6
  export declare class RedisRulesReader implements AccessRulesReader {
7
7
  private readonly client;
8
8
  private readonly logger;
@@ -10,6 +10,8 @@ export declare class RedisRulesReader implements AccessRulesReader {
10
10
  getMissingRuleIds(ruleIds: string[]): Promise<string[]>;
11
11
  fetchRules(ruleIds: string[]): Promise<AccessRuleEntry[]>;
12
12
  findRules(filter: AccessRulesFilter, matchingFieldsOnly?: boolean, skipEmptyUserScopes?: boolean): Promise<AccessRule[]>;
13
+ private findRulesRanked;
14
+ private findRulesGreedy;
13
15
  findRuleIds(filter: AccessRulesFilter, matchingFieldsOnly?: boolean): Promise<string[]>;
14
16
  fetchAllRuleIds(batchHandler: (ruleIds: string[]) => Promise<void>): Promise<void>;
15
17
  protected fetchRuleEntries(keys: string[]): Promise<AccessRuleEntry[]>;
@@ -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;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"}
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,EAAoB,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAEpE,OAAO,KAAK,EACX,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,MAAM,yBAAyB,CAAC;AAoBjC,eAAO,MAAM,sBAAsB,KAAK,CAAC;AAoEzC,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;YAuBV,eAAe;YA2Ef,eAAe;IAuDvB,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,11 +1,53 @@
1
1
  import * as util from "node:util";
2
2
  import { chunkIntoBatches, executeBatchesSequentially } from "@prosopo/common";
3
- import { getRulesRedisQuery } from "./redisRulesQuery.js";
4
- import { REDIS_BATCH_SIZE, getMissingRedisKeys, fetchRedisHashRecords, parseRedisRecords } from "../redisClient.js";
5
- import { ACCESS_RULE_REDIS_KEY_PREFIX } from "../redisRuleIndex.js";
3
+ import { getRulesRedisQuery, REDIS_QUERY_DIALECT } from "./redisRulesQuery.js";
4
+ import { REDIS_BATCH_SIZE, getMissingRedisKeys, parseRedisRecords, fetchRedisHashRecords } from "../redisClient.js";
5
+ import { ACCESS_RULE_REDIS_KEY_PREFIX, ACCESS_RULES_REDIS_INDEX_NAME } from "../redisRuleIndex.js";
6
+ import { AccessPolicyType } from "../../rule.js";
6
7
  import { accessRuleInput } from "../../ruleInput/ruleInput.js";
7
8
  import { aggregateRedisKeys } from "./redisAggregate.js";
8
- const FIND_RULES_MAX_CANDIDATES = REDIS_BATCH_SIZE * 10;
9
+ const SERVER_SIDE_RANK_TOP_N = 20;
10
+ const GREEDY_MAX_CANDIDATES = REDIS_BATCH_SIZE * 10;
11
+ const SPECIFICITY_EXPR = [
12
+ "exists(@clientId)",
13
+ "exists(@userId)",
14
+ "exists(@ja4Hash)",
15
+ "exists(@headersHash)",
16
+ "exists(@userAgentHash)",
17
+ "exists(@headHash)",
18
+ "exists(@coords)",
19
+ "exists(@countryCode)",
20
+ "exists(@asn)",
21
+ "exists(@numericIp)",
22
+ "exists(@numericIpMaskMin)"
23
+ ].join(" + ");
24
+ const SEVERITY_EXPR = `(@type == "${AccessPolicyType.Block}")`;
25
+ const RANK_EXPR = "(@_spec * 2) + @_sev";
26
+ const RULE_LOAD_FIELDS = [
27
+ "@__key",
28
+ "@type",
29
+ "@captchaType",
30
+ "@description",
31
+ "@solvedImagesCount",
32
+ "@imageThreshold",
33
+ "@powDifficulty",
34
+ "@unsolvedImagesCount",
35
+ "@frictionlessScore",
36
+ "@deferToVerify",
37
+ "@clientId",
38
+ "@groupId",
39
+ "@userId",
40
+ "@ja4Hash",
41
+ "@headersHash",
42
+ "@userAgentHash",
43
+ "@headHash",
44
+ "@coords",
45
+ "@countryCode",
46
+ "@asn",
47
+ "@numericIp",
48
+ "@numericIpMaskMin",
49
+ "@numericIpMaskMax"
50
+ ];
9
51
  class RedisRulesReader {
10
52
  constructor(client, logger) {
11
53
  this.client = client;
@@ -34,19 +76,88 @@ class RedisRulesReader {
34
76
  if (skipEmptyUserScopes && query === "ismissing(@clientId)") {
35
77
  return [];
36
78
  }
79
+ if (matchingFieldsOnly) {
80
+ return this.findRulesRanked(filter, query);
81
+ }
82
+ return this.findRulesGreedy(filter, query);
83
+ }
84
+ async findRulesRanked(filter, query) {
85
+ try {
86
+ const reply = await this.client.ft.aggregate(
87
+ ACCESS_RULES_REDIS_INDEX_NAME,
88
+ query,
89
+ {
90
+ DIALECT: REDIS_QUERY_DIALECT,
91
+ LOAD: [...RULE_LOAD_FIELDS],
92
+ STEPS: [
93
+ { type: "APPLY", expression: SPECIFICITY_EXPR, AS: "_spec" },
94
+ { type: "APPLY", expression: SEVERITY_EXPR, AS: "_sev" },
95
+ { type: "APPLY", expression: RANK_EXPR, AS: "_rank" },
96
+ {
97
+ type: "SORTBY",
98
+ BY: [{ BY: "@_rank", DIRECTION: "DESC" }]
99
+ // SORTBY MAX would let RediSearch keep only the
100
+ // top-N in a bounded heap rather than fully
101
+ // sorting, but the @redis/search client
102
+ // serialises MAX *before* DESC and RediSearch
103
+ // rejects that order ("MISSING ASC or DESC
104
+ // after sort field (MAX)"). LIMIT below still
105
+ // trims; SORTBY does a full sort. Acceptable
106
+ // because the strict-match filter already
107
+ // keeps the candidate set small in practice.
108
+ },
109
+ { type: "LIMIT", from: 0, size: SERVER_SIDE_RANK_TOP_N }
110
+ ]
111
+ }
112
+ );
113
+ if (reply.results.length === 0) {
114
+ return [];
115
+ }
116
+ this.logger.debug(() => ({
117
+ msg: "Executed ranked search query",
118
+ data: {
119
+ inspect: util.inspect(
120
+ {
121
+ filter,
122
+ foundCount: reply.results.length,
123
+ query
124
+ },
125
+ { depth: null }
126
+ )
127
+ }
128
+ }));
129
+ return parseRedisRecords(reply.results, accessRuleInput, this.logger);
130
+ } catch (e) {
131
+ this.logger.error(() => ({
132
+ err: e,
133
+ data: {
134
+ inspect: util.inspect({ query, filter }, { depth: null })
135
+ },
136
+ msg: "failed to execute ranked search query"
137
+ }));
138
+ return [];
139
+ }
140
+ }
141
+ // Used only by admin / internal callers (matchingFieldsOnly=false).
142
+ // Not on the per-request blockMiddleware path any more, so the CPU
143
+ // cost of the HGETALL fanout is acceptable. Same shape as #2689's
144
+ // aggregate-with-cursor: returns every candidate up to
145
+ // GREEDY_MAX_CANDIDATES so we don't silently drop matches that
146
+ // admin tools depend on (e.g. ASN-wide rule listings).
147
+ async findRulesGreedy(filter, query) {
37
148
  try {
38
149
  const ruleKeys = await aggregateRedisKeys(
39
150
  this.client,
40
151
  query,
41
152
  this.logger,
42
153
  void 0,
43
- FIND_RULES_MAX_CANDIDATES
154
+ GREEDY_MAX_CANDIDATES
44
155
  );
45
156
  if (ruleKeys.length === 0) {
46
157
  return [];
47
158
  }
48
159
  this.logger.debug(() => ({
49
- msg: "Executed search query",
160
+ msg: "Executed greedy search query",
50
161
  data: {
51
162
  inspect: util.inspect(
52
163
  {
@@ -71,17 +182,9 @@ class RedisRulesReader {
71
182
  this.logger.error(() => ({
72
183
  err: e,
73
184
  data: {
74
- inspect: util.inspect(
75
- {
76
- query,
77
- filter
78
- },
79
- {
80
- depth: null
81
- }
82
- )
185
+ inspect: util.inspect({ query, filter }, { depth: null })
83
186
  },
84
- msg: "failed to execute search query"
187
+ msg: "failed to execute greedy search query"
85
188
  }));
86
189
  return [];
87
190
  }
@@ -212,6 +315,6 @@ class DummyRedisRulesReader {
212
315
  }
213
316
  export {
214
317
  DummyRedisRulesReader,
215
- FIND_RULES_MAX_CANDIDATES,
216
- RedisRulesReader
318
+ RedisRulesReader,
319
+ SERVER_SIDE_RANK_TOP_N
217
320
  };
@@ -1 +1 @@
1
- {"version":3,"file":"redisRulesReader.js","sourceRoot":"","sources":["../../../src/redis/reader/redisRulesReader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"redisRulesReader.js","sourceRoot":"","sources":["../../../src/redis/reader/redisRulesReader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=redisRulesReaderRank.benchmark.integration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redisRulesReaderRank.benchmark.integration.test.d.ts","sourceRoot":"","sources":["../../../src/tests/redis/redisRulesReaderRank.benchmark.integration.test.ts"],"names":[],"mappings":""}