@authup/access 1.0.0-beta.33 → 1.0.0-beta.34

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 (49) hide show
  1. package/dist/index.mjs +132 -49
  2. package/dist/index.mjs.map +1 -1
  3. package/dist/permission/evaluator/module.d.ts +3 -3
  4. package/dist/permission/evaluator/module.d.ts.map +1 -1
  5. package/dist/permission/evaluator/types.d.ts +1 -1
  6. package/dist/permission/evaluator/types.d.ts.map +1 -1
  7. package/dist/permission/helpers/equal.d.ts +2 -1
  8. package/dist/permission/helpers/equal.d.ts.map +1 -1
  9. package/dist/permission/helpers/index.d.ts +1 -1
  10. package/dist/permission/helpers/index.d.ts.map +1 -1
  11. package/dist/permission/helpers/key.d.ts +2 -1
  12. package/dist/permission/helpers/key.d.ts.map +1 -1
  13. package/dist/permission/helpers/merge.d.ts +2 -1
  14. package/dist/permission/helpers/merge.d.ts.map +1 -1
  15. package/dist/permission/provider/memory.d.ts +5 -5
  16. package/dist/permission/provider/memory.d.ts.map +1 -1
  17. package/dist/permission/provider/types.d.ts +2 -2
  18. package/dist/permission/provider/types.d.ts.map +1 -1
  19. package/dist/permission/types.d.ts +12 -1
  20. package/dist/permission/types.d.ts.map +1 -1
  21. package/dist/policy/built-in/attribute-names/types.d.ts +2 -2
  22. package/dist/policy/built-in/attribute-names/validator.d.ts.map +1 -1
  23. package/dist/policy/built-in/attributes/types.d.ts +2 -2
  24. package/dist/policy/built-in/attributes/validator.d.ts.map +1 -1
  25. package/dist/policy/built-in/composite/evaluator.d.ts.map +1 -1
  26. package/dist/policy/built-in/composite/types.d.ts +3 -3
  27. package/dist/policy/built-in/composite/types.d.ts.map +1 -1
  28. package/dist/policy/built-in/composite/validator.d.ts.map +1 -1
  29. package/dist/policy/built-in/date/types.d.ts +2 -2
  30. package/dist/policy/built-in/date/validator.d.ts.map +1 -1
  31. package/dist/policy/built-in/identity/data/validator.d.ts.map +1 -1
  32. package/dist/policy/built-in/identity/types.d.ts +2 -2
  33. package/dist/policy/built-in/identity/validator.d.ts +1 -1
  34. package/dist/policy/built-in/identity/validator.d.ts.map +1 -1
  35. package/dist/policy/built-in/permission-binding/types.d.ts +2 -2
  36. package/dist/policy/built-in/permission-binding/validator.d.ts +1 -1
  37. package/dist/policy/built-in/permission-binding/validator.d.ts.map +1 -1
  38. package/dist/policy/built-in/realm-match/types.d.ts +2 -2
  39. package/dist/policy/built-in/realm-match/validator.d.ts.map +1 -1
  40. package/dist/policy/built-in/time/evaluator.d.ts.map +1 -1
  41. package/dist/policy/built-in/time/types.d.ts +2 -2
  42. package/dist/policy/built-in/time/validator.d.ts.map +1 -1
  43. package/dist/policy/engine/module.d.ts +3 -3
  44. package/dist/policy/engine/module.d.ts.map +1 -1
  45. package/dist/policy/engine/types.d.ts +3 -3
  46. package/dist/policy/engine/types.d.ts.map +1 -1
  47. package/dist/policy/types.d.ts +6 -8
  48. package/dist/policy/types.d.ts.map +1 -1
  49. package/package.json +5 -7
package/dist/index.mjs CHANGED
@@ -1,9 +1,7 @@
1
1
  import { AuthupError, ErrorCode } from '@authup/errors';
2
- import { buildPermissionBindingKey, mergePermissionBindings } from '@authup/core-kit';
3
- export { buildPermissionBindingKey, isPermissionBindingEqual, mergePermissionBindings } from '@authup/core-kit';
4
- import { defineIssueItem, defineIssueGroup, Container } from 'validup';
5
- import { isObject, flattenObject, DecisionStrategy, hasOwnProperty } from '@authup/kit';
2
+ import { DecisionStrategy, isObject, flattenObject, hasOwnProperty } from '@authup/kit';
6
3
  export { DecisionStrategy } from '@authup/kit';
4
+ import { defineIssueItem, defineIssueGroup, Container } from 'validup';
7
5
  import { createValidator } from '@validup/adapter-zod';
8
6
  import { z } from 'zod';
9
7
  import { guard } from '@ucast/mongo2js';
@@ -54,25 +52,109 @@ class PermissionError extends AuthupError {
54
52
  }
55
53
  }
56
54
 
55
+ /*
56
+ * Copyright (c) 2024-2024.
57
+ * Author Peter Placzek (tada5hi)
58
+ * For the full copyright and license information,
59
+ * view the LICENSE file that was distributed with this source code.
60
+ */ function isPermissionPolicyBindingEqual(a, b) {
61
+ if (a.permission.name !== b.permission.name) {
62
+ return false;
63
+ }
64
+ if ((a.permission.realm_id ?? null) !== (b.permission.realm_id ?? null)) {
65
+ return false;
66
+ }
67
+ if ((a.permission.client_id ?? null) !== (b.permission.client_id ?? null)) {
68
+ return false;
69
+ }
70
+ return true;
71
+ }
72
+
73
+ /*
74
+ * Copyright (c) 2025.
75
+ * Author Peter Placzek (tada5hi)
76
+ * For the full copyright and license information,
77
+ * view the LICENSE file that was distributed with this source code.
78
+ */ function formatKeySegment(value) {
79
+ return value || '*';
80
+ }
81
+ function buildPermissionKey(input) {
82
+ return `${formatKeySegment(input.realm_id)}/${formatKeySegment(input.client_id)}/${input.name}`;
83
+ }
84
+
85
+ function mergePermissionPolicyBindings(input) {
86
+ const grouped = input.reduce((previous, current)=>{
87
+ const key = buildPermissionKey(current.permission);
88
+ if (!previous[key]) {
89
+ previous[key] = [];
90
+ }
91
+ previous[key].push(current);
92
+ return previous;
93
+ }, {});
94
+ const output = [];
95
+ const keys = Object.keys(grouped);
96
+ for (const key of keys){
97
+ const group = grouped[key];
98
+ const first = group[0];
99
+ if (group.length === 1) {
100
+ output.push(first);
101
+ continue;
102
+ }
103
+ const children = [];
104
+ for (const element of group){
105
+ if (!element.policies || element.policies.length === 0) {
106
+ continue;
107
+ }
108
+ const policy = {
109
+ type: 'composite',
110
+ decision_strategy: element.permission.decision_strategy || DecisionStrategy.UNANIMOUS,
111
+ children: element.policies
112
+ };
113
+ children.push(policy);
114
+ }
115
+ let mergedPolicies;
116
+ if (children.length > 0 && children.length === group.length) {
117
+ const policy = {
118
+ type: 'composite',
119
+ decision_strategy: DecisionStrategy.AFFIRMATIVE,
120
+ children
121
+ };
122
+ mergedPolicies = [
123
+ policy
124
+ ];
125
+ }
126
+ output.push({
127
+ permission: {
128
+ ...first.permission,
129
+ decision_strategy: DecisionStrategy.AFFIRMATIVE
130
+ },
131
+ policies: mergedPolicies
132
+ });
133
+ }
134
+ return output;
135
+ }
136
+
57
137
  class PermissionMemoryProvider {
58
138
  items = {};
59
139
  constructor(items = []){
60
140
  this.setMany(items);
61
141
  }
62
142
  async findOne(options) {
63
- const entry = this.items[buildPermissionBindingKey({
143
+ const key = buildPermissionKey({
64
144
  name: options.name,
65
145
  client_id: options.clientId,
66
146
  realm_id: options.realmId
67
- })];
147
+ });
148
+ const entry = this.items[key];
68
149
  if (entry) {
69
150
  return entry;
70
151
  }
71
152
  return null;
72
153
  }
73
154
  setMany(input) {
74
- this.items = mergePermissionBindings(input).reduce((prev, current)=>{
75
- prev[buildPermissionBindingKey(current.permission)] = current;
155
+ this.items = mergePermissionPolicyBindings(input).reduce((prev, current)=>{
156
+ const key = buildPermissionKey(current.permission);
157
+ prev[key] = current;
76
158
  return prev;
77
159
  }, {});
78
160
  }
@@ -141,6 +223,18 @@ class PolicyError extends AuthupError {
141
223
  * @param policy
142
224
  * @param ctx
143
225
  */ async evaluate(policy, ctx) {
226
+ if (!policy.type) {
227
+ return {
228
+ success: maybeInvertPolicyOutcome(false, policy.invert),
229
+ issues: [
230
+ defineIssueItem({
231
+ path: [],
232
+ message: 'The policy can not be handled by any evaluator.',
233
+ code: ErrorCode.POLICY_EVALUATOR_NOT_FOUND
234
+ })
235
+ ]
236
+ };
237
+ }
144
238
  if (ctx.exclude && ctx.exclude.length > 0 && ctx.exclude.includes(policy.type)) {
145
239
  return {
146
240
  success: maybeInvertPolicyOutcome(true, policy.invert)
@@ -422,8 +516,8 @@ class AttributesPolicyEvaluator {
422
516
  }
423
517
  if (key === '$regex' && typeof value === 'string') {
424
518
  const fragments = value.match(/\/(.*?)\/([a-z]*)?$/i);
425
- if (fragments) {
426
- query[key] = new RegExp(fragments[1], fragments[2]);
519
+ if (fragments && fragments[1] !== undefined) {
520
+ query[key] = new RegExp(fragments[1], fragments[2] || '');
427
521
  }
428
522
  }
429
523
  }
@@ -500,11 +594,12 @@ class CompositePolicyEvaluator {
500
594
  const decision_strategy = policy.decision_strategy ?? DecisionStrategy.UNANIMOUS;
501
595
  const engine = new PolicyEngine(ctx.evaluators);
502
596
  const issues = [];
503
- for(let i = 0; i < policy.children.length; i++){
504
- const childPolicy = policy.children[i];
597
+ for (const childPolicy of policy.children){
505
598
  const path = [
506
599
  ...ctx.path || [],
507
- childPolicy.type
600
+ ...childPolicy.type ? [
601
+ childPolicy.type
602
+ ] : []
508
603
  ];
509
604
  const outcome = await engine.evaluate(childPolicy, {
510
605
  ...ctx,
@@ -902,10 +997,15 @@ function normalizeDate(input, dateRef) {
902
997
  function toDate(input, dateRef) {
903
998
  if (typeof input === 'string') {
904
999
  if (timeRegex.test(input)) {
905
- const [startHours, startMinutes] = input.split(':').map(Number);
906
- const date = dateRef ? new Date(dateRef) : new Date();
907
- date.setHours(startHours, startMinutes);
908
- return date;
1000
+ const parts = input.split(':');
1001
+ const startHours = Number(parts[0]);
1002
+ const startMinutes = Number(parts[1]);
1003
+ const startSeconds = parts[2] !== undefined ? Number(parts[2]) : 0;
1004
+ if (Number.isFinite(startHours) && Number.isFinite(startMinutes) && Number.isFinite(startSeconds)) {
1005
+ const date = dateRef ? new Date(dateRef) : new Date();
1006
+ date.setHours(startHours, startMinutes, startSeconds, 0);
1007
+ return date;
1008
+ }
909
1009
  }
910
1010
  return new Date(input);
911
1011
  }
@@ -1013,18 +1113,10 @@ class PermissionEvaluator {
1013
1113
  clientId;
1014
1114
  realmId;
1015
1115
  // ----------------------------------------------
1016
- constructor(options = {}){
1017
- if (options.provider) {
1018
- this.provider = options.provider;
1019
- } else {
1020
- this.provider = new PermissionMemoryProvider();
1021
- }
1022
- if (typeof options.clientId !== 'undefined') {
1023
- this.clientId = options.clientId;
1024
- }
1025
- if (typeof options.realmId !== 'undefined') {
1026
- this.realmId = options.realmId;
1027
- }
1116
+ constructor(options){
1117
+ this.provider = options.provider;
1118
+ this.clientId = options.clientId || null;
1119
+ this.realmId = options.realmId || null;
1028
1120
  if (options.policyEngine) {
1029
1121
  this.policyEngine = options.policyEngine;
1030
1122
  } else {
@@ -1032,21 +1124,12 @@ class PermissionEvaluator {
1032
1124
  }
1033
1125
  }
1034
1126
  // ----------------------------------------------
1035
- async findOne(input, overrides) {
1036
- const options = {
1037
- name: input
1038
- };
1039
- if (typeof overrides?.clientId !== 'undefined') {
1040
- options.clientId = overrides.clientId;
1041
- } else if (typeof this.clientId !== 'undefined') {
1042
- options.clientId = this.clientId;
1043
- }
1044
- if (typeof overrides?.realmId !== 'undefined') {
1045
- options.realmId = overrides.realmId;
1046
- } else if (typeof this.realmId !== 'undefined') {
1047
- options.realmId = this.realmId;
1048
- }
1049
- return this.provider.findOne(options);
1127
+ async findOne(input, overrides = {}) {
1128
+ return this.provider.findOne({
1129
+ name: input,
1130
+ clientId: overrides.clientId ?? this.clientId,
1131
+ realmId: overrides.realmId ?? this.realmId
1132
+ });
1050
1133
  }
1051
1134
  // ----------------------------------------------
1052
1135
  async evaluate(ctx) {
@@ -1064,17 +1147,17 @@ class PermissionEvaluator {
1064
1147
  const issues = [];
1065
1148
  let count = 0;
1066
1149
  const dataBase = ctx.input || new PolicyData();
1067
- for(let i = 0; i < ctx.name.length; i++){
1068
- const binding = await this.findOne(ctx.name[i], {
1150
+ for (const name of ctx.name){
1151
+ const binding = await this.findOne(name, {
1069
1152
  realmId: ctx.realmId,
1070
1153
  clientId: ctx.clientId
1071
1154
  });
1072
1155
  if (!binding) {
1073
1156
  issues.push(defineIssueItem({
1074
1157
  code: ErrorCode.PERMISSION_NOT_FOUND,
1075
- message: `The ${ctx.name[i]} permission could not be resolved`,
1158
+ message: `The ${name} permission could not be resolved`,
1076
1159
  path: [
1077
- ctx.name[i]
1160
+ name
1078
1161
  ]
1079
1162
  }));
1080
1163
  if (decisionStrategy === DecisionStrategy.UNANIMOUS) {
@@ -1172,5 +1255,5 @@ class PermissionEvaluator {
1172
1255
  }
1173
1256
  }
1174
1257
 
1175
- export { AttributeNamesPolicyEvaluator, AttributeNamesPolicyValidator, AttributesPolicyEvaluator, AttributesPolicyValidator, BuiltInPolicyType, CompositePolicyEvaluator, CompositePolicyValidator, DatePolicyEvaluator, DatePolicyValidator, IdentityPolicyEvaluator, IdentityPolicyValidator, PermissionBindingPolicyEvaluator, PermissionBindingPolicyValidator, PermissionError, PermissionEvaluator, PermissionMemoryProvider, PolicyData, PolicyDefaultEvaluators, PolicyEngine, PolicyError, PolicyIssueCode, PolicyIssueSeverity, RealmMatchPolicyEvaluator, RealmMatchPolicyValidator, SystemPolicyName, TimePolicyEvaluator, TimePolicyInterval, TimePolicyValidator, defineAttributesPolicy, definePolicyEvaluationContext, definePolicyIssueGroup, definePolicyIssueItem, definePolicyWithType, isCompositePolicy, isIntervalForDayOfMonth, isIntervalForDayOfWeek, isIntervalForDayOfYear, maybeInvertPolicyOutcome };
1258
+ export { AttributeNamesPolicyEvaluator, AttributeNamesPolicyValidator, AttributesPolicyEvaluator, AttributesPolicyValidator, BuiltInPolicyType, CompositePolicyEvaluator, CompositePolicyValidator, DatePolicyEvaluator, DatePolicyValidator, IdentityPolicyEvaluator, IdentityPolicyValidator, PermissionBindingPolicyEvaluator, PermissionBindingPolicyValidator, PermissionError, PermissionEvaluator, PermissionMemoryProvider, PolicyData, PolicyDefaultEvaluators, PolicyEngine, PolicyError, PolicyIssueCode, PolicyIssueSeverity, RealmMatchPolicyEvaluator, RealmMatchPolicyValidator, SystemPolicyName, TimePolicyEvaluator, TimePolicyInterval, TimePolicyValidator, buildPermissionKey, defineAttributesPolicy, definePolicyEvaluationContext, definePolicyIssueGroup, definePolicyIssueItem, definePolicyWithType, isCompositePolicy, isIntervalForDayOfMonth, isIntervalForDayOfWeek, isIntervalForDayOfYear, isPermissionPolicyBindingEqual, maybeInvertPolicyOutcome, mergePermissionPolicyBindings };
1176
1259
  //# sourceMappingURL=index.mjs.map