@frontmcp/auth 1.10.16 → 1.11.0-rc.1

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 (175) hide show
  1. package/browser/authorities/authorities.context.mjs +115 -0
  2. package/browser/authorities/authorities.engine.mjs +272 -0
  3. package/browser/authorities/authorities.errors.mjs +59 -0
  4. package/browser/authorities/authorities.evaluator.mjs +225 -0
  5. package/browser/authorities/authorities.metadata-augment.mjs +18 -0
  6. package/browser/authorities/authorities.registry.mjs +112 -0
  7. package/browser/authorities/authorities.schema.mjs +92 -0
  8. package/browser/authorities/authorities.scope-mapping.mjs +30 -0
  9. package/browser/authorities/authorities.validation.mjs +208 -0
  10. package/browser/authorities/index.mjs +43 -0
  11. package/browser/authorization/authorization.class.mjs +252 -0
  12. package/browser/authorization/authorization.types.mjs +64 -0
  13. package/browser/authorization/dcr-client.registry.mjs +222 -0
  14. package/browser/authorization/index.mjs +41 -0
  15. package/browser/authorization/orchestrated.accessor.mjs +86 -0
  16. package/browser/authorization/orchestrated.authorization.mjs +289 -0
  17. package/browser/authorization/public.authorization.mjs +124 -0
  18. package/browser/authorization/transparent.authorization.mjs +130 -0
  19. package/browser/cimd/cimd-redis.cache.mjs +231 -0
  20. package/browser/cimd/cimd.cache.mjs +215 -0
  21. package/browser/cimd/cimd.errors.mjs +142 -0
  22. package/browser/cimd/cimd.logger.mjs +15 -0
  23. package/browser/cimd/cimd.service.mjs +376 -0
  24. package/browser/cimd/cimd.types.mjs +228 -0
  25. package/browser/cimd/cimd.validator.mjs +217 -0
  26. package/browser/cimd/index.mjs +63 -0
  27. package/browser/common/auth-logger.interface.mjs +14 -0
  28. package/browser/common/index.mjs +6 -0
  29. package/browser/common/jwt.types.mjs +38 -0
  30. package/browser/common/session-user.types.mjs +0 -0
  31. package/browser/common/session.types.mjs +58 -0
  32. package/browser/common/zod-utils.mjs +0 -0
  33. package/browser/consent/consent.types.mjs +94 -0
  34. package/browser/consent/index.mjs +17 -0
  35. package/browser/context/frontmcp-auth-context.factory.mjs +29 -0
  36. package/browser/context/frontmcp-auth-context.impl.mjs +112 -0
  37. package/browser/context/index.mjs +7 -0
  38. package/browser/detection/auth-provider-detection.mjs +176 -0
  39. package/browser/detection/index.mjs +19 -0
  40. package/browser/errors/auth-internal.error.mjs +42 -0
  41. package/browser/errors/auth-internal.errors.mjs +150 -0
  42. package/browser/errors/index.mjs +53 -0
  43. package/browser/fetch/fetch-credential-middleware.mjs +91 -0
  44. package/browser/fetch/index.mjs +19 -0
  45. package/browser/index.mjs +573 -0
  46. package/browser/jwks/index.mjs +9 -0
  47. package/browser/jwks/jose.loader.mjs +28 -0
  48. package/browser/jwks/jwks.service.mjs +521 -0
  49. package/browser/jwks/jwks.utils.mjs +33 -0
  50. package/browser/options/app-auth.schema.mjs +18 -0
  51. package/browser/options/index.mjs +89 -0
  52. package/browser/options/orchestrated.schema.mjs +128 -0
  53. package/browser/options/public.schema.mjs +39 -0
  54. package/browser/options/schema.mjs +16 -0
  55. package/browser/options/shared.schemas.mjs +506 -0
  56. package/browser/options/static.schema.mjs +41 -0
  57. package/browser/options/transparent.schema.mjs +43 -0
  58. package/browser/options/utils.mjs +47 -0
  59. package/browser/people/index.mjs +15 -0
  60. package/browser/people/loopback-token.auth.mjs +115 -0
  61. package/browser/people/people-auth.options.mjs +37 -0
  62. package/browser/session/authorization-vault.mjs +279 -0
  63. package/browser/session/authorization.store.mjs +336 -0
  64. package/browser/session/consent.store.mjs +34 -0
  65. package/browser/session/credential-resume-link.mjs +43 -0
  66. package/browser/session/credentials-accessor.impl.mjs +54 -0
  67. package/browser/session/credentials-accessor.mjs +5 -0
  68. package/browser/session/encrypted-authorization-vault.mjs +405 -0
  69. package/browser/session/federated-auth.session.mjs +176 -0
  70. package/browser/session/incremental-auth-ticket.mjs +42 -0
  71. package/browser/session/index.mjs +266 -0
  72. package/browser/session/orchestrated-token.crypto.mjs +47 -0
  73. package/browser/session/orchestrated-token.store.mjs +286 -0
  74. package/browser/session/pending-login.mjs +37 -0
  75. package/browser/session/redis-session.store.mjs +255 -0
  76. package/browser/session/secure-store-accessor.impl.mjs +78 -0
  77. package/browser/session/secure-store-accessor.mjs +5 -0
  78. package/browser/session/secure-store-backends.mjs +111 -0
  79. package/browser/session/secure-store.factory.mjs +77 -0
  80. package/browser/session/session-credential-vault.factory.mjs +18 -0
  81. package/browser/session/session-credential-vault.mjs +243 -0
  82. package/browser/session/session-crypto.mjs +39 -0
  83. package/browser/session/session-rate-limiter.mjs +126 -0
  84. package/browser/session/session.transport.mjs +16 -0
  85. package/browser/session/signin-binding.mjs +30 -0
  86. package/browser/session/storage/in-memory-authorization-vault.mjs +28 -0
  87. package/browser/session/storage/index.mjs +14 -0
  88. package/browser/session/storage/storage-authorization-vault.mjs +301 -0
  89. package/browser/session/storage/storage-token-store.mjs +83 -0
  90. package/browser/session/storage-authorization.store.mjs +134 -0
  91. package/browser/session/storage-consent.store.mjs +33 -0
  92. package/browser/session/storage-federated-auth.session.mjs +55 -0
  93. package/browser/session/storage-orchestrated-token.store.mjs +197 -0
  94. package/browser/session/token-storage.factory.mjs +58 -0
  95. package/browser/session/token.refresh.mjs +36 -0
  96. package/browser/session/token.vault.mjs +61 -0
  97. package/browser/session/transport-session.types.mjs +108 -0
  98. package/browser/session/utils/auth-token.utils.mjs +58 -0
  99. package/browser/session/utils/index.mjs +23 -0
  100. package/browser/session/utils/session-crypto.utils.mjs +49 -0
  101. package/browser/session/utils/tiny-ttl-cache.mjs +46 -0
  102. package/browser/session/vault-encryption.mjs +187 -0
  103. package/browser/session/vercel-kv-session.store.mjs +230 -0
  104. package/browser/shared-server/index.mjs +17 -0
  105. package/browser/shared-server/shared-server-identity.mjs +55 -0
  106. package/browser/ui/base-layout.mjs +184 -0
  107. package/browser/ui/index.mjs +51 -0
  108. package/browser/ui/local-login.helper.mjs +46 -0
  109. package/browser/ui/templates.mjs +482 -0
  110. package/browser/utils/audience.validator.mjs +110 -0
  111. package/browser/utils/authorization-id.utils.mjs +10 -0
  112. package/browser/utils/index.mjs +45 -0
  113. package/browser/utils/redirect-uri.utils.mjs +22 -0
  114. package/browser/utils/scope-grant.utils.mjs +36 -0
  115. package/browser/utils/token-scopes.utils.mjs +12 -0
  116. package/browser/utils/www-authenticate.utils.mjs +164 -0
  117. package/browser/vault/auth-providers.accessor.impl.mjs +236 -0
  118. package/browser/vault/auth-providers.accessor.mjs +5 -0
  119. package/browser/vault/auth-providers.registry.mjs +140 -0
  120. package/browser/vault/auth-providers.types.mjs +47 -0
  121. package/browser/vault/auth-providers.vault.mjs +206 -0
  122. package/browser/vault/credential-cache.mjs +187 -0
  123. package/browser/vault/credential-helpers.mjs +15 -0
  124. package/browser/vault/credential-loaders/eager-loader.mjs +91 -0
  125. package/browser/vault/credential-loaders/lazy-loader.mjs +120 -0
  126. package/browser/vault/index.mjs +35 -0
  127. package/cimd/cimd.types.d.ts +1 -1
  128. package/cimd/cimd.types.d.ts.map +1 -1
  129. package/common/jwt.types.d.ts +1 -1
  130. package/common/jwt.types.d.ts.map +1 -1
  131. package/common/session.types.d.ts +9 -1
  132. package/common/session.types.d.ts.map +1 -1
  133. package/consent/consent.types.d.ts +1 -1
  134. package/consent/consent.types.d.ts.map +1 -1
  135. package/detection/auth-provider-detection.d.ts +1 -1
  136. package/detection/auth-provider-detection.d.ts.map +1 -1
  137. package/errors/auth-internal.errors.d.ts +6 -0
  138. package/errors/auth-internal.errors.d.ts.map +1 -1
  139. package/errors/index.d.ts +1 -1
  140. package/errors/index.d.ts.map +1 -1
  141. package/esm/index.mjs +2 -2
  142. package/esm/package.json +21 -5
  143. package/index.d.ts +5 -1
  144. package/index.d.ts.map +1 -1
  145. package/index.js +2 -2
  146. package/options/app-auth.schema.d.ts +19 -1
  147. package/options/app-auth.schema.d.ts.map +1 -1
  148. package/options/orchestrated.schema.d.ts +37 -1
  149. package/options/orchestrated.schema.d.ts.map +1 -1
  150. package/options/public.schema.d.ts +1 -1
  151. package/options/public.schema.d.ts.map +1 -1
  152. package/options/schema.d.ts +19 -1
  153. package/options/schema.d.ts.map +1 -1
  154. package/options/shared.schemas.d.ts +10 -14
  155. package/options/shared.schemas.d.ts.map +1 -1
  156. package/options/static.schema.d.ts +1 -1
  157. package/options/static.schema.d.ts.map +1 -1
  158. package/options/transparent.schema.d.ts +1 -1
  159. package/options/transparent.schema.d.ts.map +1 -1
  160. package/package.json +21 -5
  161. package/people/index.d.ts +3 -0
  162. package/people/index.d.ts.map +1 -0
  163. package/people/loopback-token.auth.d.ts +75 -0
  164. package/people/loopback-token.auth.d.ts.map +1 -0
  165. package/people/people-auth.options.d.ts +36 -0
  166. package/people/people-auth.options.d.ts.map +1 -0
  167. package/session/authorization-vault.d.ts +1 -1
  168. package/session/authorization-vault.d.ts.map +1 -1
  169. package/session/encrypted-authorization-vault.d.ts +1 -1
  170. package/session/encrypted-authorization-vault.d.ts.map +1 -1
  171. package/session/secure-store.factory.d.ts.map +1 -1
  172. package/shared-server/index.d.ts +3 -0
  173. package/shared-server/index.d.ts.map +1 -0
  174. package/shared-server/shared-server-identity.d.ts +26 -0
  175. package/shared-server/shared-server-identity.d.ts.map +1 -0
@@ -0,0 +1,112 @@
1
+ // libs/auth/src/authorities/authorities.registry.ts
2
+ var AuthoritiesProfileRegistry = class {
3
+ profiles = /* @__PURE__ */ new Map();
4
+ /**
5
+ * Register a named profile.
6
+ * Overwrites any existing profile with the same name.
7
+ */
8
+ register(name, policy) {
9
+ this.profiles.set(name, policy);
10
+ }
11
+ /**
12
+ * Register multiple profiles at once.
13
+ */
14
+ registerAll(profiles) {
15
+ for (const [name, policy] of Object.entries(profiles)) {
16
+ this.profiles.set(name, policy);
17
+ }
18
+ }
19
+ /**
20
+ * Resolve a profile name to its policy.
21
+ * Returns `undefined` if the profile is not registered.
22
+ */
23
+ resolve(name) {
24
+ return this.profiles.get(name);
25
+ }
26
+ /**
27
+ * Check if a profile is registered.
28
+ */
29
+ has(name) {
30
+ return this.profiles.has(name);
31
+ }
32
+ /**
33
+ * Get all registered profiles.
34
+ */
35
+ getAll() {
36
+ const result = {};
37
+ for (const [name, policy] of this.profiles) {
38
+ result[name] = policy;
39
+ }
40
+ return result;
41
+ }
42
+ /**
43
+ * Get the number of registered profiles.
44
+ */
45
+ get size() {
46
+ return this.profiles.size;
47
+ }
48
+ /**
49
+ * Remove a profile by name.
50
+ */
51
+ remove(name) {
52
+ return this.profiles.delete(name);
53
+ }
54
+ /**
55
+ * Clear all profiles.
56
+ */
57
+ clear() {
58
+ this.profiles.clear();
59
+ }
60
+ };
61
+ var AuthoritiesEvaluatorRegistry = class {
62
+ evaluators = /* @__PURE__ */ new Map();
63
+ /**
64
+ * Register a custom evaluator.
65
+ * The evaluator's name must match the key used in `custom.*`.
66
+ */
67
+ register(name, evaluator) {
68
+ this.evaluators.set(name, evaluator);
69
+ }
70
+ /**
71
+ * Register multiple evaluators at once.
72
+ */
73
+ registerAll(evaluators) {
74
+ for (const [name, evaluator] of Object.entries(evaluators)) {
75
+ this.evaluators.set(name, evaluator);
76
+ }
77
+ }
78
+ /**
79
+ * Get an evaluator by name.
80
+ */
81
+ get(name) {
82
+ return this.evaluators.get(name);
83
+ }
84
+ /**
85
+ * Check if an evaluator is registered.
86
+ */
87
+ has(name) {
88
+ return this.evaluators.has(name);
89
+ }
90
+ /**
91
+ * Get the number of registered evaluators.
92
+ */
93
+ get size() {
94
+ return this.evaluators.size;
95
+ }
96
+ /**
97
+ * Remove an evaluator by name.
98
+ */
99
+ remove(name) {
100
+ return this.evaluators.delete(name);
101
+ }
102
+ /**
103
+ * Clear all evaluators.
104
+ */
105
+ clear() {
106
+ this.evaluators.clear();
107
+ }
108
+ };
109
+ export {
110
+ AuthoritiesEvaluatorRegistry,
111
+ AuthoritiesProfileRegistry
112
+ };
@@ -0,0 +1,92 @@
1
+ // libs/auth/src/authorities/authorities.schema.ts
2
+ import { z } from "@frontmcp/lazy-zod";
3
+ var rbacRolesPolicySchema = z.object({
4
+ all: z.array(z.string().min(1)).optional(),
5
+ any: z.array(z.string().min(1)).optional()
6
+ }).refine((data) => data.all !== void 0 || data.any !== void 0, {
7
+ message: 'Roles policy must have at least "all" or "any"'
8
+ });
9
+ var rbacPermissionsPolicySchema = z.object({
10
+ all: z.array(z.string().min(1)).optional(),
11
+ any: z.array(z.string().min(1)).optional()
12
+ }).refine((data) => data.all !== void 0 || data.any !== void 0, {
13
+ message: 'Permissions policy must have at least "all" or "any"'
14
+ });
15
+ var abacOperatorSchema = z.enum([
16
+ "eq",
17
+ "neq",
18
+ "in",
19
+ "notIn",
20
+ "gt",
21
+ "gte",
22
+ "lt",
23
+ "lte",
24
+ "contains",
25
+ "startsWith",
26
+ "endsWith",
27
+ "exists",
28
+ "matches"
29
+ ]);
30
+ var abacConditionSchema = z.object({
31
+ path: z.string().min(1),
32
+ op: abacOperatorSchema,
33
+ value: z.unknown()
34
+ });
35
+ var abacPolicySchema = z.object({
36
+ match: z.record(z.string(), z.unknown()).optional(),
37
+ conditions: z.array(abacConditionSchema).optional()
38
+ }).refine((data) => data.match !== void 0 || data.conditions !== void 0, {
39
+ message: 'Attributes policy must have at least "match" or "conditions"'
40
+ });
41
+ var resourceIdRefSchema = z.union([
42
+ z.string().min(1),
43
+ z.object({ fromInput: z.string().min(1) }).strict(),
44
+ z.object({ fromClaims: z.string().min(1) }).strict()
45
+ ]);
46
+ var rebacPolicySchema = z.object({
47
+ type: z.string().min(1),
48
+ resource: z.string().min(1),
49
+ resourceId: resourceIdRefSchema
50
+ });
51
+ var basePolicyShape = {
52
+ roles: rbacRolesPolicySchema.optional(),
53
+ permissions: rbacPermissionsPolicySchema.optional(),
54
+ attributes: abacPolicySchema.optional(),
55
+ relationships: z.union([rebacPolicySchema, z.array(rebacPolicySchema)]).optional(),
56
+ custom: z.record(z.string(), z.unknown()).optional(),
57
+ guards: z.array(z.instanceof(Function)).optional(),
58
+ operator: z.enum(["AND", "OR"]).optional()
59
+ };
60
+ var authoritiesPolicySchema = z.lazy(
61
+ () => z.object({
62
+ ...basePolicyShape,
63
+ not: authoritiesPolicySchema.optional(),
64
+ anyOf: z.array(authoritiesPolicySchema).optional(),
65
+ allOf: z.array(authoritiesPolicySchema).optional()
66
+ })
67
+ );
68
+ var authoritiesMetadataSchema = z.union([
69
+ z.string().min(1),
70
+ z.array(z.string().min(1)).min(1),
71
+ authoritiesPolicySchema
72
+ ]);
73
+ var authoritiesClaimsMappingSchema = z.record(z.string(), z.string().optional()).refine((data) => Object.values(data).some((v) => v !== void 0), {
74
+ message: "Claims mapping must have at least one mapping"
75
+ });
76
+ var authoritiesConfigSchema = z.object({
77
+ claimsMapping: authoritiesClaimsMappingSchema.optional(),
78
+ profiles: z.record(z.string().min(1), authoritiesPolicySchema).optional()
79
+ });
80
+ export {
81
+ abacConditionSchema,
82
+ abacOperatorSchema,
83
+ abacPolicySchema,
84
+ authoritiesClaimsMappingSchema,
85
+ authoritiesConfigSchema,
86
+ authoritiesMetadataSchema,
87
+ authoritiesPolicySchema,
88
+ rbacPermissionsPolicySchema,
89
+ rbacRolesPolicySchema,
90
+ rebacPolicySchema,
91
+ resourceIdRefSchema
92
+ };
@@ -0,0 +1,30 @@
1
+ // libs/auth/src/authorities/authorities.scope-mapping.ts
2
+ function resolveRequiredScopes(denial, mapping, authorities) {
3
+ const scopes = /* @__PURE__ */ new Set();
4
+ if (typeof authorities === "string" && mapping.profiles?.[authorities]) {
5
+ mapping.profiles[authorities].forEach((s) => scopes.add(s));
6
+ }
7
+ if (Array.isArray(authorities)) {
8
+ for (const profileName of authorities) {
9
+ if (typeof profileName === "string" && mapping.profiles?.[profileName]) {
10
+ mapping.profiles[profileName].forEach((s) => scopes.add(s));
11
+ }
12
+ }
13
+ }
14
+ if (denial.kind === "roles" && denial.missing && mapping.roles) {
15
+ for (const role of denial.missing) {
16
+ const mapped = mapping.roles[role];
17
+ if (mapped) mapped.forEach((s) => scopes.add(s));
18
+ }
19
+ }
20
+ if (denial.kind === "permissions" && denial.missing && mapping.permissions) {
21
+ for (const perm of denial.missing) {
22
+ const mapped = mapping.permissions[perm];
23
+ if (mapped) mapped.forEach((s) => scopes.add(s));
24
+ }
25
+ }
26
+ return scopes.size > 0 ? [...scopes].sort() : void 0;
27
+ }
28
+ export {
29
+ resolveRequiredScopes
30
+ };
@@ -0,0 +1,208 @@
1
+ // libs/auth/src/authorities/authorities.validation.ts
2
+ var ABAC_OPERATORS = /* @__PURE__ */ new Set([
3
+ "eq",
4
+ "neq",
5
+ "in",
6
+ "notIn",
7
+ "gt",
8
+ "gte",
9
+ "lt",
10
+ "lte",
11
+ "contains",
12
+ "startsWith",
13
+ "endsWith",
14
+ "exists",
15
+ "matches"
16
+ ]);
17
+ var CHECK_FIELDS = [
18
+ "roles",
19
+ "permissions",
20
+ "attributes",
21
+ "relationships",
22
+ "custom",
23
+ "guards",
24
+ "allOf",
25
+ "anyOf",
26
+ "not"
27
+ ];
28
+ var RULE_FIELDS = /* @__PURE__ */ new Set([...CHECK_FIELDS, "operator"]);
29
+ function isPlainObject(value) {
30
+ return typeof value === "object" && value !== null && !Array.isArray(value);
31
+ }
32
+ function isNonEmptyString(value) {
33
+ return typeof value === "string" && value.length > 0;
34
+ }
35
+ function unknownFields(value, known, path) {
36
+ const prefix = path ? `${path} has` : "has";
37
+ return Object.keys(value).filter((key) => !known.has(key)).map((key) => `${prefix} an unknown field "${key}"`);
38
+ }
39
+ function checkStringList(value, path) {
40
+ if (!Array.isArray(value)) return [`${path} must be a list of names`];
41
+ if (value.length === 0) return [`${path} is empty`];
42
+ return value.every(isNonEmptyString) ? [] : [`${path} must contain only non-empty names`];
43
+ }
44
+ var ALL_OR_ANY = /* @__PURE__ */ new Set(["all", "any"]);
45
+ function checkAllOrAny(value, path) {
46
+ if (!isPlainObject(value)) return [`${path} must be an object with "all" or "any"`];
47
+ const problems = unknownFields(value, ALL_OR_ANY, path);
48
+ if (value["all"] === void 0 && value["any"] === void 0) {
49
+ problems.push(`${path} needs "all" or "any"`);
50
+ }
51
+ if (value["all"] !== void 0) problems.push(...checkStringList(value["all"], `${path}.all`));
52
+ if (value["any"] !== void 0) problems.push(...checkStringList(value["any"], `${path}.any`));
53
+ return problems;
54
+ }
55
+ var ATTRIBUTE_FIELDS = /* @__PURE__ */ new Set(["match", "conditions"]);
56
+ var CONDITION_FIELDS = /* @__PURE__ */ new Set(["path", "op", "value"]);
57
+ function isValueReference(value) {
58
+ return isPlainObject(value) && ("fromInput" in value || "fromClaims" in value);
59
+ }
60
+ function checkValueReference(value, path) {
61
+ const ref = value["fromInput"] ?? value["fromClaims"];
62
+ return Object.keys(value).length === 1 && isNonEmptyString(ref) ? [] : [`${path} must be { fromInput: "<name>" } or { fromClaims: "<path>" }`];
63
+ }
64
+ var OPERATOR_VALUES = {
65
+ in: { accepts: Array.isArray, needs: "a list" },
66
+ notIn: { accepts: Array.isArray, needs: "a list" },
67
+ gt: { accepts: (value) => typeof value === "number", needs: "a number" },
68
+ gte: { accepts: (value) => typeof value === "number", needs: "a number" },
69
+ lt: { accepts: (value) => typeof value === "number", needs: "a number" },
70
+ lte: { accepts: (value) => typeof value === "number", needs: "a number" },
71
+ startsWith: { accepts: (value) => typeof value === "string", needs: "a string" },
72
+ endsWith: { accepts: (value) => typeof value === "string", needs: "a string" },
73
+ matches: { accepts: (value) => typeof value === "string", needs: "a string" }
74
+ };
75
+ function checkConditionValue(op, condition, path) {
76
+ const value = condition["value"];
77
+ if (value === void 0) return [`${path} is missing`];
78
+ if (op === "exists") {
79
+ return typeof value === "boolean" ? [] : [`${path} must be true or false for "exists"`];
80
+ }
81
+ if (isValueReference(value)) return checkValueReference(value, path);
82
+ const expected = OPERATOR_VALUES[op];
83
+ if (expected && !expected.accepts(value)) return [`${path} must be ${expected.needs} for "${op}"`];
84
+ if (Array.isArray(value) && value.length === 0 && (op === "in" || op === "notIn")) return [`${path} is empty`];
85
+ return [];
86
+ }
87
+ function checkAttributes(value, path) {
88
+ if (!isPlainObject(value)) return [`${path} must be an object with "match" or "conditions"`];
89
+ const problems = unknownFields(value, ATTRIBUTE_FIELDS, path);
90
+ const { match, conditions } = value;
91
+ if (match === void 0 && conditions === void 0) {
92
+ problems.push(`${path} needs "match" or "conditions"`);
93
+ }
94
+ if (match !== void 0) {
95
+ if (!isPlainObject(match)) problems.push(`${path}.match must be an object`);
96
+ else if (Object.keys(match).length === 0) problems.push(`${path}.match is empty`);
97
+ else {
98
+ for (const [attribute, expected] of Object.entries(match)) {
99
+ const at = `${path}.match[${JSON.stringify(attribute)}]`;
100
+ if (expected === void 0) problems.push(`${at} has no value`);
101
+ else if (isValueReference(expected)) problems.push(...checkValueReference(expected, at));
102
+ }
103
+ }
104
+ }
105
+ if (conditions !== void 0) {
106
+ if (!Array.isArray(conditions)) problems.push(`${path}.conditions must be a list`);
107
+ else if (conditions.length === 0) problems.push(`${path}.conditions is empty`);
108
+ else {
109
+ conditions.forEach((condition, index) => {
110
+ const at = `${path}.conditions[${index}]`;
111
+ if (!isPlainObject(condition)) {
112
+ problems.push(`${at} must be an object with "path" and "op"`);
113
+ return;
114
+ }
115
+ problems.push(...unknownFields(condition, CONDITION_FIELDS, at));
116
+ if (!isNonEmptyString(condition["path"])) problems.push(`${at}.path must be a non-empty string`);
117
+ const op = condition["op"];
118
+ if (!ABAC_OPERATORS.has(op)) {
119
+ problems.push(`${at}.op "${String(condition["op"])}" is not an operator`);
120
+ } else {
121
+ problems.push(...checkConditionValue(op, condition, `${at}.value`));
122
+ }
123
+ });
124
+ }
125
+ }
126
+ return problems;
127
+ }
128
+ var RELATIONSHIP_FIELDS = /* @__PURE__ */ new Set(["type", "resource", "resourceId"]);
129
+ function checkResourceId(value, path) {
130
+ if (isNonEmptyString(value)) return [];
131
+ if (isPlainObject(value) && Object.keys(value).length === 1) {
132
+ const ref = value["fromInput"] ?? value["fromClaims"];
133
+ if (isNonEmptyString(ref)) return [];
134
+ }
135
+ return [`${path} must be a string, { fromInput } or { fromClaims }`];
136
+ }
137
+ function checkRelationship(value, path) {
138
+ if (!isPlainObject(value)) return [`${path} must be an object with "type", "resource" and "resourceId"`];
139
+ const problems = unknownFields(value, RELATIONSHIP_FIELDS, path);
140
+ if (!isNonEmptyString(value["type"])) problems.push(`${path}.type must be a non-empty string`);
141
+ if (!isNonEmptyString(value["resource"])) problems.push(`${path}.resource must be a non-empty string`);
142
+ problems.push(...checkResourceId(value["resourceId"], `${path}.resourceId`));
143
+ return problems;
144
+ }
145
+ function checkRelationships(value, path) {
146
+ if (!Array.isArray(value)) return checkRelationship(value, path);
147
+ if (value.length === 0) return [`${path} is empty`];
148
+ return value.flatMap((relationship, index) => checkRelationship(relationship, `${path}[${index}]`));
149
+ }
150
+ function checkRuleList(value, path) {
151
+ if (!Array.isArray(value)) return [`${path} must be a list of rules`];
152
+ if (value.length === 0) return [`${path} is empty`];
153
+ return value.flatMap((rule, index) => checkRule(rule, `${path}[${index}]`));
154
+ }
155
+ function checkRule(rule, path) {
156
+ if (!isPlainObject(rule)) {
157
+ return [`${path || "the rule"} must be a rule object${typeof rule === "string" ? ", not a profile name" : ""}`];
158
+ }
159
+ const problems = unknownFields(rule, RULE_FIELDS, path);
160
+ if (!CHECK_FIELDS.some((field) => rule[field] !== void 0)) {
161
+ problems.push(`${path ? `${path} ` : ""}checks nothing`);
162
+ }
163
+ if (rule["operator"] !== void 0 && rule["operator"] !== "AND" && rule["operator"] !== "OR") {
164
+ problems.push(`${path}.operator must be "AND" or "OR"`);
165
+ }
166
+ if (rule["roles"] !== void 0) problems.push(...checkAllOrAny(rule["roles"], `${path}.roles`));
167
+ if (rule["permissions"] !== void 0) problems.push(...checkAllOrAny(rule["permissions"], `${path}.permissions`));
168
+ if (rule["attributes"] !== void 0) problems.push(...checkAttributes(rule["attributes"], `${path}.attributes`));
169
+ if (rule["relationships"] !== void 0) {
170
+ problems.push(...checkRelationships(rule["relationships"], `${path}.relationships`));
171
+ }
172
+ if (rule["custom"] !== void 0) {
173
+ if (!isPlainObject(rule["custom"])) problems.push(`${path}.custom must be an object`);
174
+ else if (Object.keys(rule["custom"]).length === 0) problems.push(`${path}.custom is empty`);
175
+ }
176
+ if (rule["guards"] !== void 0) {
177
+ const guards = rule["guards"];
178
+ if (!Array.isArray(guards)) problems.push(`${path}.guards must be a list of functions`);
179
+ else if (guards.length === 0) problems.push(`${path}.guards is empty`);
180
+ else if (!guards.every((guard) => typeof guard === "function")) {
181
+ problems.push(`${path}.guards must contain only functions`);
182
+ }
183
+ }
184
+ if (rule["allOf"] !== void 0) problems.push(...checkRuleList(rule["allOf"], `${path}.allOf`));
185
+ if (rule["anyOf"] !== void 0) problems.push(...checkRuleList(rule["anyOf"], `${path}.anyOf`));
186
+ if (rule["not"] !== void 0) problems.push(...checkRule(rule["not"], `${path}.not`));
187
+ return problems;
188
+ }
189
+ function findAuthoritiesRuleProblems(authorities) {
190
+ if (typeof authorities === "string") {
191
+ return authorities.length > 0 ? [] : ["the profile name is empty"];
192
+ }
193
+ if (Array.isArray(authorities)) {
194
+ if (authorities.length === 0) return ["the list of profiles is empty"];
195
+ return authorities.every(isNonEmptyString) ? [] : ["a list of profiles must contain only non-empty profile names"];
196
+ }
197
+ if (!isPlainObject(authorities)) {
198
+ return ["must be a profile name, a list of profile names, or a rule object"];
199
+ }
200
+ return checkRule(authorities, "");
201
+ }
202
+ function findAuthoritiesProfileProblems(name, policy) {
203
+ return checkRule(policy, "").map((problem) => `profile "${name}": ${problem.replace(/^\./, "")}`);
204
+ }
205
+ export {
206
+ findAuthoritiesProfileProblems,
207
+ findAuthoritiesRuleProblems
208
+ };
@@ -0,0 +1,43 @@
1
+ // libs/auth/src/authorities/index.ts
2
+ import "./authorities.metadata-augment.mjs";
3
+ import { resolveRequiredScopes } from "./authorities.scope-mapping.mjs";
4
+ import {
5
+ rbacRolesPolicySchema,
6
+ rbacPermissionsPolicySchema,
7
+ abacOperatorSchema,
8
+ abacConditionSchema,
9
+ abacPolicySchema,
10
+ resourceIdRefSchema,
11
+ rebacPolicySchema,
12
+ authoritiesPolicySchema,
13
+ authoritiesMetadataSchema,
14
+ authoritiesClaimsMappingSchema,
15
+ authoritiesConfigSchema
16
+ } from "./authorities.schema.mjs";
17
+ import { AuthoritiesEngine } from "./authorities.engine.mjs";
18
+ import { findAuthoritiesRuleProblems, findAuthoritiesProfileProblems } from "./authorities.validation.mjs";
19
+ import { AuthoritiesContextBuilder, isAnonymousSubject } from "./authorities.context.mjs";
20
+ import { AuthoritiesEvaluatorRegistry, AuthoritiesProfileRegistry } from "./authorities.registry.mjs";
21
+ import { AuthorityDeniedError } from "./authorities.errors.mjs";
22
+ export {
23
+ AuthoritiesContextBuilder,
24
+ AuthoritiesEngine,
25
+ AuthoritiesEvaluatorRegistry,
26
+ AuthoritiesProfileRegistry,
27
+ AuthorityDeniedError,
28
+ abacConditionSchema,
29
+ abacOperatorSchema,
30
+ abacPolicySchema,
31
+ authoritiesClaimsMappingSchema,
32
+ authoritiesConfigSchema,
33
+ authoritiesMetadataSchema,
34
+ authoritiesPolicySchema,
35
+ findAuthoritiesProfileProblems,
36
+ findAuthoritiesRuleProblems,
37
+ isAnonymousSubject,
38
+ rbacPermissionsPolicySchema,
39
+ rbacRolesPolicySchema,
40
+ rebacPolicySchema,
41
+ resolveRequiredScopes,
42
+ resourceIdRefSchema
43
+ };