@astram/guard 0.5.1 → 0.7.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/auth/account.controller.d.ts.map +1 -1
- package/dist/auth/account.controller.js +3 -0
- package/dist/auth/account.controller.js.map +1 -0
- package/dist/auth/auth.controller.d.ts +90 -1
- package/dist/auth/auth.controller.d.ts.map +1 -1
- package/dist/auth/auth.controller.js +245 -7
- package/dist/auth/auth.controller.js.map +1 -0
- package/dist/auth/auth.module.d.ts +21 -0
- package/dist/auth/auth.module.d.ts.map +1 -1
- package/dist/auth/auth.module.js +57 -0
- package/dist/auth/auth.module.js.map +1 -0
- package/dist/auth/connections.js.map +1 -0
- package/dist/auth/dto.d.ts +32 -0
- package/dist/auth/dto.d.ts.map +1 -1
- package/dist/auth/dto.js.map +1 -0
- package/dist/auth/pending-mfa-store.js.map +1 -0
- package/dist/auth/persistence.module.js.map +1 -0
- package/dist/auth/ports/audit-sink.js.map +1 -0
- package/dist/auth/ports/credential-writer.js.map +1 -0
- package/dist/auth/ports/email-sender.js.map +1 -0
- package/dist/auth/ports/membership-checker.d.ts +41 -0
- package/dist/auth/ports/membership-checker.d.ts.map +1 -0
- package/dist/auth/ports/membership-checker.js +32 -0
- package/dist/auth/ports/membership-checker.js.map +1 -0
- package/dist/auth/ports/mfa-device-store.js.map +1 -0
- package/dist/auth/ports/profile-writer.js.map +1 -0
- package/dist/auth/ports/recovery-code-store.js.map +1 -0
- package/dist/auth/ports/reset-token-store.js.map +1 -0
- package/dist/auth/ports/scope-subtree-resolver.d.ts +48 -0
- package/dist/auth/ports/scope-subtree-resolver.d.ts.map +1 -0
- package/dist/auth/ports/scope-subtree-resolver.js +38 -0
- package/dist/auth/ports/scope-subtree-resolver.js.map +1 -0
- package/dist/auth/ports/session-facts-projector.js.map +1 -0
- package/dist/auth/ports/session-sweeper.js.map +1 -0
- package/dist/auth/profile-resolver.js.map +1 -0
- package/dist/auth/rate-limit/attempt-limiter.js.map +1 -0
- package/dist/auth/tokens.d.ts +25 -0
- package/dist/auth/tokens.d.ts.map +1 -1
- package/dist/auth/tokens.js +26 -1
- package/dist/auth/tokens.js.map +1 -0
- package/dist/auth/totp-enrollment.js.map +1 -0
- package/dist/authentication/argon2id-password-hasher.js.map +1 -0
- package/dist/authentication/log-email-sender.js.map +1 -0
- package/dist/authentication/mariadb-api-key-store.d.ts +43 -0
- package/dist/authentication/mariadb-api-key-store.d.ts.map +1 -0
- package/dist/authentication/mariadb-api-key-store.js +87 -0
- package/dist/authentication/mariadb-credential-resolver.js.map +1 -0
- package/dist/authentication/mariadb-credential-writer.js.map +1 -0
- package/dist/authentication/mariadb-mfa-device-store.js.map +1 -0
- package/dist/authentication/mariadb-or-totp-verifier.js.map +1 -0
- package/dist/authentication/mariadb-profile-resolver.js.map +1 -0
- package/dist/authentication/mariadb-profile-writer.d.ts.map +1 -1
- package/dist/authentication/mariadb-profile-writer.js +10 -1
- package/dist/authentication/mariadb-profile-writer.js.map +1 -0
- package/dist/authentication/mariadb-recovery-code-store.js.map +1 -0
- package/dist/authentication/mariadb-reset-token-store.js.map +1 -0
- package/dist/authentication/mariadb-session-sweeper.js.map +1 -0
- package/dist/authz/cross-tenant-grant-writer.js.map +1 -0
- package/dist/authz/list-scope-sql.d.ts +125 -0
- package/dist/authz/list-scope-sql.d.ts.map +1 -0
- package/dist/authz/list-scope-sql.js +477 -0
- package/dist/authz/list-scope-sql.js.map +1 -0
- package/dist/authz/manifest-operation-authority-adapter.js.map +1 -0
- package/dist/authz/mariadb-cross-tenant-grant-adapter.d.ts +28 -0
- package/dist/authz/mariadb-cross-tenant-grant-adapter.d.ts.map +1 -1
- package/dist/authz/mariadb-cross-tenant-grant-adapter.js +49 -0
- package/dist/authz/mariadb-cross-tenant-grant-adapter.js.map +1 -0
- package/dist/authz/mariadb-list-scope-adapter.d.ts +61 -0
- package/dist/authz/mariadb-list-scope-adapter.d.ts.map +1 -0
- package/dist/authz/mariadb-list-scope-adapter.js +157 -0
- package/dist/authz/mariadb-list-scope-adapter.js.map +1 -0
- package/dist/authz/mariadb-policy-store.d.ts +118 -0
- package/dist/authz/mariadb-policy-store.d.ts.map +1 -0
- package/dist/authz/mariadb-policy-store.js +225 -0
- package/dist/authz/mariadb-policy-store.js.map +1 -0
- package/dist/authz/mariadb-record-rule-adapter.d.ts +7 -3
- package/dist/authz/mariadb-record-rule-adapter.d.ts.map +1 -1
- package/dist/authz/mariadb-record-rule-adapter.js +156 -13
- package/dist/authz/mariadb-record-rule-adapter.js.map +1 -0
- package/dist/authz/mariadb-record-share-adapter.js.map +1 -0
- package/dist/authz/record-share-cascade.js.map +1 -0
- package/dist/authz/record-share-writer.d.ts +22 -0
- package/dist/authz/record-share-writer.d.ts.map +1 -1
- package/dist/authz/record-share-writer.js +41 -0
- package/dist/authz/record-share-writer.js.map +1 -0
- package/dist/authz/wire-record-authorization.d.ts +35 -1
- package/dist/authz/wire-record-authorization.d.ts.map +1 -1
- package/dist/authz/wire-record-authorization.js +75 -0
- package/dist/authz/wire-record-authorization.js.map +1 -0
- package/dist/boot/boot-sequence.js.map +1 -0
- package/dist/boot/boot.module.js.map +1 -0
- package/dist/completeness/catalog-reconciler.js.map +1 -0
- package/dist/completeness/operation-inventory-scanner.js.map +1 -0
- package/dist/completeness/ports/catalog-store.js.map +1 -0
- package/dist/config/app-config.d.ts +16 -0
- package/dist/config/app-config.d.ts.map +1 -1
- package/dist/config/app-config.js +22 -0
- package/dist/config/app-config.js.map +1 -0
- package/dist/config/config.module.js.map +1 -0
- package/dist/encryption/local-kek-crypto.d.ts +15 -0
- package/dist/encryption/local-kek-crypto.d.ts.map +1 -0
- package/dist/encryption/local-kek-crypto.js +79 -0
- package/dist/enforcement/classification.decorator.js.map +1 -0
- package/dist/enforcement/core-seam.js.map +1 -0
- package/dist/enforcement/enforcement.module.js.map +1 -0
- package/dist/enforcement/global-enforcement.guard.d.ts +3 -1
- package/dist/enforcement/global-enforcement.guard.d.ts.map +1 -1
- package/dist/enforcement/global-enforcement.guard.js +7 -3
- package/dist/enforcement/global-enforcement.guard.js.map +1 -0
- package/dist/enforcement/reenroll-allowlist.js.map +1 -0
- package/dist/identity/auth-facts.controller.js.map +1 -0
- package/dist/identity/identity-actions.d.ts +16 -0
- package/dist/identity/identity-actions.d.ts.map +1 -1
- package/dist/identity/identity-actions.js +23 -1
- package/dist/identity/identity-actions.js.map +1 -0
- package/dist/identity/module-registry.bridge.js.map +1 -0
- package/dist/identity/permission-facts.adapter.js.map +1 -0
- package/dist/index.d.ts +12 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +64 -3
- package/dist/index.js.map +1 -0
- package/dist/migrations-dir.js.map +1 -0
- package/dist/module/shield-tokens.js.map +1 -0
- package/dist/module/shield.module.d.ts +33 -0
- package/dist/module/shield.module.d.ts.map +1 -1
- package/dist/module/shield.module.js +12 -0
- package/dist/module/shield.module.js.map +1 -0
- package/dist/request-auth/request-principal.d.ts +11 -3
- package/dist/request-auth/request-principal.d.ts.map +1 -1
- package/dist/request-auth/request-principal.js +70 -2
- package/dist/request-auth/request-principal.js.map +1 -0
- package/dist/request-auth/session-facts-als.js.map +1 -0
- package/dist/request-auth/session-token-binder.d.ts +35 -1
- package/dist/request-auth/session-token-binder.d.ts.map +1 -1
- package/dist/request-auth/session-token-binder.js +123 -8
- package/dist/request-auth/session-token-binder.js.map +1 -0
- package/dist/request-auth/tokens.d.ts +10 -0
- package/dist/request-auth/tokens.d.ts.map +1 -1
- package/dist/request-auth/tokens.js +11 -1
- package/dist/request-auth/tokens.js.map +1 -0
- package/dist/scope/closure-builder.d.ts +75 -0
- package/dist/scope/closure-builder.d.ts.map +1 -0
- package/dist/scope/closure-builder.js +134 -0
- package/dist/scope/closure-builder.js.map +1 -0
- package/dist/secrets/encrypted-file-secrets.d.ts +16 -0
- package/dist/secrets/encrypted-file-secrets.d.ts.map +1 -0
- package/dist/secrets/encrypted-file-secrets.js +92 -0
- package/dist/session/crypto-adapters.js.map +1 -0
- package/dist/session/index.js.map +1 -0
- package/dist/session/mariadb-session-record-store.js.map +1 -0
- package/dist/session/redis-hot-session-store.js.map +1 -0
- package/migrations/1710000000009-CreateRecordPermissionRule.cjs +56 -0
- package/migrations/1710000000014-CreateRecordShare.cjs +49 -0
- package/migrations/1710000000015-CreateScopeClosure.cjs +46 -0
- package/migrations/1710000000016-AlterCompanyParentFkRestrict.cjs +71 -0
- package/migrations/1710000000017-CreateServiceAccountKey.cjs +41 -0
- package/package.json +3 -3
package/dist/auth/tokens.js
CHANGED
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
* ADR-0003: no framework/DB/crypto imports here — just Symbols (+ one re-export).
|
|
24
24
|
*/
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.SHIELD_PERMISSION_FACTS = exports.SHIELD_RESET_LIMITER = exports.SHIELD_FORGOT_HINT_LIMITER = exports.SHIELD_FORGOT_LIMITER = exports.SHIELD_RECOVERY_LIMITER = exports.SHIELD_LOGIN_LIMITER = exports.SHIELD_SESSION_FACTS_PROJECTOR = exports.SHIELD_ROOT_IDS = exports.SHIELD_TOTP_VERIFIER_OVERRIDE = exports.SHIELD_TOTP_VERIFIER = exports.SHIELD_RESET_LINK_BASE_URL = exports.SHIELD_SESSION_SWEEPER = exports.SHIELD_MFA_DEVICE_STORE = exports.SHIELD_AUDIT_SINK = exports.SHIELD_PROFILE_WRITER = exports.SHIELD_RECOVERY_CODE_STORE = exports.SHIELD_EMAIL_SENDER = 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.SHIELD_DB_POOL = exports.SHIELD_PASSWORD_HASHER = void 0;
|
|
26
|
+
exports.SHIELD_PERMISSION_FACTS = exports.SHIELD_RESET_LIMITER = exports.SHIELD_FORGOT_HINT_LIMITER = exports.SHIELD_FORGOT_LIMITER = exports.SHIELD_RECOVERY_LIMITER = exports.SHIELD_LOGIN_LIMITER = exports.SHIELD_MEMBERSHIP_CHECKER = exports.SHIELD_SCOPE_SUBTREE_RESOLVER = exports.SHIELD_SESSION_FACTS_PROJECTOR = exports.SHIELD_ROOT_IDS = exports.SHIELD_TOTP_VERIFIER_OVERRIDE = exports.SHIELD_TOTP_VERIFIER = exports.SHIELD_RESET_LINK_BASE_URL = exports.SHIELD_SESSION_SWEEPER = exports.SHIELD_MFA_DEVICE_STORE = exports.SHIELD_AUDIT_SINK = exports.SHIELD_PROFILE_WRITER = exports.SHIELD_RECOVERY_CODE_STORE = exports.SHIELD_EMAIL_SENDER = 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.SHIELD_DB_POOL = exports.SHIELD_PASSWORD_HASHER = void 0;
|
|
27
27
|
var argon2id_password_hasher_js_1 = require("../authentication/argon2id-password-hasher.js");
|
|
28
28
|
Object.defineProperty(exports, "SHIELD_PASSWORD_HASHER", { enumerable: true, get: function () { return argon2id_password_hasher_js_1.SHIELD_PASSWORD_HASHER; } });
|
|
29
29
|
/**
|
|
@@ -197,6 +197,31 @@ exports.SHIELD_ROOT_IDS = Symbol('SHIELD_ROOT_IDS');
|
|
|
197
197
|
* `auth: true`.
|
|
198
198
|
*/
|
|
199
199
|
exports.SHIELD_SESSION_FACTS_PROJECTOR = Symbol('SHIELD_SESSION_FACTS_PROJECTOR');
|
|
200
|
+
/**
|
|
201
|
+
* OPTIONAL {@link import('./ports/scope-subtree-resolver.js').ScopeSubtreeResolver} — the
|
|
202
|
+
* Task 2.2 (ADR-0027 / ADR-0024) active-scope-subtree seam. Threaded through
|
|
203
|
+
* `ShieldModule.forRoot({ scopeSubtreeResolver })` → `AuthModule.forRoot`, `@Optional()`
|
|
204
|
+
* (bound `null` when absent). When PRESENT, the auth controller calls
|
|
205
|
+
* `resolveSubtree(activeScopeNodeId)` ONCE at login and caches the returned node-id set on
|
|
206
|
+
* the session binding (`scopeSubtreeNodeIds`), so the per-request tenant gate reads the real
|
|
207
|
+
* closure-resolved subtree from the binding with ZERO extra DB (the parity guarantee). ABSENT
|
|
208
|
+
* → the controller omits `scopeSubtreeNodeIds` → the per-request path falls back to the
|
|
209
|
+
* self-node `[tenantId]` (today's flat isolation, non-widening). Fail-safe: a resolver that
|
|
210
|
+
* throws NEVER fails login. Purely additive + opt-in. Only consulted under `auth: true`.
|
|
211
|
+
*/
|
|
212
|
+
exports.SHIELD_SCOPE_SUBTREE_RESOLVER = Symbol('SHIELD_SCOPE_SUBTREE_RESOLVER');
|
|
213
|
+
/**
|
|
214
|
+
* OPTIONAL {@link import('./ports/membership-checker.js').MembershipChecker} — the Task 5.2
|
|
215
|
+
* (ADR-0027 / ADR-0024) SCOPE-SWITCH gate seam. Threaded through
|
|
216
|
+
* `ShieldModule.forRoot({ membershipChecker })` → `AuthModule.forRoot`, `@Optional()` (bound
|
|
217
|
+
* `null` when absent). When PRESENT, `POST /auth/scope-switch` calls
|
|
218
|
+
* `hasActiveMembership(principalId, targetNodeId)` BEFORE re-binding the session to the new
|
|
219
|
+
* active node — a principal may only switch to a node it HOLDS an active membership at. ABSENT
|
|
220
|
+
* (or a `false`/thrown result) → the switch is DENIED (fail-closed: cannot verify the binding →
|
|
221
|
+
* do not grant it; `targetNodeId` is NEVER trusted without this affirmative check). Only
|
|
222
|
+
* consulted under `auth: true`. Mirrors {@link SHIELD_SCOPE_SUBTREE_RESOLVER}'s wiring.
|
|
223
|
+
*/
|
|
224
|
+
exports.SHIELD_MEMBERSHIP_CHECKER = Symbol('SHIELD_MEMBERSHIP_CHECKER');
|
|
200
225
|
// ---------------------------------------------------------------------------
|
|
201
226
|
// Rate-limit seams (anti-brute-force, spec §5) — ONE `AttemptLimiter` class
|
|
202
227
|
// (Redis-backed), provided as TWO instances with independent thresholds under
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../src/auth/tokens.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"totp-enrollment.js","sourceRoot":"","sources":["../../src/auth/totp-enrollment.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;GAmBG;;AAiDH,gDAEC;AASD,0CAOC;AAQD,sDAOC;AAhFD,6CAA0C;AAE1C,sFAAsF;AACtF,MAAM,eAAe,GAAG,kCAAkC,CAAC;AAE3D;;;;GAIG;AACH,MAAM,YAAY,GAAG,EAAE,CAAC;AAExB,kFAAkF;AAClF,MAAM,2BAA2B,GAAG,EAAE,CAAC;AAEvC,yFAAyF;AACzF,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAE9B;;;;GAIG;AACH,SAAS,YAAY,CAAC,KAAiB;IACrC,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,KAAK,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;QAC5B,IAAI,IAAI,CAAC,CAAC;QACV,OAAO,IAAI,IAAI,CAAC,EAAE,CAAC;YACjB,IAAI,IAAI,CAAC,CAAC;YACV,GAAG,IAAI,eAAe,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IACD,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;QACb,6EAA6E;QAC7E,GAAG,IAAI,eAAe,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,SAAgB,kBAAkB;IAChC,OAAO,YAAY,CAAC,IAAA,yBAAW,EAAC,YAAY,CAAC,CAAC,CAAC;AACjD,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,eAAe,CAAC,MAAc,EAAE,KAAa,EAAE,MAAc;IAC3E,MAAM,SAAS,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC7C,MAAM,QAAQ,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAC3C,OAAO,CACL,kBAAkB,SAAS,IAAI,QAAQ,EAAE;QACzC,WAAW,MAAM,WAAW,SAAS,qBAAqB,CAC3D,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAgB,qBAAqB,CAAC,QAAgB,2BAA2B;IAC/E,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,OAAO,KAAK,CAAC,IAAI,GAAG,KAAK,EAAE,CAAC;QAC1B,MAAM,GAAG,GAAG,IAAA,yBAAW,EAAC,mBAAmB,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,eAAe;QAC7E,KAAK,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAClD,CAAC;IACD,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"argon2id-password-hasher.js","sourceRoot":"","sources":["../../src/authentication/argon2id-password-hasher.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0EH,wDAQC;AAhFD,+CAAiC;AAmBjC,MAAM,cAAc,GAA6B;IAC/C,UAAU,EAAE,MAAM;IAClB,QAAQ,EAAE,CAAC;IACX,WAAW,EAAE,CAAC;CACf,CAAC;AAEF,0EAA0E;AAC7D,QAAA,sBAAsB,GAAG,MAAM,CAAC,wBAAwB,CAAC,CAAC;AAEvE;;;;GAIG;AACH,MAAa,sBAAsB;IAChB,OAAO,CAAuC;IAE/D,YAAY,SAAyB,EAAE;QACrC,IAAI,CAAC,OAAO,GAAG;YACb,IAAI,EAAE,MAAM,CAAC,QAAQ;YACrB,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,cAAc,CAAC,UAAU;YAC1D,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,cAAc,CAAC,QAAQ;YACpD,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,cAAc,CAAC,WAAW;SAC9D,CAAC;IACJ,CAAC;IAED,8EAA8E;IAC9E,KAAK,CAAC,IAAI,CAAC,SAAiB;QAC1B,6EAA6E;QAC7E,OAAO,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9C,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,MAAM,CAAC,IAAY,EAAE,SAAiB;QAC1C,IAAI,CAAC;YACH,OAAO,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAC9C,CAAC;QAAC,MAAM,CAAC;YACP,yEAAyE;YACzE,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;CACF;AA/BD,wDA+BC;AAED;;;;;GAKG;AACH,SAAgB,sBAAsB,CAAC,SAAyB,EAAE;IAIhE,OAAO;QACL,OAAO,EAAE,8BAAsB;QAC/B,QAAQ,EAAE,IAAI,sBAAsB,CAAC,MAAM,CAAC;KAC7C,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log-email-sender.js","sourceRoot":"","sources":["../../src/authentication/log-email-sender.ts"],"names":[],"mappings":";;;AAQA,MAAa,cAAc;IACI;IAA7B,YAA6B,MAA6B,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;QAAlD,QAAG,GAAH,GAAG,CAA+C;IAAG,CAAC;IACnF,KAAK,CAAC,IAAI,CAAC,OAAqB;QAC9B,IAAI,CAAC,GAAG,CAAC,+DAA+D,OAAO,CAAC,EAAE,YAAY,OAAO,CAAC,OAAO,KAAK,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC;IAC1J,CAAC;CACF;AALD,wCAKC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MariaDbApiKeyStore — the framework-DEFAULT {@link ApiKeyStore} (ADR-0033), backing
|
|
3
|
+
* service-account API-key authentication. Persisted in `shield_authz`.`service_account_key`.
|
|
4
|
+
*
|
|
5
|
+
* HASH-ONLY (like the reset-token / refresh-token stores): the raw secret is hashed (Argon2id, via
|
|
6
|
+
* the PasswordHasher) BEFORE it reaches this store — the store holds only `sak_secret_hash`, never
|
|
7
|
+
* the plaintext. A store breach yields no usable key.
|
|
8
|
+
*
|
|
9
|
+
* `getByAccountId` returns the CURRENT (highest-version, non-superseded) key record, or `null` for
|
|
10
|
+
* an unknown account (anti-enumeration — the authenticator maps null → a uniform failure). A genuine
|
|
11
|
+
* store OUTAGE (the `query` rejecting) PROPAGATES (the authenticator catches it → fail-closed), never
|
|
12
|
+
* swallowed to null. Every query is parameterized; the hash is never logged.
|
|
13
|
+
*
|
|
14
|
+
* The `issue`/`rotate`/`revoke` writer methods are provided for the admin lifecycle (mint + show the
|
|
15
|
+
* key once elsewhere; here we only persist the HASH + metadata).
|
|
16
|
+
*/
|
|
17
|
+
import type { Pool } from 'mariadb';
|
|
18
|
+
import type { ApiKeyStore, ApiKeyRecord } from '@astram/core';
|
|
19
|
+
export declare class MariaDbApiKeyStore implements ApiKeyStore {
|
|
20
|
+
private readonly pool;
|
|
21
|
+
constructor(pool: Pool);
|
|
22
|
+
getByAccountId(accountId: string): Promise<ApiKeyRecord | null>;
|
|
23
|
+
/**
|
|
24
|
+
* Persist a NEW key version for an account (issue or rotate). Only the HASH is stored. `version`
|
|
25
|
+
* is monotonic per account; the caller mints the secret + computes the hash. Idempotency is on
|
|
26
|
+
* the natural key `(account, version)`.
|
|
27
|
+
*/
|
|
28
|
+
putVersion(input: {
|
|
29
|
+
accountId: string;
|
|
30
|
+
tenantId: string;
|
|
31
|
+
scopeSubtreeNodeIds: readonly string[];
|
|
32
|
+
roleIds: readonly string[];
|
|
33
|
+
secretHash: string;
|
|
34
|
+
version: number;
|
|
35
|
+
expiresAtMs?: number;
|
|
36
|
+
createdAtMs: number;
|
|
37
|
+
}): Promise<void>;
|
|
38
|
+
/** The current highest version for an account (0 if none) — for computing the next on rotate. */
|
|
39
|
+
currentVersion(accountId: string): Promise<number>;
|
|
40
|
+
/** Revoke ALL of an account's keys (immediate fail-closed on the next request). Idempotent. */
|
|
41
|
+
revoke(accountId: string, atMs: number): Promise<void>;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=mariadb-api-key-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mariadb-api-key-store.d.ts","sourceRoot":"","sources":["../../src/authentication/mariadb-api-key-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAuC9D,qBAAa,kBAAmB,YAAW,WAAW;IACxC,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,IAAI;IAEjC,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IA0BrE;;;;OAIG;IACG,UAAU,CAAC,KAAK,EAAE;QACtB,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,mBAAmB,EAAE,SAAS,MAAM,EAAE,CAAC;QACvC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;QAC3B,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,WAAW,EAAE,MAAM,CAAC;KACrB,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBjB,iGAAiG;IAC3F,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQxD,+FAA+F;IACzF,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAQ7D"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MariaDbApiKeyStore = void 0;
|
|
4
|
+
const AUTHZ = 'shield_authz';
|
|
5
|
+
/**
|
|
6
|
+
* Read a JSON-array column into a `string[]`. The mariadb driver returns a JSON/`longtext` column
|
|
7
|
+
* EITHER already-parsed (an array/object — its default for JSON columns) OR as a raw string,
|
|
8
|
+
* depending on driver/column config — so we handle BOTH: an array is filtered to its string
|
|
9
|
+
* elements directly; a string is `JSON.parse`d first. Anything else (or a parse failure) → `[]`
|
|
10
|
+
* (fail-safe: an unreadable scope/roles slot yields the empty set, never a crash or a wrong value).
|
|
11
|
+
*/
|
|
12
|
+
function parseJsonArray(v) {
|
|
13
|
+
const arr = Array.isArray(v)
|
|
14
|
+
? v
|
|
15
|
+
: typeof v === 'string'
|
|
16
|
+
? (() => {
|
|
17
|
+
try {
|
|
18
|
+
return JSON.parse(v);
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return [];
|
|
22
|
+
}
|
|
23
|
+
})()
|
|
24
|
+
: [];
|
|
25
|
+
return Array.isArray(arr) ? arr.filter((x) => typeof x === 'string') : [];
|
|
26
|
+
}
|
|
27
|
+
class MariaDbApiKeyStore {
|
|
28
|
+
pool;
|
|
29
|
+
constructor(pool) {
|
|
30
|
+
this.pool = pool;
|
|
31
|
+
}
|
|
32
|
+
async getByAccountId(accountId) {
|
|
33
|
+
// The CURRENT key = highest version for the account. (Rotation inserts a new version; the old
|
|
34
|
+
// may linger for an overlap window but only the current is returned for auth.)
|
|
35
|
+
const rows = (await this.pool.query(`SELECT sak_account_id, sak_tenant_id, sak_scope_subtree, sak_role_ids,
|
|
36
|
+
sak_secret_hash, sak_version, sak_expires_at_ms, sak_revoked_at_ms
|
|
37
|
+
FROM \`${AUTHZ}\`.\`service_account_key\`
|
|
38
|
+
WHERE sak_account_id = ?
|
|
39
|
+
ORDER BY sak_version DESC
|
|
40
|
+
LIMIT 1`, [accountId]));
|
|
41
|
+
const row = rows[0];
|
|
42
|
+
if (!row)
|
|
43
|
+
return null;
|
|
44
|
+
return {
|
|
45
|
+
accountId: row.sak_account_id,
|
|
46
|
+
tenantId: row.sak_tenant_id,
|
|
47
|
+
scopeSubtreeNodeIds: parseJsonArray(row.sak_scope_subtree),
|
|
48
|
+
roleIds: parseJsonArray(row.sak_role_ids),
|
|
49
|
+
secretHash: row.sak_secret_hash,
|
|
50
|
+
version: Number(row.sak_version),
|
|
51
|
+
...(row.sak_expires_at_ms !== null ? { expiresAtMs: Number(row.sak_expires_at_ms) } : {}),
|
|
52
|
+
...(row.sak_revoked_at_ms !== null ? { revokedAtMs: Number(row.sak_revoked_at_ms) } : {}),
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Persist a NEW key version for an account (issue or rotate). Only the HASH is stored. `version`
|
|
57
|
+
* is monotonic per account; the caller mints the secret + computes the hash. Idempotency is on
|
|
58
|
+
* the natural key `(account, version)`.
|
|
59
|
+
*/
|
|
60
|
+
async putVersion(input) {
|
|
61
|
+
await this.pool.query(`INSERT INTO \`${AUTHZ}\`.\`service_account_key\`
|
|
62
|
+
(sak_account_id, sak_tenant_id, sak_scope_subtree, sak_role_ids,
|
|
63
|
+
sak_secret_hash, sak_version, sak_expires_at_ms, sak_revoked_at_ms, sak_created_at_ms)
|
|
64
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, NULL, ?)`, [
|
|
65
|
+
input.accountId,
|
|
66
|
+
input.tenantId,
|
|
67
|
+
JSON.stringify([...input.scopeSubtreeNodeIds]),
|
|
68
|
+
JSON.stringify([...input.roleIds]),
|
|
69
|
+
input.secretHash,
|
|
70
|
+
input.version,
|
|
71
|
+
input.expiresAtMs ?? null,
|
|
72
|
+
input.createdAtMs,
|
|
73
|
+
]);
|
|
74
|
+
}
|
|
75
|
+
/** The current highest version for an account (0 if none) — for computing the next on rotate. */
|
|
76
|
+
async currentVersion(accountId) {
|
|
77
|
+
const rows = (await this.pool.query(`SELECT MAX(sak_version) AS v FROM \`${AUTHZ}\`.\`service_account_key\` WHERE sak_account_id = ?`, [accountId]));
|
|
78
|
+
return rows[0]?.v != null ? Number(rows[0].v) : 0;
|
|
79
|
+
}
|
|
80
|
+
/** Revoke ALL of an account's keys (immediate fail-closed on the next request). Idempotent. */
|
|
81
|
+
async revoke(accountId, atMs) {
|
|
82
|
+
await this.pool.query(`UPDATE \`${AUTHZ}\`.\`service_account_key\`
|
|
83
|
+
SET sak_revoked_at_ms = ?
|
|
84
|
+
WHERE sak_account_id = ? AND sak_revoked_at_ms IS NULL`, [atMs, accountId]);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
exports.MariaDbApiKeyStore = MariaDbApiKeyStore;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mariadb-credential-resolver.js","sourceRoot":"","sources":["../../src/authentication/mariadb-credential-resolver.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsEG;;;AASH,kFAAkF;AAClF,+CAA+D;AAAtD,uHAAA,0BAA0B,OAAA;AAkBnC;;;;;;;;;;;GAWG;AACH,SAAS,YAAY,CAAC,GAAY,EAAE,IAAY;IAC9C,IAAI,KAAK,GAAY,GAAG,CAAC;IACzB,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,IAAI,CAAC;YACH,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC;YACP,2EAA2E;YAC3E,mDAAmD;YACnD,MAAM,IAAI,KAAK,CACb,oEAAoE,IAAI,IAAI;gBAC1E,2EAA2E,CAC9E,CAAC;QACJ,CAAC;IACH,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,EAAE,CAAC;QACxE,MAAM,IAAI,KAAK,CACb,qDAAqD,IAAI,oBAAoB;YAC3E,qDAAqD,CACxD,CAAC;IACJ,CAAC;IACD,OAAO,KAA0B,CAAC;AACpC,CAAC;AAED;;;;;;;GAOG;AACH,MAAa,yBAAyB;IACP;IAA7B,YAA6B,IAAU;QAAV,SAAI,GAAJ,IAAI,CAAM;IAAG,CAAC;IAE3C;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,KAAK,CAAC,OAAO,CAAC,YAAoB;QAChC,8EAA8E;QAC9E,8EAA8E;QAC9E,8CAA8C;QAC9C,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACjC;;;gBAGU,EACV,CAAC,YAAY,CAAC,CACf,CAAoB,CAAC;QAEtB,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,+DAA+D;QAC/D,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,IAAI,CAAC;QACd,CAAC;QAED,6EAA6E;QAC7E,+EAA+E;QAC/E,MAAM,eAAe,GAAqB,EAAE,CAAC;QAE7C,OAAO;YACL,YAAY,EAAE,GAAG,CAAC,gBAAgB;YAClC,MAAM,EAAE;gBACN,EAAE,EAAE,GAAG,CAAC,eAAe;gBACvB,QAAQ,EAAE,GAAG,CAAC,YAAY;gBAC1B,OAAO,EAAE,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,YAAY,CAAC;aAClD;YACD,eAAe;SAChB,CAAC;IACJ,CAAC;CACF;AAxDD,8DAwDC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mariadb-credential-writer.js","sourceRoot":"","sources":["../../src/authentication/mariadb-credential-writer.ts"],"names":[],"mappings":";;;AAWA,MAAa,uBAAuB;IACL;IAA6B;IAA1D,YAA6B,IAAU,EAAmB,MAAoB,IAAI,CAAC,GAAG;QAAzD,SAAI,GAAJ,IAAI,CAAM;QAAmB,QAAG,GAAH,GAAG,CAAyB;IAAG,CAAC;IAE1F,KAAK,CAAC,WAAW,CAAC,WAAmB,EAAE,YAAoB;QACzD,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACnB,yHAAyH,EACzH,CAAC,YAAY,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,WAAW,CAAC,CACxC,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,WAAmB;QACvC,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACjC,wGAAwG,EACxG,CAAC,WAAW,CAAC,CACd,CAAc,CAAC;QAChB,OAAO,IAAI,CAAC,CAAC,CAAC,EAAE,gBAAgB,IAAI,IAAI,CAAC;IAC3C,CAAC;CACF;AAjBD,0DAiBC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mariadb-mfa-device-store.js","sourceRoot":"","sources":["../../src/authentication/mariadb-mfa-device-store.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,6CAAyC;AAIzC,wFAAwF;AACxF,MAAM,cAAc,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAWtC,8FAA8F;AAC9F,MAAM,QAAQ,GAAG,CAAC,CAAY,EAAa,EAAE,CAAC,CAAC;IAC7C,EAAE,EAAE,CAAC,CAAC,KAAK;IACX,IAAI,EAAE,CAAC,CAAC,OAAO;IACf,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC;IACvC,YAAY,EAAE,CAAC,CAAC,kBAAkB,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,kBAAkB,CAAC;IAChF,SAAS,EAAE,CAAC,CAAC,kBAAkB,IAAI,IAAI;CACxC,CAAC,CAAC;AAEH,MAAa,qBAAqB;IACH;IAA7B,YAA6B,IAAU;QAAV,SAAI,GAAJ,IAAI,CAAM;IAAG,CAAC;IAE3C,KAAK,CAAC,OAAO,CAAC,WAAmB;QAC/B,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACjC;yGACmG,EACnG,CAAC,WAAW,CAAC,CACd,CAAgB,CAAC;QAClB,OAAO,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,oBAAoB,CAAC,WAAmB;QAC5C,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACjC;qEAC+D,EAC/D,CAAC,WAAW,CAAC,CACd,CAAiC,CAAC;QACnC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,WAAmB,EAAE,QAAgB;QACnD,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACjC;wDACkD,EAClD,CAAC,QAAQ,EAAE,WAAW,CAAC,CACxB,CAAiC,CAAC;QACnC,OAAO,IAAI,CAAC,CAAC,CAAC,EAAE,SAAS,IAAI,IAAI,CAAC;IACpC,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,WAAmB,EAAE,IAAY,EAAE,MAAc;QAC3D,uEAAuE;QACvE,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACnB;0FACoF,EACpF,CAAC,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,cAAc,CAAC,CAC3C,CAAC;QACF,MAAM,EAAE,GAAG,IAAA,wBAAU,GAAE,CAAC;QACxB,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACnB;;0CAEoC,EACpC,CAAC,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAC5C,CAAC;QACF,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,WAAmB,EAAE,QAAgB;QACjD,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAChC;+EACyE,EACzE,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,WAAW,CAAC,CACpC,CAA6B,CAAC;QAC/B,OAAO,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,WAAmB,EAAE,QAAgB,EAAE,IAAY;QAC9D,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAChC;gDAC0C,EAC1C,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,CAAC,CAC9B,CAA6B,CAAC;QAC/B,IAAI,GAAG,CAAC,YAAY,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QACxC,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACjC;iGAC2F,EAC3F,CAAC,QAAQ,EAAE,WAAW,CAAC,CACxB,CAAgB,CAAC;QAClB,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5C,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,WAAmB,EAAE,QAAgB;QAChD,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAChC,wFAAwF,EACxF,CAAC,QAAQ,EAAE,WAAW,CAAC,CACxB,CAA6B,CAAC;QAC/B,OAAO,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,WAAmB;QACtC,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACjC;qEAC+D,EAC/D,CAAC,WAAW,CAAC,CACd,CAAkC,CAAC;QACpC,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,MAAc;QAC5B,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACnB,0FAA0F,EAC1F,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,CACrB,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,wDAAwD;QAC1D,CAAC;IACH,CAAC;CACF;AAlGD,sDAkGC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mariadb-or-totp-verifier.js","sourceRoot":"","sources":["../../src/authentication/mariadb-or-totp-verifier.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;;AAKH,MAAa,cAAc;IAKN;IAEA;IANV,MAAM,GAAG,MAAe,CAAC;IAElC;IACE,iFAAiF;IAChE,IAAoB;IACrC,mFAAmF;IAClE,OAA0C;QAF1C,SAAI,GAAJ,IAAI,CAAgB;QAEpB,YAAO,GAAP,OAAO,CAAmC;IAC1D,CAAC;IAEJ,KAAK,CAAC,MAAM,CAAC,UAAsB,EAAE,aAAqB;QACxD,MAAM,OAAO,GAAG,MAAM,CAAC,aAAa,IAAI,EAAE,CAAC;aACxC,KAAK,CAAC,IAAI,CAAC;aACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;aACpB,MAAM,CAAC,OAAO,CAAC,CAAC;QACnB,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;YAC3D,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;gBACtB,0EAA0E;gBAC1E,wEAAwE;gBACxE,KAAK,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;gBACpC,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;YAC7B,CAAC;QACH,CAAC;QACD,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IAC9B,CAAC;CACF;AA1BD,wCA0BC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mariadb-profile-resolver.js","sourceRoot":"","sources":["../../src/authentication/mariadb-profile-resolver.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;GAYG;;;AAUH,MAAa,sBAAsB;IACJ;IAA6B;IAA1D,YAA6B,IAAU,EAAmB,MAAoB,IAAI,CAAC,GAAG;QAAzD,SAAI,GAAJ,IAAI,CAAM;QAAmB,QAAG,GAAH,GAAG,CAAyB;IAAG,CAAC;IAE1F,KAAK,CAAC,OAAO,CAAC,SAAoB;QAChC,MAAM,QAAQ,GAAG,SAAS,CAAC,EAAE,CAAC;QAC9B,MAAM,WAAW,GAAG,SAAS,CAAC,QAAQ,CAAC;QAEvC,MAAM,KAAK,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAClC,+EAA+E,EAC/E,CAAC,QAAQ,CAAC,CACX,CAAc,CAAC;QAChB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC,CAAC,2DAA2D;QAEnF,MAAM,SAAS,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACtC,sEAAsE,EACtE,CAAC,WAAW,CAAC,CACd,CAAiB,CAAC;QACnB,MAAM,WAAW,GAAG,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,IAAI,mBAAmB,CAAC;QAEhE,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;QAEjE,OAAO;YACL,EAAE,EAAE,QAAQ;YACZ,IAAI,EAAE,IAAI,CAAC,UAAU;YACrB,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAChD,OAAO,EAAE,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,EAAE;YAC/C,KAAK;SACN,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAAC,QAAgB,EAAE,WAAmB;QAClE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACjC;;;;;;iFAM2E,EAC3E,CAAC,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,CAAC,CACtC,CAAkB,CAAC;QACpB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC7D,CAAC;CACF;AA7CD,wDA6CC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mariadb-profile-writer.d.ts","sourceRoot":"","sources":["../../src/authentication/mariadb-profile-writer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAOtE,qBAAa,oBAAqB,YAAW,aAAa;IAE5C,OAAO,CAAC,QAAQ,CAAC,IAAI;IADjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAyB;gBACrB,IAAI,EAAE,IAAI;IAIjC,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"mariadb-profile-writer.d.ts","sourceRoot":"","sources":["../../src/authentication/mariadb-profile-writer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAOtE,qBAAa,oBAAqB,YAAW,aAAa;IAE5C,OAAO,CAAC,QAAQ,CAAC,IAAI;IADjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAyB;gBACrB,IAAI,EAAE,IAAI;IAIjC,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,kBAAkB,CAAC;CAmC3G"}
|
|
@@ -27,7 +27,16 @@ class MariaDbProfileWriter {
|
|
|
27
27
|
// Resolve the caller's active company so the re-read profile is tenant-correct.
|
|
28
28
|
const active = (await this.pool.query("SELECT cm_company_uuid FROM `shield_app`.`company_membership` WHERE cm_user_uuid = ? AND cm_is_active = 1 AND cm_status = 'active' LIMIT 1", [principalId]));
|
|
29
29
|
const tenantId = active[0]?.cm_company_uuid ?? '';
|
|
30
|
-
const profile = await this.resolver.resolve({
|
|
30
|
+
const profile = await this.resolver.resolve({
|
|
31
|
+
kind: 'user',
|
|
32
|
+
id: principalId,
|
|
33
|
+
// Scope (ADR-0027) — INTERIM self-node default (Task 2.1): non-widening, = today's isolation.
|
|
34
|
+
activeScopeNodeId: tenantId,
|
|
35
|
+
scopeSubtreeNodeIds: [tenantId],
|
|
36
|
+
tenantId,
|
|
37
|
+
roleIds: [],
|
|
38
|
+
isRoot: false,
|
|
39
|
+
});
|
|
31
40
|
if (profile === null)
|
|
32
41
|
throw new Error('profile_unavailable'); // fail-closed: never a partial write result
|
|
33
42
|
return profile;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mariadb-profile-writer.js","sourceRoot":"","sources":["../../src/authentication/mariadb-profile-writer.ts"],"names":[],"mappings":";;;AAQA,+EAAuE;AAMvE,MAAa,oBAAoB;IAEF;IADZ,QAAQ,CAAyB;IAClD,YAA6B,IAAU;QAAV,SAAI,GAAJ,IAAI,CAAM;QACrC,IAAI,CAAC,QAAQ,GAAG,IAAI,oDAAsB,CAAC,IAAI,CAAC,CAAC;IACnD,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,WAAmB,EAAE,OAA0C;QAC1E,MAAM,IAAI,GAAa,EAAE,CAAC;QAC1B,MAAM,MAAM,GAAc,EAAE,CAAC;QAC7B,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC/B,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YAC5B,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;QACD,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAChC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YACzB,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC;QACD,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpB,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YACzB,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,uCAAuC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC;QAC3G,CAAC;QAED,gFAAgF;QAChF,MAAM,MAAM,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACnC,4IAA4I,EAC5I,CAAC,WAAW,CAAC,CACd,CAAgB,CAAC;QAClB,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,eAAe,IAAI,EAAE,CAAC;QAClD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;YAC1C,IAAI,EAAE,MAAM;YACZ,EAAE,EAAE,WAAW;YACf,8FAA8F;YAC9F,iBAAiB,EAAE,QAAQ;YAC3B,mBAAmB,EAAE,CAAC,QAAQ,CAAC;YAC/B,QAAQ;YACR,OAAO,EAAE,EAAE;YACX,MAAM,EAAE,KAAK;SACd,CAAC,CAAC;QACH,IAAI,OAAO,KAAK,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC,4CAA4C;QAC1G,OAAO,OAAO,CAAC;IACjB,CAAC;CACF;AAzCD,oDAyCC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mariadb-recovery-code-store.js","sourceRoot":"","sources":["../../src/authentication/mariadb-recovery-code-store.ts"],"names":[],"mappings":";;;AA4BA,MAAa,wBAAwB;IAEhB;IAEA;IACA;IAJnB,YACmB,IAAU;IAC3B,+EAA+E;IAC9D,MAAsB,EACtB,MAAoB,IAAI,CAAC,GAAG;QAH5B,SAAI,GAAJ,IAAI,CAAM;QAEV,WAAM,GAAN,MAAM,CAAgB;QACtB,QAAG,GAAH,GAAG,CAAyB;IAC5C,CAAC;IAEJ;;;;OAIG;IACH,KAAK,CAAC,UAAU,CAAC,WAAmB,EAAE,UAA6B;QACjE,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACnB,kFAAkF,EAClF,CAAC,WAAW,CAAC,CACd,CAAC;QACF,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;YAC9B,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACnB;;gCAEwB,EACxB,CAAC,WAAW,EAAE,IAAI,EAAE,SAAS,CAAC,CAC/B,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,OAAO,CAAC,WAAmB,EAAE,OAAe;QAChD,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QACtE,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACjC;kEAC4D,EAC5D,CAAC,WAAW,CAAC,CACd,CAAkB,CAAC;QACpB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,IAAI,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,aAAa,EAAE,OAAO,CAAC,EAAE,CAAC;gBACzD,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAChC;;4FAEkF,EAClF,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,GAAG,CAAC,aAAa,CAAC,CAC7C,CAA6B,CAAC;gBAC/B,mEAAmE;gBACnE,OAAO,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC;YAChC,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;CACF;AAzDD,4DAyDC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mariadb-reset-token-store.js","sourceRoot":"","sources":["../../src/authentication/mariadb-reset-token-store.ts"],"names":[],"mappings":";;;AAsBA,MAAa,sBAAsB;IAEd;IACA;IAFnB,YACmB,IAAU,EACV,MAAoB,IAAI,CAAC,GAAG;QAD5B,SAAI,GAAJ,IAAI,CAAM;QACV,QAAG,GAAH,GAAG,CAAyB;IAC5C,CAAC;IAEJ,KAAK,CAAC,KAAK,CAAC,WAAmB,EAAE,SAAiB,EAAE,WAAmB;QACrE,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACnB;;iCAE2B,EAC3B,CAAC,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAClD,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,SAAiB;QAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,wDAAwD;QACxD,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACjC;;;gBAGU,EACV,CAAC,SAAS,EAAE,GAAG,CAAC,CACjB,CAAqB,CAAC;QACvB,MAAM,WAAW,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,gBAAgB,CAAC;QAC9C,IAAI,WAAW,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC;QAE3C,wFAAwF;QACxF,yFAAyF;QACzF,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAChC;;gEAE0D,EAC1D,CAAC,GAAG,EAAE,SAAS,CAAC,CACjB,CAA6B,CAAC;QAC/B,IAAI,GAAG,CAAC,YAAY,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC,CAAC,oCAAoC;QAE7E,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,KAAK,CAAC,yBAAyB,CAAC,WAAmB;QACjD,6FAA6F;QAC7F,2CAA2C;QAC3C,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACnB;;kEAE4D,EAC5D,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,WAAW,CAAC,CAC1B,CAAC;IACJ,CAAC;CACF;AAnDD,wDAmDC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mariadb-session-sweeper.js","sourceRoot":"","sources":["../../src/authentication/mariadb-session-sweeper.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;;;AAUH,MAAa,qBAAqB;IAEb;IACA;IAFnB,YACmB,IAAU,EACV,MAA0B;QAD1B,SAAI,GAAJ,IAAI,CAAM;QACV,WAAM,GAAN,MAAM,CAAoB;IAC1C,CAAC;IAEJ,KAAK,CAAC,qBAAqB,CAAC,WAAmB;QAC7C,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACjC;;yDAEmD,EACnD,CAAC,WAAW,CAAC,CACd,CAAmB,CAAC;QACrB,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACnB;;yDAEmD,EACnD,CAAC,WAAW,CAAC,CACd,CAAC;QACF,kFAAkF;QAClF,iCAAiC;QACjC,KAAK,MAAM,EAAE,YAAY,EAAE,IAAI,IAAI,EAAE,CAAC;YACpC,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,wBAAwB,CAAC,WAAmB,EAAE,aAAqB;QACvE,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACjC;;+EAEyE,EACzE,CAAC,WAAW,EAAE,aAAa,CAAC,CAC7B,CAAmB,CAAC;QACrB,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CACnB;;+EAEyE,EACzE,CAAC,WAAW,EAAE,aAAa,CAAC,CAC7B,CAAC;QACF,kFAAkF;QAClF,0EAA0E;QAC1E,KAAK,MAAM,EAAE,YAAY,EAAE,IAAI,IAAI,EAAE,CAAC;YACpC,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;CACF;AA7CD,sDA6CC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cross-tenant-grant-writer.js","sourceRoot":"","sources":["../../src/authz/cross-tenant-grant-writer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `translateListScope` — the PURE, SECURITY-CRITICAL translator that turns core's
|
|
3
|
+
* abstract {@link ListScopeSpec} (Phase 1, `list-scope.ts`) into a SAFE, parameterized
|
|
4
|
+
* SQL WHERE fragment. Phase 3 injects the returned fragment into the engine's `list()`
|
|
5
|
+
* so a collection endpoint returns ONLY the rows `decide()` would allow — filtered IN
|
|
6
|
+
* the query (Invariant #8), never fetch-then-discard.
|
|
7
|
+
*
|
|
8
|
+
* ── THE SHAPE IT EMITS (mirrors the record-permit tier composition, `permit-tier.ts`):
|
|
9
|
+
*
|
|
10
|
+
* <tenant-bound> AND ( <positive union> ) [ AND NOT ( <deny union> ) ]
|
|
11
|
+
*
|
|
12
|
+
* • positive union = ownerBaseline OR policyAllow OR share OR crossTenant — a row is
|
|
13
|
+
* INCLUDED if ANY term is true. NO positive term present ⇒ the union is `(FALSE)`
|
|
14
|
+
* (fail-closed — never an empty `()` and never a `TRUE`).
|
|
15
|
+
* • deny union = policyDeny AND-groups OR'd, wrapped in `AND NOT (...)` so a row
|
|
16
|
+
* matching ANY deny group is EXCLUDED even if a share/owner/allow would include it
|
|
17
|
+
* (deny-wins is load-bearing).
|
|
18
|
+
* • policyAllow / policyDeny are AND-GROUPS OR'd: each group is `( c1 AND c2 ... )`,
|
|
19
|
+
* groups joined by ` OR `. Preserving the AND-within / OR-across grouping EXACTLY is
|
|
20
|
+
* security-critical — flattening `(a AND b) OR (c)` into `a OR b OR c` over-widens.
|
|
21
|
+
*
|
|
22
|
+
* ── NO SQL INJECTION (the whole point): the ONLY tokens interpolated into the `sql`
|
|
23
|
+
* string are PHYSICAL COLUMN identifiers resolved from the {@link ObjectType} registry
|
|
24
|
+
* (via `columnOf`/`ownerColumn`/`uuidPkColumn`/`tenantColumnOf` from `@astram/engine` —
|
|
25
|
+
* the guard→engine→core DAG makes that import legal), backtick-quoted. Every SPEC VALUE
|
|
26
|
+
* is a `?` placeholder with the value pushed to `params` in emission order — NEVER
|
|
27
|
+
* interpolated. An UNKNOWN field key (not registered on the type) is REJECTED (throws) —
|
|
28
|
+
* a rule referencing an unregistered field is a misconfiguration, and emitting the raw
|
|
29
|
+
* key as a column IS the injection hole (fail the read closed instead).
|
|
30
|
+
*
|
|
31
|
+
* ── FAIL-CLOSED OPERATORS (mirrors `mariadb-record-rule-adapter.ts`'s `conditionHolds`
|
|
32
|
+
* so the SQL row set equals the per-record verdict, row-for-row):
|
|
33
|
+
* • the NEGATIVE operators (`ne`/`not_in`/`not_contains`/`is_not_owner`) emit an
|
|
34
|
+
* `IS NOT NULL` guard so a NULL column never wrongly matches (the Phase-0/0.4
|
|
35
|
+
* widening bug in SQL form — `NULL <> ?` must not include the row).
|
|
36
|
+
* • `is_owner`/`is_not_owner` additionally guard `<> ''` (an empty owner column must
|
|
37
|
+
* never "match" an empty principal id) and compare to `principal.id`, NOT the
|
|
38
|
+
* condition operand (the operand is ignored, exactly as `conditionHolds` does).
|
|
39
|
+
* • `contains`/`not_contains` escape the LIKE metacharacters (`\ % _`) and use
|
|
40
|
+
* `ESCAPE '\\'` (mirrors record-engine's search LIKE).
|
|
41
|
+
* • an UNKNOWN operator falls to a defensive `FALSE` (fail-closed — never omit-and-widen,
|
|
42
|
+
* never throw-open). The switch is over the closed {@link PolicyOperator} type, so this
|
|
43
|
+
* is belt-and-braces.
|
|
44
|
+
*
|
|
45
|
+
* ── `$actor` TOKENS (mirrors `resolveValue`): a scalar-op value of `'$actor.id'` /
|
|
46
|
+
* `'$actor.tenant'` resolves to the principal's id / tenant AS A BOUND PARAM (still `?`).
|
|
47
|
+
* Inside an `in`/`not_in` SET the adapter does NOT resolve `$actor` — neither do we.
|
|
48
|
+
*
|
|
49
|
+
* ── `in`/`not_in` SERIALIZATION (the Phase-1 review's Low-1/Low-2 obligation): the value
|
|
50
|
+
* may arrive as an ARRAY (`['us','eu']`) or a COMMA-STRING (`'us,eu'`); BOTH expand to
|
|
51
|
+
* the SAME token list (split on `,`, trim) so the emitted `IN (?, ?)` matches the
|
|
52
|
+
* adapter's `String(rpr_value).split(',')` membership test exactly.
|
|
53
|
+
*
|
|
54
|
+
* ── ROOT-UNBOUNDED: `tenantBound === 'root-unbounded'` emits NO tenant clause (root spans
|
|
55
|
+
* tenants) AND OMITS the share + crossTenant terms — root's ownerBaseline is `{kind:'all'}`
|
|
56
|
+
* ⇒ the union is `(TRUE)` (all rows), so share/crossTenant would be redundant (and share
|
|
57
|
+
* needs a tenant value root does not carry). crossTenant is ALWAYS omitted in Task 2.1
|
|
58
|
+
* (Phase 4 completes the real cross-tenant record set).
|
|
59
|
+
*
|
|
60
|
+
* ── `tenantSubtree` — the scoped-hierarchy tenant bound (ADR-0027). Core
|
|
61
|
+
* (`ScopeTenantBound`) emits `{role:'tenantSubtree', nodeIds}` for every non-root list
|
|
62
|
+
* (the generalization of the flat `tenantId` bound), where `nodeIds` is the PRE-EXPANDED
|
|
63
|
+
* reachable subtree (`principal.scopeSubtreeNodeIds` — the active node + descendants,
|
|
64
|
+
* resolved once at login and cached, Task 2.2). This translator emits a DIRECT membership:
|
|
65
|
+
* `tenant_col IN (?, ...)` over those node ids — a row is visible when its tenant node is
|
|
66
|
+
* IN the subtree. Every id is `?`-bound. It uses the SAME cached set the tenant GATE tests
|
|
67
|
+
* membership against, so list ≡ decide holds BY CONSTRUCTION (no closure query at list time
|
|
68
|
+
* → no divergence from a stale/absent `scope_closure` row, and no closure read on the list
|
|
69
|
+
* hot path — the ADR-0024 parity guarantee). The subtree clause is ANDed with the positive
|
|
70
|
+
* union + deny sections exactly like the flat `tenantId` case — NOT an early return. Fails
|
|
71
|
+
* CLOSED (`{sql:'FALSE', params:[]}`) when the type has no tenant column (misconfiguration)
|
|
72
|
+
* or when `nodeIds` is empty (no reachable scope) — never silently widen. Note:
|
|
73
|
+
* `tenantSubtree` carries no single flat tenant value, so the share term (which needs one)
|
|
74
|
+
* is naturally omitted here.
|
|
75
|
+
*
|
|
76
|
+
* PURE — no DB, no I/O. `translateListScope(spec, reg, principal) → { sql, params }`.
|
|
77
|
+
*/
|
|
78
|
+
import type { ListScopeSpec, ScopeCondition } from '@astram/core';
|
|
79
|
+
import { type ObjectType } from '@astram/engine';
|
|
80
|
+
/** The translated fragment: a boolean WHERE expression + its ordered bind params. */
|
|
81
|
+
export interface TranslatedListScope {
|
|
82
|
+
/** A SQL boolean expression carrying ONLY `?` placeholders + backtick columns. */
|
|
83
|
+
readonly sql: string;
|
|
84
|
+
/** The bind values, in the exact order the `?` placeholders appear in `sql`. */
|
|
85
|
+
readonly params: unknown[];
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* The principal facts the translator needs to resolve `is_owner`/`is_not_owner` and
|
|
89
|
+
* `$actor.*` tokens — threaded EXPLICITLY (not read off the spec) so the translator's
|
|
90
|
+
* ownership/token resolution matches the adapter's `input.principal.id` /
|
|
91
|
+
* `input.principal.tenantId` exactly (Decision A in the task report).
|
|
92
|
+
*/
|
|
93
|
+
export interface ListScopePrincipal {
|
|
94
|
+
readonly principalId: string;
|
|
95
|
+
readonly principalTenantId: string;
|
|
96
|
+
}
|
|
97
|
+
/** Error thrown when a scope condition references a field the type does not register. */
|
|
98
|
+
export declare class UnknownScopeFieldError extends Error {
|
|
99
|
+
constructor(typeKey: string, field: string);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Translate the full {@link ListScopeSpec} into a SAFE parameterized WHERE fragment.
|
|
103
|
+
*
|
|
104
|
+
* @param spec the abstract visible-set description (from `computeListScope`).
|
|
105
|
+
* @param reg the target object type registration (the ONLY source of columns).
|
|
106
|
+
* @param principal the actor's id + tenant, for `is_owner`/`$actor.*` resolution.
|
|
107
|
+
* @returns `{ sql, params }` — `sql` carries ONLY `?` + backtick columns; `params` the
|
|
108
|
+
* bound values in `?`-order.
|
|
109
|
+
* @throws {@link UnknownScopeFieldError} if any condition names an unregistered field.
|
|
110
|
+
*/
|
|
111
|
+
export declare function translateListScope(spec: ListScopeSpec, reg: ObjectType, principal: ListScopePrincipal, opts?: {
|
|
112
|
+
schema?: string;
|
|
113
|
+
nowMs?: () => number;
|
|
114
|
+
/**
|
|
115
|
+
* The OWNING tenant's deny AND-groups (Task 4.2 — the fail-open leak fix). Applied ONLY to
|
|
116
|
+
* the cross-tenant branch (`crossTenantReach AND NOT (owningTenantDeny)`), mirroring
|
|
117
|
+
* `decide()`'s per-record evaluation at the resource's tenant. Empty/omitted ⇒ no
|
|
118
|
+
* owning-tenant deny (the common no-cross-grant path — the structure is then unchanged).
|
|
119
|
+
* The same-tenant deny stays `spec.policyDeny` (scoped to the actor's subtree). Global
|
|
120
|
+
* (NULL-tenant) deny rules appear in BOTH sets (the wiring fetches them for both tenant
|
|
121
|
+
* sets), so they exclude rows in either branch, exactly as `decide()` applies them.
|
|
122
|
+
*/
|
|
123
|
+
owningTenantDeny?: readonly (readonly ScopeCondition[])[];
|
|
124
|
+
}): TranslatedListScope;
|
|
125
|
+
//# sourceMappingURL=list-scope-sql.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-scope-sql.d.ts","sourceRoot":"","sources":["../../src/authz/list-scope-sql.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4EG;AAEH,OAAO,KAAK,EACV,aAAa,EACb,cAAc,EAIf,MAAM,cAAc,CAAC;AACtB,OAAO,EAKL,KAAK,UAAU,EAChB,MAAM,gBAAgB,CAAC;AAKxB,qFAAqF;AACrF,MAAM,WAAW,mBAAmB;IAClC,kFAAkF;IAClF,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,gFAAgF;IAChF,QAAQ,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;CAC5B;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;CACpC;AAED,yFAAyF;AACzF,qBAAa,sBAAuB,SAAQ,KAAK;gBACnC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;CAO3C;AAmID;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,aAAa,EACnB,GAAG,EAAE,UAAU,EACf,SAAS,EAAE,kBAAkB,EAC7B,IAAI,GAAE;IACJ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,MAAM,CAAC;IACrB;;;;;;;;OAQG;IACH,gBAAgB,CAAC,EAAE,SAAS,CAAC,SAAS,cAAc,EAAE,CAAC,EAAE,CAAC;CACtD,GACL,mBAAmB,CAoJrB"}
|