@prosopo/user-access-policy 3.9.1 → 3.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build$colon$cjs.log +35 -35
- package/.turbo/turbo-build$colon$tsc.log +14 -14
- package/.turbo/turbo-build.log +4 -4
- package/CHANGELOG.md +16 -0
- package/dist/cjs/redis/reader/redisRulesReader.cjs +120 -17
- package/dist/redis/reader/redisRulesReader.d.ts +4 -2
- package/dist/redis/reader/redisRulesReader.d.ts.map +1 -1
- package/dist/redis/reader/redisRulesReader.js +121 -18
- package/dist/redis/reader/redisRulesReader.js.map +1 -1
- package/dist/tests/redis/redisRulesReaderRank.benchmark.integration.test.d.ts +2 -0
- package/dist/tests/redis/redisRulesReaderRank.benchmark.integration.test.d.ts.map +1 -0
- package/dist/tests/redis/redisRulesReaderRank.benchmark.integration.test.js +189 -0
- package/dist/tests/redis/redisRulesReaderRank.benchmark.integration.test.js.map +1 -0
- package/package.json +3 -3
- package/src/redis/reader/redisRulesReader.ts +191 -33
- package/src/tests/redis/redisRulesReaderRank.benchmark.integration.test.ts +338 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/vite.test.config.ts +12 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @prosopo/user-access-policy@3.
|
|
2
|
+
> @prosopo/user-access-policy@3.10.0 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
|
[32m✓[39m 33 modules transformed.
|
|
37
37
|
rendering chunks...
|
|
38
|
-
[2mdist/cjs/[22m[36mapi/delete/.export.cjs [39m[1m[
|
|
39
|
-
[2mdist/cjs/[22m[36mapi/read/.export.cjs [39m[1m[
|
|
40
|
-
[2mdist/cjs/[22m[36mapi/write/.export.cjs [39m[1m[
|
|
41
|
-
[2mdist/cjs/[22m[36mmongoose/.export.cjs [39m[1m[
|
|
42
|
-
[2mdist/cjs/[22m[36mrulesStorage.cjs [39m[1m[
|
|
43
|
-
[2mdist/cjs/[22m[36mrule.cjs [39m[1m[
|
|
44
|
-
[2mdist/cjs/[22m[36mredis/.export.cjs [39m[1m[
|
|
45
|
-
[2mdist/cjs/[22m[36mruleInput/.export.cjs [39m[1m[
|
|
46
|
-
[2mdist/cjs/[22m[36mapi/.export.cjs [39m[1m[
|
|
47
|
-
[2mdist/cjs/[22m[36mapi/delete/deleteAllRules.cjs [39m[1m[
|
|
48
|
-
[2mdist/cjs/[22m[36mruleRecord.cjs [39m[1m[
|
|
49
|
-
[2mdist/cjs/[22m[36mapi/read/getMissingIds.cjs [39m[1m[
|
|
50
|
-
[2mdist/cjs/[22m[36mapi/read/fetchRules.cjs [39m[1m[
|
|
51
|
-
[2mdist/cjs/[22m[36m.export.cjs [39m[1m[
|
|
52
|
-
[2mdist/cjs/[22m[36mredis/redisRulesStorage.cjs [39m[1m[
|
|
53
|
-
[2mdist/cjs/[22m[36mmongoose/mongooseRuleSchema.cjs [39m[1m[
|
|
54
|
-
[2mdist/cjs/[22m[36mapi/delete/deleteRules.cjs [39m[1m[
|
|
55
|
-
[2mdist/cjs/[22m[36mapi/delete/deleteRuleGroups.cjs [39m[1m[
|
|
56
|
-
[2mdist/cjs/[22m[36mapi/write/rehashRules.cjs [39m[1m[
|
|
57
|
-
[2mdist/cjs/[22m[36mapi/read/findRuleIds.cjs [39m[1m[
|
|
58
|
-
[2mdist/cjs/[22m[36mruleInput/policyInput.cjs [39m[1m[
|
|
59
|
-
[2mdist/cjs/[22m[36mruleInput/ruleInput.cjs [39m[1m[
|
|
60
|
-
[2mdist/cjs/[22m[36mredis/redisClient.cjs [39m[1m[
|
|
61
|
-
[2mdist/cjs/[22m[36mruleInput/userScopeInput.cjs [39m[1m[
|
|
62
|
-
[2mdist/cjs/[22m[36mredis/redisRuleIndex.cjs [39m[1m[
|
|
63
|
-
[2mdist/cjs/[22m[36mapi/rulesApiClient.cjs [39m[1m[
|
|
64
|
-
[2mdist/cjs/[22m[36mredis/reader/redisAggregate.cjs [39m[1m[
|
|
65
|
-
[2mdist/cjs/[22m[36mtransformRule.cjs [39m[1m[
|
|
66
|
-
[2mdist/cjs/[22m[36mapi/write/insertRules.cjs [39m[1m[
|
|
67
|
-
[2mdist/cjs/[22m[36mredis/redisRulesWriter.cjs [39m[1m[
|
|
68
|
-
[2mdist/cjs/[22m[36mredis/reader/redisRulesQuery.cjs [39m[1m[
|
|
69
|
-
[2mdist/cjs/[22m[36mapi/ruleApiRoutes.cjs [39m[1m[
|
|
70
|
-
[2mdist/cjs/[22m[36mredis/reader/redisRulesReader.cjs [39m[1m[
|
|
71
|
-
[32m✓ built in
|
|
38
|
+
[2mdist/cjs/[22m[36mapi/delete/.export.cjs [39m[1m[2m 0.01 kB[22m[1m[22m
|
|
39
|
+
[2mdist/cjs/[22m[36mapi/read/.export.cjs [39m[1m[2m 0.01 kB[22m[1m[22m
|
|
40
|
+
[2mdist/cjs/[22m[36mapi/write/.export.cjs [39m[1m[2m 0.01 kB[22m[1m[22m
|
|
41
|
+
[2mdist/cjs/[22m[36mmongoose/.export.cjs [39m[1m[2m 0.23 kB[22m[1m[22m
|
|
42
|
+
[2mdist/cjs/[22m[36mrulesStorage.cjs [39m[1m[2m 0.34 kB[22m[1m[22m
|
|
43
|
+
[2mdist/cjs/[22m[36mrule.cjs [39m[1m[2m 0.34 kB[22m[1m[22m
|
|
44
|
+
[2mdist/cjs/[22m[36mredis/.export.cjs [39m[1m[2m 0.36 kB[22m[1m[22m
|
|
45
|
+
[2mdist/cjs/[22m[36mruleInput/.export.cjs [39m[1m[2m 0.46 kB[22m[1m[22m
|
|
46
|
+
[2mdist/cjs/[22m[36mapi/.export.cjs [39m[1m[2m 0.57 kB[22m[1m[22m
|
|
47
|
+
[2mdist/cjs/[22m[36mapi/delete/deleteAllRules.cjs [39m[1m[2m 0.77 kB[22m[1m[22m
|
|
48
|
+
[2mdist/cjs/[22m[36mruleRecord.cjs [39m[1m[2m 0.83 kB[22m[1m[22m
|
|
49
|
+
[2mdist/cjs/[22m[36mapi/read/getMissingIds.cjs [39m[1m[2m 1.15 kB[22m[1m[22m
|
|
50
|
+
[2mdist/cjs/[22m[36mapi/read/fetchRules.cjs [39m[1m[2m 1.22 kB[22m[1m[22m
|
|
51
|
+
[2mdist/cjs/[22m[36m.export.cjs [39m[1m[2m 1.24 kB[22m[1m[22m
|
|
52
|
+
[2mdist/cjs/[22m[36mredis/redisRulesStorage.cjs [39m[1m[2m 1.35 kB[22m[1m[22m
|
|
53
|
+
[2mdist/cjs/[22m[36mmongoose/mongooseRuleSchema.cjs [39m[1m[2m 1.48 kB[22m[1m[22m
|
|
54
|
+
[2mdist/cjs/[22m[36mapi/delete/deleteRules.cjs [39m[1m[2m 1.51 kB[22m[1m[22m
|
|
55
|
+
[2mdist/cjs/[22m[36mapi/delete/deleteRuleGroups.cjs [39m[1m[2m 1.57 kB[22m[1m[22m
|
|
56
|
+
[2mdist/cjs/[22m[36mapi/write/rehashRules.cjs [39m[1m[2m 1.64 kB[22m[1m[22m
|
|
57
|
+
[2mdist/cjs/[22m[36mapi/read/findRuleIds.cjs [39m[1m[2m 1.65 kB[22m[1m[22m
|
|
58
|
+
[2mdist/cjs/[22m[36mruleInput/policyInput.cjs [39m[1m[2m 1.70 kB[22m[1m[22m
|
|
59
|
+
[2mdist/cjs/[22m[36mruleInput/ruleInput.cjs [39m[1m[2m 2.07 kB[22m[1m[22m
|
|
60
|
+
[2mdist/cjs/[22m[36mredis/redisClient.cjs [39m[1m[2m 2.09 kB[22m[1m[22m
|
|
61
|
+
[2mdist/cjs/[22m[36mruleInput/userScopeInput.cjs [39m[1m[2m 2.45 kB[22m[1m[22m
|
|
62
|
+
[2mdist/cjs/[22m[36mredis/redisRuleIndex.cjs [39m[1m[2m 2.46 kB[22m[1m[22m
|
|
63
|
+
[2mdist/cjs/[22m[36mapi/rulesApiClient.cjs [39m[1m[2m 2.60 kB[22m[1m[22m
|
|
64
|
+
[2mdist/cjs/[22m[36mredis/reader/redisAggregate.cjs [39m[1m[2m 2.61 kB[22m[1m[22m
|
|
65
|
+
[2mdist/cjs/[22m[36mtransformRule.cjs [39m[1m[2m 3.05 kB[22m[1m[22m
|
|
66
|
+
[2mdist/cjs/[22m[36mapi/write/insertRules.cjs [39m[1m[2m 3.38 kB[22m[1m[22m
|
|
67
|
+
[2mdist/cjs/[22m[36mredis/redisRulesWriter.cjs [39m[1m[2m 3.44 kB[22m[1m[22m
|
|
68
|
+
[2mdist/cjs/[22m[36mredis/reader/redisRulesQuery.cjs [39m[1m[2m 4.34 kB[22m[1m[22m
|
|
69
|
+
[2mdist/cjs/[22m[36mapi/ruleApiRoutes.cjs [39m[1m[2m 4.55 kB[22m[1m[22m
|
|
70
|
+
[2mdist/cjs/[22m[36mredis/reader/redisRulesReader.cjs [39m[1m[2m10.28 kB[22m[1m[22m
|
|
71
|
+
[32m✓ built in 465ms[39m
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
|
-
> @prosopo/user-access-policy@3.
|
|
2
|
+
> @prosopo/user-access-policy@3.10.0 build:tsc
|
|
3
3
|
> tsc --build --verbose
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
2:03:13 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
|
-
|
|
18
|
+
2:03:13 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
|
-
|
|
20
|
+
2:03:13 PM - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/util.ts' is older than output '../locale/tsconfig.tsbuildinfo'
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
2:03:13 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
|
-
|
|
24
|
+
2:03:13 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
|
-
|
|
26
|
+
2:03:13 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
|
-
|
|
28
|
+
2:03:14 PM - Project '../types/tsconfig.json' is up to date because newest input '../types/src/provider/api.ts' is older than output '../types/tsconfig.tsbuildinfo'
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
2:03:14 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
|
-
|
|
32
|
+
2:03:14 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
|
-
|
|
34
|
+
2:03:14 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
|
-
|
|
36
|
+
2:03:14 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
|
-
|
|
38
|
+
2:03:14 PM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
2:03:14 PM - Building project '/home/runner/work/captcha/captcha/packages/user-access-policy/tsconfig.json'...
|
|
41
41
|
|
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
|
|
2
|
-
> @prosopo/user-access-policy@3.
|
|
2
|
+
> @prosopo/user-access-policy@3.10.0 build
|
|
3
3
|
> npm run build:cross-env -- --mode ${NODE_ENV:-development}
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
> @prosopo/user-access-policy@3.
|
|
6
|
+
> @prosopo/user-access-policy@3.10.0 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
|
[2mdist/[22m[36mredis/redisRulesWriter.js [39m[1m[2m3.22 kB[22m[1m[22m
|
|
72
72
|
[2mdist/[22m[36mredis/reader/redisRulesQuery.js [39m[1m[2m4.15 kB[22m[1m[22m
|
|
73
73
|
[2mdist/[22m[36mapi/ruleApiRoutes.js [39m[1m[2m4.33 kB[22m[1m[22m
|
|
74
|
-
[2mdist/[22m[36mredis/reader/redisRulesReader.js [39m[1m[
|
|
75
|
-
[32m✓ built in
|
|
74
|
+
[2mdist/[22m[36mredis/reader/redisRulesReader.js [39m[1m[2m9.40 kB[22m[1m[22m
|
|
75
|
+
[32m✓ built in 499ms[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @prosopo/user-access-policy
|
|
2
2
|
|
|
3
|
+
## 3.10.0
|
|
4
|
+
### Minor Changes
|
|
5
|
+
|
|
6
|
+
- 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).
|
|
7
|
+
|
|
8
|
+
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.
|
|
9
|
+
|
|
10
|
+
`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.
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- Updated dependencies [9b91e85]
|
|
15
|
+
- Updated dependencies [c80a05b]
|
|
16
|
+
- @prosopo/types@4.5.0
|
|
17
|
+
- @prosopo/api@3.4.12
|
|
18
|
+
|
|
3
19
|
## 3.9.1
|
|
4
20
|
### Patch Changes
|
|
5
21
|
|
|
@@ -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
|
|
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
|
-
|
|
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
|
|
270
|
+
const rule2 = redisClient.parseRedisRecords(
|
|
168
271
|
[ruleData],
|
|
169
272
|
ruleInput.accessRuleInput,
|
|
170
273
|
this.logger
|
|
171
274
|
)[0];
|
|
172
|
-
if (
|
|
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
|
|
3
|
+
import { type AccessRule } from "#policy/rule.js";
|
|
4
4
|
import type { AccessRuleEntry, AccessRulesFilter, AccessRulesReader } from "#policy/rulesStorage.js";
|
|
5
|
-
export declare const
|
|
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;
|
|
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,
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
216
|
-
|
|
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":"AAcA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAG/E,OAAO,
|
|
1
|
+
{"version":3,"file":"redisRulesReader.js","sourceRoot":"","sources":["../../../src/redis/reader/redisRulesReader.ts"],"names":[],"mappings":"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"}
|
|
@@ -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":""}
|