@astram/guard 0.1.1 → 0.3.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 +245 -0
- package/dist/auth/account.controller.d.ts.map +1 -0
- package/dist/auth/account.controller.js +673 -0
- package/dist/auth/account.controller.js.map +1 -0
- package/dist/auth/auth.controller.d.ts +316 -0
- package/dist/auth/auth.controller.d.ts.map +1 -0
- package/dist/auth/auth.controller.js +1091 -0
- package/dist/auth/auth.controller.js.map +1 -0
- package/dist/auth/auth.module.d.ts +202 -0
- package/dist/auth/auth.module.d.ts.map +1 -0
- package/dist/auth/auth.module.js +610 -0
- package/dist/auth/auth.module.js.map +1 -0
- package/dist/auth/connections.d.ts +61 -0
- package/dist/auth/connections.d.ts.map +1 -0
- package/dist/auth/connections.js +116 -0
- package/dist/auth/connections.js.map +1 -0
- package/dist/auth/dto.d.ts +154 -0
- package/dist/auth/dto.d.ts.map +1 -0
- package/dist/auth/dto.js +29 -0
- package/dist/auth/dto.js.map +1 -0
- package/dist/auth/pending-mfa-store.d.ts +72 -0
- package/dist/auth/pending-mfa-store.d.ts.map +1 -0
- package/dist/auth/pending-mfa-store.js +106 -0
- package/dist/auth/pending-mfa-store.js.map +1 -0
- package/dist/auth/persistence.module.d.ts +42 -0
- package/dist/auth/persistence.module.d.ts.map +1 -0
- package/dist/auth/persistence.module.js +94 -0
- package/dist/auth/persistence.module.js.map +1 -0
- package/dist/auth/ports/audit-sink.d.ts +47 -0
- package/dist/auth/ports/audit-sink.d.ts.map +1 -0
- package/dist/auth/ports/audit-sink.js +20 -0
- package/dist/auth/ports/audit-sink.js.map +1 -0
- package/dist/auth/ports/credential-writer.d.ts +23 -0
- package/dist/auth/ports/credential-writer.d.ts.map +1 -0
- package/dist/auth/ports/credential-writer.js +2 -0
- package/dist/auth/ports/credential-writer.js.map +1 -0
- package/dist/auth/ports/email-sender.d.ts +14 -0
- package/dist/auth/ports/email-sender.d.ts.map +1 -0
- package/dist/auth/ports/email-sender.js +2 -0
- package/dist/auth/ports/email-sender.js.map +1 -0
- package/dist/auth/ports/mfa-device-store.d.ts +45 -0
- package/dist/auth/ports/mfa-device-store.d.ts.map +1 -0
- package/dist/auth/ports/mfa-device-store.js +13 -0
- package/dist/auth/ports/mfa-device-store.js.map +1 -0
- package/dist/auth/ports/profile-writer.d.ts +12 -0
- package/dist/auth/ports/profile-writer.d.ts.map +1 -0
- package/dist/auth/ports/profile-writer.js +2 -0
- package/dist/auth/ports/profile-writer.js.map +1 -0
- package/dist/auth/ports/recovery-code-store.d.ts +10 -0
- package/dist/auth/ports/recovery-code-store.d.ts.map +1 -0
- package/dist/auth/ports/recovery-code-store.js +2 -0
- package/dist/auth/ports/recovery-code-store.js.map +1 -0
- package/dist/auth/ports/reset-token-store.d.ts +12 -0
- package/dist/auth/ports/reset-token-store.d.ts.map +1 -0
- package/dist/auth/ports/reset-token-store.js +2 -0
- package/dist/auth/ports/reset-token-store.js.map +1 -0
- package/dist/auth/ports/session-facts-projector.d.ts +44 -0
- package/dist/auth/ports/session-facts-projector.d.ts.map +1 -0
- package/dist/auth/ports/session-facts-projector.js +30 -0
- package/dist/auth/ports/session-facts-projector.js.map +1 -0
- package/dist/auth/ports/session-sweeper.d.ts +12 -0
- package/dist/auth/ports/session-sweeper.d.ts.map +1 -0
- package/dist/auth/ports/session-sweeper.js +2 -0
- package/dist/auth/ports/session-sweeper.js.map +1 -0
- package/dist/auth/profile-resolver.d.ts +73 -0
- package/dist/auth/profile-resolver.d.ts.map +1 -0
- package/dist/auth/profile-resolver.js +28 -0
- package/dist/auth/profile-resolver.js.map +1 -0
- package/dist/auth/rate-limit/attempt-limiter.d.ts +91 -0
- package/dist/auth/rate-limit/attempt-limiter.d.ts.map +1 -0
- package/dist/auth/rate-limit/attempt-limiter.js +133 -0
- package/dist/auth/rate-limit/attempt-limiter.js.map +1 -0
- package/dist/auth/tokens.d.ts +236 -0
- package/dist/auth/tokens.d.ts.map +1 -0
- package/dist/auth/tokens.js +254 -0
- package/dist/auth/tokens.js.map +1 -0
- package/dist/auth/totp-enrollment.d.ts +42 -0
- package/dist/auth/totp-enrollment.d.ts.map +1 -0
- package/dist/auth/totp-enrollment.js +96 -0
- package/dist/auth/totp-enrollment.js.map +1 -0
- package/dist/authentication/argon2id-password-hasher.js.map +1 -0
- package/dist/authentication/mariadb-credential-resolver.d.ts +110 -0
- package/dist/authentication/mariadb-credential-resolver.d.ts.map +1 -0
- package/dist/authentication/mariadb-credential-resolver.js +170 -0
- package/dist/authentication/mariadb-credential-resolver.js.map +1 -0
- package/dist/authz/cross-tenant-grant-writer.d.ts +259 -0
- package/dist/authz/cross-tenant-grant-writer.d.ts.map +1 -0
- package/dist/authz/cross-tenant-grant-writer.js +397 -0
- package/dist/authz/cross-tenant-grant-writer.js.map +1 -0
- package/dist/authz/manifest-operation-authority-adapter.d.ts +65 -0
- package/dist/authz/manifest-operation-authority-adapter.d.ts.map +1 -0
- package/dist/authz/manifest-operation-authority-adapter.js +108 -0
- package/dist/authz/manifest-operation-authority-adapter.js.map +1 -0
- package/dist/authz/mariadb-cross-tenant-grant-adapter.d.ts +90 -0
- package/dist/authz/mariadb-cross-tenant-grant-adapter.d.ts.map +1 -0
- package/dist/authz/mariadb-cross-tenant-grant-adapter.js +211 -0
- package/dist/authz/mariadb-cross-tenant-grant-adapter.js.map +1 -0
- package/dist/authz/mariadb-record-rule-adapter.d.ts +60 -0
- package/dist/authz/mariadb-record-rule-adapter.d.ts.map +1 -0
- package/dist/authz/mariadb-record-rule-adapter.js +154 -0
- package/dist/authz/mariadb-record-rule-adapter.js.map +1 -0
- package/dist/authz/mariadb-record-share-adapter.d.ts +75 -0
- package/dist/authz/mariadb-record-share-adapter.d.ts.map +1 -0
- package/dist/authz/mariadb-record-share-adapter.js +106 -0
- package/dist/authz/mariadb-record-share-adapter.js.map +1 -0
- package/dist/authz/record-share-cascade.d.ts +52 -0
- package/dist/authz/record-share-cascade.d.ts.map +1 -0
- package/dist/authz/record-share-cascade.js +49 -0
- package/dist/authz/record-share-cascade.js.map +1 -0
- package/dist/authz/record-share-writer.d.ts +175 -0
- package/dist/authz/record-share-writer.d.ts.map +1 -0
- package/dist/authz/record-share-writer.js +225 -0
- package/dist/authz/record-share-writer.js.map +1 -0
- package/dist/authz/wire-record-authorization.d.ts +66 -0
- package/dist/authz/wire-record-authorization.d.ts.map +1 -0
- package/dist/authz/wire-record-authorization.js +34 -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.d.ts +21 -0
- package/dist/completeness/catalog-reconciler.d.ts.map +1 -0
- package/dist/completeness/catalog-reconciler.js +74 -0
- package/dist/completeness/catalog-reconciler.js.map +1 -0
- package/dist/completeness/operation-inventory-scanner.d.ts +17 -0
- package/dist/completeness/operation-inventory-scanner.d.ts.map +1 -0
- package/dist/completeness/operation-inventory-scanner.js +79 -0
- package/dist/completeness/operation-inventory-scanner.js.map +1 -0
- package/dist/completeness/ports/catalog-store.d.ts +33 -0
- package/dist/completeness/ports/catalog-store.d.ts.map +1 -0
- package/dist/completeness/ports/catalog-store.js +2 -0
- package/dist/completeness/ports/catalog-store.js.map +1 -0
- package/dist/config/app-config.d.ts +134 -1
- package/dist/config/app-config.d.ts.map +1 -1
- package/dist/config/app-config.js +144 -2
- package/dist/config/app-config.js.map +1 -0
- package/dist/config/config.module.js.map +1 -0
- package/dist/enforcement/classification.decorator.d.ts +33 -14
- package/dist/enforcement/classification.decorator.d.ts.map +1 -1
- package/dist/enforcement/classification.decorator.js +34 -14
- 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 +29 -19
- package/dist/enforcement/global-enforcement.guard.d.ts.map +1 -1
- package/dist/enforcement/global-enforcement.guard.js +108 -25
- package/dist/enforcement/global-enforcement.guard.js.map +1 -0
- package/dist/enforcement/reenroll-allowlist.d.ts +49 -0
- package/dist/enforcement/reenroll-allowlist.d.ts.map +1 -0
- package/dist/enforcement/reenroll-allowlist.js +77 -0
- package/dist/enforcement/reenroll-allowlist.js.map +1 -0
- package/dist/index.d.ts +43 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +198 -1
- package/dist/index.js.map +1 -0
- package/dist/module/shield-tokens.d.ts +15 -0
- package/dist/module/shield-tokens.d.ts.map +1 -0
- package/dist/module/shield-tokens.js +17 -0
- package/dist/module/shield-tokens.js.map +1 -0
- package/dist/module/shield.module.d.ts +203 -8
- package/dist/module/shield.module.d.ts.map +1 -1
- package/dist/module/shield.module.js +232 -14
- package/dist/module/shield.module.js.map +1 -0
- package/dist/request-auth/request-principal.d.ts +42 -0
- package/dist/request-auth/request-principal.d.ts.map +1 -0
- package/dist/request-auth/request-principal.js +87 -0
- package/dist/request-auth/request-principal.js.map +1 -0
- package/dist/request-auth/session-facts-als.d.ts +65 -0
- package/dist/request-auth/session-facts-als.d.ts.map +1 -0
- package/dist/request-auth/session-facts-als.js +57 -0
- package/dist/request-auth/session-facts-als.js.map +1 -0
- package/dist/request-auth/session-token-binder.d.ts +130 -0
- package/dist/request-auth/session-token-binder.d.ts.map +1 -0
- package/dist/request-auth/session-token-binder.js +277 -0
- package/dist/request-auth/session-token-binder.js.map +1 -0
- package/dist/request-auth/tokens.d.ts +14 -0
- package/dist/request-auth/tokens.d.ts.map +1 -0
- package/dist/request-auth/tokens.js +16 -0
- package/dist/request-auth/tokens.js.map +1 -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/package.json +2 -2
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
import { type DynamicModule } from '@nestjs/common';
|
|
2
|
+
import type { CredentialResolver, FactorVerifier } from '@astram/core';
|
|
3
|
+
import type { RecordAuthorizationInputs } from '../authz/wire-record-authorization.js';
|
|
4
|
+
import type { ProfileResolver } from '../auth/profile-resolver.js';
|
|
5
|
+
import type { CredentialWriter } from '../auth/ports/credential-writer.js';
|
|
6
|
+
import type { ResetTokenStore } from '../auth/ports/reset-token-store.js';
|
|
7
|
+
import type { EmailSender } from '../auth/ports/email-sender.js';
|
|
8
|
+
import type { RecoveryCodeStore } from '../auth/ports/recovery-code-store.js';
|
|
9
|
+
import type { ProfileWriter } from '../auth/ports/profile-writer.js';
|
|
10
|
+
import type { SessionSweeper } from '../auth/ports/session-sweeper.js';
|
|
11
|
+
import type { MfaDeviceStore } from '../auth/ports/mfa-device-store.js';
|
|
12
|
+
import type { AuditSink } from '../auth/ports/audit-sink.js';
|
|
13
|
+
import type { SessionFactsProjector } from '../auth/ports/session-facts-projector.js';
|
|
2
14
|
import type { CoreDecisionAuthority } from '../enforcement/core-seam.js';
|
|
3
15
|
import { type AppConfig } from '../config/app-config.js';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
* `@astram/core` authority through {@link ShieldModule.forRoot}; when omitted the
|
|
8
|
-
* framework binds the fail-closed {@link stubDecisionAuthority} (deny-by-default),
|
|
9
|
-
* so a mis-wiring cannot silently open a door.
|
|
10
|
-
*/
|
|
11
|
-
export declare const SHIELD_DECISION_AUTHORITY: unique symbol;
|
|
16
|
+
import { SHIELD_DECISION_AUTHORITY } from './shield-tokens.js';
|
|
17
|
+
export { SHIELD_DECISION_AUTHORITY };
|
|
18
|
+
export type { RecordAuthorizationInputs } from '../authz/wire-record-authorization.js';
|
|
12
19
|
/**
|
|
13
20
|
* Options for {@link ShieldModule.forRoot}. Intentionally minimal (ADR-0023 §7 —
|
|
14
21
|
* no speculative abstraction): the consumer declares Shield through this ONE seam.
|
|
@@ -21,12 +28,126 @@ export interface ShieldModuleOptions {
|
|
|
21
28
|
* the real Core authority — the guard's call site does not change.
|
|
22
29
|
*/
|
|
23
30
|
readonly decisionAuthority?: CoreDecisionAuthority;
|
|
31
|
+
/**
|
|
32
|
+
* ⛔ FRAMEWORK-OWNED RECORD-TIER WIRING (design §9, Phase 5 — the preferred path).
|
|
33
|
+
*
|
|
34
|
+
* Supply the PIECES the framework needs to build the real Core decision authority
|
|
35
|
+
* ITSELF, instead of a pre-built {@link decisionAuthority}. When present, ShieldModule
|
|
36
|
+
* INTERNALLY constructs the four record-tier adapters
|
|
37
|
+
* (`MariaDbRecordPermissionRuleAdapter` / `MariaDbRecordShareAdapter` /
|
|
38
|
+
* `MariaDbCrossTenantGrantAdapter` / `ManifestOperationAuthorityAdapter`) over the
|
|
39
|
+
* supplied `pool`/`operationManifest` and calls core's `createWiredDecisionAuthority`
|
|
40
|
+
* with them + the app-owned `permissionFacts` / `sessionFacts` / `registry`.
|
|
41
|
+
*
|
|
42
|
+
* The app supplies ONLY: the DB `pool`, the two app-owned ports (`permissionFacts`,
|
|
43
|
+
* `sessionFacts`), the module `registry`, and the operation-manifest DATA. It CANNOT
|
|
44
|
+
* supply — or weaken — the four record-tier read adapters: they are framework-owned and
|
|
45
|
+
* un-overridable BY CONSTRUCTION (a planted fail-open record adapter is impossible —
|
|
46
|
+
* the whole point of the "framework-owns-the-data-layer" initiative).
|
|
47
|
+
*
|
|
48
|
+
* MUTUALLY EXCLUSIVE with {@link decisionAuthority} — supplying BOTH is a misconfig and
|
|
49
|
+
* throws at registration. Supplying NEITHER binds the fail-closed stub (unchanged).
|
|
50
|
+
*/
|
|
51
|
+
readonly recordAuthorization?: RecordAuthorizationInputs;
|
|
24
52
|
/**
|
|
25
53
|
* Application config (port/environment/ADR-0018 pool budget). Omit to load from
|
|
26
54
|
* the environment via {@link loadAppConfig}. Supplied here so a consumer can
|
|
27
55
|
* inject computed config through the one seam rather than editing the framework.
|
|
28
56
|
*/
|
|
29
57
|
readonly config?: AppConfig;
|
|
58
|
+
/**
|
|
59
|
+
* ⛔ OPT-IN: the framework-owned login → session auth surface (Phase 0b — the
|
|
60
|
+
* `/auth/*` endpoints + the composed `Authenticator` / `SessionAuthority`).
|
|
61
|
+
*
|
|
62
|
+
* DEFAULT `false` (ABSENT): an enforcement-only app does NOT import
|
|
63
|
+
* {@link AuthModule} — so it never opens a MariaDB pool / Redis client, never
|
|
64
|
+
* fires the fail-closed `assertRefreshHmacKey` gate, and keeps the no-`.env`
|
|
65
|
+
* boot promised by `create-astram-app`. `ShieldModule.forRoot()` composes with
|
|
66
|
+
* a blank refresh-HMAC key and no live connection (enforcement-only).
|
|
67
|
+
*
|
|
68
|
+
* `true`: imports {@link AuthModule.forRoot} (which pulls the live connections +
|
|
69
|
+
* composes the authenticator + session authority + registers the four `/auth/*`
|
|
70
|
+
* routes) and re-exports {@link SHIELD_AUTHENTICATOR} / {@link SHIELD_SESSION_AUTHORITY}
|
|
71
|
+
* app-wide. An auth-enabled app fails LOUD at boot if `SHIELD_REFRESH_HMAC_KEY`
|
|
72
|
+
* is blank — auth can never compose unkeyed.
|
|
73
|
+
*/
|
|
74
|
+
readonly auth?: boolean;
|
|
75
|
+
/**
|
|
76
|
+
* OPTIONAL custom credential resolver (the store login checks against). Omit →
|
|
77
|
+
* the framework's default `MariaDbCredentialResolver` (reads
|
|
78
|
+
* `shield_identity.identity_credential`). Supply a consumer implementation of the
|
|
79
|
+
* core `CredentialResolver` port to authenticate against your OWN user/identity
|
|
80
|
+
* schema (e.g. a multi-tenant users+roles model) WITHOUT editing the framework.
|
|
81
|
+
*
|
|
82
|
+
* Only consulted when `auth: true` (a no-op without it — no AuthModule composes,
|
|
83
|
+
* so no resolver is wired). The seam swaps the STORE only: a supplied resolver
|
|
84
|
+
* still flows through the SAME composed authenticator (anti-enumeration decoy
|
|
85
|
+
* verify, MFA, no-secret-leak). A resolver returning `null` = unknown principal
|
|
86
|
+
* (generic 401); throwing = fail-closed transient — exactly the default contract.
|
|
87
|
+
*/
|
|
88
|
+
readonly credentialResolver?: CredentialResolver;
|
|
89
|
+
/**
|
|
90
|
+
* OPTIONAL current-user profile resolver backing `GET /auth/me`. Omit → `/auth/me`
|
|
91
|
+
* returns an honest 501 (the framework is agnostic to your ORG schema, so it cannot
|
|
92
|
+
* name the user/company/roles without your tables). Supply an implementation of the
|
|
93
|
+
* {@link ProfileResolver} port to return the signed-in user's display profile
|
|
94
|
+
* (names, never UUIDs). Only consulted when `auth: true`.
|
|
95
|
+
*/
|
|
96
|
+
readonly profileResolver?: ProfileResolver;
|
|
97
|
+
/**
|
|
98
|
+
* OPTIONAL account/credential-surface seams (forgot/reset, change-password, MFA
|
|
99
|
+
* enrollment, profile edit). Each is threaded straight through to
|
|
100
|
+
* {@link AuthModule.forRoot} (bound under its token, or `null` when absent → the
|
|
101
|
+
* route returns 501). Only consulted when `auth: true`. Supply a consumer
|
|
102
|
+
* implementation of the matching `@astram/guard` port to enable the route.
|
|
103
|
+
*/
|
|
104
|
+
readonly credentialWriter?: CredentialWriter;
|
|
105
|
+
readonly resetTokenStore?: ResetTokenStore;
|
|
106
|
+
readonly emailSender?: EmailSender;
|
|
107
|
+
readonly recoveryCodeStore?: RecoveryCodeStore;
|
|
108
|
+
readonly profileWriter?: ProfileWriter;
|
|
109
|
+
readonly sessionSweeper?: SessionSweeper;
|
|
110
|
+
/**
|
|
111
|
+
* OPTIONAL auth-surface audit sink — see {@link AuthModuleOptions.auditSink}.
|
|
112
|
+
* Threaded straight through to {@link AuthModule.forRoot} (bound under its token, or
|
|
113
|
+
* `null` when absent → the recovery-login audit no-ops). Only consulted when
|
|
114
|
+
* `auth: true`.
|
|
115
|
+
*/
|
|
116
|
+
readonly auditSink?: AuditSink;
|
|
117
|
+
/**
|
|
118
|
+
* OPTIONAL multi-device MFA store — see {@link AuthModuleOptions.mfaDeviceStore}.
|
|
119
|
+
* Threaded straight through to {@link AuthModule.forRoot} (bound under its token,
|
|
120
|
+
* or `null` when absent → the device routes 501). Only consulted when `auth: true`.
|
|
121
|
+
*/
|
|
122
|
+
readonly mfaDeviceStore?: MfaDeviceStore;
|
|
123
|
+
/**
|
|
124
|
+
* OPTIONAL login `totp` verifier override — see {@link AuthModuleOptions.totpVerifier}.
|
|
125
|
+
* Threaded straight through to {@link AuthModule.forRoot} (replaces the default
|
|
126
|
+
* single-secret verifier in the composed authenticator; absent → the default). A
|
|
127
|
+
* consumer plugs an OR-matching multi-device verifier here. Only consulted when
|
|
128
|
+
* `auth: true`.
|
|
129
|
+
*/
|
|
130
|
+
readonly totpVerifier?: FactorVerifier;
|
|
131
|
+
/**
|
|
132
|
+
* OPTIONAL root allowlist — the server-side, trusted set of canonical
|
|
133
|
+
* principal ids (user uuids) that ARE roots. Threaded straight through
|
|
134
|
+
* to {@link AuthModule.forRoot} → `createIdentityBroker({ internalRootIds })`.
|
|
135
|
+
* ROOT SAFETY: this is the ONLY way a login mints a root (the
|
|
136
|
+
* Internal identity adapter keys the trusted signal off THIS list, never off a
|
|
137
|
+
* claim). Omit → `[]` → default-deny (nobody is a root). Only consulted when
|
|
138
|
+
* `auth: true`.
|
|
139
|
+
*/
|
|
140
|
+
readonly rootIds?: readonly string[];
|
|
141
|
+
/**
|
|
142
|
+
* OPTIONAL eager session-facts projector (ADR-0011) — see
|
|
143
|
+
* {@link AuthModuleOptions.sessionFactsProjector}. Threaded straight through to
|
|
144
|
+
* {@link AuthModule.forRoot} (bound under {@link SHIELD_SESSION_FACTS_PROJECTOR}, or
|
|
145
|
+
* `null` when absent → the auth controller omits `cachedFacts` and gate 5 DB-reloads
|
|
146
|
+
* every request, today's behavior). When supplied, login/refresh cache the principal's
|
|
147
|
+
* coarse grants on the session binding so gate 5 serves them from the request's
|
|
148
|
+
* `cachedFacts`. Only consulted when `auth: true`.
|
|
149
|
+
*/
|
|
150
|
+
readonly sessionFactsProjector?: SessionFactsProjector;
|
|
30
151
|
}
|
|
31
152
|
/** Async variant of {@link ShieldModuleOptions} (DI-computed config). */
|
|
32
153
|
export interface ShieldModuleAsyncOptions {
|
|
@@ -36,6 +157,80 @@ export interface ShieldModuleAsyncOptions {
|
|
|
36
157
|
readonly useFactory: (...args: readonly unknown[]) => Promise<ShieldModuleOptions> | ShieldModuleOptions;
|
|
37
158
|
/** Modules exporting the injected providers. */
|
|
38
159
|
readonly imports?: readonly unknown[];
|
|
160
|
+
/**
|
|
161
|
+
* ⛔ OPT-IN auth (see {@link ShieldModuleOptions.auth}). STATIC here (not part of
|
|
162
|
+
* the async factory result): whether an app wires the auth surface is a
|
|
163
|
+
* deployment-topology decision known at REGISTRATION time, and a NestJS
|
|
164
|
+
* `DynamicModule.imports` list is composed statically — it cannot depend on the
|
|
165
|
+
* async-resolved `ShieldModuleOptions`. So the flag lives on the async-options
|
|
166
|
+
* object directly, gating the {@link AuthModule} import + engine re-exports
|
|
167
|
+
* exactly like {@link forRoot}. DEFAULT `false` (no auth → no live connection →
|
|
168
|
+
* no-`.env` boot preserved).
|
|
169
|
+
*/
|
|
170
|
+
readonly auth?: boolean;
|
|
171
|
+
/**
|
|
172
|
+
* OPTIONAL custom credential resolver — see {@link ShieldModuleOptions.credentialResolver}.
|
|
173
|
+
* STATIC here (like {@link auth}, NOT part of the async factory result): the
|
|
174
|
+
* resolver instance is a registration-time collaborator threaded into the
|
|
175
|
+
* statically-composed {@link AuthModule} import, so it cannot depend on the
|
|
176
|
+
* async-resolved options. Only consulted when `auth: true`.
|
|
177
|
+
*/
|
|
178
|
+
readonly credentialResolver?: CredentialResolver;
|
|
179
|
+
/**
|
|
180
|
+
* OPTIONAL current-user profile resolver — see {@link ShieldModuleOptions.profileResolver}.
|
|
181
|
+
* STATIC here (like {@link credentialResolver}): a registration-time collaborator
|
|
182
|
+
* threaded into the statically-composed {@link AuthModule} import. Only consulted
|
|
183
|
+
* when `auth: true`.
|
|
184
|
+
*/
|
|
185
|
+
readonly profileResolver?: ProfileResolver;
|
|
186
|
+
/**
|
|
187
|
+
* OPTIONAL account/credential-surface seams — see
|
|
188
|
+
* {@link ShieldModuleOptions.credentialWriter} et al. STATIC here (like the other
|
|
189
|
+
* seams): registration-time collaborators threaded into the statically-composed
|
|
190
|
+
* {@link AuthModule} import, so they cannot depend on the async-resolved options.
|
|
191
|
+
* Only consulted when `auth: true`.
|
|
192
|
+
*/
|
|
193
|
+
readonly credentialWriter?: CredentialWriter;
|
|
194
|
+
readonly resetTokenStore?: ResetTokenStore;
|
|
195
|
+
readonly emailSender?: EmailSender;
|
|
196
|
+
readonly recoveryCodeStore?: RecoveryCodeStore;
|
|
197
|
+
readonly profileWriter?: ProfileWriter;
|
|
198
|
+
readonly sessionSweeper?: SessionSweeper;
|
|
199
|
+
/**
|
|
200
|
+
* OPTIONAL auth-surface audit sink — see {@link ShieldModuleOptions.auditSink}.
|
|
201
|
+
* STATIC here (like the other seams): a registration-time collaborator threaded into
|
|
202
|
+
* the statically-composed {@link AuthModule} import. Only consulted when `auth: true`.
|
|
203
|
+
*/
|
|
204
|
+
readonly auditSink?: AuditSink;
|
|
205
|
+
/**
|
|
206
|
+
* OPTIONAL multi-device MFA store — see {@link ShieldModuleOptions.mfaDeviceStore}.
|
|
207
|
+
* STATIC here (like the other seams): a registration-time collaborator threaded into
|
|
208
|
+
* the statically-composed {@link AuthModule} import. Only consulted when `auth: true`.
|
|
209
|
+
*/
|
|
210
|
+
readonly mfaDeviceStore?: MfaDeviceStore;
|
|
211
|
+
/**
|
|
212
|
+
* OPTIONAL login `totp` verifier override — see {@link ShieldModuleOptions.totpVerifier}.
|
|
213
|
+
* STATIC here (like the other seams): a registration-time collaborator threaded into
|
|
214
|
+
* the statically-composed {@link AuthModule} import. Only consulted when `auth: true`.
|
|
215
|
+
*/
|
|
216
|
+
readonly totpVerifier?: FactorVerifier;
|
|
217
|
+
/**
|
|
218
|
+
* OPTIONAL root allowlist — see {@link ShieldModuleOptions.rootIds}.
|
|
219
|
+
* STATIC here (like the other seams): a registration-time collaborator threaded into
|
|
220
|
+
* the statically-composed {@link AuthModule} import (it is passed to the broker at
|
|
221
|
+
* authenticator-composition time, not part of the async factory result). A consumer
|
|
222
|
+
* that must COMPUTE the list at boot (e.g. read it from a DB) uses `forRootAsync`'s
|
|
223
|
+
* `useFactory` to build the whole options object — the resolved `rootIds` is
|
|
224
|
+
* then threaded exactly like the static case. Only consulted when `auth: true`.
|
|
225
|
+
*/
|
|
226
|
+
readonly rootIds?: readonly string[];
|
|
227
|
+
/**
|
|
228
|
+
* OPTIONAL eager session-facts projector — see {@link ShieldModuleOptions.sessionFactsProjector}.
|
|
229
|
+
* STATIC here (like the other seams): a registration-time collaborator threaded into the
|
|
230
|
+
* statically-composed {@link AuthModule} import, so it cannot depend on the async-resolved
|
|
231
|
+
* options. Only consulted when `auth: true`.
|
|
232
|
+
*/
|
|
233
|
+
readonly sessionFactsProjector?: SessionFactsProjector;
|
|
39
234
|
}
|
|
40
235
|
/**
|
|
41
236
|
* `ShieldModule` — the SINGLE registration seam (ADR-0023 §4).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shield.module.d.ts","sourceRoot":"","sources":["../../src/module/shield.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,aAAa,EAAiB,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"shield.module.d.ts","sourceRoot":"","sources":["../../src/module/shield.module.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,27 +1,130 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
2
18
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
19
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
20
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
21
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
22
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
23
|
};
|
|
24
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
+
var ownKeys = function(o) {
|
|
26
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
+
var ar = [];
|
|
28
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
+
return ar;
|
|
30
|
+
};
|
|
31
|
+
return ownKeys(o);
|
|
32
|
+
};
|
|
33
|
+
return function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
})();
|
|
8
41
|
var ShieldModule_1;
|
|
9
42
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
43
|
exports.ShieldModule = exports.SHIELD_DECISION_AUTHORITY = void 0;
|
|
11
44
|
const common_1 = require("@nestjs/common");
|
|
45
|
+
const node_url_1 = require("node:url");
|
|
12
46
|
const core_seam_js_1 = require("../enforcement/core-seam.js");
|
|
13
47
|
const enforcement_module_js_1 = require("../enforcement/enforcement.module.js");
|
|
14
48
|
const boot_module_js_1 = require("../boot/boot.module.js");
|
|
15
49
|
const config_module_js_1 = require("../config/config.module.js");
|
|
16
50
|
const app_config_js_1 = require("../config/app-config.js");
|
|
51
|
+
// Static import is SAFE: auth.module.ts top-level-imports @astram/core as TYPES
|
|
52
|
+
// only (it loads core's ESM factory VALUES lazily inside its async provider
|
|
53
|
+
// factories — see auth.module.ts loadCore()). So pulling AuthModule here does NOT
|
|
54
|
+
// trigger a runtime `require('@astram/core')`; the opt-in gate below still ensures
|
|
55
|
+
// the enforcement-only path never INSTANTIATES it (no live pool/Redis, no HMAC
|
|
56
|
+
// gate, no core load).
|
|
57
|
+
const auth_module_js_1 = require("../auth/auth.module.js");
|
|
58
|
+
// The `SHIELD_DECISION_AUTHORITY` token now lives in `./shield-tokens.js` so the
|
|
59
|
+
// enforcement guard can import it without a cycle (guard → token → ShieldModule →
|
|
60
|
+
// EnforcementModule → guard). Re-exported here to keep the public import path stable.
|
|
61
|
+
const shield_tokens_js_1 = require("./shield-tokens.js");
|
|
62
|
+
Object.defineProperty(exports, "SHIELD_DECISION_AUTHORITY", { enumerable: true, get: function () { return shield_tokens_js_1.SHIELD_DECISION_AUTHORITY; } });
|
|
63
|
+
/**
|
|
64
|
+
* A `Function`-wrapped dynamic `import()` that survives the CommonJS **build** — the same
|
|
65
|
+
* shim as auth.module.ts's `evalImport`. Under `module: commonjs`, `tsc` would rewrite a
|
|
66
|
+
* literal `import()` into `require(...)`; routing through the `Function` constructor keeps
|
|
67
|
+
* a genuine native `import()` in the emitted dist so this file's OWN compiled output stays
|
|
68
|
+
* free of a top-level `require('../authz/wire-record-authorization.js')` (→ core). We pass
|
|
69
|
+
* the file's absolute URL (resolved off `__dirname` in the CJS dist / `import.meta.url`
|
|
70
|
+
* would not exist here) so the eval'd import has a base to resolve against.
|
|
71
|
+
*/
|
|
72
|
+
const evalImport = new Function('specifier', 'return import(specifier);');
|
|
73
|
+
let cachedRecordAuthApi;
|
|
17
74
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
75
|
+
* Lazily load the framework's record-authorization builder. Invoked ONLY inside the
|
|
76
|
+
* `SHIELD_DECISION_AUTHORITY` async factory when a consumer supplies
|
|
77
|
+
* `recordAuthorization` — NEVER at module top-level. The target file value-imports
|
|
78
|
+
* `@astram/core` + the four adapter classes, so deferring its load keeps a runtime
|
|
79
|
+
* `require('@astram/core')` OUT of THIS module's (the enforcement-only) load path.
|
|
80
|
+
*
|
|
81
|
+
* TWO strategies, mirroring auth.module.ts's `loadCore`, so it works in BOTH runtimes:
|
|
82
|
+
* 1. A plain dynamic `import()` — native under vitest/SWC (source path).
|
|
83
|
+
* 2. On failure (the tsc-built CJS dist downlevels #1 to a throwing `require` when the
|
|
84
|
+
* transitive `@astram/core` ESM cannot be `require`d in that context), the
|
|
85
|
+
* {@link evalImport} `Function`-wrapped native `import()` resolved off `__dirname`.
|
|
23
86
|
*/
|
|
24
|
-
|
|
87
|
+
async function loadBuildRecordAuthorization() {
|
|
88
|
+
if (cachedRecordAuthApi === undefined) {
|
|
89
|
+
try {
|
|
90
|
+
cachedRecordAuthApi = (await Promise.resolve().then(() => __importStar(require('../authz/wire-record-authorization.js'))));
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
// Built-dist fallback (the CJS dist path — see evalImport). `__dirname` is defined
|
|
94
|
+
// in the emitted CJS module; resolve the compiled sibling relative to it and import
|
|
95
|
+
// it as a file:// URL so Node's CJS→ESM interop loads it (and its ESM-only core dep).
|
|
96
|
+
const base = (0, node_url_1.pathToFileURL)(`${__dirname}/../authz/wire-record-authorization.js`).href;
|
|
97
|
+
cachedRecordAuthApi = (await evalImport(base));
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return cachedRecordAuthApi.buildRecordAuthorization;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Resolve the `SHIELD_DECISION_AUTHORITY` VALUE from the caller's options (the ONE seam,
|
|
104
|
+
* ADR-0023 — only how its value is PRODUCED changes here). Precedence + mutual exclusion:
|
|
105
|
+
*
|
|
106
|
+
* - `recordAuthorization` PRESENT → the framework builds the REAL wired authority itself
|
|
107
|
+
* (the four record-tier adapters constructed inside guard, un-overridable). This is the
|
|
108
|
+
* Phase-5 path: the app can no longer supply or weaken those adapters.
|
|
109
|
+
* - `decisionAuthority` PRESENT (legacy passthrough) → bind the caller's pre-built
|
|
110
|
+
* authority verbatim (kept for other consumers / back-compat).
|
|
111
|
+
* - BOTH present → MISCONFIG: throw a clear error (they are mutually exclusive).
|
|
112
|
+
* - NEITHER → the fail-closed {@link stubDecisionAuthority} (unchanged fallback).
|
|
113
|
+
*
|
|
114
|
+
* Async because the `recordAuthorization` path lazy-loads the (core-touching) builder.
|
|
115
|
+
*/
|
|
116
|
+
async function resolveDecisionAuthority(options) {
|
|
117
|
+
if (options.recordAuthorization && options.decisionAuthority) {
|
|
118
|
+
throw new Error('ShieldModule: `recordAuthorization` and `decisionAuthority` are mutually exclusive — ' +
|
|
119
|
+
'supply the record-authorization inputs (pool + app ports + registry) so the framework ' +
|
|
120
|
+
'builds the decision authority, OR a pre-built `decisionAuthority`, but not both.');
|
|
121
|
+
}
|
|
122
|
+
if (options.recordAuthorization) {
|
|
123
|
+
const build = await loadBuildRecordAuthorization();
|
|
124
|
+
return build(options.recordAuthorization);
|
|
125
|
+
}
|
|
126
|
+
return options.decisionAuthority ?? core_seam_js_1.stubDecisionAuthority;
|
|
127
|
+
}
|
|
25
128
|
/**
|
|
26
129
|
* `ShieldModule` — the SINGLE registration seam (ADR-0023 §4).
|
|
27
130
|
*
|
|
@@ -50,19 +153,80 @@ let ShieldModule = ShieldModule_1 = class ShieldModule {
|
|
|
50
153
|
/** Register Shield with static options (the common path). */
|
|
51
154
|
static forRoot(options = {}) {
|
|
52
155
|
const config = options.config ?? (0, app_config_js_1.loadAppConfig)();
|
|
156
|
+
// Build the opt-in AuthModule ONCE so the SAME DynamicModule instance is both
|
|
157
|
+
// imported (composes) and re-exported (propagates its exported engine tokens
|
|
158
|
+
// app-wide through the @Global ShieldModule). Re-exporting the two Symbols
|
|
159
|
+
// directly is NOT valid Nest — a module may only re-export a whole imported
|
|
160
|
+
// module (or a token IT provides), so we export the AuthModule dynamic module.
|
|
161
|
+
// When auth is opted in, thread the consumer's optional credentialResolver into
|
|
162
|
+
// AuthModule (it binds the supplied instance under SHIELD_CREDENTIAL_RESOLVER;
|
|
163
|
+
// omitted → the default MariaDb store, unchanged). Without auth the resolver is
|
|
164
|
+
// irrelevant (no AuthModule composes) — a documented no-op.
|
|
165
|
+
const authModule = options.auth
|
|
166
|
+
? auth_module_js_1.AuthModule.forRoot(
|
|
167
|
+
// Only pass a property when the consumer supplied one — under
|
|
168
|
+
// `exactOptionalPropertyTypes`, an explicit `undefined` is not assignable
|
|
169
|
+
// to an optional field; a spread keeps it truly absent so AuthModule falls
|
|
170
|
+
// back to its defaults (MariaDb credential store; 501 /auth/me).
|
|
171
|
+
{
|
|
172
|
+
...(options.credentialResolver
|
|
173
|
+
? { credentialResolver: options.credentialResolver }
|
|
174
|
+
: {}),
|
|
175
|
+
...(options.profileResolver
|
|
176
|
+
? { profileResolver: options.profileResolver }
|
|
177
|
+
: {}),
|
|
178
|
+
// The account/credential-surface seams — same spread-when-present rule
|
|
179
|
+
// (an explicit `undefined` is not assignable under
|
|
180
|
+
// exactOptionalPropertyTypes; absent → AuthModule binds `null` → 501).
|
|
181
|
+
...(options.credentialWriter ? { credentialWriter: options.credentialWriter } : {}),
|
|
182
|
+
...(options.resetTokenStore ? { resetTokenStore: options.resetTokenStore } : {}),
|
|
183
|
+
...(options.emailSender ? { emailSender: options.emailSender } : {}),
|
|
184
|
+
...(options.recoveryCodeStore ? { recoveryCodeStore: options.recoveryCodeStore } : {}),
|
|
185
|
+
...(options.profileWriter ? { profileWriter: options.profileWriter } : {}),
|
|
186
|
+
...(options.sessionSweeper ? { sessionSweeper: options.sessionSweeper } : {}),
|
|
187
|
+
...(options.auditSink ? { auditSink: options.auditSink } : {}),
|
|
188
|
+
...(options.mfaDeviceStore ? { mfaDeviceStore: options.mfaDeviceStore } : {}),
|
|
189
|
+
...(options.totpVerifier ? { totpVerifier: options.totpVerifier } : {}),
|
|
190
|
+
...(options.rootIds ? { rootIds: options.rootIds } : {}),
|
|
191
|
+
...(options.sessionFactsProjector
|
|
192
|
+
? { sessionFactsProjector: options.sessionFactsProjector }
|
|
193
|
+
: {}),
|
|
194
|
+
})
|
|
195
|
+
: undefined;
|
|
53
196
|
return {
|
|
54
197
|
module: ShieldModule_1,
|
|
55
198
|
// Compose the framework modules — EnforcementModule holds the ONE APP_GUARD
|
|
56
199
|
// binding; BootModule holds the boot-sequence hook. No re-declaration here.
|
|
57
|
-
|
|
200
|
+
// AuthModule is OPT-IN (options.auth === true): only then does the app open a
|
|
201
|
+
// live pool/Redis + fire the fail-closed HMAC gate. Absent/false → the
|
|
202
|
+
// enforcement-only no-`.env` boot survives untouched.
|
|
203
|
+
imports: [enforcement_module_js_1.EnforcementModule, boot_module_js_1.BootModule, ...(authModule ? [authModule] : [])],
|
|
58
204
|
providers: [
|
|
59
205
|
{ provide: config_module_js_1.APP_CONFIG, useValue: config },
|
|
60
206
|
{
|
|
61
|
-
|
|
62
|
-
|
|
207
|
+
// Async factory: the `recordAuthorization` path lazy-loads the (core-touching)
|
|
208
|
+
// builder — see resolveDecisionAuthority. The legacy `decisionAuthority` +
|
|
209
|
+
// stub paths resolve synchronously but flow through the same one seam. Both
|
|
210
|
+
// supplied → throws (mutual exclusion).
|
|
211
|
+
provide: shield_tokens_js_1.SHIELD_DECISION_AUTHORITY,
|
|
212
|
+
useFactory: () => resolveDecisionAuthority({
|
|
213
|
+
...(options.recordAuthorization
|
|
214
|
+
? { recordAuthorization: options.recordAuthorization }
|
|
215
|
+
: {}),
|
|
216
|
+
...(options.decisionAuthority
|
|
217
|
+
? { decisionAuthority: options.decisionAuthority }
|
|
218
|
+
: {}),
|
|
219
|
+
}),
|
|
63
220
|
},
|
|
64
221
|
],
|
|
65
|
-
|
|
222
|
+
// Re-export the composed AuthModule app-wide ONLY when auth is opted in — its
|
|
223
|
+
// own `exports` (SHIELD_AUTHENTICATOR / SHIELD_SESSION_AUTHORITY) then become
|
|
224
|
+
// visible to a consumer's controllers/services via the @Global seam.
|
|
225
|
+
exports: [
|
|
226
|
+
config_module_js_1.APP_CONFIG,
|
|
227
|
+
shield_tokens_js_1.SHIELD_DECISION_AUTHORITY,
|
|
228
|
+
...(authModule ? [authModule] : []),
|
|
229
|
+
],
|
|
66
230
|
};
|
|
67
231
|
}
|
|
68
232
|
/**
|
|
@@ -88,16 +252,70 @@ let ShieldModule = ShieldModule_1 = class ShieldModule {
|
|
|
88
252
|
inject: [optionsToken],
|
|
89
253
|
};
|
|
90
254
|
const authorityProvider = {
|
|
91
|
-
provide:
|
|
92
|
-
|
|
255
|
+
provide: shield_tokens_js_1.SHIELD_DECISION_AUTHORITY,
|
|
256
|
+
// Same one-seam resolution as forRoot, over the async-resolved options: the
|
|
257
|
+
// `recordAuthorization` path (the app hands pool + app ports + registry — computed
|
|
258
|
+
// in its useFactory from the injected registrations) has the framework build the
|
|
259
|
+
// real wired authority; `decisionAuthority` is the legacy passthrough; both →
|
|
260
|
+
// throws; neither → stub. Async because the record path lazy-loads the builder.
|
|
261
|
+
useFactory: (opts) => resolveDecisionAuthority({
|
|
262
|
+
...(opts.recordAuthorization ? { recordAuthorization: opts.recordAuthorization } : {}),
|
|
263
|
+
...(opts.decisionAuthority ? { decisionAuthority: opts.decisionAuthority } : {}),
|
|
264
|
+
}),
|
|
93
265
|
inject: [optionsToken],
|
|
94
266
|
};
|
|
267
|
+
// Same one-instance opt-in AuthModule as forRoot (imported + re-exported).
|
|
268
|
+
// `credentialResolver` is STATIC on the async options (like `auth`) — a
|
|
269
|
+
// registration-time collaborator, threaded straight through here.
|
|
270
|
+
const authModule = options.auth
|
|
271
|
+
? auth_module_js_1.AuthModule.forRoot(
|
|
272
|
+
// Only pass a property when the consumer supplied one — under
|
|
273
|
+
// `exactOptionalPropertyTypes`, an explicit `undefined` is not assignable
|
|
274
|
+
// to an optional field; a spread keeps it truly absent so AuthModule falls
|
|
275
|
+
// back to its defaults (MariaDb credential store; 501 /auth/me).
|
|
276
|
+
{
|
|
277
|
+
...(options.credentialResolver
|
|
278
|
+
? { credentialResolver: options.credentialResolver }
|
|
279
|
+
: {}),
|
|
280
|
+
...(options.profileResolver
|
|
281
|
+
? { profileResolver: options.profileResolver }
|
|
282
|
+
: {}),
|
|
283
|
+
// The account/credential-surface seams — same spread-when-present rule
|
|
284
|
+
// (an explicit `undefined` is not assignable under
|
|
285
|
+
// exactOptionalPropertyTypes; absent → AuthModule binds `null` → 501).
|
|
286
|
+
...(options.credentialWriter ? { credentialWriter: options.credentialWriter } : {}),
|
|
287
|
+
...(options.resetTokenStore ? { resetTokenStore: options.resetTokenStore } : {}),
|
|
288
|
+
...(options.emailSender ? { emailSender: options.emailSender } : {}),
|
|
289
|
+
...(options.recoveryCodeStore ? { recoveryCodeStore: options.recoveryCodeStore } : {}),
|
|
290
|
+
...(options.profileWriter ? { profileWriter: options.profileWriter } : {}),
|
|
291
|
+
...(options.sessionSweeper ? { sessionSweeper: options.sessionSweeper } : {}),
|
|
292
|
+
...(options.auditSink ? { auditSink: options.auditSink } : {}),
|
|
293
|
+
...(options.mfaDeviceStore ? { mfaDeviceStore: options.mfaDeviceStore } : {}),
|
|
294
|
+
...(options.totpVerifier ? { totpVerifier: options.totpVerifier } : {}),
|
|
295
|
+
...(options.rootIds ? { rootIds: options.rootIds } : {}),
|
|
296
|
+
...(options.sessionFactsProjector
|
|
297
|
+
? { sessionFactsProjector: options.sessionFactsProjector }
|
|
298
|
+
: {}),
|
|
299
|
+
})
|
|
300
|
+
: undefined;
|
|
95
301
|
return {
|
|
96
302
|
module: ShieldModule_1,
|
|
97
303
|
// Same single-path composition as forRoot (+ the caller's option imports).
|
|
98
|
-
|
|
304
|
+
// AuthModule is OPT-IN via the STATIC `options.auth` flag (see the interface
|
|
305
|
+
// doc — the imports list is composed statically, so auth cannot be gated on
|
|
306
|
+
// the async-resolved options).
|
|
307
|
+
imports: [
|
|
308
|
+
enforcement_module_js_1.EnforcementModule,
|
|
309
|
+
boot_module_js_1.BootModule,
|
|
310
|
+
...(authModule ? [authModule] : []),
|
|
311
|
+
...(options.imports ?? []),
|
|
312
|
+
],
|
|
99
313
|
providers: [asyncOptionsProvider, configProvider, authorityProvider],
|
|
100
|
-
exports: [
|
|
314
|
+
exports: [
|
|
315
|
+
config_module_js_1.APP_CONFIG,
|
|
316
|
+
shield_tokens_js_1.SHIELD_DECISION_AUTHORITY,
|
|
317
|
+
...(authModule ? [authModule] : []),
|
|
318
|
+
],
|
|
101
319
|
};
|
|
102
320
|
}
|
|
103
321
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shield.module.js","sourceRoot":"","sources":["../../src/module/shield.module.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Request-principal resolution — extract the bearer access token from an HTTP
|
|
3
|
+
* request and resolve it (via the {@link SessionTokenBinder}) to a `Principal`,
|
|
4
|
+
* fail-closed. This is the request-auth read path the enforcement guard uses for
|
|
5
|
+
* `@Classified` routes before calling `decide()`.
|
|
6
|
+
*
|
|
7
|
+
* The `Principal` is rebuilt from the bound claims. We deliberately do NOT re-run
|
|
8
|
+
* the Core identity broker here (which would apply the root allowlist and could
|
|
9
|
+
* mint a root from an id) — instead we reconstruct a plain, non-root
|
|
10
|
+
* Principal from the exact claims captured at login. `isRoot` is set to
|
|
11
|
+
* `false` on the request path unless the binding explicitly recorded it (it is
|
|
12
|
+
* captured from the login-time Principal, so a genuinely-root login stays
|
|
13
|
+
* root; a normal login can never become one on a later request).
|
|
14
|
+
*/
|
|
15
|
+
import type { Principal } from '@astram/core';
|
|
16
|
+
import type { SessionTokenBinder, BoundPrincipalClaims } from './session-token-binder.js';
|
|
17
|
+
/** Extract a bearer token from an `Authorization: Bearer <token>` header. */
|
|
18
|
+
export declare function extractBearerToken(authorizationHeader: unknown): string | null;
|
|
19
|
+
/**
|
|
20
|
+
* Rebuild a `Principal` from bound claims (validated). `isRoot` is read
|
|
21
|
+
* from the binding (captured at login), NEVER inferred — a normal user cannot become
|
|
22
|
+
* a root on the request path.
|
|
23
|
+
*/
|
|
24
|
+
export declare function principalFromClaims(claims: BoundPrincipalClaims): Principal | null;
|
|
25
|
+
/**
|
|
26
|
+
* Resolve an HTTP request's bearer token to a `Principal`, or `null` (fail-closed)
|
|
27
|
+
* when there is no token, no binding, or the binding is malformed.
|
|
28
|
+
*/
|
|
29
|
+
export declare function resolveRequestPrincipal(authorizationHeader: unknown, binder: SessionTokenBinder): Promise<Principal | null>;
|
|
30
|
+
/**
|
|
31
|
+
* Resolve an HTTP request's bearer token to BOTH a `Principal` AND the raw
|
|
32
|
+
* {@link BoundPrincipalClaims}, or `null` (fail-closed) — the same read path as
|
|
33
|
+
* {@link resolveRequestPrincipal}, but it also surfaces the claims the `Principal`
|
|
34
|
+
* projection drops (notably `mustReenroll` and `sessionId`). The enforcement guard
|
|
35
|
+
* uses this so it can read `claims.mustReenroll` to apply the enforced-re-enroll gate
|
|
36
|
+
* while still attaching the resolved `Principal` for `decide()`.
|
|
37
|
+
*/
|
|
38
|
+
export declare function resolveRequestAuth(authorizationHeader: unknown, binder: SessionTokenBinder): Promise<{
|
|
39
|
+
principal: Principal;
|
|
40
|
+
claims: BoundPrincipalClaims;
|
|
41
|
+
} | null>;
|
|
42
|
+
//# sourceMappingURL=request-principal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-principal.d.ts","sourceRoot":"","sources":["../../src/request-auth/request-principal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAK1F,6EAA6E;AAC7E,wBAAgB,kBAAkB,CAAC,mBAAmB,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAK9E;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,oBAAoB,GAAG,SAAS,GAAG,IAAI,CAoBlF;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,mBAAmB,EAAE,OAAO,EAC5B,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAM3B;AAED;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CACtC,mBAAmB,EAAE,OAAO,EAC5B,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC;IAAE,SAAS,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,oBAAoB,CAAA;CAAE,GAAG,IAAI,CAAC,CAQxE"}
|