@lenne.tech/nest-server 11.9.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 (131) hide show
  1. package/dist/config.env.js +2 -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 +37 -19
  7. package/dist/core/modules/auth/guards/roles.guard.js +33 -2
  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 +4 -4
  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.js.map +1 -1
  63. package/dist/core/modules/user/interfaces/core-user-service-options.interface.d.ts +2 -2
  64. package/dist/core.module.js +6 -6
  65. package/dist/core.module.js.map +1 -1
  66. package/dist/index.d.ts +1 -0
  67. package/dist/index.js +1 -0
  68. package/dist/index.js.map +1 -1
  69. package/dist/server/modules/better-auth/better-auth.controller.d.ts +5 -5
  70. package/dist/server/modules/better-auth/better-auth.controller.js +4 -4
  71. package/dist/server/modules/better-auth/better-auth.controller.js.map +1 -1
  72. package/dist/server/modules/better-auth/better-auth.module.js +3 -3
  73. package/dist/server/modules/better-auth/better-auth.module.js.map +1 -1
  74. package/dist/server/modules/better-auth/better-auth.resolver.d.ts +17 -17
  75. package/dist/server/modules/better-auth/better-auth.resolver.js +18 -18
  76. package/dist/server/modules/better-auth/better-auth.resolver.js.map +1 -1
  77. package/dist/server/modules/user/user.service.d.ts +2 -2
  78. package/dist/server/modules/user/user.service.js +2 -2
  79. package/dist/server/modules/user/user.service.js.map +1 -1
  80. package/dist/test/test.helper.d.ts +1 -0
  81. package/dist/test/test.helper.js +5 -1
  82. package/dist/test/test.helper.js.map +1 -1
  83. package/dist/tsconfig.build.tsbuildinfo +1 -1
  84. package/package.json +5 -3
  85. package/src/config.env.ts +15 -0
  86. package/src/core/common/helpers/logging.helper.ts +134 -0
  87. package/src/core/common/interfaces/server-options.interface.ts +419 -234
  88. package/src/core/modules/auth/guards/roles.guard.ts +44 -3
  89. package/src/core/modules/auth/services/core-auth.service.ts +4 -4
  90. package/src/core/modules/better-auth/ARCHITECTURE.md +102 -0
  91. package/src/core/modules/better-auth/INTEGRATION-CHECKLIST.md +277 -8
  92. package/src/core/modules/better-auth/README.md +97 -53
  93. package/src/core/modules/better-auth/better-auth.config.ts +66 -18
  94. package/src/core/modules/better-auth/better-auth.resolver.ts +32 -32
  95. package/src/core/modules/better-auth/better-auth.types.ts +3 -2
  96. package/src/core/modules/better-auth/core-better-auth-api.middleware.ts +134 -0
  97. package/src/core/modules/better-auth/{better-auth-auth.model.ts → core-better-auth-auth.model.ts} +6 -6
  98. package/src/core/modules/better-auth/{better-auth-migration-status.model.ts → core-better-auth-migration-status.model.ts} +1 -1
  99. package/src/core/modules/better-auth/{better-auth-models.ts → core-better-auth-models.ts} +9 -9
  100. package/src/core/modules/better-auth/{better-auth-rate-limit.middleware.ts → core-better-auth-rate-limit.middleware.ts} +5 -5
  101. package/src/core/modules/better-auth/{better-auth-rate-limiter.service.ts → core-better-auth-rate-limiter.service.ts} +2 -2
  102. package/src/core/modules/better-auth/{better-auth-user.mapper.ts → core-better-auth-user.mapper.ts} +4 -3
  103. package/src/core/modules/better-auth/core-better-auth-web.helper.ts +272 -0
  104. package/src/core/modules/better-auth/core-better-auth.controller.ts +386 -230
  105. package/src/core/modules/better-auth/{better-auth.middleware.ts → core-better-auth.middleware.ts} +57 -17
  106. package/src/core/modules/better-auth/{better-auth.module.ts → core-better-auth.module.ts} +77 -66
  107. package/src/core/modules/better-auth/core-better-auth.resolver.ts +42 -42
  108. package/src/core/modules/better-auth/{better-auth.service.ts → core-better-auth.service.ts} +86 -40
  109. package/src/core/modules/better-auth/index.ts +18 -11
  110. package/src/core/modules/error-code/INTEGRATION-CHECKLIST.md +4 -1
  111. package/src/core/modules/error-code/core-error-code.controller.ts +3 -2
  112. package/src/core/modules/user/interfaces/core-user-service-options.interface.ts +3 -3
  113. package/src/core.module.ts +12 -12
  114. package/src/index.ts +1 -0
  115. package/src/server/modules/better-auth/better-auth.controller.ts +4 -4
  116. package/src/server/modules/better-auth/better-auth.module.ts +1 -1
  117. package/src/server/modules/better-auth/better-auth.resolver.ts +31 -31
  118. package/src/server/modules/user/user.service.ts +2 -2
  119. package/src/test/test.helper.ts +13 -1
  120. package/dist/core/modules/better-auth/better-auth-auth.model.d.ts +0 -9
  121. package/dist/core/modules/better-auth/better-auth-auth.model.js.map +0 -1
  122. package/dist/core/modules/better-auth/better-auth-migration-status.model.js.map +0 -1
  123. package/dist/core/modules/better-auth/better-auth-models.js.map +0 -1
  124. package/dist/core/modules/better-auth/better-auth-rate-limit.middleware.d.ts +0 -12
  125. package/dist/core/modules/better-auth/better-auth-rate-limit.middleware.js.map +0 -1
  126. package/dist/core/modules/better-auth/better-auth-rate-limiter.service.js.map +0 -1
  127. package/dist/core/modules/better-auth/better-auth-user.mapper.js.map +0 -1
  128. package/dist/core/modules/better-auth/better-auth.middleware.d.ts +0 -21
  129. package/dist/core/modules/better-auth/better-auth.middleware.js.map +0 -1
  130. package/dist/core/modules/better-auth/better-auth.module.js.map +0 -1
  131. package/dist/core/modules/better-auth/better-auth.service.js.map +0 -1
@@ -1,13 +1,15 @@
1
1
  import { Injectable, Logger, NestMiddleware } from '@nestjs/common';
2
2
  import { NextFunction, Request, Response } from 'express';
3
3
 
4
- import { BetterAuthSessionUser, BetterAuthUserMapper, MappedUser } from './better-auth-user.mapper';
5
- import { BetterAuthService } from './better-auth.service';
4
+ import { isProduction, maskEmail, maskToken } from '../../common/helpers/logging.helper';
5
+ import { BetterAuthSessionUser, CoreBetterAuthUserMapper, MappedUser } from './core-better-auth-user.mapper';
6
+ import { extractSessionToken } from './core-better-auth-web.helper';
7
+ import { CoreBetterAuthService } from './core-better-auth.service';
6
8
 
7
9
  /**
8
10
  * Extended Express Request with Better-Auth session data
9
11
  */
10
- export interface BetterAuthRequest extends Request {
12
+ export interface CoreBetterAuthRequest extends Request {
11
13
  betterAuthSession?: {
12
14
  session: any;
13
15
  user: BetterAuthSessionUser;
@@ -29,15 +31,16 @@ export interface BetterAuthRequest extends Request {
29
31
  * for RolesGuard and other security checks.
30
32
  */
31
33
  @Injectable()
32
- export class BetterAuthMiddleware implements NestMiddleware {
33
- private readonly logger = new Logger(BetterAuthMiddleware.name);
34
+ export class CoreBetterAuthMiddleware implements NestMiddleware {
35
+ private readonly logger = new Logger(CoreBetterAuthMiddleware.name);
36
+ private readonly isProd = isProduction();
34
37
 
35
38
  constructor(
36
- private readonly betterAuthService: BetterAuthService,
37
- private readonly userMapper: BetterAuthUserMapper,
39
+ private readonly betterAuthService: CoreBetterAuthService,
40
+ private readonly userMapper: CoreBetterAuthUserMapper,
38
41
  ) {}
39
42
 
40
- async use(req: BetterAuthRequest, _res: Response, next: NextFunction) {
43
+ async use(req: CoreBetterAuthRequest, _res: Response, next: NextFunction) {
41
44
  // Skip if Better-Auth is not enabled
42
45
  if (!this.betterAuthService.isEnabled()) {
43
46
  return next();
@@ -79,7 +82,7 @@ export class BetterAuthMiddleware implements NestMiddleware {
79
82
  // Check if token looks like a JWT (has 3 parts)
80
83
  if (tokenParts === 3) {
81
84
  // Decode JWT payload to check if it's a Legacy JWT or BetterAuth JWT
82
- // Legacy JWTs have 'id' claim, BetterAuth JWTs have 'sub' claim
85
+ // Legacy JWTs have 'id' claim, BetterAuth JWTs use 'sub'
83
86
  const isLegacyJwt = this.isLegacyJwt(token);
84
87
  if (isLegacyJwt) {
85
88
  // Legacy JWT - skip BetterAuth processing, let Passport handle it
@@ -131,7 +134,9 @@ export class BetterAuthMiddleware implements NestMiddleware {
131
134
  } catch (error) {
132
135
  // Don't block the request on auth errors
133
136
  // The guards will handle unauthorized access
134
- this.logger.debug(`Session validation failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
137
+ if (!this.isProd) {
138
+ this.logger.debug(`Session validation failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
139
+ }
135
140
  }
136
141
 
137
142
  next();
@@ -159,15 +164,48 @@ export class BetterAuthMiddleware implements NestMiddleware {
159
164
  }
160
165
 
161
166
  /**
162
- * Gets the session from Better-Auth
167
+ * Gets the session from Better-Auth using session token from cookies
168
+ *
169
+ * This method first tries to extract the session token from cookies
170
+ * (checking multiple cookie names for compatibility), then validates
171
+ * the session directly from the database using getSessionByToken().
163
172
  */
164
173
  private async getSession(req: Request): Promise<null | { session: any; user: BetterAuthSessionUser }> {
165
- const api = this.betterAuthService.getApi();
166
- if (!api) {
167
- return null;
168
- }
169
-
170
174
  try {
175
+ // Strategy 1: Try to get session token from cookies using shared helper
176
+ const basePath = this.betterAuthService.getBasePath();
177
+ const sessionToken = extractSessionToken(req, basePath);
178
+
179
+ if (!this.isProd) {
180
+ this.logger.debug(`[MIDDLEWARE] getSession called, token found: ${sessionToken ? 'yes' : 'no'}`);
181
+ }
182
+
183
+ if (sessionToken) {
184
+ if (!this.isProd) {
185
+ this.logger.debug(`[MIDDLEWARE] Found session token in cookies: ${maskToken(sessionToken)}`);
186
+ }
187
+
188
+ // Use getSessionByToken to validate session directly from database
189
+ const sessionResult = await this.betterAuthService.getSessionByToken(sessionToken);
190
+
191
+ if (!this.isProd) {
192
+ this.logger.debug(`[MIDDLEWARE] getSessionByToken result: user=${maskEmail(sessionResult?.user?.email)}, session=${!!sessionResult?.session}`);
193
+ }
194
+
195
+ if (sessionResult?.user && sessionResult?.session) {
196
+ if (!this.isProd) {
197
+ this.logger.debug(`[MIDDLEWARE] Session validated for user: ${maskEmail(sessionResult.user.email)}`);
198
+ }
199
+ return sessionResult as { session: any; user: BetterAuthSessionUser };
200
+ }
201
+ }
202
+
203
+ // Strategy 2: Fallback to api.getSession() for edge cases
204
+ const api = this.betterAuthService.getApi();
205
+ if (!api) {
206
+ return null;
207
+ }
208
+
171
209
  // Convert Express headers to the format Better-Auth expects
172
210
  const headers = new Headers();
173
211
  for (const [key, value] of Object.entries(req.headers)) {
@@ -187,7 +225,9 @@ export class BetterAuthMiddleware implements NestMiddleware {
187
225
 
188
226
  return null;
189
227
  } catch (error) {
190
- this.logger.debug(`getSession error: ${error instanceof Error ? error.message : 'Unknown error'}`);
228
+ if (!this.isProd) {
229
+ this.logger.debug(`getSession error: ${error instanceof Error ? error.message : 'Unknown error'}`);
230
+ }
191
231
  return null;
192
232
  }
193
233
  }
@@ -14,15 +14,16 @@ import mongoose, { Connection } from 'mongoose';
14
14
 
15
15
  import { IBetterAuth } from '../../common/interfaces/server-options.interface';
16
16
  import { ConfigService } from '../../common/services/config.service';
17
- import { BetterAuthRateLimitMiddleware } from './better-auth-rate-limit.middleware';
18
- import { BetterAuthRateLimiter } from './better-auth-rate-limiter.service';
19
- import { BetterAuthUserMapper } from './better-auth-user.mapper';
20
17
  import { BetterAuthInstance, createBetterAuthInstance } from './better-auth.config';
21
- import { BetterAuthMiddleware } from './better-auth.middleware';
22
- import { BetterAuthResolver } from './better-auth.resolver';
23
- import { BETTER_AUTH_CONFIG, BetterAuthService } from './better-auth.service';
18
+ import { DefaultBetterAuthResolver } from './better-auth.resolver';
19
+ import { CoreBetterAuthApiMiddleware } from './core-better-auth-api.middleware';
20
+ import { CoreBetterAuthRateLimitMiddleware } from './core-better-auth-rate-limit.middleware';
21
+ import { CoreBetterAuthRateLimiter } from './core-better-auth-rate-limiter.service';
22
+ import { CoreBetterAuthUserMapper } from './core-better-auth-user.mapper';
24
23
  import { CoreBetterAuthController } from './core-better-auth.controller';
24
+ import { CoreBetterAuthMiddleware } from './core-better-auth.middleware';
25
25
  import { CoreBetterAuthResolver } from './core-better-auth.resolver';
26
+ import { BETTER_AUTH_CONFIG, CoreBetterAuthService } from './core-better-auth.service';
26
27
 
27
28
  /**
28
29
  * Token for injecting the better-auth instance
@@ -30,9 +31,9 @@ import { CoreBetterAuthResolver } from './core-better-auth.resolver';
30
31
  export const BETTER_AUTH_INSTANCE = 'BETTER_AUTH_INSTANCE';
31
32
 
32
33
  /**
33
- * Options for BetterAuthModule.forRoot()
34
+ * Options for CoreBetterAuthModule.forRoot()
34
35
  */
35
- export interface BetterAuthModuleOptions {
36
+ export interface CoreBetterAuthModuleOptions {
36
37
  /**
37
38
  * Better-auth configuration.
38
39
  * Accepts:
@@ -59,7 +60,7 @@ export interface BetterAuthModuleOptions {
59
60
  * }
60
61
  *
61
62
  * // In your module
62
- * BetterAuthModule.forRoot({
63
+ * CoreBetterAuthModule.forRoot({
63
64
  * config: environment.betterAuth,
64
65
  * controller: MyBetterAuthController,
65
66
  * })
@@ -79,14 +80,14 @@ export interface BetterAuthModuleOptions {
79
80
  fallbackSecrets?: (string | undefined)[];
80
81
 
81
82
  /**
82
- * Custom resolver class to use instead of the default BetterAuthResolver.
83
+ * Custom resolver class to use instead of the default DefaultBetterAuthResolver.
83
84
  * The class must extend CoreBetterAuthResolver.
84
85
  *
85
86
  * @example
86
87
  * ```typescript
87
88
  * // Your custom resolver
88
89
  * @Resolver(() => BetterAuthAuthModel)
89
- * export class MyBetterAuthResolver extends CoreBetterAuthResolver {
90
+ * export class MyDefaultBetterAuthResolver extends CoreBetterAuthResolver {
90
91
  * override async betterAuthSignUp(...) {
91
92
  * const result = await super.betterAuthSignUp(...);
92
93
  * await this.sendWelcomeEmail(result.user);
@@ -95,9 +96,9 @@ export interface BetterAuthModuleOptions {
95
96
  * }
96
97
  *
97
98
  * // In your module
98
- * BetterAuthModule.forRoot({
99
+ * CoreBetterAuthModule.forRoot({
99
100
  * config: environment.betterAuth,
100
- * resolver: MyBetterAuthResolver,
101
+ * resolver: MyDefaultBetterAuthResolver,
101
102
  * })
102
103
  * ```
103
104
  */
@@ -119,7 +120,7 @@ function normalizeBetterAuthConfig(config: boolean | IBetterAuth | undefined): I
119
120
  }
120
121
 
121
122
  /**
122
- * BetterAuthModule provides integration with the better-auth authentication framework.
123
+ * CoreBetterAuthModule provides integration with the better-auth authentication framework.
123
124
  *
124
125
  * This module:
125
126
  * - Creates and configures a better-auth instance based on server configuration
@@ -134,7 +135,7 @@ function normalizeBetterAuthConfig(config: boolean | IBetterAuth | undefined): I
134
135
  * @Module({
135
136
  * imports: [
136
137
  * CoreModule.forRoot(...),
137
- * BetterAuthModule.forRoot({ config: environment.betterAuth }),
138
+ * CoreBetterAuthModule.forRoot({ config: environment.betterAuth }),
138
139
  * ],
139
140
  * })
140
141
  * export class AppModule {}
@@ -142,8 +143,8 @@ function normalizeBetterAuthConfig(config: boolean | IBetterAuth | undefined): I
142
143
  */
143
144
  @Global()
144
145
  @Module({})
145
- export class BetterAuthModule implements NestModule, OnModuleInit {
146
- private static logger = new Logger(BetterAuthModule.name);
146
+ export class CoreBetterAuthModule implements NestModule, OnModuleInit {
147
+ private static logger = new Logger(CoreBetterAuthModule.name);
147
148
  private static authInstance: BetterAuthInstance | null = null;
148
149
  private static initialized = false;
149
150
  private static initLogged = false;
@@ -163,45 +164,53 @@ export class BetterAuthModule implements NestModule, OnModuleInit {
163
164
  * Gets the resolver class to use (custom or default)
164
165
  */
165
166
  private static getResolverClass(): Type<CoreBetterAuthResolver> {
166
- return this.customResolver || BetterAuthResolver;
167
+ return this.customResolver || DefaultBetterAuthResolver;
167
168
  }
168
169
 
169
170
  constructor(
170
- @Optional() private readonly betterAuthService?: BetterAuthService,
171
- @Optional() private readonly rateLimiter?: BetterAuthRateLimiter,
171
+ @Optional() private readonly betterAuthService?: CoreBetterAuthService,
172
+ @Optional() private readonly rateLimiter?: CoreBetterAuthRateLimiter,
172
173
  ) {}
173
174
 
174
175
  onModuleInit() {
175
- if (BetterAuthModule.authInstance && !BetterAuthModule.initialized) {
176
- BetterAuthModule.initialized = true;
177
- BetterAuthModule.logger.log('BetterAuthModule ready');
176
+ if (CoreBetterAuthModule.authInstance && !CoreBetterAuthModule.initialized) {
177
+ CoreBetterAuthModule.initialized = true;
178
+ CoreBetterAuthModule.logger.log('CoreBetterAuthModule ready');
178
179
  }
179
180
 
180
181
  // Configure rate limiter with stored config
181
- if (this.rateLimiter && BetterAuthModule.currentConfig?.rateLimit) {
182
- this.rateLimiter.configure(BetterAuthModule.currentConfig.rateLimit);
182
+ if (this.rateLimiter && CoreBetterAuthModule.currentConfig?.rateLimit) {
183
+ this.rateLimiter.configure(CoreBetterAuthModule.currentConfig.rateLimit);
183
184
  }
184
185
  }
185
186
 
186
187
  /**
187
- * Configure middleware for Better-Auth session handling and rate limiting
188
- * The session middleware runs on all routes and maps Better-Auth sessions to users
189
- * The rate limit middleware runs only on Better-Auth endpoints
188
+ * Configure middleware for Better-Auth API handling, session validation, and rate limiting.
189
+ *
190
+ * Middleware order (important!):
191
+ * 1. CoreBetterAuthApiMiddleware - Forwards plugin endpoints (passkey, etc.) to Better Auth's native handler
192
+ * 2. CoreBetterAuthRateLimitMiddleware - Rate limiting for auth endpoints
193
+ * 3. CoreBetterAuthMiddleware - Session validation and user mapping for all routes
190
194
  */
191
195
  configure(consumer: MiddlewareConsumer) {
192
196
  // Only apply middleware if Better-Auth is enabled
193
- if (BetterAuthModule.betterAuthEnabled && this.betterAuthService?.isEnabled()) {
194
- const basePath = BetterAuthModule.currentConfig?.basePath || '/iam';
197
+ if (CoreBetterAuthModule.betterAuthEnabled && this.betterAuthService?.isEnabled()) {
198
+ const basePath = CoreBetterAuthModule.currentConfig?.basePath || '/iam';
199
+
200
+ // Apply API middleware to Better-Auth endpoints FIRST
201
+ // This handles plugin endpoints (passkey, social login, etc.) that are not defined in the controller
202
+ consumer.apply(CoreBetterAuthApiMiddleware).forRoutes(`${basePath}/*path`);
203
+ CoreBetterAuthModule.logger.debug(`CoreBetterAuthApiMiddleware registered for ${basePath}/*path endpoints`);
195
204
 
196
205
  // Apply rate limiting to Better-Auth endpoints only
197
- if (BetterAuthModule.currentConfig?.rateLimit?.enabled) {
198
- consumer.apply(BetterAuthRateLimitMiddleware).forRoutes(`${basePath}/*path`);
199
- BetterAuthModule.logger.debug(`Rate limiting middleware registered for ${basePath}/*path endpoints`);
206
+ if (CoreBetterAuthModule.currentConfig?.rateLimit?.enabled) {
207
+ consumer.apply(CoreBetterAuthRateLimitMiddleware).forRoutes(`${basePath}/*path`);
208
+ CoreBetterAuthModule.logger.debug(`Rate limiting middleware registered for ${basePath}/*path endpoints`);
200
209
  }
201
210
 
202
211
  // Apply session middleware to all routes
203
- consumer.apply(BetterAuthMiddleware).forRoutes('(.*)'); // New path-to-regexp syntax for wildcard
204
- BetterAuthModule.logger.debug('BetterAuthMiddleware registered for all routes');
212
+ consumer.apply(CoreBetterAuthMiddleware).forRoutes('(.*)'); // New path-to-regexp syntax for wildcard
213
+ CoreBetterAuthModule.logger.debug('CoreBetterAuthMiddleware registered for all routes');
205
214
  }
206
215
  }
207
216
 
@@ -241,7 +250,7 @@ export class BetterAuthModule implements NestModule, OnModuleInit {
241
250
  * @param options - Configuration options
242
251
  * @returns Dynamic module configuration
243
252
  */
244
- static forRoot(options: BetterAuthModuleOptions): DynamicModule {
253
+ static forRoot(options: CoreBetterAuthModuleOptions): DynamicModule {
245
254
  const { config: rawConfig, controller, fallbackSecrets, resolver } = options;
246
255
 
247
256
  // Normalize config: true → {}, false/undefined → null
@@ -255,14 +264,14 @@ export class BetterAuthModule implements NestModule, OnModuleInit {
255
264
  this.customResolver = resolver || null;
256
265
 
257
266
  // If better-auth is disabled (config is null or enabled: false), return minimal module
258
- // Note: We don't provide middleware classes when disabled because they depend on BetterAuthService
267
+ // Note: We don't provide middleware classes when disabled because they depend on CoreBetterAuthService
259
268
  // and won't be used anyway (middleware is only applied when enabled)
260
269
  if (config === null || config?.enabled === false) {
261
270
  this.logger.debug('BetterAuth is disabled - skipping initialization');
262
271
  this.betterAuthEnabled = false;
263
272
  return {
264
- exports: [BETTER_AUTH_INSTANCE, BetterAuthService, BetterAuthUserMapper, BetterAuthRateLimiter],
265
- module: BetterAuthModule,
273
+ exports: [BETTER_AUTH_INSTANCE, CoreBetterAuthService, CoreBetterAuthUserMapper, CoreBetterAuthRateLimiter],
274
+ module: CoreBetterAuthModule,
266
275
  providers: [
267
276
  {
268
277
  provide: BETTER_AUTH_INSTANCE,
@@ -270,9 +279,9 @@ export class BetterAuthModule implements NestModule, OnModuleInit {
270
279
  },
271
280
  // Note: ConfigService is provided globally by CoreModule
272
281
  // Tests need to provide their own ConfigService
273
- BetterAuthService,
274
- BetterAuthUserMapper,
275
- BetterAuthRateLimiter,
282
+ CoreBetterAuthService,
283
+ CoreBetterAuthUserMapper,
284
+ CoreBetterAuthRateLimiter,
276
285
  ],
277
286
  };
278
287
  }
@@ -297,9 +306,9 @@ export class BetterAuthModule implements NestModule, OnModuleInit {
297
306
  static forRootAsync(): DynamicModule {
298
307
  return {
299
308
  controllers: [this.getControllerClass()],
300
- exports: [BETTER_AUTH_INSTANCE, BetterAuthService, BetterAuthUserMapper, BetterAuthRateLimiter],
309
+ exports: [BETTER_AUTH_INSTANCE, CoreBetterAuthService, CoreBetterAuthUserMapper, CoreBetterAuthRateLimiter],
301
310
  imports: [],
302
- module: BetterAuthModule,
311
+ module: CoreBetterAuthModule,
303
312
  providers: [
304
313
  {
305
314
  inject: [ConfigService],
@@ -337,7 +346,7 @@ export class BetterAuthModule implements NestModule, OnModuleInit {
337
346
  this.authInstance = createBetterAuthInstance({ config, db, fallbackSecrets });
338
347
 
339
348
  // IMPORTANT: Store the config AFTER createBetterAuthInstance mutates it
340
- // This ensures BetterAuthService has access to the resolved secret (with fallback applied)
349
+ // This ensures CoreBetterAuthService has access to the resolved secret (with fallback applied)
341
350
  this.currentConfig = config;
342
351
 
343
352
  if (this.authInstance) {
@@ -348,28 +357,29 @@ export class BetterAuthModule implements NestModule, OnModuleInit {
348
357
  return this.authInstance;
349
358
  },
350
359
  },
351
- // Provide the resolved config for BetterAuthService
360
+ // Provide the resolved config for CoreBetterAuthService
352
361
  {
353
362
  provide: BETTER_AUTH_CONFIG,
354
363
  useFactory: () => this.currentConfig,
355
364
  },
356
- // BetterAuthService needs to be a factory that explicitly depends on BETTER_AUTH_INSTANCE
365
+ // CoreBetterAuthService needs to be a factory that explicitly depends on BETTER_AUTH_INSTANCE
357
366
  // to ensure proper initialization order
358
367
  {
359
368
  inject: [BETTER_AUTH_INSTANCE, BETTER_AUTH_CONFIG, getConnectionToken()],
360
- provide: BetterAuthService,
369
+ provide: CoreBetterAuthService,
361
370
  useFactory: (
362
371
  authInstance: BetterAuthInstance | null,
363
372
  resolvedConfig: IBetterAuth | null,
364
373
  connection: Connection,
365
374
  ) => {
366
- return new BetterAuthService(authInstance, connection, resolvedConfig);
375
+ return new CoreBetterAuthService(authInstance, connection, resolvedConfig);
367
376
  },
368
377
  },
369
- BetterAuthUserMapper,
370
- BetterAuthMiddleware,
371
- BetterAuthRateLimiter,
372
- BetterAuthRateLimitMiddleware,
378
+ CoreBetterAuthUserMapper,
379
+ CoreBetterAuthMiddleware,
380
+ CoreBetterAuthApiMiddleware,
381
+ CoreBetterAuthRateLimiter,
382
+ CoreBetterAuthRateLimitMiddleware,
373
383
  this.getResolverClass(),
374
384
  ],
375
385
  };
@@ -384,13 +394,13 @@ export class BetterAuthModule implements NestModule, OnModuleInit {
384
394
  }
385
395
 
386
396
  /**
387
- * Resets the static state of BetterAuthModule
397
+ * Resets the static state of CoreBetterAuthModule
388
398
  * This is primarily useful for testing to ensure clean state between tests
389
399
  *
390
400
  * @example
391
401
  * ```typescript
392
402
  * afterEach(() => {
393
- * BetterAuthModule.reset();
403
+ * CoreBetterAuthModule.reset();
394
404
  * });
395
405
  * ```
396
406
  */
@@ -411,8 +421,8 @@ export class BetterAuthModule implements NestModule, OnModuleInit {
411
421
  private static createDeferredModule(config: IBetterAuth, fallbackSecrets?: (string | undefined)[]): DynamicModule {
412
422
  return {
413
423
  controllers: [this.getControllerClass()],
414
- exports: [BETTER_AUTH_INSTANCE, BetterAuthService, BetterAuthUserMapper, BetterAuthRateLimiter],
415
- module: BetterAuthModule,
424
+ exports: [BETTER_AUTH_INSTANCE, CoreBetterAuthService, CoreBetterAuthUserMapper, CoreBetterAuthRateLimiter],
425
+ module: CoreBetterAuthModule,
416
426
  providers: [
417
427
  {
418
428
  // Inject Mongoose Connection to ensure NestJS waits for it to be ready
@@ -434,7 +444,7 @@ export class BetterAuthModule implements NestModule, OnModuleInit {
434
444
  }
435
445
 
436
446
  // IMPORTANT: Store the config AFTER createBetterAuthInstance mutates it
437
- // This ensures BetterAuthService has access to the resolved secret (with fallback applied)
447
+ // This ensures CoreBetterAuthService has access to the resolved secret (with fallback applied)
438
448
  this.currentConfig = config;
439
449
 
440
450
  if (this.authInstance && !this.initLogged) {
@@ -446,28 +456,29 @@ export class BetterAuthModule implements NestModule, OnModuleInit {
446
456
  return this.authInstance;
447
457
  },
448
458
  },
449
- // Provide the resolved config for BetterAuthService
459
+ // Provide the resolved config for CoreBetterAuthService
450
460
  {
451
461
  provide: BETTER_AUTH_CONFIG,
452
462
  useFactory: () => this.currentConfig,
453
463
  },
454
- // BetterAuthService needs to be a factory that explicitly depends on BETTER_AUTH_INSTANCE
464
+ // CoreBetterAuthService needs to be a factory that explicitly depends on BETTER_AUTH_INSTANCE
455
465
  // to ensure proper initialization order
456
466
  {
457
467
  inject: [BETTER_AUTH_INSTANCE, BETTER_AUTH_CONFIG, getConnectionToken()],
458
- provide: BetterAuthService,
468
+ provide: CoreBetterAuthService,
459
469
  useFactory: (
460
470
  authInstance: BetterAuthInstance | null,
461
471
  resolvedConfig: IBetterAuth | null,
462
472
  connection: Connection,
463
473
  ) => {
464
- return new BetterAuthService(authInstance, connection, resolvedConfig);
474
+ return new CoreBetterAuthService(authInstance, connection, resolvedConfig);
465
475
  },
466
476
  },
467
- BetterAuthUserMapper,
468
- BetterAuthMiddleware,
469
- BetterAuthRateLimiter,
470
- BetterAuthRateLimitMiddleware,
477
+ CoreBetterAuthUserMapper,
478
+ CoreBetterAuthMiddleware,
479
+ CoreBetterAuthApiMiddleware,
480
+ CoreBetterAuthRateLimiter,
481
+ CoreBetterAuthRateLimitMiddleware,
471
482
  this.getResolverClass(),
472
483
  ],
473
484
  };