@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
@@ -3,17 +3,17 @@ import { Request, Response } from 'express';
3
3
 
4
4
  import { Roles } from '../../common/decorators/roles.decorator';
5
5
  import { RoleEnum } from '../../common/enums/role.enum';
6
- import { BetterAuthAuthModel } from './better-auth-auth.model';
6
+ import { CoreBetterAuthAuthModel } from './core-better-auth-auth.model';
7
7
  import {
8
- BetterAuth2FASetupModel,
9
- BetterAuthFeaturesModel,
10
- BetterAuthPasskeyChallengeModel,
11
- BetterAuthPasskeyModel,
12
- BetterAuthSessionModel,
13
- } from './better-auth-models';
14
- import { BetterAuthUserMapper } from './better-auth-user.mapper';
15
- import { BetterAuthService } from './better-auth.service';
8
+ CoreBetterAuth2FASetupModel,
9
+ CoreBetterAuthFeaturesModel,
10
+ CoreBetterAuthPasskeyChallengeModel,
11
+ CoreBetterAuthPasskeyModel,
12
+ CoreBetterAuthSessionModel,
13
+ } from './core-better-auth-models';
14
+ import { CoreBetterAuthUserMapper } from './core-better-auth-user.mapper';
16
15
  import { CoreBetterAuthResolver } from './core-better-auth.resolver';
16
+ import { CoreBetterAuthService } from './core-better-auth.service';
17
17
 
18
18
  /**
19
19
  * Default BetterAuth GraphQL Resolver
@@ -28,11 +28,11 @@ import { CoreBetterAuthResolver } from './core-better-auth.resolver';
28
28
  * @example
29
29
  * ```typescript
30
30
  * // In your project - src/server/modules/better-auth/better-auth.resolver.ts
31
- * @Resolver(() => BetterAuthAuthModel)
31
+ * @Resolver(() => CoreBetterAuthAuthModel)
32
32
  * export class BetterAuthResolver extends CoreBetterAuthResolver {
33
33
  * constructor(
34
- * betterAuthService: BetterAuthService,
35
- * userMapper: BetterAuthUserMapper,
34
+ * betterAuthService: CoreBetterAuthService,
35
+ * userMapper: CoreBetterAuthUserMapper,
36
36
  * private readonly emailService: EmailService,
37
37
  * ) {
38
38
  * super(betterAuthService, userMapper);
@@ -51,12 +51,12 @@ import { CoreBetterAuthResolver } from './core-better-auth.resolver';
51
51
  * }
52
52
  * ```
53
53
  */
54
- @Resolver(() => BetterAuthAuthModel)
54
+ @Resolver(() => CoreBetterAuthAuthModel)
55
55
  @Roles(RoleEnum.ADMIN)
56
- export class BetterAuthResolver extends CoreBetterAuthResolver {
56
+ export class DefaultBetterAuthResolver extends CoreBetterAuthResolver {
57
57
  constructor(
58
- protected override readonly betterAuthService: BetterAuthService,
59
- protected override readonly userMapper: BetterAuthUserMapper,
58
+ protected override readonly betterAuthService: CoreBetterAuthService,
59
+ protected override readonly userMapper: CoreBetterAuthUserMapper,
60
60
  ) {
61
61
  super(betterAuthService, userMapper);
62
62
  }
@@ -65,12 +65,12 @@ export class BetterAuthResolver extends CoreBetterAuthResolver {
65
65
  // Queries
66
66
  // ===========================================================================
67
67
 
68
- @Query(() => BetterAuthSessionModel, {
68
+ @Query(() => CoreBetterAuthSessionModel, {
69
69
  description: 'Get current Better-Auth session',
70
70
  nullable: true,
71
71
  })
72
72
  @Roles(RoleEnum.S_USER)
73
- override async betterAuthSession(@Context() ctx: { req: Request }): Promise<BetterAuthSessionModel | null> {
73
+ override async betterAuthSession(@Context() ctx: { req: Request }): Promise<CoreBetterAuthSessionModel | null> {
74
74
  return super.betterAuthSession(ctx);
75
75
  }
76
76
 
@@ -80,18 +80,18 @@ export class BetterAuthResolver extends CoreBetterAuthResolver {
80
80
  return super.betterAuthEnabled();
81
81
  }
82
82
 
83
- @Query(() => BetterAuthFeaturesModel, { description: 'Get enabled Better-Auth features' })
83
+ @Query(() => CoreBetterAuthFeaturesModel, { description: 'Get enabled Better-Auth features' })
84
84
  @Roles(RoleEnum.S_EVERYONE)
85
- override betterAuthFeatures(): BetterAuthFeaturesModel {
85
+ override betterAuthFeatures(): CoreBetterAuthFeaturesModel {
86
86
  return super.betterAuthFeatures();
87
87
  }
88
88
 
89
- @Query(() => [BetterAuthPasskeyModel], {
89
+ @Query(() => [CoreBetterAuthPasskeyModel], {
90
90
  description: 'List passkeys for the current user',
91
91
  nullable: true,
92
92
  })
93
93
  @Roles(RoleEnum.S_USER)
94
- override async betterAuthListPasskeys(@Context() ctx: { req: Request }): Promise<BetterAuthPasskeyModel[] | null> {
94
+ override async betterAuthListPasskeys(@Context() ctx: { req: Request }): Promise<CoreBetterAuthPasskeyModel[] | null> {
95
95
  return super.betterAuthListPasskeys(ctx);
96
96
  }
97
97
 
@@ -99,7 +99,7 @@ export class BetterAuthResolver extends CoreBetterAuthResolver {
99
99
  // Authentication Mutations
100
100
  // ===========================================================================
101
101
 
102
- @Mutation(() => BetterAuthAuthModel, {
102
+ @Mutation(() => CoreBetterAuthAuthModel, {
103
103
  description: 'Sign in via Better-Auth (email/password)',
104
104
  })
105
105
  @Roles(RoleEnum.S_EVERYONE)
@@ -107,11 +107,11 @@ export class BetterAuthResolver extends CoreBetterAuthResolver {
107
107
  @Args('email') email: string,
108
108
  @Args('password') password: string,
109
109
  @Context() ctx: { req: Request; res: Response },
110
- ): Promise<BetterAuthAuthModel> {
110
+ ): Promise<CoreBetterAuthAuthModel> {
111
111
  return super.betterAuthSignIn(email, password, ctx);
112
112
  }
113
113
 
114
- @Mutation(() => BetterAuthAuthModel, {
114
+ @Mutation(() => CoreBetterAuthAuthModel, {
115
115
  description: 'Sign up via Better-Auth (email/password)',
116
116
  })
117
117
  @Roles(RoleEnum.S_EVERYONE)
@@ -119,7 +119,7 @@ export class BetterAuthResolver extends CoreBetterAuthResolver {
119
119
  @Args('email') email: string,
120
120
  @Args('password') password: string,
121
121
  @Args('name', { nullable: true }) name?: string,
122
- ): Promise<BetterAuthAuthModel> {
122
+ ): Promise<CoreBetterAuthAuthModel> {
123
123
  return super.betterAuthSignUp(email, password, name);
124
124
  }
125
125
 
@@ -133,25 +133,25 @@ export class BetterAuthResolver extends CoreBetterAuthResolver {
133
133
  // 2FA Mutations
134
134
  // ===========================================================================
135
135
 
136
- @Mutation(() => BetterAuthAuthModel, {
136
+ @Mutation(() => CoreBetterAuthAuthModel, {
137
137
  description: 'Verify 2FA code during sign-in',
138
138
  })
139
139
  @Roles(RoleEnum.S_EVERYONE)
140
140
  override async betterAuthVerify2FA(
141
141
  @Args('code') code: string,
142
142
  @Context() ctx: { req: Request },
143
- ): Promise<BetterAuthAuthModel> {
143
+ ): Promise<CoreBetterAuthAuthModel> {
144
144
  return super.betterAuthVerify2FA(code, ctx);
145
145
  }
146
146
 
147
- @Mutation(() => BetterAuth2FASetupModel, {
147
+ @Mutation(() => CoreBetterAuth2FASetupModel, {
148
148
  description: 'Enable 2FA for the current user',
149
149
  })
150
150
  @Roles(RoleEnum.S_USER)
151
151
  override async betterAuthEnable2FA(
152
152
  @Args('password') password: string,
153
153
  @Context() ctx: { req: Request },
154
- ): Promise<BetterAuth2FASetupModel> {
154
+ ): Promise<CoreBetterAuth2FASetupModel> {
155
155
  return super.betterAuthEnable2FA(password, ctx);
156
156
  }
157
157
 
@@ -179,13 +179,13 @@ export class BetterAuthResolver extends CoreBetterAuthResolver {
179
179
  // Passkey Mutations
180
180
  // ===========================================================================
181
181
 
182
- @Mutation(() => BetterAuthPasskeyChallengeModel, {
182
+ @Mutation(() => CoreBetterAuthPasskeyChallengeModel, {
183
183
  description: 'Get passkey registration challenge for WebAuthn',
184
184
  })
185
185
  @Roles(RoleEnum.S_USER)
186
186
  override async betterAuthGetPasskeyChallenge(
187
187
  @Context() ctx: { req: Request },
188
- ): Promise<BetterAuthPasskeyChallengeModel> {
188
+ ): Promise<CoreBetterAuthPasskeyChallengeModel> {
189
189
  return super.betterAuthGetPasskeyChallenge(ctx);
190
190
  }
191
191
 
@@ -5,7 +5,7 @@
5
5
  * and reduce the need for `as any` casts throughout the codebase.
6
6
  */
7
7
 
8
- import { BetterAuthSessionUser } from './better-auth-user.mapper';
8
+ import { BetterAuthSessionUser } from './core-better-auth-user.mapper';
9
9
 
10
10
  /**
11
11
  * Better-Auth 2FA verification response
@@ -68,8 +68,9 @@ export interface BetterAuthSignUpResponse {
68
68
  /**
69
69
  * Type guard to check if response has session
70
70
  * Preserves the original type while asserting session is defined
71
+ * Includes optional token for Better Auth session authentication
71
72
  */
72
- export function hasSession<T>(response: T): response is T & { session: { expiresAt: Date; id: string } } {
73
+ export function hasSession<T>(response: T): response is T & { session: { expiresAt: Date; id: string; token?: string } } {
73
74
  return (
74
75
  response !== null &&
75
76
  typeof response === 'object' &&
@@ -0,0 +1,134 @@
1
+ import { Injectable, Logger, NestMiddleware } from '@nestjs/common';
2
+ import { NextFunction, Request, Response } from 'express';
3
+
4
+ import { isProduction } from '../../common/helpers/logging.helper';
5
+ import { extractSessionToken, sendWebResponse, toWebRequest } from './core-better-auth-web.helper';
6
+ import { CoreBetterAuthService } from './core-better-auth.service';
7
+
8
+ /**
9
+ * List of paths that are handled by CoreBetterAuthController
10
+ * These should NOT be forwarded to Better Auth's native handler
11
+ *
12
+ * Only paths with nest-server-specific logic belong here:
13
+ * - sign-in/email: Legacy user migration, password normalization
14
+ * - sign-up/email: User linking to own DB, password sync
15
+ * - sign-out: Custom cookie clearing
16
+ * - session: Custom response format with mapped user
17
+ *
18
+ * All other paths (Passkey, 2FA, etc.) go directly to Better Auth's
19
+ * native handler via this middleware for maximum compatibility.
20
+ */
21
+ const CONTROLLER_HANDLED_PATHS = [
22
+ '/sign-in/email',
23
+ '/sign-up/email',
24
+ '/sign-out',
25
+ '/session',
26
+ ];
27
+
28
+ /**
29
+ * Middleware that forwards Better Auth API requests to the native Better Auth handler.
30
+ *
31
+ * This middleware handles ALL Better Auth plugin functionality directly:
32
+ * - Passkey/WebAuthn (registration, authentication, management)
33
+ * - Two-Factor Authentication (TOTP enable, disable, verify)
34
+ * - Social Login OAuth flows
35
+ * - Magic link authentication
36
+ * - Email verification
37
+ *
38
+ * The middleware:
39
+ * 1. Checks if the request path starts with the Better Auth base path (e.g., /iam)
40
+ * 2. Skips paths that need nest-server-specific logic (sign-in, sign-up, session)
41
+ * 3. Extracts session token and signs cookies for Better Auth compatibility
42
+ * 4. Converts the Express request to a Web Standard Request
43
+ * 5. Calls Better Auth's native handler and sends the response
44
+ *
45
+ * IMPORTANT: Cookie signing is handled here to ensure Better Auth receives
46
+ * properly signed session cookies for all plugin endpoints.
47
+ */
48
+ @Injectable()
49
+ export class CoreBetterAuthApiMiddleware implements NestMiddleware {
50
+ private readonly logger = new Logger(CoreBetterAuthApiMiddleware.name);
51
+ private readonly isProd = isProduction();
52
+
53
+ constructor(private readonly betterAuthService: CoreBetterAuthService) {}
54
+
55
+ async use(req: Request, res: Response, next: NextFunction) {
56
+ // Skip if Better-Auth is not enabled
57
+ if (!this.betterAuthService.isEnabled()) {
58
+ return next();
59
+ }
60
+
61
+ const basePath = this.betterAuthService.getBasePath();
62
+ const requestPath = req.path;
63
+
64
+ // Only handle requests that start with the Better Auth base path
65
+ if (!requestPath.startsWith(basePath)) {
66
+ return next();
67
+ }
68
+
69
+ // Get the path relative to the base path
70
+ const relativePath = requestPath.slice(basePath.length);
71
+
72
+ // Skip paths that are handled by CoreBetterAuthController (nest-server-specific logic)
73
+ if (CONTROLLER_HANDLED_PATHS.some((path) => relativePath === path || relativePath.startsWith(`${path}/`))) {
74
+ return next();
75
+ }
76
+
77
+ // Get the Better Auth instance
78
+ const authInstance = this.betterAuthService.getInstance();
79
+ if (!authInstance) {
80
+ this.logger.warn('Better Auth instance not available');
81
+ return next();
82
+ }
83
+
84
+ if (!this.isProd) {
85
+ this.logger.debug(`Forwarding to Better Auth handler: ${req.method} ${requestPath}`);
86
+ }
87
+
88
+ try {
89
+ // Extract session token from cookies or Authorization header
90
+ const sessionToken = extractSessionToken(req, basePath);
91
+
92
+ // Get config for cookie signing
93
+ const config = this.betterAuthService.getConfig();
94
+
95
+ // Convert Express request to Web Standard Request with proper cookie signing
96
+ // This ensures Better Auth receives signed cookies for session validation
97
+ const webRequest = await toWebRequest(req, {
98
+ basePath,
99
+ baseUrl: this.betterAuthService.getBaseUrl(),
100
+ logger: this.logger,
101
+ secret: config.secret,
102
+ sessionToken,
103
+ });
104
+
105
+ // Call Better Auth's native handler
106
+ const response = await authInstance.handler(webRequest);
107
+
108
+ if (!this.isProd) {
109
+ this.logger.debug(`Better Auth handler response: ${response.status}`);
110
+ }
111
+
112
+ // Convert Web Standard Response to Express response using shared helper
113
+ await sendWebResponse(res, response);
114
+ } catch (error) {
115
+ // Log error with appropriate detail level
116
+ if (this.isProd) {
117
+ this.logger.error('Better Auth handler error');
118
+ } else {
119
+ this.logger.error(`Better Auth handler error: ${error instanceof Error ? error.message : 'Unknown error'}`);
120
+ }
121
+
122
+ // Send error response if headers not sent
123
+ if (!res.headersSent) {
124
+ const message = this.isProd
125
+ ? 'Authentication error'
126
+ : (error instanceof Error ? error.message : 'Unknown error');
127
+ res.status(500).json({
128
+ error: 'Authentication handler error',
129
+ message,
130
+ });
131
+ }
132
+ }
133
+ }
134
+ }
@@ -2,7 +2,7 @@ import { Field, ObjectType } from '@nestjs/graphql';
2
2
 
3
3
  import { Restricted } from '../../common/decorators/restricted.decorator';
4
4
  import { RoleEnum } from '../../common/enums/role.enum';
5
- import { BetterAuthSessionInfoModel, BetterAuthUserModel } from './better-auth-models';
5
+ import { CoreBetterAuthSessionInfoModel, CoreBetterAuthUserModel } from './core-better-auth-models';
6
6
 
7
7
  /**
8
8
  * Better-Auth Authentication Response Model
@@ -13,7 +13,7 @@ import { BetterAuthSessionInfoModel, BetterAuthUserModel } from './better-auth-m
13
13
  */
14
14
  @ObjectType({ description: 'Better-Auth Authentication Response' })
15
15
  @Restricted(RoleEnum.S_EVERYONE)
16
- export class BetterAuthAuthModel {
16
+ export class CoreBetterAuthAuthModel {
17
17
  /**
18
18
  * Whether the authentication was successful
19
19
  */
@@ -43,20 +43,20 @@ export class BetterAuthAuthModel {
43
43
  /**
44
44
  * Authenticated user
45
45
  */
46
- @Field(() => BetterAuthUserModel, {
46
+ @Field(() => CoreBetterAuthUserModel, {
47
47
  description: 'Authenticated user',
48
48
  nullable: true,
49
49
  })
50
- user?: BetterAuthUserModel;
50
+ user?: CoreBetterAuthUserModel;
51
51
 
52
52
  /**
53
53
  * Session information
54
54
  */
55
- @Field(() => BetterAuthSessionInfoModel, {
55
+ @Field(() => CoreBetterAuthSessionInfoModel, {
56
56
  description: 'Session information',
57
57
  nullable: true,
58
58
  })
59
- session?: BetterAuthSessionInfoModel;
59
+ session?: CoreBetterAuthSessionInfoModel;
60
60
 
61
61
  /**
62
62
  * Error message if authentication failed
@@ -8,7 +8,7 @@ import { Field, Int, ObjectType } from '@nestjs/graphql';
8
8
  * safe to disable Legacy Auth.
9
9
  */
10
10
  @ObjectType({ description: 'Migration status from Legacy Auth to Better-Auth (IAM)' })
11
- export class BetterAuthMigrationStatusModel {
11
+ export class CoreBetterAuthMigrationStatusModel {
12
12
  /**
13
13
  * Total number of users in the system
14
14
  */
@@ -8,7 +8,7 @@ import { RoleEnum } from '../../common/enums/role.enum';
8
8
  */
9
9
  @ObjectType({ description: 'Better-Auth User' })
10
10
  @Restricted(RoleEnum.S_EVERYONE)
11
- export class BetterAuthUserModel {
11
+ export class CoreBetterAuthUserModel {
12
12
  @Field(() => String, { description: 'User ID' })
13
13
  id: string;
14
14
 
@@ -36,15 +36,15 @@ export class BetterAuthUserModel {
36
36
  */
37
37
  @ObjectType({ description: 'Better-Auth Session' })
38
38
  @Restricted(RoleEnum.S_USER)
39
- export class BetterAuthSessionModel {
39
+ export class CoreBetterAuthSessionModel {
40
40
  @Field(() => String, { description: 'Session ID' })
41
41
  id: string;
42
42
 
43
43
  @Field(() => Date, { description: 'Session expiration date' })
44
44
  expiresAt: Date;
45
45
 
46
- @Field(() => BetterAuthUserModel, { description: 'Session user' })
47
- user: BetterAuthUserModel;
46
+ @Field(() => CoreBetterAuthUserModel, { description: 'Session user' })
47
+ user: CoreBetterAuthUserModel;
48
48
  }
49
49
 
50
50
  /**
@@ -52,7 +52,7 @@ export class BetterAuthSessionModel {
52
52
  */
53
53
  @ObjectType({ description: 'Better-Auth Session Info' })
54
54
  @Restricted(RoleEnum.S_EVERYONE)
55
- export class BetterAuthSessionInfoModel {
55
+ export class CoreBetterAuthSessionInfoModel {
56
56
  @Field(() => String, { description: 'Session ID', nullable: true })
57
57
  id?: string;
58
58
 
@@ -68,7 +68,7 @@ export class BetterAuthSessionInfoModel {
68
68
  */
69
69
  @ObjectType({ description: 'Better-Auth 2FA setup data' })
70
70
  @Restricted(RoleEnum.S_USER)
71
- export class BetterAuth2FASetupModel {
71
+ export class CoreBetterAuth2FASetupModel {
72
72
  @Field(() => Boolean, { description: 'Whether the operation was successful' })
73
73
  success: boolean;
74
74
 
@@ -87,7 +87,7 @@ export class BetterAuth2FASetupModel {
87
87
  */
88
88
  @ObjectType({ description: 'Better-Auth Passkey' })
89
89
  @Restricted(RoleEnum.S_USER)
90
- export class BetterAuthPasskeyModel {
90
+ export class CoreBetterAuthPasskeyModel {
91
91
  @Field(() => String, { description: 'Passkey ID' })
92
92
  id: string;
93
93
 
@@ -106,7 +106,7 @@ export class BetterAuthPasskeyModel {
106
106
  */
107
107
  @ObjectType({ description: 'Better-Auth Passkey registration challenge' })
108
108
  @Restricted(RoleEnum.S_USER)
109
- export class BetterAuthPasskeyChallengeModel {
109
+ export class CoreBetterAuthPasskeyChallengeModel {
110
110
  @Field(() => Boolean, { description: 'Whether the operation was successful' })
111
111
  success: boolean;
112
112
 
@@ -122,7 +122,7 @@ export class BetterAuthPasskeyChallengeModel {
122
122
  */
123
123
  @ObjectType({ description: 'Better-Auth features status' })
124
124
  @Restricted(RoleEnum.S_EVERYONE)
125
- export class BetterAuthFeaturesModel {
125
+ export class CoreBetterAuthFeaturesModel {
126
126
  @Field(() => Boolean, { description: 'Whether Better-Auth is enabled' })
127
127
  enabled: boolean;
128
128
 
@@ -1,8 +1,8 @@
1
1
  import { HttpException, HttpStatus, Injectable, NestMiddleware } from '@nestjs/common';
2
2
  import { NextFunction, Request, Response } from 'express';
3
3
 
4
- import { BetterAuthRateLimiter, RateLimitResult } from './better-auth-rate-limiter.service';
5
- import { BetterAuthService } from './better-auth.service';
4
+ import { CoreBetterAuthRateLimiter, RateLimitResult } from './core-better-auth-rate-limiter.service';
5
+ import { CoreBetterAuthService } from './core-better-auth.service';
6
6
 
7
7
  /**
8
8
  * Middleware that applies rate limiting to Better-Auth endpoints
@@ -30,10 +30,10 @@ import { BetterAuthService } from './better-auth.service';
30
30
  * ```
31
31
  */
32
32
  @Injectable()
33
- export class BetterAuthRateLimitMiddleware implements NestMiddleware {
33
+ export class CoreBetterAuthRateLimitMiddleware implements NestMiddleware {
34
34
  constructor(
35
- private readonly rateLimiter: BetterAuthRateLimiter,
36
- private readonly betterAuthService: BetterAuthService,
35
+ private readonly rateLimiter: CoreBetterAuthRateLimiter,
36
+ private readonly betterAuthService: CoreBetterAuthService,
37
37
  ) {}
38
38
 
39
39
  use(req: Request, res: Response, next: NextFunction) {
@@ -74,8 +74,8 @@ const DEFAULT_CONFIG: Required<IBetterAuthRateLimit> = {
74
74
  * ```
75
75
  */
76
76
  @Injectable()
77
- export class BetterAuthRateLimiter {
78
- private readonly logger = new Logger(BetterAuthRateLimiter.name);
77
+ export class CoreBetterAuthRateLimiter {
78
+ private readonly logger = new Logger(CoreBetterAuthRateLimiter.name);
79
79
  private readonly store = new Map<string, RateLimitEntry>();
80
80
  private config: Required<IBetterAuthRateLimit> = DEFAULT_CONFIG;
81
81
  private cleanupInterval: NodeJS.Timeout | null = null;
@@ -17,6 +17,7 @@ const scryptPromise = (password: string, salt: string, keylen: number, options:
17
17
  };
18
18
 
19
19
  import { RoleEnum } from '../../common/enums/role.enum';
20
+ import { maskEmail } from '../../common/helpers/logging.helper';
20
21
 
21
22
  /**
22
23
  * Interface for Better-Auth session user
@@ -97,8 +98,8 @@ export interface SyncedUserDocument {
97
98
  * - Legacy → IAM: Creates account entry in `accounts` from `users.password`
98
99
  */
99
100
  @Injectable()
100
- export class BetterAuthUserMapper {
101
- private readonly logger = new Logger(BetterAuthUserMapper.name);
101
+ export class CoreBetterAuthUserMapper {
102
+ private readonly logger = new Logger(CoreBetterAuthUserMapper.name);
102
103
 
103
104
  constructor(@Optional() @InjectConnection() private readonly connection?: Connection) {}
104
105
 
@@ -379,7 +380,7 @@ export class BetterAuthUserMapper {
379
380
  const sha256Match = await bcrypt.compare(sha256(plainPassword), legacyUser.password);
380
381
  if (!directMatch && !sha256Match) {
381
382
  // Security: Wrong password provided for migration - reject
382
- this.logger.warn(`Migration password verification failed for ${userEmail}`);
383
+ this.logger.warn(`Migration password verification failed for ${maskEmail(userEmail)}`);
383
384
  return false;
384
385
  }
385
386
  } else {