@astram/guard 0.2.0 → 0.4.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.
Files changed (120) hide show
  1. package/dist/auth/account.controller.d.ts +245 -0
  2. package/dist/auth/account.controller.d.ts.map +1 -0
  3. package/dist/auth/account.controller.js +673 -0
  4. package/dist/auth/auth.controller.d.ts +219 -5
  5. package/dist/auth/auth.controller.d.ts.map +1 -1
  6. package/dist/auth/auth.controller.js +790 -12
  7. package/dist/auth/auth.module.d.ts +101 -3
  8. package/dist/auth/auth.module.d.ts.map +1 -1
  9. package/dist/auth/auth.module.js +300 -8
  10. package/dist/auth/dto.d.ts +16 -6
  11. package/dist/auth/dto.d.ts.map +1 -1
  12. package/dist/auth/ports/audit-sink.d.ts +47 -0
  13. package/dist/auth/ports/audit-sink.d.ts.map +1 -0
  14. package/dist/auth/ports/audit-sink.js +20 -0
  15. package/dist/auth/ports/credential-writer.d.ts +23 -0
  16. package/dist/auth/ports/credential-writer.d.ts.map +1 -0
  17. package/dist/auth/ports/credential-writer.js +2 -0
  18. package/dist/auth/ports/email-sender.d.ts +14 -0
  19. package/dist/auth/ports/email-sender.d.ts.map +1 -0
  20. package/dist/auth/ports/email-sender.js +2 -0
  21. package/dist/auth/ports/mfa-device-store.d.ts +45 -0
  22. package/dist/auth/ports/mfa-device-store.d.ts.map +1 -0
  23. package/dist/auth/ports/mfa-device-store.js +13 -0
  24. package/dist/auth/ports/profile-writer.d.ts +12 -0
  25. package/dist/auth/ports/profile-writer.d.ts.map +1 -0
  26. package/dist/auth/ports/profile-writer.js +2 -0
  27. package/dist/auth/ports/recovery-code-store.d.ts +10 -0
  28. package/dist/auth/ports/recovery-code-store.d.ts.map +1 -0
  29. package/dist/auth/ports/recovery-code-store.js +2 -0
  30. package/dist/auth/ports/reset-token-store.d.ts +12 -0
  31. package/dist/auth/ports/reset-token-store.d.ts.map +1 -0
  32. package/dist/auth/ports/reset-token-store.js +2 -0
  33. package/dist/auth/ports/session-facts-projector.d.ts +44 -0
  34. package/dist/auth/ports/session-facts-projector.d.ts.map +1 -0
  35. package/dist/auth/ports/session-facts-projector.js +30 -0
  36. package/dist/auth/ports/session-sweeper.d.ts +12 -0
  37. package/dist/auth/ports/session-sweeper.d.ts.map +1 -0
  38. package/dist/auth/ports/session-sweeper.js +2 -0
  39. package/dist/auth/profile-resolver.d.ts +73 -0
  40. package/dist/auth/profile-resolver.d.ts.map +1 -0
  41. package/dist/auth/profile-resolver.js +28 -0
  42. package/dist/auth/rate-limit/attempt-limiter.d.ts +91 -0
  43. package/dist/auth/rate-limit/attempt-limiter.d.ts.map +1 -0
  44. package/dist/auth/rate-limit/attempt-limiter.js +133 -0
  45. package/dist/auth/tokens.d.ts +174 -0
  46. package/dist/auth/tokens.d.ts.map +1 -1
  47. package/dist/auth/tokens.js +190 -1
  48. package/dist/auth/totp-enrollment.d.ts +42 -0
  49. package/dist/auth/totp-enrollment.d.ts.map +1 -0
  50. package/dist/auth/totp-enrollment.js +96 -0
  51. package/dist/authentication/mariadb-credential-resolver.d.ts +38 -24
  52. package/dist/authentication/mariadb-credential-resolver.d.ts.map +1 -1
  53. package/dist/authentication/mariadb-credential-resolver.js +42 -28
  54. package/dist/authz/cross-tenant-grant-writer.d.ts +259 -0
  55. package/dist/authz/cross-tenant-grant-writer.d.ts.map +1 -0
  56. package/dist/authz/cross-tenant-grant-writer.js +397 -0
  57. package/dist/authz/manifest-operation-authority-adapter.d.ts +65 -0
  58. package/dist/authz/manifest-operation-authority-adapter.d.ts.map +1 -0
  59. package/dist/authz/manifest-operation-authority-adapter.js +108 -0
  60. package/dist/authz/mariadb-cross-tenant-grant-adapter.d.ts +90 -0
  61. package/dist/authz/mariadb-cross-tenant-grant-adapter.d.ts.map +1 -0
  62. package/dist/authz/mariadb-cross-tenant-grant-adapter.js +211 -0
  63. package/dist/authz/mariadb-record-rule-adapter.d.ts +60 -0
  64. package/dist/authz/mariadb-record-rule-adapter.d.ts.map +1 -0
  65. package/dist/authz/mariadb-record-rule-adapter.js +154 -0
  66. package/dist/authz/mariadb-record-share-adapter.d.ts +75 -0
  67. package/dist/authz/mariadb-record-share-adapter.d.ts.map +1 -0
  68. package/dist/authz/mariadb-record-share-adapter.js +106 -0
  69. package/dist/authz/record-share-cascade.d.ts +52 -0
  70. package/dist/authz/record-share-cascade.d.ts.map +1 -0
  71. package/dist/authz/record-share-cascade.js +49 -0
  72. package/dist/authz/record-share-writer.d.ts +175 -0
  73. package/dist/authz/record-share-writer.d.ts.map +1 -0
  74. package/dist/authz/record-share-writer.js +225 -0
  75. package/dist/authz/wire-record-authorization.d.ts +66 -0
  76. package/dist/authz/wire-record-authorization.d.ts.map +1 -0
  77. package/dist/authz/wire-record-authorization.js +34 -0
  78. package/dist/completeness/catalog-reconciler.d.ts +21 -0
  79. package/dist/completeness/catalog-reconciler.d.ts.map +1 -0
  80. package/dist/completeness/catalog-reconciler.js +74 -0
  81. package/dist/completeness/operation-inventory-scanner.d.ts +17 -0
  82. package/dist/completeness/operation-inventory-scanner.d.ts.map +1 -0
  83. package/dist/completeness/operation-inventory-scanner.js +79 -0
  84. package/dist/completeness/ports/catalog-store.d.ts +33 -0
  85. package/dist/completeness/ports/catalog-store.d.ts.map +1 -0
  86. package/dist/completeness/ports/catalog-store.js +2 -0
  87. package/dist/config/app-config.d.ts +18 -16
  88. package/dist/config/app-config.d.ts.map +1 -1
  89. package/dist/config/app-config.js +68 -35
  90. package/dist/enforcement/classification.decorator.d.ts +33 -14
  91. package/dist/enforcement/classification.decorator.d.ts.map +1 -1
  92. package/dist/enforcement/classification.decorator.js +34 -14
  93. package/dist/enforcement/global-enforcement.guard.d.ts +29 -19
  94. package/dist/enforcement/global-enforcement.guard.d.ts.map +1 -1
  95. package/dist/enforcement/global-enforcement.guard.js +108 -25
  96. package/dist/enforcement/reenroll-allowlist.d.ts +49 -0
  97. package/dist/enforcement/reenroll-allowlist.d.ts.map +1 -0
  98. package/dist/enforcement/reenroll-allowlist.js +77 -0
  99. package/dist/index.d.ts +35 -3
  100. package/dist/index.d.ts.map +1 -1
  101. package/dist/index.js +159 -7
  102. package/dist/module/shield-tokens.d.ts +15 -0
  103. package/dist/module/shield-tokens.d.ts.map +1 -0
  104. package/dist/module/shield-tokens.js +17 -0
  105. package/dist/module/shield.module.d.ts +154 -10
  106. package/dist/module/shield.module.d.ts.map +1 -1
  107. package/dist/module/shield.module.js +181 -24
  108. package/dist/request-auth/request-principal.d.ts +42 -0
  109. package/dist/request-auth/request-principal.d.ts.map +1 -0
  110. package/dist/request-auth/request-principal.js +87 -0
  111. package/dist/request-auth/session-facts-als.d.ts +65 -0
  112. package/dist/request-auth/session-facts-als.d.ts.map +1 -0
  113. package/dist/request-auth/session-facts-als.js +57 -0
  114. package/dist/request-auth/session-token-binder.d.ts +130 -0
  115. package/dist/request-auth/session-token-binder.d.ts.map +1 -0
  116. package/dist/request-auth/session-token-binder.js +277 -0
  117. package/dist/request-auth/tokens.d.ts +14 -0
  118. package/dist/request-auth/tokens.d.ts.map +1 -0
  119. package/dist/request-auth/tokens.js +16 -0
  120. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -16,7 +16,8 @@
16
16
  * `@nestjs/core`, `reflect-metadata`, `rxjs` so the host owns one copy of each.
17
17
  */
18
18
  Object.defineProperty(exports, "__esModule", { value: true });
19
- exports.PendingMfaStore = exports.AuthController = exports.AuthModule = exports.PersistenceModule = exports.MariaDbCredentialResolver = exports.SHIELD_SESSION_AUTHORITY = exports.SHIELD_AUTHENTICATOR = exports.SHIELD_CREDENTIAL_RESOLVER = exports.SHIELD_REDIS = exports.SHIELD_DB_POOL = exports.DEFAULT_REDIS_URL = exports.DEFAULT_DB_CONFIG = exports.assertRefreshHmacKey = exports.loadRefreshHmacKey = exports.loadSessionLifetimes = exports.loadRedisConfig = exports.loadDbConfig = exports.SCHEMA_SVC_POOL_HARD_CAP = exports.DEFAULT_POOL_BUDGET = exports.evaluatePoolBudget = exports.loadPoolBudget = exports.loadAppConfig = exports.APP_CONFIG = exports.assertPoolBudget = exports.BootSequence = exports.SHIELD_CLOCK = exports.SHIELD_REFRESH_HASHER = exports.SHIELD_TOKEN_GENERATOR = exports.systemClockProvider = exports.refreshHasherProvider = exports.cryptoTokenGeneratorProvider = exports.SystemClock = exports.Sha256RefreshTokenHasher = exports.CryptoTokenGenerator = exports.SHIELD_HOT_SESSION_STORE = exports.RedisHotSessionStore = exports.SHIELD_SESSION_RECORD_STORE = exports.MariaDbSessionRecordStore = exports.SHIELD_PASSWORD_HASHER = exports.argon2idHasherProvider = exports.Argon2idPasswordHasher = exports.stubDecisionAuthority = exports.GlobalEnforcementGuard = exports.CLASSIFICATION_METADATA = exports.Classified = exports.Public = exports.SHIELD_DECISION_AUTHORITY = exports.ShieldModule = void 0;
19
+ exports.InvalidGrantError = exports.GrantNotPermittedError = exports.SHIELD_CROSS_TENANT_GRANT_WRITER = exports.CrossTenantGrantWriter = exports.SHIELD_CROSS_TENANT_GRANT_PORT = exports.MariaDbCrossTenantGrantAdapter = exports.makeShareDeleteCascade = exports.ShareStoreUnavailableError = exports.ShareNotPermittedError = exports.SHIELD_RECORD_SHARE_WRITER = exports.RecordShareWriter = exports.SHIELD_RECORD_SHARE_PORT = exports.MariaDbRecordShareAdapter = exports.SHIELD_RECORD_RULE_PORT = exports.MariaDbRecordPermissionRuleAdapter = exports.SHIELD_CLOCK = exports.SHIELD_REFRESH_HASHER = exports.SHIELD_TOKEN_GENERATOR = exports.systemClockProvider = exports.refreshHasherProvider = exports.cryptoTokenGeneratorProvider = exports.SystemClock = exports.Sha256RefreshTokenHasher = exports.CryptoTokenGenerator = exports.SHIELD_HOT_SESSION_STORE = exports.RedisHotSessionStore = exports.SHIELD_SESSION_RECORD_STORE = exports.MariaDbSessionRecordStore = exports.SHIELD_PASSWORD_HASHER = exports.argon2idHasherProvider = exports.Argon2idPasswordHasher = exports.stubDecisionAuthority = exports.GlobalEnforcementGuard = exports.NO_SESSION_FACTS = exports.SHIELD_SESSION_FACTS_ALS = exports.extractBearerToken = exports.principalFromClaims = exports.resolveRequestPrincipal = exports.SessionTokenBinder = exports.SHIELD_SESSION_TOKEN_BINDER = exports.CatalogGatabilityError = exports.CatalogReconciler = exports.OperationInventoryScanner = exports.normalizeClassification = exports.DEFAULT_CLASSIFIED_ACTION = exports.CLASSIFICATION_METADATA = exports.Classified = exports.Public = exports.SHIELD_DECISION_AUTHORITY = exports.ShieldModule = void 0;
20
+ exports.AccountController = exports.generateRecoveryCodes = exports.buildOtpauthUri = exports.generateTotpSecret = exports.PendingMfaStore = exports.AuthController = exports.SHIELD_SESSION_FACTS_PROJECTOR = exports.hmacSha1 = exports.resolveTotpVerifier = exports.makeDefaultTotpVerifier = exports.AuthModule = exports.PersistenceModule = exports.MariaDbCredentialResolver = exports.SHIELD_TOTP_VERIFIER_OVERRIDE = exports.SHIELD_MFA_DEVICE_STORE = exports.SHIELD_AUDIT_SINK = exports.SHIELD_SESSION_SWEEPER = exports.SHIELD_PROFILE_WRITER = exports.SHIELD_RECOVERY_CODE_STORE = exports.SHIELD_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.DEFAULT_REDIS_URL = exports.DEFAULT_DB_CONFIG = exports.assertRefreshHmacKey = exports.loadRefreshHmacKey = exports.loadSessionLifetimes = exports.loadRedisConfig = exports.loadDbConfig = exports.SCHEMA_SVC_POOL_HARD_CAP = exports.DEFAULT_POOL_BUDGET = exports.evaluatePoolBudget = exports.loadPoolBudget = exports.loadAppConfig = exports.APP_CONFIG = exports.assertPoolBudget = exports.BootSequence = exports.buildRecordAuthorization = exports.SHIELD_OPERATION_AUTHORITY_PORT = exports.ManifestOperationAuthorityAdapter = exports.GrantStoreUnavailableError = void 0;
20
21
  // The single registration seam.
21
22
  var shield_module_js_1 = require("./module/shield.module.js");
22
23
  Object.defineProperty(exports, "ShieldModule", { enumerable: true, get: function () { return shield_module_js_1.ShieldModule; } });
@@ -26,6 +27,38 @@ var classification_decorator_js_1 = require("./enforcement/classification.decora
26
27
  Object.defineProperty(exports, "Public", { enumerable: true, get: function () { return classification_decorator_js_1.Public; } });
27
28
  Object.defineProperty(exports, "Classified", { enumerable: true, get: function () { return classification_decorator_js_1.Classified; } });
28
29
  Object.defineProperty(exports, "CLASSIFICATION_METADATA", { enumerable: true, get: function () { return classification_decorator_js_1.CLASSIFICATION_METADATA; } });
30
+ Object.defineProperty(exports, "DEFAULT_CLASSIFIED_ACTION", { enumerable: true, get: function () { return classification_decorator_js_1.DEFAULT_CLASSIFIED_ACTION; } });
31
+ Object.defineProperty(exports, "normalizeClassification", { enumerable: true, get: function () { return classification_decorator_js_1.normalizeClassification; } });
32
+ // Auto-catalog: boot-time route reflection + catalog reconcile (register a @Classified
33
+ // route → its permission auto-appears; route-less permissions orphaned). The consumer
34
+ // supplies the CatalogStore DB impl (ADR-0003 — guard does no DB).
35
+ var operation_inventory_scanner_js_1 = require("./completeness/operation-inventory-scanner.js");
36
+ Object.defineProperty(exports, "OperationInventoryScanner", { enumerable: true, get: function () { return operation_inventory_scanner_js_1.OperationInventoryScanner; } });
37
+ var catalog_reconciler_js_1 = require("./completeness/catalog-reconciler.js");
38
+ Object.defineProperty(exports, "CatalogReconciler", { enumerable: true, get: function () { return catalog_reconciler_js_1.CatalogReconciler; } });
39
+ Object.defineProperty(exports, "CatalogGatabilityError", { enumerable: true, get: function () { return catalog_reconciler_js_1.CatalogGatabilityError; } });
40
+ // The request-auth layer (access token → Principal → decide()). The binder token is
41
+ // exported so advanced consumers can inspect/override it; `SessionTokenBinder` +
42
+ // `resolveRequestPrincipal` are exported for testing + reuse. The guard wires these
43
+ // internally — a consumer does NOT hand-wire request auth.
44
+ var tokens_js_1 = require("./request-auth/tokens.js");
45
+ Object.defineProperty(exports, "SHIELD_SESSION_TOKEN_BINDER", { enumerable: true, get: function () { return tokens_js_1.SHIELD_SESSION_TOKEN_BINDER; } });
46
+ var session_token_binder_js_1 = require("./request-auth/session-token-binder.js");
47
+ Object.defineProperty(exports, "SessionTokenBinder", { enumerable: true, get: function () { return session_token_binder_js_1.SessionTokenBinder; } });
48
+ var request_principal_js_1 = require("./request-auth/request-principal.js");
49
+ Object.defineProperty(exports, "resolveRequestPrincipal", { enumerable: true, get: function () { return request_principal_js_1.resolveRequestPrincipal; } });
50
+ Object.defineProperty(exports, "principalFromClaims", { enumerable: true, get: function () { return request_principal_js_1.principalFromClaims; } });
51
+ Object.defineProperty(exports, "extractBearerToken", { enumerable: true, get: function () { return request_principal_js_1.extractBearerToken; } });
52
+ // The per-request session-facts hot path (ADR-0011): the SINGLE shared
53
+ // `AsyncLocalStorage` the enforcement guard ENTERS around decide() and the consumer's
54
+ // app-owned `SessionFactsReader` READS. The consumer imports THIS exact singleton to
55
+ // build an ALS-backed reader (swapping the null-facts slot in its authz wiring), so
56
+ // both sides share one instance — the guard writes THIS request's cached grants, the
57
+ // reader serves them to gate 5. `SessionFactsStore` is the store shape (mirrors core's
58
+ // SessionFactsReader 1:1); `NO_SESSION_FACTS` is the fail-closed empty store.
59
+ var session_facts_als_js_1 = require("./request-auth/session-facts-als.js");
60
+ Object.defineProperty(exports, "SHIELD_SESSION_FACTS_ALS", { enumerable: true, get: function () { return session_facts_als_js_1.SHIELD_SESSION_FACTS_ALS; } });
61
+ Object.defineProperty(exports, "NO_SESSION_FACTS", { enumerable: true, get: function () { return session_facts_als_js_1.NO_SESSION_FACTS; } });
29
62
  // The global enforcement guard (framework-owned; exported so the enforcement
30
63
  // point is inspectable/testable, not so consumers re-wire it).
31
64
  //
@@ -68,6 +101,83 @@ Object.defineProperty(exports, "systemClockProvider", { enumerable: true, get: f
68
101
  Object.defineProperty(exports, "SHIELD_TOKEN_GENERATOR", { enumerable: true, get: function () { return index_js_1.SHIELD_TOKEN_GENERATOR; } });
69
102
  Object.defineProperty(exports, "SHIELD_REFRESH_HASHER", { enumerable: true, get: function () { return index_js_1.SHIELD_REFRESH_HASHER; } });
70
103
  Object.defineProperty(exports, "SHIELD_CLOCK", { enumerable: true, get: function () { return index_js_1.SHIELD_CLOCK; } });
104
+ // The record-permit ADMIN-rule adapter (ADR-0003 / design §5.1): the concrete
105
+ // `RecordPermissionRulePort` over the `record_permission_rule` table. Reads ADMIN
106
+ // rules only; the framework-owned OWNER baseline is core's job (not a row here). An
107
+ // empty table ⇒ owner-only access (core baseline), NOT a lockout. Injected into core's
108
+ // wired decision authority by the consumer's authz wiring.
109
+ var mariadb_record_rule_adapter_js_1 = require("./authz/mariadb-record-rule-adapter.js");
110
+ Object.defineProperty(exports, "MariaDbRecordPermissionRuleAdapter", { enumerable: true, get: function () { return mariadb_record_rule_adapter_js_1.MariaDbRecordPermissionRuleAdapter; } });
111
+ Object.defineProperty(exports, "SHIELD_RECORD_RULE_PORT", { enumerable: true, get: function () { return mariadb_record_rule_adapter_js_1.SHIELD_RECORD_RULE_PORT; } });
112
+ // The per-record SHARE adapter (ADR-0003 / design §6): the concrete `RecordSharePort` over
113
+ // the `record_share` table. Answers `hasShare` (user- OR role-granted shares, exact-or-`*`
114
+ // action). No share ⇒ false; store outage ⇒ AuthorizationUnavailableError. Injected into
115
+ // core's wired decision authority by the consumer's authz wiring.
116
+ var mariadb_record_share_adapter_js_1 = require("./authz/mariadb-record-share-adapter.js");
117
+ Object.defineProperty(exports, "MariaDbRecordShareAdapter", { enumerable: true, get: function () { return mariadb_record_share_adapter_js_1.MariaDbRecordShareAdapter; } });
118
+ Object.defineProperty(exports, "SHIELD_RECORD_SHARE_PORT", { enumerable: true, get: function () { return mariadb_record_share_adapter_js_1.SHIELD_RECORD_SHARE_PORT; } });
119
+ // The WHO-MAY-SHARE write path (design §6.2, the Phase-3 invariant): share CREATION is
120
+ // framework-bounded — only the record's OWNER (fetched tenant-scoped, never trusted from
121
+ // input) may share an `owned`-type record; non-owners + grantees are rejected by
122
+ // construction. Idempotent INSERT, DELETE on unshare, best-effort audit. Exposed as a
123
+ // provider the consumer's share/unshare surface calls. The consumer supplies a
124
+ // `ShareTypeResolver` (over the engine registry) + an optional `ShareAuditSink` — keeping
125
+ // guard decoupled from `@astram/engine`.
126
+ var record_share_writer_js_1 = require("./authz/record-share-writer.js");
127
+ Object.defineProperty(exports, "RecordShareWriter", { enumerable: true, get: function () { return record_share_writer_js_1.RecordShareWriter; } });
128
+ Object.defineProperty(exports, "SHIELD_RECORD_SHARE_WRITER", { enumerable: true, get: function () { return record_share_writer_js_1.SHIELD_RECORD_SHARE_WRITER; } });
129
+ Object.defineProperty(exports, "ShareNotPermittedError", { enumerable: true, get: function () { return record_share_writer_js_1.ShareNotPermittedError; } });
130
+ Object.defineProperty(exports, "ShareStoreUnavailableError", { enumerable: true, get: function () { return record_share_writer_js_1.ShareStoreUnavailableError; } });
131
+ // The delete-cascade (design §6.2 orphan-share cleanup): builds the guard-owned
132
+ // `(typeKey, recordId, tenantId) => Promise<void>` the consumer wires into the engine's
133
+ // OPTIONAL `onRecordDeleted` hook (the engine never imports guard — ADR-0003). Removes a
134
+ // deleted record's `record_share` rows, tenant-scoped.
135
+ var record_share_cascade_js_1 = require("./authz/record-share-cascade.js");
136
+ Object.defineProperty(exports, "makeShareDeleteCascade", { enumerable: true, get: function () { return record_share_cascade_js_1.makeShareDeleteCascade; } });
137
+ // The CROSS-TENANT GRANT adapter (ADR-0009 / Phase 4): the concrete `CrossTenantGrantPort` over
138
+ // the `cross_tenant_grant` table. Answers `findActiveGrant` — the ONE active (accepted, unexpired,
139
+ // unrevoked) consented grant matching (owning tenant, type, grantee user/role, scope+record). No
140
+ // active grant ⇒ null; store outage ⇒ AuthorizationUnavailableError. Injected into core's wired
141
+ // decision authority by the consumer's authz wiring.
142
+ var mariadb_cross_tenant_grant_adapter_js_1 = require("./authz/mariadb-cross-tenant-grant-adapter.js");
143
+ Object.defineProperty(exports, "MariaDbCrossTenantGrantAdapter", { enumerable: true, get: function () { return mariadb_cross_tenant_grant_adapter_js_1.MariaDbCrossTenantGrantAdapter; } });
144
+ Object.defineProperty(exports, "SHIELD_CROSS_TENANT_GRANT_PORT", { enumerable: true, get: function () { return mariadb_cross_tenant_grant_adapter_js_1.SHIELD_CROSS_TENANT_GRANT_PORT; } });
145
+ // The WHO-MAY-GRANT lifecycle write path (ADR-0009, the Phase-4 invariant): grant offer/accept/
146
+ // revoke is framework-bounded — only an OWNING-tenant admin may OFFER (the grantee's own tenant
147
+ // can NEVER mint a grant), only a GRANTEE-tenant member may ACCEPT, EITHER side may REVOKE. Hard
148
+ // non-wildcard/non-empty action ceiling + mandatory future expiry enforced at offer. Audit on
149
+ // BOTH tenants (both tenant ids in structured fields, no raw uuid in a message). Exposed as a
150
+ // provider the consumer's grant surface calls. The consumer supplies a `GrantAuthorizeFn`
151
+ // (may this principal perform share/accept/revoke in this tenant? — resolved via the app's own
152
+ // `decide()`) + an optional `GrantAuditSink` — keeping guard decoupled from `@astram/engine` +
153
+ // the app.
154
+ var cross_tenant_grant_writer_js_1 = require("./authz/cross-tenant-grant-writer.js");
155
+ Object.defineProperty(exports, "CrossTenantGrantWriter", { enumerable: true, get: function () { return cross_tenant_grant_writer_js_1.CrossTenantGrantWriter; } });
156
+ Object.defineProperty(exports, "SHIELD_CROSS_TENANT_GRANT_WRITER", { enumerable: true, get: function () { return cross_tenant_grant_writer_js_1.SHIELD_CROSS_TENANT_GRANT_WRITER; } });
157
+ Object.defineProperty(exports, "GrantNotPermittedError", { enumerable: true, get: function () { return cross_tenant_grant_writer_js_1.GrantNotPermittedError; } });
158
+ Object.defineProperty(exports, "InvalidGrantError", { enumerable: true, get: function () { return cross_tenant_grant_writer_js_1.InvalidGrantError; } });
159
+ Object.defineProperty(exports, "GrantStoreUnavailableError", { enumerable: true, get: function () { return cross_tenant_grant_writer_js_1.GrantStoreUnavailableError; } });
160
+ // The DELEGATION / trusted-operation authority adapter (ADR-0008 / Phase 4): the concrete
161
+ // `OperationAuthorityPort` over a DECLARED operation manifest (no DB — declared metadata). Answers
162
+ // `resolveDelegatedAuthority` — a scoped, non-wildcard authority for a trusted operation's step,
163
+ // or undefined (pass-through, the common case). A malformed / wildcard declared entry is dropped
164
+ // (fail-closed ⇒ undefined). An EMPTY manifest ⇒ every lookup undefined = pass-through. Injected
165
+ // into core's wired decision authority by the consumer's authz wiring.
166
+ var manifest_operation_authority_adapter_js_1 = require("./authz/manifest-operation-authority-adapter.js");
167
+ Object.defineProperty(exports, "ManifestOperationAuthorityAdapter", { enumerable: true, get: function () { return manifest_operation_authority_adapter_js_1.ManifestOperationAuthorityAdapter; } });
168
+ Object.defineProperty(exports, "SHIELD_OPERATION_AUTHORITY_PORT", { enumerable: true, get: function () { return manifest_operation_authority_adapter_js_1.SHIELD_OPERATION_AUTHORITY_PORT; } });
169
+ // The framework-owned record-tier WIRING (design §9, Phase 5): constructs the four
170
+ // record-tier adapters over a supplied pool + manifest and returns the fully-wired core
171
+ // DecisionAuthority. `ShieldModule.forRoot({ recordAuthorization })` uses this internally
172
+ // (the preferred path — the app never touches the adapters). Exported so a consumer's
173
+ // TESTS can build the same wired authority directly from the app-owned inputs WITHOUT
174
+ // re-implementing the adapter construction (the app still cannot substitute a record
175
+ // adapter — it supplies only `RecordAuthorizationInputs`, which is re-exported from the
176
+ // ShieldModule seam above). NOTE: this value-imports `@astram/core` + the adapters;
177
+ // `ShieldModule` itself does NOT import it statically (it lazy-loads it) to keep the
178
+ // enforcement-only path core-free.
179
+ var wire_record_authorization_js_1 = require("./authz/wire-record-authorization.js");
180
+ Object.defineProperty(exports, "buildRecordAuthorization", { enumerable: true, get: function () { return wire_record_authorization_js_1.buildRecordAuthorization; } });
71
181
  // Boot infrastructure (ADR-0018 connection-pool budget assertion). `BootModule`
72
182
  // itself is NOT exported — it is composed internally by `ShieldModule.forRoot()`.
73
183
  var boot_sequence_js_1 = require("./boot/boot-sequence.js");
@@ -106,12 +216,28 @@ Object.defineProperty(exports, "DEFAULT_REDIS_URL", { enumerable: true, get: fun
106
216
  // ---------------------------------------------------------------------------
107
217
  // Shared DI provider tokens (the seams the teams bind/consume — see tokens.ts for
108
218
  // who provides/consumes each).
109
- var tokens_js_1 = require("./auth/tokens.js");
110
- Object.defineProperty(exports, "SHIELD_DB_POOL", { enumerable: true, get: function () { return tokens_js_1.SHIELD_DB_POOL; } });
111
- Object.defineProperty(exports, "SHIELD_REDIS", { enumerable: true, get: function () { return tokens_js_1.SHIELD_REDIS; } });
112
- Object.defineProperty(exports, "SHIELD_CREDENTIAL_RESOLVER", { enumerable: true, get: function () { return tokens_js_1.SHIELD_CREDENTIAL_RESOLVER; } });
113
- Object.defineProperty(exports, "SHIELD_AUTHENTICATOR", { enumerable: true, get: function () { return tokens_js_1.SHIELD_AUTHENTICATOR; } });
114
- Object.defineProperty(exports, "SHIELD_SESSION_AUTHORITY", { enumerable: true, get: function () { return tokens_js_1.SHIELD_SESSION_AUTHORITY; } });
219
+ var tokens_js_2 = require("./auth/tokens.js");
220
+ Object.defineProperty(exports, "SHIELD_DB_POOL", { enumerable: true, get: function () { return tokens_js_2.SHIELD_DB_POOL; } });
221
+ Object.defineProperty(exports, "SHIELD_REDIS", { enumerable: true, get: function () { return tokens_js_2.SHIELD_REDIS; } });
222
+ Object.defineProperty(exports, "SHIELD_CREDENTIAL_RESOLVER", { enumerable: true, get: function () { return tokens_js_2.SHIELD_CREDENTIAL_RESOLVER; } });
223
+ Object.defineProperty(exports, "SHIELD_PROFILE_RESOLVER", { enumerable: true, get: function () { return tokens_js_2.SHIELD_PROFILE_RESOLVER; } });
224
+ Object.defineProperty(exports, "SHIELD_AUTHENTICATOR", { enumerable: true, get: function () { return tokens_js_2.SHIELD_AUTHENTICATOR; } });
225
+ Object.defineProperty(exports, "SHIELD_SESSION_AUTHORITY", { enumerable: true, get: function () { return tokens_js_2.SHIELD_SESSION_AUTHORITY; } });
226
+ // Account & credential-surface seams (forgot/reset, change-password, MFA
227
+ // enrollment, profile edit) — all OPTIONAL, consumer-plugged through
228
+ // ShieldModule.forRoot. See tokens.ts for who provides/consumes each.
229
+ Object.defineProperty(exports, "SHIELD_CREDENTIAL_WRITER", { enumerable: true, get: function () { return tokens_js_2.SHIELD_CREDENTIAL_WRITER; } });
230
+ Object.defineProperty(exports, "SHIELD_RESET_TOKEN_STORE", { enumerable: true, get: function () { return tokens_js_2.SHIELD_RESET_TOKEN_STORE; } });
231
+ Object.defineProperty(exports, "SHIELD_EMAIL_SENDER", { enumerable: true, get: function () { return tokens_js_2.SHIELD_EMAIL_SENDER; } });
232
+ Object.defineProperty(exports, "SHIELD_RECOVERY_CODE_STORE", { enumerable: true, get: function () { return tokens_js_2.SHIELD_RECOVERY_CODE_STORE; } });
233
+ Object.defineProperty(exports, "SHIELD_PROFILE_WRITER", { enumerable: true, get: function () { return tokens_js_2.SHIELD_PROFILE_WRITER; } });
234
+ Object.defineProperty(exports, "SHIELD_SESSION_SWEEPER", { enumerable: true, get: function () { return tokens_js_2.SHIELD_SESSION_SWEEPER; } });
235
+ // The auth-surface audit sink seam (the first auth audit event — recovery login).
236
+ Object.defineProperty(exports, "SHIELD_AUDIT_SINK", { enumerable: true, get: function () { return tokens_js_2.SHIELD_AUDIT_SINK; } });
237
+ // The multi-device MFA store seam (multiple independent authenticator devices).
238
+ Object.defineProperty(exports, "SHIELD_MFA_DEVICE_STORE", { enumerable: true, get: function () { return tokens_js_2.SHIELD_MFA_DEVICE_STORE; } });
239
+ // The login totp-verifier OVERRIDE seam (Phase 2 — plug an OR-matching verifier).
240
+ Object.defineProperty(exports, "SHIELD_TOTP_VERIFIER_OVERRIDE", { enumerable: true, get: function () { return tokens_js_2.SHIELD_TOTP_VERIFIER_OVERRIDE; } });
115
241
  // The credential-store contract (skeleton — Team A implements the SELECT).
116
242
  var mariadb_credential_resolver_js_1 = require("./authentication/mariadb-credential-resolver.js");
117
243
  Object.defineProperty(exports, "MariaDbCredentialResolver", { enumerable: true, get: function () { return mariadb_credential_resolver_js_1.MariaDbCredentialResolver; } });
@@ -122,6 +248,19 @@ var persistence_module_js_1 = require("./auth/persistence.module.js");
122
248
  Object.defineProperty(exports, "PersistenceModule", { enumerable: true, get: function () { return persistence_module_js_1.PersistenceModule; } });
123
249
  var auth_module_js_1 = require("./auth/auth.module.js");
124
250
  Object.defineProperty(exports, "AuthModule", { enumerable: true, get: function () { return auth_module_js_1.AuthModule; } });
251
+ // Phase-2 verifier-seam helpers. `makeDefaultTotpVerifier()` builds the framework's
252
+ // DEFAULT single-secret TOTP FactorVerifier (loading the ESM-only core factory lazily,
253
+ // the CJS↔ESM invariant) so a CONSUMER can WRAP it (e.g. an OR-matching multi-device
254
+ // verifier delegates to it per device secret) WITHOUT importing `@astram/core`
255
+ // directly. `resolveTotpVerifier(override, default)` is the pure `override ?? default`
256
+ // decision the authenticator composition uses (exported for unit testing the seam).
257
+ // `hmacSha1` is the node:crypto HMAC-SHA1 primitive the core TOTP verifier needs.
258
+ var auth_module_js_2 = require("./auth/auth.module.js");
259
+ Object.defineProperty(exports, "makeDefaultTotpVerifier", { enumerable: true, get: function () { return auth_module_js_2.makeDefaultTotpVerifier; } });
260
+ Object.defineProperty(exports, "resolveTotpVerifier", { enumerable: true, get: function () { return auth_module_js_2.resolveTotpVerifier; } });
261
+ Object.defineProperty(exports, "hmacSha1", { enumerable: true, get: function () { return auth_module_js_2.hmacSha1; } });
262
+ var tokens_js_3 = require("./auth/tokens.js");
263
+ Object.defineProperty(exports, "SHIELD_SESSION_FACTS_PROJECTOR", { enumerable: true, get: function () { return tokens_js_3.SHIELD_SESSION_FACTS_PROJECTOR; } });
125
264
  // The framework-owned `/auth/*` HTTP controller (Team C) + its pending-MFA store.
126
265
  // The controller CONSUMES SHIELD_AUTHENTICATOR / SHIELD_SESSION_AUTHORITY and the
127
266
  // PendingMfaStore. It is EXPORTED so AuthModule (Team B) / the integration owner
@@ -131,3 +270,16 @@ var auth_controller_js_1 = require("./auth/auth.controller.js");
131
270
  Object.defineProperty(exports, "AuthController", { enumerable: true, get: function () { return auth_controller_js_1.AuthController; } });
132
271
  var pending_mfa_store_js_1 = require("./auth/pending-mfa-store.js");
133
272
  Object.defineProperty(exports, "PendingMfaStore", { enumerable: true, get: function () { return pending_mfa_store_js_1.PendingMfaStore; } });
273
+ // The pure TOTP-enrollment helpers (Phase 4 MFA). Re-exported for consumers/tests
274
+ // that need them; the multi-device MFA routes (Phase 3) reuse them to mint a device
275
+ // secret + provisioning URI + recovery codes. (The old in-memory
276
+ // PendingEnrollmentStore is gone — a pending device is now a row in the MfaDeviceStore.)
277
+ var totp_enrollment_js_1 = require("./auth/totp-enrollment.js");
278
+ Object.defineProperty(exports, "generateTotpSecret", { enumerable: true, get: function () { return totp_enrollment_js_1.generateTotpSecret; } });
279
+ Object.defineProperty(exports, "buildOtpauthUri", { enumerable: true, get: function () { return totp_enrollment_js_1.buildOtpauthUri; } });
280
+ Object.defineProperty(exports, "generateRecoveryCodes", { enumerable: true, get: function () { return totp_enrollment_js_1.generateRecoveryCodes; } });
281
+ // The framework-owned `/account/*` self-scoped HTTP controller — the authenticated
282
+ // user acting on THEIR OWN credential/profile (change-password today; MFA/profile
283
+ // later). Registered by AuthModule alongside AuthController under `auth: true`.
284
+ var account_controller_js_1 = require("./auth/account.controller.js");
285
+ Object.defineProperty(exports, "AccountController", { enumerable: true, get: function () { return account_controller_js_1.AccountController; } });
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Framework DI tokens that must be importable WITHOUT pulling in `ShieldModule`
3
+ * itself (which would create import cycles: `ShieldModule` → `EnforcementModule` →
4
+ * the guard → back to a token declared in `ShieldModule`). Declaring the shared
5
+ * tokens here lets both `shield.module.ts` and the enforcement guard depend on them
6
+ * with no cycle. `shield.module.ts` re-exports these for the public barrel.
7
+ */
8
+ /**
9
+ * The Core decision authority (`@astram/core`'s `DecisionAuthority`) — the single
10
+ * ADR-0001 decision entry both the global enforcement guard and the engine's
11
+ * permission-gate stage consult. Provided app-wide by `ShieldModule.forRoot()`
12
+ * (default: the deny-by-default stub; overridable via the `decisionAuthority` option).
13
+ */
14
+ export declare const SHIELD_DECISION_AUTHORITY: unique symbol;
15
+ //# sourceMappingURL=shield-tokens.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shield-tokens.d.ts","sourceRoot":"","sources":["../../src/module/shield-tokens.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,eAAsC,CAAC"}
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ /**
3
+ * Framework DI tokens that must be importable WITHOUT pulling in `ShieldModule`
4
+ * itself (which would create import cycles: `ShieldModule` → `EnforcementModule` →
5
+ * the guard → back to a token declared in `ShieldModule`). Declaring the shared
6
+ * tokens here lets both `shield.module.ts` and the enforcement guard depend on them
7
+ * with no cycle. `shield.module.ts` re-exports these for the public barrel.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.SHIELD_DECISION_AUTHORITY = void 0;
11
+ /**
12
+ * The Core decision authority (`@astram/core`'s `DecisionAuthority`) — the single
13
+ * ADR-0001 decision entry both the global enforcement guard and the engine's
14
+ * permission-gate stage consult. Provided app-wide by `ShieldModule.forRoot()`
15
+ * (default: the deny-by-default stub; overridable via the `decisionAuthority` option).
16
+ */
17
+ exports.SHIELD_DECISION_AUTHORITY = Symbol('SHIELD_DECISION_AUTHORITY');
@@ -1,15 +1,21 @@
1
1
  import { type DynamicModule } from '@nestjs/common';
2
- import type { CredentialResolver } from '@astram/core';
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';
3
14
  import type { CoreDecisionAuthority } from '../enforcement/core-seam.js';
4
15
  import { type AppConfig } from '../config/app-config.js';
5
- /**
6
- * DI token for the Core decision authority (the ADR-0001 single decision
7
- * authority) that the enforcement guard consults. The consumer supplies the real
8
- * `@astram/core` authority through {@link ShieldModule.forRoot}; when omitted the
9
- * framework binds the fail-closed {@link stubDecisionAuthority} (deny-by-default),
10
- * so a mis-wiring cannot silently open a door.
11
- */
12
- 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';
13
19
  /**
14
20
  * Options for {@link ShieldModule.forRoot}. Intentionally minimal (ADR-0023 §7 —
15
21
  * no speculative abstraction): the consumer declares Shield through this ONE seam.
@@ -22,6 +28,27 @@ export interface ShieldModuleOptions {
22
28
  * the real Core authority — the guard's call site does not change.
23
29
  */
24
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;
25
52
  /**
26
53
  * Application config (port/environment/ADR-0018 pool budget). Omit to load from
27
54
  * the environment via {@link loadAppConfig}. Supplied here so a consumer can
@@ -41,7 +68,7 @@ export interface ShieldModuleOptions {
41
68
  * `true`: imports {@link AuthModule.forRoot} (which pulls the live connections +
42
69
  * composes the authenticator + session authority + registers the four `/auth/*`
43
70
  * routes) and re-exports {@link SHIELD_AUTHENTICATOR} / {@link SHIELD_SESSION_AUTHORITY}
44
- * app-wide. An auth-enabled app fails LOUD at boot if `SHIELD_REFRESH_HMAC_KEY`
71
+ * app-wide. An auth-enabled app fails LOUD at boot if `REFRESH_HMAC_KEY`
45
72
  * is blank — auth can never compose unkeyed.
46
73
  */
47
74
  readonly auth?: boolean;
@@ -59,6 +86,68 @@ export interface ShieldModuleOptions {
59
86
  * (generic 401); throwing = fail-closed transient — exactly the default contract.
60
87
  */
61
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;
62
151
  }
63
152
  /** Async variant of {@link ShieldModuleOptions} (DI-computed config). */
64
153
  export interface ShieldModuleAsyncOptions {
@@ -87,6 +176,61 @@ export interface ShieldModuleAsyncOptions {
87
176
  * async-resolved options. Only consulted when `auth: true`.
88
177
  */
89
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;
90
234
  }
91
235
  /**
92
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;AAMnF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAKzE,OAAO,EAAiB,KAAK,SAAS,EAAE,MAAM,yBAAyB,CAAC;AASxE;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,eAAsC,CAAC;AAE7E;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;;;OAKG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,qBAAqB,CAAC;IACnD;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;IAC5B;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;CAClD;AAED,yEAAyE;AACzE,MAAM,WAAW,wBAAwB;IACvC,0EAA0E;IAC1E,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,OAAO,EAAE,CAAC;IACrC,oEAAoE;IACpE,QAAQ,CAAC,UAAU,EAAE,CACnB,GAAG,IAAI,EAAE,SAAS,OAAO,EAAE,KACxB,OAAO,CAAC,mBAAmB,CAAC,GAAG,mBAAmB,CAAC;IACxD,gDAAgD;IAChD,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,OAAO,EAAE,CAAC;IACtC;;;;;;;;;OASG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;;OAMG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;CAClD;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAEa,YAAY;IACvB,6DAA6D;IAC7D,MAAM,CAAC,OAAO,CAAC,OAAO,GAAE,mBAAwB,GAAG,aAAa;IAgDhE;;;;;;;;;OASG;IACH,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,wBAAwB,GAAG,aAAa;CAwDtE"}
1
+ {"version":3,"file":"shield.module.d.ts","sourceRoot":"","sources":["../../src/module/shield.module.ts"],"names":[],"mappings":"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"}