@prosopo/user-access-policy 3.5.19 → 3.5.28

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.
Files changed (93) hide show
  1. package/CHANGELOG.md +84 -0
  2. package/dist/.export.js +21 -0
  3. package/dist/api/.export.js +11 -0
  4. package/dist/api/delete/.export.js +1 -0
  5. package/dist/api/{deleteAllRulesEndpoint.js → delete/deleteAllRules.js} +10 -9
  6. package/dist/api/delete/deleteRuleGroups.js +52 -0
  7. package/dist/api/delete/deleteRules.js +43 -0
  8. package/dist/api/read/.export.js +1 -0
  9. package/dist/api/read/fetchRules.js +43 -0
  10. package/dist/api/read/findRuleIds.js +50 -0
  11. package/dist/api/read/getMissingIds.js +41 -0
  12. package/dist/api/ruleApiRoutes.js +131 -0
  13. package/dist/api/rulesApiClient.js +93 -0
  14. package/dist/api/write/.export.js +1 -0
  15. package/dist/api/write/insertRules.js +102 -0
  16. package/dist/api/write/rehashRules.js +57 -0
  17. package/dist/cjs/.export.cjs +21 -0
  18. package/dist/cjs/api/.export.cjs +11 -0
  19. package/dist/cjs/api/delete/.export.cjs +1 -0
  20. package/dist/cjs/api/{deleteAllRulesEndpoint.cjs → delete/deleteAllRules.cjs} +9 -8
  21. package/dist/cjs/api/delete/deleteRuleGroups.cjs +52 -0
  22. package/dist/cjs/api/delete/deleteRules.cjs +43 -0
  23. package/dist/cjs/api/read/.export.cjs +1 -0
  24. package/dist/cjs/api/read/fetchRules.cjs +43 -0
  25. package/dist/cjs/api/read/findRuleIds.cjs +50 -0
  26. package/dist/cjs/api/read/getMissingIds.cjs +41 -0
  27. package/dist/cjs/api/ruleApiRoutes.cjs +131 -0
  28. package/dist/cjs/api/rulesApiClient.cjs +93 -0
  29. package/dist/cjs/api/write/.export.cjs +1 -0
  30. package/dist/cjs/api/write/insertRules.cjs +102 -0
  31. package/dist/cjs/api/write/rehashRules.cjs +57 -0
  32. package/dist/cjs/mongoose/.export.cjs +4 -0
  33. package/dist/cjs/mongoose/mongooseRuleSchema.cjs +36 -0
  34. package/dist/cjs/redis/.export.cjs +6 -0
  35. package/dist/cjs/redis/reader/redisAggregate.cjs +60 -0
  36. package/dist/cjs/redis/reader/redisRulesQuery.cjs +99 -0
  37. package/dist/cjs/redis/reader/redisRulesReader.cjs +230 -0
  38. package/dist/cjs/redis/redisClient.cjs +67 -0
  39. package/dist/cjs/redis/redisRuleIndex.cjs +50 -0
  40. package/dist/cjs/redis/redisRulesStorage.cjs +22 -9
  41. package/dist/cjs/redis/redisRulesWriter.cjs +91 -64
  42. package/dist/cjs/rule.cjs +8 -0
  43. package/dist/cjs/ruleInput/.export.cjs +9 -0
  44. package/dist/cjs/ruleInput/policyInput.cjs +25 -0
  45. package/dist/cjs/ruleInput/ruleInput.cjs +50 -0
  46. package/dist/cjs/ruleInput/userScopeInput.cjs +55 -0
  47. package/dist/cjs/ruleRecord.cjs +23 -0
  48. package/dist/cjs/rulesStorage.cjs +8 -0
  49. package/dist/cjs/transformRule.cjs +77 -0
  50. package/dist/mongoose/.export.js +4 -0
  51. package/dist/mongoose/mongooseRuleSchema.js +36 -0
  52. package/dist/redis/.export.js +6 -0
  53. package/dist/redis/reader/redisAggregate.js +60 -0
  54. package/dist/redis/reader/redisRulesQuery.js +99 -0
  55. package/dist/redis/reader/redisRulesReader.js +213 -0
  56. package/dist/redis/redisClient.js +67 -0
  57. package/dist/redis/redisRuleIndex.js +50 -0
  58. package/dist/redis/redisRulesStorage.js +23 -10
  59. package/dist/redis/redisRulesWriter.js +91 -64
  60. package/dist/rule.js +8 -0
  61. package/dist/ruleInput/.export.js +9 -0
  62. package/dist/ruleInput/policyInput.js +25 -0
  63. package/dist/ruleInput/ruleInput.js +50 -0
  64. package/dist/ruleInput/userScopeInput.js +55 -0
  65. package/dist/ruleRecord.js +23 -0
  66. package/dist/rulesStorage.js +8 -0
  67. package/dist/transformRule.js +77 -0
  68. package/entries.ts +20 -0
  69. package/package.json +34 -18
  70. package/vite.cjs.config.ts +4 -1
  71. package/vite.esm.config.ts +6 -1
  72. package/dist/accessPolicy.js +0 -80
  73. package/dist/accessPolicyResolver.js +0 -31
  74. package/dist/accessRules.js +0 -11
  75. package/dist/api/accessRuleApiRoutes.js +0 -79
  76. package/dist/api/accessRulesApiClient.js +0 -38
  77. package/dist/api/deleteRulesEndpoint.js +0 -34
  78. package/dist/api/insertRulesEndpoint.js +0 -62
  79. package/dist/cjs/accessPolicy.cjs +0 -80
  80. package/dist/cjs/accessPolicyResolver.cjs +0 -31
  81. package/dist/cjs/accessRules.cjs +0 -11
  82. package/dist/cjs/api/accessRuleApiRoutes.cjs +0 -79
  83. package/dist/cjs/api/accessRulesApiClient.cjs +0 -38
  84. package/dist/cjs/api/deleteRulesEndpoint.cjs +0 -34
  85. package/dist/cjs/api/insertRulesEndpoint.cjs +0 -62
  86. package/dist/cjs/index.cjs +0 -31
  87. package/dist/cjs/redis/redisRulesIndex.cjs +0 -138
  88. package/dist/cjs/redis/redisRulesReader.cjs +0 -142
  89. package/dist/cjs/util.cjs +0 -5
  90. package/dist/index.js +0 -32
  91. package/dist/redis/redisRulesIndex.js +0 -138
  92. package/dist/redis/redisRulesReader.js +0 -125
  93. package/dist/util.js +0 -5
@@ -1,62 +0,0 @@
1
- import { ApiEndpointResponseStatus } from "@prosopo/api-route";
2
- import { getLogger, LogLevel } from "@prosopo/common";
3
- import { z } from "zod";
4
- import { userScopeInputSchema, policyScopeSchema, accessPolicySchema } from "../accessPolicy.js";
5
- const insertRulesEndpointSchema = z.object({
6
- accessPolicy: accessPolicySchema,
7
- policyScope: policyScopeSchema.optional(),
8
- userScopes: z.array(userScopeInputSchema),
9
- expirationTimestamp: z.number().optional().transform((val) => val !== void 0 ? Math.floor(val) : val)
10
- });
11
- class InsertRulesEndpoint {
12
- constructor(accessRulesWriter) {
13
- this.accessRulesWriter = accessRulesWriter;
14
- }
15
- async processRequest(args, logger) {
16
- logger = logger || getLogger(LogLevel.enum.info, "InsertRulesEndpoint");
17
- const timeoutPromise = new Promise((resolve) => {
18
- setTimeout(() => {
19
- resolve({
20
- status: ApiEndpointResponseStatus.PROCESSING
21
- });
22
- }, 5e3);
23
- });
24
- const createRulesPromise = this.createRules(args).then(() => ({
25
- status: ApiEndpointResponseStatus.SUCCESS
26
- })).catch((error) => {
27
- if (logger?.getLogLevel() === LogLevel.enum.debug) {
28
- logger.error(() => ({
29
- err: error,
30
- data: { args },
31
- msg: "Failed to insert access rules"
32
- }));
33
- }
34
- return {
35
- status: ApiEndpointResponseStatus.FAIL
36
- };
37
- });
38
- return Promise.race([timeoutPromise, createRulesPromise]);
39
- }
40
- getRequestArgsSchema() {
41
- return insertRulesEndpointSchema;
42
- }
43
- async createRules(args) {
44
- const policyScope = args.policyScope || {};
45
- const createPromises = [];
46
- for (const userScope of args.userScopes) {
47
- const rule = {
48
- ...args.accessPolicy,
49
- ...policyScope,
50
- ...userScope
51
- };
52
- createPromises.push(
53
- this.accessRulesWriter.insertRule(rule, args.expirationTimestamp)
54
- );
55
- }
56
- return Promise.all(createPromises);
57
- }
58
- }
59
- export {
60
- InsertRulesEndpoint,
61
- insertRulesEndpointSchema
62
- };
@@ -1,80 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const types = require("@prosopo/types");
4
- const util = require("@prosopo/util");
5
- const ipAddress = require("ip-address");
6
- const zod = require("zod");
7
- const util$1 = require("./util.cjs");
8
- var AccessPolicyType = /* @__PURE__ */ ((AccessPolicyType2) => {
9
- AccessPolicyType2["Block"] = "block";
10
- AccessPolicyType2["Restrict"] = "restrict";
11
- return AccessPolicyType2;
12
- })(AccessPolicyType || {});
13
- const accessPolicySchema = zod.z.object({
14
- type: zod.z.nativeEnum(AccessPolicyType),
15
- captchaType: types.CaptchaTypeSchema.optional(),
16
- description: zod.z.coerce.string().optional(),
17
- // Redis stores values as strings, so coerce is needed to parse properly
18
- solvedImagesCount: zod.z.coerce.number().optional(),
19
- // the percentage of image panels that must be solved per image CAPTCHA
20
- imageThreshold: zod.z.coerce.number().optional(),
21
- // the Proof-of-Work difficulty level
22
- powDifficulty: zod.z.coerce.number().optional(),
23
- // the number of unsolved image CAPTCHA challenges to serve
24
- unsolvedImagesCount: zod.z.coerce.number().optional(),
25
- // used to increase the user's score
26
- frictionlessScore: zod.z.coerce.number().optional()
27
- });
28
- const policyScopeSchema = zod.z.object({
29
- clientId: zod.z.coerce.string().optional(),
30
- ruleGroupId: zod.z.coerce.string().optional()
31
- });
32
- const userScopeSchema = zod.z.object({
33
- // coerce is used for safety, as e.g., incoming userId can be digital
34
- userId: zod.z.coerce.string().optional(),
35
- numericIp: zod.z.coerce.bigint().optional(),
36
- numericIpMaskMin: zod.z.coerce.bigint().optional(),
37
- numericIpMaskMax: zod.z.coerce.bigint().optional(),
38
- ja4Hash: zod.z.coerce.string().optional(),
39
- headersHash: zod.z.coerce.string().optional(),
40
- userAgentHash: zod.z.coerce.string().optional()
41
- });
42
- const userScopeInputSchema = userScopeSchema.extend({
43
- // human-friendly ip versions. If present, then converted to numeric and removed from the object
44
- // 127.0.0.1
45
- ip: zod.z.string().optional(),
46
- // 127.0.0.1/24
47
- ipMask: zod.z.string().optional(),
48
- // human friendly user agent
49
- userAgent: zod.z.string().optional()
50
- }).transform((inputUserScope) => {
51
- const { ip, ipMask, userAgent, ...userScope } = inputUserScope;
52
- if ("string" === typeof ip) {
53
- userScope.numericIp = util.getIPAddress(ip).bigInt();
54
- }
55
- if ("string" === typeof ipMask) {
56
- const ipObject = new ipAddress.Address4(ipMask);
57
- userScope.numericIpMaskMin = ipObject.startAddress().bigInt();
58
- userScope.numericIpMaskMax = ipObject.endAddress().bigInt();
59
- }
60
- if ("string" === typeof userAgent) {
61
- userScope.userAgentHash = util$1.hashUserAgent(userAgent);
62
- }
63
- return userScope;
64
- });
65
- const accessRuleSchemaExtended = zod.z.object({
66
- // flat structure is used to fit the Redis requirements
67
- ...accessPolicySchema.shape,
68
- ...policyScopeSchema.shape,
69
- ...userScopeInputSchema._def.schema.shape
70
- }).omit({
71
- numericIp: true,
72
- numericIpMaskMin: true,
73
- numericIpMaskMax: true
74
- });
75
- exports.AccessPolicyType = AccessPolicyType;
76
- exports.accessPolicySchema = accessPolicySchema;
77
- exports.accessRuleSchemaExtended = accessRuleSchemaExtended;
78
- exports.policyScopeSchema = policyScopeSchema;
79
- exports.userScopeInputSchema = userScopeInputSchema;
80
- exports.userScopeSchema = userScopeSchema;
@@ -1,31 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const zod = require("zod");
4
- const accessPolicy = require("./accessPolicy.cjs");
5
- var ScopeMatch = /* @__PURE__ */ ((ScopeMatch2) => {
6
- ScopeMatch2["Exact"] = "exact";
7
- ScopeMatch2["Greedy"] = "greedy";
8
- return ScopeMatch2;
9
- })(ScopeMatch || {});
10
- const policyFilterSchema = zod.z.object({
11
- policyScope: accessPolicy.policyScopeSchema.optional(),
12
- /**
13
- * Exact: "clientId" => client rules, "undefined" => global rules. Used by the API
14
- * Greedy: "clientId" => client + global rules, "undefined" => any rules. Used by the Express middleware
15
- */
16
- policyScopeMatch: zod.z.nativeEnum(ScopeMatch).default(
17
- "exact"
18
- /* Exact */
19
- ),
20
- userScope: accessPolicy.userScopeInputSchema.optional(),
21
- /**
22
- * Exact: finds rules where all the given fields matches and doesn't check IP against masks. Used by the API
23
- * Greedy: finds rules where any of the given fields match and checks IP against masks. Used by the Express middleware
24
- */
25
- userScopeMatch: zod.z.nativeEnum(ScopeMatch).default(
26
- "exact"
27
- /* Exact */
28
- )
29
- });
30
- exports.ScopeMatch = ScopeMatch;
31
- exports.policyFilterSchema = policyFilterSchema;
@@ -1,11 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const zod = require("zod");
4
- const accessPolicy = require("./accessPolicy.cjs");
5
- const accessRuleSchema = zod.z.object({
6
- // flat structure is used to fit the Redis requirements
7
- ...accessPolicy.accessPolicySchema.shape,
8
- ...accessPolicy.policyScopeSchema.shape,
9
- ...accessPolicy.userScopeSchema.shape
10
- });
11
- exports.accessRuleSchema = accessRuleSchema;
@@ -1,79 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const deleteAllRulesEndpoint = require("./deleteAllRulesEndpoint.cjs");
4
- const deleteRulesEndpoint = require("./deleteRulesEndpoint.cjs");
5
- const insertRulesEndpoint = require("./insertRulesEndpoint.cjs");
6
- var accessRuleApiPaths = /* @__PURE__ */ ((accessRuleApiPaths2) => {
7
- accessRuleApiPaths2["INSERT_MANY"] = "/v1/prosopo/user-access-policy/rules/insert-many";
8
- accessRuleApiPaths2["DELETE_MANY"] = "/v1/prosopo/user-access-policy/rules/delete-many";
9
- accessRuleApiPaths2["DELETE_ALL"] = "/v1/prosopo/user-access-policy/rules/delete-all";
10
- return accessRuleApiPaths2;
11
- })(accessRuleApiPaths || {});
12
- class AccessRuleApiRoutes {
13
- constructor(accessRulesStorage) {
14
- this.accessRulesStorage = accessRulesStorage;
15
- }
16
- getRoutes() {
17
- return [
18
- {
19
- path: "/v1/prosopo/user-access-policy/rules/insert-many",
20
- endpoint: new insertRulesEndpoint.InsertRulesEndpoint(this.accessRulesStorage)
21
- },
22
- {
23
- path: "/v1/prosopo/user-access-policy/rules/delete-many",
24
- endpoint: new deleteRulesEndpoint.DeleteRulesEndpoint(this.accessRulesStorage)
25
- },
26
- {
27
- path: "/v1/prosopo/user-access-policy/rules/delete-all",
28
- endpoint: new deleteAllRulesEndpoint.DeleteAllRulesEndpoint(this.accessRulesStorage)
29
- }
30
- ];
31
- }
32
- }
33
- const getExpressApiRuleRateLimits = () => {
34
- const defaultWindowsMs = 6e4;
35
- const defaultLimit = 5;
36
- return {
37
- [
38
- "/v1/prosopo/user-access-policy/rules/insert-many"
39
- /* INSERT_MANY */
40
- ]: {
41
- windowMs: getIntEnvironmentVariable(
42
- "PROSOPO_USER_ACCESS_POLICY_RULE_INSERT_MANY_WINDOW"
43
- ) || defaultWindowsMs,
44
- limit: getIntEnvironmentVariable(
45
- "PROSOPO_USER_ACCESS_POLICY_RULE_INSERT_MANY_LIMIT"
46
- ) || defaultLimit
47
- },
48
- [
49
- "/v1/prosopo/user-access-policy/rules/delete-many"
50
- /* DELETE_MANY */
51
- ]: {
52
- windowMs: getIntEnvironmentVariable(
53
- "PROSOPO_USER_ACCESS_POLICY_RULE_DELETE_MANY_WINDOW"
54
- ) || defaultWindowsMs,
55
- limit: getIntEnvironmentVariable(
56
- "PROSOPO_USER_ACCESS_POLICY_RULE_DELETE_MANY_LIMIT"
57
- ) || defaultLimit
58
- },
59
- [
60
- "/v1/prosopo/user-access-policy/rules/delete-all"
61
- /* DELETE_ALL */
62
- ]: {
63
- windowMs: getIntEnvironmentVariable(
64
- "PROSOPO_USER_ACCESS_POLICY_RULE_DELETE_ALL_WINDOW"
65
- ) || defaultWindowsMs,
66
- limit: getIntEnvironmentVariable(
67
- "PROSOPO_USER_ACCESS_POLICY_RULE_DELETE_ALL_LIMIT"
68
- ) || defaultLimit
69
- }
70
- };
71
- };
72
- const getIntEnvironmentVariable = (variableName) => {
73
- const variableValue = process.env[variableName];
74
- const numericValue = variableValue ? Number.parseInt(variableValue) : Number.NaN;
75
- return Number.isInteger(numericValue) ? numericValue : void 0;
76
- };
77
- exports.AccessRuleApiRoutes = AccessRuleApiRoutes;
78
- exports.accessRuleApiPaths = accessRuleApiPaths;
79
- exports.getExpressApiRuleRateLimits = getExpressApiRuleRateLimits;
@@ -1,38 +0,0 @@
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;
@@ -1,34 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const apiRoute = require("@prosopo/api-route");
4
- const zod = require("zod");
5
- const accessPolicyResolver = require("../accessPolicyResolver.cjs");
6
- const deleteRulesEndpointSchema = zod.z.array(accessPolicyResolver.policyFilterSchema);
7
- class DeleteRulesEndpoint {
8
- constructor(accessRulesStorage) {
9
- this.accessRulesStorage = accessRulesStorage;
10
- }
11
- async processRequest(args) {
12
- const allRuleIds = [];
13
- for (const accessRuleFilter of args) {
14
- const parsedRules = accessPolicyResolver.policyFilterSchema.parse(accessRuleFilter);
15
- const foundRuleIds = await this.accessRulesStorage.findRuleIds(parsedRules);
16
- allRuleIds.push(...foundRuleIds);
17
- }
18
- const uniqueRuleIds = [...new Set(allRuleIds)];
19
- if (uniqueRuleIds.length > 0) {
20
- await this.accessRulesStorage.deleteRules(uniqueRuleIds);
21
- }
22
- return {
23
- status: apiRoute.ApiEndpointResponseStatus.SUCCESS,
24
- data: {
25
- deleted_count: uniqueRuleIds.length
26
- }
27
- };
28
- }
29
- getRequestArgsSchema() {
30
- return deleteRulesEndpointSchema;
31
- }
32
- }
33
- exports.DeleteRulesEndpoint = DeleteRulesEndpoint;
34
- exports.deleteRulesEndpointSchema = deleteRulesEndpointSchema;
@@ -1,62 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const apiRoute = require("@prosopo/api-route");
4
- const common = require("@prosopo/common");
5
- const zod = require("zod");
6
- const accessPolicy = require("../accessPolicy.cjs");
7
- const insertRulesEndpointSchema = zod.z.object({
8
- accessPolicy: accessPolicy.accessPolicySchema,
9
- policyScope: accessPolicy.policyScopeSchema.optional(),
10
- userScopes: zod.z.array(accessPolicy.userScopeInputSchema),
11
- expirationTimestamp: zod.z.number().optional().transform((val) => val !== void 0 ? Math.floor(val) : val)
12
- });
13
- class InsertRulesEndpoint {
14
- constructor(accessRulesWriter) {
15
- this.accessRulesWriter = accessRulesWriter;
16
- }
17
- async processRequest(args, logger) {
18
- logger = logger || common.getLogger(common.LogLevel.enum.info, "InsertRulesEndpoint");
19
- const timeoutPromise = new Promise((resolve) => {
20
- setTimeout(() => {
21
- resolve({
22
- status: apiRoute.ApiEndpointResponseStatus.PROCESSING
23
- });
24
- }, 5e3);
25
- });
26
- const createRulesPromise = this.createRules(args).then(() => ({
27
- status: apiRoute.ApiEndpointResponseStatus.SUCCESS
28
- })).catch((error) => {
29
- if (logger?.getLogLevel() === common.LogLevel.enum.debug) {
30
- logger.error(() => ({
31
- err: error,
32
- data: { args },
33
- msg: "Failed to insert access rules"
34
- }));
35
- }
36
- return {
37
- status: apiRoute.ApiEndpointResponseStatus.FAIL
38
- };
39
- });
40
- return Promise.race([timeoutPromise, createRulesPromise]);
41
- }
42
- getRequestArgsSchema() {
43
- return insertRulesEndpointSchema;
44
- }
45
- async createRules(args) {
46
- const policyScope = args.policyScope || {};
47
- const createPromises = [];
48
- for (const userScope of args.userScopes) {
49
- const rule = {
50
- ...args.accessPolicy,
51
- ...policyScope,
52
- ...userScope
53
- };
54
- createPromises.push(
55
- this.accessRulesWriter.insertRule(rule, args.expirationTimestamp)
56
- );
57
- }
58
- return Promise.all(createPromises);
59
- }
60
- }
61
- exports.InsertRulesEndpoint = InsertRulesEndpoint;
62
- exports.insertRulesEndpointSchema = insertRulesEndpointSchema;
@@ -1,31 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const accessPolicy = require("./accessPolicy.cjs");
4
- const accessPolicyResolver = require("./accessPolicyResolver.cjs");
5
- const accessRules = require("./accessRules.cjs");
6
- const accessRuleApiRoutes = require("./api/accessRuleApiRoutes.cjs");
7
- const deleteAllRulesEndpoint = require("./api/deleteAllRulesEndpoint.cjs");
8
- const deleteRulesEndpoint = require("./api/deleteRulesEndpoint.cjs");
9
- const insertRulesEndpoint = require("./api/insertRulesEndpoint.cjs");
10
- const redisRulesStorage = require("./redis/redisRulesStorage.cjs");
11
- const redisRulesIndex = require("./redis/redisRulesIndex.cjs");
12
- const accessRulesApiClient = require("./api/accessRulesApiClient.cjs");
13
- const createApiRuleRoutesProvider = (rulesStorage) => {
14
- return new accessRuleApiRoutes.AccessRuleApiRoutes(rulesStorage);
15
- };
16
- exports.AccessPolicyType = accessPolicy.AccessPolicyType;
17
- exports.accessPolicySchema = accessPolicy.accessPolicySchema;
18
- exports.accessRuleSchemaExtended = accessPolicy.accessRuleSchemaExtended;
19
- exports.policyScopeSchema = accessPolicy.policyScopeSchema;
20
- exports.userScopeInputSchema = accessPolicy.userScopeInputSchema;
21
- exports.ScopeMatch = accessPolicyResolver.ScopeMatch;
22
- exports.accessRuleSchema = accessRules.accessRuleSchema;
23
- exports.accessRuleApiPaths = accessRuleApiRoutes.accessRuleApiPaths;
24
- exports.getExpressApiRuleRateLimits = accessRuleApiRoutes.getExpressApiRuleRateLimits;
25
- exports.deleteAllRulesEndpointSchema = deleteAllRulesEndpoint.deleteAllRulesEndpointSchema;
26
- exports.deleteRulesEndpointSchema = deleteRulesEndpoint.deleteRulesEndpointSchema;
27
- exports.insertRulesEndpointSchema = insertRulesEndpoint.insertRulesEndpointSchema;
28
- exports.createRedisAccessRulesStorage = redisRulesStorage.createRedisAccessRulesStorage;
29
- exports.redisAccessRulesIndex = redisRulesIndex.redisAccessRulesIndex;
30
- exports.AccessRulesApiClient = accessRulesApiClient.AccessRulesApiClient;
31
- exports.createApiRuleRoutesProvider = createApiRuleRoutesProvider;
@@ -1,138 +0,0 @@
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;