@lenne.tech/nest-server 11.42.10 → 11.42.12
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/.claude/rules/configurable-features.md +1 -1
- package/.claude/rules/package-management.md +12 -5
- package/.claude/rules/testing.md +10 -8
- package/CLAUDE.md +1 -1
- package/FRAMEWORK-API.md +1 -1
- package/dist/core/common/helpers/cookies.helper.d.ts +3 -2
- package/dist/core/common/helpers/cookies.helper.js +13 -4
- package/dist/core/common/helpers/cookies.helper.js.map +1 -1
- package/dist/core/common/helpers/outbound-url.helper.js +2 -5
- package/dist/core/common/helpers/outbound-url.helper.js.map +1 -1
- package/dist/core/modules/auth/core-auth.controller.js +2 -1
- package/dist/core/modules/auth/core-auth.controller.js.map +1 -1
- package/dist/core/modules/auth/core-auth.resolver.js +2 -1
- package/dist/core/modules/auth/core-auth.resolver.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth-api.middleware.js +1 -0
- package/dist/core/modules/better-auth/core-better-auth-api.middleware.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth-cookie.helper.d.ts +2 -0
- package/dist/core/modules/better-auth/core-better-auth-cookie.helper.js +2 -1
- package/dist/core/modules/better-auth/core-better-auth-cookie.helper.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth-email-verification.service.js +7 -2
- package/dist/core/modules/better-auth/core-better-auth-email-verification.service.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth.controller.js +1 -0
- package/dist/core/modules/better-auth/core-better-auth.controller.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth.service.d.ts +1 -0
- package/dist/core/modules/better-auth/core-better-auth.service.js +4 -0
- package/dist/core/modules/better-auth/core-better-auth.service.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/migration-guides/11.27.2-to-11.27.3.md +4 -2
- package/migration-guides/11.36.3-to-11.36.4.md +12 -7
- package/migration-guides/11.42.10-to-11.42.11.md +176 -0
- package/migration-guides/11.42.11-to-11.42.12.md +142 -0
- package/package.json +12 -12
- package/src/core/common/helpers/cookies.helper.ts +50 -6
- package/src/core/common/helpers/outbound-url.helper.ts +4 -10
- package/src/core/modules/auth/core-auth.controller.ts +2 -1
- package/src/core/modules/auth/core-auth.resolver.ts +2 -1
- package/src/core/modules/better-auth/README.md +1 -0
- package/src/core/modules/better-auth/core-better-auth-api.middleware.ts +1 -0
- package/src/core/modules/better-auth/core-better-auth-cookie.helper.ts +24 -5
- package/src/core/modules/better-auth/core-better-auth-email-verification.service.ts +20 -10
- package/src/core/modules/better-auth/core-better-auth.controller.ts +4 -0
- package/src/core/modules/better-auth/core-better-auth.service.ts +24 -0
|
@@ -81,6 +81,16 @@ export interface BetterAuthCookieHelperConfig {
|
|
|
81
81
|
* CRITICAL: Required for Passkey/2FA to work correctly.
|
|
82
82
|
*/
|
|
83
83
|
secret?: string;
|
|
84
|
+
/**
|
|
85
|
+
* Whether Better-Auth's own handlers set `Secure` on the cookies they write
|
|
86
|
+
* (`CoreBetterAuthService.usesSecureCookies()`). `true` makes this helper set it too, whatever the
|
|
87
|
+
* environment, so one session cookie never carries two different transport rules.
|
|
88
|
+
*
|
|
89
|
+
* @since 11.42.12 Before, `secure` followed {@link isProductionLikeEnv} alone, so on the deployed
|
|
90
|
+
* `develop` / `test` stages of a starter-based project the cookie this helper wrote
|
|
91
|
+
* lacked `Secure` while Better-Auth's handlers set it on the same https deployment.
|
|
92
|
+
*/
|
|
93
|
+
secureTransport?: boolean;
|
|
84
94
|
}
|
|
85
95
|
|
|
86
96
|
/**
|
|
@@ -146,9 +156,11 @@ export class BetterAuthCookieHelper {
|
|
|
146
156
|
/**
|
|
147
157
|
* Gets the default cookie options for authentication cookies.
|
|
148
158
|
*
|
|
149
|
-
* The `secure` flag is `true` when
|
|
150
|
-
*
|
|
151
|
-
* staging
|
|
159
|
+
* The `secure` flag is `true` when Better-Auth's own cookies are secure (`config.secureTransport`,
|
|
160
|
+
* i.e. an `https://` base URL unless the project opted out), when `config.env` is production-like
|
|
161
|
+
* (`production` / `staging`), or when `NODE_ENV === 'production'`. The first covers every https
|
|
162
|
+
* deployment whatever its environment name; the other two keep `Secure` where real users are
|
|
163
|
+
* certain even if a project switched it off in Better-Auth.
|
|
152
164
|
*
|
|
153
165
|
* @returns Cookie options with httpOnly, sameSite, and secure settings
|
|
154
166
|
*/
|
|
@@ -156,7 +168,7 @@ export class BetterAuthCookieHelper {
|
|
|
156
168
|
const options: AuthCookieOptions = {
|
|
157
169
|
httpOnly: true,
|
|
158
170
|
sameSite: 'lax',
|
|
159
|
-
secure: isProductionLikeEnv(this.config.env),
|
|
171
|
+
secure: this.config.secureTransport === true || isProductionLikeEnv(this.config.env),
|
|
160
172
|
};
|
|
161
173
|
|
|
162
174
|
if (this.config.domain) {
|
|
@@ -403,7 +415,13 @@ export class BetterAuthCookieHelper {
|
|
|
403
415
|
*/
|
|
404
416
|
export function createCookieHelper(
|
|
405
417
|
basePath: string,
|
|
406
|
-
options?: {
|
|
418
|
+
options?: {
|
|
419
|
+
domain?: string;
|
|
420
|
+
env?: string;
|
|
421
|
+
legacyCookieEnabled?: boolean;
|
|
422
|
+
secret?: string;
|
|
423
|
+
secureTransport?: boolean;
|
|
424
|
+
},
|
|
407
425
|
logger?: Logger,
|
|
408
426
|
): BetterAuthCookieHelper {
|
|
409
427
|
return new BetterAuthCookieHelper({
|
|
@@ -413,5 +431,6 @@ export function createCookieHelper(
|
|
|
413
431
|
legacyCookieEnabled: options?.legacyCookieEnabled ?? false,
|
|
414
432
|
logger,
|
|
415
433
|
secret: options?.secret,
|
|
434
|
+
secureTransport: options?.secureTransport,
|
|
416
435
|
});
|
|
417
436
|
}
|
|
@@ -4,7 +4,7 @@ import ejs = require('ejs');
|
|
|
4
4
|
import * as fs from 'fs';
|
|
5
5
|
import * as path from 'path';
|
|
6
6
|
|
|
7
|
-
import { isProductionLikeEnv, resolveAppUrlFromConfig } from '../../common/helpers/cookies.helper';
|
|
7
|
+
import { isLocalEnv, isProductionLikeEnv, resolveAppUrlFromConfig } from '../../common/helpers/cookies.helper';
|
|
8
8
|
import { maskEmail } from '../../common/helpers/logging.helper';
|
|
9
9
|
import { IBetterAuthEmailVerificationConfig } from '../../common/interfaces/server-options.interface';
|
|
10
10
|
import { BrevoService } from '../../common/services/brevo.service';
|
|
@@ -838,25 +838,35 @@ export class CoreBetterAuthEmailVerificationService {
|
|
|
838
838
|
* Print an auth link (verification / password reset) to stdout for local development.
|
|
839
839
|
*
|
|
840
840
|
* The URL embeds a bearer token: the verification link confirms an address, the reset link
|
|
841
|
-
* changes a password outright. Neither may reach a deployment
|
|
842
|
-
*
|
|
843
|
-
*
|
|
844
|
-
* `
|
|
845
|
-
*
|
|
841
|
+
* changes a password outright. Neither may reach a deployment's logs, so the link is printed only
|
|
842
|
+
* in a LOCAL environment (`isLocalEnv()`: `local`, `ci`, `e2e`) — an allowlist, not "anything
|
|
843
|
+
* that is not production". Until 11.42.12 the gate was `!isProductionLikeEnv()`, which names only
|
|
844
|
+
* `production` and `staging`; the deployed `develop` and `test` stages of a starter-based project
|
|
845
|
+
* passed it and wrote live reset links into their log pipeline, where log access alone was
|
|
846
|
+
* enough to take over an account.
|
|
847
|
+
*
|
|
848
|
+
* `LT_LOG_AUTH_URLS=1` opts in for another environment that runs on a developer machine (this
|
|
849
|
+
* repository's own `development`, for one); `LT_LOG_AUTH_URLS=0` suppresses it everywhere. A
|
|
850
|
+
* production-like environment never prints, whatever the variable says: the opt-in exists for
|
|
851
|
+
* laptops, and a hard floor keeps it from being the thing that reopens a deployment.
|
|
846
852
|
*
|
|
847
853
|
* The address is masked (PII, and the rest of this file already masks it); the URL is printed in
|
|
848
|
-
* full because following it without a mail server is the whole point locally.
|
|
849
|
-
* `LT_LOG_AUTH_URLS=0` to suppress it even outside production.
|
|
854
|
+
* full because following it without a mail server is the whole point locally.
|
|
850
855
|
*
|
|
851
856
|
* `console.log` rather than the NestJS logger, deliberately and for two reasons: the logger
|
|
852
857
|
* buffers, which makes interception unreliable under Vitest, and a logger call would route the
|
|
853
858
|
* token into `HubLogBufferService`'s ring buffer, which is readable over HTTP by any ADMIN.
|
|
854
859
|
*/
|
|
855
860
|
protected logAuthUrlForDevelopment(label: string, email: string, url: string): void {
|
|
856
|
-
|
|
861
|
+
const optIn = process.env.LT_LOG_AUTH_URLS;
|
|
862
|
+
if (optIn === '0') {
|
|
863
|
+
return;
|
|
864
|
+
}
|
|
865
|
+
const env = this.configService?.getFastButReadOnly<string>('env') ?? process.env.NODE_ENV;
|
|
866
|
+
if (isProductionLikeEnv(env)) {
|
|
857
867
|
return;
|
|
858
868
|
}
|
|
859
|
-
if (
|
|
869
|
+
if (!isLocalEnv(env) && optIn !== '1') {
|
|
860
870
|
return;
|
|
861
871
|
}
|
|
862
872
|
// oxlint-disable-next-line no-console
|
|
@@ -268,6 +268,10 @@ export class CoreBetterAuthController {
|
|
|
268
268
|
env: this.configService.getFastButReadOnly<string>('env'),
|
|
269
269
|
legacyCookieEnabled: legacyAuthEnabled,
|
|
270
270
|
secret: betterAuthConfig?.secret,
|
|
271
|
+
// Mirror Better-Auth's own `Secure` decision, so the cookie this controller writes and the
|
|
272
|
+
// one Better-Auth's handlers write follow the same transport rule on every https deployment.
|
|
273
|
+
// Optional call: a project's test stub of the service may predate the method.
|
|
274
|
+
secureTransport: this.betterAuthService.usesSecureCookies?.() === true,
|
|
271
275
|
},
|
|
272
276
|
this.logger,
|
|
273
277
|
);
|
|
@@ -703,6 +703,30 @@ export class CoreBetterAuthService implements OnApplicationBootstrap, OnModuleIn
|
|
|
703
703
|
return this.config.baseUrl || 'http://localhost:3000';
|
|
704
704
|
}
|
|
705
705
|
|
|
706
|
+
/**
|
|
707
|
+
* Whether Better-Auth's own handlers set `Secure` on the cookies they write, read off the live
|
|
708
|
+
* instance.
|
|
709
|
+
*
|
|
710
|
+
* `createBetterAuthInstance()` pins `useSecureCookies: false` (for the cookie NAME) and restores
|
|
711
|
+
* the transport flag through `advanced.defaultCookieAttributes.secure` on an `https://` base URL;
|
|
712
|
+
* a project may override either. Reading the instance rather than re-deriving from a URL gives
|
|
713
|
+
* exactly the answer Better-Auth applies — including the base URL it actually uses, which
|
|
714
|
+
* {@link getBaseUrl} does not know when only the server's `baseUrl` is set.
|
|
715
|
+
*
|
|
716
|
+
* The framework's own cookie helper mirrors this, so a session cookie carries `Secure` no matter
|
|
717
|
+
* which path wrote it.
|
|
718
|
+
*
|
|
719
|
+
* @since 11.42.12
|
|
720
|
+
*/
|
|
721
|
+
usesSecureCookies(): boolean {
|
|
722
|
+
const advanced = (
|
|
723
|
+
this.getInstance() as unknown as {
|
|
724
|
+
options?: { advanced?: { defaultCookieAttributes?: { secure?: unknown }; useSecureCookies?: unknown } };
|
|
725
|
+
} | null
|
|
726
|
+
)?.options?.advanced;
|
|
727
|
+
return advanced?.useSecureCookies === true || advanced?.defaultCookieAttributes?.secure === true;
|
|
728
|
+
}
|
|
729
|
+
|
|
706
730
|
/**
|
|
707
731
|
* Gets the resolved cookie domain for cross-subdomain cookie sharing.
|
|
708
732
|
*
|