@prosopo/user-access-policy 3.3.2 → 3.5.19

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/CHANGELOG.md CHANGED
@@ -1,5 +1,271 @@
1
1
  # @prosopo/user-access-policy
2
2
 
3
+ ## 3.5.19
4
+ ### Patch Changes
5
+
6
+ - @prosopo/api@3.1.24
7
+ - @prosopo/api-route@2.6.28
8
+ - @prosopo/common@3.1.20
9
+ - @prosopo/redis-client@1.0.5
10
+ - @prosopo/types@3.5.3
11
+ - @prosopo/util@3.1.5
12
+
13
+ ## 3.5.18
14
+ ### Patch Changes
15
+
16
+ - 5659b24: Release 3.4.4
17
+ - Updated dependencies [f912439]
18
+ - Updated dependencies [5659b24]
19
+ - @prosopo/common@3.1.19
20
+ - @prosopo/redis-client@1.0.4
21
+ - @prosopo/api-route@2.6.27
22
+ - @prosopo/types@3.5.2
23
+ - @prosopo/util@3.1.4
24
+ - @prosopo/api@3.1.23
25
+
26
+ ## 3.5.17
27
+ ### Patch Changes
28
+
29
+ - 50c4120: Release 3.4.3
30
+ - Updated dependencies [52cd544]
31
+ - Updated dependencies [b117ba3]
32
+ - Updated dependencies [50c4120]
33
+ - @prosopo/types@3.5.1
34
+ - @prosopo/redis-client@1.0.3
35
+ - @prosopo/api-route@2.6.26
36
+ - @prosopo/common@3.1.18
37
+ - @prosopo/util@3.1.3
38
+ - @prosopo/api@3.1.22
39
+
40
+ ## 3.5.16
41
+ ### Patch Changes
42
+
43
+ - 618703f: Release 3.4.2
44
+ - Updated dependencies [618703f]
45
+ - Updated dependencies [e20ad6b]
46
+ - @prosopo/redis-client@1.0.2
47
+ - @prosopo/api-route@2.6.25
48
+ - @prosopo/common@3.1.17
49
+ - @prosopo/types@3.5.0
50
+ - @prosopo/util@3.1.2
51
+ - @prosopo/api@3.1.21
52
+
53
+ ## 3.5.15
54
+ ### Patch Changes
55
+
56
+ - 11303d9: feat/pluggable-redis
57
+ - 11303d9: Release 3.4.0
58
+ - 18cb28b: Release 3.4.1
59
+ - 11303d9: feat/pluggable-redis
60
+ - Updated dependencies [11303d9]
61
+ - Updated dependencies [11303d9]
62
+ - Updated dependencies [18cb28b]
63
+ - Updated dependencies [11303d9]
64
+ - @prosopo/redis-client@1.0.1
65
+ - @prosopo/api-route@2.6.24
66
+ - @prosopo/common@3.1.16
67
+ - @prosopo/types@3.4.1
68
+ - @prosopo/util@3.1.1
69
+ - @prosopo/api@3.1.20
70
+
71
+ ## 3.5.14
72
+ ### Patch Changes
73
+
74
+ - f3f7aec: Release 3.4.0
75
+ - Updated dependencies [f3f7aec]
76
+ - Updated dependencies [6768f14]
77
+ - @prosopo/api-route@2.6.23
78
+ - @prosopo/common@3.1.15
79
+ - @prosopo/types@3.4.0
80
+ - @prosopo/util@3.1.0
81
+ - @prosopo/config@3.1.15
82
+
83
+ ## 3.5.13
84
+ ### Patch Changes
85
+
86
+ - Release 3.3.1
87
+ - 0824221: Release 3.2.4
88
+ - Updated dependencies [97edf3f]
89
+ - Updated dependencies
90
+ - Updated dependencies [0824221]
91
+ - @prosopo/types@3.3.0
92
+ - @prosopo/api-route@2.6.22
93
+ - @prosopo/common@3.1.14
94
+ - @prosopo/util@3.0.17
95
+ - @prosopo/config@3.1.14
96
+
97
+ ## 3.5.12
98
+ ### Patch Changes
99
+
100
+ - 008d112: Release 3.3.0
101
+ - Updated dependencies [509be28]
102
+ - Updated dependencies [008d112]
103
+ - @prosopo/types@3.2.1
104
+ - @prosopo/api-route@2.6.21
105
+ - @prosopo/common@3.1.13
106
+ - @prosopo/util@3.0.16
107
+ - @prosopo/config@3.1.13
108
+
109
+ ## 3.5.11
110
+ ### Patch Changes
111
+
112
+ - 0824221: Release 3.2.4
113
+ - Updated dependencies [cf48565]
114
+ - Updated dependencies [0824221]
115
+ - @prosopo/types@3.2.0
116
+ - @prosopo/api-route@2.6.20
117
+ - @prosopo/common@3.1.12
118
+ - @prosopo/util@3.0.15
119
+ - @prosopo/config@3.1.12
120
+
121
+ ## 3.5.10
122
+ ### Patch Changes
123
+
124
+ - 1a23649: Release 3.2.3
125
+ - Updated dependencies [0d1a33e]
126
+ - Updated dependencies [0d1a33e]
127
+ - Updated dependencies [1a23649]
128
+ - @prosopo/types@3.1.4
129
+ - @prosopo/api-route@2.6.19
130
+ - @prosopo/common@3.1.11
131
+ - @prosopo/util@3.0.14
132
+ - @prosopo/config@3.1.11
133
+
134
+ ## 3.5.9
135
+ ### Patch Changes
136
+
137
+ - 657a827: Release 3.2.2
138
+ - Updated dependencies [657a827]
139
+ - @prosopo/api-route@2.6.18
140
+ - @prosopo/common@3.1.10
141
+ - @prosopo/types@3.1.3
142
+ - @prosopo/util@3.0.13
143
+ - @prosopo/config@3.1.10
144
+
145
+ ## 3.5.8
146
+ ### Patch Changes
147
+
148
+ - 4440947: fix type-only tsc compilation
149
+ - 7bdaca6: Release 3.2.1
150
+ - Updated dependencies [4440947]
151
+ - Updated dependencies [7bdaca6]
152
+ - Updated dependencies [809b984]
153
+ - Updated dependencies [1249ce0]
154
+ - Updated dependencies [809b984]
155
+ - @prosopo/api-route@2.6.17
156
+ - @prosopo/common@3.1.9
157
+ - @prosopo/types@3.1.2
158
+ - @prosopo/util@3.0.12
159
+ - @prosopo/config@3.1.9
160
+
161
+ ## 3.5.7
162
+ ### Patch Changes
163
+
164
+ - 6fe8570: Release 3.2.0
165
+ - Updated dependencies [1f980c4]
166
+ - Updated dependencies [6fe8570]
167
+ - @prosopo/types@3.1.1
168
+ - @prosopo/api-route@2.6.16
169
+ - @prosopo/common@3.1.8
170
+ - @prosopo/util@3.0.11
171
+ - @prosopo/config@3.1.8
172
+
173
+ ## 3.5.6
174
+ ### Patch Changes
175
+
176
+ - f304be9: Release 3.1.13
177
+ - Updated dependencies [f304be9]
178
+ - Updated dependencies [8bdc7f0]
179
+ - @prosopo/api-route@2.6.15
180
+ - @prosopo/common@3.1.7
181
+ - @prosopo/types@3.1.0
182
+ - @prosopo/util@3.0.10
183
+ - @prosopo/config@3.1.7
184
+
185
+ ## 3.5.5
186
+ ### Patch Changes
187
+
188
+ - a07db04: Release 3.1.12
189
+ - Updated dependencies [9eed772]
190
+ - Updated dependencies [ebb0168]
191
+ - @prosopo/config@3.1.6
192
+ - @prosopo/util@3.0.9
193
+ - @prosopo/api-route@2.6.14
194
+ - @prosopo/common@3.1.6
195
+ - @prosopo/types@3.0.10
196
+
197
+ ## 3.5.4
198
+ ### Patch Changes
199
+
200
+ - 553025d: Index
201
+
202
+ ## 3.5.3
203
+ ### Patch Changes
204
+
205
+ - 6960643: lint detect missing and unneccessary imports
206
+ - Updated dependencies [6960643]
207
+ - @prosopo/api-route@2.6.13
208
+ - @prosopo/common@3.1.5
209
+ - @prosopo/types@3.0.9
210
+ - @prosopo/util@3.0.8
211
+
212
+ ## 3.5.2
213
+ ### Patch Changes
214
+
215
+ - Updated dependencies [30e7d4d]
216
+ - @prosopo/config@3.1.5
217
+ - @prosopo/api-route@2.6.12
218
+ - @prosopo/common@3.1.4
219
+ - @prosopo/types@3.0.8
220
+ - @prosopo/util@3.0.7
221
+
222
+ ## 3.5.1
223
+ ### Patch Changes
224
+
225
+ - 1f3a02f: Release 3.1.8
226
+
227
+ ## 3.5.0
228
+ ### Minor Changes
229
+
230
+ - e0628d9: Make sure rules don't leak between IPs
231
+
232
+ ## 3.4.1
233
+ ### Patch Changes
234
+
235
+ - a49b538: Extra tests
236
+ - e090e2f: More tests
237
+ - Updated dependencies [44ffda2]
238
+ - Updated dependencies [a49b538]
239
+ - @prosopo/config@3.1.4
240
+ - @prosopo/common@3.1.3
241
+ - @prosopo/api-route@2.6.11
242
+ - @prosopo/types@3.0.7
243
+ - @prosopo/util@3.0.6
244
+
245
+ ## 3.4.0
246
+ ### Minor Changes
247
+
248
+ - df4e030: Revising UAP rule getters
249
+
250
+ ### Patch Changes
251
+
252
+ - 91bbe87: configure typecheck before bundle for vue packages
253
+ - 91bbe87: make typecheck script always recompile
254
+ - 346e092: NODE_ENV default to "development"
255
+ - 5d36e05: remove tsc --force
256
+ - Updated dependencies [828066d]
257
+ - Updated dependencies [df4e030]
258
+ - Updated dependencies [91bbe87]
259
+ - Updated dependencies [3ef4fd2]
260
+ - Updated dependencies [91bbe87]
261
+ - Updated dependencies [346e092]
262
+ - Updated dependencies [5d36e05]
263
+ - @prosopo/api-route@2.6.10
264
+ - @prosopo/common@3.1.2
265
+ - @prosopo/types@3.0.6
266
+ - @prosopo/config@3.1.3
267
+ - @prosopo/util@3.0.5
268
+
3
269
  ## 3.3.2
4
270
  ### Patch Changes
5
271
 
@@ -1,6 +1,5 @@
1
- import * as util from "node:util";
2
1
  import { z } from "zod";
3
- import { userScopeInputSchema, policyScopeSchema, AccessPolicyType } from "./accessPolicy.js";
2
+ import { userScopeInputSchema, policyScopeSchema } from "./accessPolicy.js";
4
3
  var ScopeMatch = /* @__PURE__ */ ((ScopeMatch2) => {
5
4
  ScopeMatch2["Exact"] = "exact";
6
5
  ScopeMatch2["Greedy"] = "greedy";
@@ -26,45 +25,7 @@ const policyFilterSchema = z.object({
26
25
  /* Exact */
27
26
  )
28
27
  });
29
- const createAccessPolicyResolver = (accessRulesReader, logger) => {
30
- return async (filter) => {
31
- const accessRules = await accessRulesReader.findRules(filter);
32
- const primaryAccessRule = resolvePrimaryRule(accessRules);
33
- logger.debug(() => ({
34
- msg: "Resolved access policy",
35
- // filter contains BigInt, which can't be handled directly via logger.
36
- data: {
37
- inspect: util.inspect(
38
- {
39
- filter,
40
- accessRules,
41
- primaryAccessRule
42
- },
43
- { depth: null }
44
- )
45
- }
46
- }));
47
- return primaryAccessRule;
48
- };
49
- };
50
- const resolvePrimaryRule = (rules) => {
51
- const blockingRules = rules.filter(
52
- (accessRule) => AccessPolicyType.Block === accessRule.type
53
- );
54
- const rulesToEvaluate = blockingRules.length > 0 ? blockingRules : rules;
55
- return resolveMostLocalRule(rulesToEvaluate);
56
- };
57
- const resolveMostLocalRule = (rules) => {
58
- const clientRules = rules.filter(
59
- (accessRule) => "string" === typeof accessRule.clientId
60
- );
61
- if (clientRules.length > 0) {
62
- return clientRules.shift();
63
- }
64
- return rules.shift();
65
- };
66
28
  export {
67
29
  ScopeMatch,
68
- createAccessPolicyResolver,
69
30
  policyFilterSchema
70
31
  };
@@ -0,0 +1,38 @@
1
+ import { ApiClient } from "@prosopo/api";
2
+ import { accessRuleApiPaths } from "./accessRuleApiRoutes.js";
3
+ class AccessRulesApiClient extends ApiClient {
4
+ insertMany(toInsert, timestamp, signature) {
5
+ return this.post(accessRuleApiPaths.INSERT_MANY, toInsert, {
6
+ headers: {
7
+ "Prosopo-Site-Key": this.account,
8
+ timestamp,
9
+ signature
10
+ }
11
+ });
12
+ }
13
+ deleteMany(toDelete, timestamp, signature) {
14
+ return this.post(accessRuleApiPaths.DELETE_MANY, toDelete, {
15
+ headers: {
16
+ "Prosopo-Site-Key": this.account,
17
+ timestamp,
18
+ signature
19
+ }
20
+ });
21
+ }
22
+ deleteAll(timestamp, signature) {
23
+ return this.post(
24
+ accessRuleApiPaths.DELETE_ALL,
25
+ {},
26
+ {
27
+ headers: {
28
+ "Prosopo-Site-Key": this.account,
29
+ timestamp,
30
+ signature
31
+ }
32
+ }
33
+ );
34
+ }
35
+ }
36
+ export {
37
+ AccessRulesApiClient
38
+ };
@@ -1,25 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const util = require("node:util");
4
3
  const zod = require("zod");
5
4
  const accessPolicy = require("./accessPolicy.cjs");
6
- function _interopNamespaceDefault(e) {
7
- const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
8
- if (e) {
9
- for (const k in e) {
10
- if (k !== "default") {
11
- const d = Object.getOwnPropertyDescriptor(e, k);
12
- Object.defineProperty(n, k, d.get ? d : {
13
- enumerable: true,
14
- get: () => e[k]
15
- });
16
- }
17
- }
18
- }
19
- n.default = e;
20
- return Object.freeze(n);
21
- }
22
- const util__namespace = /* @__PURE__ */ _interopNamespaceDefault(util);
23
5
  var ScopeMatch = /* @__PURE__ */ ((ScopeMatch2) => {
24
6
  ScopeMatch2["Exact"] = "exact";
25
7
  ScopeMatch2["Greedy"] = "greedy";
@@ -45,43 +27,5 @@ const policyFilterSchema = zod.z.object({
45
27
  /* Exact */
46
28
  )
47
29
  });
48
- const createAccessPolicyResolver = (accessRulesReader, logger) => {
49
- return async (filter) => {
50
- const accessRules = await accessRulesReader.findRules(filter);
51
- const primaryAccessRule = resolvePrimaryRule(accessRules);
52
- logger.debug(() => ({
53
- msg: "Resolved access policy",
54
- // filter contains BigInt, which can't be handled directly via logger.
55
- data: {
56
- inspect: util__namespace.inspect(
57
- {
58
- filter,
59
- accessRules,
60
- primaryAccessRule
61
- },
62
- { depth: null }
63
- )
64
- }
65
- }));
66
- return primaryAccessRule;
67
- };
68
- };
69
- const resolvePrimaryRule = (rules) => {
70
- const blockingRules = rules.filter(
71
- (accessRule) => accessPolicy.AccessPolicyType.Block === accessRule.type
72
- );
73
- const rulesToEvaluate = blockingRules.length > 0 ? blockingRules : rules;
74
- return resolveMostLocalRule(rulesToEvaluate);
75
- };
76
- const resolveMostLocalRule = (rules) => {
77
- const clientRules = rules.filter(
78
- (accessRule) => "string" === typeof accessRule.clientId
79
- );
80
- if (clientRules.length > 0) {
81
- return clientRules.shift();
82
- }
83
- return rules.shift();
84
- };
85
30
  exports.ScopeMatch = ScopeMatch;
86
- exports.createAccessPolicyResolver = createAccessPolicyResolver;
87
31
  exports.policyFilterSchema = policyFilterSchema;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const api = require("@prosopo/api");
4
+ const accessRuleApiRoutes = require("./accessRuleApiRoutes.cjs");
5
+ class AccessRulesApiClient extends api.ApiClient {
6
+ insertMany(toInsert, timestamp, signature) {
7
+ return this.post(accessRuleApiRoutes.accessRuleApiPaths.INSERT_MANY, toInsert, {
8
+ headers: {
9
+ "Prosopo-Site-Key": this.account,
10
+ timestamp,
11
+ signature
12
+ }
13
+ });
14
+ }
15
+ deleteMany(toDelete, timestamp, signature) {
16
+ return this.post(accessRuleApiRoutes.accessRuleApiPaths.DELETE_MANY, toDelete, {
17
+ headers: {
18
+ "Prosopo-Site-Key": this.account,
19
+ timestamp,
20
+ signature
21
+ }
22
+ });
23
+ }
24
+ deleteAll(timestamp, signature) {
25
+ return this.post(
26
+ accessRuleApiRoutes.accessRuleApiPaths.DELETE_ALL,
27
+ {},
28
+ {
29
+ headers: {
30
+ "Prosopo-Site-Key": this.account,
31
+ timestamp,
32
+ signature
33
+ }
34
+ }
35
+ );
36
+ }
37
+ }
38
+ exports.AccessRulesApiClient = AccessRulesApiClient;
@@ -2,26 +2,30 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const accessPolicy = require("./accessPolicy.cjs");
4
4
  const accessPolicyResolver = require("./accessPolicyResolver.cjs");
5
+ const accessRules = require("./accessRules.cjs");
5
6
  const accessRuleApiRoutes = require("./api/accessRuleApiRoutes.cjs");
6
7
  const deleteAllRulesEndpoint = require("./api/deleteAllRulesEndpoint.cjs");
7
8
  const deleteRulesEndpoint = require("./api/deleteRulesEndpoint.cjs");
8
9
  const insertRulesEndpoint = require("./api/insertRulesEndpoint.cjs");
9
- const redisAccessRules = require("./redis/redisAccessRules.cjs");
10
- const redisAccessRulesIndex = require("./redis/redisAccessRulesIndex.cjs");
10
+ const redisRulesStorage = require("./redis/redisRulesStorage.cjs");
11
+ const redisRulesIndex = require("./redis/redisRulesIndex.cjs");
12
+ const accessRulesApiClient = require("./api/accessRulesApiClient.cjs");
11
13
  const createApiRuleRoutesProvider = (rulesStorage) => {
12
14
  return new accessRuleApiRoutes.AccessRuleApiRoutes(rulesStorage);
13
15
  };
14
16
  exports.AccessPolicyType = accessPolicy.AccessPolicyType;
15
17
  exports.accessPolicySchema = accessPolicy.accessPolicySchema;
18
+ exports.accessRuleSchemaExtended = accessPolicy.accessRuleSchemaExtended;
16
19
  exports.policyScopeSchema = accessPolicy.policyScopeSchema;
17
20
  exports.userScopeInputSchema = accessPolicy.userScopeInputSchema;
18
21
  exports.ScopeMatch = accessPolicyResolver.ScopeMatch;
19
- exports.createAccessPolicyResolver = accessPolicyResolver.createAccessPolicyResolver;
22
+ exports.accessRuleSchema = accessRules.accessRuleSchema;
20
23
  exports.accessRuleApiPaths = accessRuleApiRoutes.accessRuleApiPaths;
21
24
  exports.getExpressApiRuleRateLimits = accessRuleApiRoutes.getExpressApiRuleRateLimits;
22
25
  exports.deleteAllRulesEndpointSchema = deleteAllRulesEndpoint.deleteAllRulesEndpointSchema;
23
26
  exports.deleteRulesEndpointSchema = deleteRulesEndpoint.deleteRulesEndpointSchema;
24
27
  exports.insertRulesEndpointSchema = insertRulesEndpoint.insertRulesEndpointSchema;
25
- exports.createRedisAccessRulesStorage = redisAccessRules.createRedisAccessRulesStorage;
26
- exports.createRedisAccessRulesIndex = redisAccessRulesIndex.createRedisAccessRulesIndex;
28
+ exports.createRedisAccessRulesStorage = redisRulesStorage.createRedisAccessRulesStorage;
29
+ exports.redisAccessRulesIndex = redisRulesIndex.redisAccessRulesIndex;
30
+ exports.AccessRulesApiClient = accessRulesApiClient.AccessRulesApiClient;
27
31
  exports.createApiRuleRoutesProvider = createApiRuleRoutesProvider;
@@ -0,0 +1,138 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const search = require("@redis/search");
4
+ const accessPolicy = require("../accessPolicy.cjs");
5
+ const accessPolicyResolver = require("../accessPolicyResolver.cjs");
6
+ const redisRulesIndexName = "index:user-access-rules";
7
+ const redisRuleKeyPrefix = "uar:";
8
+ const redisAccessRulesIndex = {
9
+ name: redisRulesIndexName,
10
+ /**
11
+ * Note on the field type decision
12
+ *
13
+ * TAG is designed for the exact value matching
14
+ * TEXT is designed for the word-based and pattern matching
15
+ *
16
+ * For our goal TAG fits perfectly and, more performant
17
+ */
18
+ schema: {
19
+ clientId: {
20
+ type: search.SCHEMA_FIELD_TYPE.TAG,
21
+ // necessary to make possible use of the ismissing() function on this field in the search
22
+ INDEXMISSING: true
23
+ },
24
+ numericIpMaskMin: { type: search.SCHEMA_FIELD_TYPE.NUMERIC, INDEXMISSING: true },
25
+ numericIpMaskMax: { type: search.SCHEMA_FIELD_TYPE.NUMERIC, INDEXMISSING: true },
26
+ userId: { type: search.SCHEMA_FIELD_TYPE.TAG, INDEXMISSING: true },
27
+ numericIp: { type: search.SCHEMA_FIELD_TYPE.NUMERIC, INDEXMISSING: true },
28
+ ja4Hash: { type: search.SCHEMA_FIELD_TYPE.TAG, INDEXMISSING: true },
29
+ headersHash: { type: search.SCHEMA_FIELD_TYPE.TAG, INDEXMISSING: true },
30
+ userAgentHash: { type: search.SCHEMA_FIELD_TYPE.TAG, INDEXMISSING: true }
31
+ },
32
+ // the satisfy statement is to guarantee that the keys are right
33
+ options: {
34
+ ON: "HASH",
35
+ PREFIX: [redisRuleKeyPrefix]
36
+ }
37
+ };
38
+ const numericIndexFields = [
39
+ "numericIp",
40
+ "numericIpMaskMin",
41
+ "numericIpMaskMax"
42
+ ];
43
+ const greedyFieldComparisons = {
44
+ numericIp: (value, scope) => {
45
+ if (value !== void 0) {
46
+ return `( @numericIp:[${value}] | ( @numericIpMaskMin:[-inf ${value}] @numericIpMaskMax:[${value} +inf] ) )`;
47
+ }
48
+ if (scope.numericIpMaskMin === void 0 && scope.numericIpMaskMax === void 0) {
49
+ return "ismissing(@numericIp) ismissing(@numericIpMaskMin) ismissing(@numericIpMaskMax)";
50
+ }
51
+ return "";
52
+ },
53
+ numericIpMaskMin: (value, scope) => {
54
+ if (scope.numericIp !== void 0) {
55
+ return "";
56
+ }
57
+ return value !== void 0 ? `@numericIpMaskMin:[-inf ${value}]` : "ismissing(@numericIpMaskMin)";
58
+ },
59
+ numericIpMaskMax: (value, scope) => {
60
+ if (scope.numericIp !== void 0) {
61
+ return "";
62
+ }
63
+ return value !== void 0 ? `@numericIpMaskMax:[${value} +inf]` : "ismissing(@numericIpMaskMax)";
64
+ }
65
+ };
66
+ const redisRulesSearchOptions = {
67
+ // #2 is a required option when the 'ismissing()' function is in the query body
68
+ DIALECT: 2
69
+ };
70
+ const getRedisRulesQuery = (filter, matchingFieldsOnly) => {
71
+ const { policyScope, userScope } = filter;
72
+ const policyScopeFilter = getPolicyScopeQuery(
73
+ policyScope,
74
+ filter.policyScopeMatch
75
+ );
76
+ if (userScope && Object.keys(userScope).length > 0) {
77
+ const userScopeFilter = getUserScopeQuery(
78
+ userScope,
79
+ filter.userScopeMatch,
80
+ matchingFieldsOnly
81
+ );
82
+ return `${policyScopeFilter} ( ${userScopeFilter} )`;
83
+ }
84
+ return policyScopeFilter ? policyScopeFilter : "*";
85
+ };
86
+ const getPolicyScopeQuery = (policyScope, scopeMatchType) => {
87
+ const clientId = policyScope?.clientId;
88
+ if ("string" === typeof clientId) {
89
+ return accessPolicyResolver.ScopeMatch.Exact === scopeMatchType ? `@clientId:{${clientId}}` : `( @clientId:{${clientId}} | ismissing(@clientId) )`;
90
+ }
91
+ return accessPolicyResolver.ScopeMatch.Exact === scopeMatchType ? "ismissing(@clientId)" : "";
92
+ };
93
+ const getUserScopeQuery = (userScope, scopeMatchType, matchingFieldsOnly) => {
94
+ let scopeEntries = Object.entries(userScope);
95
+ let scopeJoinType = " ";
96
+ if (scopeMatchType === accessPolicyResolver.ScopeMatch.Greedy) {
97
+ scopeEntries = scopeEntries.filter(
98
+ ([_, value]) => value !== void 0
99
+ );
100
+ scopeJoinType = " | ";
101
+ }
102
+ if (matchingFieldsOnly) {
103
+ const scopeMap = new Map(scopeEntries);
104
+ if (scopeMap.has("numericIp") && scopeMap.get("numericIp") === void 0) {
105
+ scopeMap.set("numericIpMaskMin", void 0);
106
+ scopeMap.set("numericIpMaskMax", void 0);
107
+ }
108
+ for (const name of Object.keys(accessPolicy.userScopeSchema.shape)) {
109
+ if (!scopeMap.has(name)) {
110
+ scopeMap.set(name, void 0);
111
+ }
112
+ }
113
+ scopeEntries = [...scopeMap.entries()];
114
+ }
115
+ const scopeObj = Object.fromEntries(scopeEntries);
116
+ return scopeEntries.map(
117
+ ([scopeFieldName, scopeFieldValue]) => getUserScopeFieldQuery(
118
+ scopeFieldName,
119
+ scopeFieldValue,
120
+ scopeMatchType,
121
+ scopeObj
122
+ )
123
+ ).filter(Boolean).join(scopeJoinType);
124
+ };
125
+ const getUserScopeFieldQuery = (fieldName, fieldValue, matchType, fullScope) => {
126
+ if ("function" === typeof greedyFieldComparisons[fieldName]) {
127
+ return greedyFieldComparisons[fieldName](fieldValue, fullScope);
128
+ }
129
+ if (fieldValue === void 0) {
130
+ return `ismissing(@${fieldName})`;
131
+ }
132
+ return numericIndexFields.includes(fieldName) ? `@${fieldName}:[${fieldValue}]` : `@${fieldName}:{${fieldValue}}`;
133
+ };
134
+ exports.getRedisRulesQuery = getRedisRulesQuery;
135
+ exports.redisAccessRulesIndex = redisAccessRulesIndex;
136
+ exports.redisRuleKeyPrefix = redisRuleKeyPrefix;
137
+ exports.redisRulesIndexName = redisRulesIndexName;
138
+ exports.redisRulesSearchOptions = redisRulesSearchOptions;