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