@lenne.tech/nest-server 11.8.0 → 11.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. package/dist/config.env.js +5 -0
  2. package/dist/config.env.js.map +1 -1
  3. package/dist/core/common/helpers/logging.helper.d.ts +6 -0
  4. package/dist/core/common/helpers/logging.helper.js +55 -0
  5. package/dist/core/common/helpers/logging.helper.js.map +1 -0
  6. package/dist/core/common/interfaces/server-options.interface.d.ts +50 -19
  7. package/dist/core/modules/auth/guards/roles.guard.js +37 -5
  8. package/dist/core/modules/auth/guards/roles.guard.js.map +1 -1
  9. package/dist/core/modules/auth/services/core-auth.service.d.ts +5 -5
  10. package/dist/core/modules/auth/services/core-auth.service.js +9 -8
  11. package/dist/core/modules/auth/services/core-auth.service.js.map +1 -1
  12. package/dist/core/modules/auth/tokens.decorator.d.ts +1 -1
  13. package/dist/core/modules/better-auth/better-auth.config.js +32 -10
  14. package/dist/core/modules/better-auth/better-auth.config.js.map +1 -1
  15. package/dist/core/modules/better-auth/better-auth.resolver.d.ts +16 -16
  16. package/dist/core/modules/better-auth/better-auth.resolver.js +34 -34
  17. package/dist/core/modules/better-auth/better-auth.resolver.js.map +1 -1
  18. package/dist/core/modules/better-auth/better-auth.types.d.ts +2 -1
  19. package/dist/core/modules/better-auth/better-auth.types.js.map +1 -1
  20. package/dist/core/modules/better-auth/core-better-auth-api.middleware.d.ts +10 -0
  21. package/dist/core/modules/better-auth/core-better-auth-api.middleware.js +91 -0
  22. package/dist/core/modules/better-auth/core-better-auth-api.middleware.js.map +1 -0
  23. package/dist/core/modules/better-auth/core-better-auth-auth.model.d.ts +9 -0
  24. package/dist/core/modules/better-auth/{better-auth-auth.model.js → core-better-auth-auth.model.js} +17 -17
  25. package/dist/core/modules/better-auth/core-better-auth-auth.model.js.map +1 -0
  26. package/dist/core/modules/better-auth/{better-auth-migration-status.model.d.ts → core-better-auth-migration-status.model.d.ts} +1 -1
  27. package/dist/core/modules/better-auth/{better-auth-migration-status.model.js → core-better-auth-migration-status.model.js} +14 -14
  28. package/dist/core/modules/better-auth/core-better-auth-migration-status.model.js.map +1 -0
  29. package/dist/core/modules/better-auth/{better-auth-models.d.ts → core-better-auth-models.d.ts} +8 -8
  30. package/dist/core/modules/better-auth/{better-auth-models.js → core-better-auth-models.js} +61 -61
  31. package/dist/core/modules/better-auth/core-better-auth-models.js.map +1 -0
  32. package/dist/core/modules/better-auth/core-better-auth-rate-limit.middleware.d.ts +12 -0
  33. package/dist/core/modules/better-auth/{better-auth-rate-limit.middleware.js → core-better-auth-rate-limit.middleware.js} +10 -10
  34. package/dist/core/modules/better-auth/core-better-auth-rate-limit.middleware.js.map +1 -0
  35. package/dist/core/modules/better-auth/{better-auth-rate-limiter.service.d.ts → core-better-auth-rate-limiter.service.d.ts} +1 -1
  36. package/dist/core/modules/better-auth/{better-auth-rate-limiter.service.js → core-better-auth-rate-limiter.service.js} +8 -8
  37. package/dist/core/modules/better-auth/core-better-auth-rate-limiter.service.js.map +1 -0
  38. package/dist/core/modules/better-auth/{better-auth-user.mapper.d.ts → core-better-auth-user.mapper.d.ts} +1 -1
  39. package/dist/core/modules/better-auth/{better-auth-user.mapper.js → core-better-auth-user.mapper.js} +10 -9
  40. package/dist/core/modules/better-auth/core-better-auth-user.mapper.js.map +1 -0
  41. package/dist/core/modules/better-auth/core-better-auth-web.helper.d.ts +19 -0
  42. package/dist/core/modules/better-auth/core-better-auth-web.helper.js +152 -0
  43. package/dist/core/modules/better-auth/core-better-auth-web.helper.js.map +1 -0
  44. package/dist/core/modules/better-auth/core-better-auth.controller.d.ts +23 -32
  45. package/dist/core/modules/better-auth/core-better-auth.controller.js +184 -201
  46. package/dist/core/modules/better-auth/core-better-auth.controller.js.map +1 -1
  47. package/dist/core/modules/better-auth/core-better-auth.middleware.d.ts +22 -0
  48. package/dist/core/modules/better-auth/{better-auth.middleware.js → core-better-auth.middleware.js} +45 -18
  49. package/dist/core/modules/better-auth/core-better-auth.middleware.js.map +1 -0
  50. package/dist/core/modules/better-auth/{better-auth.module.d.ts → core-better-auth.module.d.ts} +6 -6
  51. package/dist/core/modules/better-auth/{better-auth.module.js → core-better-auth.module.js} +65 -60
  52. package/dist/core/modules/better-auth/core-better-auth.module.js.map +1 -0
  53. package/dist/core/modules/better-auth/core-better-auth.resolver.d.ts +19 -19
  54. package/dist/core/modules/better-auth/core-better-auth.resolver.js +18 -18
  55. package/dist/core/modules/better-auth/core-better-auth.resolver.js.map +1 -1
  56. package/dist/core/modules/better-auth/{better-auth.service.d.ts → core-better-auth.service.d.ts} +3 -2
  57. package/dist/core/modules/better-auth/{better-auth.service.js → core-better-auth.service.js} +75 -35
  58. package/dist/core/modules/better-auth/core-better-auth.service.js.map +1 -0
  59. package/dist/core/modules/better-auth/index.d.ts +11 -9
  60. package/dist/core/modules/better-auth/index.js +11 -9
  61. package/dist/core/modules/better-auth/index.js.map +1 -1
  62. package/dist/core/modules/error-code/core-error-code.controller.d.ts +7 -0
  63. package/dist/core/modules/error-code/core-error-code.controller.js +45 -0
  64. package/dist/core/modules/error-code/core-error-code.controller.js.map +1 -0
  65. package/dist/core/modules/error-code/core-error-code.service.d.ts +16 -0
  66. package/dist/core/modules/error-code/core-error-code.service.js +65 -0
  67. package/dist/core/modules/error-code/core-error-code.service.js.map +1 -0
  68. package/dist/core/modules/error-code/error-code.module.d.ts +7 -0
  69. package/dist/core/modules/error-code/error-code.module.js +64 -0
  70. package/dist/core/modules/error-code/error-code.module.js.map +1 -0
  71. package/dist/core/modules/error-code/error-codes.d.ts +219 -0
  72. package/dist/core/modules/error-code/error-codes.js +204 -0
  73. package/dist/core/modules/error-code/error-codes.js.map +1 -0
  74. package/dist/core/modules/error-code/index.d.ts +5 -0
  75. package/dist/core/modules/error-code/index.js +22 -0
  76. package/dist/core/modules/error-code/index.js.map +1 -0
  77. package/dist/core/modules/error-code/interfaces/error-code.interfaces.d.ts +12 -0
  78. package/dist/core/modules/error-code/interfaces/error-code.interfaces.js +3 -0
  79. package/dist/core/modules/error-code/interfaces/error-code.interfaces.js.map +1 -0
  80. package/dist/core/modules/user/interfaces/core-user-service-options.interface.d.ts +2 -2
  81. package/dist/core.module.js +14 -6
  82. package/dist/core.module.js.map +1 -1
  83. package/dist/index.d.ts +2 -0
  84. package/dist/index.js +2 -0
  85. package/dist/index.js.map +1 -1
  86. package/dist/server/modules/better-auth/better-auth.controller.d.ts +5 -5
  87. package/dist/server/modules/better-auth/better-auth.controller.js +4 -4
  88. package/dist/server/modules/better-auth/better-auth.controller.js.map +1 -1
  89. package/dist/server/modules/better-auth/better-auth.module.js +3 -3
  90. package/dist/server/modules/better-auth/better-auth.module.js.map +1 -1
  91. package/dist/server/modules/better-auth/better-auth.resolver.d.ts +17 -17
  92. package/dist/server/modules/better-auth/better-auth.resolver.js +18 -18
  93. package/dist/server/modules/better-auth/better-auth.resolver.js.map +1 -1
  94. package/dist/server/modules/error-code/error-code.controller.d.ts +8 -0
  95. package/dist/server/modules/error-code/error-code.controller.js +55 -0
  96. package/dist/server/modules/error-code/error-code.controller.js.map +1 -0
  97. package/dist/server/modules/error-code/error-code.service.d.ts +4 -0
  98. package/dist/server/modules/error-code/error-code.service.js +27 -0
  99. package/dist/server/modules/error-code/error-code.service.js.map +1 -0
  100. package/dist/server/modules/error-code/error-codes.d.ts +45 -0
  101. package/dist/server/modules/error-code/error-codes.js +24 -0
  102. package/dist/server/modules/error-code/error-codes.js.map +1 -0
  103. package/dist/server/modules/error-code/index.d.ts +3 -0
  104. package/dist/server/modules/error-code/index.js +20 -0
  105. package/dist/server/modules/error-code/index.js.map +1 -0
  106. package/dist/server/modules/user/user.service.d.ts +2 -2
  107. package/dist/server/modules/user/user.service.js +2 -2
  108. package/dist/server/modules/user/user.service.js.map +1 -1
  109. package/dist/server/server.module.js +7 -0
  110. package/dist/server/server.module.js.map +1 -1
  111. package/dist/test/test.helper.d.ts +1 -0
  112. package/dist/test/test.helper.js +5 -1
  113. package/dist/test/test.helper.js.map +1 -1
  114. package/dist/tsconfig.build.tsbuildinfo +1 -1
  115. package/package.json +6 -4
  116. package/src/config.env.ts +19 -0
  117. package/src/core/common/helpers/logging.helper.ts +134 -0
  118. package/src/core/common/interfaces/server-options.interface.ts +511 -237
  119. package/src/core/modules/auth/guards/roles.guard.ts +49 -7
  120. package/src/core/modules/auth/services/core-auth.service.ts +9 -8
  121. package/src/core/modules/better-auth/ARCHITECTURE.md +102 -0
  122. package/src/core/modules/better-auth/INTEGRATION-CHECKLIST.md +277 -8
  123. package/src/core/modules/better-auth/README.md +97 -53
  124. package/src/core/modules/better-auth/better-auth.config.ts +66 -18
  125. package/src/core/modules/better-auth/better-auth.resolver.ts +32 -32
  126. package/src/core/modules/better-auth/better-auth.types.ts +3 -2
  127. package/src/core/modules/better-auth/core-better-auth-api.middleware.ts +134 -0
  128. package/src/core/modules/better-auth/{better-auth-auth.model.ts → core-better-auth-auth.model.ts} +6 -6
  129. package/src/core/modules/better-auth/{better-auth-migration-status.model.ts → core-better-auth-migration-status.model.ts} +1 -1
  130. package/src/core/modules/better-auth/{better-auth-models.ts → core-better-auth-models.ts} +9 -9
  131. package/src/core/modules/better-auth/{better-auth-rate-limit.middleware.ts → core-better-auth-rate-limit.middleware.ts} +5 -5
  132. package/src/core/modules/better-auth/{better-auth-rate-limiter.service.ts → core-better-auth-rate-limiter.service.ts} +2 -2
  133. package/src/core/modules/better-auth/{better-auth-user.mapper.ts → core-better-auth-user.mapper.ts} +4 -3
  134. package/src/core/modules/better-auth/core-better-auth-web.helper.ts +272 -0
  135. package/src/core/modules/better-auth/core-better-auth.controller.ts +386 -230
  136. package/src/core/modules/better-auth/{better-auth.middleware.ts → core-better-auth.middleware.ts} +57 -17
  137. package/src/core/modules/better-auth/{better-auth.module.ts → core-better-auth.module.ts} +77 -66
  138. package/src/core/modules/better-auth/core-better-auth.resolver.ts +42 -42
  139. package/src/core/modules/better-auth/{better-auth.service.ts → core-better-auth.service.ts} +86 -40
  140. package/src/core/modules/better-auth/index.ts +18 -11
  141. package/src/core/modules/error-code/INTEGRATION-CHECKLIST.md +291 -0
  142. package/src/core/modules/error-code/core-error-code.controller.ts +55 -0
  143. package/src/core/modules/error-code/core-error-code.service.ts +135 -0
  144. package/src/core/modules/error-code/error-code.module.ts +119 -0
  145. package/src/core/modules/error-code/error-codes.ts +405 -0
  146. package/src/core/modules/error-code/index.ts +14 -0
  147. package/src/core/modules/error-code/interfaces/error-code.interfaces.ts +99 -0
  148. package/src/core/modules/user/interfaces/core-user-service-options.interface.ts +3 -3
  149. package/src/core.module.ts +28 -12
  150. package/src/index.ts +7 -0
  151. package/src/server/modules/better-auth/better-auth.controller.ts +4 -4
  152. package/src/server/modules/better-auth/better-auth.module.ts +1 -1
  153. package/src/server/modules/better-auth/better-auth.resolver.ts +31 -31
  154. package/src/server/modules/error-code/README.md +131 -0
  155. package/src/server/modules/error-code/error-code.controller.ts +91 -0
  156. package/src/server/modules/error-code/error-code.service.ts +42 -0
  157. package/src/server/modules/error-code/error-codes.ts +65 -0
  158. package/src/server/modules/error-code/index.ts +8 -0
  159. package/src/server/modules/user/user.service.ts +2 -2
  160. package/src/server/server.module.ts +10 -0
  161. package/src/test/test.helper.ts +13 -1
  162. package/dist/core/modules/better-auth/better-auth-auth.model.d.ts +0 -9
  163. package/dist/core/modules/better-auth/better-auth-auth.model.js.map +0 -1
  164. package/dist/core/modules/better-auth/better-auth-migration-status.model.js.map +0 -1
  165. package/dist/core/modules/better-auth/better-auth-models.js.map +0 -1
  166. package/dist/core/modules/better-auth/better-auth-rate-limit.middleware.d.ts +0 -12
  167. package/dist/core/modules/better-auth/better-auth-rate-limit.middleware.js.map +0 -1
  168. package/dist/core/modules/better-auth/better-auth-rate-limiter.service.js.map +0 -1
  169. package/dist/core/modules/better-auth/better-auth-user.mapper.js.map +0 -1
  170. package/dist/core/modules/better-auth/better-auth.middleware.d.ts +0 -21
  171. package/dist/core/modules/better-auth/better-auth.middleware.js.map +0 -1
  172. package/dist/core/modules/better-auth/better-auth.module.js.map +0 -1
  173. package/dist/core/modules/better-auth/better-auth.service.js.map +0 -1
@@ -187,241 +187,41 @@ export interface IAuthRateLimit {
187
187
  }
188
188
 
189
189
  /**
190
- * Interface for better-auth configuration
190
+ * Better-Auth configuration type (Discriminated Union).
191
+ *
192
+ * This type enforces at compile-time that `trustedOrigins` is REQUIRED
193
+ * when `passkey` is enabled. This prevents CORS errors at runtime.
194
+ *
195
+ * ## Why this constraint?
196
+ * Passkey (WebAuthn) uses `credentials: 'include'` for API calls.
197
+ * Browsers don't allow CORS wildcard `*` with credentials, so explicit
198
+ * origins must be configured.
199
+ *
200
+ * ## Usage Examples
201
+ *
202
+ * ```typescript
203
+ * // CORRECT: Passkey with trustedOrigins
204
+ * const config: IBetterAuth = {
205
+ * passkey: true,
206
+ * trustedOrigins: ['http://localhost:3001'],
207
+ * };
208
+ *
209
+ * // CORRECT: No Passkey, trustedOrigins optional
210
+ * const config: IBetterAuth = {
211
+ * twoFactor: true,
212
+ * };
213
+ *
214
+ * // TypeScript ERROR: trustedOrigins required when passkey is enabled
215
+ * const config: IBetterAuth = {
216
+ * passkey: true,
217
+ * // Error: Property 'trustedOrigins' is missing
218
+ * };
219
+ * ```
220
+ *
221
+ * @see IBetterAuthWithPasskey - When Passkey is enabled
222
+ * @see IBetterAuthWithoutPasskey - When Passkey is disabled
191
223
  */
192
- export interface IBetterAuth {
193
- /**
194
- * Additional user fields beyond the core fields (firstName, lastName, etc.)
195
- * These fields will be merged with the default user fields.
196
- * @see https://www.better-auth.com/docs/concepts/users-accounts#additional-fields
197
- * @example
198
- * ```typescript
199
- * additionalUserFields: {
200
- * phoneNumber: { type: 'string', defaultValue: null },
201
- * department: { type: 'string', required: true },
202
- * preferences: { type: 'string', defaultValue: '{}' },
203
- * }
204
- * ```
205
- */
206
- additionalUserFields?: Record<string, IBetterAuthUserField>;
207
-
208
- /**
209
- * Whether BetterAuthModule should be auto-registered in CoreModule.
210
- *
211
- * When false (default), projects integrate BetterAuth via an extended module
212
- * in their project (e.g., `src/server/modules/better-auth/better-auth.module.ts`).
213
- * This follows the same pattern as Legacy Auth and allows for custom resolvers,
214
- * controllers, and project-specific authentication logic.
215
- *
216
- * Set to true only for simple projects that don't need customization.
217
- *
218
- * @default false
219
- *
220
- * @example
221
- * ```typescript
222
- * // Recommended: Extend BetterAuthModule in your project
223
- * // src/server/modules/better-auth/better-auth.module.ts
224
- * import { BetterAuthModule as CoreBetterAuthModule } from '@lenne.tech/nest-server';
225
- *
226
- * @Module({})
227
- * export class BetterAuthModule {
228
- * static forRoot(options) {
229
- * return {
230
- * imports: [CoreBetterAuthModule.forRoot(options)],
231
- * // Add custom providers, controllers, etc.
232
- * };
233
- * }
234
- * }
235
- *
236
- * // Then import in ServerModule
237
- * import { BetterAuthModule } from './modules/better-auth/better-auth.module';
238
- * ```
239
- */
240
- autoRegister?: boolean;
241
-
242
- /**
243
- * Base path for better-auth endpoints
244
- * default: '/iam'
245
- */
246
- basePath?: string;
247
-
248
- /**
249
- * Base URL of the application
250
- * e.g. 'http://localhost:3000'
251
- */
252
- baseUrl?: string;
253
-
254
- /**
255
- * Email/password authentication configuration.
256
- * Enabled by default.
257
- * Set `enabled: false` to explicitly disable email/password auth.
258
- */
259
- emailAndPassword?: {
260
- /**
261
- * Whether email/password authentication is enabled.
262
- * @default true
263
- */
264
- enabled?: boolean;
265
- };
266
-
267
- /**
268
- * Whether better-auth is enabled.
269
- * BetterAuth is enabled by default (zero-config philosophy).
270
- * Set to false to explicitly disable it.
271
- * @default true
272
- */
273
- enabled?: boolean;
274
-
275
- /**
276
- * JWT plugin configuration for API clients.
277
- *
278
- * **Default: Enabled** - JWT is enabled by default when BetterAuth is enabled.
279
- * This ensures a minimal config (`betterAuth: true`) provides full functionality.
280
- *
281
- * Accepts:
282
- * - `true` or `{}`: Enable with defaults (same as not specifying)
283
- * - `{ expiresIn: '1h' }`: Enable with custom settings
284
- * - `false` or `{ enabled: false }`: Explicitly disable
285
- * - `undefined`: Enabled with defaults (JWT is on by default)
286
- *
287
- * @example
288
- * ```typescript
289
- * // JWT is enabled by default, no config needed
290
- * betterAuth: true,
291
- *
292
- * // Customize JWT expiry
293
- * betterAuth: { jwt: { expiresIn: '1h' } },
294
- *
295
- * // Explicitly disable JWT (session-only mode)
296
- * betterAuth: { jwt: false },
297
- * ```
298
- */
299
- jwt?: boolean | IBetterAuthJwtConfig;
300
-
301
- /**
302
- * Advanced Better-Auth options passthrough.
303
- * These options are passed directly to Better-Auth, allowing full customization.
304
- * Use this for any Better-Auth options not explicitly defined in this interface.
305
- * @see https://www.better-auth.com/docs/reference/options
306
- * @example
307
- * ```typescript
308
- * options: {
309
- * emailAndPassword: {
310
- * enabled: true,
311
- * requireEmailVerification: true,
312
- * sendResetPassword: async ({ user, url }) => { ... },
313
- * },
314
- * account: {
315
- * accountLinking: { enabled: true },
316
- * },
317
- * session: {
318
- * expiresIn: 60 * 60 * 24 * 7, // 7 days
319
- * updateAge: 60 * 60 * 24, // 1 day
320
- * },
321
- * advanced: {
322
- * cookiePrefix: 'my-app',
323
- * useSecureCookies: true,
324
- * },
325
- * }
326
- * ```
327
- */
328
- options?: Record<string, unknown>;
329
-
330
- /**
331
- * Passkey/WebAuthn configuration.
332
- *
333
- * Accepts:
334
- * - `true` or `{}`: Enable with defaults
335
- * - `{ rpName: 'My App' }`: Enable with custom settings
336
- * - `false` or `{ enabled: false }`: Disable
337
- * - `undefined`: Disabled (default)
338
- *
339
- * @example
340
- * ```typescript
341
- * passkey: true, // Enable with defaults
342
- * passkey: {}, // Enable with defaults
343
- * passkey: { rpName: 'My App', rpId: 'example.com' }, // Enable with custom settings
344
- * passkey: false, // Disable
345
- * ```
346
- */
347
- passkey?: boolean | IBetterAuthPasskeyConfig;
348
-
349
- /**
350
- * Additional Better-Auth plugins to include.
351
- * These will be merged with the built-in plugins (jwt, twoFactor, passkey).
352
- * @see https://www.better-auth.com/docs/plugins
353
- * @example
354
- * ```typescript
355
- * import { organization } from 'better-auth/plugins';
356
- * import { magicLink } from 'better-auth/plugins';
357
- *
358
- * plugins: [
359
- * organization({ ... }),
360
- * magicLink({ ... }),
361
- * ]
362
- * ```
363
- */
364
- plugins?: unknown[];
365
-
366
- /**
367
- * Rate limiting configuration for Better-Auth endpoints
368
- * Protects against brute-force attacks
369
- */
370
- rateLimit?: IBetterAuthRateLimit;
371
-
372
- /**
373
- * Secret for better-auth (min 32 characters)
374
- * Used for session encryption
375
- */
376
- secret?: string;
377
-
378
- /**
379
- * Social login providers configuration
380
- * Supports all Better-Auth providers dynamically (google, github, apple, discord, etc.)
381
- *
382
- * **Enabled by default:** Providers are automatically enabled when credentials
383
- * are configured. Set `enabled: false` to explicitly disable a provider.
384
- *
385
- * @see https://www.better-auth.com/docs/authentication/social-sign-in
386
- * @example
387
- * ```typescript
388
- * socialProviders: {
389
- * // These providers are enabled (no need for enabled: true)
390
- * google: { clientId: '...', clientSecret: '...' },
391
- * github: { clientId: '...', clientSecret: '...' },
392
- * // This provider is explicitly disabled
393
- * discord: { clientId: '...', clientSecret: '...', enabled: false },
394
- * }
395
- * ```
396
- */
397
- socialProviders?: Record<string, IBetterAuthSocialProvider>;
398
-
399
- /**
400
- * Trusted origins for CORS and OAuth callbacks
401
- * If not specified, defaults to [baseUrl]
402
- * e.g. ['https://example.com', 'https://app.example.com']
403
- */
404
- trustedOrigins?: string[];
405
-
406
- /**
407
- * Two-factor authentication configuration.
408
- *
409
- * Accepts:
410
- * - `true` or `{}`: Enable with defaults
411
- * - `{ appName: 'My App' }`: Enable with custom settings
412
- * - `false` or `{ enabled: false }`: Disable
413
- * - `undefined`: Disabled (default)
414
- *
415
- * @example
416
- * ```typescript
417
- * twoFactor: true, // Enable with defaults
418
- * twoFactor: {}, // Enable with defaults
419
- * twoFactor: { appName: 'My App' }, // Enable with custom app name
420
- * twoFactor: false, // Disable
421
- * ```
422
- */
423
- twoFactor?: boolean | IBetterAuthTwoFactorConfig;
424
- }
224
+ export type IBetterAuth = IBetterAuthWithoutPasskey | IBetterAuthWithPasskey;
425
225
 
426
226
  /**
427
227
  * JWT plugin configuration for Better-Auth
@@ -442,8 +242,18 @@ export interface IBetterAuthJwtConfig {
442
242
 
443
243
  /**
444
244
  * Passkey/WebAuthn plugin configuration for Better-Auth
245
+ * @see https://www.better-auth.com/docs/plugins/passkey
445
246
  */
446
247
  export interface IBetterAuthPasskeyConfig {
248
+ /**
249
+ * Authenticator attachment preference.
250
+ * - 'platform': Built-in authenticators (Touch ID, Face ID, Windows Hello)
251
+ * - 'cross-platform': External authenticators (YubiKey, security keys)
252
+ * - undefined: Allow both (default, platform preferred)
253
+ * @default undefined (both allowed)
254
+ */
255
+ authenticatorAttachment?: 'cross-platform' | 'platform';
256
+
447
257
  /**
448
258
  * Whether passkey authentication is enabled.
449
259
  * @default true (when config block is present)
@@ -456,6 +266,15 @@ export interface IBetterAuthPasskeyConfig {
456
266
  */
457
267
  origin?: string;
458
268
 
269
+ /**
270
+ * Resident key (discoverable credential) requirement.
271
+ * - 'required': Must create discoverable credential
272
+ * - 'preferred': Prefer discoverable, but allow non-discoverable (default)
273
+ * - 'discouraged': Prefer non-discoverable credentials
274
+ * @default 'preferred'
275
+ */
276
+ residentKey?: 'discouraged' | 'preferred' | 'required';
277
+
459
278
  /**
460
279
  * Relying Party ID (usually the domain)
461
280
  * e.g. 'localhost' or 'example.com'
@@ -467,6 +286,21 @@ export interface IBetterAuthPasskeyConfig {
467
286
  * e.g. 'My Application'
468
287
  */
469
288
  rpName?: string;
289
+
290
+ /**
291
+ * User verification requirement.
292
+ * - 'required': Always require biometric/PIN verification (most secure)
293
+ * - 'preferred': Request verification if available (default)
294
+ * - 'discouraged': Skip verification for faster auth (least secure)
295
+ * @default 'preferred'
296
+ */
297
+ userVerification?: 'discouraged' | 'preferred' | 'required';
298
+
299
+ /**
300
+ * Custom cookie name for WebAuthn challenge storage.
301
+ * @default 'better-auth-passkey'
302
+ */
303
+ webAuthnChallengeCookie?: string;
470
304
  }
471
305
 
472
306
  /**
@@ -590,11 +424,75 @@ export interface IBetterAuthUserField {
590
424
  }
591
425
 
592
426
  /**
593
- * Interface for JWT configuration (main and refresh)
427
+ * Interface for Error Code module configuration
428
+ *
429
+ * Controls how the ErrorCodeModule is registered and configured.
430
+ *
431
+ * @since 11.9.0
594
432
  */
595
- export interface IJwt {
433
+ export interface IErrorCode {
596
434
  /**
597
- * Private key
435
+ * Additional error registry to merge with core LTNS_* errors
436
+ *
437
+ * Use this to add project-specific error codes with a custom prefix.
438
+ *
439
+ * @example
440
+ * ```typescript
441
+ * const ProjectErrors = {
442
+ * ORDER_NOT_FOUND: {
443
+ * code: 'PROJ_0001',
444
+ * message: 'Order not found',
445
+ * translations: { de: 'Bestellung nicht gefunden.', en: 'Order not found.' }
446
+ * }
447
+ * } as const satisfies IErrorRegistry;
448
+ *
449
+ * errorCode: {
450
+ * additionalErrorRegistry: ProjectErrors,
451
+ * }
452
+ * ```
453
+ */
454
+ additionalErrorRegistry?: Record<
455
+ string,
456
+ {
457
+ code: string;
458
+ message: string;
459
+ translations: { [locale: string]: string; de: string; en: string };
460
+ }
461
+ >;
462
+
463
+ /**
464
+ * Automatically register the ErrorCodeModule in CoreModule
465
+ *
466
+ * Set to `false` to disable auto-registration and provide your own
467
+ * ErrorCodeModule with custom controller and/or service.
468
+ *
469
+ * @default true
470
+ *
471
+ * @example
472
+ * ```typescript
473
+ * // In config.env.ts - disable auto-registration
474
+ * errorCode: {
475
+ * autoRegister: false,
476
+ * }
477
+ *
478
+ * // In server.module.ts - import your custom module
479
+ * @Module({
480
+ * imports: [
481
+ * CoreModule.forRoot(...),
482
+ * ErrorCodeModule.forRoot(), // Your custom module
483
+ * ],
484
+ * })
485
+ * ```
486
+ */
487
+ autoRegister?: boolean;
488
+ }
489
+
490
+ /**
491
+ * Interface for JWT configuration (main and refresh)
492
+ */
493
+ export interface IJwt {
494
+ /**
495
+ * Private key
598
496
  */
599
497
  privateKey?: string;
600
498
 
@@ -766,6 +664,31 @@ export interface IServerOptions {
766
664
  */
767
665
  env?: string;
768
666
 
667
+ /**
668
+ * Configuration for the error code module
669
+ *
670
+ * Controls how error codes and translations are handled.
671
+ *
672
+ * @since 11.9.0
673
+ *
674
+ * @example
675
+ * ```typescript
676
+ * // Default: auto-register with core errors only
677
+ * errorCode: undefined
678
+ *
679
+ * // Add project-specific error codes
680
+ * errorCode: {
681
+ * additionalErrorRegistry: ProjectErrors,
682
+ * }
683
+ *
684
+ * // Disable auto-registration to provide your own module
685
+ * errorCode: {
686
+ * autoRegister: false,
687
+ * }
688
+ * ```
689
+ */
690
+ errorCode?: IErrorCode;
691
+
769
692
  /**
770
693
  * Exec a command after server is initialized
771
694
  * e.g. 'npm run docs:bootstrap'
@@ -1287,3 +1210,354 @@ export interface ITusExpirationConfig {
1287
1210
  */
1288
1211
  expiresIn?: string;
1289
1212
  }
1213
+
1214
+ /**
1215
+ * Base interface for better-auth configuration (shared properties)
1216
+ * This contains all properties except passkey and trustedOrigins,
1217
+ * which are handled by the discriminated union types below.
1218
+ */
1219
+ interface IBetterAuthBase {
1220
+ /**
1221
+ * Additional user fields beyond the core fields (firstName, lastName, etc.)
1222
+ * These fields will be merged with the default user fields.
1223
+ * @see https://www.better-auth.com/docs/concepts/users-accounts#additional-fields
1224
+ * @example
1225
+ * ```typescript
1226
+ * additionalUserFields: {
1227
+ * phoneNumber: { type: 'string', defaultValue: null },
1228
+ * department: { type: 'string', required: true },
1229
+ * preferences: { type: 'string', defaultValue: '{}' },
1230
+ * }
1231
+ * ```
1232
+ */
1233
+ additionalUserFields?: Record<string, IBetterAuthUserField>;
1234
+
1235
+ /**
1236
+ * Whether BetterAuthModule should be auto-registered in CoreModule.
1237
+ *
1238
+ * When false (default), projects integrate BetterAuth via an extended module
1239
+ * in their project (e.g., `src/server/modules/better-auth/better-auth.module.ts`).
1240
+ * This follows the same pattern as Legacy Auth and allows for custom resolvers,
1241
+ * controllers, and project-specific authentication logic.
1242
+ *
1243
+ * Set to true only for simple projects that don't need customization.
1244
+ *
1245
+ * @default false
1246
+ *
1247
+ * @example
1248
+ * ```typescript
1249
+ * // Recommended: Extend BetterAuthModule in your project
1250
+ * // src/server/modules/better-auth/better-auth.module.ts
1251
+ * import { BetterAuthModule as CoreBetterAuthModule } from '@lenne.tech/nest-server';
1252
+ *
1253
+ * @Module({})
1254
+ * export class BetterAuthModule {
1255
+ * static forRoot(options) {
1256
+ * return {
1257
+ * imports: [CoreBetterAuthModule.forRoot(options)],
1258
+ * // Add custom providers, controllers, etc.
1259
+ * };
1260
+ * }
1261
+ * }
1262
+ *
1263
+ * // Then import in ServerModule
1264
+ * import { BetterAuthModule } from './modules/better-auth/better-auth.module';
1265
+ * ```
1266
+ */
1267
+ autoRegister?: boolean;
1268
+
1269
+ /**
1270
+ * Base path for better-auth endpoints
1271
+ * default: '/iam'
1272
+ */
1273
+ basePath?: string;
1274
+
1275
+ /**
1276
+ * Base URL of the application
1277
+ * e.g. 'http://localhost:3000'
1278
+ */
1279
+ baseUrl?: string;
1280
+
1281
+ /**
1282
+ * Email/password authentication configuration.
1283
+ * Enabled by default.
1284
+ * Set `enabled: false` to explicitly disable email/password auth.
1285
+ */
1286
+ emailAndPassword?: {
1287
+ /**
1288
+ * Whether email/password authentication is enabled.
1289
+ * @default true
1290
+ */
1291
+ enabled?: boolean;
1292
+ };
1293
+
1294
+ /**
1295
+ * Whether better-auth is enabled.
1296
+ * BetterAuth is enabled by default (zero-config philosophy).
1297
+ * Set to false to explicitly disable it.
1298
+ * @default true
1299
+ */
1300
+ enabled?: boolean;
1301
+
1302
+ /**
1303
+ * JWT plugin configuration for API clients.
1304
+ *
1305
+ * **Default: Enabled** - JWT is enabled by default when BetterAuth is enabled.
1306
+ * This ensures a minimal config (`betterAuth: true`) provides full functionality.
1307
+ *
1308
+ * Accepts:
1309
+ * - `true` or `{}`: Enable with defaults (same as not specifying)
1310
+ * - `{ expiresIn: '1h' }`: Enable with custom settings
1311
+ * - `false` or `{ enabled: false }`: Explicitly disable
1312
+ * - `undefined`: Enabled with defaults (JWT is on by default)
1313
+ *
1314
+ * @example
1315
+ * ```typescript
1316
+ * // JWT is enabled by default, no config needed
1317
+ * betterAuth: true,
1318
+ *
1319
+ * // Customize JWT expiry
1320
+ * betterAuth: { jwt: { expiresIn: '1h' } },
1321
+ *
1322
+ * // Explicitly disable JWT (session-only mode)
1323
+ * betterAuth: { jwt: false },
1324
+ * ```
1325
+ */
1326
+ jwt?: boolean | IBetterAuthJwtConfig;
1327
+
1328
+ /**
1329
+ * Advanced Better-Auth options passthrough.
1330
+ * These options are passed directly to Better-Auth, allowing full customization.
1331
+ * Use this for any Better-Auth options not explicitly defined in this interface.
1332
+ * @see https://www.better-auth.com/docs/reference/options
1333
+ * @example
1334
+ * ```typescript
1335
+ * options: {
1336
+ * emailAndPassword: {
1337
+ * enabled: true,
1338
+ * requireEmailVerification: true,
1339
+ * sendResetPassword: async ({ user, url }) => { ... },
1340
+ * },
1341
+ * account: {
1342
+ * accountLinking: { enabled: true },
1343
+ * },
1344
+ * session: {
1345
+ * expiresIn: 60 * 60 * 24 * 7, // 7 days
1346
+ * updateAge: 60 * 60 * 24, // 1 day
1347
+ * },
1348
+ * advanced: {
1349
+ * cookiePrefix: 'my-app',
1350
+ * useSecureCookies: true,
1351
+ * },
1352
+ * }
1353
+ * ```
1354
+ */
1355
+ options?: Record<string, unknown>;
1356
+
1357
+ /**
1358
+ * Additional Better-Auth plugins to include.
1359
+ * These will be merged with the built-in plugins (jwt, twoFactor, passkey).
1360
+ * @see https://www.better-auth.com/docs/plugins
1361
+ * @example
1362
+ * ```typescript
1363
+ * import { organization } from 'better-auth/plugins';
1364
+ * import { magicLink } from 'better-auth/plugins';
1365
+ *
1366
+ * plugins: [
1367
+ * organization({ ... }),
1368
+ * magicLink({ ... }),
1369
+ * ]
1370
+ * ```
1371
+ */
1372
+ plugins?: unknown[];
1373
+
1374
+ /**
1375
+ * Rate limiting configuration for Better-Auth endpoints
1376
+ * Protects against brute-force attacks
1377
+ */
1378
+ rateLimit?: IBetterAuthRateLimit;
1379
+
1380
+ /**
1381
+ * Secret for better-auth (min 32 characters)
1382
+ * Used for session encryption
1383
+ */
1384
+ secret?: string;
1385
+
1386
+ /**
1387
+ * Social login providers configuration
1388
+ * Supports all Better-Auth providers dynamically (google, github, apple, discord, etc.)
1389
+ *
1390
+ * **Enabled by default:** Providers are automatically enabled when credentials
1391
+ * are configured. Set `enabled: false` to explicitly disable a provider.
1392
+ *
1393
+ * @see https://www.better-auth.com/docs/authentication/social-sign-in
1394
+ * @example
1395
+ * ```typescript
1396
+ * socialProviders: {
1397
+ * // These providers are enabled (no need for enabled: true)
1398
+ * google: { clientId: '...', clientSecret: '...' },
1399
+ * github: { clientId: '...', clientSecret: '...' },
1400
+ * // This provider is explicitly disabled
1401
+ * discord: { clientId: '...', clientSecret: '...', enabled: false },
1402
+ * }
1403
+ * ```
1404
+ */
1405
+ socialProviders?: Record<string, IBetterAuthSocialProvider>;
1406
+
1407
+ /**
1408
+ * Two-factor authentication configuration.
1409
+ *
1410
+ * Accepts:
1411
+ * - `true` or `{}`: Enable with defaults
1412
+ * - `{ appName: 'My App' }`: Enable with custom settings
1413
+ * - `false` or `{ enabled: false }`: Disable
1414
+ * - `undefined`: Disabled (default)
1415
+ *
1416
+ * @example
1417
+ * ```typescript
1418
+ * twoFactor: true, // Enable with defaults
1419
+ * twoFactor: {}, // Enable with defaults
1420
+ * twoFactor: { appName: 'My App' }, // Enable with custom app name
1421
+ * twoFactor: false, // Disable
1422
+ * ```
1423
+ */
1424
+ twoFactor?: boolean | IBetterAuthTwoFactorConfig;
1425
+ }
1426
+
1427
+ /**
1428
+ * Passkey configuration that is considered "disabled".
1429
+ * This includes:
1430
+ * - `false` (boolean shorthand)
1431
+ * - `{ enabled: false, ...otherProps }` (explicit disabled, can include other props)
1432
+ * - `undefined` (not configured = disabled by default)
1433
+ *
1434
+ * ## TypeScript Type Narrowing Note
1435
+ *
1436
+ * When using `enabled: false` in an object literal, TypeScript may infer the type
1437
+ * as `boolean` instead of the literal `false`. To ensure proper type narrowing,
1438
+ * use `as const` assertion:
1439
+ *
1440
+ * ```typescript
1441
+ * // MAY NOT TYPE-CHECK CORRECTLY (TypeScript infers boolean)
1442
+ * const config: IBetterAuth = {
1443
+ * passkey: { enabled: false },
1444
+ * };
1445
+ *
1446
+ * // CORRECT: Use 'as const' for literal type
1447
+ * const config: IBetterAuth = {
1448
+ * passkey: { enabled: false as const },
1449
+ * };
1450
+ *
1451
+ * // ALTERNATIVE: Use boolean shorthand (recommended)
1452
+ * const config: IBetterAuth = {
1453
+ * passkey: false,
1454
+ * };
1455
+ * ```
1456
+ */
1457
+ type IBetterAuthPasskeyDisabled =
1458
+ | false
1459
+ | (Omit<IBetterAuthPasskeyConfig, 'enabled'> & { enabled: false })
1460
+ | undefined;
1461
+
1462
+ /**
1463
+ * Passkey configuration that is considered "enabled".
1464
+ * This includes:
1465
+ * - `true` (boolean shorthand)
1466
+ * - `{}` (empty object = defaults)
1467
+ * - `{ enabled: true, ... }` (explicit enabled)
1468
+ * - `{ rpName: 'My App', ... }` (config without explicit enabled = defaults to true)
1469
+ */
1470
+ type IBetterAuthPasskeyEnabled =
1471
+ | (Omit<IBetterAuthPasskeyConfig, 'enabled'> & { enabled?: true })
1472
+ | true;
1473
+
1474
+ /**
1475
+ * BetterAuth configuration WITHOUT Passkey (or Passkey disabled).
1476
+ * When Passkey is disabled, trustedOrigins is optional.
1477
+ * If not set, all origins are allowed (CORS `*`).
1478
+ *
1479
+ * @example
1480
+ * ```typescript
1481
+ * // Without Passkey: trustedOrigins optional
1482
+ * betterAuth: {
1483
+ * twoFactor: true,
1484
+ * // trustedOrigins is optional here
1485
+ * }
1486
+ *
1487
+ * // Explicitly disabled Passkey
1488
+ * betterAuth: {
1489
+ * passkey: false,
1490
+ * trustedOrigins: ['https://app.example.com'], // Still optional
1491
+ * }
1492
+ * ```
1493
+ */
1494
+ interface IBetterAuthWithoutPasskey extends IBetterAuthBase {
1495
+ /**
1496
+ * Passkey/WebAuthn configuration (DISABLED or not configured).
1497
+ */
1498
+ passkey?: IBetterAuthPasskeyDisabled;
1499
+
1500
+ /**
1501
+ * Trusted origins for CORS configuration.
1502
+ *
1503
+ * Optional when Passkey is disabled.
1504
+ * If not set, all origins are allowed (CORS `*`).
1505
+ *
1506
+ * @example
1507
+ * ```typescript
1508
+ * // Restrict origins even without Passkey
1509
+ * trustedOrigins: ['https://app.example.com'],
1510
+ *
1511
+ * // Or leave undefined for open CORS
1512
+ * ```
1513
+ */
1514
+ trustedOrigins?: string[];
1515
+ }
1516
+
1517
+ /**
1518
+ * BetterAuth configuration WITH Passkey enabled.
1519
+ * When Passkey is enabled, trustedOrigins is REQUIRED because:
1520
+ * - Passkey uses `credentials: 'include'` for WebAuthn API calls
1521
+ * - Browsers don't allow CORS wildcard `*` with credentials
1522
+ * - Explicit origins must be configured for CORS to work
1523
+ *
1524
+ * @example
1525
+ * ```typescript
1526
+ * // CORRECT: Passkey with trustedOrigins
1527
+ * betterAuth: {
1528
+ * passkey: true,
1529
+ * trustedOrigins: ['http://localhost:3000', 'http://localhost:3001'],
1530
+ * }
1531
+ *
1532
+ * // TypeScript ERROR: trustedOrigins missing
1533
+ * betterAuth: {
1534
+ * passkey: true,
1535
+ * // Missing trustedOrigins!
1536
+ * }
1537
+ * ```
1538
+ */
1539
+ interface IBetterAuthWithPasskey extends IBetterAuthBase {
1540
+ /**
1541
+ * Passkey/WebAuthn configuration (ENABLED).
1542
+ * @see IBetterAuthPasskeyConfig
1543
+ */
1544
+ passkey: IBetterAuthPasskeyEnabled;
1545
+
1546
+ /**
1547
+ * Trusted origins for CORS configuration.
1548
+ *
1549
+ * **REQUIRED when Passkey is enabled!**
1550
+ * Passkey uses `credentials: 'include'` which requires explicit CORS origins.
1551
+ * Browsers don't allow wildcard `*` with credentials.
1552
+ *
1553
+ * @example
1554
+ * ```typescript
1555
+ * // Development
1556
+ * trustedOrigins: ['http://localhost:3000', 'http://localhost:3001'],
1557
+ *
1558
+ * // Production
1559
+ * trustedOrigins: process.env.TRUSTED_ORIGINS?.split(',') || [],
1560
+ * ```
1561
+ */
1562
+ trustedOrigins: string[];
1563
+ }