@astram/guard 0.22.0 → 0.23.0
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/completeness/catalog-reconciler.d.ts +16 -1
- package/dist/completeness/catalog-reconciler.d.ts.map +1 -1
- package/dist/completeness/catalog-reconciler.js +70 -6
- package/dist/completeness/ports/catalog-store.d.ts +38 -3
- package/dist/completeness/ports/catalog-store.d.ts.map +1 -1
- package/dist/identity/module-registry.bridge.d.ts +9 -1
- package/dist/identity/module-registry.bridge.d.ts.map +1 -1
- package/dist/identity/module-registry.bridge.js +19 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -5
- package/migrations/1710000000107-AddPermissionTextAndFirstSeen.cjs +43 -0
- package/package.json +4 -4
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { OperationInventory, ModuleRegistry } from '@astram/core';
|
|
2
|
+
import type { PermissionText } from '@astram/engine';
|
|
2
3
|
import type { CatalogStore, ReconcileReport } from './ports/catalog-store.js';
|
|
3
4
|
/** A @Classified route could not be gated (stranded or key-not-registered). Boot must
|
|
4
5
|
* abort — an ungatable route may never serve traffic (ADR-0002 fail-closed). */
|
|
@@ -15,7 +16,21 @@ export declare class CatalogReconciler {
|
|
|
15
16
|
* CRON — mutating. Auto-adds an ACTIVE catalog row per registered non-public action,
|
|
16
17
|
* marks orphaned any stored row with no registered action, reactivates revived ones.
|
|
17
18
|
* Idempotent. Returns a report for logging + /health/catalog.
|
|
19
|
+
*
|
|
20
|
+
* G-027 (spec §5E): `opts.text` (from `permissionTextByKey`) supplies label, description
|
|
21
|
+
* and caution; a key without text gets the engine's generated label. An insert stamps
|
|
22
|
+
* `firstSeenAt`/`lastActivatedAt = nowIso` and `firstSeenVersion = opts.release ?? null`;
|
|
23
|
+
* a reactivation stamps `lastActivatedAt` only. First-seen fields are never sent anywhere
|
|
24
|
+
* but the insert (spec §11, §13). A registered row whose text differs from `opts.text` is
|
|
25
|
+
* rewritten through ONE `store.updateText` call (skipped when the store lacks it).
|
|
18
26
|
*/
|
|
19
|
-
reconcile(registry: ModuleRegistry, store: CatalogStore, nowIso: string): Promise<ReconcileReport>;
|
|
27
|
+
reconcile(registry: ModuleRegistry, store: CatalogStore, nowIso: string, opts?: ReconcileOptions): Promise<ReconcileReport>;
|
|
28
|
+
}
|
|
29
|
+
/** Options of {@link CatalogReconciler.reconcile} (G-027, spec §5E). */
|
|
30
|
+
export interface ReconcileOptions {
|
|
31
|
+
/** Permission key → code text (`permissionTextByKey`). Absent ⇒ generated labels, no relabel. */
|
|
32
|
+
readonly text?: ReadonlyMap<string, PermissionText>;
|
|
33
|
+
/** The app release (`APP_RELEASE`) stamped as `firstSeenVersion` on insert; absent ⇒ null. */
|
|
34
|
+
readonly release?: string | null;
|
|
20
35
|
}
|
|
21
36
|
//# sourceMappingURL=catalog-reconciler.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalog-reconciler.d.ts","sourceRoot":"","sources":["../../src/completeness/catalog-reconciler.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"catalog-reconciler.d.ts","sourceRoot":"","sources":["../../src/completeness/catalog-reconciler.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEvE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD,OAAO,KAAK,EAEV,YAAY,EAEZ,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAElC;iFACiF;AACjF,qBAAa,sBAAuB,SAAQ,KAAK;gBACnC,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,iBAAiB;IAC5B;;;OAGG;IACH,aAAa,CAAC,SAAS,EAAE,kBAAkB,EAAE,QAAQ,EAAE,cAAc,GAAG,IAAI;IAgB5E;;;;;;;;;;;OAWG;IACG,SAAS,CACb,QAAQ,EAAE,cAAc,EACxB,KAAK,EAAE,YAAY,EACnB,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,gBAAgB,GACtB,OAAO,CAAC,eAAe,CAAC;CA2D5B;AAED,wEAAwE;AACxE,MAAM,WAAW,gBAAgB;IAC/B,iGAAiG;IACjG,QAAQ,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACpD,8FAA8F;IAC9F,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC"}
|
|
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.CatalogReconciler = exports.CatalogGatabilityError = void 0;
|
|
4
4
|
// astram-framework/packages/guard/src/completeness/catalog-reconciler.ts
|
|
5
5
|
const core_1 = require("@astram/core");
|
|
6
|
+
const engine_1 = require("@astram/engine");
|
|
7
|
+
const identity_actions_js_1 = require("../identity/identity-actions.js");
|
|
6
8
|
/** A @Classified route could not be gated (stranded or key-not-registered). Boot must
|
|
7
9
|
* abort — an ungatable route may never serve traffic (ADR-0002 fail-closed). */
|
|
8
10
|
class CatalogGatabilityError extends Error {
|
|
@@ -32,43 +34,105 @@ class CatalogReconciler {
|
|
|
32
34
|
* CRON — mutating. Auto-adds an ACTIVE catalog row per registered non-public action,
|
|
33
35
|
* marks orphaned any stored row with no registered action, reactivates revived ones.
|
|
34
36
|
* Idempotent. Returns a report for logging + /health/catalog.
|
|
37
|
+
*
|
|
38
|
+
* G-027 (spec §5E): `opts.text` (from `permissionTextByKey`) supplies label, description
|
|
39
|
+
* and caution; a key without text gets the engine's generated label. An insert stamps
|
|
40
|
+
* `firstSeenAt`/`lastActivatedAt = nowIso` and `firstSeenVersion = opts.release ?? null`;
|
|
41
|
+
* a reactivation stamps `lastActivatedAt` only. First-seen fields are never sent anywhere
|
|
42
|
+
* but the insert (spec §11, §13). A registered row whose text differs from `opts.text` is
|
|
43
|
+
* rewritten through ONE `store.updateText` call (skipped when the store lacks it).
|
|
35
44
|
*/
|
|
36
|
-
async reconcile(registry, store, nowIso) {
|
|
45
|
+
async reconcile(registry, store, nowIso, opts) {
|
|
46
|
+
const text = opts?.text;
|
|
47
|
+
const release = opts?.release ?? null;
|
|
37
48
|
const stored = await store.listPermissions();
|
|
38
49
|
const storedByKey = new Map(stored.map((r) => [r.permissionKey, r]));
|
|
39
50
|
const registered = registry.listActions().filter((a) => a.tier !== 'public');
|
|
40
51
|
const registeredKeys = new Set(registered.map((a) => a.permissionKey));
|
|
41
|
-
// code → catalog: add missing rows; revive orphaned-but-now-registered.
|
|
52
|
+
// code → catalog: add missing rows; revive orphaned-but-now-registered; queue text rewrites.
|
|
42
53
|
const added = [];
|
|
43
54
|
const reactivated = [];
|
|
55
|
+
const textUpdates = [];
|
|
44
56
|
for (const a of registered) {
|
|
45
57
|
const key = a.permissionKey;
|
|
46
58
|
const existing = storedByKey.get(key);
|
|
47
59
|
if (!existing) {
|
|
60
|
+
const t = text?.get(key) ?? generatedText(registry, a.action.typeKey, a.action.actionKey);
|
|
48
61
|
const inserted = await store.upsertPermission({
|
|
49
62
|
permissionKey: key,
|
|
50
63
|
moduleKey: a.moduleKey,
|
|
51
64
|
typeKey: a.action.typeKey,
|
|
52
65
|
action: a.action.actionKey,
|
|
53
|
-
label:
|
|
66
|
+
label: t.label,
|
|
54
67
|
tier: a.tier,
|
|
68
|
+
description: t.description,
|
|
69
|
+
caution: t.caution,
|
|
70
|
+
firstSeenAt: nowIso,
|
|
71
|
+
firstSeenVersion: release,
|
|
72
|
+
lastActivatedAt: nowIso,
|
|
55
73
|
});
|
|
56
74
|
if (inserted)
|
|
57
75
|
added.push(key);
|
|
76
|
+
continue;
|
|
58
77
|
}
|
|
59
|
-
|
|
78
|
+
if (existing.status === 'orphaned')
|
|
60
79
|
reactivated.push(key);
|
|
80
|
+
const t = text?.get(key);
|
|
81
|
+
if (t && textDiffers(existing, t)) {
|
|
82
|
+
textUpdates.push({
|
|
83
|
+
permissionKey: key,
|
|
84
|
+
label: t.label,
|
|
85
|
+
description: t.description,
|
|
86
|
+
caution: t.caution,
|
|
87
|
+
});
|
|
61
88
|
}
|
|
62
89
|
}
|
|
63
90
|
if (reactivated.length)
|
|
64
|
-
await store.markActive(reactivated);
|
|
91
|
+
await store.markActive(reactivated, nowIso);
|
|
92
|
+
const relabelled = [];
|
|
93
|
+
if (textUpdates.length && store.updateText) {
|
|
94
|
+
await store.updateText(textUpdates);
|
|
95
|
+
relabelled.push(...textUpdates.map((u) => u.permissionKey));
|
|
96
|
+
}
|
|
65
97
|
// catalog → code: mark orphaned any active stored row with no registered action.
|
|
66
98
|
const orphaned = stored
|
|
67
99
|
.filter((r) => r.status === 'active' && !registeredKeys.has(r.permissionKey))
|
|
68
100
|
.map((r) => r.permissionKey);
|
|
69
101
|
if (orphaned.length)
|
|
70
102
|
await store.markOrphaned(orphaned);
|
|
71
|
-
return { added, orphaned, reactivated, at: nowIso };
|
|
103
|
+
return { added, orphaned, reactivated, relabelled, at: nowIso };
|
|
72
104
|
}
|
|
73
105
|
}
|
|
74
106
|
exports.CatalogReconciler = CatalogReconciler;
|
|
107
|
+
/** Stored vs code text, with absent/undefined normalised to null. */
|
|
108
|
+
function textDiffers(row, t) {
|
|
109
|
+
return (row.label !== t.label ||
|
|
110
|
+
(row.description ?? null) !== (t.description ?? null) ||
|
|
111
|
+
(row.caution ?? null) !== (t.caution ?? null));
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* The engine's generated text for a key with no text map entry (spec §10): engine
|
|
115
|
+
* `permissionTextOf` over a one-action declaration, the type label taken from the registry
|
|
116
|
+
* descriptor when it differs from the typeKey (the bridge sets `reg.label ?? typeKey`), else
|
|
117
|
+
* the humanized typeKey. A registry the engine rules cannot describe (e.g. a non-engine
|
|
118
|
+
* module's reserved action or an out-of-limits label) keeps the pre-G-027 label.
|
|
119
|
+
*/
|
|
120
|
+
function generatedText(registry, typeKey, actionKey) {
|
|
121
|
+
const descriptorLabel = registry.resolveObjectType(typeKey)?.label;
|
|
122
|
+
const label = descriptorLabel && descriptorLabel !== typeKey ? descriptorLabel : undefined;
|
|
123
|
+
const isCrud = identity_actions_js_1.IDENTITY_ACTIONS.includes(actionKey);
|
|
124
|
+
try {
|
|
125
|
+
const [t] = (0, engine_1.permissionTextOf)({
|
|
126
|
+
typeKey,
|
|
127
|
+
...(label !== undefined ? { label } : {}),
|
|
128
|
+
...(isCrud ? {} : { crudActions: false, actions: [actionKey] }),
|
|
129
|
+
}).filter((p) => p.action === actionKey);
|
|
130
|
+
if (t)
|
|
131
|
+
return t;
|
|
132
|
+
}
|
|
133
|
+
catch (err) {
|
|
134
|
+
if (!(err instanceof engine_1.RegistrationError))
|
|
135
|
+
throw err;
|
|
136
|
+
}
|
|
137
|
+
return { label: `${actionKey} ${typeKey}`, description: null, caution: null };
|
|
138
|
+
}
|
|
@@ -3,6 +3,12 @@
|
|
|
3
3
|
* the consumer app supplies the implementation (ADR-0003 — guard does no DB). A row is
|
|
4
4
|
* keyed by its permission key (`moduleKey:typeKey:actionKey`); `status` is the soft
|
|
5
5
|
* active/orphaned marker (never hard-delete).
|
|
6
|
+
*
|
|
7
|
+
* G-027 (permission text + first seen): the text and date fields are OPTIONAL and additive,
|
|
8
|
+
* so a store written before them keeps compiling. `firstSeenAt`/`firstSeenVersion` are
|
|
9
|
+
* written once, by the insert, and never changed afterwards (insert-only; the reconciler never
|
|
10
|
+
* asks the store to update them). Dates are ISO strings; `null` = unknown (e.g. a key that
|
|
11
|
+
* existed before tracking).
|
|
6
12
|
*/
|
|
7
13
|
export interface CatalogPermissionRow {
|
|
8
14
|
readonly permissionKey: string;
|
|
@@ -12,22 +18,51 @@ export interface CatalogPermissionRow {
|
|
|
12
18
|
readonly label: string;
|
|
13
19
|
readonly tier: string;
|
|
14
20
|
readonly status: 'active' | 'orphaned';
|
|
21
|
+
/** What holding the permission lets a person do (plain text). */
|
|
22
|
+
readonly description?: string | null;
|
|
23
|
+
/** Optional warning shown to whoever grants it (plain text). */
|
|
24
|
+
readonly caution?: string | null;
|
|
25
|
+
/** When the key was first catalogued (ISO); insert-only. */
|
|
26
|
+
readonly firstSeenAt?: string | null;
|
|
27
|
+
/** The app release (`APP_RELEASE`) that first catalogued the key; insert-only. */
|
|
28
|
+
readonly firstSeenVersion?: string | null;
|
|
29
|
+
/** When the key last became active (insert or orphaned → active), ISO. */
|
|
30
|
+
readonly lastActivatedAt?: string | null;
|
|
31
|
+
}
|
|
32
|
+
/** One text rewrite the reconciler asks for (code text replaces stored text, G-027). */
|
|
33
|
+
export interface CatalogTextUpdate {
|
|
34
|
+
readonly permissionKey: string;
|
|
35
|
+
readonly label: string;
|
|
36
|
+
readonly description: string | null;
|
|
37
|
+
readonly caution: string | null;
|
|
15
38
|
}
|
|
16
39
|
/** The result of one mutating reconcile pass — surfaced via /health/catalog + logged. */
|
|
17
40
|
export interface ReconcileReport {
|
|
18
41
|
readonly added: readonly string[];
|
|
19
42
|
readonly orphaned: readonly string[];
|
|
20
43
|
readonly reactivated: readonly string[];
|
|
44
|
+
readonly relabelled: readonly string[];
|
|
21
45
|
readonly at: string;
|
|
22
46
|
}
|
|
23
47
|
export interface CatalogStore {
|
|
24
48
|
/** All catalog rows (both active + orphaned). */
|
|
25
49
|
listPermissions(): Promise<CatalogPermissionRow[]>;
|
|
26
|
-
/**
|
|
50
|
+
/**
|
|
51
|
+
* Idempotent insert of an ACTIVE row (no-op if the key already exists). Insert-only: an
|
|
52
|
+
* existing row is never updated here, so its first-seen fields keep their first values.
|
|
53
|
+
*/
|
|
27
54
|
upsertPermission(row: Omit<CatalogPermissionRow, 'status'>): Promise<boolean>;
|
|
28
55
|
/** Mark keys orphaned (soft). No-op for keys already orphaned. */
|
|
29
56
|
markOrphaned(keys: readonly string[]): Promise<void>;
|
|
30
|
-
/**
|
|
31
|
-
|
|
57
|
+
/**
|
|
58
|
+
* Flip keys orphaned → active (a route returned). With `nowIso`, stamp `lastActivatedAt`;
|
|
59
|
+
* never touch `firstSeenAt`/`firstSeenVersion`.
|
|
60
|
+
*/
|
|
61
|
+
markActive(keys: readonly string[], nowIso?: string): Promise<void>;
|
|
62
|
+
/**
|
|
63
|
+
* OPTIONAL (G-027): rewrite label/description/caution of existing rows to the code's text.
|
|
64
|
+
* Writes only those three fields. A store without it still reconciles (no relabelling).
|
|
65
|
+
*/
|
|
66
|
+
updateText?(rows: readonly CatalogTextUpdate[]): Promise<void>;
|
|
32
67
|
}
|
|
33
68
|
//# sourceMappingURL=catalog-store.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalog-store.d.ts","sourceRoot":"","sources":["../../../src/completeness/ports/catalog-store.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"catalog-store.d.ts","sourceRoot":"","sources":["../../../src/completeness/ports/catalog-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,QAAQ,GAAG,UAAU,CAAC;IACvC,iEAAiE;IACjE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,gEAAgE;IAChE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,4DAA4D;IAC5D,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,kFAAkF;IAClF,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,0EAA0E;IAC1E,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1C;AAED,wFAAwF;AACxF,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED,yFAAyF;AACzF,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,iDAAiD;IACjD,eAAe,IAAI,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAAC;IACnD;;;OAGG;IACH,gBAAgB,CAAC,GAAG,EAAE,IAAI,CAAC,oBAAoB,EAAE,QAAQ,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9E,kEAAkE;IAClE,YAAY,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD;;;OAGG;IACH,UAAU,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpE;;;OAGG;IACH,UAAU,CAAC,CAAC,IAAI,EAAE,SAAS,iBAAiB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAChE"}
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import type { ModuleRegistry } from '@astram/core';
|
|
2
|
-
import type { ObjectTypeInput } from '@astram/engine';
|
|
2
|
+
import type { ObjectTypeInput, PermissionText } from '@astram/engine';
|
|
3
3
|
export declare function buildIdentityModuleRegistry(inputs: readonly ObjectTypeInput[]): ModuleRegistry;
|
|
4
|
+
/**
|
|
5
|
+
* G-027 (spec §5D): the permission text of every action of the given types, keyed by the SAME
|
|
6
|
+
* permission key {@link buildIdentityModuleRegistry} registers (`MODULE_KEY` + core
|
|
7
|
+
* `derivePermissionKey`). Engine `permissionTextOf` gives the text in `effectiveActions` order
|
|
8
|
+
* (= {@link actionsOf}); declared text wins, else the generated label. Throws engine's
|
|
9
|
+
* `RegistrationError` on invalid text, like the registry build.
|
|
10
|
+
*/
|
|
11
|
+
export declare function permissionTextByKey(inputs: readonly ObjectTypeInput[]): ReadonlyMap<string, PermissionText>;
|
|
4
12
|
//# sourceMappingURL=module-registry.bridge.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module-registry.bridge.d.ts","sourceRoot":"","sources":["../../src/identity/module-registry.bridge.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EACV,cAAc,EAIf,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAc,eAAe,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"module-registry.bridge.d.ts","sourceRoot":"","sources":["../../src/identity/module-registry.bridge.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EACV,cAAc,EAIf,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAc,eAAe,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AASlF,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,GAAG,cAAc,CAgC9F;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,SAAS,eAAe,EAAE,GACjC,WAAW,CAAC,MAAM,EAAE,cAAc,CAAC,CAQrC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.buildIdentityModuleRegistry = buildIdentityModuleRegistry;
|
|
4
|
+
exports.permissionTextByKey = permissionTextByKey;
|
|
4
5
|
/**
|
|
5
6
|
* Bridge: engine ObjectTypes → a populated core ModuleRegistry. Ported from astram3 (framework
|
|
6
7
|
* now owns identity). Engine ObjectTypes describe physical tables; core's gates + the
|
|
@@ -25,7 +26,8 @@ function buildIdentityModuleRegistry(inputs) {
|
|
|
25
26
|
const access = (0, core_access_js_1.coreAccessOf)(r.access);
|
|
26
27
|
return {
|
|
27
28
|
typeKey: r.typeKey,
|
|
28
|
-
|
|
29
|
+
// G-027: the type's declared human name, else its typeKey (core contract unchanged).
|
|
30
|
+
label: r.label ?? r.typeKey,
|
|
29
31
|
fields: r.fields.map((f) => {
|
|
30
32
|
const ref = (0, engine_1.referencedTypeOf)(f);
|
|
31
33
|
return { key: f.key, label: f.key, ...(ref ? { referencesTypeKey: ref } : {}) };
|
|
@@ -48,3 +50,19 @@ function buildIdentityModuleRegistry(inputs) {
|
|
|
48
50
|
registry.register(metadata);
|
|
49
51
|
return registry;
|
|
50
52
|
}
|
|
53
|
+
/**
|
|
54
|
+
* G-027 (spec §5D): the permission text of every action of the given types, keyed by the SAME
|
|
55
|
+
* permission key {@link buildIdentityModuleRegistry} registers (`MODULE_KEY` + core
|
|
56
|
+
* `derivePermissionKey`). Engine `permissionTextOf` gives the text in `effectiveActions` order
|
|
57
|
+
* (= {@link actionsOf}); declared text wins, else the generated label. Throws engine's
|
|
58
|
+
* `RegistrationError` on invalid text, like the registry build.
|
|
59
|
+
*/
|
|
60
|
+
function permissionTextByKey(inputs) {
|
|
61
|
+
const out = new Map();
|
|
62
|
+
for (const reg of inputs.map(toObjectType)) {
|
|
63
|
+
for (const t of (0, engine_1.permissionTextOf)(reg)) {
|
|
64
|
+
out.set((0, core_1.derivePermissionKey)(identity_actions_js_1.MODULE_KEY, reg.typeKey, t.action), t);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return out;
|
|
68
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -15,7 +15,8 @@
|
|
|
15
15
|
* `@nestjs/core`, `reflect-metadata`, `rxjs` so the host owns one copy of each.
|
|
16
16
|
*/
|
|
17
17
|
export { guardMigrationsDir } from './migrations-dir.js';
|
|
18
|
-
export { buildIdentityModuleRegistry } from './identity/module-registry.bridge.js';
|
|
18
|
+
export { buildIdentityModuleRegistry, permissionTextByKey, } from './identity/module-registry.bridge.js';
|
|
19
|
+
export type { PermissionText } from '@astram/engine';
|
|
19
20
|
export { MODULE_KEY, IDENTITY_ACTIONS, CROSS_TENANT_GRANT_ACTIONS, RECORD_SHARE_ACTIONS, SERVICE_ACCOUNT_ACTIONS, actionsFor, actionsOf, } from './identity/identity-actions.js';
|
|
20
21
|
export { ShieldModule, SHIELD_DECISION_AUTHORITY, SHIELD_RECORD_AUTHORIZATION, type ShieldModuleOptions, type ShieldModuleAsyncOptions, type RecordAuthorizationInputs, } from './module/shield.module.js';
|
|
21
22
|
export { Public, Classified, CLASSIFICATION_METADATA, DEFAULT_CLASSIFIED_ACTION, normalizeClassification, } from './enforcement/classification.decorator.js';
|
|
@@ -23,7 +24,8 @@ export type { Classification } from './enforcement/classification.decorator.js';
|
|
|
23
24
|
export { UuidPipe, uuidField, optionalUuidField, uuidArrayField } from './enforcement/uuid.pipe.js';
|
|
24
25
|
export { OperationInventoryScanner } from './completeness/operation-inventory-scanner.js';
|
|
25
26
|
export { CatalogReconciler, CatalogGatabilityError } from './completeness/catalog-reconciler.js';
|
|
26
|
-
export type {
|
|
27
|
+
export type { ReconcileOptions } from './completeness/catalog-reconciler.js';
|
|
28
|
+
export type { CatalogStore, CatalogPermissionRow, CatalogTextUpdate, ReconcileReport, } from './completeness/ports/catalog-store.js';
|
|
27
29
|
export { SHIELD_SESSION_TOKEN_BINDER, SHIELD_SERVICE_AUTHENTICATOR, } from './request-auth/tokens.js';
|
|
28
30
|
export { SessionTokenBinder } from './request-auth/session-token-binder.js';
|
|
29
31
|
export type { BoundPrincipalClaims, SessionTokenBinderOptions, } from './request-auth/session-token-binder.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AASzD,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -16,11 +16,11 @@
|
|
|
16
16
|
* `@nestjs/core`, `reflect-metadata`, `rxjs` so the host owns one copy of each.
|
|
17
17
|
*/
|
|
18
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
-
exports.
|
|
20
|
-
exports.
|
|
21
|
-
exports.
|
|
22
|
-
exports.
|
|
23
|
-
exports.ScopeUnknownParentError = exports.ScopeDepthError = exports.ScopeCycleError = exports.buildClosureRows = exports.ConfirmEmailController = exports.AccountController = exports.generateRecoveryCodes = exports.buildOtpauthUri = exports.generateTotpSecret = exports.SHIELD_LOGIN_TOTP_VERIFIER = exports.SHIELD_MFA_STEP_UP = exports.SHIELD_MFA_LIMITER = exports.challengeMatches = exports.credentialFingerprint = exports.CredentialMfaStepUp = exports.RedisPendingMfaStore = exports.PendingMfaStore = exports.AuthController = exports.SHIELD_SCOPE_SUBTREE_RESOLVER = void 0;
|
|
19
|
+
exports.assertNoUnresolvedSecretRefs = exports.createSecretsProviderFromEnv = exports.resolveBootSecrets = exports.EncryptedFileSecretsProvider = exports.LocalKekCrypto = exports.resolveAuthLinkBaseUrls = exports.CredentialExistsError = exports.isLockedHash = exports.lockedPasswordHash = exports.SHIELD_PASSWORD_HASHER = exports.argon2idHasherProvider = exports.Argon2idPasswordHasher = exports.stubDecisionAuthority = exports.GlobalEnforcementGuard = exports.NO_SESSION_FACTS = exports.SHIELD_SESSION_FACTS_ALS = exports.MariaDbApiKeyStore = exports.isApiKey = exports.extractBearerToken = exports.principalFromClaims = exports.resolveRequestAuth = exports.resolveRequestPrincipal = exports.SessionTokenBinder = exports.SHIELD_SERVICE_AUTHENTICATOR = exports.SHIELD_SESSION_TOKEN_BINDER = exports.CatalogGatabilityError = exports.CatalogReconciler = exports.OperationInventoryScanner = exports.uuidArrayField = exports.optionalUuidField = exports.uuidField = exports.UuidPipe = exports.normalizeClassification = exports.DEFAULT_CLASSIFIED_ACTION = exports.CLASSIFICATION_METADATA = exports.Classified = exports.Public = exports.SHIELD_RECORD_AUTHORIZATION = exports.SHIELD_DECISION_AUTHORITY = exports.ShieldModule = exports.actionsOf = exports.actionsFor = exports.SERVICE_ACCOUNT_ACTIONS = exports.RECORD_SHARE_ACTIONS = exports.CROSS_TENANT_GRANT_ACTIONS = exports.IDENTITY_ACTIONS = exports.MODULE_KEY = exports.permissionTextByKey = exports.buildIdentityModuleRegistry = exports.guardMigrationsDir = void 0;
|
|
20
|
+
exports.SHIELD_CROSS_TENANT_GRANT_WRITER = exports.CrossTenantGrantWriter = exports.SHIELD_CROSS_TENANT_GRANT_PORT = exports.MariaDbCrossTenantGrantAdapter = exports.makeShareDeleteCascade = exports.ShareStoreUnavailableError = exports.ShareNotPermittedError = exports.SHIELD_RECORD_SHARE_WRITER = exports.RecordShareWriter = exports.SHIELD_RECORD_SHARE_PORT = exports.MariaDbRecordShareAdapter = exports.UnknownScopeFieldError = exports.translateListScope = exports.SHIELD_LIST_SCOPE_PORT = exports.MariaDbListScopeAdapter = exports.SHIELD_POLICY_STORE = exports.MariaDbPolicyStore = exports.SHIELD_RECORD_RULE_PORT = exports.MariaDbRecordPermissionRuleAdapter = exports.accessBindingTtlMs = exports.ROTATE_GRACE_MS = exports.SHIELD_SESSION_LIFETIMES = exports.HotRevokingSessionRecordStore = exports.SHIELD_CLOCK = exports.SHIELD_REFRESH_HASHER = exports.SHIELD_TOKEN_GENERATOR = exports.systemClockProvider = exports.refreshHasherProvider = exports.cryptoTokenGeneratorProvider = exports.SystemClock = exports.Sha256RefreshTokenHasher = exports.CryptoTokenGenerator = exports.RedisRecentRotationStore = exports.SHIELD_HOT_SESSION_STORE = exports.RedisHotSessionStore = exports.SHIELD_SESSION_RECORD_STORE = exports.MariaDbSessionRecordStore = exports.DEFAULT_OBJECT_STORAGE_MAX_BYTES = exports.loadObjectStorageConfig = exports.SHIELD_FILE_INGEST = exports.SHIELD_OBJECT_STORE = exports.FILE_INTAKE_DEFAULT_MAX_BYTES = exports.FILE_INTAKE_REQUEST_KEY = exports.FileIntake = exports.ObjectStoreBootCheck = exports.loadAuditSealConfig = exports.NodeSha256Hash = exports.NodeSha256Digest = exports.S3ObjectStore = exports.wasResolvedFromSecretRef = void 0;
|
|
21
|
+
exports.reservedOperationPrincipal = exports.RESERVED_OPERATION_PRINCIPALS = exports.assertNoReservedRootId = exports.ORG_BOOTSTRAP_PRINCIPAL_ID = exports.rootIdsFromEnv = exports.loadPoolTuning = exports.loadDbTlsConfig = exports.isDevOrTestNodeEnv = exports.DEFAULT_LOGIN_IP_LIMIT = exports.loadRefreshReplayWindowMs = exports.loadLoginIpLimit = exports.DEFAULT_REDIS_URL = exports.DEFAULT_DB_CONFIG = exports.assertRefreshHmacKey = exports.loadRefreshHmacKey = exports.loadSessionLifetimes = exports.loadRedisConfig = exports.loadDbConfig = exports.SCHEMA_SVC_POOL_HARD_CAP = exports.DEFAULT_POOL_BUDGET = exports.evaluatePoolBudget = exports.loadPoolBudget = exports.loadAppConfig = exports.frameworkSchemasOf = exports.FRAMEWORK_SCHEMAS = exports.APP_CONFIG = exports.resolveMigrationLedgerCheck = exports.resolveMigrationLedger = exports.frameworkMigrationIds = exports.assertFrameworkMigrationsApplied = exports.SHIELD_MIGRATION_LEDGER_REGISTRY = exports.MigrationLedgerRegistry = exports.FrameworkMigrationLedgerCheck = exports.frameworkDatabasesLogLine = exports.assertPoolBudget = exports.BootSequence = exports.buildListScopeFn = exports.MariaDbSessionRestrictionStore = exports.SHIELD_SESSION_RESTRICTIONS = exports.SHIELD_PERMISSION_VERSION_CACHE = exports.DEFAULT_PERMISSION_VERSION_TTL_MS = exports.PERMISSION_VERSION_KEY_PREFIX = exports.RedisPermissionVersionCache = exports.withRedisPermissionVersion = exports.buildRecordAuthorization = exports.SHIELD_OPERATION_AUTHORITY_PORT = exports.ManifestOperationAuthorityAdapter = exports.GrantStoreUnavailableError = exports.InvalidGrantError = exports.GrantNotPermittedError = void 0;
|
|
22
|
+
exports.ProfileNameTakenError = exports.maskPhone = exports.MAX_MESSAGE_SEND_TIMEOUT_MS = exports.DEFAULT_MESSAGE_SEND_TIMEOUT_MS = exports.EMAIL_PROVIDER_VALUES = exports.loadMessageConfig = exports.MariaDbEmailAddressChanger = exports.maskEmail = exports.isEmailShaped = exports.canonicalEmail = exports.hmacSha1 = exports.resolveTotpVerifier = exports.makeDefaultTotpVerifier = exports.AuthModule = exports.SHIELD_CAPTCHA_GATE = exports.RECAPTCHA_SITEVERIFY_URL = exports.RecaptchaVerifier = exports.TURNSTILE_SITEVERIFY_URL = exports.TurnstileVerifier = exports.MAX_CAPTCHA_TIMEOUT_MS = exports.DEFAULT_CAPTCHA_TIMEOUT_MS = exports.DEFAULT_CAPTCHA_MIN_SCORE = exports.DEFAULT_CAPTCHA_THRESHOLD = exports.CAPTCHA_FAIL_MODES = exports.CAPTCHA_MODES = exports.CAPTCHA_ENDPOINTS = exports.loadCaptchaConfig = exports.SHIELD_SIGN_IN_WITH = exports.DEFAULT_SIGN_IN_WITH = exports.resolveSignInWith = exports.MariaDbCredentialResolver = exports.SHIELD_TOTP_VERIFIER_OVERRIDE = exports.SHIELD_MFA_DEVICE_STORE = exports.SHIELD_AUDIT_SINK = exports.SHIELD_SESSION_SWEEPER = exports.SHIELD_PROFILE_WRITER = exports.SHIELD_RECOVERY_CODE_STORE = exports.SHIELD_MESSAGE_DISPATCHER = exports.SHIELD_EMAIL_SENDER = exports.SHIELD_EMAIL_CHANGE_TOKEN_STORE = exports.SHIELD_RESET_TOKEN_STORE = exports.SHIELD_CREDENTIAL_WRITER = exports.SHIELD_SESSION_AUTHORITY = exports.SHIELD_AUTHENTICATOR = exports.SHIELD_PROFILE_RESOLVER = exports.SHIELD_CREDENTIAL_RESOLVER = exports.SHIELD_REDIS = exports.withoutStatementTimeout = exports.mariadbPoolTuningOptions = exports.mariadbSslOption = void 0;
|
|
23
|
+
exports.ScopeUnknownParentError = exports.ScopeDepthError = exports.ScopeCycleError = exports.buildClosureRows = exports.ConfirmEmailController = exports.AccountController = exports.generateRecoveryCodes = exports.buildOtpauthUri = exports.generateTotpSecret = exports.SHIELD_LOGIN_TOTP_VERIFIER = exports.SHIELD_MFA_STEP_UP = exports.SHIELD_MFA_LIMITER = exports.challengeMatches = exports.credentialFingerprint = exports.CredentialMfaStepUp = exports.RedisPendingMfaStore = exports.PendingMfaStore = exports.AuthController = exports.SHIELD_SCOPE_SUBTREE_RESOLVER = exports.SHIELD_SESSION_FACTS_PROJECTOR = void 0;
|
|
24
24
|
// Framework authz migrations (shield_authz DDL — permission / role_permission /
|
|
25
25
|
// authz_permission_version). Absolute path a consumer's `@astram/migrate` setup merges in.
|
|
26
26
|
var migrations_dir_js_1 = require("./migrations-dir.js");
|
|
@@ -34,6 +34,7 @@ Object.defineProperty(exports, "guardMigrationsDir", { enumerable: true, get: fu
|
|
|
34
34
|
// runtime option values the consumer threads in.
|
|
35
35
|
var module_registry_bridge_js_1 = require("./identity/module-registry.bridge.js");
|
|
36
36
|
Object.defineProperty(exports, "buildIdentityModuleRegistry", { enumerable: true, get: function () { return module_registry_bridge_js_1.buildIdentityModuleRegistry; } });
|
|
37
|
+
Object.defineProperty(exports, "permissionTextByKey", { enumerable: true, get: function () { return module_registry_bridge_js_1.permissionTextByKey; } });
|
|
37
38
|
var identity_actions_js_1 = require("./identity/identity-actions.js");
|
|
38
39
|
Object.defineProperty(exports, "MODULE_KEY", { enumerable: true, get: function () { return identity_actions_js_1.MODULE_KEY; } });
|
|
39
40
|
Object.defineProperty(exports, "IDENTITY_ACTIONS", { enumerable: true, get: function () { return identity_actions_js_1.IDENTITY_ACTIONS; } });
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework authz migration — G-027 step 1 (NAES G-034; docs/features/permission-notification/SPEC.md §4):
|
|
3
|
+
* a permission key's caution text and when it first appeared in the catalog.
|
|
4
|
+
*
|
|
5
|
+
* Adds to `permission`: `perm_caution` (app-declared caution, plain text), `perm_first_seen_at` /
|
|
6
|
+
* `perm_first_seen_version` (written once by the catalog reconcile when it first inserts the key;
|
|
7
|
+
* the version is `APP_RELEASE`, NULL when unset) and `perm_last_activated_at` (first insert and
|
|
8
|
+
* every orphaned → active flip). `perm_label` (007) and `perm_description` (006) are reused.
|
|
9
|
+
*
|
|
10
|
+
* No backfill: rows present when this runs keep NULL `perm_first_seen_at`, meaning "existed before
|
|
11
|
+
* tracking began", so a later admin-task step never raises tasks for them.
|
|
12
|
+
*
|
|
13
|
+
* Idempotent: `ADD COLUMN IF NOT EXISTS` / `DROP COLUMN IF EXISTS`. The timestamps are explicitly
|
|
14
|
+
* `NULL DEFAULT NULL` so MariaDB never auto-initialises them. Literal column names; run by the
|
|
15
|
+
* DDL account.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
const { frameworkSchemasForMigration } = require('@astram/core');
|
|
19
|
+
|
|
20
|
+
const COLUMNS = [
|
|
21
|
+
['perm_caution', 'VARCHAR(300) NULL DEFAULT NULL'],
|
|
22
|
+
['perm_first_seen_at', 'TIMESTAMP NULL DEFAULT NULL'],
|
|
23
|
+
['perm_first_seen_version', 'VARCHAR(64) NULL DEFAULT NULL'],
|
|
24
|
+
['perm_last_activated_at', 'TIMESTAMP NULL DEFAULT NULL'],
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
async function up(ctx) {
|
|
28
|
+
const { query } = ctx;
|
|
29
|
+
const SCHEMA = frameworkSchemasForMigration(ctx, process.env).authz;
|
|
30
|
+
for (const [name, type] of COLUMNS) {
|
|
31
|
+
await query(`ALTER TABLE \`${SCHEMA}\`.\`permission\` ADD COLUMN IF NOT EXISTS ${name} ${type}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async function down(ctx) {
|
|
36
|
+
const { query } = ctx;
|
|
37
|
+
const SCHEMA = frameworkSchemasForMigration(ctx, process.env).authz;
|
|
38
|
+
for (const [name] of [...COLUMNS].reverse()) {
|
|
39
|
+
await query(`ALTER TABLE \`${SCHEMA}\`.\`permission\` DROP COLUMN IF EXISTS ${name}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
module.exports = { up, down };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astram/guard",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Astram framework — the enforcement guard + real-world adapters (the 'hands'). One global deny-by-default gate every request passes through (ADR-0002), classification decorators, boot-pool assertion (ADR-0018), the forRoot() registration seam, and the DB/Redis/crypto adapters that connect the sealed core to a real backend. Depends on @astram/core (ADR-0003, ADR-0023).",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"argon2": "^0.41.1",
|
|
37
37
|
"ioredis": "^5.4.1",
|
|
38
38
|
"mariadb": "^3.5.4",
|
|
39
|
-
"@astram/engine": "0.
|
|
39
|
+
"@astram/engine": "0.16.0",
|
|
40
40
|
"@astram/core": "1.12.0"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"@nestjs/platform-express": "^11",
|
|
46
46
|
"reflect-metadata": "^0.2",
|
|
47
47
|
"rxjs": "^7",
|
|
48
|
-
"@astram/messaging": "^0.1.
|
|
48
|
+
"@astram/messaging": "^0.1.8"
|
|
49
49
|
},
|
|
50
50
|
"peerDependenciesMeta": {
|
|
51
51
|
"@astram/messaging": {
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"typescript": "^5.7.0",
|
|
69
69
|
"unplugin-swc": "^1.5.1",
|
|
70
70
|
"vitest": "^2.1.8",
|
|
71
|
-
"@astram/messaging": "0.1.
|
|
71
|
+
"@astram/messaging": "0.1.8"
|
|
72
72
|
},
|
|
73
73
|
"repository": {
|
|
74
74
|
"type": "git",
|