@authup/access 1.0.0-beta.24 → 1.0.0-beta.26

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 (58) hide show
  1. package/LICENSE +1 -1
  2. package/dist/index.cjs +208 -160
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.mjs +204 -162
  5. package/dist/index.mjs.map +1 -1
  6. package/dist/permission/error/module.d.ts +5 -4
  7. package/dist/permission/error/module.d.ts.map +1 -1
  8. package/dist/permission/helpers/equal.d.ts.map +1 -1
  9. package/dist/permission/helpers/index.d.ts +1 -0
  10. package/dist/permission/helpers/index.d.ts.map +1 -1
  11. package/dist/permission/helpers/key.d.ts +3 -0
  12. package/dist/permission/helpers/key.d.ts.map +1 -0
  13. package/dist/permission/helpers/merge.d.ts.map +1 -1
  14. package/dist/permission/module.d.ts +2 -1
  15. package/dist/permission/module.d.ts.map +1 -1
  16. package/dist/permission/provider/types.d.ts +2 -1
  17. package/dist/permission/provider/types.d.ts.map +1 -1
  18. package/dist/permission/types.d.ts +4 -2
  19. package/dist/permission/types.d.ts.map +1 -1
  20. package/dist/policy/built-in/attribute-names/validator.d.ts +1 -1
  21. package/dist/policy/built-in/attribute-names/validator.d.ts.map +1 -1
  22. package/dist/policy/built-in/attributes/define.d.ts +3 -0
  23. package/dist/policy/built-in/attributes/define.d.ts.map +1 -0
  24. package/dist/policy/built-in/attributes/index.d.ts +1 -0
  25. package/dist/policy/built-in/attributes/index.d.ts.map +1 -1
  26. package/dist/policy/built-in/attributes/validator.d.ts +2 -3
  27. package/dist/policy/built-in/attributes/validator.d.ts.map +1 -1
  28. package/dist/policy/built-in/composite/validator.d.ts +2 -3
  29. package/dist/policy/built-in/composite/validator.d.ts.map +1 -1
  30. package/dist/policy/built-in/date/validator.d.ts +2 -3
  31. package/dist/policy/built-in/date/validator.d.ts.map +1 -1
  32. package/dist/policy/built-in/define.d.ts +4 -0
  33. package/dist/policy/built-in/define.d.ts.map +1 -0
  34. package/dist/policy/built-in/identity/validator.d.ts.map +1 -1
  35. package/dist/policy/built-in/index.d.ts +1 -0
  36. package/dist/policy/built-in/index.d.ts.map +1 -1
  37. package/dist/policy/built-in/realm-match/validator.d.ts +2 -3
  38. package/dist/policy/built-in/realm-match/validator.d.ts.map +1 -1
  39. package/dist/policy/built-in/time/evaluator.d.ts.map +1 -1
  40. package/dist/policy/built-in/time/helpers.d.ts +5 -0
  41. package/dist/policy/built-in/time/helpers.d.ts.map +1 -0
  42. package/dist/policy/built-in/time/index.d.ts +1 -0
  43. package/dist/policy/built-in/time/index.d.ts.map +1 -1
  44. package/dist/policy/built-in/time/validator.d.ts +2 -3
  45. package/dist/policy/built-in/time/validator.d.ts.map +1 -1
  46. package/dist/policy/built-in/types.d.ts +21 -1
  47. package/dist/policy/built-in/types.d.ts.map +1 -1
  48. package/dist/policy/error/module.d.ts +2 -2
  49. package/dist/policy/error/module.d.ts.map +1 -1
  50. package/dist/policy/evaluator/data/identity/validator.d.ts +1 -3
  51. package/dist/policy/evaluator/data/identity/validator.d.ts.map +1 -1
  52. package/dist/policy/evaluator/data/permission/validator.d.ts +1 -3
  53. package/dist/policy/evaluator/data/permission/validator.d.ts.map +1 -1
  54. package/dist/policy/evaluator/data/validator.d.ts +1 -3
  55. package/dist/policy/evaluator/data/validator.d.ts.map +1 -1
  56. package/dist/policy/types.d.ts +20 -4
  57. package/dist/policy/types.d.ts.map +1 -1
  58. package/package.json +8 -6
package/dist/index.mjs CHANGED
@@ -1,82 +1,11 @@
1
- import { ErrorCode } from '@authup/errors';
1
+ import { AuthupError, ErrorCode } from '@authup/errors';
2
2
  import { isObject, flattenObject, hasOwnProperty } from '@authup/kit';
3
3
  import { createValidator } from '@validup/adapter-zod';
4
4
  import { Container } from 'validup';
5
5
  import { z } from 'zod';
6
6
  import { guard } from '@ucast/mongo2js';
7
7
 
8
- class PermissionError extends Error {
9
- static notFound(name) {
10
- return new PermissionError({
11
- message: `The permission ${name} was not found.`,
12
- code: ErrorCode.PERMISSION_NOT_FOUND
13
- });
14
- }
15
- static denied(name) {
16
- return new PermissionError({
17
- message: `The permission ${name} has not been granted.`,
18
- code: ErrorCode.PERMISSION_DENIED
19
- });
20
- }
21
- static deniedAll(names) {
22
- return new PermissionError({
23
- message: `None of the permissions ${names.join(', ')} has been granted.`,
24
- code: ErrorCode.PERMISSION_DENIED
25
- });
26
- }
27
- static evaluationFailed(options) {
28
- const error = new PermissionError({
29
- message: `The evaluation of permission ${options.name} failed.`,
30
- code: ErrorCode.PERMISSION_EVALUATION_FAILED
31
- });
32
- if (options.policy) {
33
- error.policy = options.policy;
34
- }
35
- if (options.policyError) {
36
- error.policyError = options.policyError;
37
- }
38
- return error;
39
- }
40
- constructor(options = {}){
41
- super(options.message || 'A permission error occurred.');
42
- this.code = options.code ?? null;
43
- }
44
- }
45
-
46
- /*
47
- * Copyright (c) 2024-2024.
48
- * Author Peter Placzek (tada5hi)
49
- * For the full copyright and license information,
50
- * view the LICENSE file that was distributed with this source code.
51
- */ function isPermissionItemEqual(a, b) {
52
- if (a.name !== b.name) {
53
- return false;
54
- }
55
- if (typeof a.realm_id === 'string' || typeof b.realm_id === 'string') {
56
- return a.realm_id === b.realm_id;
57
- }
58
- return !!a.realm_id === !!b.realm_id;
59
- }
60
-
61
- /*
62
- * Copyright (c) 2024-2024.
63
- * Author Peter Placzek (tada5hi)
64
- * For the full copyright and license information,
65
- * view the LICENSE file that was distributed with this source code.
66
- */ var DecisionStrategy = /*#__PURE__*/ function(DecisionStrategy) {
67
- /**
68
- * One or more positive
69
- */ DecisionStrategy["AFFIRMATIVE"] = "affirmative";
70
- /**
71
- * All positive
72
- */ DecisionStrategy["UNANIMOUS"] = "unanimous";
73
- /**
74
- * More positive than negative
75
- */ DecisionStrategy["CONSENSUS"] = "consensus";
76
- return DecisionStrategy;
77
- }({});
78
-
79
- class PolicyError extends Error {
8
+ class PolicyError extends AuthupError {
80
9
  static evaluatorNotFound(type) {
81
10
  return new PolicyError(`No evaluator is registered to handle the policy: ${type}`, ErrorCode.POLICY_EVALUATOR_NOT_FOUND);
82
11
  }
@@ -87,8 +16,10 @@ class PolicyError extends Error {
87
16
  throw new PolicyError('The evaluator context is not valid.', ErrorCode.POLICY_EVALUATOR_CONTEXT_INVALID);
88
17
  }
89
18
  constructor(message, code){
90
- super(message);
91
- this.code = code ?? null;
19
+ super({
20
+ message,
21
+ code
22
+ });
92
23
  }
93
24
  }
94
25
 
@@ -145,8 +76,9 @@ class PolicyError extends Error {
145
76
 
146
77
  class AttributeNamesPolicyValidator extends Container {
147
78
  initialize() {
79
+ super.initialize();
148
80
  this.mount('names', createValidator(z.array(z.string().min(3).max(128))));
149
- this.mount('invert', createValidator(z.boolean().optional()));
81
+ this.mount('invert', createValidator(z.boolean().or(z.null()).or(z.undefined()).optional()));
150
82
  }
151
83
  }
152
84
 
@@ -182,14 +114,20 @@ class AttributeNamesPolicyEvaluator {
182
114
  }
183
115
  }
184
116
 
117
+ /*
118
+ * Copyright (c) 2025.
119
+ * Author Peter Placzek (tada5hi)
120
+ * For the full copyright and license information,
121
+ * view the LICENSE file that was distributed with this source code.
122
+ */ function defineAttributesPolicy(data) {
123
+ return data;
124
+ }
125
+
185
126
  class AttributesPolicyValidator extends Container {
186
- mountAll() {
127
+ initialize() {
128
+ super.initialize();
187
129
  this.mount('query', createValidator(z.object({}).passthrough()));
188
- this.mount('invert', createValidator(z.boolean().optional()));
189
- }
190
- constructor(options = {}){
191
- super(options);
192
- this.mountAll();
130
+ this.mount('invert', createValidator(z.boolean().or(z.null()).or(z.undefined()).optional()));
193
131
  }
194
132
  }
195
133
 
@@ -236,35 +174,50 @@ class AttributesPolicyEvaluator {
236
174
  }
237
175
  }
238
176
 
177
+ /*
178
+ * Copyright (c) 2024-2024.
179
+ * Author Peter Placzek (tada5hi)
180
+ * For the full copyright and license information,
181
+ * view the LICENSE file that was distributed with this source code.
182
+ */ var DecisionStrategy = /*#__PURE__*/ function(DecisionStrategy) {
183
+ /**
184
+ * One or more positive
185
+ */ DecisionStrategy["AFFIRMATIVE"] = "affirmative";
186
+ /**
187
+ * All positive
188
+ */ DecisionStrategy["UNANIMOUS"] = "unanimous";
189
+ /**
190
+ * More positive than negative
191
+ */ DecisionStrategy["CONSENSUS"] = "consensus";
192
+ return DecisionStrategy;
193
+ }({});
194
+
239
195
  class PolicyDataIdentityValidator extends Container {
240
- mountAll() {
196
+ initialize() {
197
+ super.initialize();
241
198
  this.mount('type', createValidator(z.string().min(3).max(128)));
242
199
  this.mount('id', createValidator(z.string().uuid()));
243
- this.mount('realmId', createValidator(z.string().uuid().optional()));
244
- this.mount('realmName', createValidator(z.string().min(3).max(128).optional()));
245
- }
246
- constructor(options = {}){
247
- super(options);
248
- this.mountAll();
200
+ this.mount('clientId', createValidator(z.string().uuid().or(z.null()).or(z.undefined()).optional()));
201
+ this.mount('realmId', createValidator(z.string().uuid().or(z.null()).or(z.undefined()).optional()));
202
+ this.mount('realmName', createValidator(z.string().min(3).max(128).or(z.null()).or(z.undefined()).optional()));
249
203
  }
250
204
  }
251
205
 
252
206
  class PolicyDataPermissionValidator extends Container {
253
- mountAll() {
207
+ initialize() {
208
+ super.initialize();
254
209
  this.mount('name', createValidator(z.string().min(3).max(256)));
255
- this.mount('realm_id', createValidator(z.string().uuid().optional()));
210
+ this.mount('clientId', createValidator(z.string().uuid().or(z.null()).or(z.undefined()).optional()));
211
+ this.mount('realmId', createValidator(z.string().uuid().or(z.null()).or(z.undefined()).optional()));
256
212
  this.mount('policy', createValidator(z.object({
257
213
  type: z.string()
258
214
  }).optional()));
259
215
  }
260
- constructor(options = {}){
261
- super(options);
262
- this.mountAll();
263
- }
264
216
  }
265
217
 
266
218
  class PolicyDataValidator extends Container {
267
- mountAll() {
219
+ initialize() {
220
+ super.initialize();
268
221
  // todo: optionalValue should be null
269
222
  const identity = new PolicyDataIdentityValidator();
270
223
  this.mount('identity', {
@@ -282,10 +235,6 @@ class PolicyDataValidator extends Container {
282
235
  this.mount('attributes', createValidator(z.object({}).optional()));
283
236
  this.mount('dateTime', createValidator(z.date().or(z.string()).or(z.number()).optional()));
284
237
  }
285
- constructor(options = {}){
286
- super(options);
287
- this.mountAll();
288
- }
289
238
  }
290
239
 
291
240
  async function evaluatePolicy(ctx) {
@@ -335,16 +284,13 @@ function isCompositePolicy(input) {
335
284
  }
336
285
 
337
286
  class CompositePolicyValidator extends Container {
338
- mountAll() {
339
- this.mount('decisionStrategy', createValidator(z.nativeEnum(DecisionStrategy).optional()));
287
+ initialize() {
288
+ super.initialize();
289
+ this.mount('decisionStrategy', createValidator(z.nativeEnum(DecisionStrategy).or(z.null()).or(z.undefined()).optional()));
340
290
  this.mount('children', createValidator(z.array(z.object({
341
291
  type: z.string().min(3)
342
292
  }).passthrough())));
343
- this.mount('invert', createValidator(z.boolean().optional()));
344
- }
345
- constructor(options = {}){
346
- super(options);
347
- this.mountAll();
293
+ this.mount('invert', createValidator(z.boolean().or(z.null()).or(z.undefined()).optional()));
348
294
  }
349
295
  }
350
296
 
@@ -395,14 +341,11 @@ class CompositePolicyEvaluator {
395
341
  }
396
342
 
397
343
  class DatePolicyValidator extends Container {
398
- mountAll() {
399
- this.mount('start', createValidator(z.date().or(z.string()).or(z.number()).optional()));
400
- this.mount('end', createValidator(z.date().or(z.string()).or(z.number()).optional()));
401
- this.mount('invert', createValidator(z.boolean().optional()));
402
- }
403
- constructor(options = {}){
404
- super(options);
405
- this.mountAll();
344
+ initialize() {
345
+ super.initialize();
346
+ this.mount('start', createValidator(z.date().or(z.string().date()).or(z.number()).or(z.null()).or(z.undefined()).optional()));
347
+ this.mount('end', createValidator(z.date().or(z.string().date()).or(z.number()).or(z.null()).or(z.undefined()).optional()));
348
+ this.mount('invert', createValidator(z.boolean().or(z.undefined()).or(z.null()).optional()));
406
349
  }
407
350
  }
408
351
 
@@ -456,8 +399,8 @@ class DatePolicyEvaluator {
456
399
 
457
400
  class IdentityPolicyValidator extends Container {
458
401
  initialize() {
459
- this.mount('types', createValidator(z.array(z.string()).optional()));
460
- this.mount('invert', createValidator(z.boolean().optional()));
402
+ this.mount('types', createValidator(z.array(z.string()).or(z.null()).or(z.undefined()).optional()));
403
+ this.mount('invert', createValidator(z.boolean().or(z.null()).or(z.undefined()).optional()));
461
404
  }
462
405
  }
463
406
 
@@ -514,17 +457,14 @@ class PermissionBindingPolicyEvaluator {
514
457
  }
515
458
 
516
459
  class RealmMatchPolicyValidator extends Container {
517
- mountAll() {
518
- this.mount('decisionStrategy', createValidator(z.nativeEnum(DecisionStrategy).optional()));
519
- this.mount('attributeName', createValidator(z.string().min(3).or(z.array(z.string().min(3))).optional()));
520
- this.mount('attributeNameStrict', createValidator(z.boolean().optional()));
521
- this.mount('attributeNullMatchAll', createValidator(z.boolean().optional()));
522
- this.mount('identityMasterMatchAll', createValidator(z.boolean().optional()));
523
- this.mount('invert', createValidator(z.boolean().optional()));
524
- }
525
- constructor(options = {}){
526
- super(options);
527
- this.mountAll();
460
+ initialize() {
461
+ super.initialize();
462
+ this.mount('decisionStrategy', createValidator(z.nativeEnum(DecisionStrategy).or(z.null()).or(z.undefined()).optional()));
463
+ this.mount('attributeName', createValidator(z.string().min(3).or(z.array(z.string().min(3))).or(z.null()).or(z.undefined()).optional()));
464
+ this.mount('attributeNameStrict', createValidator(z.boolean().or(z.null()).or(z.undefined()).optional()));
465
+ this.mount('attributeNullMatchAll', createValidator(z.boolean().or(z.null()).or(z.undefined()).optional()));
466
+ this.mount('identityMasterMatchAll', createValidator(z.boolean().or(z.null()).or(z.undefined()).optional()));
467
+ this.mount('invert', createValidator(z.boolean().or(z.null()).or(z.undefined()).optional()));
528
468
  }
529
469
  }
530
470
 
@@ -631,23 +571,30 @@ class RealmMatchPolicyEvaluator {
631
571
  return TimePolicyInterval;
632
572
  }({});
633
573
 
574
+ function isIntervalForDayOfWeek(interval) {
575
+ return interval === TimePolicyInterval.WEEKLY || interval === TimePolicyInterval.MONTHLY || interval === TimePolicyInterval.YEARLY;
576
+ }
577
+ function isIntervalForDayOfMonth(interval) {
578
+ return interval === TimePolicyInterval.MONTHLY || interval === TimePolicyInterval.YEARLY;
579
+ }
580
+ function isIntervalForDayOfYear(interval) {
581
+ return interval === TimePolicyInterval.YEARLY;
582
+ }
583
+
634
584
  class TimePolicyValidator extends Container {
635
- mountAll() {
636
- this.mount('dayOfWeek', createValidator(z.number().min(0).max(6).optional()));
637
- this.mount('dayOfMonth', createValidator(z.number().min(1).max(31).optional()));
638
- this.mount('dayOfYear', createValidator(z.number().min(1).max(366).optional()));
639
- this.mount('start', createValidator(z.date().or(z.string()).or(z.number()).optional()));
640
- this.mount('end', createValidator(z.date().or(z.string()).or(z.number()).optional()));
641
- this.mount('interval', createValidator(z.nativeEnum(TimePolicyInterval).optional()));
642
- this.mount('invert', createValidator(z.boolean().optional()));
643
- }
644
- constructor(options = {}){
645
- super(options);
646
- this.mountAll();
585
+ initialize() {
586
+ super.initialize();
587
+ this.mount('dayOfWeek', createValidator(z.number().min(0).max(6).or(z.null()).or(z.undefined()).optional()));
588
+ this.mount('dayOfMonth', createValidator(z.number().min(1).max(31).or(z.null()).or(z.undefined()).optional()));
589
+ this.mount('dayOfYear', createValidator(z.number().min(1).max(366).or(z.null()).or(z.undefined()).optional()));
590
+ this.mount('start', createValidator(z.date().or(z.string().datetime()).or(z.string().time()).or(z.number()).or(z.null()).or(z.undefined()).optional()));
591
+ this.mount('end', createValidator(z.date().or(z.string().datetime()).or(z.string().time()).or(z.number()).or(z.null()).or(z.undefined()).optional()));
592
+ this.mount('interval', createValidator(z.nativeEnum(TimePolicyInterval).or(z.null()).or(z.undefined()).optional()));
593
+ this.mount('invert', createValidator(z.boolean().or(z.undefined()).or(z.null()).optional()));
647
594
  }
648
595
  }
649
596
 
650
- const timeRegex = /^(?:[01]\d|2[0-3]):[0-5]\d$/;
597
+ const timeRegex = /^(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d)?$/;
651
598
  function normalizeDate(input, dateRef) {
652
599
  const date = dateRef ? new Date(dateRef) : new Date();
653
600
  date.setHours(input.getHours(), input.getMinutes());
@@ -697,23 +644,25 @@ class TimePolicyEvaluator {
697
644
  return maybeInvertPolicyOutcome(false, ctx.spec.invert);
698
645
  }
699
646
  }
700
- if (ctx.spec.dayOfWeek) {
701
- if (now.getDay() !== ctx.spec.dayOfWeek) {
702
- return maybeInvertPolicyOutcome(false, ctx.spec.invert);
647
+ if (ctx.spec.interval) {
648
+ if (isIntervalForDayOfWeek(ctx.spec.interval) && ctx.spec.dayOfWeek) {
649
+ if (now.getDay() !== ctx.spec.dayOfWeek) {
650
+ return maybeInvertPolicyOutcome(false, ctx.spec.invert);
651
+ }
703
652
  }
704
- }
705
- if (ctx.spec.dayOfMonth) {
706
- if (now.getDate() !== ctx.spec.dayOfMonth) {
707
- return maybeInvertPolicyOutcome(false, ctx.spec.invert);
653
+ if (isIntervalForDayOfMonth(ctx.spec.interval) && ctx.spec.dayOfMonth) {
654
+ if (now.getDate() !== ctx.spec.dayOfMonth) {
655
+ return maybeInvertPolicyOutcome(false, ctx.spec.invert);
656
+ }
708
657
  }
709
- }
710
- if (ctx.spec.dayOfYear) {
711
- const start = new Date(now.getFullYear(), 0, 0);
712
- const diff = now.getTime() - start.getTime() + (start.getTimezoneOffset() - now.getTimezoneOffset()) * 60 * 1000;
713
- const oneDay = 1000 * 60 * 60 * 24;
714
- const dayOfYear = Math.floor(diff / oneDay);
715
- if (dayOfYear !== ctx.spec.dayOfYear) {
716
- return maybeInvertPolicyOutcome(false, ctx.spec.invert);
658
+ if (isIntervalForDayOfYear(ctx.spec.interval) && ctx.spec.dayOfYear) {
659
+ const start = new Date(now.getFullYear(), 0, 0);
660
+ const diff = now.getTime() - start.getTime() + (start.getTimezoneOffset() - now.getTimezoneOffset()) * 60 * 1000;
661
+ const oneDay = 1000 * 60 * 60 * 24;
662
+ const dayOfYear = Math.floor(diff / oneDay);
663
+ if (dayOfYear !== ctx.spec.dayOfYear) {
664
+ return maybeInvertPolicyOutcome(false, ctx.spec.invert);
665
+ }
717
666
  }
718
667
  }
719
668
  return maybeInvertPolicyOutcome(true, ctx.spec.invert);
@@ -723,6 +672,18 @@ class TimePolicyEvaluator {
723
672
  }
724
673
  }
725
674
 
675
+ /*
676
+ * Copyright (c) 2025.
677
+ * Author Peter Placzek (tada5hi)
678
+ * For the full copyright and license information,
679
+ * view the LICENSE file that was distributed with this source code.
680
+ */ function definePolicyWithType(type, data) {
681
+ return {
682
+ ...data,
683
+ type
684
+ };
685
+ }
686
+
726
687
  /**
727
688
  * The policy engine is a component that interprets defined policies and makes decisions
728
689
  * on whether to allow or deny a particular access.
@@ -764,9 +725,80 @@ class TimePolicyEvaluator {
764
725
  }
765
726
  }
766
727
 
728
+ class PermissionError extends AuthupError {
729
+ static notFound(name) {
730
+ return new PermissionError({
731
+ message: `The permission ${name} was not found.`,
732
+ code: ErrorCode.PERMISSION_NOT_FOUND
733
+ });
734
+ }
735
+ static denied(name) {
736
+ return new PermissionError({
737
+ message: `The permission ${name} has not been granted.`,
738
+ code: ErrorCode.PERMISSION_DENIED
739
+ });
740
+ }
741
+ static deniedAll(names) {
742
+ return new PermissionError({
743
+ message: `None of the permissions ${names.join(', ')} has been granted.`,
744
+ code: ErrorCode.PERMISSION_DENIED
745
+ });
746
+ }
747
+ static evaluationFailed(options) {
748
+ const error = new PermissionError({
749
+ message: `The evaluation of permission ${options.name} failed.`,
750
+ code: ErrorCode.PERMISSION_EVALUATION_FAILED
751
+ });
752
+ if (options.policy) {
753
+ error.policy = options.policy;
754
+ if (options.policy.type === BuiltInPolicyType.IDENTITY) {
755
+ error.statusCode = 401;
756
+ }
757
+ }
758
+ if (options.policyError) {
759
+ error.policyError = options.policyError;
760
+ }
761
+ return error;
762
+ }
763
+ constructor(options = {}){
764
+ super({
765
+ ...options,
766
+ message: options.message || 'A permission error occurred.',
767
+ statusCode: options.statusCode || 403
768
+ });
769
+ }
770
+ }
771
+
772
+ /*
773
+ * Copyright (c) 2025.
774
+ * Author Peter Placzek (tada5hi)
775
+ * For the full copyright and license information,
776
+ * view the LICENSE file that was distributed with this source code.
777
+ */ function buildPermissionItemKey(input) {
778
+ return `${input.realmId || '_'}/${input.clientId || '_'}/${input.name}`;
779
+ }
780
+
781
+ /*
782
+ * Copyright (c) 2024-2024.
783
+ * Author Peter Placzek (tada5hi)
784
+ * For the full copyright and license information,
785
+ * view the LICENSE file that was distributed with this source code.
786
+ */ function isPermissionItemEqual(a, b) {
787
+ if (a.name !== b.name) {
788
+ return false;
789
+ }
790
+ if (typeof a.realmId === 'string' || typeof b.realmId === 'string') {
791
+ return a.realmId === b.realmId;
792
+ }
793
+ if (typeof a.clientId === 'string' || typeof b.clientId === 'string') {
794
+ return a.clientId === b.clientId;
795
+ }
796
+ return !!a.realmId === !!b.realmId && !!a.clientId === !!b.clientId;
797
+ }
798
+
767
799
  function mergePermissionItems(input) {
768
800
  const grouped = input.reduce((previous, current)=>{
769
- const key = current.realm_id || `/${current.name}`;
801
+ const key = buildPermissionItemKey(current);
770
802
  if (!previous[key]) {
771
803
  previous[key] = [];
772
804
  }
@@ -797,11 +829,11 @@ function mergePermissionItems(input) {
797
829
 
798
830
  class PermissionMemoryProvider {
799
831
  async get(options) {
800
- return this.items[`${options.realmId || '/'}:${options.name}`];
832
+ return this.items[buildPermissionItemKey(options)];
801
833
  }
802
834
  setMany(input) {
803
835
  this.items = mergePermissionItems(input).reduce((prev, current)=>{
804
- prev[`${current.realm_id || '/'}:${current.name}`] = current;
836
+ prev[buildPermissionItemKey(current)] = current;
805
837
  return prev;
806
838
  }, {});
807
839
  }
@@ -821,7 +853,10 @@ class PermissionChecker {
821
853
  const options = {
822
854
  name: input
823
855
  };
824
- if (typeof this.realmId !== 'undefined') {
856
+ if (this.clientId) {
857
+ options.clientId = this.clientId;
858
+ }
859
+ if (this.realmId) {
825
860
  options.realmId = this.realmId;
826
861
  }
827
862
  return this.provider.get(options);
@@ -850,7 +885,11 @@ class PermissionChecker {
850
885
  for(let i = 0; i < ctx.name.length; i++){
851
886
  const entity = await this.get(ctx.name[i]);
852
887
  if (!entity) {
853
- throw PermissionError.notFound(ctx.name[i]);
888
+ lastError = PermissionError.notFound(ctx.name[i]);
889
+ if (decisionStrategy === DecisionStrategy.UNANIMOUS) {
890
+ throw lastError;
891
+ }
892
+ continue;
854
893
  }
855
894
  if (!entity.policy) {
856
895
  if (decisionStrategy === DecisionStrategy.AFFIRMATIVE) {
@@ -959,6 +998,9 @@ class PermissionChecker {
959
998
  } else {
960
999
  this.provider = new PermissionMemoryProvider();
961
1000
  }
1001
+ if (options.clientId) {
1002
+ this.clientId = options.clientId;
1003
+ }
962
1004
  if (options.realmId) {
963
1005
  this.realmId = options.realmId;
964
1006
  }
@@ -970,5 +1012,5 @@ class PermissionChecker {
970
1012
  }
971
1013
  }
972
1014
 
973
- export { AttributeNamesPolicyEvaluator, AttributeNamesPolicyValidator, AttributesPolicyEvaluator, AttributesPolicyValidator, BuiltInPolicyType, CompositePolicyEvaluator, CompositePolicyValidator, DatePolicyEvaluator, DatePolicyValidator, DecisionStrategy, IdentityPolicyEvaluator, IdentityPolicyValidator, PermissionBindingPolicyEvaluator, PermissionBindingPolicyValidator, PermissionChecker, PermissionError, PermissionMemoryProvider, PolicyDataIdentityValidator, PolicyDataPermissionValidator, PolicyDataValidator, PolicyEngine, PolicyError, RealmMatchPolicyEvaluator, RealmMatchPolicyValidator, TimePolicyEvaluator, TimePolicyInterval, TimePolicyValidator, evaluatePolicy, isCompositePolicy, isPermissionItemEqual, maybeInvertPolicyOutcome, mergePermissionItems };
1015
+ export { AttributeNamesPolicyEvaluator, AttributeNamesPolicyValidator, AttributesPolicyEvaluator, AttributesPolicyValidator, BuiltInPolicyType, CompositePolicyEvaluator, CompositePolicyValidator, DatePolicyEvaluator, DatePolicyValidator, DecisionStrategy, IdentityPolicyEvaluator, IdentityPolicyValidator, PermissionBindingPolicyEvaluator, PermissionBindingPolicyValidator, PermissionChecker, PermissionError, PermissionMemoryProvider, PolicyDataIdentityValidator, PolicyDataPermissionValidator, PolicyDataValidator, PolicyEngine, PolicyError, RealmMatchPolicyEvaluator, RealmMatchPolicyValidator, TimePolicyEvaluator, TimePolicyInterval, TimePolicyValidator, buildPermissionItemKey, defineAttributesPolicy, definePolicyWithType, evaluatePolicy, isCompositePolicy, isIntervalForDayOfMonth, isIntervalForDayOfWeek, isIntervalForDayOfYear, isPermissionItemEqual, maybeInvertPolicyOutcome, mergePermissionItems };
974
1016
  //# sourceMappingURL=index.mjs.map