@astram/guard 0.11.0 → 0.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth/account.controller.d.ts +4 -1
- package/dist/auth/account.controller.d.ts.map +1 -1
- package/dist/auth/account.controller.js +40 -11
- package/dist/auth/auth.module.d.ts +4 -2
- package/dist/auth/auth.module.d.ts.map +1 -1
- package/dist/auth/auth.module.js +32 -11
- package/dist/auth/email-change-messages.d.ts +7 -2
- package/dist/auth/email-change-messages.d.ts.map +1 -1
- package/dist/auth/email-change-messages.js +8 -2
- package/dist/auth/link-base-url.d.ts +24 -0
- package/dist/auth/link-base-url.d.ts.map +1 -0
- package/dist/auth/link-base-url.js +93 -0
- package/dist/auth/tokens.d.ts +4 -2
- package/dist/auth/tokens.d.ts.map +1 -1
- package/dist/auth/tokens.js +4 -2
- package/dist/module/shield.module.d.ts +4 -2
- package/dist/module/shield.module.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -173,7 +173,10 @@ export declare class AccountController {
|
|
|
173
173
|
* • a confirmed MFA device and no `code` → 400 `mfa_required`; wrong code → 400
|
|
174
174
|
* `invalid_request` (`mfa:pid` budget, replay-guarded TOTP or a recovery code, A1); locked → 429
|
|
175
175
|
* • `email-change:pid` budget exhausted → 429 `too_many_requests`
|
|
176
|
-
* • a limiter / token store / mail outage
|
|
176
|
+
* • a limiter / MFA device or recovery-code store / token store / mail outage → 503
|
|
177
|
+
* `authentication_unavailable` (the token is issued before the second factor is checked, so
|
|
178
|
+
* a STORE outage never spends a recovery code or a TOTP; a failed proof burns that token. A
|
|
179
|
+
* mail failure after a successful proof does spend it — the proof precedes the send)
|
|
177
180
|
* • name only → 200 (the refreshed CurrentUserProfile)
|
|
178
181
|
* • email accepted → 202 `{ pendingEmail: true, profile }`
|
|
179
182
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account.controller.d.ts","sourceRoot":"","sources":["../../src/auth/account.controller.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"account.controller.d.ts","sourceRoot":"","sources":["../../src/auth/account.controller.ts"],"names":[],"mappings":"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"}
|
|
@@ -406,7 +406,10 @@ let AccountController = class AccountController {
|
|
|
406
406
|
* • a confirmed MFA device and no `code` → 400 `mfa_required`; wrong code → 400
|
|
407
407
|
* `invalid_request` (`mfa:pid` budget, replay-guarded TOTP or a recovery code, A1); locked → 429
|
|
408
408
|
* • `email-change:pid` budget exhausted → 429 `too_many_requests`
|
|
409
|
-
* • a limiter / token store / mail outage
|
|
409
|
+
* • a limiter / MFA device or recovery-code store / token store / mail outage → 503
|
|
410
|
+
* `authentication_unavailable` (the token is issued before the second factor is checked, so
|
|
411
|
+
* a STORE outage never spends a recovery code or a TOTP; a failed proof burns that token. A
|
|
412
|
+
* mail failure after a successful proof does spend it — the proof precedes the send)
|
|
410
413
|
* • name only → 200 (the refreshed CurrentUserProfile)
|
|
411
414
|
* • email accepted → 202 `{ pendingEmail: true, profile }`
|
|
412
415
|
*
|
|
@@ -494,25 +497,35 @@ let AccountController = class AccountController {
|
|
|
494
497
|
invalidCurrentPassword();
|
|
495
498
|
await this.loginLimiter?.reset(loginKey);
|
|
496
499
|
// The per-account request budget, counted only once the password proved the caller (a typo
|
|
497
|
-
// never spends it); given back when the second factor is missing or wrong
|
|
500
|
+
// never spends it); given back when the second factor is missing or wrong, and when a store
|
|
501
|
+
// outage stops the request before any link is mailed (Phase 13 #2b). A mail failure keeps it
|
|
502
|
+
// counted: the sender may have delivered before it failed.
|
|
498
503
|
const requestKey = `email-change:pid:${claims.id}`;
|
|
499
504
|
await consumeAttempt(this.emailChangeLimiter, requestKey);
|
|
500
|
-
|
|
501
|
-
|
|
505
|
+
const giveBackRequest = async () => {
|
|
506
|
+
await this.emailChangeLimiter?.refund(requestKey).catch(() => undefined);
|
|
507
|
+
};
|
|
508
|
+
// A1: a confirmed MFA device ⇒ a second factor. A store outage here is a 503, not a 500.
|
|
509
|
+
let code = null;
|
|
502
510
|
try {
|
|
503
511
|
if ((await devices.countConfirmed(claims.id)) > 0) {
|
|
504
|
-
|
|
505
|
-
if (code === '')
|
|
506
|
-
mfaRequired();
|
|
507
|
-
await this.requireMfaProof(devices, claims.id, code);
|
|
512
|
+
code = typeof body?.code === 'string' ? body.code.trim() : '';
|
|
508
513
|
}
|
|
509
514
|
}
|
|
510
|
-
catch
|
|
511
|
-
await
|
|
512
|
-
|
|
515
|
+
catch {
|
|
516
|
+
await giveBackRequest();
|
|
517
|
+
retryableUnavailable();
|
|
518
|
+
}
|
|
519
|
+
if (code === '') {
|
|
520
|
+
await giveBackRequest();
|
|
521
|
+
mfaRequired();
|
|
513
522
|
}
|
|
514
523
|
// A2/A3/A4: one pending change; 32 random bytes, stored as sha256, bound to the canonical new
|
|
515
524
|
// address, the current email and this session; 30-minute TTL.
|
|
525
|
+
// Phase 13 #2b: the token is issued BEFORE the second factor is checked, so a token-store outage
|
|
526
|
+
// never spends a recovery code (consumed on a match) or a TOTP (claimed by the replay guard).
|
|
527
|
+
// Until the mail goes out the raw token exists only in this handler, so a row whose proof then
|
|
528
|
+
// fails is inert; it is burned anyway (best effort).
|
|
516
529
|
const rawToken = (0, node_crypto_1.randomBytes)(32).toString('hex');
|
|
517
530
|
try {
|
|
518
531
|
await tokens.issue({
|
|
@@ -526,8 +539,24 @@ let AccountController = class AccountController {
|
|
|
526
539
|
});
|
|
527
540
|
}
|
|
528
541
|
catch {
|
|
542
|
+
await giveBackRequest();
|
|
529
543
|
retryableUnavailable();
|
|
530
544
|
}
|
|
545
|
+
// A1: TOTP via the replay-guarded verifier, or a recovery code, on the shared `mfa:pid` budget,
|
|
546
|
+
// exactly like the code-gated MFA routes. Any refusal (400/429/503) burns the token just issued
|
|
547
|
+
// and gives the request budget back; a store error inside the proof is a 503, not a 500.
|
|
548
|
+
if (code !== null) {
|
|
549
|
+
try {
|
|
550
|
+
await this.requireMfaProof(devices, claims.id, code);
|
|
551
|
+
}
|
|
552
|
+
catch (err) {
|
|
553
|
+
await tokens.invalidateAllForPrincipal(claims.id).catch(() => undefined);
|
|
554
|
+
await giveBackRequest();
|
|
555
|
+
if (err instanceof common_1.HttpException)
|
|
556
|
+
throw err;
|
|
557
|
+
retryableUnavailable();
|
|
558
|
+
}
|
|
559
|
+
}
|
|
531
560
|
const link = (0, email_change_messages_js_1.emailChangeLink)(this.emailChangeLinkBaseUrl ?? email_change_messages_js_1.DEFAULT_EMAIL_CHANGE_LINK_BASE_URL, rawToken);
|
|
532
561
|
try {
|
|
533
562
|
await sender.send((0, email_change_messages_js_1.confirmEmailChangeMessage)(email, link));
|
|
@@ -220,8 +220,10 @@ export interface AuthModuleOptions {
|
|
|
220
220
|
readonly membershipChecker?: MembershipChecker;
|
|
221
221
|
/**
|
|
222
222
|
* The base URL of the app's confirm-email page (Phase 12, KI #14). The mailed link is
|
|
223
|
-
* `${emailChangeLinkBaseUrl}#t=<token>` (the token in the fragment, never the query).
|
|
224
|
-
* `http://localhost:5173/confirm-email`.
|
|
223
|
+
* `${emailChangeLinkBaseUrl}#t=<token>` (the token in the fragment, never the query). Option >
|
|
224
|
+
* env `EMAIL_CHANGE_LINK_BASE_URL` > dev default `http://localhost:5173/confirm-email`. Outside
|
|
225
|
+
* `NODE_ENV` development/test an unset or loopback base fails the boot unless
|
|
226
|
+
* `emailSender: 'disabled'` (Phase 13 #1; `RESET_LINK_BASE_URL` follows the same rule).
|
|
225
227
|
*/
|
|
226
228
|
readonly emailChangeLinkBaseUrl?: string;
|
|
227
229
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.module.d.ts","sourceRoot":"","sources":["../../src/auth/auth.module.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"auth.module.d.ts","sourceRoot":"","sources":["../../src/auth/auth.module.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+DG;AAEH,OAAO,EAAkB,KAAK,aAAa,EAAiB,MAAM,gBAAgB,CAAC;AAanF,OAAO,KAAK,EAGV,kBAAkB,EAOlB,QAAQ,EACR,cAAc,EAEf,MAAM,cAAc,CAAC;AAiGtB,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAChF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAGvE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAGpE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAavD;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,EAAE,QACqE,CAAC;AAE7F;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,cAAc,GAAG,IAAI,GAAG,SAAS,EAC3C,eAAe,EAAE,cAAc,GAC9B,cAAc,CAEhB;AAED;;;;;;;;GAQG;AACH,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,cAAc,CAAC,CAGvE;AAqfD;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;;;;OAMG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACjD;;;;;;OAMG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,eAAe,CAAC;IAC3C;;;;;;OAMG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IAC7C,QAAQ,CAAC,eAAe,CAAC,EAAE,eAAe,CAAC;IAC3C;;;;;;;;OAQG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,GAAG,UAAU,CAAC;IAChD,QAAQ,CAAC,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IAC/C,QAAQ,CAAC,aAAa,CAAC,EAAE,aAAa,CAAC;IACvC,QAAQ,CAAC,cAAc,CAAC,EAAE,cAAc,CAAC;IACzC;;;;;;OAMG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC;IAC/B;;;;;OAKG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,cAAc,CAAC;IACzC;;;;;;;;OAQG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,cAAc,CAAC;IACvC;;;;;;;;OAQG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC;;oGAEgG;IAChG,QAAQ,CAAC,kBAAkB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChD,uGAAuG;IACvG,QAAQ,CAAC,wBAAwB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACtD;;;;;;;OAOG;IACH,QAAQ,CAAC,qBAAqB,CAAC,EAAE,qBAAqB,CAAC;IACvD;;;;;;;;OAQG;IACH,QAAQ,CAAC,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IACrD;;;;;;;OAOG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IAC/C;;;;;;OAMG;IACH,QAAQ,CAAC,sBAAsB,CAAC,EAAE,MAAM,CAAC;CAC1C;AAwID;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,WAAW,CAcrF;AAiGD;;;;;;GAMG;AACH,qBACa,UAAU;IACrB;;;;;OAKG;IACH,MAAM,CAAC,OAAO,CAAC,OAAO,GAAE,iBAAsB,GAAG,aAAa;CA0K/D"}
|
package/dist/auth/auth.module.js
CHANGED
|
@@ -120,7 +120,7 @@ const mariadb_profile_writer_js_1 = require("../authentication/mariadb-profile-w
|
|
|
120
120
|
const mariadb_reset_token_store_js_1 = require("../authentication/mariadb-reset-token-store.js");
|
|
121
121
|
const mariadb_email_change_token_store_js_1 = require("../authentication/mariadb-email-change-token-store.js");
|
|
122
122
|
const mariadb_email_address_changer_js_1 = require("../authentication/mariadb-email-address-changer.js");
|
|
123
|
-
const
|
|
123
|
+
const link_base_url_js_1 = require("./link-base-url.js");
|
|
124
124
|
const mariadb_recovery_code_store_js_1 = require("../authentication/mariadb-recovery-code-store.js");
|
|
125
125
|
const mariadb_mfa_device_store_js_1 = require("../authentication/mariadb-mfa-device-store.js");
|
|
126
126
|
const mariadb_session_sweeper_js_1 = require("../authentication/mariadb-session-sweeper.js");
|
|
@@ -684,11 +684,20 @@ const confirmEmailLimiterProvider = {
|
|
|
684
684
|
useFactory: (redis) => new attempt_limiter_js_1.AttemptLimiter(redis, { maxAttempts: 10, windowMs: 15 * 60 * 1000 }),
|
|
685
685
|
inject: [tokens_js_1.SHIELD_REDIS],
|
|
686
686
|
};
|
|
687
|
-
/**
|
|
688
|
-
|
|
687
|
+
/**
|
|
688
|
+
* The confirm-link base (Phase 13 #1): `ShieldModule.forRoot({ emailChangeLinkBaseUrl })` >
|
|
689
|
+
* `EMAIL_CHANGE_LINK_BASE_URL` > dev default, read when the module compiles. Outside development/test
|
|
690
|
+
* (and unless `emailSender: 'disabled'`) an unset or loopback base FAILS the boot — see
|
|
691
|
+
* {@link resolveAuthLinkBaseUrls}.
|
|
692
|
+
*/
|
|
693
|
+
function makeEmailChangeLinkBaseUrlProvider(base, mailDisabled) {
|
|
689
694
|
return {
|
|
690
695
|
provide: tokens_js_1.SHIELD_EMAIL_CHANGE_LINK_BASE_URL,
|
|
691
|
-
|
|
696
|
+
useFactory: () => (0, link_base_url_js_1.resolveAuthLinkBaseUrls)({
|
|
697
|
+
env: process.env,
|
|
698
|
+
emailChangeLinkBaseUrlOption: base,
|
|
699
|
+
mailDisabled,
|
|
700
|
+
}).emailChangeLinkBaseUrl,
|
|
692
701
|
};
|
|
693
702
|
}
|
|
694
703
|
/**
|
|
@@ -807,12 +816,20 @@ function makeMembershipCheckerProvider(override) {
|
|
|
807
816
|
* (`${base}?token=<rawToken>`). A plain string VALUE (not a seam) resolved from the
|
|
808
817
|
* environment (`RESET_LINK_BASE_URL`) with a dev default, so the framework owns the
|
|
809
818
|
* URL composition and {@link SHIELD_EMAIL_SENDER} stays URL-agnostic. Always
|
|
810
|
-
* provided so the `@Optional()` injection resolves.
|
|
819
|
+
* provided so the `@Optional()` injection resolves. Read when the module compiles (not at import);
|
|
820
|
+
* outside development/test (and unless `emailSender: 'disabled'`) an unset or loopback base FAILS
|
|
821
|
+
* the boot (Phase 13 #1, {@link resolveAuthLinkBaseUrls}).
|
|
811
822
|
*/
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
823
|
+
function makeResetLinkBaseUrlProvider(emailChangeLinkBaseUrl, mailDisabled) {
|
|
824
|
+
return {
|
|
825
|
+
provide: tokens_js_1.SHIELD_RESET_LINK_BASE_URL,
|
|
826
|
+
useFactory: () => (0, link_base_url_js_1.resolveAuthLinkBaseUrls)({
|
|
827
|
+
env: process.env,
|
|
828
|
+
emailChangeLinkBaseUrlOption: emailChangeLinkBaseUrl,
|
|
829
|
+
mailDisabled,
|
|
830
|
+
}).resetLinkBaseUrl,
|
|
831
|
+
};
|
|
832
|
+
}
|
|
816
833
|
/**
|
|
817
834
|
* The auth composition module. Imports {@link PersistenceModule} (the live
|
|
818
835
|
* connections) and provides the adapters + composed engines. Exports the two
|
|
@@ -835,6 +852,10 @@ let AuthModule = AuthModule_1 = class AuthModule {
|
|
|
835
852
|
// through `ShieldModule.forRoot` — guard NEVER imports `@astram/identity`.
|
|
836
853
|
const identityActionKeys = options.identityActionKeys ?? [];
|
|
837
854
|
const identityControlPlaneKeys = options.identityControlPlaneKeys ?? [];
|
|
855
|
+
// The link-base boot rule (Phase 13 #1) applies only with a real sender: `'disabled'` delivers
|
|
856
|
+
// nothing, and an omitted sender outside development/test already fails the boot through
|
|
857
|
+
// `resolveDefaultEmailSender` (that clearer error is kept; in development/test the rule is off).
|
|
858
|
+
const mailDisabled = options.emailSender === undefined || options.emailSender === 'disabled';
|
|
838
859
|
return {
|
|
839
860
|
module: AuthModule_1,
|
|
840
861
|
imports: [persistence_module_js_1.PersistenceModule.forRoot()],
|
|
@@ -858,7 +879,7 @@ let AuthModule = AuthModule_1 = class AuthModule {
|
|
|
858
879
|
emailAddressChangerProvider,
|
|
859
880
|
emailChangeLimiterProvider,
|
|
860
881
|
confirmEmailLimiterProvider,
|
|
861
|
-
makeEmailChangeLinkBaseUrlProvider(options.emailChangeLinkBaseUrl),
|
|
882
|
+
makeEmailChangeLinkBaseUrlProvider(options.emailChangeLinkBaseUrl, mailDisabled),
|
|
862
883
|
makeEmailSenderProvider(options.emailSender),
|
|
863
884
|
makeRecoveryCodeStoreProvider(options.recoveryCodeStore),
|
|
864
885
|
makeProfileWriterProvider(options.profileWriter),
|
|
@@ -898,7 +919,7 @@ let AuthModule = AuthModule_1 = class AuthModule {
|
|
|
898
919
|
},
|
|
899
920
|
// The reset-link base URL value the forgot-password handler composes into the
|
|
900
921
|
// emailed link (framework-owned URL composition; EmailSender stays dumb).
|
|
901
|
-
|
|
922
|
+
makeResetLinkBaseUrlProvider(options.emailChangeLinkBaseUrl, mailDisabled),
|
|
902
923
|
// The resolved session lifetimes (#8) — one source for authority, binder, controller.
|
|
903
924
|
sessionLifetimesProvider,
|
|
904
925
|
sessionRecordStoreProvider,
|
|
@@ -12,8 +12,13 @@ import type { EmailMessage } from './ports/email-sender.js';
|
|
|
12
12
|
export declare const EMAIL_CHANGE_TTL_MS: number;
|
|
13
13
|
/** The default confirm-page base (a dev Vite origin), like the reset-link default. */
|
|
14
14
|
export declare const DEFAULT_EMAIL_CHANGE_LINK_BASE_URL = "http://localhost:5173/confirm-email";
|
|
15
|
-
/**
|
|
16
|
-
|
|
15
|
+
/**
|
|
16
|
+
* What to do if the change was not the owner's (A10, reworded in Phase 13 #2a). After an
|
|
17
|
+
* attacker's change the login hint may have moved with the email (it follows when it equalled the
|
|
18
|
+
* old address), so a reset from the login page may not reach the victim: the administrator comes
|
|
19
|
+
* first, and the reset advice is qualified rather than given as the remedy.
|
|
20
|
+
*/
|
|
21
|
+
export declare const NOT_YOU_SENTENCE: string;
|
|
17
22
|
/** The confirm link: the token rides in the fragment, never the query (A4). */
|
|
18
23
|
export declare function emailChangeLink(base: string, rawToken: string): string;
|
|
19
24
|
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
|
|
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"}
|
|
@@ -8,8 +8,14 @@ exports.emailChangedNoticeMessage = emailChangedNoticeMessage;
|
|
|
8
8
|
exports.EMAIL_CHANGE_TTL_MS = 30 * 60 * 1000;
|
|
9
9
|
/** The default confirm-page base (a dev Vite origin), like the reset-link default. */
|
|
10
10
|
exports.DEFAULT_EMAIL_CHANGE_LINK_BASE_URL = 'http://localhost:5173/confirm-email';
|
|
11
|
-
/**
|
|
12
|
-
|
|
11
|
+
/**
|
|
12
|
+
* What to do if the change was not the owner's (A10, reworded in Phase 13 #2a). After an
|
|
13
|
+
* attacker's change the login hint may have moved with the email (it follows when it equalled the
|
|
14
|
+
* old address), so a reset from the login page may not reach the victim: the administrator comes
|
|
15
|
+
* first, and the reset advice is qualified rather than given as the remedy.
|
|
16
|
+
*/
|
|
17
|
+
exports.NOT_YOU_SENTENCE = "If this wasn't you, contact your administrator immediately. Your sign-in email may have " +
|
|
18
|
+
'changed too, so a password reset from the login page may not reach you.';
|
|
13
19
|
function escapeHtml(value) {
|
|
14
20
|
return value
|
|
15
21
|
.replace(/&/g, '&')
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** The default reset-page base (a dev Vite origin). */
|
|
2
|
+
export declare const DEFAULT_RESET_LINK_BASE_URL = "http://localhost:5173/reset-password";
|
|
3
|
+
export interface AuthLinkBaseUrls {
|
|
4
|
+
readonly resetLinkBaseUrl: string;
|
|
5
|
+
readonly emailChangeLinkBaseUrl: string;
|
|
6
|
+
}
|
|
7
|
+
export interface ResolveAuthLinkBaseUrlsInput {
|
|
8
|
+
/** The raw environment (`NODE_ENV`, `RESET_LINK_BASE_URL`, `EMAIL_CHANGE_LINK_BASE_URL`). */
|
|
9
|
+
readonly env: NodeJS.ProcessEnv;
|
|
10
|
+
/** `ShieldModule.forRoot({ emailChangeLinkBaseUrl })`. */
|
|
11
|
+
readonly emailChangeLinkBaseUrlOption?: string | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* `true` when no app-supplied sender exists: `emailSender: 'disabled'` (nothing is delivered) or
|
|
14
|
+
* omitted (outside development/test the email-sender boot rule already fails the boot with its
|
|
15
|
+
* own error; in development/test the link rule is off anyway).
|
|
16
|
+
*/
|
|
17
|
+
readonly mailDisabled: boolean;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Resolve both link bases and apply the boot rule. Throws (boot fails) outside development/test
|
|
21
|
+
* when a base is unset or local and mail is not `'disabled'`.
|
|
22
|
+
*/
|
|
23
|
+
export declare function resolveAuthLinkBaseUrls(input: ResolveAuthLinkBaseUrlsInput): AuthLinkBaseUrls;
|
|
24
|
+
//# sourceMappingURL=link-base-url.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"link-base-url.d.ts","sourceRoot":"","sources":["../../src/auth/link-base-url.ts"],"names":[],"mappings":"AAmBA,uDAAuD;AACvD,eAAO,MAAM,2BAA2B,yCAAyC,CAAC;AAElF,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC;CACzC;AAED,MAAM,WAAW,4BAA4B;IAC3C,6FAA6F;IAC7F,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IAChC,0DAA0D;IAC1D,QAAQ,CAAC,4BAA4B,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3D;;;;OAIG;IACH,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;CAChC;AAmCD;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,4BAA4B,GAAG,gBAAgB,CAgC7F"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_RESET_LINK_BASE_URL = void 0;
|
|
4
|
+
exports.resolveAuthLinkBaseUrls = resolveAuthLinkBaseUrls;
|
|
5
|
+
/**
|
|
6
|
+
* The two link bases the framework mails (security hardening Phase 13 #1):
|
|
7
|
+
* - the password-reset link `${RESET_LINK_BASE_URL}?token=…` (`POST /auth/forgot-password`);
|
|
8
|
+
* - the email-change confirm link `${emailChangeLinkBaseUrl}#t=…` (`PATCH /account/profile`).
|
|
9
|
+
*
|
|
10
|
+
* Precedence: the `emailChangeLinkBaseUrl` option > `EMAIL_CHANGE_LINK_BASE_URL` > dev default;
|
|
11
|
+
* the reset link: `RESET_LINK_BASE_URL` > dev default. A blank value counts as unset.
|
|
12
|
+
*
|
|
13
|
+
* Boot rule (fail closed): outside `NODE_ENV` development/test (raw value, unset is NOT dev), with
|
|
14
|
+
* a mail sender, each base must be set, parse as an `http:`/`https:` URL and name a host that is
|
|
15
|
+
* not loopback/unspecified (`localhost`, `*.localhost`, `127.0.0.0/8`, `::1`, `0.0.0.0`, `::`).
|
|
16
|
+
* Otherwise auth composition throws, naming the variable(s) — never the configured value (it may
|
|
17
|
+
* carry credentials). `emailSender: 'disabled'` skips the rule: the no-op sender delivers nothing,
|
|
18
|
+
* so no link can reach a user (an omitted sender fails the boot earlier, see `auth.module.ts`).
|
|
19
|
+
* `https:` is not required (the reset path never required it).
|
|
20
|
+
*/
|
|
21
|
+
const app_config_js_1 = require("../config/app-config.js");
|
|
22
|
+
const email_change_messages_js_1 = require("./email-change-messages.js");
|
|
23
|
+
/** The default reset-page base (a dev Vite origin). */
|
|
24
|
+
exports.DEFAULT_RESET_LINK_BASE_URL = 'http://localhost:5173/reset-password';
|
|
25
|
+
function present(value) {
|
|
26
|
+
return value !== undefined && value.trim() !== '' ? value.trim() : undefined;
|
|
27
|
+
}
|
|
28
|
+
function isLoopbackOrUnspecifiedHost(hostname) {
|
|
29
|
+
const host = hostname
|
|
30
|
+
.toLowerCase()
|
|
31
|
+
.replace(/^\[|\]$/gu, '')
|
|
32
|
+
.replace(/\.$/u, '');
|
|
33
|
+
if (host === 'localhost' || host.endsWith('.localhost'))
|
|
34
|
+
return true;
|
|
35
|
+
if (host === '0.0.0.0' || host === '::' || host === '::1')
|
|
36
|
+
return true;
|
|
37
|
+
if (/^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/u.test(host))
|
|
38
|
+
return true;
|
|
39
|
+
// IPv4-mapped loopback/unspecified (`::ffff:127.0.0.1` normalises to `::ffff:7f00:1`).
|
|
40
|
+
if (/^::ffff:(7f[0-9a-f]{2}:[0-9a-f]{1,4}|0:0)$/u.test(host))
|
|
41
|
+
return true;
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
/** Why a production link base is unusable, or `null` when it is fine. */
|
|
45
|
+
function problemWith(value) {
|
|
46
|
+
if (value === undefined)
|
|
47
|
+
return 'is not set';
|
|
48
|
+
let url;
|
|
49
|
+
try {
|
|
50
|
+
url = new URL(value);
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return 'is not a valid URL';
|
|
54
|
+
}
|
|
55
|
+
if (url.protocol !== 'http:' && url.protocol !== 'https:')
|
|
56
|
+
return 'is not an http(s) URL';
|
|
57
|
+
if (isLoopbackOrUnspecifiedHost(url.hostname)) {
|
|
58
|
+
return 'points at a loopback/unspecified host (localhost, 127.0.0.1, ::1, 0.0.0.0)';
|
|
59
|
+
}
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Resolve both link bases and apply the boot rule. Throws (boot fails) outside development/test
|
|
64
|
+
* when a base is unset or local and mail is not `'disabled'`.
|
|
65
|
+
*/
|
|
66
|
+
function resolveAuthLinkBaseUrls(input) {
|
|
67
|
+
const resetConfigured = present(input.env.RESET_LINK_BASE_URL);
|
|
68
|
+
const optionConfigured = present(input.emailChangeLinkBaseUrlOption);
|
|
69
|
+
const emailChangeConfigured = optionConfigured ?? present(input.env.EMAIL_CHANGE_LINK_BASE_URL);
|
|
70
|
+
if (!input.mailDisabled && !(0, app_config_js_1.isDevOrTestNodeEnv)(input.env.NODE_ENV)) {
|
|
71
|
+
const problems = [];
|
|
72
|
+
const resetProblem = problemWith(resetConfigured);
|
|
73
|
+
if (resetProblem)
|
|
74
|
+
problems.push(`RESET_LINK_BASE_URL ${resetProblem}`);
|
|
75
|
+
const changeProblem = problemWith(emailChangeConfigured);
|
|
76
|
+
if (changeProblem) {
|
|
77
|
+
const name = optionConfigured
|
|
78
|
+
? 'the emailChangeLinkBaseUrl option'
|
|
79
|
+
: 'EMAIL_CHANGE_LINK_BASE_URL (or the emailChangeLinkBaseUrl option)';
|
|
80
|
+
problems.push(`${name} ${changeProblem}`);
|
|
81
|
+
}
|
|
82
|
+
if (problems.length > 0) {
|
|
83
|
+
const nodeEnv = input.env.NODE_ENV;
|
|
84
|
+
throw new Error('Astram auth composition: the mailed password-reset and email-change links need a ' +
|
|
85
|
+
`public base URL when NODE_ENV is not 'development' or 'test' (got: ${nodeEnv === undefined ? 'unset' : `'${nodeEnv}'`}): ${problems.join('; ')}. Set them to your app's /reset-password and /confirm-email ` +
|
|
86
|
+
"pages, or pass emailSender: 'disabled' if this deployment sends no email.");
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
resetLinkBaseUrl: resetConfigured ?? exports.DEFAULT_RESET_LINK_BASE_URL,
|
|
91
|
+
emailChangeLinkBaseUrl: emailChangeConfigured ?? email_change_messages_js_1.DEFAULT_EMAIL_CHANGE_LINK_BASE_URL,
|
|
92
|
+
};
|
|
93
|
+
}
|
package/dist/auth/tokens.d.ts
CHANGED
|
@@ -99,7 +99,8 @@ export declare const SHIELD_EMAIL_CHANGE_TOKEN_STORE: unique symbol;
|
|
|
99
99
|
export declare const SHIELD_EMAIL_ADDRESS_CHANGER: unique symbol;
|
|
100
100
|
/**
|
|
101
101
|
* The email-change confirm-link base URL (a plain `string`, `ShieldModule.forRoot({
|
|
102
|
-
* emailChangeLinkBaseUrl })
|
|
102
|
+
* emailChangeLinkBaseUrl })` > env `EMAIL_CHANGE_LINK_BASE_URL` > dev default
|
|
103
|
+
* `http://localhost:5173/confirm-email`; production boot rule in `link-base-url.ts`). The link is
|
|
103
104
|
* `${base}#t=<rawToken>` — the token rides in the FRAGMENT, never the query (A4), so it is not
|
|
104
105
|
* sent to the server that serves the page nor leaked through a Referer.
|
|
105
106
|
*/
|
|
@@ -164,7 +165,8 @@ export declare const SHIELD_SESSION_SWEEPER: unique symbol;
|
|
|
164
165
|
* composes the emailed reset link as `${base}?token=<rawToken>` so the
|
|
165
166
|
* {@link SHIELD_EMAIL_SENDER} seam stays a dumb delivery channel (no URL/token
|
|
166
167
|
* logic). Bound app-wide by `AuthModule` from the environment
|
|
167
|
-
* (`RESET_LINK_BASE_URL`, default `http://localhost:5173/reset-password
|
|
168
|
+
* (`RESET_LINK_BASE_URL`, default `http://localhost:5173/reset-password`; outside
|
|
169
|
+
* development/test an unset or loopback value fails the boot, see `link-base-url.ts`). Consumed
|
|
168
170
|
* by `POST /auth/forgot-password`.
|
|
169
171
|
*/
|
|
170
172
|
export declare const SHIELD_RESET_LINK_BASE_URL: unique symbol;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../src/auth/tokens.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,+CAA+C,CAAC;AAEvF;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,eAA2B,CAAC;AAEvD;;;;GAIG;AACH,eAAO,MAAM,YAAY,eAAyB,CAAC;AAEnD;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,eAAuC,CAAC;AAE/E;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,eAAoC,CAAC;AAEzE;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,eAAiC,CAAC;AAEnE;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,eAAqC,CAAC;AAW3E;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,eAAqC,CAAC;AAE3E;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,eAAqC,CAAC;AAE3E;;;;;;GAMG;AACH,eAAO,MAAM,+BAA+B,eAA4C,CAAC;AAEzF;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,eAAyC,CAAC;AAEnF
|
|
1
|
+
{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../src/auth/tokens.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,+CAA+C,CAAC;AAEvF;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,eAA2B,CAAC;AAEvD;;;;GAIG;AACH,eAAO,MAAM,YAAY,eAAyB,CAAC;AAEnD;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,eAAuC,CAAC;AAE/E;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,eAAoC,CAAC;AAEzE;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,eAAiC,CAAC;AAEnE;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,eAAqC,CAAC;AAW3E;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,eAAqC,CAAC;AAE3E;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,eAAqC,CAAC;AAE3E;;;;;;GAMG;AACH,eAAO,MAAM,+BAA+B,eAA4C,CAAC;AAEzF;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,eAAyC,CAAC;AAEnF;;;;;;GAMG;AACH,eAAO,MAAM,iCAAiC,eAA8C,CAAC;AAE7F;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,eAAwC,CAAC;AAEjF;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,eAAyC,CAAC;AAEnF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,eAAgC,CAAC;AAEjE;;;GAGG;AACH,eAAO,MAAM,0BAA0B,eAAuC,CAAC;AAE/E;;;GAGG;AACH,eAAO,MAAM,qBAAqB,eAAkC,CAAC;AAErE;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,eAA8B,CAAC;AAE7D;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,eAAoC,CAAC;AAEzE;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,eAAmC,CAAC;AAEvE;;;;;;;;GAQG;AACH,eAAO,MAAM,0BAA0B,eAAuC,CAAC;AAE/E;;;;;;;;;;GAUG;AACH,eAAO,MAAM,oBAAoB,eAAiC,CAAC;AAEnE;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,6BAA6B,eAA0C,CAAC;AAErF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,eAAe,eAA4B,CAAC;AAEzD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,8BAA8B,eAA2C,CAAC;AAEvF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,6BAA6B,eAA0C,CAAC;AAErF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,yBAAyB,eAAsC,CAAC;AAU7E;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,oBAAoB,eAAiC,CAAC;AAEnE;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,uBAAuB,eAAoC,CAAC;AAEzE;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,eAAoC,CAAC;AAEzE;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,eAA+B,CAAC;AAE/D;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,eAA+B,CAAC;AAE/D;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,eAAuC,CAAC;AAE/E;;;;;;;;;;GAUG;AACH,eAAO,MAAM,qBAAqB,eAAkC,CAAC;AAErE;;;;;;;;;GASG;AACH,eAAO,MAAM,0BAA0B,eAAuC,CAAC;AAE/E;;;;;;;;;;GAUG;AACH,eAAO,MAAM,oBAAoB,eAAiC,CAAC;AAEnE;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,eAAoC,CAAC;AAEzE;;;;;;;GAOG;AACH,eAAO,MAAM,+BAA+B,eAA4C,CAAC;AAEzF;;;;;;GAMG;AACH,eAAO,MAAM,2BAA2B,eAAwC,CAAC"}
|
package/dist/auth/tokens.js
CHANGED
|
@@ -111,7 +111,8 @@ exports.SHIELD_EMAIL_CHANGE_TOKEN_STORE = Symbol('SHIELD_EMAIL_CHANGE_TOKEN_STOR
|
|
|
111
111
|
exports.SHIELD_EMAIL_ADDRESS_CHANGER = Symbol('SHIELD_EMAIL_ADDRESS_CHANGER');
|
|
112
112
|
/**
|
|
113
113
|
* The email-change confirm-link base URL (a plain `string`, `ShieldModule.forRoot({
|
|
114
|
-
* emailChangeLinkBaseUrl })
|
|
114
|
+
* emailChangeLinkBaseUrl })` > env `EMAIL_CHANGE_LINK_BASE_URL` > dev default
|
|
115
|
+
* `http://localhost:5173/confirm-email`; production boot rule in `link-base-url.ts`). The link is
|
|
115
116
|
* `${base}#t=<rawToken>` — the token rides in the FRAGMENT, never the query (A4), so it is not
|
|
116
117
|
* sent to the server that serves the page nor leaked through a Referer.
|
|
117
118
|
*/
|
|
@@ -176,7 +177,8 @@ exports.SHIELD_SESSION_SWEEPER = Symbol('SHIELD_SESSION_SWEEPER');
|
|
|
176
177
|
* composes the emailed reset link as `${base}?token=<rawToken>` so the
|
|
177
178
|
* {@link SHIELD_EMAIL_SENDER} seam stays a dumb delivery channel (no URL/token
|
|
178
179
|
* logic). Bound app-wide by `AuthModule` from the environment
|
|
179
|
-
* (`RESET_LINK_BASE_URL`, default `http://localhost:5173/reset-password
|
|
180
|
+
* (`RESET_LINK_BASE_URL`, default `http://localhost:5173/reset-password`; outside
|
|
181
|
+
* development/test an unset or loopback value fails the boot, see `link-base-url.ts`). Consumed
|
|
180
182
|
* by `POST /auth/forgot-password`.
|
|
181
183
|
*/
|
|
182
184
|
exports.SHIELD_RESET_LINK_BASE_URL = Symbol('SHIELD_RESET_LINK_BASE_URL');
|
|
@@ -190,8 +190,10 @@ export interface ShieldModuleOptions {
|
|
|
190
190
|
/**
|
|
191
191
|
* The base URL of the app's confirm-email page (security hardening Phase 12, KI #14). A
|
|
192
192
|
* self-service email change mails `${emailChangeLinkBaseUrl}#t=<token>` to the NEW address — the
|
|
193
|
-
* token in the fragment, never the query.
|
|
194
|
-
* consulted when `auth: true`.
|
|
193
|
+
* token in the fragment, never the query. Option > env `EMAIL_CHANGE_LINK_BASE_URL` > dev default
|
|
194
|
+
* `http://localhost:5173/confirm-email`. Only consulted when `auth: true`. Outside `NODE_ENV`
|
|
195
|
+
* development/test the boot FAILS when this base (or `RESET_LINK_BASE_URL`) is unset, invalid or
|
|
196
|
+
* loopback (`localhost`, `127.0.0.1`, `::1`, `0.0.0.0`), unless `emailSender: 'disabled'`.
|
|
195
197
|
*/
|
|
196
198
|
readonly emailChangeLinkBaseUrl?: string;
|
|
197
199
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shield.module.d.ts","sourceRoot":"","sources":["../../src/module/shield.module.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"shield.module.d.ts","sourceRoot":"","sources":["../../src/module/shield.module.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astram/guard",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Astram framework — the enforcement guard + real-world adapters (the 'hands'). One global deny-by-default gate every request passes through (ADR-0002), classification decorators, boot-pool assertion (ADR-0018), the forRoot() registration seam, and the DB/Redis/crypto adapters that connect the sealed core to a real backend. Depends on @astram/core (ADR-0003, ADR-0023).",
|
|
6
6
|
"type": "commonjs",
|