@authup/access 1.0.0-beta.66 → 1.0.0-beta.68
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.d.mts +86 -6
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +149 -29
- package/dist/index.mjs.map +1 -1
- package/dist/permission/authorization/module.d.ts +12 -5
- package/dist/permission/authorization/module.d.ts.map +1 -1
- package/dist/permission/authorization/policy.d.ts +9 -1
- package/dist/permission/authorization/policy.d.ts.map +1 -1
- package/dist/permission/authorization/types.d.ts +15 -1
- package/dist/permission/authorization/types.d.ts.map +1 -1
- package/dist/permission/evaluator/module.d.ts.map +1 -1
- package/dist/permission/evaluator/types.d.ts +8 -1
- package/dist/permission/evaluator/types.d.ts.map +1 -1
- package/dist/permission/realm-scope/helpers.d.ts +1 -1
- package/dist/permission/realm-scope/helpers.d.ts.map +1 -1
- package/dist/policy/built-in/date/evaluator.d.ts.map +1 -1
- package/dist/policy/built-in/permission-binding/identity-evaluator.d.ts.map +1 -1
- package/dist/policy/built-in/time/evaluator.d.ts.map +1 -1
- package/dist/policy/constants.d.ts +11 -0
- package/dist/policy/constants.d.ts.map +1 -1
- package/dist/policy/evaluation/context/define.d.ts.map +1 -1
- package/dist/policy/evaluation/context/index.d.ts +1 -0
- package/dist/policy/evaluation/context/index.d.ts.map +1 -1
- package/dist/policy/evaluation/context/transition.d.ts +13 -0
- package/dist/policy/evaluation/context/transition.d.ts.map +1 -0
- package/dist/policy/evaluation/context/types.d.ts +18 -0
- package/dist/policy/evaluation/context/types.d.ts.map +1 -1
- package/dist/policy/types.d.ts +5 -0
- package/dist/policy/types.d.ts.map +1 -1
- package/package.json +6 -6
package/dist/index.d.mts
CHANGED
|
@@ -29,6 +29,18 @@ export declare class PolicyData implements IPolicyData {
|
|
|
29
29
|
}
|
|
30
30
|
//#endregion
|
|
31
31
|
//#region src/policy/evaluation/context/types.d.ts
|
|
32
|
+
/**
|
|
33
|
+
* Receives the instants at which a clock-dependent verdict could change.
|
|
34
|
+
*
|
|
35
|
+
* A `date` or `time` policy that fell back to the real clock (no `date` / `time`
|
|
36
|
+
* key in the bag) reports the next strictly-future instant its own verdict could
|
|
37
|
+
* flip, from inside the evaluation walk that already runs. A caller that caches
|
|
38
|
+
* an answer derived from such a walk learns when to stop trusting it. Reports may
|
|
39
|
+
* be early (conservative) but never late, and `invert` does not move them.
|
|
40
|
+
*/
|
|
41
|
+
export type PolicyTransitionSink = {
|
|
42
|
+
report(at: Date): void;
|
|
43
|
+
};
|
|
32
44
|
export type PolicyEvaluationContext = {
|
|
33
45
|
readonly evaluators: Record<string, IPolicyEvaluator>;
|
|
34
46
|
readonly path: (string | number)[];
|
|
@@ -51,12 +63,31 @@ export type PolicyEvaluationContext = {
|
|
|
51
63
|
* consults a column name, so this can never change an evaluate() outcome.
|
|
52
64
|
*/
|
|
53
65
|
readonly realmAttributeName?: string;
|
|
66
|
+
/**
|
|
67
|
+
* Optional receiver of clock transitions (see {@link PolicyTransitionSink}).
|
|
68
|
+
* Nested evaluations inherit it, since every walk propagates the context by
|
|
69
|
+
* spread.
|
|
70
|
+
*/
|
|
71
|
+
readonly transitions?: PolicyTransitionSink;
|
|
54
72
|
};
|
|
55
73
|
export type PolicyEvaluationContextInput = Partial<PolicyEvaluationContext>;
|
|
56
74
|
//#endregion
|
|
57
75
|
//#region src/policy/evaluation/context/define.d.ts
|
|
58
76
|
export declare function definePolicyEvaluationContext(input?: PolicyEvaluationContextInput): PolicyEvaluationContext;
|
|
59
77
|
//#endregion
|
|
78
|
+
//#region src/policy/evaluation/context/transition.d.ts
|
|
79
|
+
export type PolicyTransitionCollector = PolicyTransitionSink & {
|
|
80
|
+
/**
|
|
81
|
+
* The earliest reported instant, or undefined when nothing reported one.
|
|
82
|
+
*/
|
|
83
|
+
readonly next: Date | undefined;
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* A sink keeping the earliest reported instant, which is the moment an answer
|
|
87
|
+
* built from every evaluation it was handed to stops being current.
|
|
88
|
+
*/
|
|
89
|
+
export declare function createPolicyTransitionCollector(): PolicyTransitionCollector;
|
|
90
|
+
//#endregion
|
|
60
91
|
//#region src/policy/evaluation/types.d.ts
|
|
61
92
|
export type PolicyEvaluators = Record<string, IPolicyEvaluator>;
|
|
62
93
|
export type PolicyEvaluationResult = {
|
|
@@ -112,6 +143,10 @@ export interface IPolicyEvaluator {
|
|
|
112
143
|
}
|
|
113
144
|
//#endregion
|
|
114
145
|
//#region src/policy/types.d.ts
|
|
146
|
+
/**
|
|
147
|
+
* A policy type's configuration validator, keyed by the type it validates.
|
|
148
|
+
*/
|
|
149
|
+
export type PolicyValidators = Record<string, Container<Record<string, any>>>;
|
|
115
150
|
export type BasePolicy<T extends string = string> = {
|
|
116
151
|
/**
|
|
117
152
|
* Type describing the policy.
|
|
@@ -376,7 +411,7 @@ export declare function minRealmScope(values: Array<`${RealmScope}` | null | und
|
|
|
376
411
|
* multiple realms) requires the scope to reach EVERY listed realm (unanimous, fail-closed),
|
|
377
412
|
* so any app/entity can express its realm via one or many keys under the canonical contract.
|
|
378
413
|
*/
|
|
379
|
-
export declare function realmScopeMatches(scope: `${RealmScope}` | null | undefined, resourceRealmId: string | string
|
|
414
|
+
export declare function realmScopeMatches(scope: `${RealmScope}` | null | undefined, resourceRealmId: string | Array<string | null> | null | undefined, identityRealmId: string | null | undefined, identityRealmName?: string | null): boolean;
|
|
380
415
|
//#endregion
|
|
381
416
|
//#region src/permission/types.d.ts
|
|
382
417
|
export type BasePermission = {
|
|
@@ -640,6 +675,16 @@ export declare const PolicyDefaultEvaluators: {
|
|
|
640
675
|
readonly realmMatch: RealmMatchPolicyEvaluator;
|
|
641
676
|
readonly time: TimePolicyEvaluator;
|
|
642
677
|
};
|
|
678
|
+
/**
|
|
679
|
+
* The configuration validator of every built-in policy type, keyed like
|
|
680
|
+
* `PolicyDefaultEvaluators`. It is what `projectAuthorizationPolicy` runs a
|
|
681
|
+
* node through, so a type absent here cannot travel in the authorization
|
|
682
|
+
* catalog. The registry is open like the evaluator one (#3635): spread it and
|
|
683
|
+
* add a custom type's validator to let that type travel. It is frozen, since
|
|
684
|
+
* a write into it would make the type projectable for every caller in the
|
|
685
|
+
* process.
|
|
686
|
+
*/
|
|
687
|
+
export declare const PolicyDefaultValidators: Readonly<PolicyValidators>;
|
|
643
688
|
//#endregion
|
|
644
689
|
//#region src/policy/input.d.ts
|
|
645
690
|
/**
|
|
@@ -753,6 +798,13 @@ export type PermissionEvaluationOptions = {
|
|
|
753
798
|
* (`preEvaluate()`): only a tree that settles false with the current bag denies.
|
|
754
799
|
*/
|
|
755
800
|
pendingPolicies?: 'deny' | 'permit';
|
|
801
|
+
/**
|
|
802
|
+
* Receives the instants at which a clock-dependent policy (`date`, `time`)
|
|
803
|
+
* in an evaluated tree could change its verdict, so a caller caching the
|
|
804
|
+
* outcome knows when it expires. Handed to every policy evaluation this call
|
|
805
|
+
* runs; a policy-free grant evaluates nothing and reports nothing.
|
|
806
|
+
*/
|
|
807
|
+
transitions?: PolicyTransitionSink;
|
|
756
808
|
};
|
|
757
809
|
export type PermissionEvaluationContext = {
|
|
758
810
|
name: string | string[];
|
|
@@ -932,6 +984,20 @@ export type AuthorizationEvaluatorInput = {
|
|
|
932
984
|
*/
|
|
933
985
|
identity?: IdentityPolicyData;
|
|
934
986
|
};
|
|
987
|
+
export type AuthorizationEvaluatorOptions = {
|
|
988
|
+
/**
|
|
989
|
+
* The policy types a catalog tree may carry. Defaults to
|
|
990
|
+
* `PolicyDefaultValidators`; spread it to add a custom type.
|
|
991
|
+
*/
|
|
992
|
+
validators?: PolicyValidators;
|
|
993
|
+
/**
|
|
994
|
+
* How the projected trees evaluate. Defaults to
|
|
995
|
+
* `PolicyDefaultEvaluators`; spread it to add a custom type. The
|
|
996
|
+
* permission-binding evaluator is always replaced by the one binding the
|
|
997
|
+
* introspected grants.
|
|
998
|
+
*/
|
|
999
|
+
evaluators?: PolicyEvaluators;
|
|
1000
|
+
};
|
|
935
1001
|
/**
|
|
936
1002
|
* Which resource realms a batch check evaluates against.
|
|
937
1003
|
*
|
|
@@ -1031,9 +1097,9 @@ export declare const AUTHORIZATION_POLICY_WITHHELD_TYPE = "withheld";
|
|
|
1031
1097
|
* the permission denies until the policy is fixed.
|
|
1032
1098
|
*
|
|
1033
1099
|
* A tree THIS copy cannot project is the same condition read from the other
|
|
1034
|
-
* side, and it is per tree: a policy type
|
|
1035
|
-
*
|
|
1036
|
-
* configuration its validator refuses denies the definitions that reference
|
|
1100
|
+
* side, and it is per tree: a policy type the validator registry lacks (a
|
|
1101
|
+
* type newer than this package, or a custom one the caller did not register)
|
|
1102
|
+
* or a configuration its validator refuses denies the definitions that reference
|
|
1037
1103
|
* it, exactly as `policies: null` does, and drops a grant that names it,
|
|
1038
1104
|
* exactly as a binding check does. One such tree never takes the evaluator
|
|
1039
1105
|
* down for the permissions that do not use it. A malformed catalog still
|
|
@@ -1055,8 +1121,15 @@ export declare const AUTHORIZATION_POLICY_WITHHELD_TYPE = "withheld";
|
|
|
1055
1121
|
* rejected or evaluated over every candidate before paging. The supplied
|
|
1056
1122
|
* identity is authoritative; `options.decisionStrategy` is forwarded and the
|
|
1057
1123
|
* policy include, exclude and pending options are refused.
|
|
1124
|
+
*
|
|
1125
|
+
* The policy type set is open (#3635): `options.validators` decides which
|
|
1126
|
+
* trees project and `options.evaluators` how they evaluate, the built-in
|
|
1127
|
+
* registries by default. A custom type needs both, the validator the server
|
|
1128
|
+
* projected it with and the evaluator the server decides it with; given only
|
|
1129
|
+
* the first it projects and then denies. The binding evaluator is always this
|
|
1130
|
+
* function's own, since it is what binds the introspected grants.
|
|
1058
1131
|
*/
|
|
1059
|
-
export declare function createAuthorizationEvaluator(input: AuthorizationEvaluatorInput): Promise<IPermissionEvaluator>;
|
|
1132
|
+
export declare function createAuthorizationEvaluator(input: AuthorizationEvaluatorInput, options?: AuthorizationEvaluatorOptions): Promise<IPermissionEvaluator>;
|
|
1060
1133
|
/**
|
|
1061
1134
|
* An `IPermissionEvaluator` over the answer `POST /authorization/check`
|
|
1062
1135
|
* served: the caller's own verdicts, paired with the realms they hold in.
|
|
@@ -1093,11 +1166,18 @@ export declare function createAuthorizationCheckEvaluator(input: AuthorizationCh
|
|
|
1093
1166
|
* such as `id`, `name`, `builtIn` or `createdAt` never travel), plus its type
|
|
1094
1167
|
* and, for a composite, its projected children.
|
|
1095
1168
|
*
|
|
1169
|
+
* The type set is the `validators` registry, `PolicyDefaultValidators` unless
|
|
1170
|
+
* the caller hands another (#3635): a type the registry lacks is refused, so
|
|
1171
|
+
* the server and a consumer that register the same custom type let it travel,
|
|
1172
|
+
* and one that does not denies it. The withheld node is refused whatever the
|
|
1173
|
+
* registry says, since projecting it would evaluate a tree the caller was not
|
|
1174
|
+
* allowed to see.
|
|
1175
|
+
*
|
|
1096
1176
|
* Every refusal is a `ValidupError`, the node's head and the type's own
|
|
1097
1177
|
* validator alike, and a child's issues are rebased onto the position it sits
|
|
1098
1178
|
* at, so one message names the node in the tree that is wrong.
|
|
1099
1179
|
*/
|
|
1100
|
-
export declare function projectAuthorizationPolicy(input: unknown): Promise<AuthorizationPolicy>;
|
|
1180
|
+
export declare function projectAuthorizationPolicy(input: unknown, validators?: PolicyValidators): Promise<AuthorizationPolicy>;
|
|
1101
1181
|
/**
|
|
1102
1182
|
* Whether a projected tree evaluates the permission binding at any depth. A
|
|
1103
1183
|
* grant policy carrying one would re-enter its own permission's grants, so
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/policy/data.ts","../src/policy/evaluation/context/types.ts","../src/policy/evaluation/context/define.ts","../src/policy/evaluation/types.ts","../src/policy/types.ts","../src/policy/engine/types.ts","../src/policy/engine/module.ts","../src/policy/issue/constants.ts","../src/policy/issue/types.ts","../src/policy/issue/define.ts","../src/policy/error/module.ts","../src/policy/error/check.ts","../src/policy/helpers/invert.ts","../src/policy/built-in/attribute-names/types.ts","../src/policy/built-in/attribute-names/validator.ts","../src/policy/built-in/attributes/types.ts","../src/policy/built-in/attributes/define.ts","../src/policy/built-in/attributes/validator.ts","../src/policy/built-in/attributes/evaluator.ts","../src/policy/built-in/attribute-names/evaluator.ts","../src/policy/built-in/composite/types.ts","../src/policy/built-in/composite/validator.ts","../src/policy/built-in/composite/evaluator.ts","../src/policy/built-in/composite/helper.ts","../src/policy/built-in/date/types.ts","../src/policy/built-in/date/validator.ts","../src/policy/built-in/date/evaluator.ts","../src/policy/built-in/identity/types.ts","../src/policy/built-in/identity/data/validator.ts","../src/policy/built-in/identity/validator.ts","../src/policy/built-in/identity/evaluator.ts","../src/permission/realm-scope/constants.ts","../src/permission/realm-scope/helpers.ts","../src/permission/types.ts","../src/policy/built-in/realm-match/types.ts","../src/policy/built-in/realm-match/validator.ts","../src/policy/built-in/realm-match/evaluator.ts","../src/policy/built-in/permission-binding/types.ts","../src/policy/built-in/permission-binding/validator.ts","../src/policy/built-in/permission-binding/identity-evaluator.ts","../src/policy/built-in/permission-binding/module.ts","../src/policy/built-in/time/constants.ts","../src/policy/built-in/time/types.ts","../src/policy/built-in/time/validator.ts","../src/policy/built-in/time/evaluator.ts","../src/policy/built-in/time/helpers.ts","../src/policy/built-in/constants.ts","../src/policy/built-in/types.ts","../src/policy/built-in/define.ts","../src/policy/constants.ts","../src/policy/input.ts","../src/permission/error/module.ts","../src/permission/error/check.ts","../src/permission/helpers/aggregate.ts","../src/permission/helpers/equal.ts","../src/permission/helpers/grant.ts","../src/permission/helpers/key.ts","../src/permission/provider/types.ts","../src/permission/provider/memory.ts","../src/permission/evaluator/types.ts","../src/permission/evaluator/module.ts","../src/permission/authorization/error.ts","../src/permission/authorization/check.ts","../src/permission/authorization/types.ts","../src/permission/authorization/check-schema.ts","../src/permission/authorization/constants.ts","../src/permission/authorization/module.ts","../src/permission/authorization/policy.ts","../src/permission/authorization/schema.ts"],"mappings":";;;;;;;;iBAOiB;EACb,IAAI,aAAa;EACjB,IAAI;EACJ,IAAI,aAAa,cAAe;EAChC,OAAO;EAEP,YAAY;EACZ,aAAa;EAEb,SAAU;;qBAGD,sBAAsB;YACrB,MAAM;YAEN,WAAY;EAGlB,YAAA,OAAM,qBACN,YAAW;EAMf,IAAI,aAAa,aAAa,OAAO;EAKrC,IAAI,aAAa,cAAe;EAQhC,IAAI;EAIJ,OAAO;EAKP,aAAa;EAIb,YAAY;EAIZ,SAAK
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/policy/data.ts","../src/policy/evaluation/context/types.ts","../src/policy/evaluation/context/define.ts","../src/policy/evaluation/context/transition.ts","../src/policy/evaluation/types.ts","../src/policy/types.ts","../src/policy/engine/types.ts","../src/policy/engine/module.ts","../src/policy/issue/constants.ts","../src/policy/issue/types.ts","../src/policy/issue/define.ts","../src/policy/error/module.ts","../src/policy/error/check.ts","../src/policy/helpers/invert.ts","../src/policy/built-in/attribute-names/types.ts","../src/policy/built-in/attribute-names/validator.ts","../src/policy/built-in/attributes/types.ts","../src/policy/built-in/attributes/define.ts","../src/policy/built-in/attributes/validator.ts","../src/policy/built-in/attributes/evaluator.ts","../src/policy/built-in/attribute-names/evaluator.ts","../src/policy/built-in/composite/types.ts","../src/policy/built-in/composite/validator.ts","../src/policy/built-in/composite/evaluator.ts","../src/policy/built-in/composite/helper.ts","../src/policy/built-in/date/types.ts","../src/policy/built-in/date/validator.ts","../src/policy/built-in/date/evaluator.ts","../src/policy/built-in/identity/types.ts","../src/policy/built-in/identity/data/validator.ts","../src/policy/built-in/identity/validator.ts","../src/policy/built-in/identity/evaluator.ts","../src/permission/realm-scope/constants.ts","../src/permission/realm-scope/helpers.ts","../src/permission/types.ts","../src/policy/built-in/realm-match/types.ts","../src/policy/built-in/realm-match/validator.ts","../src/policy/built-in/realm-match/evaluator.ts","../src/policy/built-in/permission-binding/types.ts","../src/policy/built-in/permission-binding/validator.ts","../src/policy/built-in/permission-binding/identity-evaluator.ts","../src/policy/built-in/permission-binding/module.ts","../src/policy/built-in/time/constants.ts","../src/policy/built-in/time/types.ts","../src/policy/built-in/time/validator.ts","../src/policy/built-in/time/evaluator.ts","../src/policy/built-in/time/helpers.ts","../src/policy/built-in/constants.ts","../src/policy/built-in/types.ts","../src/policy/built-in/define.ts","../src/policy/constants.ts","../src/policy/input.ts","../src/permission/error/module.ts","../src/permission/error/check.ts","../src/permission/helpers/aggregate.ts","../src/permission/helpers/equal.ts","../src/permission/helpers/grant.ts","../src/permission/helpers/key.ts","../src/permission/provider/types.ts","../src/permission/provider/memory.ts","../src/permission/evaluator/types.ts","../src/permission/evaluator/module.ts","../src/permission/authorization/error.ts","../src/permission/authorization/check.ts","../src/permission/authorization/types.ts","../src/permission/authorization/check-schema.ts","../src/permission/authorization/constants.ts","../src/permission/authorization/module.ts","../src/permission/authorization/policy.ts","../src/permission/authorization/schema.ts"],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -539,7 +539,25 @@ function definePolicyEvaluationContext(input = {}) {
|
|
|
539
539
|
include: input.include || [],
|
|
540
540
|
exclude: input.exclude || [],
|
|
541
541
|
withConditions: input.withConditions ?? false,
|
|
542
|
-
realmAttributeName: input.realmAttributeName
|
|
542
|
+
realmAttributeName: input.realmAttributeName,
|
|
543
|
+
transitions: input.transitions
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
//#endregion
|
|
547
|
+
//#region src/policy/evaluation/context/transition.ts
|
|
548
|
+
/**
|
|
549
|
+
* A sink keeping the earliest reported instant, which is the moment an answer
|
|
550
|
+
* built from every evaluation it was handed to stops being current.
|
|
551
|
+
*/
|
|
552
|
+
function createPolicyTransitionCollector() {
|
|
553
|
+
let next;
|
|
554
|
+
return {
|
|
555
|
+
report(at) {
|
|
556
|
+
if (!next || at.getTime() < next.getTime()) next = at;
|
|
557
|
+
},
|
|
558
|
+
get next() {
|
|
559
|
+
return next;
|
|
560
|
+
}
|
|
543
561
|
};
|
|
544
562
|
}
|
|
545
563
|
//#endregion
|
|
@@ -762,7 +780,7 @@ var CompositePolicyValidator = class extends Container {
|
|
|
762
780
|
initialize() {
|
|
763
781
|
super.initialize();
|
|
764
782
|
this.mount("decisionStrategy", createValidator(z.enum(DecisionStrategy).or(z.null()).or(z.undefined()).optional()));
|
|
765
|
-
this.mount("children", createValidator(z.array(z.looseObject({ type: z.string().min(
|
|
783
|
+
this.mount("children", createValidator(z.array(z.looseObject({ type: z.string().min(1) }))));
|
|
766
784
|
this.mount("invert", createValidator(z.boolean().or(z.null()).or(z.undefined()).optional()));
|
|
767
785
|
}
|
|
768
786
|
};
|
|
@@ -900,6 +918,22 @@ function toDate$1(input) {
|
|
|
900
918
|
if (typeof input === "number") return new Date(input);
|
|
901
919
|
return input;
|
|
902
920
|
}
|
|
921
|
+
/**
|
|
922
|
+
* The next instant at which a date policy's verdict could change, seen from the
|
|
923
|
+
* (day-normalized) `now`: the start day while it is still ahead, else the
|
|
924
|
+
* midnight after the end day while that day has not passed. Nothing once the
|
|
925
|
+
* end day is behind, since the verdict is final from then on.
|
|
926
|
+
*/
|
|
927
|
+
function nextDateTransition(policy, now) {
|
|
928
|
+
if (policy.start) {
|
|
929
|
+
const start = normalizeDate$1(toDate$1(policy.start));
|
|
930
|
+
if (now < start) return start;
|
|
931
|
+
}
|
|
932
|
+
if (policy.end) {
|
|
933
|
+
const end = normalizeDate$1(toDate$1(policy.end));
|
|
934
|
+
if (now <= end) return new Date(end.getFullYear(), end.getMonth(), end.getDate() + 1);
|
|
935
|
+
}
|
|
936
|
+
}
|
|
903
937
|
var DatePolicyEvaluator = class {
|
|
904
938
|
validator;
|
|
905
939
|
constructor() {
|
|
@@ -915,7 +949,13 @@ var DatePolicyEvaluator = class {
|
|
|
915
949
|
ctx.data.set("date", now);
|
|
916
950
|
ctx.data.setValidated("date");
|
|
917
951
|
}
|
|
918
|
-
} else
|
|
952
|
+
} else {
|
|
953
|
+
now = normalizeDate$1(/* @__PURE__ */ new Date());
|
|
954
|
+
if (ctx.transitions) {
|
|
955
|
+
const next = nextDateTransition(policy, now);
|
|
956
|
+
if (next) ctx.transitions.report(next);
|
|
957
|
+
}
|
|
958
|
+
}
|
|
919
959
|
if (policy.start) {
|
|
920
960
|
const start = normalizeDate$1(toDate$1(policy.start));
|
|
921
961
|
if (now < start) return { success: maybeInvertPolicyOutcome(false, policy.invert) };
|
|
@@ -1155,6 +1195,12 @@ var PermissionBindingPolicyValidator = class extends Container {
|
|
|
1155
1195
|
};
|
|
1156
1196
|
//#endregion
|
|
1157
1197
|
//#region src/policy/built-in/permission-binding/identity-evaluator.ts
|
|
1198
|
+
function containsPermissionBinding(policy) {
|
|
1199
|
+
if (policy.type === "permissionBinding") return true;
|
|
1200
|
+
if (policy.type !== "composite") return false;
|
|
1201
|
+
const children = policy.children;
|
|
1202
|
+
return Array.isArray(children) && children.some((child) => !!child && typeof child === "object" && containsPermissionBinding(child));
|
|
1203
|
+
}
|
|
1158
1204
|
var IdentityPermissionBindingPolicyEvaluator = class {
|
|
1159
1205
|
validator;
|
|
1160
1206
|
identityEvaluator;
|
|
@@ -1233,6 +1279,14 @@ var IdentityPermissionBindingPolicyEvaluator = class {
|
|
|
1233
1279
|
pending = true;
|
|
1234
1280
|
continue;
|
|
1235
1281
|
}
|
|
1282
|
+
if (containsPermissionBinding(grant.policy)) {
|
|
1283
|
+
issues.push(definePolicyIssueItem({
|
|
1284
|
+
code: "INVALID",
|
|
1285
|
+
message: "A grant policy must not evaluate the permission binding.",
|
|
1286
|
+
path: ctx.path
|
|
1287
|
+
}));
|
|
1288
|
+
continue;
|
|
1289
|
+
}
|
|
1236
1290
|
const outcome = await new PolicyEngine(ctx.evaluators).evaluate(grant.policy, {
|
|
1237
1291
|
...ctx,
|
|
1238
1292
|
path: [...ctx.path || []]
|
|
@@ -1345,6 +1399,30 @@ function toDate(input, dateRef) {
|
|
|
1345
1399
|
if (typeof input === "number") return new Date(input);
|
|
1346
1400
|
return input;
|
|
1347
1401
|
}
|
|
1402
|
+
/**
|
|
1403
|
+
* The next instant at which a time policy's verdict could change, seen from
|
|
1404
|
+
* `now`: today's start while it is ahead, the minute after today's end while
|
|
1405
|
+
* that is ahead, and the next local midnight, where the daily window moves on
|
|
1406
|
+
* and the day-of-week/month/year checks roll over. The earliest of those; a
|
|
1407
|
+
* policy with no constraint never changes.
|
|
1408
|
+
*
|
|
1409
|
+
* `normalizeDate` keeps the seconds and milliseconds of the instant it is
|
|
1410
|
+
* evaluated at and drops the policy's own, so the comparisons below are made
|
|
1411
|
+
* at minute precision: `now < start` stops holding at HH:MM:00.000 of the
|
|
1412
|
+
* start, and `now > end` starts holding at the following minute. Reading the
|
|
1413
|
+
* candidates off `normalizeDate` instead would report the seconds of this
|
|
1414
|
+
* evaluation, up to a minute after the verdict already flipped.
|
|
1415
|
+
*/
|
|
1416
|
+
function nextTimeTransition(policy, now) {
|
|
1417
|
+
const candidates = [];
|
|
1418
|
+
const atMinute = (input) => new Date(now.getFullYear(), now.getMonth(), now.getDate(), input.getHours(), input.getMinutes());
|
|
1419
|
+
if (policy.start) candidates.push(atMinute(toDate(policy.start, now)));
|
|
1420
|
+
if (policy.end) candidates.push(new Date(atMinute(toDate(policy.end, now)).getTime() + 6e4));
|
|
1421
|
+
if (policy.start || policy.end || policy.interval) candidates.push(new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1));
|
|
1422
|
+
let next;
|
|
1423
|
+
for (const candidate of candidates) if (candidate.getTime() > now.getTime() && (!next || candidate.getTime() < next.getTime())) next = candidate;
|
|
1424
|
+
return next;
|
|
1425
|
+
}
|
|
1348
1426
|
var TimePolicyEvaluator = class {
|
|
1349
1427
|
validator;
|
|
1350
1428
|
constructor() {
|
|
@@ -1360,7 +1438,13 @@ var TimePolicyEvaluator = class {
|
|
|
1360
1438
|
ctx.data.set("time", now);
|
|
1361
1439
|
ctx.data.setValidated("time");
|
|
1362
1440
|
}
|
|
1363
|
-
} else
|
|
1441
|
+
} else {
|
|
1442
|
+
now = /* @__PURE__ */ new Date();
|
|
1443
|
+
if (ctx.transitions) {
|
|
1444
|
+
const next = nextTimeTransition(policy, now);
|
|
1445
|
+
if (next) ctx.transitions.report(next);
|
|
1446
|
+
}
|
|
1447
|
+
}
|
|
1364
1448
|
if (policy.start) {
|
|
1365
1449
|
const start = normalizeDate(toDate(policy.start, now), now);
|
|
1366
1450
|
if (now < start) return { success: maybeInvertPolicyOutcome(false, policy.invert) };
|
|
@@ -1405,6 +1489,25 @@ const PolicyDefaultEvaluators = {
|
|
|
1405
1489
|
["realmMatch"]: new RealmMatchPolicyEvaluator(),
|
|
1406
1490
|
["time"]: new TimePolicyEvaluator()
|
|
1407
1491
|
};
|
|
1492
|
+
/**
|
|
1493
|
+
* The configuration validator of every built-in policy type, keyed like
|
|
1494
|
+
* `PolicyDefaultEvaluators`. It is what `projectAuthorizationPolicy` runs a
|
|
1495
|
+
* node through, so a type absent here cannot travel in the authorization
|
|
1496
|
+
* catalog. The registry is open like the evaluator one (#3635): spread it and
|
|
1497
|
+
* add a custom type's validator to let that type travel. It is frozen, since
|
|
1498
|
+
* a write into it would make the type projectable for every caller in the
|
|
1499
|
+
* process.
|
|
1500
|
+
*/
|
|
1501
|
+
const PolicyDefaultValidators = Object.freeze({
|
|
1502
|
+
["composite"]: new CompositePolicyValidator(),
|
|
1503
|
+
["attributes"]: new AttributesPolicyValidator(),
|
|
1504
|
+
["attributeNames"]: new AttributeNamesPolicyValidator(),
|
|
1505
|
+
["date"]: new DatePolicyValidator(),
|
|
1506
|
+
["identity"]: new IdentityPolicyValidator(),
|
|
1507
|
+
["permissionBinding"]: new PermissionBindingPolicyValidator(),
|
|
1508
|
+
["realmMatch"]: new RealmMatchPolicyValidator(),
|
|
1509
|
+
["time"]: new TimePolicyValidator()
|
|
1510
|
+
});
|
|
1408
1511
|
//#endregion
|
|
1409
1512
|
//#region src/policy/input.ts
|
|
1410
1513
|
/**
|
|
@@ -1481,6 +1584,7 @@ var PermissionEvaluator = class {
|
|
|
1481
1584
|
const evaluationResult = await this.policyEngine.evaluate(compositePolicy, definePolicyEvaluationContext({
|
|
1482
1585
|
include: options.policiesIncluded,
|
|
1483
1586
|
exclude: options.policiesExcluded,
|
|
1587
|
+
transitions: options.transitions,
|
|
1484
1588
|
data
|
|
1485
1589
|
}));
|
|
1486
1590
|
if (evaluationResult.success || options.pendingPolicies === "permit" && !!evaluationResult.pending) {
|
|
@@ -1801,22 +1905,10 @@ const AUTHORIZATION_POLICY_WITHHELD_TYPE = "withheld";
|
|
|
1801
1905
|
var AuthorizationPolicyHeadValidator = class extends Container {
|
|
1802
1906
|
initialize() {
|
|
1803
1907
|
super.initialize();
|
|
1804
|
-
this.mount("type", createValidator(z.
|
|
1908
|
+
this.mount("type", createValidator(z.string().min(1)));
|
|
1805
1909
|
this.mount("children", createValidator(z.array(z.unknown()).optional()));
|
|
1806
1910
|
}
|
|
1807
1911
|
};
|
|
1808
|
-
function createValidators() {
|
|
1809
|
-
return {
|
|
1810
|
-
["attributes"]: new AttributesPolicyValidator(),
|
|
1811
|
-
["attributeNames"]: new AttributeNamesPolicyValidator(),
|
|
1812
|
-
["composite"]: new CompositePolicyValidator(),
|
|
1813
|
-
["date"]: new DatePolicyValidator(),
|
|
1814
|
-
["time"]: new TimePolicyValidator(),
|
|
1815
|
-
["identity"]: new IdentityPolicyValidator(),
|
|
1816
|
-
["permissionBinding"]: new PermissionBindingPolicyValidator(),
|
|
1817
|
-
["realmMatch"]: new RealmMatchPolicyValidator()
|
|
1818
|
-
};
|
|
1819
|
-
}
|
|
1820
1912
|
/**
|
|
1821
1913
|
* The one definition of what a policy looks like on the wire, used by the server
|
|
1822
1914
|
* to build a document and by the consumer to validate one. A node is the OUTPUT
|
|
@@ -1824,17 +1916,28 @@ function createValidators() {
|
|
|
1824
1916
|
* such as `id`, `name`, `builtIn` or `createdAt` never travel), plus its type
|
|
1825
1917
|
* and, for a composite, its projected children.
|
|
1826
1918
|
*
|
|
1919
|
+
* The type set is the `validators` registry, `PolicyDefaultValidators` unless
|
|
1920
|
+
* the caller hands another (#3635): a type the registry lacks is refused, so
|
|
1921
|
+
* the server and a consumer that register the same custom type let it travel,
|
|
1922
|
+
* and one that does not denies it. The withheld node is refused whatever the
|
|
1923
|
+
* registry says, since projecting it would evaluate a tree the caller was not
|
|
1924
|
+
* allowed to see.
|
|
1925
|
+
*
|
|
1827
1926
|
* Every refusal is a `ValidupError`, the node's head and the type's own
|
|
1828
1927
|
* validator alike, and a child's issues are rebased onto the position it sits
|
|
1829
1928
|
* at, so one message names the node in the tree that is wrong.
|
|
1830
1929
|
*/
|
|
1831
|
-
async function projectAuthorizationPolicy(input) {
|
|
1930
|
+
async function projectAuthorizationPolicy(input, validators = PolicyDefaultValidators) {
|
|
1832
1931
|
const headValidator = new AuthorizationPolicyHeadValidator();
|
|
1833
|
-
const validators = createValidators();
|
|
1834
1932
|
const project = async (value) => {
|
|
1835
1933
|
const head = await headValidator.run(value);
|
|
1934
|
+
const validator = head.type !== "withheld" && Object.hasOwn(validators, head.type) ? validators[head.type] : void 0;
|
|
1935
|
+
if (!validator) throw new ValidupError([defineIssueItem({
|
|
1936
|
+
message: `The policy type ${head.type} is not supported.`,
|
|
1937
|
+
path: ["type"]
|
|
1938
|
+
})]);
|
|
1836
1939
|
const output = {
|
|
1837
|
-
...await
|
|
1940
|
+
...await validator.run(value),
|
|
1838
1941
|
type: head.type
|
|
1839
1942
|
};
|
|
1840
1943
|
for (const key of Object.keys(output)) if (typeof output[key] === "undefined") delete output[key];
|
|
@@ -1866,9 +1969,19 @@ function containsBindingCheck(policy) {
|
|
|
1866
1969
|
}
|
|
1867
1970
|
//#endregion
|
|
1868
1971
|
//#region src/permission/authorization/module.ts
|
|
1972
|
+
/**
|
|
1973
|
+
* Every value `realmScopeMatches` decides, and nothing it would have to guess
|
|
1974
|
+
* at (#3636): a realm key, `null` for a global row, or a list of either for a
|
|
1975
|
+
* row spanning several realms. An empty key and an empty list are legal and
|
|
1976
|
+
* DENY there (no identity's realm is the empty string, and the empty set is
|
|
1977
|
+
* fail-closed), so refusing them here would make the consumer the one side
|
|
1978
|
+
* that errors where the server answers. `undefined` stays refused: the server
|
|
1979
|
+
* coerces it to `null`, which reads as a global row, and a caller passing an
|
|
1980
|
+
* absent column should hear about it rather than reach the global rows.
|
|
1981
|
+
*/
|
|
1869
1982
|
const realmMatchSchema = z.union([
|
|
1870
|
-
z.string()
|
|
1871
|
-
z.array(z.string().
|
|
1983
|
+
z.string(),
|
|
1984
|
+
z.array(z.string().nullable()),
|
|
1872
1985
|
z.null()
|
|
1873
1986
|
]);
|
|
1874
1987
|
/**
|
|
@@ -1908,9 +2021,9 @@ function toPolicy(tree) {
|
|
|
1908
2021
|
* the permission denies until the policy is fixed.
|
|
1909
2022
|
*
|
|
1910
2023
|
* A tree THIS copy cannot project is the same condition read from the other
|
|
1911
|
-
* side, and it is per tree: a policy type
|
|
1912
|
-
*
|
|
1913
|
-
* configuration its validator refuses denies the definitions that reference
|
|
2024
|
+
* side, and it is per tree: a policy type the validator registry lacks (a
|
|
2025
|
+
* type newer than this package, or a custom one the caller did not register)
|
|
2026
|
+
* or a configuration its validator refuses denies the definitions that reference
|
|
1914
2027
|
* it, exactly as `policies: null` does, and drops a grant that names it,
|
|
1915
2028
|
* exactly as a binding check does. One such tree never takes the evaluator
|
|
1916
2029
|
* down for the permissions that do not use it. A malformed catalog still
|
|
@@ -1932,13 +2045,20 @@ function toPolicy(tree) {
|
|
|
1932
2045
|
* rejected or evaluated over every candidate before paging. The supplied
|
|
1933
2046
|
* identity is authoritative; `options.decisionStrategy` is forwarded and the
|
|
1934
2047
|
* policy include, exclude and pending options are refused.
|
|
2048
|
+
*
|
|
2049
|
+
* The policy type set is open (#3635): `options.validators` decides which
|
|
2050
|
+
* trees project and `options.evaluators` how they evaluate, the built-in
|
|
2051
|
+
* registries by default. A custom type needs both, the validator the server
|
|
2052
|
+
* projected it with and the evaluator the server decides it with; given only
|
|
2053
|
+
* the first it projects and then denies. The binding evaluator is always this
|
|
2054
|
+
* function's own, since it is what binds the introspected grants.
|
|
1935
2055
|
*/
|
|
1936
|
-
async function createAuthorizationEvaluator(input) {
|
|
2056
|
+
async function createAuthorizationEvaluator(input, options = {}) {
|
|
1937
2057
|
const { catalog, grants, identity } = await parseAuthorizationEvaluatorInput(input);
|
|
1938
2058
|
const trees = /* @__PURE__ */ new Map();
|
|
1939
2059
|
const unevaluable = /* @__PURE__ */ new Set();
|
|
1940
2060
|
for (const [id, raw] of Object.entries(catalog.policies)) try {
|
|
1941
|
-
trees.set(id, await projectAuthorizationPolicy(raw));
|
|
2061
|
+
trees.set(id, await projectAuthorizationPolicy(raw, options.validators));
|
|
1942
2062
|
} catch {
|
|
1943
2063
|
unevaluable.add(id);
|
|
1944
2064
|
}
|
|
@@ -2011,7 +2131,7 @@ async function createAuthorizationEvaluator(input) {
|
|
|
2011
2131
|
policies: policies.length > 0 ? policies : void 0
|
|
2012
2132
|
});
|
|
2013
2133
|
}
|
|
2014
|
-
const engine = new PolicyEngine(PolicyDefaultEvaluators);
|
|
2134
|
+
const engine = new PolicyEngine(options.evaluators ?? PolicyDefaultEvaluators);
|
|
2015
2135
|
engine.registerEvaluator("permissionBinding", new IdentityPermissionBindingPolicyEvaluator({ getFor: async () => bindings }));
|
|
2016
2136
|
const evaluator = new PermissionEvaluator({
|
|
2017
2137
|
provider: new PermissionMemoryProvider(definitions),
|
|
@@ -2147,6 +2267,6 @@ async function createAuthorizationCheckEvaluator(input) {
|
|
|
2147
2267
|
};
|
|
2148
2268
|
}
|
|
2149
2269
|
//#endregion
|
|
2150
|
-
export { AUTHORIZATION_CATALOG_STALE_ERROR_INSTANCE, AUTHORIZATION_POLICY_WITHHELD_TYPE, AttributeNamesPolicyEvaluator, AttributeNamesPolicyValidator, AttributesPolicyEvaluator, AttributesPolicyValidator, AuthorizationCatalogStaleError, AuthorizationCheckEvaluatorInputValidator, AuthorizationEvaluatorInputValidator, BuiltInPolicyType, CompositePolicyEvaluator, CompositePolicyValidator, DatePolicyEvaluator, DatePolicyValidator, IdentityPermissionBindingPolicyEvaluator, IdentityPolicyEvaluator, IdentityPolicyValidator, PERMISSION_ERROR_INSTANCE, POLICY_ERROR_INSTANCE, PermissionBindingPolicyEvaluator, PermissionBindingPolicyValidator, PermissionError, PermissionEvaluator, PermissionMemoryProvider, PolicyData, PolicyDefaultEvaluators, PolicyEngine, PolicyError, PolicyIssueCode, PolicyIssueSeverity, REALM_SCOPE_ORDER, RealmMatchPolicyEvaluator, RealmMatchPolicyValidator, RealmScope, SystemPolicyName, TimePolicyEvaluator, TimePolicyInterval, TimePolicyValidator, aggregatePermissionPolicyBindings, authorizationCatalogSchema, authorizationCheckPermissionSchema, authorizationCheckPermissionsSchema, authorizationDefinitionSchema, authorizationGrantSchema, authorizationIdentitySchema, authorizationPolicySchema, buildPermissionKey, compareRealmScope, containsBindingCheck, createAuthorizationCheckEvaluator, createAuthorizationEvaluator, defineAttributesPolicy, definePolicyData, definePolicyEvaluationContext, definePolicyIssueGroup, definePolicyIssueItem, definePolicyWithType, grantDominates, isAuthorizationCatalogStaleError, isCompositePolicy, isIntervalForDayOfMonth, isIntervalForDayOfWeek, isIntervalForDayOfYear, isPermissionError, isPermissionPolicyBindingEqual, isPolicyError, maxRealmScope, maybeInvertPolicyOutcome, minRealmScope, normalizeRealmScope, parseAuthorizationCheckEvaluatorInput, parseAuthorizationEvaluatorInput, projectAuthorizationPolicy, realmScopeMatches };
|
|
2270
|
+
export { AUTHORIZATION_CATALOG_STALE_ERROR_INSTANCE, AUTHORIZATION_POLICY_WITHHELD_TYPE, AttributeNamesPolicyEvaluator, AttributeNamesPolicyValidator, AttributesPolicyEvaluator, AttributesPolicyValidator, AuthorizationCatalogStaleError, AuthorizationCheckEvaluatorInputValidator, AuthorizationEvaluatorInputValidator, BuiltInPolicyType, CompositePolicyEvaluator, CompositePolicyValidator, DatePolicyEvaluator, DatePolicyValidator, IdentityPermissionBindingPolicyEvaluator, IdentityPolicyEvaluator, IdentityPolicyValidator, PERMISSION_ERROR_INSTANCE, POLICY_ERROR_INSTANCE, PermissionBindingPolicyEvaluator, PermissionBindingPolicyValidator, PermissionError, PermissionEvaluator, PermissionMemoryProvider, PolicyData, PolicyDefaultEvaluators, PolicyDefaultValidators, PolicyEngine, PolicyError, PolicyIssueCode, PolicyIssueSeverity, REALM_SCOPE_ORDER, RealmMatchPolicyEvaluator, RealmMatchPolicyValidator, RealmScope, SystemPolicyName, TimePolicyEvaluator, TimePolicyInterval, TimePolicyValidator, aggregatePermissionPolicyBindings, authorizationCatalogSchema, authorizationCheckPermissionSchema, authorizationCheckPermissionsSchema, authorizationDefinitionSchema, authorizationGrantSchema, authorizationIdentitySchema, authorizationPolicySchema, buildPermissionKey, compareRealmScope, containsBindingCheck, createAuthorizationCheckEvaluator, createAuthorizationEvaluator, createPolicyTransitionCollector, defineAttributesPolicy, definePolicyData, definePolicyEvaluationContext, definePolicyIssueGroup, definePolicyIssueItem, definePolicyWithType, grantDominates, isAuthorizationCatalogStaleError, isCompositePolicy, isIntervalForDayOfMonth, isIntervalForDayOfWeek, isIntervalForDayOfYear, isPermissionError, isPermissionPolicyBindingEqual, isPolicyError, maxRealmScope, maybeInvertPolicyOutcome, minRealmScope, normalizeRealmScope, parseAuthorizationCheckEvaluatorInput, parseAuthorizationEvaluatorInput, projectAuthorizationPolicy, realmScopeMatches };
|
|
2151
2271
|
|
|
2152
2272
|
//# sourceMappingURL=index.mjs.map
|