@authup/access 1.0.0-beta.26 → 1.0.0-beta.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 (37) hide show
  1. package/LICENSE +201 -201
  2. package/dist/index.mjs +233 -210
  3. package/dist/index.mjs.map +1 -1
  4. package/dist/permission/module.d.ts +2 -2
  5. package/dist/permission/module.d.ts.map +1 -1
  6. package/dist/permission/provider/memory.d.ts +2 -2
  7. package/dist/permission/provider/memory.d.ts.map +1 -1
  8. package/dist/permission/provider/types.d.ts +1 -1
  9. package/dist/permission/provider/types.d.ts.map +1 -1
  10. package/dist/permission/types.d.ts +4 -4
  11. package/dist/permission/types.d.ts.map +1 -1
  12. package/dist/policy/built-in/attribute-names/evaluator.d.ts +4 -4
  13. package/dist/policy/built-in/attribute-names/evaluator.d.ts.map +1 -1
  14. package/dist/policy/built-in/attributes/evaluator.d.ts +4 -4
  15. package/dist/policy/built-in/attributes/evaluator.d.ts.map +1 -1
  16. package/dist/policy/built-in/composite/evaluator.d.ts +3 -3
  17. package/dist/policy/built-in/composite/evaluator.d.ts.map +1 -1
  18. package/dist/policy/built-in/date/evaluator.d.ts +3 -3
  19. package/dist/policy/built-in/date/evaluator.d.ts.map +1 -1
  20. package/dist/policy/built-in/identity/evaluator.d.ts +3 -3
  21. package/dist/policy/built-in/identity/evaluator.d.ts.map +1 -1
  22. package/dist/policy/built-in/permission-binding/module.d.ts +4 -4
  23. package/dist/policy/built-in/permission-binding/module.d.ts.map +1 -1
  24. package/dist/policy/built-in/realm-match/evaluator.d.ts +3 -3
  25. package/dist/policy/built-in/realm-match/evaluator.d.ts.map +1 -1
  26. package/dist/policy/built-in/time/evaluator.d.ts +3 -3
  27. package/dist/policy/built-in/time/evaluator.d.ts.map +1 -1
  28. package/dist/policy/error/module.d.ts +2 -2
  29. package/dist/policy/evaluator/data/validator.d.ts +2 -2
  30. package/dist/policy/evaluator/data/validator.d.ts.map +1 -1
  31. package/dist/policy/evaluator/types.d.ts +11 -11
  32. package/dist/policy/evaluator/types.d.ts.map +1 -1
  33. package/dist/policy/types.d.ts +1 -1
  34. package/dist/policy/types.d.ts.map +1 -1
  35. package/package.json +16 -13
  36. package/dist/index.cjs +0 -1055
  37. package/dist/index.cjs.map +0 -1
package/dist/index.mjs CHANGED
@@ -6,20 +6,20 @@ import { z } from 'zod';
6
6
  import { guard } from '@ucast/mongo2js';
7
7
 
8
8
  class PolicyError extends AuthupError {
9
+ constructor(message, code){
10
+ super({
11
+ message,
12
+ code
13
+ });
14
+ }
9
15
  static evaluatorNotFound(type) {
10
16
  return new PolicyError(`No evaluator is registered to handle the policy: ${type}`, ErrorCode.POLICY_EVALUATOR_NOT_FOUND);
11
17
  }
12
18
  static evaluatorNotProcessable() {
13
- throw new PolicyError('The evaluator can not process the policy.', ErrorCode.POLICY_EVALUATOR_NOT_PROCESSABLE);
19
+ return new PolicyError('The evaluator can not process the policy.', ErrorCode.POLICY_EVALUATOR_NOT_PROCESSABLE);
14
20
  }
15
21
  static evaluatorContextInvalid() {
16
- throw new PolicyError('The evaluator context is not valid.', ErrorCode.POLICY_EVALUATOR_CONTEXT_INVALID);
17
- }
18
- constructor(message, code){
19
- super({
20
- message,
21
- code
22
- });
22
+ return new PolicyError('The evaluator context is not valid.', ErrorCode.POLICY_EVALUATOR_CONTEXT_INVALID);
23
23
  }
24
24
  }
25
25
 
@@ -83,34 +83,35 @@ class AttributeNamesPolicyValidator extends Container {
83
83
  }
84
84
 
85
85
  class AttributeNamesPolicyEvaluator {
86
+ validator;
87
+ constructor(){
88
+ this.validator = new AttributeNamesPolicyValidator();
89
+ }
86
90
  async can(ctx) {
87
- return ctx.spec.type === BuiltInPolicyType.ATTRIBUTE_NAMES;
91
+ return ctx.config.type === BuiltInPolicyType.ATTRIBUTE_NAMES;
88
92
  }
89
- async validateSpecification(ctx) {
90
- return this.validator.run(ctx.spec);
93
+ async validateConfig(ctx) {
94
+ return this.validator.run(ctx.config);
91
95
  }
92
- async validateData(ctx) {
93
- if (!isObject(ctx.data.attributes)) {
96
+ async validateInput(ctx) {
97
+ if (!isObject(ctx.input.attributes)) {
94
98
  throw PolicyError.evaluatorContextInvalid();
95
99
  }
96
- return ctx.data;
100
+ return ctx.input;
97
101
  }
98
102
  async evaluate(ctx) {
99
- if (!ctx.data.attributes) {
103
+ if (!ctx.input.attributes) {
100
104
  throw PolicyError.evaluatorContextInvalid();
101
105
  }
102
- const attributes = flattenObject(ctx.data.attributes);
106
+ const attributes = flattenObject(ctx.input.attributes);
103
107
  const keys = Object.keys(attributes);
104
108
  for(let i = 0; i < keys.length; i++){
105
- const index = ctx.spec.names.indexOf(keys[i]);
109
+ const index = ctx.config.names.indexOf(keys[i]);
106
110
  if (index === -1) {
107
- return maybeInvertPolicyOutcome(false, ctx.spec.invert);
111
+ return maybeInvertPolicyOutcome(false, ctx.config.invert);
108
112
  }
109
113
  }
110
- return maybeInvertPolicyOutcome(true, ctx.spec.invert);
111
- }
112
- constructor(){
113
- this.validator = new AttributeNamesPolicyValidator();
114
+ return maybeInvertPolicyOutcome(true, ctx.config.invert);
114
115
  }
115
116
  }
116
117
 
@@ -132,46 +133,55 @@ class AttributesPolicyValidator extends Container {
132
133
  }
133
134
 
134
135
  class AttributesPolicyEvaluator {
136
+ validator;
137
+ constructor(){
138
+ this.validator = new AttributesPolicyValidator();
139
+ }
135
140
  async can(ctx) {
136
- return ctx.spec.type === BuiltInPolicyType.ATTRIBUTES;
141
+ return ctx.config.type === BuiltInPolicyType.ATTRIBUTES;
137
142
  }
138
- async validateSpecification(ctx) {
139
- return this.validator.run(ctx.spec);
143
+ async validateConfig(ctx) {
144
+ return this.validator.run(ctx.config);
140
145
  }
141
- async validateData(ctx) {
142
- if (!isObject(ctx.data.attributes)) {
146
+ async validateInput(ctx) {
147
+ if (!isObject(ctx.input.attributes)) {
143
148
  throw PolicyError.evaluatorContextInvalid();
144
149
  }
145
- return ctx.data;
150
+ return ctx.input;
146
151
  }
147
152
  async evaluate(ctx) {
148
- if (!ctx.data.attributes) {
153
+ if (!ctx.input.attributes) {
149
154
  throw PolicyError.evaluatorContextInvalid();
150
155
  }
151
- this.fixQuery(ctx.spec.query);
152
- const testIt = guard(ctx.spec.query);
153
- return maybeInvertPolicyOutcome(testIt(ctx.data.attributes), ctx.spec.invert);
156
+ this.fixQuery(ctx.config.query);
157
+ const testIt = guard(ctx.config.query);
158
+ return maybeInvertPolicyOutcome(testIt(ctx.input.attributes), ctx.config.invert);
154
159
  }
155
160
  fixQuery(query) {
156
- const keys = Object.keys(query);
157
- for(let i = 0; i < keys.length; i++){
158
- const key = keys[i];
159
- const value = query[key];
160
- if (isObject(value) || Array.isArray(value)) {
161
- this.fixQuery(value);
162
- continue;
161
+ if (Array.isArray(query)) {
162
+ for(let i = 0; i < query.length; i++){
163
+ this.fixQuery(query[i]);
163
164
  }
164
- if (key === '$regex' && typeof value === 'string') {
165
- const fragments = value.match(/\/(.*?)\/([a-z]*)?$/i);
166
- if (fragments) {
167
- query[key] = new RegExp(fragments[1], fragments[2]);
165
+ return;
166
+ }
167
+ if (isObject(query)) {
168
+ const keys = Object.keys(query);
169
+ for(let i = 0; i < keys.length; i++){
170
+ const key = keys[i];
171
+ const value = query[key];
172
+ if (isObject(value) || Array.isArray(value)) {
173
+ this.fixQuery(value);
174
+ continue;
175
+ }
176
+ if (key === '$regex' && typeof value === 'string') {
177
+ const fragments = value.match(/\/(.*?)\/([a-z]*)?$/i);
178
+ if (fragments) {
179
+ query[key] = new RegExp(fragments[1], fragments[2]);
180
+ }
168
181
  }
169
182
  }
170
183
  }
171
184
  }
172
- constructor(){
173
- this.validator = new AttributesPolicyValidator();
174
- }
175
185
  }
176
186
 
177
187
  /*
@@ -238,31 +248,31 @@ class PolicyDataValidator extends Container {
238
248
  }
239
249
 
240
250
  async function evaluatePolicy(ctx) {
241
- if (ctx.options.exclude && ctx.options.exclude.length > 0 && ctx.options.exclude.indexOf(ctx.spec.type) !== -1) {
242
- if (typeof ctx.spec.invert === 'boolean') {
243
- return maybeInvertPolicyOutcome(true, ctx.spec.invert);
251
+ if (ctx.options.exclude && ctx.options.exclude.length > 0 && ctx.options.exclude.indexOf(ctx.config.type) !== -1) {
252
+ if (typeof ctx.config.invert === 'boolean') {
253
+ return maybeInvertPolicyOutcome(true, ctx.config.invert);
244
254
  }
245
255
  return true;
246
256
  }
247
- if (ctx.options.include && ctx.options.include.length > 0 && ctx.options.include.indexOf(ctx.spec.type) === -1) {
248
- if (typeof ctx.spec.invert === 'boolean') {
249
- return maybeInvertPolicyOutcome(true, ctx.spec.invert);
257
+ if (ctx.options.include && ctx.options.include.length > 0 && ctx.options.include.indexOf(ctx.config.type) === -1) {
258
+ if (typeof ctx.config.invert === 'boolean') {
259
+ return maybeInvertPolicyOutcome(true, ctx.config.invert);
250
260
  }
251
261
  return true;
252
262
  }
253
- const evaluator = ctx.evaluators[ctx.spec.type];
263
+ const evaluator = ctx.evaluators[ctx.config.type];
254
264
  if (!evaluator) {
255
- throw PolicyError.evaluatorNotFound(ctx.spec.type);
265
+ throw PolicyError.evaluatorNotFound(ctx.config.type);
256
266
  }
257
267
  try {
258
268
  const canEvaluate = await evaluator.can(ctx);
259
269
  if (canEvaluate) {
260
- const spec = await evaluator.validateSpecification(ctx);
261
- const data = await evaluator.validateData(ctx);
270
+ const config = await evaluator.validateConfig(ctx);
271
+ const input = await evaluator.validateInput(ctx);
262
272
  return await evaluator.evaluate({
263
273
  ...ctx,
264
- data,
265
- spec
274
+ input,
275
+ config
266
276
  });
267
277
  }
268
278
  } catch (e) {
@@ -295,48 +305,49 @@ class CompositePolicyValidator extends Container {
295
305
  }
296
306
 
297
307
  class CompositePolicyEvaluator {
308
+ validator;
309
+ constructor(){
310
+ this.validator = new CompositePolicyValidator();
311
+ }
298
312
  async can(ctx) {
299
- return isCompositePolicy(ctx.spec);
313
+ return isCompositePolicy(ctx.config);
300
314
  }
301
- async validateSpecification(ctx) {
302
- return this.validator.run(ctx.spec);
315
+ async validateConfig(ctx) {
316
+ return this.validator.run(ctx.config);
303
317
  }
304
- async validateData(ctx) {
305
- return ctx.data;
318
+ async validateInput(ctx) {
319
+ return ctx.input;
306
320
  }
307
321
  async evaluate(ctx) {
308
322
  let count = 0;
309
- const decisionStrategy = ctx.spec.decisionStrategy ?? DecisionStrategy.UNANIMOUS;
310
- for(let i = 0; i < ctx.spec.children.length; i++){
311
- const childPolicy = ctx.spec.children[i];
323
+ const decisionStrategy = ctx.config.decisionStrategy ?? DecisionStrategy.UNANIMOUS;
324
+ for(let i = 0; i < ctx.config.children.length; i++){
325
+ const childPolicy = ctx.config.children[i];
312
326
  let outcome;
313
327
  if (isCompositePolicy(childPolicy)) {
314
328
  outcome = await this.evaluate({
315
329
  ...ctx,
316
- spec: childPolicy
330
+ config: childPolicy
317
331
  });
318
332
  } else {
319
333
  outcome = await evaluatePolicy({
320
334
  ...ctx,
321
- spec: childPolicy
335
+ config: childPolicy
322
336
  });
323
337
  }
324
338
  if (outcome) {
325
339
  if (decisionStrategy === DecisionStrategy.AFFIRMATIVE) {
326
- return maybeInvertPolicyOutcome(true, ctx.spec.invert);
340
+ return maybeInvertPolicyOutcome(true, ctx.config.invert);
327
341
  }
328
342
  count++;
329
343
  } else {
330
344
  if (decisionStrategy === DecisionStrategy.UNANIMOUS) {
331
- return maybeInvertPolicyOutcome(false, ctx.spec.invert);
345
+ return maybeInvertPolicyOutcome(false, ctx.config.invert);
332
346
  }
333
347
  count--;
334
348
  }
335
349
  }
336
- return maybeInvertPolicyOutcome(count > 0, ctx.spec.invert);
337
- }
338
- constructor(){
339
- this.validator = new CompositePolicyValidator();
350
+ return maybeInvertPolicyOutcome(count > 0, ctx.config.invert);
340
351
  }
341
352
  }
342
353
 
@@ -362,38 +373,39 @@ function toDate$1(input) {
362
373
  return input;
363
374
  }
364
375
  class DatePolicyEvaluator {
376
+ validator;
377
+ constructor(){
378
+ this.validator = new DatePolicyValidator();
379
+ }
365
380
  async can(ctx) {
366
- return ctx.spec.type === BuiltInPolicyType.DATE;
381
+ return ctx.config.type === BuiltInPolicyType.DATE;
367
382
  }
368
- async validateSpecification(ctx) {
369
- return this.validator.run(ctx.spec);
383
+ async validateConfig(ctx) {
384
+ return this.validator.run(ctx.config);
370
385
  }
371
- async validateData(ctx) {
372
- return ctx.data;
386
+ async validateInput(ctx) {
387
+ return ctx.input;
373
388
  }
374
389
  async evaluate(ctx) {
375
390
  let now;
376
- if (ctx.data.dateTime) {
377
- now = normalizeDate$1(toDate$1(ctx.data.dateTime));
391
+ if (ctx.input.dateTime) {
392
+ now = normalizeDate$1(toDate$1(ctx.input.dateTime));
378
393
  } else {
379
394
  now = normalizeDate$1(new Date());
380
395
  }
381
- if (ctx.spec.start) {
382
- const start = normalizeDate$1(toDate$1(ctx.spec.start));
396
+ if (ctx.config.start) {
397
+ const start = normalizeDate$1(toDate$1(ctx.config.start));
383
398
  if (now < start) {
384
- return maybeInvertPolicyOutcome(false, ctx.spec.invert);
399
+ return maybeInvertPolicyOutcome(false, ctx.config.invert);
385
400
  }
386
401
  }
387
- if (ctx.spec.end) {
388
- const end = normalizeDate$1(toDate$1(ctx.spec.end));
402
+ if (ctx.config.end) {
403
+ const end = normalizeDate$1(toDate$1(ctx.config.end));
389
404
  if (now > end) {
390
- return maybeInvertPolicyOutcome(false, ctx.spec.invert);
405
+ return maybeInvertPolicyOutcome(false, ctx.config.invert);
391
406
  }
392
407
  }
393
- return maybeInvertPolicyOutcome(true, ctx.spec.invert);
394
- }
395
- constructor(){
396
- this.validator = new DatePolicyValidator();
408
+ return maybeInvertPolicyOutcome(true, ctx.config.invert);
397
409
  }
398
410
  }
399
411
 
@@ -405,28 +417,29 @@ class IdentityPolicyValidator extends Container {
405
417
  }
406
418
 
407
419
  class IdentityPolicyEvaluator {
420
+ validator;
421
+ constructor(){
422
+ this.validator = new IdentityPolicyValidator();
423
+ }
408
424
  async can(ctx) {
409
- return ctx.spec.type === BuiltInPolicyType.IDENTITY;
425
+ return ctx.config.type === BuiltInPolicyType.IDENTITY;
410
426
  }
411
- async validateSpecification(ctx) {
412
- return this.validator.run(ctx.spec);
427
+ async validateConfig(ctx) {
428
+ return this.validator.run(ctx.config);
413
429
  }
414
- async validateData(ctx) {
415
- return ctx.data;
430
+ async validateInput(ctx) {
431
+ return ctx.input;
416
432
  }
417
433
  async evaluate(ctx) {
418
- if (!isObject(ctx.data.identity)) {
419
- return maybeInvertPolicyOutcome(false, ctx.spec.invert);
434
+ if (!isObject(ctx.input.identity)) {
435
+ return maybeInvertPolicyOutcome(false, ctx.config.invert);
420
436
  }
421
- const types = ctx.spec.types || [];
437
+ const types = ctx.config.types || [];
422
438
  if (types.length === 0) {
423
- return maybeInvertPolicyOutcome(true, ctx.spec.invert);
439
+ return maybeInvertPolicyOutcome(true, ctx.config.invert);
424
440
  }
425
- const typeAllowed = types.indexOf(ctx.data.identity.type) !== -1;
426
- return maybeInvertPolicyOutcome(typeAllowed, ctx.spec.invert);
427
- }
428
- constructor(){
429
- this.validator = new IdentityPolicyValidator();
441
+ const typeAllowed = types.indexOf(ctx.input.identity.type) !== -1;
442
+ return maybeInvertPolicyOutcome(typeAllowed, ctx.config.invert);
430
443
  }
431
444
  }
432
445
 
@@ -435,24 +448,25 @@ class PermissionBindingPolicyValidator extends Container {
435
448
  }
436
449
 
437
450
  class PermissionBindingPolicyEvaluator {
451
+ validator;
452
+ constructor(){
453
+ this.validator = new PermissionBindingPolicyValidator();
454
+ }
438
455
  async can(ctx) {
439
- return ctx.spec.type === BuiltInPolicyType.PERMISSION_BINDING;
456
+ return ctx.config.type === BuiltInPolicyType.PERMISSION_BINDING;
440
457
  }
441
- async validateSpecification(ctx) {
442
- return this.validator.run(ctx.spec);
458
+ async validateConfig(ctx) {
459
+ return this.validator.run(ctx.config);
443
460
  }
444
- async validateData(ctx) {
445
- if (!isObject(ctx.data.identity) && !isObject(ctx.data.permission)) {
461
+ async validateInput(ctx) {
462
+ if (!isObject(ctx.input.identity) && !isObject(ctx.input.permission)) {
446
463
  throw PolicyError.evaluatorContextInvalid();
447
464
  }
448
- return ctx.data;
465
+ return ctx.input;
449
466
  }
450
467
  async evaluate(ctx) {
451
468
  // todo: this must be changed when the permission-checker not only checks owned permissions.
452
- return maybeInvertPolicyOutcome(true, ctx.spec.invert);
453
- }
454
- constructor(){
455
- this.validator = new PermissionBindingPolicyValidator();
469
+ return maybeInvertPolicyOutcome(true, ctx.config.invert);
456
470
  }
457
471
  }
458
472
 
@@ -469,33 +483,37 @@ class RealmMatchPolicyValidator extends Container {
469
483
  }
470
484
 
471
485
  class RealmMatchPolicyEvaluator {
486
+ validator;
487
+ constructor(){
488
+ this.validator = new RealmMatchPolicyValidator();
489
+ }
472
490
  async can(ctx) {
473
- return ctx.spec.type === BuiltInPolicyType.REALM_MATCH;
491
+ return ctx.config.type === BuiltInPolicyType.REALM_MATCH;
474
492
  }
475
- async validateSpecification(ctx) {
476
- return this.validator.run(ctx.spec);
493
+ async validateConfig(ctx) {
494
+ return this.validator.run(ctx.config);
477
495
  }
478
- async validateData(ctx) {
479
- if (!isObject(ctx.data.attributes) || !isObject(ctx.data.identity)) {
496
+ async validateInput(ctx) {
497
+ if (!isObject(ctx.input.attributes) || !isObject(ctx.input.identity)) {
480
498
  throw PolicyError.evaluatorContextInvalid();
481
499
  }
482
- return ctx.data;
500
+ return ctx.input;
483
501
  }
484
502
  async evaluate(ctx) {
485
- if (!ctx.data.attributes || !ctx.data.identity) {
503
+ if (!ctx.input.attributes || !ctx.input.identity) {
486
504
  throw PolicyError.evaluatorContextInvalid();
487
505
  }
488
- const identityMasterMatchAll = ctx.spec.identityMasterMatchAll ?? true;
489
- if (identityMasterMatchAll && ctx.data.identity.realmName && ctx.data.identity.realmName === 'master') {
490
- return maybeInvertPolicyOutcome(true, ctx.spec.invert);
506
+ const identityMasterMatchAll = ctx.config.identityMasterMatchAll ?? true;
507
+ if (identityMasterMatchAll && ctx.input.identity.realmName && ctx.input.identity.realmName === 'master') {
508
+ return maybeInvertPolicyOutcome(true, ctx.config.invert);
491
509
  }
492
510
  let keys;
493
- if (ctx.spec.attributeName) {
494
- if (Array.isArray(ctx.spec.attributeName)) {
495
- keys = ctx.spec.attributeName;
511
+ if (ctx.config.attributeName) {
512
+ if (Array.isArray(ctx.config.attributeName)) {
513
+ keys = ctx.config.attributeName;
496
514
  } else {
497
515
  keys = [
498
- ctx.spec.attributeName
516
+ ctx.config.attributeName
499
517
  ];
500
518
  }
501
519
  } else {
@@ -505,11 +523,11 @@ class RealmMatchPolicyEvaluator {
505
523
  'realmId',
506
524
  'realmName'
507
525
  ];
508
- ctx.spec.decisionStrategy = DecisionStrategy.CONSENSUS;
526
+ ctx.config.decisionStrategy = DecisionStrategy.CONSENSUS;
509
527
  }
510
- const attributeNameStrict = ctx.spec.attributeNameStrict ?? true;
528
+ const attributeNameStrict = ctx.config.attributeNameStrict ?? true;
511
529
  if (!attributeNameStrict) {
512
- const resourceKeys = Object.keys(ctx.data.attributes);
530
+ const resourceKeys = Object.keys(ctx.input.attributes);
513
531
  const keysToAdd = [];
514
532
  for(let i = 0; i < resourceKeys.length; i++){
515
533
  let contains = false;
@@ -529,32 +547,29 @@ class RealmMatchPolicyEvaluator {
529
547
  }
530
548
  let count = 0;
531
549
  for(let i = 0; i < keys.length; i++){
532
- if (!hasOwnProperty(ctx.data.attributes, keys[i])) {
550
+ if (!hasOwnProperty(ctx.input.attributes, keys[i])) {
533
551
  continue;
534
552
  }
535
553
  let outcome = false;
536
- const attributeValue = ctx.data.attributes[keys[i]];
537
- if (attributeValue === null && ctx.spec.attributeNullMatchAll) {
554
+ const attributeValue = ctx.input.attributes[keys[i]];
555
+ if (attributeValue === null && ctx.config.attributeNullMatchAll) {
538
556
  outcome = true;
539
- } else if (attributeValue === ctx.data.identity.realmId || attributeValue === ctx.data.identity.realmName) {
557
+ } else if (attributeValue === ctx.input.identity.realmId || attributeValue === ctx.input.identity.realmName) {
540
558
  outcome = true;
541
559
  }
542
560
  if (outcome) {
543
- if (ctx.spec.decisionStrategy === DecisionStrategy.AFFIRMATIVE) {
544
- return maybeInvertPolicyOutcome(true, ctx.spec.invert);
561
+ if (ctx.config.decisionStrategy === DecisionStrategy.AFFIRMATIVE) {
562
+ return maybeInvertPolicyOutcome(true, ctx.config.invert);
545
563
  }
546
564
  count++;
547
565
  } else {
548
- if (ctx.spec.decisionStrategy === DecisionStrategy.UNANIMOUS) {
549
- return maybeInvertPolicyOutcome(false, ctx.spec.invert);
566
+ if (ctx.config.decisionStrategy === DecisionStrategy.UNANIMOUS) {
567
+ return maybeInvertPolicyOutcome(false, ctx.config.invert);
550
568
  }
551
569
  count--;
552
570
  }
553
571
  }
554
- return maybeInvertPolicyOutcome(count > 0, ctx.spec.invert);
555
- }
556
- constructor(){
557
- this.validator = new RealmMatchPolicyValidator();
572
+ return maybeInvertPolicyOutcome(count > 0, ctx.config.invert);
558
573
  }
559
574
  }
560
575
 
@@ -586,7 +601,7 @@ class TimePolicyValidator extends Container {
586
601
  super.initialize();
587
602
  this.mount('dayOfWeek', createValidator(z.number().min(0).max(6).or(z.null()).or(z.undefined()).optional()));
588
603
  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()));
604
+ this.mount('dayOfYear', createValidator(z.number().min(1).max(365).or(z.null()).or(z.undefined()).optional()));
590
605
  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
606
  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
607
  this.mount('interval', createValidator(z.nativeEnum(TimePolicyInterval).or(z.null()).or(z.undefined()).optional()));
@@ -616,59 +631,60 @@ function toDate(input, dateRef) {
616
631
  return input;
617
632
  }
618
633
  class TimePolicyEvaluator {
634
+ validator;
635
+ constructor(){
636
+ this.validator = new TimePolicyValidator();
637
+ }
619
638
  async can(ctx) {
620
- return ctx.spec.type === BuiltInPolicyType.TIME;
639
+ return ctx.config.type === BuiltInPolicyType.TIME;
621
640
  }
622
- async validateSpecification(ctx) {
623
- return this.validator.run(ctx.spec);
641
+ async validateConfig(ctx) {
642
+ return this.validator.run(ctx.config);
624
643
  }
625
- async validateData(ctx) {
626
- return ctx.data;
644
+ async validateInput(ctx) {
645
+ return ctx.input;
627
646
  }
628
647
  async evaluate(ctx) {
629
648
  let now;
630
- if (ctx.data.dateTime) {
631
- now = toDate(ctx.data.dateTime);
649
+ if (ctx.input.dateTime) {
650
+ now = toDate(ctx.input.dateTime);
632
651
  } else {
633
652
  now = new Date();
634
653
  }
635
- if (ctx.spec.start) {
636
- const start = normalizeDate(toDate(ctx.spec.start, now), now);
654
+ if (ctx.config.start) {
655
+ const start = normalizeDate(toDate(ctx.config.start, now), now);
637
656
  if (now < start) {
638
- return maybeInvertPolicyOutcome(false, ctx.spec.invert);
657
+ return maybeInvertPolicyOutcome(false, ctx.config.invert);
639
658
  }
640
659
  }
641
- if (ctx.spec.end) {
642
- const end = normalizeDate(toDate(ctx.spec.end, now), now);
660
+ if (ctx.config.end) {
661
+ const end = normalizeDate(toDate(ctx.config.end, now), now);
643
662
  if (now > end) {
644
- return maybeInvertPolicyOutcome(false, ctx.spec.invert);
663
+ return maybeInvertPolicyOutcome(false, ctx.config.invert);
645
664
  }
646
665
  }
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);
666
+ if (ctx.config.interval) {
667
+ if (isIntervalForDayOfWeek(ctx.config.interval) && ctx.config.dayOfWeek) {
668
+ if (now.getDay() !== ctx.config.dayOfWeek) {
669
+ return maybeInvertPolicyOutcome(false, ctx.config.invert);
651
670
  }
652
671
  }
653
- if (isIntervalForDayOfMonth(ctx.spec.interval) && ctx.spec.dayOfMonth) {
654
- if (now.getDate() !== ctx.spec.dayOfMonth) {
655
- return maybeInvertPolicyOutcome(false, ctx.spec.invert);
672
+ if (isIntervalForDayOfMonth(ctx.config.interval) && ctx.config.dayOfMonth) {
673
+ if (now.getDate() !== ctx.config.dayOfMonth) {
674
+ return maybeInvertPolicyOutcome(false, ctx.config.invert);
656
675
  }
657
676
  }
658
- if (isIntervalForDayOfYear(ctx.spec.interval) && ctx.spec.dayOfYear) {
677
+ if (isIntervalForDayOfYear(ctx.config.interval) && ctx.config.dayOfYear) {
659
678
  const start = new Date(now.getFullYear(), 0, 0);
660
679
  const diff = now.getTime() - start.getTime() + (start.getTimezoneOffset() - now.getTimezoneOffset()) * 60 * 1000;
661
680
  const oneDay = 1000 * 60 * 60 * 24;
662
681
  const dayOfYear = Math.floor(diff / oneDay);
663
- if (dayOfYear !== ctx.spec.dayOfYear) {
664
- return maybeInvertPolicyOutcome(false, ctx.spec.invert);
682
+ if (dayOfYear !== ctx.config.dayOfYear) {
683
+ return maybeInvertPolicyOutcome(false, ctx.config.invert);
665
684
  }
666
685
  }
667
686
  }
668
- return maybeInvertPolicyOutcome(true, ctx.spec.invert);
669
- }
670
- constructor(){
671
- this.validator = new TimePolicyValidator();
687
+ return maybeInvertPolicyOutcome(true, ctx.config.invert);
672
688
  }
673
689
  }
674
690
 
@@ -688,6 +704,12 @@ class TimePolicyEvaluator {
688
704
  * The policy engine is a component that interprets defined policies and makes decisions
689
705
  * on whether to allow or deny a particular access.
690
706
  */ class PolicyEngine {
707
+ evaluators;
708
+ constructor(evaluators = {}){
709
+ this.evaluators = {};
710
+ this.registerDefaultEvaluators();
711
+ this.registerEvaluators(evaluators);
712
+ }
691
713
  registerEvaluator(type, evaluator) {
692
714
  this.evaluators[type] = evaluator;
693
715
  }
@@ -718,14 +740,18 @@ class TimePolicyEvaluator {
718
740
  evaluators: this.evaluators
719
741
  });
720
742
  }
721
- constructor(evaluators = {}){
722
- this.evaluators = {};
723
- this.registerDefaultEvaluators();
724
- this.registerEvaluators(evaluators);
725
- }
726
743
  }
727
744
 
728
745
  class PermissionError extends AuthupError {
746
+ policy;
747
+ policyError;
748
+ constructor(options = {}){
749
+ super({
750
+ ...options,
751
+ message: options.message || 'A permission error occurred.',
752
+ statusCode: options.statusCode || 403
753
+ });
754
+ }
729
755
  static notFound(name) {
730
756
  return new PermissionError({
731
757
  message: `The permission ${name} was not found.`,
@@ -760,13 +786,6 @@ class PermissionError extends AuthupError {
760
786
  }
761
787
  return error;
762
788
  }
763
- constructor(options = {}){
764
- super({
765
- ...options,
766
- message: options.message || 'A permission error occurred.',
767
- statusCode: options.statusCode || 403
768
- });
769
- }
770
789
  }
771
790
 
772
791
  /*
@@ -828,6 +847,10 @@ function mergePermissionItems(input) {
828
847
  }
829
848
 
830
849
  class PermissionMemoryProvider {
850
+ items = {};
851
+ constructor(items = []){
852
+ this.setMany(items);
853
+ }
831
854
  async get(options) {
832
855
  return this.items[buildPermissionItemKey(options)];
833
856
  }
@@ -837,13 +860,32 @@ class PermissionMemoryProvider {
837
860
  return prev;
838
861
  }, {});
839
862
  }
840
- constructor(items = []){
841
- this.items = {};
842
- this.setMany(items);
843
- }
844
863
  }
845
864
 
846
865
  class PermissionChecker {
866
+ provider;
867
+ policyEngine;
868
+ clientId;
869
+ realmId;
870
+ // ----------------------------------------------
871
+ constructor(options = {}){
872
+ if (options.provider) {
873
+ this.provider = options.provider;
874
+ } else {
875
+ this.provider = new PermissionMemoryProvider();
876
+ }
877
+ if (options.clientId) {
878
+ this.clientId = options.clientId;
879
+ }
880
+ if (options.realmId) {
881
+ this.realmId = options.realmId;
882
+ }
883
+ if (options.policyEngine) {
884
+ this.policyEngine = options.policyEngine;
885
+ } else {
886
+ this.policyEngine = new PolicyEngine();
887
+ }
888
+ }
847
889
  // ----------------------------------------------
848
890
  /**
849
891
  * Get a permission.
@@ -901,11 +943,11 @@ class PermissionChecker {
901
943
  let outcome;
902
944
  try {
903
945
  outcome = await this.policyEngine.evaluate({
904
- data: {
905
- ...ctx.data || {},
946
+ input: {
947
+ ...ctx.input || {},
906
948
  permission: entity
907
949
  },
908
- spec: entity.policy,
950
+ config: entity.policy,
909
951
  options: {
910
952
  include: options.policiesIncluded,
911
953
  exclude: options.policiesExcluded
@@ -991,25 +1033,6 @@ class PermissionChecker {
991
1033
  }
992
1034
  });
993
1035
  }
994
- // ----------------------------------------------
995
- constructor(options = {}){
996
- if (options.provider) {
997
- this.provider = options.provider;
998
- } else {
999
- this.provider = new PermissionMemoryProvider();
1000
- }
1001
- if (options.clientId) {
1002
- this.clientId = options.clientId;
1003
- }
1004
- if (options.realmId) {
1005
- this.realmId = options.realmId;
1006
- }
1007
- if (options.policyEngine) {
1008
- this.policyEngine = options.policyEngine;
1009
- } else {
1010
- this.policyEngine = new PolicyEngine();
1011
- }
1012
- }
1013
1036
  }
1014
1037
 
1015
1038
  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 };