@authup/access 1.0.0-beta.32 → 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.
- package/dist/index.mjs +132 -49
- package/dist/index.mjs.map +1 -1
- package/dist/permission/evaluator/index.d.ts.map +1 -0
- package/dist/permission/{checker → evaluator}/module.d.ts +3 -3
- package/dist/permission/evaluator/module.d.ts.map +1 -0
- package/dist/permission/{checker → evaluator}/types.d.ts +1 -1
- package/dist/permission/evaluator/types.d.ts.map +1 -0
- package/dist/permission/helpers/equal.d.ts +2 -1
- package/dist/permission/helpers/equal.d.ts.map +1 -1
- package/dist/permission/helpers/index.d.ts +1 -1
- package/dist/permission/helpers/index.d.ts.map +1 -1
- package/dist/permission/helpers/key.d.ts +2 -1
- package/dist/permission/helpers/key.d.ts.map +1 -1
- package/dist/permission/helpers/merge.d.ts +2 -1
- package/dist/permission/helpers/merge.d.ts.map +1 -1
- package/dist/permission/index.d.ts +1 -1
- package/dist/permission/index.d.ts.map +1 -1
- package/dist/permission/provider/memory.d.ts +5 -5
- package/dist/permission/provider/memory.d.ts.map +1 -1
- package/dist/permission/provider/types.d.ts +2 -2
- package/dist/permission/provider/types.d.ts.map +1 -1
- package/dist/permission/types.d.ts +12 -1
- package/dist/permission/types.d.ts.map +1 -1
- package/dist/policy/built-in/attribute-names/types.d.ts +2 -2
- package/dist/policy/built-in/attribute-names/validator.d.ts.map +1 -1
- package/dist/policy/built-in/attributes/evaluator.d.ts.map +1 -1
- package/dist/policy/built-in/attributes/types.d.ts +2 -2
- package/dist/policy/built-in/attributes/types.d.ts.map +1 -1
- package/dist/policy/built-in/attributes/validator.d.ts.map +1 -1
- package/dist/policy/built-in/composite/evaluator.d.ts.map +1 -1
- package/dist/policy/built-in/composite/types.d.ts +3 -3
- package/dist/policy/built-in/composite/types.d.ts.map +1 -1
- package/dist/policy/built-in/composite/validator.d.ts.map +1 -1
- package/dist/policy/built-in/date/evaluator.d.ts.map +1 -1
- package/dist/policy/built-in/date/types.d.ts +2 -2
- package/dist/policy/built-in/date/validator.d.ts.map +1 -1
- package/dist/policy/built-in/identity/data/validator.d.ts.map +1 -1
- package/dist/policy/built-in/identity/evaluator.d.ts.map +1 -1
- package/dist/policy/built-in/identity/types.d.ts +2 -2
- package/dist/policy/built-in/identity/validator.d.ts +1 -1
- package/dist/policy/built-in/identity/validator.d.ts.map +1 -1
- package/dist/policy/built-in/permission-binding/module.d.ts.map +1 -1
- package/dist/policy/built-in/permission-binding/types.d.ts +2 -2
- package/dist/policy/built-in/permission-binding/validator.d.ts +1 -1
- package/dist/policy/built-in/permission-binding/validator.d.ts.map +1 -1
- package/dist/policy/built-in/realm-match/evaluator.d.ts.map +1 -1
- package/dist/policy/built-in/realm-match/types.d.ts +2 -2
- 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/types.d.ts +2 -2
- package/dist/policy/built-in/time/validator.d.ts.map +1 -1
- package/dist/policy/data.d.ts.map +1 -1
- package/dist/policy/engine/module.d.ts +3 -3
- package/dist/policy/engine/module.d.ts.map +1 -1
- package/dist/policy/engine/types.d.ts +3 -3
- package/dist/policy/engine/types.d.ts.map +1 -1
- package/dist/policy/error/module.d.ts.map +1 -1
- package/dist/policy/types.d.ts +6 -8
- package/dist/policy/types.d.ts.map +1 -1
- package/package.json +6 -8
- package/dist/permission/checker/index.d.ts.map +0 -1
- package/dist/permission/checker/module.d.ts.map +0 -1
- package/dist/permission/checker/types.d.ts.map +0 -1
- /package/dist/permission/{checker → evaluator}/index.d.ts +0 -0
package/dist/index.mjs
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { AuthupError, ErrorCode } from '@authup/errors';
|
|
2
|
-
import {
|
|
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
|
|
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 =
|
|
75
|
-
|
|
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(
|
|
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
|
|
906
|
-
const
|
|
907
|
-
|
|
908
|
-
|
|
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
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
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
|
-
|
|
1037
|
-
name: input
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
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(
|
|
1068
|
-
const binding = await this.findOne(
|
|
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 ${
|
|
1158
|
+
message: `The ${name} permission could not be resolved`,
|
|
1076
1159
|
path: [
|
|
1077
|
-
|
|
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
|