@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 +266 -0
- package/dist/accessPolicyResolver.js +1 -40
- package/dist/api/accessRulesApiClient.js +38 -0
- package/dist/cjs/accessPolicyResolver.cjs +0 -56
- package/dist/cjs/api/accessRulesApiClient.cjs +38 -0
- package/dist/cjs/index.cjs +9 -5
- package/dist/cjs/redis/redisRulesIndex.cjs +138 -0
- package/dist/cjs/redis/{redisAccessRules.cjs → redisRulesReader.cjs} +30 -40
- package/dist/cjs/redis/redisRulesStorage.cjs +21 -0
- package/dist/cjs/redis/redisRulesWriter.cjs +73 -0
- package/dist/index.js +10 -6
- package/dist/redis/redisRulesIndex.js +138 -0
- package/dist/redis/{redisAccessRules.js → redisRulesReader.js} +30 -40
- package/dist/redis/redisRulesStorage.js +21 -0
- package/dist/redis/redisRulesWriter.js +73 -0
- package/package.json +19 -14
- package/dist/cjs/redis/redisAccessRulesIndex.cjs +0 -113
- package/dist/cjs/redis/redisIndex.cjs +0 -22
- package/dist/redis/redisAccessRulesIndex.js +0 -113
- package/dist/redis/redisIndex.js +0 -22
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
|
|
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;
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -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
|
|
10
|
-
const
|
|
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.
|
|
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 =
|
|
26
|
-
exports.
|
|
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;
|