@astram/guard 0.17.0 → 0.19.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 (67) hide show
  1. package/dist/audit/audit-chain-sealer.d.ts +90 -0
  2. package/dist/audit/audit-chain-sealer.d.ts.map +1 -0
  3. package/dist/audit/audit-chain-sealer.js +520 -0
  4. package/dist/audit/audit-seal-config.d.ts +22 -0
  5. package/dist/audit/audit-seal-config.d.ts.map +1 -0
  6. package/dist/audit/audit-seal-config.js +35 -0
  7. package/dist/audit/audit-sealer.service.d.ts +62 -0
  8. package/dist/audit/audit-sealer.service.d.ts.map +1 -0
  9. package/dist/audit/audit-sealer.service.js +197 -0
  10. package/dist/audit/node-sha256-hash.d.ts +6 -0
  11. package/dist/audit/node-sha256-hash.d.ts.map +1 -0
  12. package/dist/audit/node-sha256-hash.js +16 -0
  13. package/dist/auth/account.controller.d.ts +3 -1
  14. package/dist/auth/account.controller.d.ts.map +1 -1
  15. package/dist/auth/account.controller.js +10 -6
  16. package/dist/auth/auth.controller.d.ts +3 -1
  17. package/dist/auth/auth.controller.d.ts.map +1 -1
  18. package/dist/auth/auth.controller.js +13 -11
  19. package/dist/auth/auth.module.d.ts +14 -2
  20. package/dist/auth/auth.module.d.ts.map +1 -1
  21. package/dist/auth/auth.module.js +54 -7
  22. package/dist/auth/confirm-email.controller.d.ts +3 -1
  23. package/dist/auth/confirm-email.controller.d.ts.map +1 -1
  24. package/dist/auth/confirm-email.controller.js +9 -5
  25. package/dist/auth/email-change-messages.d.ts +2 -0
  26. package/dist/auth/email-change-messages.d.ts.map +1 -1
  27. package/dist/auth/email-change-messages.js +2 -0
  28. package/dist/auth/password-reset-message.d.ts +7 -0
  29. package/dist/auth/password-reset-message.d.ts.map +1 -0
  30. package/dist/auth/password-reset-message.js +17 -0
  31. package/dist/auth/persistence.module.d.ts +2 -2
  32. package/dist/auth/persistence.module.d.ts.map +1 -1
  33. package/dist/auth/persistence.module.js +19 -3
  34. package/dist/auth/ports/email-sender.d.ts +7 -7
  35. package/dist/auth/ports/email-sender.d.ts.map +1 -1
  36. package/dist/auth/tokens.d.ts +14 -0
  37. package/dist/auth/tokens.d.ts.map +1 -1
  38. package/dist/auth/tokens.js +15 -1
  39. package/dist/authentication/credential-provisioner.d.ts +5 -0
  40. package/dist/authentication/credential-provisioner.d.ts.map +1 -1
  41. package/dist/authentication/mariadb-credential-provisioner.d.ts +1 -0
  42. package/dist/authentication/mariadb-credential-provisioner.d.ts.map +1 -1
  43. package/dist/authentication/mariadb-credential-provisioner.js +24 -1
  44. package/dist/config/message-config.d.ts +70 -0
  45. package/dist/config/message-config.d.ts.map +1 -0
  46. package/dist/config/message-config.js +249 -0
  47. package/dist/index.d.ts +7 -1
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +17 -3
  50. package/dist/internal.d.ts +10 -0
  51. package/dist/internal.d.ts.map +1 -1
  52. package/dist/internal.js +13 -1
  53. package/dist/messaging/deliver-email.d.ts +10 -0
  54. package/dist/messaging/deliver-email.d.ts.map +1 -0
  55. package/dist/messaging/deliver-email.js +19 -0
  56. package/dist/messaging/email-delivery.d.ts +42 -0
  57. package/dist/messaging/email-delivery.d.ts.map +1 -0
  58. package/dist/messaging/email-delivery.js +117 -0
  59. package/dist/messaging/message-dispatcher.d.ts +66 -0
  60. package/dist/messaging/message-dispatcher.d.ts.map +1 -0
  61. package/dist/messaging/message-dispatcher.js +133 -0
  62. package/dist/messaging/recipient-mask.d.ts +7 -0
  63. package/dist/messaging/recipient-mask.d.ts.map +1 -0
  64. package/dist/messaging/recipient-mask.js +15 -0
  65. package/dist/module/shield.module.d.ts +5 -3
  66. package/dist/module/shield.module.d.ts.map +1 -1
  67. package/package.json +15 -5
@@ -104,7 +104,7 @@ var __importStar = (this && this.__importStar) || (function () {
104
104
  })();
105
105
  var AuthModule_1;
106
106
  Object.defineProperty(exports, "__esModule", { value: true });
107
- exports.AuthModule = exports.singleLayoutProbeProvider = exports.SHIELD_SINGLE_LAYOUT_PROBE = exports.hmacSha1 = void 0;
107
+ exports.AuthModule = exports.attemptLimiterFactoryProvider = exports.singleLayoutProbeProvider = exports.SHIELD_SINGLE_LAYOUT_PROBE = exports.hmacSha1 = void 0;
108
108
  exports.resolveTotpVerifier = resolveTotpVerifier;
109
109
  exports.makeDefaultTotpVerifier = makeDefaultTotpVerifier;
110
110
  exports.resolveDefaultEmailSender = resolveDefaultEmailSender;
@@ -145,6 +145,8 @@ const permission_version_cache_js_1 = require("../authz/permission-version-cache
145
145
  const session_restriction_store_js_1 = require("../session/session-restriction-store.js");
146
146
  const attempt_limiter_js_1 = require("./rate-limit/attempt-limiter.js");
147
147
  const trust_proxy_check_js_1 = require("./rate-limit/trust-proxy-check.js");
148
+ const email_delivery_js_1 = require("../messaging/email-delivery.js");
149
+ const message_dispatcher_js_1 = require("../messaging/message-dispatcher.js");
148
150
  const tokens_js_2 = require("../request-auth/tokens.js");
149
151
  const mariadb_api_key_store_js_1 = require("../authentication/mariadb-api-key-store.js");
150
152
  const core_1 = require("@astram/core");
@@ -741,10 +743,11 @@ const emailAddressChangerProvider = {
741
743
  useFactory: (pool, config) => new mariadb_email_address_changer_js_1.MariaDbEmailAddressChanger(pool, undefined, (0, app_config_js_1.frameworkSchemasOf)(config)),
742
744
  inject: [tokens_js_1.SHIELD_DB_POOL, config_module_js_1.APP_CONFIG],
743
745
  };
744
- /**
745
- * The per-account email-change REQUEST limiter (Phase 12) — `email-change:pid:<id>`, 3 per 60-min
746
- * window, so the route cannot spam an inbox. `consume` fails closed (503).
747
- */
746
+ exports.attemptLimiterFactoryProvider = {
747
+ provide: tokens_js_1.SHIELD_ATTEMPT_LIMITER_FACTORY,
748
+ useFactory: (redis) => (cfg) => new attempt_limiter_js_1.AttemptLimiter(redis, cfg),
749
+ inject: [tokens_js_1.SHIELD_REDIS],
750
+ };
748
751
  const emailChangeLimiterProvider = {
749
752
  provide: tokens_js_1.SHIELD_EMAIL_CHANGE_LIMITER,
750
753
  useFactory: (redis) => new attempt_limiter_js_1.AttemptLimiter(redis, { maxAttempts: 3, windowMs: 60 * 60 * 1000 }),
@@ -818,6 +821,44 @@ function resolveDefaultEmailSender(rawNodeEnv) {
818
821
  'to stdout, reset links included. Never run like this in production — supply an emailSender.');
819
822
  return new log_email_sender_js_1.LogEmailSender();
820
823
  }
824
+ /**
825
+ * The email delivery chain (G-010): `SHIELD_EMAIL_DELIVERY` (the bound provider and its per-send
826
+ * bound), `SHIELD_EMAIL_SENDER` (the port existing injectors know) and `SHIELD_MESSAGE_DISPATCHER`
827
+ * (bounded, audited, never throws). For `'env'` the sender is derived from the adapter; otherwise
828
+ * the sender binds exactly as before (AC-11) and the provider wraps it.
829
+ */
830
+ function makeEmailDeliveryProviders(option) {
831
+ const dispatcher = {
832
+ provide: tokens_js_1.SHIELD_MESSAGE_DISPATCHER,
833
+ useFactory: (delivery, pool, config) => new message_dispatcher_js_1.GuardMessageDispatcher(delivery.provider, (0, email_delivery_js_1.messageAuditWriter)(pool, (0, app_config_js_1.frameworkSchemasOf)(config)), { timeoutMs: delivery.timeoutMs }),
834
+ inject: [tokens_js_1.SHIELD_EMAIL_DELIVERY, tokens_js_1.SHIELD_DB_POOL, config_module_js_1.APP_CONFIG],
835
+ };
836
+ if (option === 'env') {
837
+ return [
838
+ {
839
+ provide: tokens_js_1.SHIELD_EMAIL_DELIVERY,
840
+ useFactory: () => (0, email_delivery_js_1.buildEmailProvider)('env', null, {}),
841
+ },
842
+ {
843
+ provide: tokens_js_1.SHIELD_EMAIL_SENDER,
844
+ useFactory: (delivery) => delivery.provider
845
+ ? (0, email_delivery_js_1.senderFromProvider)(delivery.provider, delivery.timeoutMs)
846
+ : new noop_email_sender_js_1.NoopEmailSender(),
847
+ inject: [tokens_js_1.SHIELD_EMAIL_DELIVERY],
848
+ },
849
+ dispatcher,
850
+ ];
851
+ }
852
+ return [
853
+ makeEmailSenderProvider(option),
854
+ {
855
+ provide: tokens_js_1.SHIELD_EMAIL_DELIVERY,
856
+ useFactory: (sender) => (0, email_delivery_js_1.buildEmailProvider)(option, sender, {}),
857
+ inject: [tokens_js_1.SHIELD_EMAIL_SENDER],
858
+ },
859
+ dispatcher,
860
+ ];
861
+ }
821
862
  function makeRecoveryCodeStoreProvider(override) {
822
863
  return override
823
864
  ? { provide: tokens_js_1.SHIELD_RECOVERY_CODE_STORE, useValue: override }
@@ -930,7 +971,8 @@ let AuthModule = AuthModule_1 = class AuthModule {
930
971
  // The link-base boot rule (Phase 13 #1) applies only with a real sender: `'disabled'` delivers
931
972
  // nothing, and an omitted sender outside development/test already fails the boot through
932
973
  // `resolveDefaultEmailSender` (that clearer error is kept; in development/test the rule is off).
933
- const mailDisabled = options.emailSender === undefined || options.emailSender === 'disabled';
974
+ // G-010: `'env'` is a real sender unless `EMAIL_PROVIDER=disabled` (read after resolveBootSecrets).
975
+ const mailDisabled = (0, email_delivery_js_1.isMailDisabled)(options.emailSender, process.env);
934
976
  return {
935
977
  module: AuthModule_1,
936
978
  imports: [persistence_module_js_1.PersistenceModule.forRoot()],
@@ -954,8 +996,9 @@ let AuthModule = AuthModule_1 = class AuthModule {
954
996
  emailAddressChangerProvider,
955
997
  emailChangeLimiterProvider,
956
998
  confirmEmailLimiterProvider,
999
+ exports.attemptLimiterFactoryProvider,
957
1000
  makeEmailChangeLinkBaseUrlProvider(options.emailChangeLinkBaseUrl, mailDisabled),
958
- makeEmailSenderProvider(options.emailSender),
1001
+ ...makeEmailDeliveryProviders(options.emailSender),
959
1002
  makeRecoveryCodeStoreProvider(options.recoveryCodeStore),
960
1003
  makeProfileWriterProvider(options.profileWriter),
961
1004
  makeSessionSweeperProvider(options.sessionSweeper),
@@ -1065,6 +1108,10 @@ let AuthModule = AuthModule_1 = class AuthModule {
1065
1108
  // Phase 12: identity's admin email change invalidates pending self-service tokens.
1066
1109
  tokens_js_1.SHIELD_EMAIL_CHANGE_TOKEN_STORE,
1067
1110
  tokens_js_1.SHIELD_EMAIL_SENDER,
1111
+ // G-010: the one exit for framework messages (identity's invite injects it).
1112
+ tokens_js_1.SHIELD_MESSAGE_DISPATCHER,
1113
+ // G-010: identity's invite rate limits (a limiter factory, never the raw Redis client).
1114
+ tokens_js_1.SHIELD_ATTEMPT_LIMITER_FACTORY,
1068
1115
  tokens_js_1.SHIELD_RECOVERY_CODE_STORE,
1069
1116
  tokens_js_1.SHIELD_PROFILE_WRITER,
1070
1117
  tokens_js_1.SHIELD_SESSION_SWEEPER,
@@ -2,6 +2,7 @@ import type { AttemptLimiter } from './rate-limit/attempt-limiter.js';
2
2
  import { TrustProxyBootCheck } from './rate-limit/trust-proxy-check.js';
3
3
  import type { AuditSink } from './ports/audit-sink.js';
4
4
  import type { EmailSender } from './ports/email-sender.js';
5
+ import type { MessageDispatcher } from '../messaging/message-dispatcher.js';
5
6
  import type { EmailChangeTokenStore } from './ports/email-change-token-store.js';
6
7
  import type { EmailAddressChanger } from './ports/email-address-changer.js';
7
8
  import type { ResetTokenStore } from './ports/reset-token-store.js';
@@ -15,7 +16,8 @@ export declare class ConfirmEmailController {
15
16
  private readonly auditSink?;
16
17
  private readonly limiter?;
17
18
  private readonly trustProxyCheck?;
18
- constructor(tokens?: (EmailChangeTokenStore | null) | undefined, addresses?: (EmailAddressChanger | null) | undefined, sweeper?: (SessionSweeper | null) | undefined, resetTokens?: (ResetTokenStore | null) | undefined, emailSender?: (EmailSender | null) | undefined, auditSink?: (AuditSink | null) | undefined, limiter?: (AttemptLimiter | null) | undefined, trustProxyCheck?: (Pick<TrustProxyBootCheck, "perIpLimitingEnabled"> | null) | undefined);
19
+ private readonly messageDispatcher?;
20
+ constructor(tokens?: (EmailChangeTokenStore | null) | undefined, addresses?: (EmailAddressChanger | null) | undefined, sweeper?: (SessionSweeper | null) | undefined, resetTokens?: (ResetTokenStore | null) | undefined, emailSender?: (EmailSender | null) | undefined, auditSink?: (AuditSink | null) | undefined, limiter?: (AttemptLimiter | null) | undefined, trustProxyCheck?: (Pick<TrustProxyBootCheck, "perIpLimitingEnabled"> | null) | undefined, messageDispatcher?: (MessageDispatcher | null) | undefined);
19
21
  confirmEmail(body: {
20
22
  token?: unknown;
21
23
  }, ip: string): Promise<{
@@ -1 +1 @@
1
- {"version":3,"file":"confirm-email.controller.d.ts","sourceRoot":"","sources":["../../src/auth/confirm-email.controller.ts"],"names":[],"mappings":"AA2CA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,KAAK,EAEV,qBAAqB,EACtB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,KAAK,EAAE,mBAAmB,EAAsB,MAAM,kCAAkC,CAAC;AAChG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAcjE,qBACa,sBAAsB;IAI/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IAGxB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;IAG3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;IAGzB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;IAG7B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;IAG7B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;IAG3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;IAGzB,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC;gBArBhB,MAAM,CAAC,GAAE,qBAAqB,GAAG,IAAI,aAAA,EAGrC,SAAS,CAAC,GAAE,mBAAmB,GAAG,IAAI,aAAA,EAGtC,OAAO,CAAC,GAAE,cAAc,GAAG,IAAI,aAAA,EAG/B,WAAW,CAAC,GAAE,eAAe,GAAG,IAAI,aAAA,EAGpC,WAAW,CAAC,GAAE,WAAW,GAAG,IAAI,aAAA,EAGhC,SAAS,CAAC,GAAE,SAAS,GAAG,IAAI,aAAA,EAG5B,OAAO,CAAC,GAAE,cAAc,GAAG,IAAI,aAAA,EAG/B,eAAe,CAAC,GAAE,IAAI,CAAC,mBAAmB,EAAE,sBAAsB,CAAC,GAAG,IAAI,aAAA;IAMvF,YAAY,CACR,IAAI,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,EAE3B,EAAE,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,EAAE,EAAE,IAAI,CAAA;KAAE,CAAC;IA6ExB;;;;;;OAMG;IACH,OAAO,CAAC,KAAK;CAkBd"}
1
+ {"version":3,"file":"confirm-email.controller.d.ts","sourceRoot":"","sources":["../../src/auth/confirm-email.controller.ts"],"names":[],"mappings":"AA4CA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AAC5E,OAAO,KAAK,EAEV,qBAAqB,EACtB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,KAAK,EAAE,mBAAmB,EAAsB,MAAM,kCAAkC,CAAC;AAChG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAcjE,qBACa,sBAAsB;IAI/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IAGxB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;IAG3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;IAGzB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;IAG7B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;IAG7B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;IAG3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;IAGzB,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC;IAKjC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC;gBA1BlB,MAAM,CAAC,GAAE,qBAAqB,GAAG,IAAI,aAAA,EAGrC,SAAS,CAAC,GAAE,mBAAmB,GAAG,IAAI,aAAA,EAGtC,OAAO,CAAC,GAAE,cAAc,GAAG,IAAI,aAAA,EAG/B,WAAW,CAAC,GAAE,eAAe,GAAG,IAAI,aAAA,EAGpC,WAAW,CAAC,GAAE,WAAW,GAAG,IAAI,aAAA,EAGhC,SAAS,CAAC,GAAE,SAAS,GAAG,IAAI,aAAA,EAG5B,OAAO,CAAC,GAAE,cAAc,GAAG,IAAI,aAAA,EAG/B,eAAe,CAAC,GAAE,IAAI,CAAC,mBAAmB,EAAE,sBAAsB,CAAC,GAAG,IAAI,aAAA,EAK1E,iBAAiB,CAAC,GAAE,iBAAiB,GAAG,IAAI,aAAA;IAMzD,YAAY,CACR,IAAI,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,EAE3B,EAAE,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,EAAE,EAAE,IAAI,CAAA;KAAE,CAAC;IAkFxB;;;;;;OAMG;IACH,OAAO,CAAC,KAAK;CAkBd"}
@@ -39,6 +39,7 @@ const node_crypto_1 = require("node:crypto");
39
39
  const classification_decorator_js_1 = require("../enforcement/classification.decorator.js");
40
40
  const tokens_js_1 = require("./tokens.js");
41
41
  const trust_proxy_check_js_1 = require("./rate-limit/trust-proxy-check.js");
42
+ const deliver_email_js_1 = require("../messaging/deliver-email.js");
42
43
  const email_address_js_1 = require("./email-address.js");
43
44
  const email_change_messages_js_1 = require("./email-change-messages.js");
44
45
  function fail(status, error) {
@@ -59,7 +60,8 @@ let ConfirmEmailController = class ConfirmEmailController {
59
60
  auditSink;
60
61
  limiter;
61
62
  trustProxyCheck;
62
- constructor(tokens, addresses, sweeper, resetTokens, emailSender, auditSink, limiter, trustProxyCheck) {
63
+ messageDispatcher;
64
+ constructor(tokens, addresses, sweeper, resetTokens, emailSender, auditSink, limiter, trustProxyCheck, messageDispatcher) {
63
65
  this.tokens = tokens;
64
66
  this.addresses = addresses;
65
67
  this.sweeper = sweeper;
@@ -68,6 +70,7 @@ let ConfirmEmailController = class ConfirmEmailController {
68
70
  this.auditSink = auditSink;
69
71
  this.limiter = limiter;
70
72
  this.trustProxyCheck = trustProxyCheck;
73
+ this.messageDispatcher = messageDispatcher;
71
74
  }
72
75
  async confirmEmail(body, ip) {
73
76
  const tokens = this.tokens;
@@ -138,9 +141,8 @@ let ConfirmEmailController = class ConfirmEmailController {
138
141
  });
139
142
  }
140
143
  if (outcome.oldEmail !== null && outcome.oldEmail !== '' && this.emailSender != null) {
141
- await this.emailSender
142
- .send((0, email_change_messages_js_1.emailChangedNoticeMessage)(outcome.oldEmail, maskedNew, Date.now()))
143
- .catch(() => undefined); // best-effort: the change is committed
144
+ // Best-effort (the change is committed); G-010: bounded and audited (`security_notice`).
145
+ await (0, deliver_email_js_1.deliverEmail)(this.messageDispatcher, this.emailSender, 'security_notice', (0, email_change_messages_js_1.emailChangedNoticeMessage)(outcome.oldEmail, maskedNew, Date.now()), { actorId: binding.principalId, tenantId: binding.tenantId });
144
146
  }
145
147
  this.audit(binding, 'account.email_changed', {
146
148
  newEmail: maskedNew,
@@ -201,5 +203,7 @@ exports.ConfirmEmailController = ConfirmEmailController = __decorate([
201
203
  __param(6, (0, common_1.Inject)(tokens_js_1.SHIELD_CONFIRM_EMAIL_LIMITER)),
202
204
  __param(7, (0, common_1.Optional)()),
203
205
  __param(7, (0, common_1.Inject)(trust_proxy_check_js_1.TrustProxyBootCheck)),
204
- __metadata("design:paramtypes", [Object, Object, Object, Object, Object, Object, Object, Object])
206
+ __param(8, (0, common_1.Optional)()),
207
+ __param(8, (0, common_1.Inject)(tokens_js_1.SHIELD_MESSAGE_DISPATCHER)),
208
+ __metadata("design:paramtypes", [Object, Object, Object, Object, Object, Object, Object, Object, Object])
205
209
  ], ConfirmEmailController);
@@ -19,6 +19,8 @@ export declare const DEFAULT_EMAIL_CHANGE_LINK_BASE_URL = "http://localhost:5173
19
19
  * first, and the reset advice is qualified rather than given as the remedy.
20
20
  */
21
21
  export declare const NOT_YOU_SENTENCE: string;
22
+ /** Escape a value for HTML text or a DOUBLE-quoted attribute (shared by framework messages). */
23
+ export declare function escapeHtml(value: string): string;
22
24
  /** The confirm link: the token rides in the fragment, never the query (A4). */
23
25
  export declare function emailChangeLink(base: string, rawToken: string): string;
24
26
  export declare function confirmEmailChangeMessage(to: string, link: string): EmailMessage;
@@ -1 +1 @@
1
- {"version":3,"file":"email-change-messages.d.ts","sourceRoot":"","sources":["../../src/auth/email-change-messages.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAE5D,8EAA8E;AAC9E,eAAO,MAAM,mBAAmB,QAAiB,CAAC;AAElD,sFAAsF;AACtF,eAAO,MAAM,kCAAkC,wCAAwC,CAAC;AAExF;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,QAE8C,CAAC;AAU5E,+EAA+E;AAC/E,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEtE;AAED,wBAAgB,yBAAyB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,YAAY,CAehF;AAED,wBAAgB,yBAAyB,CACvC,EAAE,EAAE,MAAM,EACV,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE,MAAM,GACX,YAAY,CAYd"}
1
+ {"version":3,"file":"email-change-messages.d.ts","sourceRoot":"","sources":["../../src/auth/email-change-messages.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAE5D,8EAA8E;AAC9E,eAAO,MAAM,mBAAmB,QAAiB,CAAC;AAElD,sFAAsF;AACtF,eAAO,MAAM,kCAAkC,wCAAwC,CAAC;AAExF;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,QAE8C,CAAC;AAE5E,gGAAgG;AAChG,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMhD;AAED,+EAA+E;AAC/E,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEtE;AAED,wBAAgB,yBAAyB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,YAAY,CAehF;AAED,wBAAgB,yBAAyB,CACvC,EAAE,EAAE,MAAM,EACV,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE,MAAM,GACX,YAAY,CAYd"}
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.NOT_YOU_SENTENCE = exports.DEFAULT_EMAIL_CHANGE_LINK_BASE_URL = exports.EMAIL_CHANGE_TTL_MS = void 0;
4
+ exports.escapeHtml = escapeHtml;
4
5
  exports.emailChangeLink = emailChangeLink;
5
6
  exports.confirmEmailChangeMessage = confirmEmailChangeMessage;
6
7
  exports.emailChangedNoticeMessage = emailChangedNoticeMessage;
@@ -16,6 +17,7 @@ exports.DEFAULT_EMAIL_CHANGE_LINK_BASE_URL = 'http://localhost:5173/confirm-emai
16
17
  */
17
18
  exports.NOT_YOU_SENTENCE = "If this wasn't you, contact your administrator immediately. Your sign-in email may have " +
18
19
  'changed too, so a password reset from the login page may not reach you.';
20
+ /** Escape a value for HTML text or a DOUBLE-quoted attribute (shared by framework messages). */
19
21
  function escapeHtml(value) {
20
22
  return value
21
23
  .replace(/&/g, '&amp;')
@@ -0,0 +1,7 @@
1
+ import type { EmailMessage } from './ports/email-sender.js';
2
+ /**
3
+ * The forgot-password email (G-010 R9: the link is HTML-escaped; before G-010 it was interpolated
4
+ * raw). The text part carries the plain link.
5
+ */
6
+ export declare function passwordResetMessage(to: string, link: string): EmailMessage;
7
+ //# sourceMappingURL=password-reset-message.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"password-reset-message.d.ts","sourceRoot":"","sources":["../../src/auth/password-reset-message.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAG5D;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,YAAY,CAQ3E"}
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.passwordResetMessage = passwordResetMessage;
4
+ const email_change_messages_js_1 = require("./email-change-messages.js");
5
+ /**
6
+ * The forgot-password email (G-010 R9: the link is HTML-escaped; before G-010 it was interpolated
7
+ * raw). The text part carries the plain link.
8
+ */
9
+ function passwordResetMessage(to, link) {
10
+ const safe = (0, email_change_messages_js_1.escapeHtml)(link);
11
+ return {
12
+ to,
13
+ subject: 'Reset your password',
14
+ text: `Reset your password: ${link}`,
15
+ html: `<p>Reset your password: <a href="${safe}">${safe}</a></p>`,
16
+ };
17
+ }
@@ -33,8 +33,8 @@
33
33
  import { type DynamicModule } from '@nestjs/common';
34
34
  /**
35
35
  * The persistence module. `forRoot()` returns the two connection providers (both
36
- * exported so AuthModule can inject them) plus the shutdown holder. Opt-in: only
37
- * imported when auth is wired.
36
+ * exported so AuthModule can inject them), the shutdown holder and the audit sealer.
37
+ * Opt-in: only imported when auth is wired.
38
38
  */
39
39
  export declare class PersistenceModule {
40
40
  static forRoot(): DynamicModule;
@@ -1 +1 @@
1
- {"version":3,"file":"persistence.module.d.ts","sourceRoot":"","sources":["../../src/auth/persistence.module.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,EAAU,KAAK,aAAa,EAAiB,MAAM,gBAAgB,CAAC;AA0C3E;;;;GAIG;AACH,qBACa,iBAAiB;IAC5B,MAAM,CAAC,OAAO,IAAI,aAAa;CAOhC"}
1
+ {"version":3,"file":"persistence.module.d.ts","sourceRoot":"","sources":["../../src/auth/persistence.module.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,EAAU,KAAK,aAAa,EAAiB,MAAM,gBAAgB,CAAC;AA2D3E;;;;GAIG;AACH,qBACa,iBAAiB;IAC5B,MAAM,CAAC,OAAO,IAAI,aAAa;CAOhC"}
@@ -41,7 +41,10 @@ var PersistenceModule_1;
41
41
  Object.defineProperty(exports, "__esModule", { value: true });
42
42
  exports.PersistenceModule = void 0;
43
43
  const common_1 = require("@nestjs/common");
44
+ const app_config_js_1 = require("../config/app-config.js");
44
45
  const config_module_js_1 = require("../config/config.module.js");
46
+ const audit_sealer_service_js_1 = require("../audit/audit-sealer.service.js");
47
+ const audit_seal_config_js_1 = require("../audit/audit-seal-config.js");
45
48
  const tokens_js_1 = require("./tokens.js");
46
49
  const connections_js_1 = require("./connections.js");
47
50
  /**
@@ -74,16 +77,29 @@ const lifecycleProvider = {
74
77
  useFactory: (pool, redis) => new connections_js_1.ConnectionLifecycle(pool, redis),
75
78
  inject: [tokens_js_1.SHIELD_DB_POOL, tokens_js_1.SHIELD_REDIS],
76
79
  };
80
+ /**
81
+ * The deferred audit sealer (audit-chain-store SPEC §5.H): registered here so it exists
82
+ * exactly when {@link SHIELD_DB_POOL} does. `AUDIT_SEAL_*` is read now, so an invalid value
83
+ * fails the boot (SPEC §13). It ticks only once its table probe finds `audit_log` and
84
+ * `audit_chain`; a stub or unreachable pool leaves it idle (never a boot failure).
85
+ */
86
+ const auditSealerProvider = {
87
+ provide: audit_sealer_service_js_1.AuditSealerService,
88
+ useFactory: (pool, config) => new audit_sealer_service_js_1.AuditSealerService(pool, (0, app_config_js_1.frameworkSchemasOf)(config), {
89
+ config: (0, audit_seal_config_js_1.loadAuditSealConfig)(process.env),
90
+ }),
91
+ inject: [tokens_js_1.SHIELD_DB_POOL, config_module_js_1.APP_CONFIG],
92
+ };
77
93
  /**
78
94
  * The persistence module. `forRoot()` returns the two connection providers (both
79
- * exported so AuthModule can inject them) plus the shutdown holder. Opt-in: only
80
- * imported when auth is wired.
95
+ * exported so AuthModule can inject them), the shutdown holder and the audit sealer.
96
+ * Opt-in: only imported when auth is wired.
81
97
  */
82
98
  let PersistenceModule = PersistenceModule_1 = class PersistenceModule {
83
99
  static forRoot() {
84
100
  return {
85
101
  module: PersistenceModule_1,
86
- providers: [dbPoolProvider, redisProvider, lifecycleProvider],
102
+ providers: [dbPoolProvider, redisProvider, lifecycleProvider, auditSealerProvider],
87
103
  exports: [tokens_js_1.SHIELD_DB_POOL, tokens_js_1.SHIELD_REDIS],
88
104
  };
89
105
  }
@@ -1,13 +1,13 @@
1
1
  /**
2
2
  * EmailSender — the delivery seam. The framework builds the message; the consumer
3
- * delivers it (SendGrid, SMTP, or a test capturer). Consumer-plugged.
3
+ * delivers it (SendGrid, SMTP, or a test capturer). Consumer-plugged, or chosen by
4
+ * configuration with `ShieldModule.forRoot({ emailSender: 'env' })` (G-010).
5
+ *
6
+ * `EmailMessage` is core's channel type (G-010 R1); the name and shape are unchanged, so an app's
7
+ * existing sender keeps working.
4
8
  */
5
- export interface EmailMessage {
6
- readonly to: string;
7
- readonly subject: string;
8
- readonly html: string;
9
- readonly text: string;
10
- }
9
+ import type { EmailMessage } from '@astram/core';
10
+ export type { EmailMessage };
11
11
  export interface EmailSender {
12
12
  send(message: EmailMessage): Promise<void>;
13
13
  }
@@ -1 +1 @@
1
- {"version":3,"file":"email-sender.d.ts","sourceRoot":"","sources":["../../../src/auth/ports/email-sender.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AACD,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5C"}
1
+ {"version":3,"file":"email-sender.d.ts","sourceRoot":"","sources":["../../../src/auth/ports/email-sender.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,YAAY,EAAE,YAAY,EAAE,CAAC;AAE7B,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5C"}
@@ -131,6 +131,20 @@ export declare const SHIELD_CONFIRM_EMAIL_LIMITER: unique symbol;
131
131
  * consumer delivers it. Consumed by forgot-password.
132
132
  */
133
133
  export declare const SHIELD_EMAIL_SENDER: unique symbol;
134
+ /**
135
+ * The {@link MessageDispatcher} (G-010, `../messaging/message-dispatcher.ts`): the one exit for
136
+ * framework messages. Bounds, audits (`message.sent` / `message.failed`) and never throws. Every
137
+ * framework send uses it; `@astram/identity`'s invite injects it too.
138
+ */
139
+ export declare const SHIELD_MESSAGE_DISPATCHER: unique symbol;
140
+ /**
141
+ * A factory for guard's Redis-backed `AttemptLimiter` (G-010 P-5): `(cfg) => AttemptLimiter`. For
142
+ * `@astram/identity`'s invite rate limits; exported from `AuthModule` and `@astram/guard/internal`
143
+ * so identity builds limiters without ever holding the raw Redis client.
144
+ */
145
+ export declare const SHIELD_ATTEMPT_LIMITER_FACTORY: unique symbol;
146
+ /** Internal: the bound email provider and its per-send bound (`EmailDelivery`). Not exported. */
147
+ export declare const SHIELD_EMAIL_DELIVERY: unique symbol;
134
148
  /**
135
149
  * The `RecoveryCodeStore` (guard port, `../auth/ports/recovery-code-store.ts`) —
136
150
  * persists Argon2-hashed one-time MFA recovery codes. Consumed by MFA enrollment.
@@ -1 +1 @@
1
- {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../src/auth/tokens.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../src/auth/tokens.ts"],"names":[],"mappings":"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"}
@@ -23,7 +23,7 @@
23
23
  * ADR-0003: no framework/DB/crypto imports here — just Symbols (+ one re-export).
24
24
  */
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.SHIELD_SESSION_RESTRICTIONS = exports.SHIELD_PERMISSION_VERSION_CACHE = exports.SHIELD_PERMISSION_FACTS = exports.SHIELD_RESET_LIMITER = exports.SHIELD_FORGOT_HINT_LIMITER = exports.SHIELD_FORGOT_LIMITER = exports.SHIELD_LOGIN_TOTP_VERIFIER = exports.SHIELD_MFA_STEP_UP = exports.SHIELD_MFA_LIMITER = exports.SHIELD_RECOVERY_LIMITER = exports.SHIELD_LOGIN_IP_LIMITER = exports.SHIELD_LOGIN_LIMITER = exports.SHIELD_MEMBERSHIP_CHECKER = exports.SHIELD_SCOPE_SUBTREE_RESOLVER = exports.SHIELD_SESSION_FACTS_PROJECTOR = exports.SHIELD_ROOT_IDS = exports.SHIELD_TOTP_VERIFIER_OVERRIDE = exports.SHIELD_TOTP_VERIFIER = exports.SHIELD_RESET_LINK_BASE_URL = exports.SHIELD_SESSION_SWEEPER = exports.SHIELD_MFA_DEVICE_STORE = exports.SHIELD_AUDIT_SINK = exports.SHIELD_PROFILE_WRITER = exports.SHIELD_RECOVERY_CODE_STORE = exports.SHIELD_EMAIL_SENDER = exports.SHIELD_CONFIRM_EMAIL_LIMITER = exports.SHIELD_EMAIL_CHANGE_LIMITER = exports.SHIELD_EMAIL_CHANGE_LINK_BASE_URL = exports.SHIELD_EMAIL_ADDRESS_CHANGER = exports.SHIELD_EMAIL_CHANGE_TOKEN_STORE = exports.SHIELD_RESET_TOKEN_STORE = exports.SHIELD_CREDENTIAL_WRITER = exports.SHIELD_RECENT_ROTATION_STORE = exports.SHIELD_SESSION_AUTHORITY = exports.SHIELD_AUTHENTICATOR = exports.SHIELD_PROFILE_RESOLVER = exports.SHIELD_CREDENTIAL_RESOLVER = exports.SHIELD_REDIS = exports.SHIELD_DB_POOL = exports.SHIELD_PASSWORD_HASHER = void 0;
26
+ exports.SHIELD_SESSION_RESTRICTIONS = exports.SHIELD_PERMISSION_VERSION_CACHE = exports.SHIELD_PERMISSION_FACTS = exports.SHIELD_RESET_LIMITER = exports.SHIELD_FORGOT_HINT_LIMITER = exports.SHIELD_FORGOT_LIMITER = exports.SHIELD_LOGIN_TOTP_VERIFIER = exports.SHIELD_MFA_STEP_UP = exports.SHIELD_MFA_LIMITER = exports.SHIELD_RECOVERY_LIMITER = exports.SHIELD_LOGIN_IP_LIMITER = exports.SHIELD_LOGIN_LIMITER = exports.SHIELD_MEMBERSHIP_CHECKER = exports.SHIELD_SCOPE_SUBTREE_RESOLVER = exports.SHIELD_SESSION_FACTS_PROJECTOR = exports.SHIELD_ROOT_IDS = exports.SHIELD_TOTP_VERIFIER_OVERRIDE = exports.SHIELD_TOTP_VERIFIER = exports.SHIELD_RESET_LINK_BASE_URL = exports.SHIELD_SESSION_SWEEPER = exports.SHIELD_MFA_DEVICE_STORE = exports.SHIELD_AUDIT_SINK = exports.SHIELD_PROFILE_WRITER = exports.SHIELD_RECOVERY_CODE_STORE = exports.SHIELD_EMAIL_DELIVERY = exports.SHIELD_ATTEMPT_LIMITER_FACTORY = exports.SHIELD_MESSAGE_DISPATCHER = exports.SHIELD_EMAIL_SENDER = exports.SHIELD_CONFIRM_EMAIL_LIMITER = exports.SHIELD_EMAIL_CHANGE_LIMITER = exports.SHIELD_EMAIL_CHANGE_LINK_BASE_URL = exports.SHIELD_EMAIL_ADDRESS_CHANGER = exports.SHIELD_EMAIL_CHANGE_TOKEN_STORE = exports.SHIELD_RESET_TOKEN_STORE = exports.SHIELD_CREDENTIAL_WRITER = exports.SHIELD_RECENT_ROTATION_STORE = exports.SHIELD_SESSION_AUTHORITY = exports.SHIELD_AUTHENTICATOR = exports.SHIELD_PROFILE_RESOLVER = exports.SHIELD_CREDENTIAL_RESOLVER = exports.SHIELD_REDIS = exports.SHIELD_DB_POOL = exports.SHIELD_PASSWORD_HASHER = void 0;
27
27
  var argon2id_password_hasher_js_1 = require("../authentication/argon2id-password-hasher.js");
28
28
  Object.defineProperty(exports, "SHIELD_PASSWORD_HASHER", { enumerable: true, get: function () { return argon2id_password_hasher_js_1.SHIELD_PASSWORD_HASHER; } });
29
29
  /**
@@ -143,6 +143,20 @@ exports.SHIELD_CONFIRM_EMAIL_LIMITER = Symbol('SHIELD_CONFIRM_EMAIL_LIMITER');
143
143
  * consumer delivers it. Consumed by forgot-password.
144
144
  */
145
145
  exports.SHIELD_EMAIL_SENDER = Symbol('SHIELD_EMAIL_SENDER');
146
+ /**
147
+ * The {@link MessageDispatcher} (G-010, `../messaging/message-dispatcher.ts`): the one exit for
148
+ * framework messages. Bounds, audits (`message.sent` / `message.failed`) and never throws. Every
149
+ * framework send uses it; `@astram/identity`'s invite injects it too.
150
+ */
151
+ exports.SHIELD_MESSAGE_DISPATCHER = Symbol('SHIELD_MESSAGE_DISPATCHER');
152
+ /**
153
+ * A factory for guard's Redis-backed `AttemptLimiter` (G-010 P-5): `(cfg) => AttemptLimiter`. For
154
+ * `@astram/identity`'s invite rate limits; exported from `AuthModule` and `@astram/guard/internal`
155
+ * so identity builds limiters without ever holding the raw Redis client.
156
+ */
157
+ exports.SHIELD_ATTEMPT_LIMITER_FACTORY = Symbol('SHIELD_ATTEMPT_LIMITER_FACTORY');
158
+ /** Internal: the bound email provider and its per-send bound (`EmailDelivery`). Not exported. */
159
+ exports.SHIELD_EMAIL_DELIVERY = Symbol('SHIELD_EMAIL_DELIVERY');
146
160
  /**
147
161
  * The `RecoveryCodeStore` (guard port, `../auth/ports/recovery-code-store.ts`) —
148
162
  * persists Argon2-hashed one-time MFA recovery codes. Consumed by MFA enrollment.
@@ -22,6 +22,11 @@ export interface CredentialProvisioner {
22
22
  /** Insert an Argon2id credential for `password` (≥ 8 chars). */
23
23
  provisionPassword(input: PasswordCredentialProvisionInput, query?: CredentialQuery): Promise<void>;
24
24
  stateOf(principalId: string, query?: CredentialQuery): Promise<CredentialState>;
25
+ /**
26
+ * Batch {@link stateOf} (G-010 P-6): one query per 500 ids, an entry for EVERY requested id
27
+ * (`none` when no row). Empty input ⇒ empty map, no query. Duplicate ids are fine.
28
+ */
29
+ statesOf(principalIds: readonly string[], query?: CredentialQuery): Promise<Map<string, CredentialState>>;
25
30
  }
26
31
  /** The principal or login hint already has a credential. Fixed message: no hint, no driver text. */
27
32
  export declare class CredentialExistsError extends Error {
@@ -1 +1 @@
1
- {"version":3,"file":"credential-provisioner.d.ts","sourceRoot":"","sources":["../../src/authentication/credential-provisioner.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,0FAA0F;AAC1F,MAAM,MAAM,eAAe,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpF,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,2DAA2D;IAC3D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,gCAAiC,SAAQ,wBAAwB;IAChF,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,yGAAyG;AACzG,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE3D,MAAM,WAAW,qBAAqB;IACpC,8EAA8E;IAC9E,eAAe,CAAC,KAAK,EAAE,wBAAwB,EAAE,KAAK,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzF,gEAAgE;IAChE,iBAAiB,CACf,KAAK,EAAE,gCAAgC,EACvC,KAAK,CAAC,EAAE,eAAe,GACtB,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;CACjF;AAED,oGAAoG;AACpG,qBAAa,qBAAsB,SAAQ,KAAK;;CAK/C"}
1
+ {"version":3,"file":"credential-provisioner.d.ts","sourceRoot":"","sources":["../../src/authentication/credential-provisioner.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,0FAA0F;AAC1F,MAAM,MAAM,eAAe,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpF,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,2DAA2D;IAC3D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,gCAAiC,SAAQ,wBAAwB;IAChF,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,yGAAyG;AACzG,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE3D,MAAM,WAAW,qBAAqB;IACpC,8EAA8E;IAC9E,eAAe,CAAC,KAAK,EAAE,wBAAwB,EAAE,KAAK,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzF,gEAAgE;IAChE,iBAAiB,CACf,KAAK,EAAE,gCAAgC,EACvC,KAAK,CAAC,EAAE,eAAe,GACtB,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAChF;;;OAGG;IACH,QAAQ,CACN,YAAY,EAAE,SAAS,MAAM,EAAE,EAC/B,KAAK,CAAC,EAAE,eAAe,GACtB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC;CAC1C;AAED,oGAAoG;AACpG,qBAAa,qBAAsB,SAAQ,KAAK;;CAK/C"}
@@ -19,6 +19,7 @@ export declare class MariaDbCredentialProvisioner implements CredentialProvision
19
19
  provisionLocked(input: CredentialProvisionInput, query?: CredentialQuery): Promise<void>;
20
20
  provisionPassword(input: PasswordCredentialProvisionInput, query?: CredentialQuery): Promise<void>;
21
21
  stateOf(principalId: string, query?: CredentialQuery): Promise<CredentialState>;
22
+ statesOf(principalIds: readonly string[], query?: CredentialQuery): Promise<Map<string, CredentialState>>;
22
23
  private validate;
23
24
  private run;
24
25
  private insert;
@@ -1 +1 @@
1
- {"version":3,"file":"mariadb-credential-provisioner.d.ts","sourceRoot":"","sources":["../../src/authentication/mariadb-credential-provisioner.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAEL,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,EAC7B,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,gCAAgC,EACtC,MAAM,6BAA6B,CAAC;AAMrC,OAAO,EAGL,KAAK,oBAAoB,EAC1B,MAAM,qCAAqC,CAAC;AAW7C,qBAAa,4BAA6B,YAAW,qBAAqB;IAMtE,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,GAAG;IANtB,oEAAoE;IACpE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgC;gBAGpC,IAAI,EAAE,IAAI,EACV,GAAG,GAAE,MAAM,MAAiB;IAC7C,yFAAyF;IACzF,OAAO,CAAC,EAAE,oBAAoB;IAQ1B,eAAe,CAAC,KAAK,EAAE,wBAAwB,EAAE,KAAK,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAKxF,iBAAiB,CACrB,KAAK,EAAE,gCAAgC,EACvC,KAAK,CAAC,EAAE,eAAe,GACtB,OAAO,CAAC,IAAI,CAAC;IAQV,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;IAUrF,OAAO,CAAC,QAAQ;IAMhB,OAAO,CAAC,GAAG;YAIG,MAAM;CA0BrB"}
1
+ {"version":3,"file":"mariadb-credential-provisioner.d.ts","sourceRoot":"","sources":["../../src/authentication/mariadb-credential-provisioner.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAEL,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,EAC7B,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,gCAAgC,EACtC,MAAM,6BAA6B,CAAC;AAMrC,OAAO,EAGL,KAAK,oBAAoB,EAC1B,MAAM,qCAAqC,CAAC;AAkB7C,qBAAa,4BAA6B,YAAW,qBAAqB;IAMtE,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,GAAG;IANtB,oEAAoE;IACpE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgC;gBAGpC,IAAI,EAAE,IAAI,EACV,GAAG,GAAE,MAAM,MAAiB;IAC7C,yFAAyF;IACzF,OAAO,CAAC,EAAE,oBAAoB;IAQ1B,eAAe,CAAC,KAAK,EAAE,wBAAwB,EAAE,KAAK,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAKxF,iBAAiB,CACrB,KAAK,EAAE,gCAAgC,EACvC,KAAK,CAAC,EAAE,eAAe,GACtB,OAAO,CAAC,IAAI,CAAC;IAQV,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;IAU/E,QAAQ,CACZ,YAAY,EAAE,SAAS,MAAM,EAAE,EAC/B,KAAK,CAAC,EAAE,eAAe,GACtB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAqBxC,OAAO,CAAC,QAAQ;IAMhB,OAAO,CAAC,GAAG;YAIG,MAAM;CA0BrB"}
@@ -6,11 +6,17 @@ const argon2id_password_hasher_js_1 = require("./argon2id-password-hasher.js");
6
6
  const framework_schema_names_js_1 = require("../config/framework-schema-names.js");
7
7
  const MIN_PASSWORD_LENGTH = 8;
8
8
  const ER_DUP_ENTRY = 1062;
9
+ /** Max ids bound into one `statesOf` `IN (...)`. */
10
+ const STATES_CHUNK = 500;
9
11
  function requireText(value, name) {
10
12
  if (typeof value !== 'string' || value.trim() === '') {
11
13
  throw new TypeError(`${name} must be a non-empty string`);
12
14
  }
13
15
  }
16
+ /** Locked placeholder ⇒ `locked`; any other stored hash ⇒ `usable`. The hash never leaves here. */
17
+ function classify(hash) {
18
+ return (0, argon2id_password_hasher_js_1.isLockedHash)(hash) ? 'locked' : 'usable';
19
+ }
14
20
  class MariaDbCredentialProvisioner {
15
21
  pool;
16
22
  now;
@@ -40,7 +46,24 @@ class MariaDbCredentialProvisioner {
40
46
  const row = rows[0];
41
47
  if (!row)
42
48
  return 'none';
43
- return (0, argon2id_password_hasher_js_1.isLockedHash)(row.ic_password_hash) ? 'locked' : 'usable';
49
+ return classify(row.ic_password_hash);
50
+ }
51
+ async statesOf(principalIds, query) {
52
+ const ids = [...new Set(principalIds)];
53
+ const out = new Map(ids.map((id) => [id, 'none']));
54
+ const run = this.run(query);
55
+ for (let i = 0; i < ids.length; i += STATES_CHUNK) {
56
+ const chunk = ids.slice(i, i + STATES_CHUNK);
57
+ const rows = (await run(`SELECT ic_principal_id, ic_password_hash FROM ${this.table} WHERE ic_principal_id IN (${chunk
58
+ .map(() => '?')
59
+ .join(', ')})`, chunk));
60
+ for (const row of rows) {
61
+ if (out.has(row.ic_principal_id)) {
62
+ out.set(row.ic_principal_id, classify(row.ic_password_hash));
63
+ }
64
+ }
65
+ }
66
+ return out;
44
67
  }
45
68
  validate(input) {
46
69
  requireText(input.principalId, 'principalId');
@@ -0,0 +1,70 @@
1
+ /** The email providers `EMAIL_PROVIDER` accepts. */
2
+ export declare const EMAIL_PROVIDER_VALUES: readonly ["smtp", "brevo", "sendgrid", "mailgun", "disabled"];
3
+ /** Default and ceiling for `MESSAGE_SEND_TIMEOUT_MS` (R6). */
4
+ export declare const DEFAULT_MESSAGE_SEND_TIMEOUT_MS = 10000;
5
+ export declare const MAX_MESSAGE_SEND_TIMEOUT_MS = 30000;
6
+ export interface EmailFromConfig {
7
+ readonly address: string;
8
+ readonly name?: string;
9
+ }
10
+ /** A validated email provider config, structurally `@astram/messaging`'s `EmailProviderConfig`. */
11
+ export type EmailDeliveryConfig = {
12
+ readonly provider: 'smtp';
13
+ readonly from: EmailFromConfig;
14
+ readonly timeoutMs: number;
15
+ readonly host: string;
16
+ readonly port: number;
17
+ readonly tls: 'starttls' | 'implicit' | 'none';
18
+ readonly user?: string;
19
+ readonly password?: string;
20
+ readonly tlsCaPem?: string;
21
+ } | {
22
+ readonly provider: 'brevo' | 'sendgrid';
23
+ readonly from: EmailFromConfig;
24
+ readonly timeoutMs: number;
25
+ readonly apiKey: string;
26
+ readonly baseUrl?: string;
27
+ } | {
28
+ readonly provider: 'mailgun';
29
+ readonly from: EmailFromConfig;
30
+ readonly timeoutMs: number;
31
+ readonly apiKey: string;
32
+ readonly domain: string;
33
+ readonly region: 'us' | 'eu';
34
+ readonly baseUrl?: string;
35
+ };
36
+ export interface MessageConfig {
37
+ readonly email: EmailDeliveryConfig | {
38
+ readonly provider: 'disabled';
39
+ };
40
+ /** SMS and WhatsApp have ports only this round (OD-1): always `disabled`. */
41
+ readonly sms: 'disabled';
42
+ readonly whatsapp: 'disabled';
43
+ /** `MESSAGE_BOOT_PROBE=1`: check reachability and credentials at boot, sending nothing (R8). */
44
+ readonly probe: boolean;
45
+ }
46
+ export interface LoadMessageConfigOptions {
47
+ /**
48
+ * Provenance check for credential variables outside development/test (`wasResolvedFromSecretRef`).
49
+ * Omitted there: fail closed, every credential counts as a literal and is refused.
50
+ */
51
+ readonly resolvedFromSecretRef?: (envKey: string, env: Readonly<Record<string, string | undefined>>) => boolean;
52
+ /** Reads `SMTP_TLS_CA` (UTF-8 PEM). Injected so the loader stays testable. */
53
+ readonly readFile: (path: string) => string;
54
+ }
55
+ /**
56
+ * Read the message config for `emailSender: 'env'`. Refuses (naming variables only):
57
+ * - `EMAIL_PROVIDER` unset or not one of {@link EMAIL_PROVIDER_VALUES};
58
+ * - `SMS_PROVIDER` / `WHATSAPP_PROVIDER` other than `disabled` (no adapter yet);
59
+ * - a missing or malformed `EMAIL_FROM_ADDRESS`, a control character in `EMAIL_FROM_NAME`;
60
+ * - a missing provider credential, an unresolved `secret-ref:` (naming the `SECRETS_PROVIDER`
61
+ * prerequisite when none is set), or outside development/test a credential not resolved from
62
+ * a `secret-ref:`;
63
+ * - `EMAIL_API_BASE_URL` that is not `https:`, carries credentials, or is set for `smtp`;
64
+ * - Mailgun without a domain, or with a region other than `us` / `eu`;
65
+ * - SMTP without a host, with a bad port, half a login, an unknown `SMTP_TLS`, `none` to a
66
+ * non-loopback host outside development/test, or an unreadable `SMTP_TLS_CA`;
67
+ * - `MESSAGE_SEND_TIMEOUT_MS` outside 1–30000, `MESSAGE_BOOT_PROBE` other than `1` / `0`.
68
+ */
69
+ export declare function loadMessageConfig(env: NodeJS.ProcessEnv, options: LoadMessageConfigOptions): MessageConfig;
70
+ //# sourceMappingURL=message-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-config.d.ts","sourceRoot":"","sources":["../../src/config/message-config.ts"],"names":[],"mappings":"AAkBA,oDAAoD;AACpD,eAAO,MAAM,qBAAqB,+DAAgE,CAAC;AAEnG,8DAA8D;AAC9D,eAAO,MAAM,+BAA+B,QAAS,CAAC;AACtD,eAAO,MAAM,2BAA2B,QAAS,CAAC;AAElD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,mGAAmG;AACnG,MAAM,MAAM,mBAAmB,GAC3B;IACE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,UAAU,GAAG,UAAU,GAAG,MAAM,CAAC;IAC/C,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B,GACD;IACE,QAAQ,CAAC,QAAQ,EAAE,OAAO,GAAG,UAAU,CAAC;IACxC,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B,GACD;IACE,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,IAAI,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEN,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,mBAAmB,GAAG;QAAE,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAA;KAAE,CAAC;IACxE,6EAA6E;IAC7E,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC;IAC9B,gGAAgG;IAChG,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,wBAAwB;IACvC;;;OAGG;IACH,QAAQ,CAAC,qBAAqB,CAAC,EAAE,CAC/B,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,KAC9C,OAAO,CAAC;IACb,8EAA8E;IAC9E,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CAC7C;AASD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,CAAC,UAAU,EACtB,OAAO,EAAE,wBAAwB,GAChC,aAAa,CAuDf"}