@prosopo/user-access-policy 3.12.33 → 3.14.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 +11 -10
- package/.turbo/turbo-build$colon$tsc.log +14 -14
- package/.turbo/turbo-build.log +12 -11
- package/CHANGELOG.md +53 -0
- package/dist/.export.d.ts +1 -0
- package/dist/.export.d.ts.map +1 -1
- package/dist/.export.js +2 -1
- package/dist/.export.js.map +1 -1
- package/dist/cjs/.export.cjs +8 -0
- package/dist/cjs/headerMatch.cjs +122 -0
- package/dist/cjs/mongoose/mongooseRuleSchema.cjs +20 -0
- package/dist/cjs/redis/reader/redisRulesReader.cjs +5 -0
- package/dist/cjs/redis/redisRuleIndex.cjs +20 -0
- package/dist/cjs/rule.cjs +1 -0
- package/dist/cjs/ruleInput/userScopeInput.cjs +13 -1
- package/dist/cjs/ruleRecord.cjs +6 -1
- package/dist/headerMatch.d.ts +13 -0
- package/dist/headerMatch.d.ts.map +1 -0
- package/dist/headerMatch.js +116 -0
- package/dist/headerMatch.js.map +1 -0
- package/dist/mongoose/mongooseRuleSchema.d.ts.map +1 -1
- package/dist/mongoose/mongooseRuleSchema.js +20 -0
- package/dist/mongoose/mongooseRuleSchema.js.map +1 -1
- package/dist/redis/reader/redisRulesReader.d.ts.map +1 -1
- package/dist/redis/reader/redisRulesReader.js +5 -0
- package/dist/redis/reader/redisRulesReader.js.map +1 -1
- package/dist/redis/redisRuleIndex.d.ts.map +1 -1
- package/dist/redis/redisRuleIndex.js +20 -0
- package/dist/redis/redisRuleIndex.js.map +1 -1
- package/dist/rule.d.ts +7 -1
- package/dist/rule.d.ts.map +1 -1
- package/dist/rule.js +1 -0
- package/dist/rule.js.map +1 -1
- package/dist/ruleInput/ruleInput.d.ts +30 -0
- package/dist/ruleInput/ruleInput.d.ts.map +1 -1
- package/dist/ruleInput/userScopeInput.d.ts +40 -0
- package/dist/ruleInput/userScopeInput.d.ts.map +1 -1
- package/dist/ruleInput/userScopeInput.js +13 -1
- package/dist/ruleInput/userScopeInput.js.map +1 -1
- package/dist/ruleRecord.d.ts +2 -2
- package/dist/ruleRecord.d.ts.map +1 -1
- package/dist/ruleRecord.js +6 -1
- package/dist/ruleRecord.js.map +1 -1
- package/dist/tests/headerMatch.unit.test.d.ts +2 -0
- package/dist/tests/headerMatch.unit.test.d.ts.map +1 -0
- package/dist/tests/headerMatch.unit.test.js +202 -0
- package/dist/tests/headerMatch.unit.test.js.map +1 -0
- package/dist/tests/redis/reader/redisRulesQuery.unit.test.js +3 -3
- package/dist/tests/redis/reader/redisRulesQuery.unit.test.js.map +1 -1
- package/dist/tests/transformRule.unit.test.js +5 -0
- package/dist/tests/transformRule.unit.test.js.map +1 -1
- package/package.json +11 -11
- package/src/.export.ts +11 -0
- package/src/headerMatch.ts +180 -0
- package/src/mongoose/mongooseRuleSchema.ts +5 -0
- package/src/redis/reader/redisRulesReader.ts +7 -0
- package/src/redis/redisRuleIndex.ts +14 -0
- package/src/rule.ts +29 -0
- package/src/ruleInput/userScopeInput.ts +28 -0
- package/src/ruleRecord.ts +5 -0
- package/src/tests/headerMatch.unit.test.ts +350 -0
- package/src/tests/redis/reader/redisRulesQuery.unit.test.ts +3 -3
- package/src/tests/transformRule.unit.test.ts +5 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"headerMatch.unit.test.d.ts","sourceRoot":"","sources":["../../src/tests/headerMatch.unit.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { accessRuleHeaderMatches, decodeHeaderValueList, encodeHeaderValueList, evaluateHeaderCondition, isHeaderOperator, } from "#policy/headerMatch.js";
|
|
3
|
+
describe("isHeaderOperator", () => {
|
|
4
|
+
it("accepts the six known operators", () => {
|
|
5
|
+
for (const op of [
|
|
6
|
+
"equals",
|
|
7
|
+
"contains",
|
|
8
|
+
"notEquals",
|
|
9
|
+
"notContains",
|
|
10
|
+
"notEqualsAny",
|
|
11
|
+
"notContainsAny",
|
|
12
|
+
]) {
|
|
13
|
+
expect(isHeaderOperator(op)).toBe(true);
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
it("rejects unknown / undefined values", () => {
|
|
17
|
+
expect(isHeaderOperator("startsWith")).toBe(false);
|
|
18
|
+
expect(isHeaderOperator("")).toBe(false);
|
|
19
|
+
expect(isHeaderOperator(undefined)).toBe(false);
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
describe("evaluateHeaderCondition", () => {
|
|
23
|
+
const headers = {
|
|
24
|
+
"x-app-version": "1.2.3-beta",
|
|
25
|
+
"cf-worker": "example.com",
|
|
26
|
+
};
|
|
27
|
+
const cases = [
|
|
28
|
+
{
|
|
29
|
+
name: "equals hit",
|
|
30
|
+
op: "equals",
|
|
31
|
+
value: "example.com",
|
|
32
|
+
header: "cf-worker",
|
|
33
|
+
expected: true,
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: "equals miss (different value)",
|
|
37
|
+
op: "equals",
|
|
38
|
+
value: "evil.com",
|
|
39
|
+
header: "cf-worker",
|
|
40
|
+
expected: false,
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: "equals miss (header absent)",
|
|
44
|
+
op: "equals",
|
|
45
|
+
value: "anything",
|
|
46
|
+
header: "x-missing",
|
|
47
|
+
expected: false,
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: "contains hit",
|
|
51
|
+
op: "contains",
|
|
52
|
+
value: "beta",
|
|
53
|
+
header: "x-app-version",
|
|
54
|
+
expected: true,
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
name: "contains miss (no substring)",
|
|
58
|
+
op: "contains",
|
|
59
|
+
value: "alpha",
|
|
60
|
+
header: "x-app-version",
|
|
61
|
+
expected: false,
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
name: "contains miss (header absent)",
|
|
65
|
+
op: "contains",
|
|
66
|
+
value: "beta",
|
|
67
|
+
header: "x-missing",
|
|
68
|
+
expected: false,
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
name: "notEquals blocks a different value",
|
|
72
|
+
op: "notEquals",
|
|
73
|
+
value: "example.com",
|
|
74
|
+
header: "cf-worker",
|
|
75
|
+
expected: false,
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: "notEquals lets an exact match through",
|
|
79
|
+
op: "notEquals",
|
|
80
|
+
value: "evil.com",
|
|
81
|
+
header: "cf-worker",
|
|
82
|
+
expected: true,
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
name: "notEquals blocks an absent header",
|
|
86
|
+
op: "notEquals",
|
|
87
|
+
value: "secret",
|
|
88
|
+
header: "x-secret",
|
|
89
|
+
expected: true,
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
name: "notContains blocks when substring present",
|
|
93
|
+
op: "notContains",
|
|
94
|
+
value: "beta",
|
|
95
|
+
header: "x-app-version",
|
|
96
|
+
expected: false,
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
name: "notContains lets a substring hit through",
|
|
100
|
+
op: "notContains",
|
|
101
|
+
value: "alpha",
|
|
102
|
+
header: "x-app-version",
|
|
103
|
+
expected: true,
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
name: "notContains blocks an absent header",
|
|
107
|
+
op: "notContains",
|
|
108
|
+
value: "beta",
|
|
109
|
+
header: "x-missing",
|
|
110
|
+
expected: true,
|
|
111
|
+
},
|
|
112
|
+
];
|
|
113
|
+
for (const c of cases) {
|
|
114
|
+
it(c.name, () => {
|
|
115
|
+
expect(evaluateHeaderCondition(c.header, c.op, c.value, headers)).toBe(c.expected);
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
it("matches header names case-insensitively", () => {
|
|
119
|
+
expect(evaluateHeaderCondition("CF-Worker", "equals", "example.com", headers)).toBe(true);
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
describe("accessRuleHeaderMatches", () => {
|
|
123
|
+
const headers = { "x-debug": "1" };
|
|
124
|
+
it("passes trivially when the rule has no header condition", () => {
|
|
125
|
+
expect(accessRuleHeaderMatches({}, headers)).toBe(true);
|
|
126
|
+
});
|
|
127
|
+
it("evaluates a well-formed header condition", () => {
|
|
128
|
+
expect(accessRuleHeaderMatches({ headerName: "x-debug", headerOperator: "equals", headerValue: "1" }, headers)).toBe(true);
|
|
129
|
+
expect(accessRuleHeaderMatches({ headerName: "x-debug", headerOperator: "equals", headerValue: "0" }, headers)).toBe(false);
|
|
130
|
+
});
|
|
131
|
+
it("never matches a rule with a header name but an invalid operator", () => {
|
|
132
|
+
expect(accessRuleHeaderMatches({ headerName: "x-debug", headerOperator: "wat", headerValue: "1" }, headers)).toBe(false);
|
|
133
|
+
});
|
|
134
|
+
it("treats a missing headerValue as an empty string", () => {
|
|
135
|
+
expect(accessRuleHeaderMatches({ headerName: "x-debug", headerOperator: "contains" }, headers)).toBe(true);
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
describe("encode/decodeHeaderValueList", () => {
|
|
139
|
+
it("round-trips a list of values", () => {
|
|
140
|
+
const values = ["ios", "android", "web"];
|
|
141
|
+
expect(decodeHeaderValueList(encodeHeaderValueList(values))).toEqual(values);
|
|
142
|
+
});
|
|
143
|
+
it("round-trips values containing the characters a delimiter would break on", () => {
|
|
144
|
+
const values = ["en-GB,en;q=0.9", 'a"b', "c\\d", "[bracketed]"];
|
|
145
|
+
expect(decodeHeaderValueList(encodeHeaderValueList(values))).toEqual(values);
|
|
146
|
+
});
|
|
147
|
+
it("treats a plain (non list-encoded) value as a one-value list", () => {
|
|
148
|
+
expect(decodeHeaderValueList("ios")).toEqual(["ios"]);
|
|
149
|
+
expect(decodeHeaderValueList("")).toEqual([""]);
|
|
150
|
+
});
|
|
151
|
+
it("rejects a list-shaped value that is not a usable list", () => {
|
|
152
|
+
expect(decodeHeaderValueList("[")).toBeUndefined();
|
|
153
|
+
expect(decodeHeaderValueList("[not json]")).toBeUndefined();
|
|
154
|
+
expect(decodeHeaderValueList("[]")).toBeUndefined();
|
|
155
|
+
expect(decodeHeaderValueList("[1,2]")).toBeUndefined();
|
|
156
|
+
expect(decodeHeaderValueList('["ok", null]')).toBeUndefined();
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
describe("evaluateHeaderCondition — multi-value allow-list operators", () => {
|
|
160
|
+
const headers = {
|
|
161
|
+
"x-app": "android",
|
|
162
|
+
"user-agent": "Mozilla/5.0 (Linux; Android 14) Chrome/120",
|
|
163
|
+
};
|
|
164
|
+
const allowedApps = encodeHeaderValueList(["ios", "android"]);
|
|
165
|
+
it("does not block a request whose header is one of the allowed values", () => {
|
|
166
|
+
expect(evaluateHeaderCondition("x-app", "notEqualsAny", allowedApps, headers)).toBe(false);
|
|
167
|
+
expect(evaluateHeaderCondition("x-app", "notEqualsAny", encodeHeaderValueList(["android"]), headers)).toBe(false);
|
|
168
|
+
});
|
|
169
|
+
it("blocks a request whose header matches none of the allowed values", () => {
|
|
170
|
+
expect(evaluateHeaderCondition("x-app", "notEqualsAny", encodeHeaderValueList(["ios", "web"]), headers)).toBe(true);
|
|
171
|
+
});
|
|
172
|
+
it("blocks a request that omits the header entirely", () => {
|
|
173
|
+
expect(evaluateHeaderCondition("x-missing", "notEqualsAny", allowedApps, headers)).toBe(true);
|
|
174
|
+
expect(evaluateHeaderCondition("x-missing", "notContainsAny", allowedApps, headers)).toBe(true);
|
|
175
|
+
});
|
|
176
|
+
it("matches a substring of the header for notContainsAny", () => {
|
|
177
|
+
expect(evaluateHeaderCondition("user-agent", "notContainsAny", encodeHeaderValueList(["Android", "iPhone"]), headers)).toBe(false);
|
|
178
|
+
expect(evaluateHeaderCondition("user-agent", "notContainsAny", encodeHeaderValueList(["iPhone", "Windows"]), headers)).toBe(true);
|
|
179
|
+
});
|
|
180
|
+
it("is exact for notEqualsAny — a substring is not a match", () => {
|
|
181
|
+
expect(evaluateHeaderCondition("x-app", "notEqualsAny", encodeHeaderValueList(["droid"]), headers)).toBe(true);
|
|
182
|
+
});
|
|
183
|
+
it("never fires on a malformed value list, rather than blocking everything", () => {
|
|
184
|
+
for (const operator of ["notEqualsAny", "notContainsAny"]) {
|
|
185
|
+
expect(evaluateHeaderCondition("x-app", operator, "[]", headers)).toBe(false);
|
|
186
|
+
expect(evaluateHeaderCondition("x-missing", operator, "[bad", headers)).toBe(false);
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
it("is reachable through accessRuleHeaderMatches", () => {
|
|
190
|
+
expect(accessRuleHeaderMatches({
|
|
191
|
+
headerName: "X-App",
|
|
192
|
+
headerOperator: "notEqualsAny",
|
|
193
|
+
headerValue: allowedApps,
|
|
194
|
+
}, headers)).toBe(false);
|
|
195
|
+
expect(accessRuleHeaderMatches({
|
|
196
|
+
headerName: "X-App",
|
|
197
|
+
headerOperator: "notEqualsAny",
|
|
198
|
+
headerValue: encodeHeaderValueList(["ios"]),
|
|
199
|
+
}, headers)).toBe(true);
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
//# sourceMappingURL=headerMatch.unit.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"headerMatch.unit.test.js","sourceRoot":"","sources":["../../src/tests/headerMatch.unit.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -24,7 +24,7 @@ describe("getRulesRedisQuery", () => {
|
|
|
24
24
|
userScopeMatch: FilterScopeMatch.Exact,
|
|
25
25
|
};
|
|
26
26
|
const query = getRulesRedisQuery(filter, true);
|
|
27
|
-
expect(query).toBe("( ( @numericIp:[100 100] | ( @numericIpMaskMin:[-inf 100] @numericIpMaskMax:[100 +inf] ) ) @ja4Hash:{ja4Hash} ismissing(@userAgentHash) ismissing(@userId) ismissing(@headersHash) ismissing(@headHash) ismissing(@coords) ismissing(@countryCode) ismissing(@asn) ismissing(@os) ismissing(@browser) )");
|
|
27
|
+
expect(query).toBe("( ( @numericIp:[100 100] | ( @numericIpMaskMin:[-inf 100] @numericIpMaskMax:[100 +inf] ) ) @ja4Hash:{ja4Hash} ismissing(@userAgentHash) ismissing(@userId) ismissing(@headersHash) ismissing(@headHash) ismissing(@coords) ismissing(@countryCode) ismissing(@asn) ismissing(@os) ismissing(@browser) ismissing(@headerMatch) ismissing(@headerName) ismissing(@headerValue) ismissing(@headerOperator) ismissing(@webBotAuthAgent) )");
|
|
28
28
|
});
|
|
29
29
|
it("puts ismissing(x) for multiple fields passed in as `undefined` when user scope match is exact", () => {
|
|
30
30
|
const filter = {
|
|
@@ -80,7 +80,7 @@ describe("getRulesRedisQuery", () => {
|
|
|
80
80
|
userScopeMatch: FilterScopeMatch.Exact,
|
|
81
81
|
};
|
|
82
82
|
const query = getRulesRedisQuery(filter, true);
|
|
83
|
-
expect(query).toBe("( ( @numericIp:[100 100] | ( @numericIpMaskMin:[-inf 100] @numericIpMaskMax:[100 +inf] ) ) @ja4Hash:{ja4Hash} ismissing(@userAgentHash) ismissing(@headersHash) ismissing(@userId) ismissing(@headHash) ismissing(@coords) ismissing(@countryCode) ismissing(@asn) ismissing(@os) ismissing(@browser) )");
|
|
83
|
+
expect(query).toBe("( ( @numericIp:[100 100] | ( @numericIpMaskMin:[-inf 100] @numericIpMaskMax:[100 +inf] ) ) @ja4Hash:{ja4Hash} ismissing(@userAgentHash) ismissing(@headersHash) ismissing(@userId) ismissing(@headHash) ismissing(@coords) ismissing(@countryCode) ismissing(@asn) ismissing(@os) ismissing(@browser) ismissing(@headerMatch) ismissing(@headerName) ismissing(@headerValue) ismissing(@headerOperator) ismissing(@webBotAuthAgent) )");
|
|
84
84
|
});
|
|
85
85
|
it("does not put ismissing(numericIp) when numericIpMaskMin and numericIpMaskMax are passed in", () => {
|
|
86
86
|
const filter = {
|
|
@@ -95,7 +95,7 @@ describe("getRulesRedisQuery", () => {
|
|
|
95
95
|
userScopeMatch: FilterScopeMatch.Exact,
|
|
96
96
|
};
|
|
97
97
|
const query = getRulesRedisQuery(filter, true);
|
|
98
|
-
expect(query).toBe("( @numericIpMaskMin:[-inf 100] @numericIpMaskMax:[200 +inf] @ja4Hash:{ja4Hash} ismissing(@userAgentHash) ismissing(@headersHash) ismissing(@userId) ismissing(@headHash) ismissing(@coords) ismissing(@countryCode) ismissing(@asn) ismissing(@os) ismissing(@browser) )");
|
|
98
|
+
expect(query).toBe("( @numericIpMaskMin:[-inf 100] @numericIpMaskMax:[200 +inf] @ja4Hash:{ja4Hash} ismissing(@userAgentHash) ismissing(@headersHash) ismissing(@userId) ismissing(@headHash) ismissing(@coords) ismissing(@countryCode) ismissing(@asn) ismissing(@os) ismissing(@browser) ismissing(@headerMatch) ismissing(@headerName) ismissing(@headerValue) ismissing(@headerOperator) ismissing(@webBotAuthAgent) )");
|
|
99
99
|
});
|
|
100
100
|
it("emits NUMERIC range syntax for asn, not TAG syntax", () => {
|
|
101
101
|
const filter = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redisRulesQuery.unit.test.js","sourceRoot":"","sources":["../../../../src/tests/redis/reader/redisRulesQuery.unit.test.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,EAEN,gBAAgB,GAChB,MAAM,yBAAyB,CAAC;AAEjC,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IACnC,EAAE,CAAC,uFAAuF,EAAE,GAAG,EAAE;QAChG,MAAM,MAAM,GAAG;YACd,SAAS,EAAE;gBACV,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC;gBACtB,OAAO,EAAE,SAAS;gBAClB,aAAa,EAAE,SAAS;aACxB;YACD,cAAc,EAAE,gBAAgB,CAAC,KAAK;SACjB,CAAC;QAEvB,MAAM,KAAK,GAAG,kBAAkB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAEhD,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CACjB,2IAA2I,CAC3I,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6IAA6I,EAAE,GAAG,EAAE;QACtJ,MAAM,MAAM,GAAG;YACd,SAAS,EAAE;gBACV,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC;gBACtB,OAAO,EAAE,SAAS;gBAClB,aAAa,EAAE,SAAS;aACxB;YACD,cAAc,EAAE,gBAAgB,CAAC,KAAK;SACjB,CAAC;QAEvB,MAAM,KAAK,GAAG,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAE/C,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CACjB,
|
|
1
|
+
{"version":3,"file":"redisRulesQuery.unit.test.js","sourceRoot":"","sources":["../../../../src/tests/redis/reader/redisRulesQuery.unit.test.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,EAEN,gBAAgB,GAChB,MAAM,yBAAyB,CAAC;AAEjC,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IACnC,EAAE,CAAC,uFAAuF,EAAE,GAAG,EAAE;QAChG,MAAM,MAAM,GAAG;YACd,SAAS,EAAE;gBACV,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC;gBACtB,OAAO,EAAE,SAAS;gBAClB,aAAa,EAAE,SAAS;aACxB;YACD,cAAc,EAAE,gBAAgB,CAAC,KAAK;SACjB,CAAC;QAEvB,MAAM,KAAK,GAAG,kBAAkB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAEhD,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CACjB,2IAA2I,CAC3I,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6IAA6I,EAAE,GAAG,EAAE;QACtJ,MAAM,MAAM,GAAG;YACd,SAAS,EAAE;gBACV,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC;gBACtB,OAAO,EAAE,SAAS;gBAClB,aAAa,EAAE,SAAS;aACxB;YACD,cAAc,EAAE,gBAAgB,CAAC,KAAK;SACjB,CAAC;QAEvB,MAAM,KAAK,GAAG,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAE/C,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CACjB,uaAAua,CACva,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+FAA+F,EAAE,GAAG,EAAE;QACxG,MAAM,MAAM,GAAG;YACd,SAAS,EAAE;gBACV,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC;gBACtB,OAAO,EAAE,SAAS;gBAClB,aAAa,EAAE,SAAS;gBACxB,WAAW,EAAE,SAAS;gBACtB,MAAM,EAAE,SAAS;aACjB;YACD,cAAc,EAAE,gBAAgB,CAAC,KAAK;SACjB,CAAC;QAEvB,MAAM,KAAK,GAAG,kBAAkB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAEhD,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CACjB,sLAAsL,CACtL,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wGAAwG,EAAE,GAAG,EAAE;QACjH,MAAM,MAAM,GAAG;YACd,SAAS,EAAE;gBACV,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC;gBACtB,OAAO,EAAE,SAAS;gBAClB,aAAa,EAAE,SAAS;gBACxB,WAAW,EAAE,SAAS;gBACtB,MAAM,EAAE,SAAS;aACjB;YACD,cAAc,EAAE,gBAAgB,CAAC,MAAM;SAClB,CAAC;QAEvB,MAAM,KAAK,GAAG,kBAAkB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAEhD,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CACjB,mHAAmH,CACnH,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iGAAiG,EAAE,GAAG,EAAE;QAC1G,MAAM,MAAM,GAAG;YACd,SAAS,EAAE;gBACV,SAAS,EAAE,SAAS;gBACpB,OAAO,EAAE,SAAS;gBAClB,aAAa,EAAE,SAAS;gBACxB,WAAW,EAAE,SAAS;gBACtB,MAAM,EAAE,SAAS;aACjB;YACD,cAAc,EAAE,gBAAgB,CAAC,KAAK;SACjB,CAAC;QAEvB,MAAM,KAAK,GAAG,kBAAkB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAEhD,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CACjB,6KAA6K,CAC7K,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mHAAmH,EAAE,GAAG,EAAE;QAC5H,MAAM,MAAM,GAAG;YACd,SAAS,EAAE;gBACV,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC;gBACtB,OAAO,EAAE,SAAS;gBAClB,aAAa,EAAE,SAAS;gBACxB,WAAW,EAAE,SAAS;gBACtB,MAAM,EAAE,SAAS;aACjB;YACD,cAAc,EAAE,gBAAgB,CAAC,KAAK;SACjB,CAAC;QAEvB,MAAM,KAAK,GAAG,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAE/C,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CACjB,uaAAua,CACva,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4FAA4F,EAAE,GAAG,EAAE;QACrG,MAAM,MAAM,GAAG;YACd,SAAS,EAAE;gBACV,gBAAgB,EAAE,MAAM,CAAC,GAAG,CAAC;gBAC7B,gBAAgB,EAAE,MAAM,CAAC,GAAG,CAAC;gBAC7B,OAAO,EAAE,SAAS;gBAClB,aAAa,EAAE,SAAS;gBACxB,WAAW,EAAE,SAAS;gBACtB,MAAM,EAAE,SAAS;aACjB;YACD,cAAc,EAAE,gBAAgB,CAAC,KAAK;SACjB,CAAC;QAEvB,MAAM,KAAK,GAAG,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAE/C,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CACjB,wYAAwY,CACxY,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC7D,MAAM,MAAM,GAAG;YACd,SAAS,EAAE;gBACV,GAAG,EAAE,MAAM;aACX;YACD,cAAc,EAAE,gBAAgB,CAAC,MAAM;SAClB,CAAC;QAEvB,MAAM,KAAK,GAAG,kBAAkB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAIhD,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;QAChD,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wIAAwI,EAAE,GAAG,EAAE;QACjJ,MAAM,MAAM,GAAG;YACd,SAAS,EAAE;gBACV,MAAM,EAAE,SAAS;aACjB;YACD,cAAc,EAAE,gBAAgB,CAAC,KAAK;SACjB,CAAC;QAEvB,MAAM,KAAK,GAAG,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAI/C,MAAM,uBAAuB,GAAG,KAAK,CAAC,KAAK,CAC1C,iCAAiC,CACjC,CAAC;QACF,MAAM,uBAAuB,GAAG,KAAK,CAAC,KAAK,CAC1C,iCAAiC,CACjC,CAAC;QAEF,MAAM,CAAC,uBAAuB,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAChD,MAAM,CAAC,uBAAuB,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAChD,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC;QACjD,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mGAAmG,EAAE,GAAG,EAAE;QAC5G,MAAM,MAAM,GAAG;YACd,SAAS,EAAE;gBACV,gBAAgB,EAAE,MAAM,CAAC,GAAG,CAAC;aAC7B;YACD,cAAc,EAAE,gBAAgB,CAAC,KAAK;SACjB,CAAC;QAEvB,MAAM,KAAK,GAAG,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAI/C,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,8BAA8B,CAAC,CAAC;QACxD,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,8BAA8B,CAAC,CAAC;QACxD,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,8BAA8B,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mGAAmG,EAAE,GAAG,EAAE;QAC5G,MAAM,MAAM,GAAG;YACd,SAAS,EAAE;gBACV,gBAAgB,EAAE,MAAM,CAAC,GAAG,CAAC;aAC7B;YACD,cAAc,EAAE,gBAAgB,CAAC,KAAK;SACjB,CAAC;QAEvB,MAAM,KAAK,GAAG,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAE/C,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,8BAA8B,CAAC,CAAC;QACxD,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,8BAA8B,CAAC,CAAC;QACxD,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,8BAA8B,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QACnD,MAAM,MAAM,GAAG;YACd,SAAS,EAAE;gBACV,QAAQ,EAAE,cAAc;aACxB;YACD,cAAc,EAAE,gBAAgB,CAAC,KAAK;SACjB,CAAC;QAEvB,MAAM,KAAK,GAAG,kBAAkB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAEhD,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wEAAwE,EAAE,GAAG,EAAE;QACjF,MAAM,MAAM,GAAG;YACd,SAAS,EAAE;gBACV,MAAM,EAAE,eAAe;aACvB;YACD,cAAc,EAAE,gBAAgB,CAAC,KAAK;SACjB,CAAC;QAEvB,MAAM,KAAK,GAAG,kBAAkB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAGhD,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,uCAAuC,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAC/D,MAAM,MAAM,GAAG;YACd,SAAS,EAAE;gBACV,QAAQ,EAAE,cAAc;gBACxB,MAAM,EAAE,eAAe;aACvB;YACD,cAAc,EAAE,gBAAgB,CAAC,KAAK;SACjB,CAAC;QAEvB,MAAM,KAAK,GAAG,kBAAkB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAEhD,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,0BAA0B,CAAC,CAAC;QACpD,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,uCAAuC,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iGAAiG,EAAE,GAAG,EAAE;QAC1G,MAAM,MAAM,GAAG;YACd,SAAS,EAAE;gBACV,OAAO,EAAE,SAAS;aAClB;YACD,cAAc,EAAE,gBAAgB,CAAC,KAAK;SACjB,CAAC;QAEvB,MAAM,KAAK,GAAG,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAE/C,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;QAChD,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8DAA8D,EAAE,GAAG,EAAE;QACvE,MAAM,MAAM,GAAG;YACd,SAAS,EAAE;gBACV,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC;gBACtB,OAAO,EAAE,SAAS;gBAClB,QAAQ,EAAE,cAAc;gBACxB,aAAa,EAAE,SAAS;aACxB;YACD,cAAc,EAAE,gBAAgB,CAAC,KAAK;SACjB,CAAC;QAEvB,MAAM,KAAK,GAAG,kBAAkB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAEhD,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;QAChD,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;QAC9C,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,0BAA0B,CAAC,CAAC;QACpD,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,2BAA2B,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;QACrE,MAAM,MAAM,GAAG;YACd,SAAS,EAAE;gBACV,OAAO,EAAE,SAAS;aAClB;YACD,cAAc,EAAE,gBAAgB,CAAC,MAAM;YACvC,SAAS,EAAE,IAAI;SACM,CAAC;QAEvB,MAAM,KAAK,GAAG,kBAAkB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAEhD,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;QAGzC,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QAC/C,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAC/C,MAAM,CAAC,OAAO,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACxD,MAAM,MAAM,GAAG;YACd,SAAS,EAAE;gBACV,OAAO,EAAE,SAAS;aAClB;YACD,cAAc,EAAE,gBAAgB,CAAC,MAAM;SAClB,CAAC;QAEvB,MAAM,KAAK,GAAG,kBAAkB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAEhD,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACxD,MAAM,MAAM,GAAG;YACd,WAAW,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE;YACnC,gBAAgB,EAAE,gBAAgB,CAAC,MAAM;YACzC,SAAS,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE;YACjC,cAAc,EAAE,gBAAgB,CAAC,MAAM;YACvC,SAAS,EAAE,IAAI;SACM,CAAC;QAEvB,MAAM,KAAK,GAAG,kBAAkB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAEhD,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;QACzC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;QAC9C,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC"}
|
|
@@ -78,6 +78,11 @@ describe("transformRule", () => {
|
|
|
78
78
|
asn: 205016,
|
|
79
79
|
os: "macos",
|
|
80
80
|
browser: "firefox",
|
|
81
|
+
headerMatch: "1",
|
|
82
|
+
headerName: "x-test",
|
|
83
|
+
headerValue: "test",
|
|
84
|
+
headerOperator: "equals",
|
|
85
|
+
webBotAuthAgent: "https://signatures.openai.com",
|
|
81
86
|
};
|
|
82
87
|
it("should transform access rule record into rule", () => {
|
|
83
88
|
const ruleRecord = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transformRule.unit.test.js","sourceRoot":"","sources":["../../src/tests/transformRule.unit.test.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"transformRule.unit.test.js","sourceRoot":"","sources":["../../src/tests/transformRule.unit.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prosopo/user-access-policy",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.14.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": "^24",
|
|
@@ -43,29 +43,29 @@
|
|
|
43
43
|
"test": "npm run test:unit && npm run test:integration"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@prosopo/api": "4.
|
|
47
|
-
"@prosopo/api-route": "2.6.
|
|
48
|
-
"@prosopo/common": "3.1.
|
|
49
|
-
"@prosopo/logger": "2.0.
|
|
50
|
-
"@prosopo/redis-client": "1.0.
|
|
51
|
-
"@prosopo/types": "5.
|
|
52
|
-
"@prosopo/util": "3.3.
|
|
46
|
+
"@prosopo/api": "4.2.0",
|
|
47
|
+
"@prosopo/api-route": "2.6.58",
|
|
48
|
+
"@prosopo/common": "3.1.54",
|
|
49
|
+
"@prosopo/logger": "2.0.9",
|
|
50
|
+
"@prosopo/redis-client": "1.0.35",
|
|
51
|
+
"@prosopo/types": "5.8.0",
|
|
52
|
+
"@prosopo/util": "3.3.9",
|
|
53
53
|
"@redis/search": "5.0.0",
|
|
54
54
|
"cidr-calc": "1.0.4",
|
|
55
55
|
"dotenv": "16.4.5",
|
|
56
|
-
"ip-address": "10.
|
|
56
|
+
"ip-address": "10.7.0",
|
|
57
57
|
"redis": "5.0.0",
|
|
58
58
|
"zod": "3.23.8"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
|
-
"@prosopo/config": "3.3.
|
|
61
|
+
"@prosopo/config": "3.3.15",
|
|
62
62
|
"@prosopo/util-crypto": "13.5.31",
|
|
63
63
|
"@types/node": "22.10.2",
|
|
64
64
|
"fast-glob": "3.3.3",
|
|
65
65
|
"mongoose": "9.9.4",
|
|
66
66
|
"vite": "8.1.5",
|
|
67
67
|
"vitest": "4.1.11",
|
|
68
|
-
"yargs": "
|
|
68
|
+
"yargs": "18.1.0"
|
|
69
69
|
},
|
|
70
70
|
"author": "PROSOPO LIMITED <info@prosopo.io>",
|
|
71
71
|
"license": "Apache-2.0",
|
package/src/.export.ts
CHANGED
|
@@ -38,6 +38,17 @@ export {
|
|
|
38
38
|
type BrowserName,
|
|
39
39
|
} from "./classifyBrowser.js";
|
|
40
40
|
|
|
41
|
+
export {
|
|
42
|
+
HEADER_OPERATORS,
|
|
43
|
+
type HeaderOperator,
|
|
44
|
+
HEADER_RULE_MARKER,
|
|
45
|
+
isHeaderOperator,
|
|
46
|
+
evaluateHeaderCondition,
|
|
47
|
+
accessRuleHeaderMatches,
|
|
48
|
+
encodeHeaderValueList,
|
|
49
|
+
decodeHeaderValueList,
|
|
50
|
+
} from "./headerMatch.js";
|
|
51
|
+
|
|
41
52
|
export {
|
|
42
53
|
type AccessRulesFilter,
|
|
43
54
|
type AccessRulesStorage,
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
// Copyright 2021-2026 Prosopo (UK) Ltd.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Operators for an access rule's arbitrary-header condition.
|
|
17
|
+
*
|
|
18
|
+
* `equals` / `contains` are the deny-list operators (block when the request's
|
|
19
|
+
* header matches). `notEquals` / `notContains` are their allow-list negations
|
|
20
|
+
* (block when the request's header does NOT match — including when the header
|
|
21
|
+
* is absent), so an allow-list card that says "only let requests with header X
|
|
22
|
+
* through" desugars to `notEquals` / `notContains` Block rules, exactly the way
|
|
23
|
+
* the OS allow-list desugars to Block rules on the complement.
|
|
24
|
+
*
|
|
25
|
+
* `notEqualsAny` / `notContainsAny` are the multi-value form of those two: the
|
|
26
|
+
* rule's `headerValue` holds a list (see `encodeHeaderValueList`) and the rule
|
|
27
|
+
* blocks unless the request's header matches *one of* the listed values. They
|
|
28
|
+
* exist because an allow-list over several values of the SAME header cannot be
|
|
29
|
+
* expressed as several single-value rules — each rule fires independently, so
|
|
30
|
+
* `notEquals ios` + `notEquals android` blocks both an iOS and an Android
|
|
31
|
+
* request. One rule holding both values is the only way to get the "any of"
|
|
32
|
+
* semantics the allow-list needs.
|
|
33
|
+
*/
|
|
34
|
+
export const HEADER_OPERATORS = [
|
|
35
|
+
"equals",
|
|
36
|
+
"contains",
|
|
37
|
+
"notEquals",
|
|
38
|
+
"notContains",
|
|
39
|
+
"notEqualsAny",
|
|
40
|
+
"notContainsAny",
|
|
41
|
+
] as const;
|
|
42
|
+
|
|
43
|
+
export type HeaderOperator = (typeof HEADER_OPERATORS)[number];
|
|
44
|
+
|
|
45
|
+
export const isHeaderOperator = (
|
|
46
|
+
value: string | undefined,
|
|
47
|
+
): value is HeaderOperator =>
|
|
48
|
+
value !== undefined &&
|
|
49
|
+
(HEADER_OPERATORS as ReadonlyArray<string>).includes(value);
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Sentinel value carried both on every request's user scope (see
|
|
53
|
+
* `getRequestUserScope`) and on every header-restriction rule. Header rules
|
|
54
|
+
* match on data (`headerName` / `headerValue` / `headerOperator`) that Redis
|
|
55
|
+
* cannot evaluate — substring `contains` and per-rule operators aren't
|
|
56
|
+
* expressible as a TAG query, and an allow-list rule must still fire on a
|
|
57
|
+
* request that OMITS the target header, so candidate selection can't key off
|
|
58
|
+
* header presence. Redis returns header rules via the reader's
|
|
59
|
+
* `no-user-scope` fall-through probe (they constrain none of the indexed
|
|
60
|
+
* scope dimensions); this marker is what keeps them candidates through the
|
|
61
|
+
* JS-side `ruleApplies` scalar check, which would otherwise drop a rule
|
|
62
|
+
* carrying a scope field the request lacks. The concrete condition is then
|
|
63
|
+
* checked by `accessRuleHeaderMatches`.
|
|
64
|
+
*/
|
|
65
|
+
export const HEADER_RULE_MARKER = "1";
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Encode the value list carried by a multi-value operator (`notEqualsAny` /
|
|
69
|
+
* `notContainsAny`) into the single `headerValue` string an access rule can
|
|
70
|
+
* store. JSON rather than a delimiter because header values are arbitrary
|
|
71
|
+
* text — any separator we picked could legitimately occur inside a value.
|
|
72
|
+
*/
|
|
73
|
+
export const encodeHeaderValueList = (values: ReadonlyArray<string>): string =>
|
|
74
|
+
JSON.stringify(values);
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Inverse of {@link encodeHeaderValueList}, tolerant of rules written by hand
|
|
78
|
+
* (e.g. via the access-policy CLI) that carry a single literal value instead of
|
|
79
|
+
* an encoded list.
|
|
80
|
+
*
|
|
81
|
+
* Returns `undefined` for a value that looks list-encoded but isn't usable — an
|
|
82
|
+
* empty list, a non-array, non-string members, or malformed JSON. Callers treat
|
|
83
|
+
* that as a malformed rule and decline to fire it, so a garbled list can't
|
|
84
|
+
* silently block all traffic.
|
|
85
|
+
*/
|
|
86
|
+
export const decodeHeaderValueList = (value: string): string[] | undefined => {
|
|
87
|
+
if (!value.trimStart().startsWith("[")) {
|
|
88
|
+
// Not list-encoded: treat the whole string as a one-value list.
|
|
89
|
+
return [value];
|
|
90
|
+
}
|
|
91
|
+
let parsed: unknown;
|
|
92
|
+
try {
|
|
93
|
+
parsed = JSON.parse(value);
|
|
94
|
+
} catch {
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
if (
|
|
98
|
+
!Array.isArray(parsed) ||
|
|
99
|
+
parsed.length === 0 ||
|
|
100
|
+
!parsed.every((entry): entry is string => typeof entry === "string")
|
|
101
|
+
) {
|
|
102
|
+
return undefined;
|
|
103
|
+
}
|
|
104
|
+
return parsed;
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Evaluate a single header condition against a request's headers. Returns
|
|
109
|
+
* `true` when the condition is satisfied — i.e. when a Block rule carrying it
|
|
110
|
+
* should fire for this request.
|
|
111
|
+
*
|
|
112
|
+
* `headers` is expected to be keyed by lower-cased header name (HTTP header
|
|
113
|
+
* names are case-insensitive); `headerName` is lower-cased here defensively.
|
|
114
|
+
* The negated operators treat an absent header as "not matching the value",
|
|
115
|
+
* which is what makes an allow-list block a request that drops the header.
|
|
116
|
+
*/
|
|
117
|
+
export const evaluateHeaderCondition = (
|
|
118
|
+
headerName: string,
|
|
119
|
+
operator: HeaderOperator,
|
|
120
|
+
value: string,
|
|
121
|
+
headers: Record<string, string>,
|
|
122
|
+
): boolean => {
|
|
123
|
+
const actual = headers[headerName.toLowerCase()];
|
|
124
|
+
switch (operator) {
|
|
125
|
+
case "equals":
|
|
126
|
+
return actual !== undefined && actual === value;
|
|
127
|
+
case "contains":
|
|
128
|
+
return actual?.includes(value) ?? false;
|
|
129
|
+
case "notEquals":
|
|
130
|
+
return actual === undefined || actual !== value;
|
|
131
|
+
case "notContains":
|
|
132
|
+
return actual === undefined || !actual.includes(value);
|
|
133
|
+
case "notEqualsAny": {
|
|
134
|
+
const values = decodeHeaderValueList(value);
|
|
135
|
+
if (values === undefined) {
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
return actual === undefined || !values.includes(actual);
|
|
139
|
+
}
|
|
140
|
+
case "notContainsAny": {
|
|
141
|
+
const values = decodeHeaderValueList(value);
|
|
142
|
+
if (values === undefined) {
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
return (
|
|
146
|
+
actual === undefined ||
|
|
147
|
+
!values.some((candidate) => actual.includes(candidate))
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Whether a rule's header condition (if any) is satisfied by the request's
|
|
155
|
+
* headers. A rule with no `headerName` carries no header constraint, so it is
|
|
156
|
+
* treated as satisfied and the rule's other dimensions decide the match. A
|
|
157
|
+
* rule with a `headerName` but an unrecognised operator is malformed and never
|
|
158
|
+
* matches (fail-safe: a garbled rule must not silently block traffic).
|
|
159
|
+
*/
|
|
160
|
+
export const accessRuleHeaderMatches = (
|
|
161
|
+
rule: {
|
|
162
|
+
headerName?: string;
|
|
163
|
+
headerValue?: string;
|
|
164
|
+
headerOperator?: string;
|
|
165
|
+
},
|
|
166
|
+
headers: Record<string, string>,
|
|
167
|
+
): boolean => {
|
|
168
|
+
if (rule.headerName === undefined) {
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
if (!isHeaderOperator(rule.headerOperator)) {
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
174
|
+
return evaluateHeaderCondition(
|
|
175
|
+
rule.headerName,
|
|
176
|
+
rule.headerOperator,
|
|
177
|
+
rule.headerValue ?? "",
|
|
178
|
+
headers,
|
|
179
|
+
);
|
|
180
|
+
};
|
|
@@ -33,6 +33,11 @@ const userAttributesSchema: SchemaDefinition<UserAttributesRecord> = {
|
|
|
33
33
|
asn: { type: Number, required: false },
|
|
34
34
|
os: { type: String, required: false },
|
|
35
35
|
browser: { type: String, required: false },
|
|
36
|
+
headerMatch: { type: String, required: false },
|
|
37
|
+
headerName: { type: String, required: false },
|
|
38
|
+
headerValue: { type: String, required: false },
|
|
39
|
+
headerOperator: { type: String, required: false },
|
|
40
|
+
webBotAuthAgent: { type: String, required: false },
|
|
36
41
|
} satisfies AllKeys<UserAttributesRecord>;
|
|
37
42
|
|
|
38
43
|
const userIpSchema: SchemaDefinition<UserIpRecord> = {
|
|
@@ -96,6 +96,9 @@ const SPECIFICITY_EXPR = [
|
|
|
96
96
|
"exists(@asn)",
|
|
97
97
|
"exists(@os)",
|
|
98
98
|
"exists(@browser)",
|
|
99
|
+
// A header rule is one logical dimension: only the sentinel counts toward
|
|
100
|
+
// specificity, not the name/value/operator triple it also carries.
|
|
101
|
+
"exists(@headerMatch)",
|
|
99
102
|
"exists(@numericIp)",
|
|
100
103
|
"exists(@numericIpMaskMin)",
|
|
101
104
|
].join(" + ");
|
|
@@ -137,6 +140,10 @@ const RULE_LOAD_FIELDS = [
|
|
|
137
140
|
"@asn",
|
|
138
141
|
"@os",
|
|
139
142
|
"@browser",
|
|
143
|
+
"@headerMatch",
|
|
144
|
+
"@headerName",
|
|
145
|
+
"@headerValue",
|
|
146
|
+
"@headerOperator",
|
|
140
147
|
"@numericIp",
|
|
141
148
|
"@numericIpMaskMin",
|
|
142
149
|
"@numericIpMaskMax",
|
|
@@ -42,6 +42,20 @@ export const userAttributesRedisSchema: RediSearchSchema = {
|
|
|
42
42
|
asn: { type: SCHEMA_FIELD_TYPE.NUMERIC, INDEXMISSING: true },
|
|
43
43
|
os: { type: SCHEMA_FIELD_TYPE.TAG, INDEXMISSING: true },
|
|
44
44
|
browser: { type: SCHEMA_FIELD_TYPE.TAG, INDEXMISSING: true },
|
|
45
|
+
// Header-restriction fields. NONE of these are queried on the hot path:
|
|
46
|
+
// the split-query builder probes neither `headerMatch` nor the
|
|
47
|
+
// name/value/operator triple, and a header rule populates none of the
|
|
48
|
+
// fields that builder does probe, so it is returned by the `no-user-scope`
|
|
49
|
+
// fall-through probe (the same route `os` rules take) and the concrete
|
|
50
|
+
// condition is evaluated in code by `accessRuleHeaderMatches`. They are
|
|
51
|
+
// indexed to satisfy the schema exhaustiveness check, and `headerMatch`
|
|
52
|
+
// additionally gates candidacy JS-side in `ruleApplies` and scores one
|
|
53
|
+
// specificity point in the reader's SPECIFICITY_EXPR.
|
|
54
|
+
headerMatch: { type: SCHEMA_FIELD_TYPE.TAG, INDEXMISSING: true },
|
|
55
|
+
headerName: { type: SCHEMA_FIELD_TYPE.TAG, INDEXMISSING: true },
|
|
56
|
+
headerValue: { type: SCHEMA_FIELD_TYPE.TAG, INDEXMISSING: true },
|
|
57
|
+
headerOperator: { type: SCHEMA_FIELD_TYPE.TAG, INDEXMISSING: true },
|
|
58
|
+
webBotAuthAgent: { type: SCHEMA_FIELD_TYPE.TAG, INDEXMISSING: true },
|
|
45
59
|
} satisfies AllKeys<UserAttributes>;
|
|
46
60
|
|
|
47
61
|
export const userScopeRedisSchema: RediSearchSchema = {
|