@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.
- package/dist/config.env.js +19 -12
- package/dist/config.env.js.map +1 -1
- package/dist/core/common/helpers/filter.helper.d.ts +9 -9
- package/dist/core/common/helpers/filter.helper.js +2 -4
- package/dist/core/common/helpers/filter.helper.js.map +1 -1
- package/dist/core/common/helpers/gridfs.helper.js +3 -3
- package/dist/core/common/helpers/gridfs.helper.js.map +1 -1
- package/dist/core/common/interfaces/server-options.interface.d.ts +21 -3
- package/dist/core/common/services/crud.service.d.ts +16 -16
- package/dist/core/common/services/crud.service.js +1 -1
- package/dist/core/common/services/crud.service.js.map +1 -1
- package/dist/core/modules/auth/core-auth.controller.d.ts +1 -0
- package/dist/core/modules/auth/core-auth.controller.js +28 -2
- package/dist/core/modules/auth/core-auth.controller.js.map +1 -1
- package/dist/core/modules/auth/core-auth.module.js +14 -1
- package/dist/core/modules/auth/core-auth.module.js.map +1 -1
- package/dist/core/modules/auth/core-auth.resolver.d.ts +1 -0
- package/dist/core/modules/auth/core-auth.resolver.js +20 -2
- package/dist/core/modules/auth/core-auth.resolver.js.map +1 -1
- package/dist/core/modules/auth/exceptions/legacy-auth-disabled.exception.d.ts +4 -0
- package/dist/core/modules/auth/exceptions/legacy-auth-disabled.exception.js +17 -0
- package/dist/core/modules/auth/exceptions/legacy-auth-disabled.exception.js.map +1 -0
- package/dist/core/modules/auth/guards/legacy-auth-rate-limit.guard.d.ts +9 -0
- package/dist/core/modules/auth/guards/legacy-auth-rate-limit.guard.js +74 -0
- package/dist/core/modules/auth/guards/legacy-auth-rate-limit.guard.js.map +1 -0
- package/dist/core/modules/auth/interfaces/auth-provider.interface.d.ts +7 -0
- package/dist/core/modules/auth/interfaces/auth-provider.interface.js +5 -0
- package/dist/core/modules/auth/interfaces/auth-provider.interface.js.map +1 -0
- package/dist/core/modules/auth/interfaces/core-auth-user.interface.d.ts +1 -0
- package/dist/core/modules/auth/services/core-auth.service.d.ts +10 -1
- package/dist/core/modules/auth/services/core-auth.service.js +141 -9
- package/dist/core/modules/auth/services/core-auth.service.js.map +1 -1
- package/dist/core/modules/auth/services/legacy-auth-rate-limiter.service.d.ts +31 -0
- package/dist/core/modules/auth/services/legacy-auth-rate-limiter.service.js +153 -0
- package/dist/core/modules/auth/services/legacy-auth-rate-limiter.service.js.map +1 -0
- package/dist/core/modules/better-auth/better-auth-migration-status.model.d.ts +10 -0
- package/dist/core/modules/better-auth/better-auth-migration-status.model.js +57 -0
- package/dist/core/modules/better-auth/better-auth-migration-status.model.js.map +1 -0
- package/dist/core/modules/better-auth/better-auth-models.d.ts +0 -1
- package/dist/core/modules/better-auth/better-auth-models.js +0 -4
- package/dist/core/modules/better-auth/better-auth-models.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth-user.mapper.d.ts +33 -0
- package/dist/core/modules/better-auth/better-auth-user.mapper.js +443 -0
- package/dist/core/modules/better-auth/better-auth-user.mapper.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth.config.js +3 -0
- package/dist/core/modules/better-auth/better-auth.config.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth.module.d.ts +10 -2
- package/dist/core/modules/better-auth/better-auth.module.js +40 -52
- package/dist/core/modules/better-auth/better-auth.module.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth.resolver.d.ts +8 -12
- package/dist/core/modules/better-auth/better-auth.resolver.js +33 -351
- package/dist/core/modules/better-auth/better-auth.resolver.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth.service.d.ts +0 -1
- package/dist/core/modules/better-auth/better-auth.service.js +0 -3
- package/dist/core/modules/better-auth/better-auth.service.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth.types.d.ts +9 -8
- package/dist/core/modules/better-auth/better-auth.types.js +14 -3
- package/dist/core/modules/better-auth/better-auth.types.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth.controller.d.ts +67 -0
- package/dist/core/modules/better-auth/core-better-auth.controller.js +504 -0
- package/dist/core/modules/better-auth/core-better-auth.controller.js.map +1 -0
- package/dist/core/modules/better-auth/core-better-auth.resolver.d.ts +61 -0
- package/dist/core/modules/better-auth/core-better-auth.resolver.js +552 -0
- package/dist/core/modules/better-auth/core-better-auth.resolver.js.map +1 -0
- package/dist/core/modules/better-auth/index.d.ts +3 -0
- package/dist/core/modules/better-auth/index.js +3 -0
- package/dist/core/modules/better-auth/index.js.map +1 -1
- package/dist/core/modules/user/core-user.service.d.ts +7 -1
- package/dist/core/modules/user/core-user.service.js +57 -3
- package/dist/core/modules/user/core-user.service.js.map +1 -1
- package/dist/core/modules/user/interfaces/core-user-service-options.interface.d.ts +4 -0
- package/dist/core/modules/user/interfaces/core-user-service-options.interface.js +3 -0
- package/dist/core/modules/user/interfaces/core-user-service-options.interface.js.map +1 -0
- package/dist/core.module.d.ts +3 -0
- package/dist/core.module.js +132 -54
- package/dist/core.module.js.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/server/modules/auth/auth.resolver.js +2 -0
- package/dist/server/modules/auth/auth.resolver.js.map +1 -1
- package/dist/server/modules/better-auth/better-auth.controller.d.ts +10 -0
- package/dist/server/modules/better-auth/better-auth.controller.js +36 -0
- package/dist/server/modules/better-auth/better-auth.controller.js.map +1 -0
- package/dist/server/modules/better-auth/better-auth.module.d.ts +9 -0
- package/dist/server/modules/better-auth/better-auth.module.js +44 -0
- package/dist/server/modules/better-auth/better-auth.module.js.map +1 -0
- package/dist/server/modules/better-auth/better-auth.resolver.d.ts +47 -0
- package/dist/server/modules/better-auth/better-auth.resolver.js +234 -0
- package/dist/server/modules/better-auth/better-auth.resolver.js.map +1 -0
- package/dist/server/modules/file/file-info.model.d.ts +71 -3
- package/dist/server/modules/user/user.model.d.ts +169 -3
- package/dist/server/modules/user/user.service.d.ts +3 -1
- package/dist/server/modules/user/user.service.js +7 -3
- package/dist/server/modules/user/user.service.js.map +1 -1
- package/dist/server/server.module.js +6 -1
- package/dist/server/server.module.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +20 -29
- package/src/config.env.ts +34 -13
- package/src/core/common/helpers/filter.helper.ts +15 -17
- package/src/core/common/helpers/gridfs.helper.ts +5 -5
- package/src/core/common/interfaces/server-options.interface.ts +222 -14
- package/src/core/common/services/crud.service.ts +22 -22
- package/src/core/modules/auth/core-auth.controller.ts +93 -5
- package/src/core/modules/auth/core-auth.module.ts +15 -1
- package/src/core/modules/auth/core-auth.resolver.ts +70 -2
- package/src/core/modules/auth/exceptions/legacy-auth-disabled.exception.ts +35 -0
- package/src/core/modules/auth/guards/legacy-auth-rate-limit.guard.ts +109 -0
- package/src/core/modules/auth/interfaces/auth-provider.interface.ts +86 -0
- package/src/core/modules/auth/interfaces/core-auth-user.interface.ts +6 -0
- package/src/core/modules/auth/services/core-auth.service.ts +245 -6
- package/src/core/modules/auth/services/legacy-auth-rate-limiter.service.ts +283 -0
- package/src/core/modules/better-auth/INTEGRATION-CHECKLIST.md +254 -0
- package/src/core/modules/better-auth/README.md +698 -54
- package/src/core/modules/better-auth/better-auth-migration-status.model.ts +73 -0
- package/src/core/modules/better-auth/better-auth-models.ts +0 -3
- package/src/core/modules/better-auth/better-auth-user.mapper.ts +805 -0
- package/src/core/modules/better-auth/better-auth.config.ts +5 -0
- package/src/core/modules/better-auth/better-auth.module.ts +107 -66
- package/src/core/modules/better-auth/better-auth.resolver.ts +88 -553
- package/src/core/modules/better-auth/better-auth.service.ts +0 -9
- package/src/core/modules/better-auth/better-auth.types.ts +25 -10
- package/src/core/modules/better-auth/core-better-auth.controller.ts +646 -0
- package/src/core/modules/better-auth/core-better-auth.resolver.ts +730 -0
- package/src/core/modules/better-auth/index.ts +9 -1
- package/src/core/modules/user/core-user.service.ts +131 -4
- package/src/core/modules/user/interfaces/core-user-service-options.interface.ts +15 -0
- package/src/core.module.ts +257 -74
- package/src/index.ts +5 -0
- package/src/server/modules/auth/auth.resolver.ts +8 -0
- package/src/server/modules/better-auth/better-auth.controller.ts +41 -0
- package/src/server/modules/better-auth/better-auth.module.ts +88 -0
- package/src/server/modules/better-auth/better-auth.resolver.ts +210 -0
- package/src/server/modules/user/user.service.ts +4 -2
- 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
|
],
|