@lenne.tech/nest-server 11.6.2 → 11.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/dist/config.env.js +19 -12
  2. package/dist/config.env.js.map +1 -1
  3. package/dist/core/common/helpers/filter.helper.d.ts +9 -9
  4. package/dist/core/common/helpers/filter.helper.js +2 -4
  5. package/dist/core/common/helpers/filter.helper.js.map +1 -1
  6. package/dist/core/common/helpers/gridfs.helper.js +3 -3
  7. package/dist/core/common/helpers/gridfs.helper.js.map +1 -1
  8. package/dist/core/common/interfaces/server-options.interface.d.ts +21 -3
  9. package/dist/core/common/services/crud.service.d.ts +16 -16
  10. package/dist/core/common/services/crud.service.js +1 -1
  11. package/dist/core/common/services/crud.service.js.map +1 -1
  12. package/dist/core/modules/auth/core-auth.controller.d.ts +1 -0
  13. package/dist/core/modules/auth/core-auth.controller.js +28 -2
  14. package/dist/core/modules/auth/core-auth.controller.js.map +1 -1
  15. package/dist/core/modules/auth/core-auth.module.js +14 -1
  16. package/dist/core/modules/auth/core-auth.module.js.map +1 -1
  17. package/dist/core/modules/auth/core-auth.resolver.d.ts +1 -0
  18. package/dist/core/modules/auth/core-auth.resolver.js +20 -2
  19. package/dist/core/modules/auth/core-auth.resolver.js.map +1 -1
  20. package/dist/core/modules/auth/exceptions/legacy-auth-disabled.exception.d.ts +4 -0
  21. package/dist/core/modules/auth/exceptions/legacy-auth-disabled.exception.js +17 -0
  22. package/dist/core/modules/auth/exceptions/legacy-auth-disabled.exception.js.map +1 -0
  23. package/dist/core/modules/auth/guards/legacy-auth-rate-limit.guard.d.ts +9 -0
  24. package/dist/core/modules/auth/guards/legacy-auth-rate-limit.guard.js +74 -0
  25. package/dist/core/modules/auth/guards/legacy-auth-rate-limit.guard.js.map +1 -0
  26. package/dist/core/modules/auth/interfaces/auth-provider.interface.d.ts +7 -0
  27. package/dist/core/modules/auth/interfaces/auth-provider.interface.js +5 -0
  28. package/dist/core/modules/auth/interfaces/auth-provider.interface.js.map +1 -0
  29. package/dist/core/modules/auth/interfaces/core-auth-user.interface.d.ts +1 -0
  30. package/dist/core/modules/auth/services/core-auth.service.d.ts +10 -1
  31. package/dist/core/modules/auth/services/core-auth.service.js +141 -9
  32. package/dist/core/modules/auth/services/core-auth.service.js.map +1 -1
  33. package/dist/core/modules/auth/services/legacy-auth-rate-limiter.service.d.ts +31 -0
  34. package/dist/core/modules/auth/services/legacy-auth-rate-limiter.service.js +153 -0
  35. package/dist/core/modules/auth/services/legacy-auth-rate-limiter.service.js.map +1 -0
  36. package/dist/core/modules/better-auth/better-auth-migration-status.model.d.ts +10 -0
  37. package/dist/core/modules/better-auth/better-auth-migration-status.model.js +57 -0
  38. package/dist/core/modules/better-auth/better-auth-migration-status.model.js.map +1 -0
  39. package/dist/core/modules/better-auth/better-auth-models.d.ts +0 -1
  40. package/dist/core/modules/better-auth/better-auth-models.js +0 -4
  41. package/dist/core/modules/better-auth/better-auth-models.js.map +1 -1
  42. package/dist/core/modules/better-auth/better-auth-user.mapper.d.ts +33 -0
  43. package/dist/core/modules/better-auth/better-auth-user.mapper.js +443 -0
  44. package/dist/core/modules/better-auth/better-auth-user.mapper.js.map +1 -1
  45. package/dist/core/modules/better-auth/better-auth.config.js +3 -0
  46. package/dist/core/modules/better-auth/better-auth.config.js.map +1 -1
  47. package/dist/core/modules/better-auth/better-auth.module.d.ts +10 -2
  48. package/dist/core/modules/better-auth/better-auth.module.js +40 -52
  49. package/dist/core/modules/better-auth/better-auth.module.js.map +1 -1
  50. package/dist/core/modules/better-auth/better-auth.resolver.d.ts +8 -12
  51. package/dist/core/modules/better-auth/better-auth.resolver.js +33 -351
  52. package/dist/core/modules/better-auth/better-auth.resolver.js.map +1 -1
  53. package/dist/core/modules/better-auth/better-auth.service.d.ts +0 -1
  54. package/dist/core/modules/better-auth/better-auth.service.js +0 -3
  55. package/dist/core/modules/better-auth/better-auth.service.js.map +1 -1
  56. package/dist/core/modules/better-auth/better-auth.types.d.ts +9 -8
  57. package/dist/core/modules/better-auth/better-auth.types.js +14 -3
  58. package/dist/core/modules/better-auth/better-auth.types.js.map +1 -1
  59. package/dist/core/modules/better-auth/core-better-auth.controller.d.ts +67 -0
  60. package/dist/core/modules/better-auth/core-better-auth.controller.js +504 -0
  61. package/dist/core/modules/better-auth/core-better-auth.controller.js.map +1 -0
  62. package/dist/core/modules/better-auth/core-better-auth.resolver.d.ts +61 -0
  63. package/dist/core/modules/better-auth/core-better-auth.resolver.js +552 -0
  64. package/dist/core/modules/better-auth/core-better-auth.resolver.js.map +1 -0
  65. package/dist/core/modules/better-auth/index.d.ts +3 -0
  66. package/dist/core/modules/better-auth/index.js +3 -0
  67. package/dist/core/modules/better-auth/index.js.map +1 -1
  68. package/dist/core/modules/user/core-user.service.d.ts +7 -1
  69. package/dist/core/modules/user/core-user.service.js +57 -3
  70. package/dist/core/modules/user/core-user.service.js.map +1 -1
  71. package/dist/core/modules/user/interfaces/core-user-service-options.interface.d.ts +4 -0
  72. package/dist/core/modules/user/interfaces/core-user-service-options.interface.js +3 -0
  73. package/dist/core/modules/user/interfaces/core-user-service-options.interface.js.map +1 -0
  74. package/dist/core.module.d.ts +3 -0
  75. package/dist/core.module.js +132 -54
  76. package/dist/core.module.js.map +1 -1
  77. package/dist/index.d.ts +5 -0
  78. package/dist/index.js +5 -0
  79. package/dist/index.js.map +1 -1
  80. package/dist/server/modules/auth/auth.resolver.js +2 -0
  81. package/dist/server/modules/auth/auth.resolver.js.map +1 -1
  82. package/dist/server/modules/better-auth/better-auth.controller.d.ts +10 -0
  83. package/dist/server/modules/better-auth/better-auth.controller.js +36 -0
  84. package/dist/server/modules/better-auth/better-auth.controller.js.map +1 -0
  85. package/dist/server/modules/better-auth/better-auth.module.d.ts +9 -0
  86. package/dist/server/modules/better-auth/better-auth.module.js +44 -0
  87. package/dist/server/modules/better-auth/better-auth.module.js.map +1 -0
  88. package/dist/server/modules/better-auth/better-auth.resolver.d.ts +47 -0
  89. package/dist/server/modules/better-auth/better-auth.resolver.js +234 -0
  90. package/dist/server/modules/better-auth/better-auth.resolver.js.map +1 -0
  91. package/dist/server/modules/file/file-info.model.d.ts +71 -3
  92. package/dist/server/modules/user/user.model.d.ts +169 -3
  93. package/dist/server/modules/user/user.service.d.ts +3 -1
  94. package/dist/server/modules/user/user.service.js +7 -3
  95. package/dist/server/modules/user/user.service.js.map +1 -1
  96. package/dist/server/server.module.js +6 -1
  97. package/dist/server/server.module.js.map +1 -1
  98. package/dist/tsconfig.build.tsbuildinfo +1 -1
  99. package/package.json +20 -29
  100. package/src/config.env.ts +34 -13
  101. package/src/core/common/helpers/filter.helper.ts +15 -17
  102. package/src/core/common/helpers/gridfs.helper.ts +5 -5
  103. package/src/core/common/interfaces/server-options.interface.ts +222 -14
  104. package/src/core/common/services/crud.service.ts +22 -22
  105. package/src/core/modules/auth/core-auth.controller.ts +93 -5
  106. package/src/core/modules/auth/core-auth.module.ts +15 -1
  107. package/src/core/modules/auth/core-auth.resolver.ts +70 -2
  108. package/src/core/modules/auth/exceptions/legacy-auth-disabled.exception.ts +35 -0
  109. package/src/core/modules/auth/guards/legacy-auth-rate-limit.guard.ts +109 -0
  110. package/src/core/modules/auth/interfaces/auth-provider.interface.ts +86 -0
  111. package/src/core/modules/auth/interfaces/core-auth-user.interface.ts +6 -0
  112. package/src/core/modules/auth/services/core-auth.service.ts +245 -6
  113. package/src/core/modules/auth/services/legacy-auth-rate-limiter.service.ts +283 -0
  114. package/src/core/modules/better-auth/INTEGRATION-CHECKLIST.md +254 -0
  115. package/src/core/modules/better-auth/README.md +698 -54
  116. package/src/core/modules/better-auth/better-auth-migration-status.model.ts +73 -0
  117. package/src/core/modules/better-auth/better-auth-models.ts +0 -3
  118. package/src/core/modules/better-auth/better-auth-user.mapper.ts +805 -0
  119. package/src/core/modules/better-auth/better-auth.config.ts +5 -0
  120. package/src/core/modules/better-auth/better-auth.module.ts +107 -66
  121. package/src/core/modules/better-auth/better-auth.resolver.ts +88 -553
  122. package/src/core/modules/better-auth/better-auth.service.ts +0 -9
  123. package/src/core/modules/better-auth/better-auth.types.ts +25 -10
  124. package/src/core/modules/better-auth/core-better-auth.controller.ts +646 -0
  125. package/src/core/modules/better-auth/core-better-auth.resolver.ts +730 -0
  126. package/src/core/modules/better-auth/index.ts +9 -1
  127. package/src/core/modules/user/core-user.service.ts +131 -4
  128. package/src/core/modules/user/interfaces/core-user-service-options.interface.ts +15 -0
  129. package/src/core.module.ts +257 -74
  130. package/src/index.ts +5 -0
  131. package/src/server/modules/auth/auth.resolver.ts +8 -0
  132. package/src/server/modules/better-auth/better-auth.controller.ts +41 -0
  133. package/src/server/modules/better-auth/better-auth.module.ts +88 -0
  134. package/src/server/modules/better-auth/better-auth.resolver.ts +210 -0
  135. package/src/server/modules/user/user.service.ts +4 -2
  136. package/src/server/server.module.ts +10 -1
@@ -0,0 +1,41 @@
1
+ import { Controller } from '@nestjs/common';
2
+
3
+ import { Roles } from '../../../core/common/decorators/roles.decorator';
4
+ import { RoleEnum } from '../../../core/common/enums/role.enum';
5
+ import { ConfigService } from '../../../core/common/services/config.service';
6
+ import { BetterAuthUserMapper } from '../../../core/modules/better-auth/better-auth-user.mapper';
7
+ import { BetterAuthService } from '../../../core/modules/better-auth/better-auth.service';
8
+ import { CoreBetterAuthController } from '../../../core/modules/better-auth/core-better-auth.controller';
9
+
10
+ /**
11
+ * Server BetterAuth REST Controller
12
+ *
13
+ * This controller extends CoreBetterAuthController and can be customized
14
+ * for project-specific requirements (e.g., sending welcome emails,
15
+ * custom validation, audit logging).
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * // Add custom behavior after sign-up
20
+ * override async signUp(res: Response, input: BetterAuthSignUpInput) {
21
+ * const result = await super.signUp(res, input);
22
+ *
23
+ * if (result.success && result.user) {
24
+ * await this.emailService.sendWelcomeEmail(result.user.email);
25
+ * }
26
+ *
27
+ * return result;
28
+ * }
29
+ * ```
30
+ */
31
+ @Controller('iam')
32
+ @Roles(RoleEnum.ADMIN)
33
+ export class BetterAuthController extends CoreBetterAuthController {
34
+ constructor(
35
+ protected override readonly betterAuthService: BetterAuthService,
36
+ protected override readonly userMapper: BetterAuthUserMapper,
37
+ protected override readonly configService: ConfigService,
38
+ ) {
39
+ super(betterAuthService, userMapper, configService);
40
+ }
41
+ }
@@ -0,0 +1,88 @@
1
+ import { DynamicModule, Module } from '@nestjs/common';
2
+
3
+ import { IBetterAuth } from '../../../core/common/interfaces/server-options.interface';
4
+ import { BetterAuthModule as CoreBetterAuthModule } from '../../../core/modules/better-auth/better-auth.module';
5
+ import { BetterAuthController } from './better-auth.controller';
6
+ import { BetterAuthResolver } from './better-auth.resolver';
7
+
8
+ /**
9
+ * Options for BetterAuthModule.forRoot()
10
+ */
11
+ export interface ServerBetterAuthModuleOptions {
12
+ /**
13
+ * Better-auth configuration from environment
14
+ */
15
+ config: IBetterAuth;
16
+
17
+ /**
18
+ * Fallback secrets for backwards compatibility with JWT config.
19
+ * If no betterAuth.secret is configured, these secrets are tried in order.
20
+ */
21
+ fallbackSecrets?: (string | undefined)[];
22
+ }
23
+
24
+ /**
25
+ * Server BetterAuthModule - Project-specific Better-Auth integration
26
+ *
27
+ * This module wraps the core BetterAuthModule and provides project-specific
28
+ * customization through the BetterAuthController and BetterAuthResolver.
29
+ *
30
+ * Following the same pattern as src/server/modules/auth/auth.module.ts:
31
+ * - Core module provides abstract/base functionality
32
+ * - Server module provides project-specific implementations
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * // In server.module.ts
37
+ * import { BetterAuthModule } from './modules/better-auth/better-auth.module';
38
+ *
39
+ * @Module({
40
+ * imports: [
41
+ * CoreModule.forRoot(CoreAuthService, AuthModule.forRoot(envConfig.jwt), {
42
+ * ...envConfig,
43
+ * betterAuth: { ...envConfig.betterAuth, autoRegister: false },
44
+ * }),
45
+ * BetterAuthModule.forRoot({
46
+ * config: envConfig.betterAuth,
47
+ * fallbackSecrets: [envConfig.jwt?.secret, envConfig.jwt?.refresh?.secret],
48
+ * }),
49
+ * ],
50
+ * })
51
+ * export class ServerModule {}
52
+ * ```
53
+ */
54
+ @Module({})
55
+ export class BetterAuthModule {
56
+ /**
57
+ * Creates a dynamic module with project-specific Better-Auth configuration
58
+ *
59
+ * @param options - Configuration options
60
+ * @returns Dynamic module configuration
61
+ */
62
+ static forRoot(options: ServerBetterAuthModuleOptions): DynamicModule {
63
+ const { config, fallbackSecrets } = options;
64
+
65
+ // If better-auth is explicitly disabled, return minimal module
66
+ if (config?.enabled === false) {
67
+ return {
68
+ exports: [],
69
+ module: BetterAuthModule,
70
+ providers: [],
71
+ };
72
+ }
73
+
74
+ return {
75
+ exports: [CoreBetterAuthModule],
76
+ imports: [
77
+ CoreBetterAuthModule.forRoot({
78
+ config,
79
+ controller: BetterAuthController,
80
+ fallbackSecrets,
81
+ resolver: BetterAuthResolver,
82
+ }),
83
+ ],
84
+ module: BetterAuthModule,
85
+ providers: [],
86
+ };
87
+ }
88
+ }
@@ -0,0 +1,210 @@
1
+ import { UseGuards } from '@nestjs/common';
2
+ import { Args, Context, Mutation, Query, Resolver } from '@nestjs/graphql';
3
+ import { Request, Response } from 'express';
4
+
5
+ import { Roles } from '../../../core/common/decorators/roles.decorator';
6
+ import { RoleEnum } from '../../../core/common/enums/role.enum';
7
+ import { AuthGuardStrategy } from '../../../core/modules/auth/auth-guard-strategy.enum';
8
+ import { AuthGuard } from '../../../core/modules/auth/guards/auth.guard';
9
+ import { BetterAuthAuthModel } from '../../../core/modules/better-auth/better-auth-auth.model';
10
+ import { BetterAuthMigrationStatusModel } from '../../../core/modules/better-auth/better-auth-migration-status.model';
11
+ import {
12
+ BetterAuth2FASetupModel,
13
+ BetterAuthFeaturesModel,
14
+ BetterAuthPasskeyChallengeModel,
15
+ BetterAuthPasskeyModel,
16
+ BetterAuthSessionModel,
17
+ } from '../../../core/modules/better-auth/better-auth-models';
18
+ import { BetterAuthUserMapper } from '../../../core/modules/better-auth/better-auth-user.mapper';
19
+ import { BetterAuthService } from '../../../core/modules/better-auth/better-auth.service';
20
+ import { CoreBetterAuthResolver } from '../../../core/modules/better-auth/core-better-auth.resolver';
21
+
22
+ /**
23
+ * Server BetterAuth GraphQL Resolver
24
+ *
25
+ * This resolver extends CoreBetterAuthResolver and exposes all GraphQL operations.
26
+ * The `isAbstract: true` pattern in NestJS GraphQL requires concrete classes to
27
+ * explicitly override and decorate methods for them to be registered in the schema.
28
+ *
29
+ * Each method delegates to the parent implementation via `super.methodName()`.
30
+ * Override any method to add custom behavior (e.g., sending welcome emails after signup).
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * // Add custom behavior after sign-up
35
+ * override async betterAuthSignUp(email: string, password: string, name?: string) {
36
+ * const result = await super.betterAuthSignUp(email, password, name);
37
+ *
38
+ * if (result.success && result.user) {
39
+ * await this.emailService.sendWelcomeEmail(result.user.email);
40
+ * }
41
+ *
42
+ * return result;
43
+ * }
44
+ * ```
45
+ */
46
+ @Resolver(() => BetterAuthAuthModel)
47
+ @Roles(RoleEnum.ADMIN)
48
+ export class BetterAuthResolver extends CoreBetterAuthResolver {
49
+ constructor(
50
+ protected override readonly betterAuthService: BetterAuthService,
51
+ protected override readonly userMapper: BetterAuthUserMapper,
52
+ ) {
53
+ super(betterAuthService, userMapper);
54
+ }
55
+
56
+ // ===========================================================================
57
+ // Queries
58
+ // ===========================================================================
59
+
60
+ @Query(() => BetterAuthSessionModel, {
61
+ description: 'Get current Better-Auth session',
62
+ nullable: true,
63
+ })
64
+ @Roles(RoleEnum.S_USER)
65
+ @UseGuards(AuthGuard(AuthGuardStrategy.JWT))
66
+ override async betterAuthSession(@Context() ctx: { req: Request }): Promise<BetterAuthSessionModel | null> {
67
+ return super.betterAuthSession(ctx);
68
+ }
69
+
70
+ @Query(() => Boolean, { description: 'Check if Better-Auth is enabled' })
71
+ @Roles(RoleEnum.S_EVERYONE)
72
+ override betterAuthEnabled(): boolean {
73
+ return super.betterAuthEnabled();
74
+ }
75
+
76
+ @Query(() => BetterAuthFeaturesModel, { description: 'Get enabled Better-Auth features' })
77
+ @Roles(RoleEnum.S_EVERYONE)
78
+ override betterAuthFeatures(): BetterAuthFeaturesModel {
79
+ return super.betterAuthFeatures();
80
+ }
81
+
82
+ @Query(() => BetterAuthMigrationStatusModel, {
83
+ description: 'Get migration status from Legacy Auth to Better-Auth (IAM) - Admin only',
84
+ })
85
+ @Roles(RoleEnum.ADMIN)
86
+ override async betterAuthMigrationStatus(): Promise<BetterAuthMigrationStatusModel> {
87
+ return super.betterAuthMigrationStatus();
88
+ }
89
+
90
+ @Query(() => [BetterAuthPasskeyModel], {
91
+ description: 'List passkeys for the current user',
92
+ nullable: true,
93
+ })
94
+ @Roles(RoleEnum.S_USER)
95
+ @UseGuards(AuthGuard(AuthGuardStrategy.JWT))
96
+ override async betterAuthListPasskeys(@Context() ctx: { req: Request }): Promise<BetterAuthPasskeyModel[] | null> {
97
+ return super.betterAuthListPasskeys(ctx);
98
+ }
99
+
100
+ // ===========================================================================
101
+ // Authentication Mutations
102
+ // ===========================================================================
103
+
104
+ @Mutation(() => BetterAuthAuthModel, {
105
+ description: 'Sign in via Better-Auth (email/password)',
106
+ })
107
+ @Roles(RoleEnum.S_EVERYONE)
108
+ override async betterAuthSignIn(
109
+ @Args('email') email: string,
110
+ @Args('password') password: string,
111
+ @Context() ctx: { req: Request; res: Response },
112
+ ): Promise<BetterAuthAuthModel> {
113
+ return super.betterAuthSignIn(email, password, ctx);
114
+ }
115
+
116
+ @Mutation(() => BetterAuthAuthModel, {
117
+ description: 'Sign up via Better-Auth (email/password)',
118
+ })
119
+ @Roles(RoleEnum.S_EVERYONE)
120
+ override async betterAuthSignUp(
121
+ @Args('email') email: string,
122
+ @Args('password') password: string,
123
+ @Args('name', { nullable: true }) name?: string,
124
+ ): Promise<BetterAuthAuthModel> {
125
+ return super.betterAuthSignUp(email, password, name);
126
+ }
127
+
128
+ @Mutation(() => Boolean, { description: 'Sign out via Better-Auth' })
129
+ @Roles(RoleEnum.S_USER)
130
+ @UseGuards(AuthGuard(AuthGuardStrategy.JWT))
131
+ override async betterAuthSignOut(@Context() ctx: { req: Request }): Promise<boolean> {
132
+ return super.betterAuthSignOut(ctx);
133
+ }
134
+
135
+ // ===========================================================================
136
+ // 2FA Mutations
137
+ // ===========================================================================
138
+
139
+ @Mutation(() => BetterAuthAuthModel, {
140
+ description: 'Verify 2FA code during sign-in',
141
+ })
142
+ @Roles(RoleEnum.S_EVERYONE)
143
+ override async betterAuthVerify2FA(
144
+ @Args('code') code: string,
145
+ @Context() ctx: { req: Request },
146
+ ): Promise<BetterAuthAuthModel> {
147
+ return super.betterAuthVerify2FA(code, ctx);
148
+ }
149
+
150
+ @Mutation(() => BetterAuth2FASetupModel, {
151
+ description: 'Enable 2FA for the current user',
152
+ })
153
+ @Roles(RoleEnum.S_USER)
154
+ @UseGuards(AuthGuard(AuthGuardStrategy.JWT))
155
+ override async betterAuthEnable2FA(
156
+ @Args('password') password: string,
157
+ @Context() ctx: { req: Request },
158
+ ): Promise<BetterAuth2FASetupModel> {
159
+ return super.betterAuthEnable2FA(password, ctx);
160
+ }
161
+
162
+ @Mutation(() => Boolean, {
163
+ description: 'Disable 2FA for the current user',
164
+ })
165
+ @Roles(RoleEnum.S_USER)
166
+ @UseGuards(AuthGuard(AuthGuardStrategy.JWT))
167
+ override async betterAuthDisable2FA(
168
+ @Args('password') password: string,
169
+ @Context() ctx: { req: Request },
170
+ ): Promise<boolean> {
171
+ return super.betterAuthDisable2FA(password, ctx);
172
+ }
173
+
174
+ @Mutation(() => [String], {
175
+ description: 'Generate new backup codes for 2FA',
176
+ nullable: true,
177
+ })
178
+ @Roles(RoleEnum.S_USER)
179
+ @UseGuards(AuthGuard(AuthGuardStrategy.JWT))
180
+ override async betterAuthGenerateBackupCodes(@Context() ctx: { req: Request }): Promise<null | string[]> {
181
+ return super.betterAuthGenerateBackupCodes(ctx);
182
+ }
183
+
184
+ // ===========================================================================
185
+ // Passkey Mutations
186
+ // ===========================================================================
187
+
188
+ @Mutation(() => BetterAuthPasskeyChallengeModel, {
189
+ description: 'Get passkey registration challenge for WebAuthn',
190
+ })
191
+ @Roles(RoleEnum.S_USER)
192
+ @UseGuards(AuthGuard(AuthGuardStrategy.JWT))
193
+ override async betterAuthGetPasskeyChallenge(
194
+ @Context() ctx: { req: Request },
195
+ ): Promise<BetterAuthPasskeyChallengeModel> {
196
+ return super.betterAuthGetPasskeyChallenge(ctx);
197
+ }
198
+
199
+ @Mutation(() => Boolean, {
200
+ description: 'Delete a passkey by ID',
201
+ })
202
+ @Roles(RoleEnum.S_USER)
203
+ @UseGuards(AuthGuard(AuthGuardStrategy.JWT))
204
+ override async betterAuthDeletePasskey(
205
+ @Args('passkeyId') passkeyId: string,
206
+ @Context() ctx: { req: Request },
207
+ ): Promise<boolean> {
208
+ return super.betterAuthDeletePasskey(passkeyId, ctx);
209
+ }
210
+ }
@@ -1,4 +1,4 @@
1
- import { Inject, Injectable, UnauthorizedException, UnprocessableEntityException } from '@nestjs/common';
1
+ import { Inject, Injectable, Optional, UnauthorizedException, UnprocessableEntityException } from '@nestjs/common';
2
2
  import { InjectModel } from '@nestjs/mongoose';
3
3
  import fs = require('fs');
4
4
  import { PubSub } from 'graphql-subscriptions';
@@ -9,6 +9,7 @@ import { ServiceOptions } from '../../../core/common/interfaces/service-options.
9
9
  import { ConfigService } from '../../../core/common/services/config.service';
10
10
  import { EmailService } from '../../../core/common/services/email.service';
11
11
  import { CoreModelConstructor } from '../../../core/common/types/core-model-constructor.type';
12
+ import { BetterAuthUserMapper } from '../../../core/modules/better-auth/better-auth-user.mapper';
12
13
  import { CoreUserService } from '../../../core/modules/user/core-user.service';
13
14
  import { UserCreateInput } from './inputs/user-create.input';
14
15
  import { UserInput } from './inputs/user.input';
@@ -32,8 +33,9 @@ export class UserService extends CoreUserService<User, UserInput, UserCreateInpu
32
33
  @Inject('USER_CLASS') protected override readonly mainModelConstructor: CoreModelConstructor<User>,
33
34
  @InjectModel('User') protected override readonly mainDbModel: Model<UserDocument>,
34
35
  @Inject('PUB_SUB') protected readonly pubSub: PubSub,
36
+ @Optional() private readonly betterAuthUserMapper?: BetterAuthUserMapper,
35
37
  ) {
36
- super(configService, emailService, mainDbModel, mainModelConstructor);
38
+ super(configService, emailService, mainDbModel, mainModelConstructor, { betterAuthUserMapper });
37
39
  }
38
40
 
39
41
  // ===================================================================================================================
@@ -10,6 +10,7 @@ import { CoreAuthService } from '../core/modules/auth/services/core-auth.service
10
10
  import { CronJobs } from './common/services/cron-jobs.service';
11
11
  import { AuthController } from './modules/auth/auth.controller';
12
12
  import { AuthModule } from './modules/auth/auth.module';
13
+ import { BetterAuthModule } from './modules/better-auth/better-auth.module';
13
14
  import { FileModule } from './modules/file/file.module';
14
15
  import { ServerController } from './server.controller';
15
16
 
@@ -24,11 +25,12 @@ import { ServerController } from './server.controller';
24
25
  controllers: [ServerController, AuthController],
25
26
 
26
27
  // Export modules for reuse in other modules
27
- exports: [CoreModule, AuthModule, FileModule],
28
+ exports: [CoreModule, AuthModule, BetterAuthModule, FileModule],
28
29
 
29
30
  // Include modules
30
31
  imports: [
31
32
  // Include CoreModule for standard processes
33
+ // Note: BetterAuthModule is imported manually below (autoRegister defaults to false)
32
34
  CoreModule.forRoot(CoreAuthService, AuthModule.forRoot(envConfig.jwt), envConfig),
33
35
 
34
36
  // Include cron job handling
@@ -38,6 +40,13 @@ import { ServerController } from './server.controller';
38
40
  // which will also include UserModule
39
41
  AuthModule.forRoot(envConfig.jwt),
40
42
 
43
+ // Include BetterAuthModule for better-auth integration
44
+ // This allows project-specific customization via BetterAuthResolver
45
+ BetterAuthModule.forRoot({
46
+ config: envConfig.betterAuth,
47
+ fallbackSecrets: [envConfig.jwt?.secret, envConfig.jwt?.refresh?.secret],
48
+ }),
49
+
41
50
  // Include FileModule for file handling
42
51
  FileModule,
43
52
  ],