@lenne.tech/nest-server 11.24.4 → 11.25.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/.claude/rules/configurable-features.md +2 -0
- package/CLAUDE.md +13 -0
- package/FRAMEWORK-API.md +14 -2
- package/README.md +15 -0
- package/dist/config.env.js +100 -81
- package/dist/config.env.js.map +1 -1
- package/dist/core/common/helpers/cookies.helper.d.ts +19 -0
- package/dist/core/common/helpers/cookies.helper.js +109 -0
- package/dist/core/common/helpers/cookies.helper.js.map +1 -0
- package/dist/core/common/interfaces/server-options.interface.d.ts +11 -1
- package/dist/core/modules/auth/core-auth.controller.js +4 -16
- package/dist/core/modules/auth/core-auth.controller.js.map +1 -1
- package/dist/core/modules/auth/core-auth.resolver.js +4 -16
- package/dist/core/modules/auth/core-auth.resolver.js.map +1 -1
- package/dist/core/modules/auth/tokens.decorator.d.ts +1 -1
- package/dist/core/modules/better-auth/better-auth.config.d.ts +24 -1
- package/dist/core/modules/better-auth/better-auth.config.js +22 -2
- package/dist/core/modules/better-auth/better-auth.config.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth-api.middleware.js +3 -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 +3 -1
- package/dist/core/modules/better-auth/core-better-auth-cookie.helper.js +7 -3
- package/dist/core/modules/better-auth/core-better-auth-cookie.helper.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth.controller.js +7 -3
- package/dist/core/modules/better-auth/core-better-auth.controller.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth.module.d.ts +2 -1
- package/dist/core/modules/better-auth/core-better-auth.module.js +4 -1
- package/dist/core/modules/better-auth/core-better-auth.module.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth.service.js +5 -4
- package/dist/core/modules/better-auth/core-better-auth.service.js.map +1 -1
- package/dist/core/modules/migrate/templates/migration-project.template.ts +16 -2
- package/dist/core.module.d.ts +3 -1
- package/dist/core.module.js +10 -7
- package/dist/core.module.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/main.js +17 -3
- package/dist/main.js.map +1 -1
- package/dist/test/test.helper.d.ts +1 -0
- package/dist/test/test.helper.js +2 -1
- package/dist/test/test.helper.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/docs/REQUEST-LIFECYCLE.md +78 -3
- package/migration-guides/11.24.x-to-11.25.0.md +438 -0
- package/package.json +23 -21
- package/src/config.env.ts +116 -111
- package/src/core/common/helpers/cookies.helper.ts +298 -0
- package/src/core/common/interfaces/server-options.interface.ts +141 -2
- package/src/core/modules/auth/core-auth.controller.ts +11 -23
- package/src/core/modules/auth/core-auth.resolver.ts +11 -23
- package/src/core/modules/better-auth/INTEGRATION-CHECKLIST.md +18 -0
- package/src/core/modules/better-auth/README.md +7 -0
- package/src/core/modules/better-auth/better-auth.config.ts +53 -15
- package/src/core/modules/better-auth/core-better-auth-api.middleware.ts +6 -3
- package/src/core/modules/better-auth/core-better-auth-cookie.helper.ts +33 -7
- package/src/core/modules/better-auth/core-better-auth.controller.ts +12 -3
- package/src/core/modules/better-auth/core-better-auth.module.ts +16 -1
- package/src/core/modules/better-auth/core-better-auth.service.ts +26 -10
- package/src/core/modules/migrate/templates/migration-project.template.ts +16 -2
- package/src/core.module.ts +40 -12
- package/src/index.ts +1 -0
- package/src/main.ts +32 -5
- package/src/test/test.helper.ts +15 -1
|
@@ -42,6 +42,8 @@ The `CoreModule` is a dynamic module that bootstraps the entire framework:
|
|
|
42
42
|
| **Mongoose Plugins** | Auto-registration of ID, password, audit, and role guard plugins |
|
|
43
43
|
| **GraphQL Subscriptions** | WebSocket support with JWT/session authentication |
|
|
44
44
|
| **Configuration System** | `config.env.ts` with ENV variables, `NEST_SERVER_CONFIG` JSON, `NSC__*` prefixes |
|
|
45
|
+
| **Cookie Handling** | Enabled by default (`cookies: true`), configurable via `ICookiesConfig` with `exposeTokenInBody` option |
|
|
46
|
+
| **Unified CORS** | Single `cors` config propagates to GraphQL, REST, and BetterAuth layers |
|
|
45
47
|
| **Dual Auth Modes** | IAM-Only (BetterAuth) or Legacy+IAM for migration periods |
|
|
46
48
|
|
|
47
49
|
### Authentication & Authorization
|
|
@@ -290,7 +292,25 @@ The following diagram shows the exact order of execution from HTTP request to re
|
|
|
290
292
|
+----------+----------+
|
|
291
293
|
|
|
|
292
294
|
+----------------------------v----------------------------+
|
|
293
|
-
|
|
|
295
|
+
| EXPRESS-LEVEL MIDDLEWARE |
|
|
296
|
+
| (registered in main.ts) |
|
|
297
|
+
| |
|
|
298
|
+
| 0a. cookie-parser [if cookies enabled, default: yes] |
|
|
299
|
+
| - Parses Cookie header into req.cookies |
|
|
300
|
+
| - Required for session cookie authentication |
|
|
301
|
+
| |
|
|
302
|
+
| 0b. compression [if configured] |
|
|
303
|
+
| - gzip response compression |
|
|
304
|
+
| |
|
|
305
|
+
| 0c. CORS [if not disabled] |
|
|
306
|
+
| - credentials: true when cookies enabled |
|
|
307
|
+
| - Origins from appUrl/baseUrl/cors.allowedOrigins |
|
|
308
|
+
| - Propagated to BetterAuth trustedOrigins |
|
|
309
|
+
+----------------------------+----------------------------+
|
|
310
|
+
|
|
|
311
|
+
+----------------------------v----------------------------+
|
|
312
|
+
| NESTJS MIDDLEWARE CHAIN |
|
|
313
|
+
| (registered in CoreModule.configure()) |
|
|
294
314
|
| |
|
|
295
315
|
| 1. RequestContextMiddleware |
|
|
296
316
|
| - AsyncLocalStorage context |
|
|
@@ -397,9 +417,45 @@ The following diagram shows the exact order of execution from HTTP request to re
|
|
|
397
417
|
|
|
398
418
|
## Phase 1: Incoming Request
|
|
399
419
|
|
|
400
|
-
### Middleware
|
|
420
|
+
### Express-Level Middleware (main.ts)
|
|
421
|
+
|
|
422
|
+
These run **before NestJS** processes the request. They are registered in the application bootstrap (`main.ts`), not in `CoreModule`:
|
|
401
423
|
|
|
402
|
-
|
|
424
|
+
#### 0a. cookie-parser
|
|
425
|
+
|
|
426
|
+
Parses the `Cookie` header into `req.cookies`. Loaded when cookies are enabled (default: `true` since v11.25.0).
|
|
427
|
+
|
|
428
|
+
```typescript
|
|
429
|
+
// main.ts
|
|
430
|
+
if (isCookiesEnabled(envConfig.cookies)) {
|
|
431
|
+
server.use(cookieParser());
|
|
432
|
+
}
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
Without `cookie-parser`, session cookie authentication in `CoreBetterAuthMiddleware` falls back to manual header parsing. With it, `req.cookies` is a parsed object — more reliable and required for signed cookie verification.
|
|
436
|
+
|
|
437
|
+
#### 0b. CORS
|
|
438
|
+
|
|
439
|
+
CORS headers are configured based on the unified `cors` config (since v11.25.0). The same origin list is propagated to GraphQL (Apollo), REST (Express), and BetterAuth (`trustedOrigins`).
|
|
440
|
+
|
|
441
|
+
```typescript
|
|
442
|
+
// main.ts — uses helpers from cookies.helper.ts
|
|
443
|
+
if (!isCorsDisabled(envConfig.cors)) {
|
|
444
|
+
server.enableCors({ credentials: cookiesEnabled, origin: resolvedOrigins });
|
|
445
|
+
}
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
| Config | REST (Express) | GraphQL (Apollo) | BetterAuth |
|
|
449
|
+
|--------|----------------|-------------------|------------|
|
|
450
|
+
| `cors: { allowAll: true }` | `origin: true` | `origin: true` | `trustedOrigins: undefined` |
|
|
451
|
+
| `cors: { allowedOrigins: [...] }` | `origin: [merged list]` | `origin: [merged list]` | `trustedOrigins: [merged list]` |
|
|
452
|
+
| `cors: { enabled: false }` | No CORS headers | No CORS headers | `trustedOrigins: []` |
|
|
453
|
+
|
|
454
|
+
> **Note:** GraphQL CORS is configured in `CoreModule.buildCorsConfig()` using raw config values. BetterAuth derives `trustedOrigins` using resolved URLs (auto-derived from `baseUrl`). In edge cases (no explicit `appUrl`), these may differ slightly. Set `appUrl` explicitly for consistent behavior across all layers.
|
|
455
|
+
|
|
456
|
+
### NestJS Middleware Chain (CoreModule)
|
|
457
|
+
|
|
458
|
+
NestJS middleware runs for every request after Express-level middleware. Registration happens in `CoreModule.configure()`:
|
|
403
459
|
|
|
404
460
|
```typescript
|
|
405
461
|
// src/core.module.ts
|
|
@@ -1194,6 +1250,25 @@ const request = gqlContext?.req || context.switchToHttp().getRequest();
|
|
|
1194
1250
|
|
|
1195
1251
|
All security features are configured in `config.env.ts` under the `security` key:
|
|
1196
1252
|
|
|
1253
|
+
### Cookies & CORS (since v11.25.0)
|
|
1254
|
+
|
|
1255
|
+
| Config Path | Type | Default | Description |
|
|
1256
|
+
|-------------|------|---------|-------------|
|
|
1257
|
+
| `cookies` | `boolean \| ICookiesConfig` | `true` | Enable cookie-parser and session cookies |
|
|
1258
|
+
| `cookies.exposeTokenInBody` | `boolean` | `false` | Keep token in response body alongside cookies |
|
|
1259
|
+
| `cors` | `boolean \| ICorsConfig` | `undefined` (enabled) | Unified CORS across GraphQL, REST, BetterAuth |
|
|
1260
|
+
| `cors.allowAll` | `boolean` | `false` | Allow all origins (mirrors request origin) |
|
|
1261
|
+
| `cors.allowedOrigins` | `string[]` | `[]` | Additional origins beyond appUrl/baseUrl |
|
|
1262
|
+
| `cors.enabled` | `boolean` | `true` | Enable/disable CORS on all layers |
|
|
1263
|
+
|
|
1264
|
+
**Cookie modes:**
|
|
1265
|
+
|
|
1266
|
+
| Mode | Config | Token in body | Cookie set | JWT via header |
|
|
1267
|
+
|------|--------|:---:|:---:|:---:|
|
|
1268
|
+
| Cookie-only (default) | `cookies: true` | No | Yes | Yes (always) |
|
|
1269
|
+
| JWT-only | `cookies: false` | Yes | No | Yes |
|
|
1270
|
+
| Hybrid | `cookies: { exposeTokenInBody: true }` | Yes | Yes | Yes |
|
|
1271
|
+
|
|
1197
1272
|
### Guardian Gates
|
|
1198
1273
|
|
|
1199
1274
|
| Config Path | Type | Default | Description |
|
|
@@ -0,0 +1,438 @@
|
|
|
1
|
+
# Migration Guide: 11.24.x → 11.25.0
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
| Category | Details |
|
|
6
|
+
|----------|---------|
|
|
7
|
+
| **Breaking Changes** | `cookies` default changed from `false` to `true`; secrets moved from `config.env.ts` to env vars; MongoDB URI no longer falls back to localhost in production |
|
|
8
|
+
| **New Features** | Unified CORS configuration (`cors`), configurable token exposure (`exposeTokenInBody`), Brevo transactional overlay via `BREVO_API_KEY`, Dockerfile HEALTHCHECK |
|
|
9
|
+
| **Security Fixes** | `secure` cookie flag now also honors app-level `env: 'staging'`; `cors: false` fully disables Apollo CORS (previously silently opened it); `cookieParser` signs with `betterAuth.secret` in IAM-only mode; JWT conversion now runs in hybrid cookie mode (previously skipped) |
|
|
10
|
+
| **Bugfixes** | Fixed inconsistency between nest-server and BetterAuth cookie defaults; fixed `resolveJwtToken` incorrectly skipping conversion when `exposeTokenInBody: true` |
|
|
11
|
+
| **Migration Effort** | 10–30 minutes (add env vars, review cookie/CORS behavior, update `.env`) |
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Quick Migration (If You Don't Want Cookies)
|
|
16
|
+
|
|
17
|
+
If your project was running without cookies and you want to keep it that way:
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
// config.env.ts — add cookies: false to your environment config
|
|
21
|
+
production: {
|
|
22
|
+
cookies: false, // Explicit opt-out (was the implicit default before 11.25.0)
|
|
23
|
+
// ... rest of config
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
If you want to adopt the new cookie default, no changes are needed — cookies are now enabled by default.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## What's New in 11.25.0
|
|
32
|
+
|
|
33
|
+
### 1. Cookies Enabled by Default
|
|
34
|
+
|
|
35
|
+
Cookies are now enabled by default, consistent with BetterAuth's existing behavior. This means:
|
|
36
|
+
|
|
37
|
+
- `cookie-parser` middleware is automatically loaded
|
|
38
|
+
- CORS is configured with `credentials: true`
|
|
39
|
+
- Session cookies are set on authentication responses
|
|
40
|
+
- JWT via `Authorization: Bearer` header continues to work independently
|
|
41
|
+
|
|
42
|
+
**Before (11.24.x):**
|
|
43
|
+
```typescript
|
|
44
|
+
// cookies was undefined → treated as false
|
|
45
|
+
// No cookie-parser, no CORS credentials
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
**After (11.25.0):**
|
|
49
|
+
```typescript
|
|
50
|
+
// cookies is undefined → treated as true (default)
|
|
51
|
+
// cookie-parser loaded, CORS with credentials: true
|
|
52
|
+
// To disable: cookies: false
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### 2. Cookie Configuration Object (`ICookiesConfig`)
|
|
56
|
+
|
|
57
|
+
The `cookies` property now accepts a configuration object (Boolean Shorthand Pattern):
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
// Boolean (same as before)
|
|
61
|
+
cookies: false // Disabled
|
|
62
|
+
cookies: true // Enabled (default)
|
|
63
|
+
|
|
64
|
+
// Object (new)
|
|
65
|
+
cookies: {
|
|
66
|
+
enabled: true, // Whether cookies are enabled (default: true)
|
|
67
|
+
exposeTokenInBody: true, // Keep token in response body alongside cookies (default: false)
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
#### `exposeTokenInBody` Option
|
|
72
|
+
|
|
73
|
+
By default, when cookies are enabled, the token is **removed from the response body** (the httpOnly cookie provides XSS protection — exposing the token in the body would negate this benefit).
|
|
74
|
+
|
|
75
|
+
Set `exposeTokenInBody: true` when clients need both JWT and cookies in parallel:
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
// Hybrid mode: JWT + Cookies
|
|
79
|
+
cookies: { exposeTokenInBody: true }
|
|
80
|
+
|
|
81
|
+
// Login response includes:
|
|
82
|
+
// Response Body: { token: "eyJ...", session: {...}, user: {...} }
|
|
83
|
+
// Set-Cookie: iam.session_token=signed_value
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### 3. Brevo Transactional API — Auto-Config via `BREVO_API_KEY`
|
|
87
|
+
|
|
88
|
+
The reference `config.env.ts` now auto-wires a `brevo` config block in `production`, `development`, and `local` environments when `BREVO_API_KEY` is set:
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
// Automatically added to config.env.ts (no manual brevo: { ... } needed)
|
|
92
|
+
...(process.env.BREVO_API_KEY
|
|
93
|
+
? {
|
|
94
|
+
brevo: {
|
|
95
|
+
apiKey: process.env.BREVO_API_KEY,
|
|
96
|
+
sender: { email: EMAIL_DEFAULT_SENDER, name: EMAIL_DEFAULT_SENDER_NAME },
|
|
97
|
+
},
|
|
98
|
+
}
|
|
99
|
+
: {})
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**How it integrates:** Brevo runs IN PARALLEL to SMTP. It is used only when a module explicitly references a `brevoTemplateId`:
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
// config.env.ts
|
|
106
|
+
betterAuth: {
|
|
107
|
+
emailVerification: {
|
|
108
|
+
brevoTemplateId: 123, // Uses Brevo Transactional API with server-side template
|
|
109
|
+
locale: 'de',
|
|
110
|
+
},
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
All other emails (password resets without a template, custom app mails, 2FA codes) continue to flow through the SMTP transport configured via `SMTP_HOST/PORT/USER/PASS`.
|
|
115
|
+
|
|
116
|
+
**Activation:**
|
|
117
|
+
```bash
|
|
118
|
+
# .env
|
|
119
|
+
BREVO_API_KEY=xkeysib-your-api-key
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
`ci` and `e2e` environments intentionally skip Brevo — tests never make external API calls.
|
|
123
|
+
|
|
124
|
+
### 4. Unified CORS Configuration (`ICorsConfig`)
|
|
125
|
+
|
|
126
|
+
A new `cors` property controls CORS across all three layers: GraphQL (Apollo), REST (Express), and BetterAuth (`trustedOrigins`).
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
// Allow all origins (development)
|
|
130
|
+
cors: { allowAll: true }
|
|
131
|
+
|
|
132
|
+
// Specific additional origins (production)
|
|
133
|
+
cors: { allowedOrigins: ['https://admin.example.com'] }
|
|
134
|
+
// Combined with appUrl and baseUrl automatically
|
|
135
|
+
|
|
136
|
+
// Disable CORS on all layers including BetterAuth
|
|
137
|
+
cors: { enabled: false }
|
|
138
|
+
|
|
139
|
+
// Environment variable support
|
|
140
|
+
cors: {
|
|
141
|
+
allowedOrigins: process.env.CORS_ALLOWED_ORIGINS?.split(',').filter(Boolean),
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
**Origin resolution priority:**
|
|
146
|
+
1. `cors.allowAll: true` → mirrors request origin (allows all)
|
|
147
|
+
2. `cors.allowedOrigins` + `appUrl` + `baseUrl` → deduplicated list
|
|
148
|
+
3. Only `appUrl`/`baseUrl` → those origins
|
|
149
|
+
4. Nothing configured → **no credentialed CORS** (secure default — same-origin requests still work; cross-origin browsers will fail the preflight). The legacy "allow all" fallback was removed in v11.25.0 because it combined with `credentials: true` would allow any website to perform credentialed requests. Configure `appUrl`/`baseUrl` or `cors.allowedOrigins` explicitly.
|
|
150
|
+
|
|
151
|
+
**BetterAuth integration:**
|
|
152
|
+
- `cors.allowAll` → BetterAuth `trustedOrigins` is set to `undefined` (allows all)
|
|
153
|
+
- `cors.allowedOrigins` → merged with `appUrl`/`baseUrl` for BetterAuth `trustedOrigins`
|
|
154
|
+
- `cors.enabled: false` → BetterAuth `trustedOrigins` set to `[]` (no origins allowed)
|
|
155
|
+
- Explicit `betterAuth.trustedOrigins` always takes precedence (backward compatible)
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## Breaking Changes
|
|
160
|
+
|
|
161
|
+
### Change 1: `cookies` Default from `false` to `true`
|
|
162
|
+
|
|
163
|
+
**Impact:** Projects that did not explicitly set `cookies` will now have cookie handling enabled.
|
|
164
|
+
|
|
165
|
+
**Symptoms if not addressed:**
|
|
166
|
+
- Session cookies will be set on authentication responses
|
|
167
|
+
- CORS will include `credentials: true`
|
|
168
|
+
- Tokens may be removed from response body (if your code reads `response.token`)
|
|
169
|
+
|
|
170
|
+
**Fix:**
|
|
171
|
+
```typescript
|
|
172
|
+
// config.env.ts — if you want to keep the old behavior
|
|
173
|
+
production: {
|
|
174
|
+
cookies: false, // Explicit opt-out
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// OR if you want cookies but need tokens in body
|
|
178
|
+
production: {
|
|
179
|
+
cookies: { exposeTokenInBody: true },
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Change 2: Hardcoded Secret Fallbacks Removed from Production Config
|
|
184
|
+
|
|
185
|
+
**Impact:** Most of these environment variables were already read in 11.24.x. What changed in 11.25.0 is that the **hardcoded fallback strings in the production block** (e.g. `'SECRET_OR_PRIVATE_KEY_LOCAL'`, `'mongodb://127.0.0.1/nest-server-prod'`) were removed. Production deployments that previously relied on the reference config without setting env vars will now fail fast at startup with a clearer misconfiguration signal instead of silently booting with insecure defaults.
|
|
186
|
+
|
|
187
|
+
- **No action needed** if you already set all required env vars in your `.env` / secret store.
|
|
188
|
+
- **Action required** if you depended on the reference-config fallbacks — add the listed variables to your production environment.
|
|
189
|
+
|
|
190
|
+
Test environments (`ci`/`e2e`/`local`/`development`) still use hardcoded fallback secrets so tests run without a `.env` file (see the dedicated warning section further below).
|
|
191
|
+
|
|
192
|
+
**Variables read from the environment in the production config block:**
|
|
193
|
+
|
|
194
|
+
| Config Path | Environment Variable | Notes |
|
|
195
|
+
|-------------|---------------------|-------|
|
|
196
|
+
| `mongoose.uri` | `MONGODB_URI` | Required in production (no fallback) |
|
|
197
|
+
| `baseUrl` | `BASE_URL` | Used for CORS / Passkey / email links / OAuth callbacks |
|
|
198
|
+
| `jwt.secret` | `JWT_SECRET` | Required only for Legacy Auth |
|
|
199
|
+
| `jwt.refresh.secret` | `JWT_REFRESH_SECRET` | Required only for Legacy Auth |
|
|
200
|
+
| `betterAuth.secret` | `BETTER_AUTH_SECRET` | Required, min. 32 chars |
|
|
201
|
+
| `email.defaultSender.email` | `EMAIL_DEFAULT_SENDER` | |
|
|
202
|
+
| `email.defaultSender.name` | `EMAIL_DEFAULT_SENDER_NAME` | Default: `"Nest Server"` |
|
|
203
|
+
| `email.smtp.host` | `SMTP_HOST` | |
|
|
204
|
+
| `email.smtp.port` | `SMTP_PORT` | Default: `587` |
|
|
205
|
+
| `email.smtp.secure` | `SMTP_SECURE` | Default: `true` |
|
|
206
|
+
| `email.smtp.auth.user` | `SMTP_USER` | |
|
|
207
|
+
| `email.smtp.auth.pass` | `SMTP_PASS` | |
|
|
208
|
+
| `cors.allowedOrigins` | `CORS_ALLOWED_ORIGINS` | Comma-separated |
|
|
209
|
+
| `brevo.apiKey` | `BREVO_API_KEY` | **NEW** — activates Brevo overlay automatically |
|
|
210
|
+
|
|
211
|
+
When `BREVO_API_KEY` is set, the production config auto-configures a `brevo` config block with sender derived from `EMAIL_DEFAULT_SENDER` / `EMAIL_DEFAULT_SENDER_NAME`. No manual `brevo: { ... }` in `config.env.ts` is required anymore.
|
|
212
|
+
|
|
213
|
+
**Removed from the reference config (still supported in `IServerOptions`):**
|
|
214
|
+
- `email.mailjet` — the `MailjetService` remains available; only the hardcoded reference-config entry was removed. If your project actively uses it, keep your `email.mailjet` block.
|
|
215
|
+
- `email.passwordResetLink` / `email.verificationLink` — removed from the reference config. Both keys are still accepted by `IServerOptions` and read from `ConfigService` at runtime; derive them from `baseUrl`/`appUrl` if you don't need deployment-specific overrides.
|
|
216
|
+
|
|
217
|
+
**Fix:** Update your `.env` file with the required variables. See `.env.example` in the repo root — it documents all variables (required ones uncommented, optional ones commented out), including SMTP baseline and the optional Brevo Transactional API overlay for template-based mails.
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
# Production .env
|
|
221
|
+
MONGODB_URI=mongodb://host:27017/my-app
|
|
222
|
+
BASE_URL=https://api.example.com
|
|
223
|
+
BETTER_AUTH_SECRET=<32+ char secret>
|
|
224
|
+
SMTP_HOST=smtp.example.com
|
|
225
|
+
SMTP_USER=user
|
|
226
|
+
SMTP_PASS=password
|
|
227
|
+
EMAIL_DEFAULT_SENDER=noreply@example.com
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
## Detailed Migration Steps
|
|
233
|
+
|
|
234
|
+
### Step 1: Update Package
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
pnpm install @lenne.tech/nest-server@11.25.0
|
|
238
|
+
|
|
239
|
+
# If package.json dependencies changed
|
|
240
|
+
pnpm run update
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Step 2: Decide on Cookie Strategy
|
|
244
|
+
|
|
245
|
+
| Strategy | Config | Use Case |
|
|
246
|
+
|----------|--------|----------|
|
|
247
|
+
| **Cookie-only** (new default) | No config needed | Web apps with browser-based auth |
|
|
248
|
+
| **JWT-only** (old default) | `cookies: false` | Mobile apps, pure API clients |
|
|
249
|
+
| **Hybrid** | `cookies: { exposeTokenInBody: true }` | Apps needing both JWT + cookies |
|
|
250
|
+
|
|
251
|
+
### Step 3: Configure CORS (Optional)
|
|
252
|
+
|
|
253
|
+
```typescript
|
|
254
|
+
// Production: restrict to specific origins
|
|
255
|
+
cors: {
|
|
256
|
+
allowedOrigins: process.env.CORS_ALLOWED_ORIGINS?.split(',').filter(Boolean),
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Development: allow all
|
|
260
|
+
cors: { allowAll: true }
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### Step 4: Verify Build and Tests
|
|
264
|
+
|
|
265
|
+
```bash
|
|
266
|
+
pnpm run build
|
|
267
|
+
pnpm test
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
## Compatibility Notes
|
|
273
|
+
|
|
274
|
+
### JWT Authentication
|
|
275
|
+
JWT via `Authorization: Bearer <token>` continues to work independently of cookie configuration. The middleware token priority remains:
|
|
276
|
+
1. Authorization header (JWT) → always processed first
|
|
277
|
+
2. JWT from cookie (`lt-jwt-token`) → fallback when no auth header
|
|
278
|
+
3. Session cookie → final fallback
|
|
279
|
+
|
|
280
|
+
### Existing `betterAuth.trustedOrigins`
|
|
281
|
+
If your project explicitly sets `betterAuth.trustedOrigins`, it takes precedence over the new `cors` configuration. No changes needed.
|
|
282
|
+
|
|
283
|
+
### Legacy Auth
|
|
284
|
+
The Legacy Auth controller and resolver also respect `exposeTokenInBody`. Both `token` and `refreshToken` are kept in the response body when `exposeTokenInBody: true`.
|
|
285
|
+
|
|
286
|
+
Legacy auth cookies (`token`, `refreshToken`) are now set with **secure defaults**:
|
|
287
|
+
- `httpOnly: true` (no JavaScript access — XSS mitigation)
|
|
288
|
+
- `sameSite: 'lax'` (CSRF mitigation)
|
|
289
|
+
- `secure: true` in production (HTTPS-only)
|
|
290
|
+
|
|
291
|
+
### `secure` Cookie Flag — Staging Coverage
|
|
292
|
+
|
|
293
|
+
Auth cookies' `secure` flag is now `true` when EITHER:
|
|
294
|
+
- `config.env === 'production'` or `config.env === 'staging'` (app-level), OR
|
|
295
|
+
- `process.env.NODE_ENV === 'production'` (runtime)
|
|
296
|
+
|
|
297
|
+
Previously only `NODE_ENV` was checked. Staging deployments that set `config.env: 'staging'` but forgot `NODE_ENV=production` were silently sending auth cookies over HTTP.
|
|
298
|
+
|
|
299
|
+
### Apollo GraphQL CORS — `cors: false` Now Fully Disables
|
|
300
|
+
|
|
301
|
+
In v11.24.x, setting `cors: false` passed `cors: {}` to Apollo, which Apollo interprets as "CORS with default origin behavior" (i.e. it sent CORS headers with `Access-Control-Allow-Origin: *`). The fix in v11.25.0 passes `cors: false` to Apollo directly, which fully disables Apollo's CORS handling. No backward-compatible workaround is possible — projects that relied on the old permissive behavior must now explicitly set `cors: { allowAll: true }` instead.
|
|
302
|
+
|
|
303
|
+
### `cookieParser` Signing Secret — Fallback Chain
|
|
304
|
+
|
|
305
|
+
`main.ts` now picks a signing secret for the `cookie-parser` middleware via a fallback chain:
|
|
306
|
+
|
|
307
|
+
1. `jwt.secret` (Legacy Auth)
|
|
308
|
+
2. `betterAuth.secret` (IAM-only mode)
|
|
309
|
+
3. Unsigned cookies (no secret anywhere)
|
|
310
|
+
|
|
311
|
+
IAM-only projects previously had `cookieParser()` called without a signing secret even though a `betterAuth.secret` was configured. Signed cookies (`req.signedCookies`) are now verifiable in IAM-only mode.
|
|
312
|
+
|
|
313
|
+
### Hybrid Mode JWT Conversion (`resolveJwtToken`)
|
|
314
|
+
|
|
315
|
+
`CoreBetterAuthService.resolveJwtToken()` now converts opaque session tokens to proper JWTs when BOTH:
|
|
316
|
+
- `cookies.exposeTokenInBody: true` (hybrid mode)
|
|
317
|
+
- `betterAuth.jwt.enabled: true`
|
|
318
|
+
|
|
319
|
+
In 11.24.x the conversion was unconditionally skipped as soon as cookies were enabled, which meant hybrid clients received an opaque session token in the body instead of the expected JWT. Pure JWT-only mode (`cookies: false`) and cookie-only mode (default) behave unchanged.
|
|
320
|
+
|
|
321
|
+
### Production Startup Guard for `exposeTokenInBody`
|
|
322
|
+
|
|
323
|
+
Since v11.25.0, the framework **throws at startup** if `cookies.exposeTokenInBody: true` is set in `production` or `staging` environments. This prevents accidental XSS-risk misconfiguration (the httpOnly cookie protection is negated when the token is also in the body). Test environments (`ci`, `e2e`, `development`, `local`) are unaffected.
|
|
324
|
+
|
|
325
|
+
If you need hybrid JWT+Cookie in production, keep `exposeTokenInBody: false` and use the separate `GET /iam/token` endpoint on the client to fetch a JWT on demand.
|
|
326
|
+
|
|
327
|
+
### Secret Fallbacks in Dev/CI/E2E Environments
|
|
328
|
+
|
|
329
|
+
The `ci`, `e2e`, `development`, and `local` environment configs use **hardcoded fallback secrets** (e.g., `'SECRET_OR_PRIVATE_KEY_LOCAL'`, `'BETTER_AUTH_SECRET_LOCAL_32_CHARS_M'`) so that tests run without a `.env` file. These values are **publicly visible in this repository**.
|
|
330
|
+
|
|
331
|
+
> **Warning:** Do NOT deploy to production with `NODE_ENV=development` (or `ci`/`e2e`/`local`) AND missing real secrets. Any attacker can forge JWTs signed with the public fallback key. In production, `NODE_ENV=production` MUST be set, and `BETTER_AUTH_SECRET`, `JWT_SECRET`, `JWT_REFRESH_SECRET` MUST come from environment variables (the production config has no fallbacks — missing values cause startup failure).
|
|
332
|
+
|
|
333
|
+
### Dockerfile HEALTHCHECK
|
|
334
|
+
|
|
335
|
+
v11.25.0 adds a `HEALTHCHECK` directive to the default `Dockerfile`:
|
|
336
|
+
|
|
337
|
+
```dockerfile
|
|
338
|
+
HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
|
|
339
|
+
CMD wget -qO- http://127.0.0.1:3000/health || exit 1
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
**Requirement:** The `/health` endpoint is provided by `HealthCheckModule`, which is enabled via `healthCheck` in `config.env.ts`. If your project disables it, Docker will keep reporting the container as `unhealthy` and orchestrators (Docker Swarm, Kubernetes readiness/liveness, docker-compose `depends_on.service.condition: service_healthy`) will refuse to route traffic or will restart the container.
|
|
343
|
+
|
|
344
|
+
**To enable:**
|
|
345
|
+
```typescript
|
|
346
|
+
// config.env.ts
|
|
347
|
+
production: {
|
|
348
|
+
healthCheck: {}, // Uses defaults — enables /health endpoint
|
|
349
|
+
// or opt out: healthCheck: false
|
|
350
|
+
}
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
**If you already had a custom Dockerfile:** The HEALTHCHECK is optional — remove the directive if your orchestrator performs its own probes.
|
|
354
|
+
|
|
355
|
+
### Deprecated: Static CoreModule Cookie Helpers
|
|
356
|
+
|
|
357
|
+
The static helpers `CoreModule.isCookiesEnabled()` and `CoreModule.isExposeTokenInBodyEnabled()` are now marked `@deprecated`. Use the standalone exports from the framework instead — they are framework-scoped (no `CoreModule` import), tree-shakeable, and consistent with the other helpers in `cookies.helper.ts`.
|
|
358
|
+
|
|
359
|
+
```typescript
|
|
360
|
+
// Before (11.24.x and earlier)
|
|
361
|
+
import { CoreModule } from '@lenne.tech/nest-server';
|
|
362
|
+
if (CoreModule.isCookiesEnabled(config.cookies)) { ... }
|
|
363
|
+
|
|
364
|
+
// After (11.25.0+)
|
|
365
|
+
import { isCookiesEnabled, isExposeTokenInBodyEnabled } from '@lenne.tech/nest-server';
|
|
366
|
+
if (isCookiesEnabled(config.cookies)) { ... }
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
Both static methods still work (they delegate internally) — they will be removed in a future MINOR release.
|
|
370
|
+
|
|
371
|
+
### MongoDB URI — No Production Fallback
|
|
372
|
+
|
|
373
|
+
Production config no longer falls back to `mongodb://127.0.0.1/nest-server-prod` when `MONGODB_URI` is unset. Starting the server without a valid `MONGODB_URI` in production will now fail fast. This prevents silent misconfiguration where the app would otherwise connect to an unintended local database.
|
|
374
|
+
|
|
375
|
+
---
|
|
376
|
+
|
|
377
|
+
## Troubleshooting
|
|
378
|
+
|
|
379
|
+
### Tokens missing from API responses
|
|
380
|
+
**Cause:** Cookies are now enabled by default, which removes tokens from the response body.
|
|
381
|
+
**Fix:** Set `cookies: { exposeTokenInBody: true }` or `cookies: false`.
|
|
382
|
+
|
|
383
|
+
### CORS errors in browser
|
|
384
|
+
**Cause:** CORS now includes `credentials: true` by default, which requires explicit origins.
|
|
385
|
+
**Fix:** Set `cors: { allowAll: true }` for development, or configure `cors.allowedOrigins` for production.
|
|
386
|
+
|
|
387
|
+
### Tests failing with "token is null"
|
|
388
|
+
**Cause:** Test environment needs `exposeTokenInBody: true` if tests read tokens from response body.
|
|
389
|
+
**Fix:** Set `cookies: { exposeTokenInBody: true }` in test/CI/E2E config.
|
|
390
|
+
|
|
391
|
+
### `Error: SECURITY: cookies.exposeTokenInBody must not be true in production or staging`
|
|
392
|
+
**Cause:** The new production safety guard — `exposeTokenInBody: true` is blocked in `production`/`staging` envs.
|
|
393
|
+
**Fix:** Either remove `exposeTokenInBody` from those env blocks, or use `GET /iam/token` on the client to fetch a JWT on demand.
|
|
394
|
+
|
|
395
|
+
### Hybrid client receives opaque session token instead of JWT
|
|
396
|
+
**Cause:** Fixed in 11.25.0 — `resolveJwtToken` previously skipped conversion whenever cookies were enabled.
|
|
397
|
+
**Fix:** Upgrading to 11.25.0 fixes this automatically. Ensure `betterAuth.jwt.enabled: true` is set.
|
|
398
|
+
|
|
399
|
+
### Container stays in `unhealthy` state
|
|
400
|
+
**Cause:** The new Dockerfile HEALTHCHECK probes `/health`, but `HealthCheckModule` is disabled.
|
|
401
|
+
**Fix:** Enable `healthCheck: {}` in your `config.env.ts`, or remove the `HEALTHCHECK` directive if you don't use it.
|
|
402
|
+
|
|
403
|
+
### MongoDB connection refused after upgrade in production
|
|
404
|
+
**Cause:** The production config no longer falls back to `mongodb://127.0.0.1/nest-server-prod` when `MONGODB_URI` is unset.
|
|
405
|
+
**Fix:** Set `MONGODB_URI` explicitly in your production `.env` / secret store.
|
|
406
|
+
|
|
407
|
+
---
|
|
408
|
+
|
|
409
|
+
## Module Documentation
|
|
410
|
+
|
|
411
|
+
### Core Module
|
|
412
|
+
- **Shared Helper (NEW):** [src/core/common/helpers/cookies.helper.ts](../src/core/common/helpers/cookies.helper.ts) — `isCookiesEnabled`, `isExposeTokenInBodyEnabled`, `isCorsDisabled`, `isProductionLikeEnv`, `getDefaultAuthCookieOptions`, `setLegacyAuthCookies`, `assertCookiesProductionSafe`, `buildCorsConfig`, `shouldConvertSessionTokenToJwt`
|
|
413
|
+
- **Core Module:** [src/core.module.ts](../src/core.module.ts) — `buildCorsConfig()` integration, `assertCookiesProductionSafe()` guard, deprecated static helpers
|
|
414
|
+
- **Interface:** [src/core/common/interfaces/server-options.interface.ts](../src/core/common/interfaces/server-options.interface.ts) — `ICookiesConfig`, `ICorsConfig`
|
|
415
|
+
- **Bootstrap:** [src/main.ts](../src/main.ts) — Conditional `cookieParser` with fallback chain, tri-case CORS logic
|
|
416
|
+
|
|
417
|
+
### BetterAuth Module
|
|
418
|
+
- **Config:** [src/core/modules/better-auth/better-auth.config.ts](../src/core/modules/better-auth/better-auth.config.ts) — `buildTrustedOrigins()` with `serverCorsConfig`
|
|
419
|
+
- **Cookie Helper:** [src/core/modules/better-auth/core-better-auth-cookie.helper.ts](../src/core/modules/better-auth/core-better-auth-cookie.helper.ts) — `exposeTokenInBody` parameter, `env` field for staging `secure` flag
|
|
420
|
+
- **Service:** [src/core/modules/better-auth/core-better-auth.service.ts](../src/core/modules/better-auth/core-better-auth.service.ts) — `resolveJwtToken()` hybrid-mode fix
|
|
421
|
+
- **Integration Checklist:** [src/core/modules/better-auth/INTEGRATION-CHECKLIST.md](../src/core/modules/better-auth/INTEGRATION-CHECKLIST.md)
|
|
422
|
+
|
|
423
|
+
### Legacy Auth Module
|
|
424
|
+
- **Controller:** [src/core/modules/auth/core-auth.controller.ts](../src/core/modules/auth/core-auth.controller.ts) — Updated `processCookies()`
|
|
425
|
+
- **Resolver:** [src/core/modules/auth/core-auth.resolver.ts](../src/core/modules/auth/core-auth.resolver.ts) — Updated `processCookies()`
|
|
426
|
+
|
|
427
|
+
### Infrastructure
|
|
428
|
+
- **Dockerfile:** [Dockerfile](../Dockerfile) — New `HEALTHCHECK` directive
|
|
429
|
+
- **Env Example:** [.env.example](../.env.example) — Consolidated (required + optional in one file)
|
|
430
|
+
- **Request Lifecycle:** [docs/REQUEST-LIFECYCLE.md](../docs/REQUEST-LIFECYCLE.md) — Express-middleware section documents `cookie-parser` and CORS ordering
|
|
431
|
+
- **API Reference:** [FRAMEWORK-API.md](../FRAMEWORK-API.md) — Auto-generated, includes `ICookiesConfig` + `ICorsConfig` field lists
|
|
432
|
+
|
|
433
|
+
---
|
|
434
|
+
|
|
435
|
+
## References
|
|
436
|
+
|
|
437
|
+
- [Configurable Features Pattern](./../.claude/rules/configurable-features.md)
|
|
438
|
+
- [nest-server-starter](https://github.com/lenneTech/nest-server-starter) (reference implementation)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lenne.tech/nest-server",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.25.1",
|
|
4
4
|
"description": "Modern, fast, powerful Node.js web framework in TypeScript based on Nest with a GraphQL API and a connection to MongoDB (or other databases).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"node",
|
|
@@ -79,17 +79,17 @@
|
|
|
79
79
|
"@better-auth/passkey": "1.5.5",
|
|
80
80
|
"@getbrevo/brevo": "3.0.1",
|
|
81
81
|
"@nestjs/apollo": "13.2.5",
|
|
82
|
-
"@nestjs/common": "11.1.
|
|
83
|
-
"@nestjs/core": "11.1.
|
|
82
|
+
"@nestjs/common": "11.1.19",
|
|
83
|
+
"@nestjs/core": "11.1.19",
|
|
84
84
|
"@nestjs/graphql": "13.2.5",
|
|
85
85
|
"@nestjs/jwt": "11.0.2",
|
|
86
86
|
"@nestjs/mongoose": "11.0.4",
|
|
87
87
|
"@nestjs/passport": "11.0.5",
|
|
88
|
-
"@nestjs/platform-express": "11.1.
|
|
89
|
-
"@nestjs/schedule": "6.1.
|
|
90
|
-
"@nestjs/swagger": "11.
|
|
88
|
+
"@nestjs/platform-express": "11.1.19",
|
|
89
|
+
"@nestjs/schedule": "6.1.3",
|
|
90
|
+
"@nestjs/swagger": "11.3.0",
|
|
91
91
|
"@nestjs/terminus": "11.1.1",
|
|
92
|
-
"@nestjs/websockets": "11.1.
|
|
92
|
+
"@nestjs/websockets": "11.1.19",
|
|
93
93
|
"@tus/file-store": "2.0.0",
|
|
94
94
|
"@tus/server": "2.3.0",
|
|
95
95
|
"@types/supertest": "7.2.0",
|
|
@@ -99,8 +99,8 @@
|
|
|
99
99
|
"class-validator": "0.15.1",
|
|
100
100
|
"compression": "1.8.1",
|
|
101
101
|
"cookie-parser": "1.4.7",
|
|
102
|
-
"dotenv": "17.4.
|
|
103
|
-
"ejs": "5.0.
|
|
102
|
+
"dotenv": "17.4.2",
|
|
103
|
+
"ejs": "5.0.2",
|
|
104
104
|
"express": "5.2.1",
|
|
105
105
|
"graphql": "16.13.2",
|
|
106
106
|
"graphql-query-complexity": "1.1.0",
|
|
@@ -125,11 +125,11 @@
|
|
|
125
125
|
},
|
|
126
126
|
"devDependencies": {
|
|
127
127
|
"@compodoc/compodoc": "1.2.1",
|
|
128
|
-
"@nestjs/cli": "11.0.
|
|
129
|
-
"@nestjs/schematics": "11.0
|
|
130
|
-
"@nestjs/testing": "11.1.
|
|
128
|
+
"@nestjs/cli": "11.0.21",
|
|
129
|
+
"@nestjs/schematics": "11.1.0",
|
|
130
|
+
"@nestjs/testing": "11.1.19",
|
|
131
131
|
"@swc/cli": "0.8.1",
|
|
132
|
-
"@swc/core": "1.15.
|
|
132
|
+
"@swc/core": "1.15.26",
|
|
133
133
|
"@types/compression": "1.8.1",
|
|
134
134
|
"@types/cookie-parser": "1.4.10",
|
|
135
135
|
"@types/ejs": "3.1.5",
|
|
@@ -147,8 +147,8 @@
|
|
|
147
147
|
"nodemon": "3.1.14",
|
|
148
148
|
"npm-watch": "0.13.0",
|
|
149
149
|
"otpauth": "9.5.0",
|
|
150
|
-
"oxfmt": "0.
|
|
151
|
-
"oxlint": "1.
|
|
150
|
+
"oxfmt": "0.45.0",
|
|
151
|
+
"oxlint": "1.60.0",
|
|
152
152
|
"rimraf": "6.1.3",
|
|
153
153
|
"ts-node": "10.9.2",
|
|
154
154
|
"tsconfig-paths": "4.2.0",
|
|
@@ -188,7 +188,7 @@
|
|
|
188
188
|
"minimatch@>=10.0.0 <10.2.5": "Security: RegExp DoS - transitive via @nestjs/apollo>ts-morph>@ts-morph/common and nodemon",
|
|
189
189
|
"ajv@<6.14.0": "Security: prototype pollution - transitive via @getbrevo/brevo>rewire>eslint",
|
|
190
190
|
"ajv@>=7.0.0-alpha.0 <8.18.0": "Security: prototype pollution - transitive via @nestjs/cli>@angular-devkit",
|
|
191
|
-
"undici@>=7.0.0 <7.
|
|
191
|
+
"undici@>=7.0.0 <7.25.0": "Security: various CVEs - transitive via @compodoc/compodoc>cheerio",
|
|
192
192
|
"srvx@<0.11.15": "Compatibility: @tus/server@2.3.0 requires ~0.8.2 but 0.11.15 needed for security - remove when @tus/server ships with >=0.11.15",
|
|
193
193
|
"handlebars@>=4.0.0 <4.7.9": "Security: prototype pollution (GHSA-q42p-pg8m-cqh6) - transitive via @compodoc/compodoc",
|
|
194
194
|
"brace-expansion@<1.1.13": "Security: RegExp DoS - transitive via eslint>minimatch",
|
|
@@ -196,9 +196,10 @@
|
|
|
196
196
|
"picomatch@<2.3.2": "Security: ReDoS - transitive via @nestjs/graphql>fast-glob>micromatch and @compodoc/compodoc>chokidar",
|
|
197
197
|
"picomatch@>=4.0.0 <4.0.4": "Security: ReDoS - transitive via vitest and vite",
|
|
198
198
|
"path-to-regexp@>=8.0.0 <8.4.2": "Security: ReDoS (GHSA-rhx6-c78j-4q9w) - transitive via express>router",
|
|
199
|
-
"kysely@>=0.26.0 <0.28.
|
|
199
|
+
"kysely@>=0.26.0 <0.28.16": "Security: SQL injection - transitive via better-auth",
|
|
200
200
|
"lodash@>=4.0.0 <4.18.0": "Security: CVE in lodash@4.17.x - transitive via @nestjs/graphql. 4.18.1 is the latest patched version",
|
|
201
|
-
"defu@<=6.1.6": "Security: prototype pollution via __proto__ key - transitive via better-auth"
|
|
201
|
+
"defu@<=6.1.6": "Security: prototype pollution via __proto__ key - transitive via better-auth",
|
|
202
|
+
"follow-redirects@<=1.15.11": "Security: Custom Authentication Headers leak on cross-domain redirect (GHSA-r4q5-vmmm-2653) - transitive via axios>@getbrevo/brevo and axios>node-mailjet"
|
|
202
203
|
},
|
|
203
204
|
"overrides": {
|
|
204
205
|
"axios@<1.15.0": "1.15.0",
|
|
@@ -207,7 +208,7 @@
|
|
|
207
208
|
"minimatch@>=10.0.0 <10.2.5": "10.2.5",
|
|
208
209
|
"ajv@<6.14.0": "6.14.0",
|
|
209
210
|
"ajv@>=7.0.0-alpha.0 <8.18.0": "8.18.0",
|
|
210
|
-
"undici@>=7.0.0 <7.
|
|
211
|
+
"undici@>=7.0.0 <7.25.0": "7.25.0",
|
|
211
212
|
"srvx@<0.11.15": "0.11.15",
|
|
212
213
|
"handlebars@>=4.0.0 <4.7.9": "4.7.9",
|
|
213
214
|
"brace-expansion@<1.1.13": "1.1.13",
|
|
@@ -215,9 +216,10 @@
|
|
|
215
216
|
"picomatch@<2.3.2": "2.3.2",
|
|
216
217
|
"picomatch@>=4.0.0 <4.0.4": "4.0.4",
|
|
217
218
|
"path-to-regexp@>=8.0.0 <8.4.2": "8.4.2",
|
|
218
|
-
"kysely@>=0.26.0 <0.28.
|
|
219
|
+
"kysely@>=0.26.0 <0.28.16": "0.28.16",
|
|
219
220
|
"lodash@>=4.0.0 <4.18.0": "4.18.1",
|
|
220
|
-
"defu@<=6.1.6": "6.1.7"
|
|
221
|
+
"defu@<=6.1.6": "6.1.7",
|
|
222
|
+
"follow-redirects@<=1.15.11": "1.16.0"
|
|
221
223
|
},
|
|
222
224
|
"onlyBuiltDependencies": [
|
|
223
225
|
"bcrypt",
|