@lenne.tech/nest-server 11.21.3 → 11.22.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.
Files changed (57) hide show
  1. package/.claude/rules/architecture.md +79 -0
  2. package/.claude/rules/better-auth.md +262 -0
  3. package/.claude/rules/configurable-features.md +308 -0
  4. package/.claude/rules/core-modules.md +205 -0
  5. package/.claude/rules/framework-compatibility.md +79 -0
  6. package/.claude/rules/migration-guides.md +149 -0
  7. package/.claude/rules/module-deprecation.md +214 -0
  8. package/.claude/rules/module-inheritance.md +97 -0
  9. package/.claude/rules/package-management.md +112 -0
  10. package/.claude/rules/role-system.md +146 -0
  11. package/.claude/rules/testing.md +120 -0
  12. package/.claude/rules/versioning.md +53 -0
  13. package/CLAUDE.md +174 -0
  14. package/FRAMEWORK-API.md +231 -0
  15. package/dist/core/common/interfaces/server-options.interface.d.ts +10 -0
  16. package/dist/core/modules/error-code/error-code.module.js.map +1 -1
  17. package/dist/core.module.d.ts +3 -3
  18. package/dist/core.module.js +17 -4
  19. package/dist/core.module.js.map +1 -1
  20. package/dist/server/modules/file/file-info.model.d.ts +1 -5
  21. package/dist/server/modules/user/user.model.d.ts +1 -5
  22. package/dist/server/server.module.js +6 -6
  23. package/dist/server/server.module.js.map +1 -1
  24. package/dist/tsconfig.build.tsbuildinfo +1 -1
  25. package/docs/REQUEST-LIFECYCLE.md +1256 -0
  26. package/docs/error-codes.md +446 -0
  27. package/migration-guides/11.10.x-to-11.11.x.md +266 -0
  28. package/migration-guides/11.11.x-to-11.12.x.md +323 -0
  29. package/migration-guides/11.12.x-to-11.13.0.md +612 -0
  30. package/migration-guides/11.13.x-to-11.14.0.md +348 -0
  31. package/migration-guides/11.14.x-to-11.15.0.md +262 -0
  32. package/migration-guides/11.15.0-to-11.15.3.md +118 -0
  33. package/migration-guides/11.15.x-to-11.16.0.md +497 -0
  34. package/migration-guides/11.16.x-to-11.17.0.md +130 -0
  35. package/migration-guides/11.17.x-to-11.18.0.md +393 -0
  36. package/migration-guides/11.18.x-to-11.19.0.md +151 -0
  37. package/migration-guides/11.19.x-to-11.20.0.md +170 -0
  38. package/migration-guides/11.20.x-to-11.21.0.md +216 -0
  39. package/migration-guides/11.21.0-to-11.21.1.md +194 -0
  40. package/migration-guides/11.21.1-to-11.21.2.md +114 -0
  41. package/migration-guides/11.21.2-to-11.21.3.md +175 -0
  42. package/migration-guides/11.21.x-to-11.22.0.md +224 -0
  43. package/migration-guides/11.22.0-to-11.22.1.md +105 -0
  44. package/migration-guides/11.3.x-to-11.4.x.md +233 -0
  45. package/migration-guides/11.6.x-to-11.7.x.md +394 -0
  46. package/migration-guides/11.7.x-to-11.8.x.md +318 -0
  47. package/migration-guides/11.8.x-to-11.9.x.md +322 -0
  48. package/migration-guides/11.9.x-to-11.10.x.md +571 -0
  49. package/migration-guides/TEMPLATE.md +113 -0
  50. package/package.json +25 -18
  51. package/src/core/common/interfaces/server-options.interface.ts +83 -16
  52. package/src/core/modules/better-auth/CUSTOMIZATION.md +24 -17
  53. package/src/core/modules/better-auth/INTEGRATION-CHECKLIST.md +5 -5
  54. package/src/core/modules/error-code/INTEGRATION-CHECKLIST.md +42 -12
  55. package/src/core/modules/error-code/error-code.module.ts +4 -9
  56. package/src/core.module.ts +52 -10
  57. package/src/server/server.module.ts +7 -9
@@ -0,0 +1,571 @@
1
+ # Migration Guide: 11.9.x → 11.10.x
2
+
3
+ ## Overview
4
+
5
+ | Category | Details |
6
+ |----------|---------|
7
+ | **Breaking Changes** | None (trustedOrigins now auto-detected from baseUrl) |
8
+ | **New Features** | **Zero-Config Passkey**, URL Auto-Detection, Database Challenge Storage (JWT mode), Logging helpers, BetterAuthTokenService, Secure-by-Default RolesGuard, RolesGuardRegistry |
9
+ | **Bugfixes** | Session token forwarding, RolesGuard enforcement in IAM-only mode |
10
+ | **Migration Effort** | Very Low (~5 minutes) - Most projects need no changes |
11
+
12
+ ---
13
+
14
+ ## Quick Migration
15
+
16
+ ### All Projects
17
+
18
+ ```bash
19
+ # Update package
20
+ npm install @lenne.tech/nest-server@11.10.x
21
+
22
+ # Verify build
23
+ npm run build
24
+
25
+ # Run tests
26
+ npm test
27
+ ```
28
+
29
+ **That's it!** Most projects need no code changes due to Zero-Config improvements.
30
+
31
+ ### New in 11.10.3: Zero-Config Passkey
32
+
33
+ Passkey now works without explicit configuration! URL auto-detection makes setup much simpler:
34
+
35
+ ```typescript
36
+ // config.env.ts - BEFORE (11.10.0-11.10.2)
37
+ betterAuth: {
38
+ passkey: true,
39
+ trustedOrigins: ['http://localhost:3001'], // Was required
40
+ }
41
+
42
+ // config.env.ts - AFTER (11.10.3) - Zero-Config!
43
+ // Option 1: Use env: 'local' for development (auto: API=:3000, App=:3001)
44
+ const config = {
45
+ env: 'local', // Passkey auto-activated with localhost defaults
46
+ };
47
+
48
+ // Option 2: Set root-level baseUrl for production
49
+ const config = {
50
+ baseUrl: 'https://api.example.com', // Auto-detects appUrl, rpId, trustedOrigins
51
+ env: 'production',
52
+ };
53
+ ```
54
+
55
+ ### IAM-only Projects (No Changes Required)
56
+
57
+ If you use the 1-parameter `CoreModule.forRoot(environment)` signature (IAM-only, no Legacy Auth), **no changes are required**. Since **11.10.3**, `registerRolesGuardGlobally` defaults to `true`, ensuring `@Roles()` decorators work automatically.
58
+
59
+ ```typescript
60
+ // server.module.ts - RolesGuard is registered automatically!
61
+ CoreBetterAuthModule.forRoot({
62
+ config: environment.betterAuth,
63
+ // registerRolesGuardGlobally: true // Now the default! No need to specify.
64
+ })
65
+ ```
66
+
67
+ **Note:** Projects upgrading from 11.10.0-11.10.2 that already have `registerRolesGuardGlobally: true` can keep or remove it - the behavior is unchanged.
68
+
69
+ ---
70
+
71
+ ## What's New in 11.10.x
72
+
73
+ ### 1. Zero-Config Passkey with URL Auto-Detection (11.10.3)
74
+
75
+ **All three plugins (JWT, 2FA, Passkey) are now enabled by default!**
76
+
77
+ Passkey configuration is now automatically derived from your server configuration:
78
+
79
+ | Config Source | `baseUrl` (API) | `appUrl` (Frontend) | Passkey |
80
+ |---------------|-----------------|---------------------|---------|
81
+ | `env: 'local'/'ci'/'e2e'` | `http://localhost:3000` | `http://localhost:3001` | ✅ auto |
82
+ | Root-level `baseUrl` set | as configured | derived (removes `api.` prefix) | ✅ auto |
83
+ | Neither set | - | - | ⚠️ disabled (warning) |
84
+
85
+ **URL Auto-Detection Logic:**
86
+ 1. `appUrl` is derived from `baseUrl` by removing `api.` prefix (e.g., `api.example.com` → `example.com`)
87
+ 2. `rpId` is extracted from `appUrl` hostname (e.g., `example.com`)
88
+ 3. `origin` = `appUrl` (e.g., `https://example.com`)
89
+ 4. `trustedOrigins` = `[appUrl]`
90
+
91
+ ```typescript
92
+ // RECOMMENDED: Set root-level baseUrl
93
+ const config = {
94
+ baseUrl: 'https://api.example.com', // Passkey values auto-detected
95
+ env: 'production',
96
+ };
97
+ // Auto-detected: rpId='example.com', origin='https://example.com', trustedOrigins=['https://example.com']
98
+
99
+ // For development: Use env: 'local'
100
+ const config = {
101
+ env: 'local', // Uses localhost:3000 (API), localhost:3001 (App)
102
+ };
103
+ ```
104
+
105
+ **Graceful Degradation:** If URLs cannot be resolved, Passkey is disabled with a warning - other auth methods continue to work.
106
+
107
+ ### 2. Database Challenge Storage for JWT Mode (11.10.3)
108
+
109
+ New `CoreBetterAuthChallengeService` enables Passkey authentication in **cookieless/JWT mode**.
110
+
111
+ **Problem:** Better-Auth's Passkey plugin uses cookies to store WebAuthn challenges. This doesn't work with JWT-based APIs.
112
+
113
+ **Solution:** An adapter pattern bridges the gap:
114
+ 1. On `generate-options`: Extract Better-Auth's `verificationToken` from Set-Cookie, store mapping in MongoDB
115
+ 2. Return `challengeId` to client (not the verificationToken for security)
116
+ 3. On `verify`: Client sends `challengeId`, we inject `verificationToken` as cookie for Better-Auth
117
+
118
+ **Security measures:**
119
+ - 256-bit entropy challenge IDs (`crypto.randomBytes(32)`)
120
+ - TTL-based MongoDB index for automatic cleanup
121
+ - One-time use (deleted after verification)
122
+ - User binding (challenges tied to specific user)
123
+
124
+ **Client-side usage (JWT mode):**
125
+ ```typescript
126
+ // Use composable methods which handle challengeId automatically
127
+ const { authenticateWithPasskey, registerPasskey } = useBetterAuth();
128
+
129
+ // Authentication
130
+ const result = await authenticateWithPasskey();
131
+
132
+ // Registration
133
+ const result = await registerPasskey('My Device');
134
+ ```
135
+
136
+ ### 3. TypeScript Compile-Time Validation for Passkey CORS (11.10.0)
137
+
138
+ The `IBetterAuth` type enforces `trustedOrigins` when Passkey is enabled. **Note:** With URL auto-detection in 11.10.3, this is automatically handled.
139
+
140
+ ### 2. Logging Helper for Secure Logging
141
+
142
+ New helper functions for safely logging sensitive data (GDPR compliant):
143
+
144
+ ```typescript
145
+ import { maskToken, maskEmail, maskCookieHeader, isProduction } from '@lenne.tech/nest-server';
146
+
147
+ // Mask tokens: 'abc123xyz789' → 'abc1...9789'
148
+ this.logger.debug(`Token: ${maskToken(token)}`);
149
+
150
+ // Mask emails: 'john.doe@example.com' → 'jo***@example.com'
151
+ this.logger.debug(`User: ${maskEmail(user.email)}`);
152
+
153
+ // Mask cookie headers: 'session=abc123; token=xyz' → 'session=***; token=***'
154
+ this.logger.debug(`Cookies: ${maskCookieHeader(req.headers.cookie)}`);
155
+
156
+ // Conditional logging for non-production only
157
+ if (!isProduction()) {
158
+ this.logger.debug('Debug info...');
159
+ }
160
+ ```
161
+
162
+ ### 3. Improved Session Lookup Performance
163
+
164
+ The `getSessionByToken()` method now uses a MongoDB aggregation pipeline for single-query session+user lookup, improving performance and handling both ObjectId and string userId formats automatically.
165
+
166
+ ### 4. Enhanced Cookie Handling for Plugin Compatibility
167
+
168
+ Session tokens are now set in multiple cookies to ensure compatibility with Better Auth plugins (especially Passkey):
169
+
170
+ | Cookie | Purpose |
171
+ |--------|---------|
172
+ | `token` | nest-server compatibility |
173
+ | `{basePath}.session_token` | Better Auth native (e.g., `iam.session_token`) |
174
+ | `better-auth.session_token` | Legacy Better Auth |
175
+
176
+ ### 5. Native Better Auth Plugin Endpoints
177
+
178
+ 2FA and Passkey endpoints now use Better Auth's native plugin handlers, providing more features:
179
+
180
+ **Two-Factor Authentication (2FA):**
181
+
182
+ | Endpoint | Method | Description |
183
+ |----------|--------|-------------|
184
+ | `/iam/two-factor/enable` | POST | Enable 2FA, get TOTP URI |
185
+ | `/iam/two-factor/disable` | POST | Disable 2FA |
186
+ | `/iam/two-factor/verify-totp` | POST | Verify TOTP code |
187
+ | `/iam/two-factor/generate-backup-codes` | POST | Generate backup codes |
188
+ | `/iam/two-factor/verify-backup-code` | POST | Verify backup code |
189
+
190
+ **Passkey (WebAuthn):**
191
+
192
+ | Endpoint | Method | Description |
193
+ |----------|--------|-------------|
194
+ | `/iam/passkey/generate-register-options` | POST | Get WebAuthn registration options |
195
+ | `/iam/passkey/verify-registration` | POST | Verify and store passkey |
196
+ | `/iam/passkey/generate-authenticate-options` | POST | Get WebAuthn authentication options |
197
+ | `/iam/passkey/verify-authentication` | POST | Verify passkey authentication |
198
+ | `/iam/passkey/list-user-passkeys` | POST | List user's passkeys |
199
+ | `/iam/passkey/delete-passkey` | POST | Delete a passkey |
200
+ | `/iam/passkey/update-passkey` | POST | Update passkey name |
201
+
202
+ ### 6. BetterAuthTokenService
203
+
204
+ New centralized service for token extraction and user loading in BetterAuth authentication.
205
+
206
+ **What the service provides:**
207
+ - Token extraction from Authorization header or cookies
208
+ - JWT token verification via BetterAuth
209
+ - Session token verification via database lookup
210
+ - User loading from MongoDB with `hasRole()` capability
211
+
212
+ **Benefits:**
213
+ - Consolidates token verification logic that was previously duplicated in AuthGuard and RolesGuard
214
+ - Lazy resolution: Guards use `ModuleRef.get()` with `{ strict: false }` for optional dependencies
215
+ - Improved testability and maintainability
216
+
217
+ ```typescript
218
+ import { BetterAuthTokenService } from '@lenne.tech/nest-server';
219
+
220
+ // In a guard or service
221
+ const { token, source } = this.tokenService.extractTokenFromRequest(request);
222
+ if (token) {
223
+ const user = await this.tokenService.verifyAndLoadUser(token);
224
+ if (user) {
225
+ request.user = user;
226
+ }
227
+ }
228
+ ```
229
+
230
+ ### 7. Secure-by-Default RolesGuard (11.10.3)
231
+
232
+ The `registerRolesGuardGlobally` option now defaults to `true` for security-by-default behavior.
233
+
234
+ **Problem (11.10.0-11.10.2):**
235
+ In IAM-only setups, `@Roles()` decorators were not enforced unless `registerRolesGuardGlobally: true` was explicitly set.
236
+
237
+ **Solution (11.10.3+):**
238
+ ```typescript
239
+ // server.module.ts - IAM-only Setup
240
+ @Module({
241
+ imports: [
242
+ CoreModule.forRoot(environment), // 1-parameter signature = IAM-only
243
+ CoreBetterAuthModule.forRoot({
244
+ config: environment.betterAuth,
245
+ // registerRolesGuardGlobally defaults to true - @Roles() decorators work automatically!
246
+ }),
247
+ ],
248
+ })
249
+ export class ServerModule {}
250
+ ```
251
+
252
+ **Behavior:**
253
+ - `registerRolesGuardGlobally: true` (default) - RolesGuard registered globally, `@Roles()` enforced
254
+ - `registerRolesGuardGlobally: false` - Explicit opt-out (shows security warning if no other guard registered)
255
+
256
+ **RolesGuardRegistry (Advanced):**
257
+
258
+ A shared `RolesGuardRegistry` prevents duplicate registrations when both CoreAuthModule (Legacy) and CoreBetterAuthModule (IAM) are used together:
259
+
260
+ ```typescript
261
+ import { RolesGuardRegistry } from '@lenne.tech/nest-server';
262
+
263
+ // Check if RolesGuard is already registered
264
+ if (RolesGuardRegistry.isRegistered()) {
265
+ console.log(`Registered by: ${RolesGuardRegistry.getRegisteredBy()}`);
266
+ }
267
+ ```
268
+
269
+ **Security Warning:**
270
+
271
+ If `registerRolesGuardGlobally: false` is explicitly set and no other guard is registered, a warning is logged:
272
+
273
+ ```
274
+ ⚠️ SECURITY WARNING: registerRolesGuardGlobally is explicitly set to false,
275
+ but no RolesGuard is registered globally. @Roles() decorators will NOT enforce access control!
276
+ ```
277
+
278
+ ---
279
+
280
+ ## Breaking Changes
281
+
282
+ ### No Breaking Changes in 11.10.3
283
+
284
+ With URL auto-detection, the previous requirement for explicit `trustedOrigins` is now resolved automatically.
285
+
286
+ **For 11.10.0-11.10.2 users:** The TypeScript requirement for `trustedOrigins` with Passkey is now handled by auto-detection. You can simplify your config:
287
+
288
+ **Before (11.10.0-11.10.2):**
289
+ ```typescript
290
+ betterAuth: {
291
+ passkey: true,
292
+ trustedOrigins: ['http://localhost:3001'], // Was required
293
+ }
294
+ ```
295
+
296
+ **After (11.10.3) - Zero-Config:**
297
+ ```typescript
298
+ // Just set env: 'local' or root-level baseUrl - trustedOrigins auto-detected!
299
+ const config = {
300
+ env: 'local',
301
+ // Passkey works automatically!
302
+ };
303
+ ```
304
+
305
+ ### Historical: `trustedOrigins` Requirement (11.10.0-11.10.2)
306
+
307
+ **Note:** This was resolved in 11.10.3 with URL auto-detection.
308
+
309
+ **Before (11.9.x):**
310
+ ```typescript
311
+ betterAuth: {
312
+ passkey: true,
313
+ // trustedOrigins was optional (caused runtime CORS errors)
314
+ }
315
+ ```
316
+
317
+ **In 11.10.0-11.10.2:**
318
+ ```typescript
319
+ betterAuth: {
320
+ passkey: true,
321
+ trustedOrigins: ['http://localhost:3001', 'https://app.example.com'],
322
+ }
323
+ ```
324
+
325
+ ### 2. 2FA Endpoint Changes
326
+
327
+ **Impact:** Projects calling 2FA endpoints directly
328
+
329
+ The endpoint for verifying TOTP codes changed:
330
+
331
+ | Before (11.9.x) | After (11.10.x) |
332
+ |-----------------|-----------------|
333
+ | `POST /iam/two-factor/verify` | `POST /iam/two-factor/verify-totp` |
334
+
335
+ Additionally, new endpoints are available for backup codes.
336
+
337
+ ---
338
+
339
+ ## Bugfixes
340
+
341
+ ### 2FA Session Token Cookie Handling
342
+
343
+ **Fixed Issue:** When signing in with 2FA enabled, the temporary session token was not being set as a cookie. This caused the 2FA verification step (`/iam/two-factor/verify-totp`) to fail with 401 Unauthorized because the browser couldn't authenticate the request.
344
+
345
+ **What was happening:**
346
+ 1. User signs in with email/password
347
+ 2. Server returns `requiresTwoFactor: true` but no cookie was set
348
+ 3. User enters TOTP code
349
+ 4. Request fails because there's no session token to identify the 2FA flow
350
+
351
+ **What's fixed:**
352
+ 1. User signs in with email/password
353
+ 2. Server returns `requiresTwoFactor: true` AND sets the temporary session token as a cookie
354
+ 3. User enters TOTP code
355
+ 4. Browser automatically sends the session cookie → verification succeeds
356
+
357
+ **No action required** - this is a bugfix that improves 2FA functionality without requiring any code changes.
358
+
359
+ ### RolesGuard Enforcement in IAM-only Mode
360
+
361
+ **Fixed Issue:** In IAM-only setups (CoreModule.forRoot with 1 parameter), `@Roles()` decorators were not automatically enforced because the RolesGuard was not globally registered.
362
+
363
+ **Symptom:** Endpoints with `@Roles(RoleEnum.ADMIN)` were accessible without authentication.
364
+
365
+ **Cause:** CoreAuthModule (which globally registers the RolesGuard) is not imported in IAM-only setups.
366
+
367
+ **Solution (11.10.3+):** `registerRolesGuardGlobally` now defaults to `true`. **No action required** - `@Roles()` decorators are automatically enforced.
368
+
369
+ ```typescript
370
+ // Works automatically in 11.10.3+
371
+ CoreBetterAuthModule.forRoot({
372
+ config: environment.betterAuth,
373
+ // registerRolesGuardGlobally defaults to true
374
+ })
375
+ ```
376
+
377
+ **Note:** Projects upgrading from 11.10.0-11.10.2 that already have `registerRolesGuardGlobally: true` can keep or remove it.
378
+
379
+ ---
380
+
381
+ ## Detailed Migration Steps
382
+
383
+ ### Step 1: Update Package
384
+
385
+ ```bash
386
+ npm install @lenne.tech/nest-server@11.10.x
387
+ ```
388
+
389
+ ### Step 2: Add trustedOrigins (If Using Passkey)
390
+
391
+ If you have `passkey: true` in your config, add `trustedOrigins`:
392
+
393
+ ```typescript
394
+ // config.env.ts
395
+ betterAuth: {
396
+ passkey: true,
397
+ trustedOrigins: [
398
+ 'http://localhost:3001', // Development frontend
399
+ 'https://app.example.com', // Production frontend
400
+ ],
401
+ }
402
+ ```
403
+
404
+ ### Step 3: Update 2FA API Calls (If Using 2FA)
405
+
406
+ If your frontend calls the 2FA verify endpoint, update the path:
407
+
408
+ ```typescript
409
+ // Before
410
+ await fetch('/iam/two-factor/verify', { body: { code: '123456' } });
411
+
412
+ // After
413
+ await fetch('/iam/two-factor/verify-totp', { body: { code: '123456' } });
414
+ ```
415
+
416
+ ### Step 4: Verify RolesGuard (IAM-only Setup)
417
+
418
+ **No changes required for 11.10.3+.** The `registerRolesGuardGlobally` option now defaults to `true`.
419
+
420
+ If you upgraded from 11.10.0-11.10.2 and added `registerRolesGuardGlobally: true`, you can optionally remove it:
421
+
422
+ ```typescript
423
+ // server.module.ts - 11.10.3+ (registerRolesGuardGlobally defaults to true)
424
+ CoreBetterAuthModule.forRoot({
425
+ config: environment.betterAuth,
426
+ // registerRolesGuardGlobally: true, // Optional - this is now the default
427
+ })
428
+ ```
429
+
430
+ **How to check if you're IAM-only:**
431
+ - 1-parameter: `CoreModule.forRoot(environment)` → IAM-only, RolesGuard registered automatically
432
+ - 3-parameter: `CoreModule.forRoot(CoreAuthService, AuthModule.forRoot(...), environment)` → Legacy + IAM, RolesGuard registered by CoreAuthModule
433
+
434
+ ### Step 5: Verify Build and Tests
435
+
436
+ ```bash
437
+ npm run build
438
+ npm test
439
+ ```
440
+
441
+ ---
442
+
443
+ ## Compatibility Notes
444
+
445
+ ### Existing Projects Without Passkey
446
+
447
+ No changes required. The migration is seamless.
448
+
449
+ ### Existing Projects With 2FA Only
450
+
451
+ No breaking changes for basic 2FA usage. The new endpoints provide additional features (backup codes) but the core flow remains the same.
452
+
453
+ ### Custom BetterAuthController Extensions
454
+
455
+ If you extend `CoreBetterAuthController`, note that the `handleBetterAuthPlugins()` method is now used for plugin endpoints. Your existing overrides should continue to work.
456
+
457
+ ---
458
+
459
+ ## Troubleshooting
460
+
461
+ ### Passkey Disabled Warning
462
+
463
+ **Symptom:** Console shows `⚠️ PASSKEY DISABLED: Cannot auto-detect required values`
464
+
465
+ **Solution:** Ensure URLs can be resolved via one of these methods:
466
+ ```typescript
467
+ // Option 1: Set env for local development
468
+ const config = { env: 'local' };
469
+
470
+ // Option 2: Set root-level baseUrl for production
471
+ const config = { baseUrl: 'https://api.example.com', env: 'production' };
472
+
473
+ // Option 3: Explicit passkey config (not recommended)
474
+ betterAuth: {
475
+ passkey: { rpId: 'example.com', origin: 'https://example.com' },
476
+ trustedOrigins: ['https://example.com'],
477
+ }
478
+ ```
479
+
480
+ ### CORS Error with Passkey
481
+
482
+ **Symptom:** Browser console shows CORS error when using Passkey
483
+
484
+ **Solution:** Ensure `trustedOrigins` is correctly auto-detected. Check console for URL resolution warnings. If auto-detection fails, provide explicit `trustedOrigins`:
485
+ ```typescript
486
+ betterAuth: {
487
+ trustedOrigins: ['http://localhost:3001'], // Include protocol and port!
488
+ }
489
+ ```
490
+
491
+ ### Passkey Challenge Mapping Not Found (JWT Mode)
492
+
493
+ **Symptom:** `Challenge mapping not found` error when verifying passkey
494
+
495
+ **Solution:** Ensure you're using the composable methods that handle `challengeId`:
496
+ ```typescript
497
+ // CORRECT: Use composable methods
498
+ const { authenticateWithPasskey } = useBetterAuth();
499
+ await authenticateWithPasskey();
500
+
501
+ // WRONG: Direct client call (doesn't handle challengeId in JWT mode)
502
+ await authClient.signIn.passkey();
503
+ ```
504
+
505
+ ### 2FA Verify Returns 404
506
+
507
+ **Symptom:** `POST /iam/two-factor/verify` returns 404
508
+
509
+ **Solution:** Update to new endpoint: `POST /iam/two-factor/verify-totp`
510
+
511
+ ### Debug Logging Not Appearing
512
+
513
+ **Symptom:** Debug logs missing in development
514
+
515
+ **Solution:** Debug logs are now suppressed in production. Ensure `NODE_ENV` is not set to `production` during development.
516
+
517
+ ### Protected Endpoints Accessible Without Authentication (IAM-only)
518
+
519
+ **Symptom:** Endpoints with `@Roles(RoleEnum.ADMIN)` are accessible without authentication in IAM-only setups.
520
+
521
+ **Cause (11.10.0-11.10.2):** RolesGuard was not globally registered by default.
522
+
523
+ **Solution:** Upgrade to 11.10.3+. The `registerRolesGuardGlobally` option now defaults to `true`.
524
+
525
+ If you explicitly set `registerRolesGuardGlobally: false`, ensure you have another guard mechanism in place:
526
+ ```typescript
527
+ // Check console for security warning:
528
+ // ⚠️ SECURITY WARNING: registerRolesGuardGlobally is explicitly set to false...
529
+ ```
530
+
531
+ ---
532
+
533
+ ## Module Documentation
534
+
535
+ ### BetterAuth Module
536
+
537
+ - **README:** [src/core/modules/better-auth/README.md](../src/core/modules/better-auth/README.md)
538
+ - **Integration Checklist:** [src/core/modules/better-auth/INTEGRATION-CHECKLIST.md](../src/core/modules/better-auth/INTEGRATION-CHECKLIST.md)
539
+ - **Reference Implementation:** `src/server/modules/better-auth/`
540
+
541
+ ---
542
+
543
+ ## New Exports
544
+
545
+ The following are now exported from `@lenne.tech/nest-server`:
546
+
547
+ ```typescript
548
+ // Logging helpers (11.10.0)
549
+ export { isProduction, maskCookieHeader, maskEmail, maskId, maskSensitive, maskToken } from './core/common/helpers/logging.helper';
550
+
551
+ // BetterAuth types (updated)
552
+ export { IBetterAuth, IBetterAuthWithPasskey, IBetterAuthWithoutPasskey } from './core/common/interfaces/server-options.interface';
553
+
554
+ // BetterAuthTokenService (11.10.2)
555
+ export { BetterAuthTokenService, TokenExtractionResult } from './core/modules/better-auth/better-auth-token.service';
556
+
557
+ // CoreBetterAuthChallengeService (11.10.3) - Database challenge storage for JWT mode
558
+ export { CoreBetterAuthChallengeService } from './core/modules/better-auth/core-better-auth-challenge.service';
559
+
560
+ // RolesGuardRegistry (11.10.3) - Prevents duplicate global RolesGuard registrations
561
+ export { RolesGuardRegistry } from './core/modules/auth/guards/roles-guard-registry';
562
+ ```
563
+
564
+ ---
565
+
566
+ ## References
567
+
568
+ - [BetterAuth README](../src/core/modules/better-auth/README.md)
569
+ - [BetterAuth Integration Checklist](../src/core/modules/better-auth/INTEGRATION-CHECKLIST.md)
570
+ - [nest-server-starter](https://github.com/lenneTech/nest-server-starter) (reference implementation)
571
+ - [Better Auth Documentation](https://www.better-auth.com/docs)
@@ -0,0 +1,113 @@
1
+ # Migration Guide: X.Y.x → X.Z.x
2
+
3
+ ## Overview
4
+
5
+ | Category | Details |
6
+ |----------|---------|
7
+ | **Breaking Changes** | None / List them |
8
+ | **New Features** | List new features |
9
+ | **Bugfixes** | List bugfixes |
10
+ | **Migration Effort** | Estimated time |
11
+
12
+ ---
13
+
14
+ ## Quick Migration (No Breaking Changes)
15
+
16
+ ```bash
17
+ # Update package
18
+ npm install @lenne.tech/nest-server@X.Z.x
19
+
20
+ # If package.json dependencies changed
21
+ npm run update
22
+
23
+ # Verify build
24
+ npm run build
25
+
26
+ # Run tests
27
+ npm test
28
+ ```
29
+
30
+ ---
31
+
32
+ ## What's New in X.Z.x
33
+
34
+ ### 1. Feature Name
35
+
36
+ Description of the feature and how to use it.
37
+
38
+ ```typescript
39
+ // Code example
40
+ ```
41
+
42
+ ---
43
+
44
+ ## Breaking Changes (If Any)
45
+
46
+ ### Change 1: Description
47
+
48
+ **Before:**
49
+ ```typescript
50
+ // Old code
51
+ ```
52
+
53
+ **After:**
54
+ ```typescript
55
+ // New code
56
+ ```
57
+
58
+ ---
59
+
60
+ ## Detailed Migration Steps
61
+
62
+ ### Step 1: Update Package
63
+
64
+ ```bash
65
+ npm install @lenne.tech/nest-server@X.Z.x
66
+ ```
67
+
68
+ ### Step 2: Address Breaking Changes
69
+
70
+ (Details for each breaking change)
71
+
72
+ ### Step 3: Adopt New Features (Optional)
73
+
74
+ (Details for each new feature)
75
+
76
+ ---
77
+
78
+ ## Compatibility Notes
79
+
80
+ Notes about patterns that continue to work, custom implementations, etc.
81
+
82
+ ---
83
+
84
+ ## Troubleshooting
85
+
86
+ ### Common Issue 1
87
+
88
+ Solution...
89
+
90
+ ---
91
+
92
+ ## Module Documentation
93
+
94
+ For detailed information about affected modules, link to their documentation:
95
+
96
+ ### Module Name
97
+
98
+ - **README:** [src/core/modules/module-name/README.md](../src/core/modules/module-name/README.md)
99
+ - **Integration Checklist:** [src/core/modules/module-name/INTEGRATION-CHECKLIST.md](../src/core/modules/module-name/INTEGRATION-CHECKLIST.md) (if exists)
100
+ - **Reference Implementation:** `src/server/modules/module-name/`
101
+ - **Key Files:** List important files with brief descriptions
102
+
103
+ > **Note:** Only include modules that have changes relevant to this migration.
104
+ > Check for existing documentation using:
105
+ > - `src/core/modules/**/README.md`
106
+ > - `src/core/modules/**/INTEGRATION-CHECKLIST.md`
107
+
108
+ ---
109
+
110
+ ## References
111
+
112
+ - [Relevant documentation links]
113
+ - [nest-server-starter](https://github.com/lenneTech/nest-server-starter) (reference implementation)