@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.
- package/dist/config.env.js +5 -0
- package/dist/config.env.js.map +1 -1
- package/dist/core/common/helpers/logging.helper.d.ts +6 -0
- package/dist/core/common/helpers/logging.helper.js +55 -0
- package/dist/core/common/helpers/logging.helper.js.map +1 -0
- package/dist/core/common/interfaces/server-options.interface.d.ts +50 -19
- package/dist/core/modules/auth/guards/roles.guard.js +37 -5
- package/dist/core/modules/auth/guards/roles.guard.js.map +1 -1
- package/dist/core/modules/auth/services/core-auth.service.d.ts +5 -5
- package/dist/core/modules/auth/services/core-auth.service.js +9 -8
- package/dist/core/modules/auth/services/core-auth.service.js.map +1 -1
- package/dist/core/modules/auth/tokens.decorator.d.ts +1 -1
- package/dist/core/modules/better-auth/better-auth.config.js +32 -10
- package/dist/core/modules/better-auth/better-auth.config.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth.resolver.d.ts +16 -16
- package/dist/core/modules/better-auth/better-auth.resolver.js +34 -34
- package/dist/core/modules/better-auth/better-auth.resolver.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth.types.d.ts +2 -1
- package/dist/core/modules/better-auth/better-auth.types.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth-api.middleware.d.ts +10 -0
- package/dist/core/modules/better-auth/core-better-auth-api.middleware.js +91 -0
- package/dist/core/modules/better-auth/core-better-auth-api.middleware.js.map +1 -0
- package/dist/core/modules/better-auth/core-better-auth-auth.model.d.ts +9 -0
- package/dist/core/modules/better-auth/{better-auth-auth.model.js → core-better-auth-auth.model.js} +17 -17
- package/dist/core/modules/better-auth/core-better-auth-auth.model.js.map +1 -0
- package/dist/core/modules/better-auth/{better-auth-migration-status.model.d.ts → core-better-auth-migration-status.model.d.ts} +1 -1
- package/dist/core/modules/better-auth/{better-auth-migration-status.model.js → core-better-auth-migration-status.model.js} +14 -14
- package/dist/core/modules/better-auth/core-better-auth-migration-status.model.js.map +1 -0
- package/dist/core/modules/better-auth/{better-auth-models.d.ts → core-better-auth-models.d.ts} +8 -8
- package/dist/core/modules/better-auth/{better-auth-models.js → core-better-auth-models.js} +61 -61
- package/dist/core/modules/better-auth/core-better-auth-models.js.map +1 -0
- package/dist/core/modules/better-auth/core-better-auth-rate-limit.middleware.d.ts +12 -0
- package/dist/core/modules/better-auth/{better-auth-rate-limit.middleware.js → core-better-auth-rate-limit.middleware.js} +10 -10
- package/dist/core/modules/better-auth/core-better-auth-rate-limit.middleware.js.map +1 -0
- package/dist/core/modules/better-auth/{better-auth-rate-limiter.service.d.ts → core-better-auth-rate-limiter.service.d.ts} +1 -1
- package/dist/core/modules/better-auth/{better-auth-rate-limiter.service.js → core-better-auth-rate-limiter.service.js} +8 -8
- package/dist/core/modules/better-auth/core-better-auth-rate-limiter.service.js.map +1 -0
- package/dist/core/modules/better-auth/{better-auth-user.mapper.d.ts → core-better-auth-user.mapper.d.ts} +1 -1
- package/dist/core/modules/better-auth/{better-auth-user.mapper.js → core-better-auth-user.mapper.js} +10 -9
- package/dist/core/modules/better-auth/core-better-auth-user.mapper.js.map +1 -0
- package/dist/core/modules/better-auth/core-better-auth-web.helper.d.ts +19 -0
- package/dist/core/modules/better-auth/core-better-auth-web.helper.js +152 -0
- package/dist/core/modules/better-auth/core-better-auth-web.helper.js.map +1 -0
- package/dist/core/modules/better-auth/core-better-auth.controller.d.ts +23 -32
- package/dist/core/modules/better-auth/core-better-auth.controller.js +184 -201
- package/dist/core/modules/better-auth/core-better-auth.controller.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth.middleware.d.ts +22 -0
- package/dist/core/modules/better-auth/{better-auth.middleware.js → core-better-auth.middleware.js} +45 -18
- package/dist/core/modules/better-auth/core-better-auth.middleware.js.map +1 -0
- package/dist/core/modules/better-auth/{better-auth.module.d.ts → core-better-auth.module.d.ts} +6 -6
- package/dist/core/modules/better-auth/{better-auth.module.js → core-better-auth.module.js} +65 -60
- package/dist/core/modules/better-auth/core-better-auth.module.js.map +1 -0
- package/dist/core/modules/better-auth/core-better-auth.resolver.d.ts +19 -19
- package/dist/core/modules/better-auth/core-better-auth.resolver.js +18 -18
- package/dist/core/modules/better-auth/core-better-auth.resolver.js.map +1 -1
- package/dist/core/modules/better-auth/{better-auth.service.d.ts → core-better-auth.service.d.ts} +3 -2
- package/dist/core/modules/better-auth/{better-auth.service.js → core-better-auth.service.js} +75 -35
- package/dist/core/modules/better-auth/core-better-auth.service.js.map +1 -0
- package/dist/core/modules/better-auth/index.d.ts +11 -9
- package/dist/core/modules/better-auth/index.js +11 -9
- package/dist/core/modules/better-auth/index.js.map +1 -1
- package/dist/core/modules/error-code/core-error-code.controller.d.ts +7 -0
- package/dist/core/modules/error-code/core-error-code.controller.js +45 -0
- package/dist/core/modules/error-code/core-error-code.controller.js.map +1 -0
- package/dist/core/modules/error-code/core-error-code.service.d.ts +16 -0
- package/dist/core/modules/error-code/core-error-code.service.js +65 -0
- package/dist/core/modules/error-code/core-error-code.service.js.map +1 -0
- package/dist/core/modules/error-code/error-code.module.d.ts +7 -0
- package/dist/core/modules/error-code/error-code.module.js +64 -0
- package/dist/core/modules/error-code/error-code.module.js.map +1 -0
- package/dist/core/modules/error-code/error-codes.d.ts +219 -0
- package/dist/core/modules/error-code/error-codes.js +204 -0
- package/dist/core/modules/error-code/error-codes.js.map +1 -0
- package/dist/core/modules/error-code/index.d.ts +5 -0
- package/dist/core/modules/error-code/index.js +22 -0
- package/dist/core/modules/error-code/index.js.map +1 -0
- package/dist/core/modules/error-code/interfaces/error-code.interfaces.d.ts +12 -0
- package/dist/core/modules/error-code/interfaces/error-code.interfaces.js +3 -0
- package/dist/core/modules/error-code/interfaces/error-code.interfaces.js.map +1 -0
- package/dist/core/modules/user/interfaces/core-user-service-options.interface.d.ts +2 -2
- package/dist/core.module.js +14 -6
- package/dist/core.module.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/server/modules/better-auth/better-auth.controller.d.ts +5 -5
- package/dist/server/modules/better-auth/better-auth.controller.js +4 -4
- package/dist/server/modules/better-auth/better-auth.controller.js.map +1 -1
- package/dist/server/modules/better-auth/better-auth.module.js +3 -3
- package/dist/server/modules/better-auth/better-auth.module.js.map +1 -1
- package/dist/server/modules/better-auth/better-auth.resolver.d.ts +17 -17
- package/dist/server/modules/better-auth/better-auth.resolver.js +18 -18
- package/dist/server/modules/better-auth/better-auth.resolver.js.map +1 -1
- package/dist/server/modules/error-code/error-code.controller.d.ts +8 -0
- package/dist/server/modules/error-code/error-code.controller.js +55 -0
- package/dist/server/modules/error-code/error-code.controller.js.map +1 -0
- package/dist/server/modules/error-code/error-code.service.d.ts +4 -0
- package/dist/server/modules/error-code/error-code.service.js +27 -0
- package/dist/server/modules/error-code/error-code.service.js.map +1 -0
- package/dist/server/modules/error-code/error-codes.d.ts +45 -0
- package/dist/server/modules/error-code/error-codes.js +24 -0
- package/dist/server/modules/error-code/error-codes.js.map +1 -0
- package/dist/server/modules/error-code/index.d.ts +3 -0
- package/dist/server/modules/error-code/index.js +20 -0
- package/dist/server/modules/error-code/index.js.map +1 -0
- package/dist/server/modules/user/user.service.d.ts +2 -2
- package/dist/server/modules/user/user.service.js +2 -2
- package/dist/server/modules/user/user.service.js.map +1 -1
- package/dist/server/server.module.js +7 -0
- package/dist/server/server.module.js.map +1 -1
- package/dist/test/test.helper.d.ts +1 -0
- package/dist/test/test.helper.js +5 -1
- package/dist/test/test.helper.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +6 -4
- package/src/config.env.ts +19 -0
- package/src/core/common/helpers/logging.helper.ts +134 -0
- package/src/core/common/interfaces/server-options.interface.ts +511 -237
- package/src/core/modules/auth/guards/roles.guard.ts +49 -7
- package/src/core/modules/auth/services/core-auth.service.ts +9 -8
- package/src/core/modules/better-auth/ARCHITECTURE.md +102 -0
- package/src/core/modules/better-auth/INTEGRATION-CHECKLIST.md +277 -8
- package/src/core/modules/better-auth/README.md +97 -53
- package/src/core/modules/better-auth/better-auth.config.ts +66 -18
- package/src/core/modules/better-auth/better-auth.resolver.ts +32 -32
- package/src/core/modules/better-auth/better-auth.types.ts +3 -2
- package/src/core/modules/better-auth/core-better-auth-api.middleware.ts +134 -0
- package/src/core/modules/better-auth/{better-auth-auth.model.ts → core-better-auth-auth.model.ts} +6 -6
- package/src/core/modules/better-auth/{better-auth-migration-status.model.ts → core-better-auth-migration-status.model.ts} +1 -1
- package/src/core/modules/better-auth/{better-auth-models.ts → core-better-auth-models.ts} +9 -9
- package/src/core/modules/better-auth/{better-auth-rate-limit.middleware.ts → core-better-auth-rate-limit.middleware.ts} +5 -5
- package/src/core/modules/better-auth/{better-auth-rate-limiter.service.ts → core-better-auth-rate-limiter.service.ts} +2 -2
- package/src/core/modules/better-auth/{better-auth-user.mapper.ts → core-better-auth-user.mapper.ts} +4 -3
- package/src/core/modules/better-auth/core-better-auth-web.helper.ts +272 -0
- package/src/core/modules/better-auth/core-better-auth.controller.ts +386 -230
- package/src/core/modules/better-auth/{better-auth.middleware.ts → core-better-auth.middleware.ts} +57 -17
- package/src/core/modules/better-auth/{better-auth.module.ts → core-better-auth.module.ts} +77 -66
- package/src/core/modules/better-auth/core-better-auth.resolver.ts +42 -42
- package/src/core/modules/better-auth/{better-auth.service.ts → core-better-auth.service.ts} +86 -40
- package/src/core/modules/better-auth/index.ts +18 -11
- package/src/core/modules/error-code/INTEGRATION-CHECKLIST.md +291 -0
- package/src/core/modules/error-code/core-error-code.controller.ts +55 -0
- package/src/core/modules/error-code/core-error-code.service.ts +135 -0
- package/src/core/modules/error-code/error-code.module.ts +119 -0
- package/src/core/modules/error-code/error-codes.ts +405 -0
- package/src/core/modules/error-code/index.ts +14 -0
- package/src/core/modules/error-code/interfaces/error-code.interfaces.ts +99 -0
- package/src/core/modules/user/interfaces/core-user-service-options.interface.ts +3 -3
- package/src/core.module.ts +28 -12
- package/src/index.ts +7 -0
- package/src/server/modules/better-auth/better-auth.controller.ts +4 -4
- package/src/server/modules/better-auth/better-auth.module.ts +1 -1
- package/src/server/modules/better-auth/better-auth.resolver.ts +31 -31
- package/src/server/modules/error-code/README.md +131 -0
- package/src/server/modules/error-code/error-code.controller.ts +91 -0
- package/src/server/modules/error-code/error-code.service.ts +42 -0
- package/src/server/modules/error-code/error-codes.ts +65 -0
- package/src/server/modules/error-code/index.ts +8 -0
- package/src/server/modules/user/user.service.ts +2 -2
- package/src/server/server.module.ts +10 -0
- package/src/test/test.helper.ts +13 -1
- package/dist/core/modules/better-auth/better-auth-auth.model.d.ts +0 -9
- package/dist/core/modules/better-auth/better-auth-auth.model.js.map +0 -1
- package/dist/core/modules/better-auth/better-auth-migration-status.model.js.map +0 -1
- package/dist/core/modules/better-auth/better-auth-models.js.map +0 -1
- package/dist/core/modules/better-auth/better-auth-rate-limit.middleware.d.ts +0 -12
- package/dist/core/modules/better-auth/better-auth-rate-limit.middleware.js.map +0 -1
- package/dist/core/modules/better-auth/better-auth-rate-limiter.service.js.map +0 -1
- package/dist/core/modules/better-auth/better-auth-user.mapper.js.map +0 -1
- package/dist/core/modules/better-auth/better-auth.middleware.d.ts +0 -21
- package/dist/core/modules/better-auth/better-auth.middleware.js.map +0 -1
- package/dist/core/modules/better-auth/better-auth.module.js.map +0 -1
- package/dist/core/modules/better-auth/better-auth.service.js.map +0 -1
|
@@ -4,18 +4,6 @@ import { Request, Response } from 'express';
|
|
|
4
4
|
|
|
5
5
|
import { Roles } from '../../common/decorators/roles.decorator';
|
|
6
6
|
import { RoleEnum } from '../../common/enums/role.enum';
|
|
7
|
-
import { BetterAuthAuthModel } from './better-auth-auth.model';
|
|
8
|
-
import { BetterAuthMigrationStatusModel } from './better-auth-migration-status.model';
|
|
9
|
-
import {
|
|
10
|
-
BetterAuth2FASetupModel,
|
|
11
|
-
BetterAuthFeaturesModel,
|
|
12
|
-
BetterAuthPasskeyChallengeModel,
|
|
13
|
-
BetterAuthPasskeyModel,
|
|
14
|
-
BetterAuthSessionModel,
|
|
15
|
-
BetterAuthUserModel,
|
|
16
|
-
} from './better-auth-models';
|
|
17
|
-
import { BetterAuthSessionUser, BetterAuthUserMapper, MappedUser } from './better-auth-user.mapper';
|
|
18
|
-
import { BetterAuthService } from './better-auth.service';
|
|
19
7
|
import {
|
|
20
8
|
BetterAuth2FAResponse,
|
|
21
9
|
BetterAuthSignInResponse,
|
|
@@ -24,6 +12,18 @@ import {
|
|
|
24
12
|
hasUser,
|
|
25
13
|
requires2FA,
|
|
26
14
|
} from './better-auth.types';
|
|
15
|
+
import { CoreBetterAuthAuthModel } from './core-better-auth-auth.model';
|
|
16
|
+
import { CoreBetterAuthMigrationStatusModel } from './core-better-auth-migration-status.model';
|
|
17
|
+
import {
|
|
18
|
+
CoreBetterAuth2FASetupModel,
|
|
19
|
+
CoreBetterAuthFeaturesModel,
|
|
20
|
+
CoreBetterAuthPasskeyChallengeModel,
|
|
21
|
+
CoreBetterAuthPasskeyModel,
|
|
22
|
+
CoreBetterAuthSessionModel,
|
|
23
|
+
CoreBetterAuthUserModel,
|
|
24
|
+
} from './core-better-auth-models';
|
|
25
|
+
import { BetterAuthSessionUser, CoreBetterAuthUserMapper, MappedUser } from './core-better-auth-user.mapper';
|
|
26
|
+
import { CoreBetterAuthService } from './core-better-auth.service';
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
29
|
* Abstract GraphQL Resolver for Better-Auth operations
|
|
@@ -38,11 +38,11 @@ import {
|
|
|
38
38
|
* @example
|
|
39
39
|
* ```typescript
|
|
40
40
|
* // In your project's better-auth.resolver.ts
|
|
41
|
-
* @Resolver(() =>
|
|
41
|
+
* @Resolver(() => CoreBetterAuthAuthModel)
|
|
42
42
|
* export class BetterAuthResolver extends CoreBetterAuthResolver {
|
|
43
43
|
* constructor(
|
|
44
|
-
* betterAuthService:
|
|
45
|
-
* userMapper:
|
|
44
|
+
* betterAuthService: CoreBetterAuthService,
|
|
45
|
+
* userMapper: CoreBetterAuthUserMapper,
|
|
46
46
|
* private readonly emailService: EmailService,
|
|
47
47
|
* ) {
|
|
48
48
|
* super(betterAuthService, userMapper);
|
|
@@ -59,14 +59,14 @@ import {
|
|
|
59
59
|
* }
|
|
60
60
|
* ```
|
|
61
61
|
*/
|
|
62
|
-
@Resolver(() =>
|
|
62
|
+
@Resolver(() => CoreBetterAuthAuthModel, { isAbstract: true })
|
|
63
63
|
@Roles(RoleEnum.ADMIN)
|
|
64
64
|
export class CoreBetterAuthResolver {
|
|
65
65
|
protected readonly logger = new Logger(CoreBetterAuthResolver.name);
|
|
66
66
|
|
|
67
67
|
constructor(
|
|
68
|
-
protected readonly betterAuthService:
|
|
69
|
-
protected readonly userMapper:
|
|
68
|
+
protected readonly betterAuthService: CoreBetterAuthService,
|
|
69
|
+
protected readonly userMapper: CoreBetterAuthUserMapper,
|
|
70
70
|
) {}
|
|
71
71
|
|
|
72
72
|
// ===========================================================================
|
|
@@ -76,12 +76,12 @@ export class CoreBetterAuthResolver {
|
|
|
76
76
|
/**
|
|
77
77
|
* Get current Better-Auth session
|
|
78
78
|
*/
|
|
79
|
-
@Query(() =>
|
|
79
|
+
@Query(() => CoreBetterAuthSessionModel, {
|
|
80
80
|
description: 'Get current Better-Auth session',
|
|
81
81
|
nullable: true,
|
|
82
82
|
})
|
|
83
83
|
@Roles(RoleEnum.S_USER)
|
|
84
|
-
async betterAuthSession(@Context() ctx: { req: Request }): Promise<
|
|
84
|
+
async betterAuthSession(@Context() ctx: { req: Request }): Promise<CoreBetterAuthSessionModel | null> {
|
|
85
85
|
if (!this.betterAuthService.isEnabled()) {
|
|
86
86
|
return null;
|
|
87
87
|
}
|
|
@@ -116,9 +116,9 @@ export class CoreBetterAuthResolver {
|
|
|
116
116
|
/**
|
|
117
117
|
* Get enabled Better-Auth features
|
|
118
118
|
*/
|
|
119
|
-
@Query(() =>
|
|
119
|
+
@Query(() => CoreBetterAuthFeaturesModel, { description: 'Get enabled Better-Auth features' })
|
|
120
120
|
@Roles(RoleEnum.S_EVERYONE)
|
|
121
|
-
betterAuthFeatures():
|
|
121
|
+
betterAuthFeatures(): CoreBetterAuthFeaturesModel {
|
|
122
122
|
return {
|
|
123
123
|
enabled: this.betterAuthService.isEnabled(),
|
|
124
124
|
jwt: this.betterAuthService.isJwtEnabled(),
|
|
@@ -164,11 +164,11 @@ export class CoreBetterAuthResolver {
|
|
|
164
164
|
* currently be removed because CoreModule.forRoot requires AuthService
|
|
165
165
|
* for GraphQL Subscriptions authentication.
|
|
166
166
|
*/
|
|
167
|
-
@Query(() =>
|
|
167
|
+
@Query(() => CoreBetterAuthMigrationStatusModel, {
|
|
168
168
|
description: 'Get migration status from Legacy Auth to Better-Auth (IAM) - Admin only',
|
|
169
169
|
})
|
|
170
170
|
@Roles(RoleEnum.ADMIN)
|
|
171
|
-
async betterAuthMigrationStatus(): Promise<
|
|
171
|
+
async betterAuthMigrationStatus(): Promise<CoreBetterAuthMigrationStatusModel> {
|
|
172
172
|
const status = await this.userMapper.getMigrationStatus();
|
|
173
173
|
return status;
|
|
174
174
|
}
|
|
@@ -188,7 +188,7 @@ export class CoreBetterAuthResolver {
|
|
|
188
188
|
*
|
|
189
189
|
* Override this method to add custom pre/post sign-in logic.
|
|
190
190
|
*/
|
|
191
|
-
@Mutation(() =>
|
|
191
|
+
@Mutation(() => CoreBetterAuthAuthModel, {
|
|
192
192
|
description: 'Sign in via Better-Auth (email/password)',
|
|
193
193
|
})
|
|
194
194
|
@Roles(RoleEnum.S_EVERYONE)
|
|
@@ -197,7 +197,7 @@ export class CoreBetterAuthResolver {
|
|
|
197
197
|
@Args('password') password: string,
|
|
198
198
|
// eslint-disable-next-line unused-imports/no-unused-vars -- Reserved for future cookie/session handling
|
|
199
199
|
@Context() _ctx: { req: Request; res: Response },
|
|
200
|
-
): Promise<
|
|
200
|
+
): Promise<CoreBetterAuthAuthModel> {
|
|
201
201
|
this.ensureEnabled();
|
|
202
202
|
|
|
203
203
|
const api = this.betterAuthService.getApi();
|
|
@@ -219,9 +219,9 @@ export class CoreBetterAuthResolver {
|
|
|
219
219
|
protected async attemptSignIn(
|
|
220
220
|
email: string,
|
|
221
221
|
password: string,
|
|
222
|
-
api: ReturnType<
|
|
222
|
+
api: ReturnType<CoreBetterAuthService['getApi']>,
|
|
223
223
|
allowMigration: boolean,
|
|
224
|
-
): Promise<
|
|
224
|
+
): Promise<CoreBetterAuthAuthModel> {
|
|
225
225
|
try {
|
|
226
226
|
// Try sign-in with original password first (for native IAM users)
|
|
227
227
|
const response = (await api!.signInEmail({
|
|
@@ -300,8 +300,8 @@ export class CoreBetterAuthResolver {
|
|
|
300
300
|
private async attemptSignInDirect(
|
|
301
301
|
email: string,
|
|
302
302
|
password: string,
|
|
303
|
-
api: ReturnType<
|
|
304
|
-
): Promise<
|
|
303
|
+
api: ReturnType<CoreBetterAuthService['getApi']>,
|
|
304
|
+
): Promise<CoreBetterAuthAuthModel> {
|
|
305
305
|
const response = (await api!.signInEmail({
|
|
306
306
|
body: { email, password },
|
|
307
307
|
})) as BetterAuthSignInResponse | null;
|
|
@@ -334,7 +334,7 @@ export class CoreBetterAuthResolver {
|
|
|
334
334
|
*
|
|
335
335
|
* Override this method to add custom pre/post sign-up logic (e.g., sending welcome emails).
|
|
336
336
|
*/
|
|
337
|
-
@Mutation(() =>
|
|
337
|
+
@Mutation(() => CoreBetterAuthAuthModel, {
|
|
338
338
|
description: 'Sign up via Better-Auth (email/password)',
|
|
339
339
|
})
|
|
340
340
|
@Roles(RoleEnum.S_EVERYONE)
|
|
@@ -342,7 +342,7 @@ export class CoreBetterAuthResolver {
|
|
|
342
342
|
@Args('email') email: string,
|
|
343
343
|
@Args('password') password: string,
|
|
344
344
|
@Args('name', { nullable: true }) name?: string,
|
|
345
|
-
): Promise<
|
|
345
|
+
): Promise<CoreBetterAuthAuthModel> {
|
|
346
346
|
this.ensureEnabled();
|
|
347
347
|
|
|
348
348
|
const api = this.betterAuthService.getApi();
|
|
@@ -417,14 +417,14 @@ export class CoreBetterAuthResolver {
|
|
|
417
417
|
/**
|
|
418
418
|
* Verify 2FA code
|
|
419
419
|
*/
|
|
420
|
-
@Mutation(() =>
|
|
420
|
+
@Mutation(() => CoreBetterAuthAuthModel, {
|
|
421
421
|
description: 'Verify 2FA code during sign-in',
|
|
422
422
|
})
|
|
423
423
|
@Roles(RoleEnum.S_EVERYONE)
|
|
424
424
|
async betterAuthVerify2FA(
|
|
425
425
|
@Args('code') code: string,
|
|
426
426
|
@Context() ctx: { req: Request },
|
|
427
|
-
): Promise<
|
|
427
|
+
): Promise<CoreBetterAuthAuthModel> {
|
|
428
428
|
this.ensureEnabled();
|
|
429
429
|
|
|
430
430
|
if (!this.betterAuthService.isTwoFactorEnabled()) {
|
|
@@ -483,14 +483,14 @@ export class CoreBetterAuthResolver {
|
|
|
483
483
|
* Enable 2FA for the current user
|
|
484
484
|
* Returns TOTP URI for QR code generation and backup codes
|
|
485
485
|
*/
|
|
486
|
-
@Mutation(() =>
|
|
486
|
+
@Mutation(() => CoreBetterAuth2FASetupModel, {
|
|
487
487
|
description: 'Enable 2FA for the current user',
|
|
488
488
|
})
|
|
489
489
|
@Roles(RoleEnum.S_USER)
|
|
490
490
|
async betterAuthEnable2FA(
|
|
491
491
|
@Args('password') password: string,
|
|
492
492
|
@Context() ctx: { req: Request },
|
|
493
|
-
): Promise<
|
|
493
|
+
): Promise<CoreBetterAuth2FASetupModel> {
|
|
494
494
|
this.ensureEnabled();
|
|
495
495
|
|
|
496
496
|
if (!this.betterAuthService.isTwoFactorEnabled()) {
|
|
@@ -628,11 +628,11 @@ export class CoreBetterAuthResolver {
|
|
|
628
628
|
* Get passkey registration challenge
|
|
629
629
|
* Returns the challenge data needed for WebAuthn registration
|
|
630
630
|
*/
|
|
631
|
-
@Mutation(() =>
|
|
631
|
+
@Mutation(() => CoreBetterAuthPasskeyChallengeModel, {
|
|
632
632
|
description: 'Get passkey registration challenge for WebAuthn',
|
|
633
633
|
})
|
|
634
634
|
@Roles(RoleEnum.S_USER)
|
|
635
|
-
async betterAuthGetPasskeyChallenge(@Context() ctx: { req: Request }): Promise<
|
|
635
|
+
async betterAuthGetPasskeyChallenge(@Context() ctx: { req: Request }): Promise<CoreBetterAuthPasskeyChallengeModel> {
|
|
636
636
|
this.ensureEnabled();
|
|
637
637
|
|
|
638
638
|
if (!this.betterAuthService.isPasskeyEnabled()) {
|
|
@@ -672,12 +672,12 @@ export class CoreBetterAuthResolver {
|
|
|
672
672
|
/**
|
|
673
673
|
* List passkeys for the current user
|
|
674
674
|
*/
|
|
675
|
-
@Query(() => [
|
|
675
|
+
@Query(() => [CoreBetterAuthPasskeyModel], {
|
|
676
676
|
description: 'List passkeys for the current user',
|
|
677
677
|
nullable: true,
|
|
678
678
|
})
|
|
679
679
|
@Roles(RoleEnum.S_USER)
|
|
680
|
-
async betterAuthListPasskeys(@Context() ctx: { req: Request }): Promise<
|
|
680
|
+
async betterAuthListPasskeys(@Context() ctx: { req: Request }): Promise<CoreBetterAuthPasskeyModel[] | null> {
|
|
681
681
|
if (!this.betterAuthService.isEnabled() || !this.betterAuthService.isPasskeyEnabled()) {
|
|
682
682
|
return null;
|
|
683
683
|
}
|
|
@@ -809,9 +809,9 @@ export class CoreBetterAuthResolver {
|
|
|
809
809
|
}
|
|
810
810
|
|
|
811
811
|
/**
|
|
812
|
-
* Map MappedUser to
|
|
812
|
+
* Map MappedUser to CoreBetterAuthUserModel
|
|
813
813
|
*/
|
|
814
|
-
protected mapToUserModel(user: MappedUser):
|
|
814
|
+
protected mapToUserModel(user: MappedUser): CoreBetterAuthUserModel {
|
|
815
815
|
return {
|
|
816
816
|
email: user.email,
|
|
817
817
|
emailVerified: user.emailVerified,
|
|
@@ -4,11 +4,12 @@ import { Request } from 'express';
|
|
|
4
4
|
import { importJWK, jwtVerify } from 'jose';
|
|
5
5
|
import { Connection } from 'mongoose';
|
|
6
6
|
|
|
7
|
+
import { isProduction, maskCookieHeader, maskEmail, maskToken } from '../../common/helpers/logging.helper';
|
|
7
8
|
import { IBetterAuth } from '../../common/interfaces/server-options.interface';
|
|
8
9
|
import { ConfigService } from '../../common/services/config.service';
|
|
9
|
-
import { BetterAuthSessionUser } from './better-auth-user.mapper';
|
|
10
10
|
import { BetterAuthInstance } from './better-auth.config';
|
|
11
|
-
import {
|
|
11
|
+
import { BetterAuthSessionUser } from './core-better-auth-user.mapper';
|
|
12
|
+
import { BETTER_AUTH_INSTANCE } from './core-better-auth.module';
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* Result of a session validation
|
|
@@ -24,7 +25,7 @@ export interface SessionResult {
|
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
/**
|
|
27
|
-
*
|
|
28
|
+
* CoreBetterAuthService provides a NestJS-friendly wrapper around the better-auth instance.
|
|
28
29
|
*
|
|
29
30
|
* This service:
|
|
30
31
|
* - Provides access to the better-auth API
|
|
@@ -35,7 +36,7 @@ export interface SessionResult {
|
|
|
35
36
|
* ```typescript
|
|
36
37
|
* @Injectable()
|
|
37
38
|
* export class MyService {
|
|
38
|
-
* constructor(private readonly betterAuthService:
|
|
39
|
+
* constructor(private readonly betterAuthService: CoreBetterAuthService) {}
|
|
39
40
|
*
|
|
40
41
|
* async doSomething() {
|
|
41
42
|
* if (this.betterAuthService.isEnabled()) {
|
|
@@ -52,8 +53,9 @@ export interface SessionResult {
|
|
|
52
53
|
export const BETTER_AUTH_CONFIG = 'BETTER_AUTH_CONFIG';
|
|
53
54
|
|
|
54
55
|
@Injectable()
|
|
55
|
-
export class
|
|
56
|
-
private readonly logger = new Logger(
|
|
56
|
+
export class CoreBetterAuthService {
|
|
57
|
+
private readonly logger = new Logger(CoreBetterAuthService.name);
|
|
58
|
+
private readonly isProd = isProduction();
|
|
57
59
|
private readonly config: IBetterAuth;
|
|
58
60
|
|
|
59
61
|
constructor(
|
|
@@ -304,15 +306,28 @@ export class BetterAuthService {
|
|
|
304
306
|
}
|
|
305
307
|
}
|
|
306
308
|
|
|
309
|
+
// Debug: Log the cookie header being sent to api.getSession (masked for security)
|
|
310
|
+
if (!this.isProd) {
|
|
311
|
+
const cookieHeader = headers.get('cookie');
|
|
312
|
+
this.logger.debug(`getSession called with cookies: ${maskCookieHeader(cookieHeader)}`);
|
|
313
|
+
}
|
|
314
|
+
|
|
307
315
|
const response = await api.getSession({ headers });
|
|
308
316
|
|
|
317
|
+
// Debug: Log the response from api.getSession
|
|
318
|
+
if (!this.isProd) {
|
|
319
|
+
this.logger.debug(`getSession response: ${JSON.stringify(response)?.substring(0, 200)}`);
|
|
320
|
+
}
|
|
321
|
+
|
|
309
322
|
if (response && typeof response === 'object' && 'user' in response) {
|
|
310
323
|
return response as SessionResult;
|
|
311
324
|
}
|
|
312
325
|
|
|
313
326
|
return { session: null, user: null };
|
|
314
327
|
} catch (error) {
|
|
315
|
-
this.
|
|
328
|
+
if (!this.isProd) {
|
|
329
|
+
this.logger.debug(`getSession error: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
330
|
+
}
|
|
316
331
|
return { session: null, user: null };
|
|
317
332
|
}
|
|
318
333
|
}
|
|
@@ -355,7 +370,9 @@ export class BetterAuthService {
|
|
|
355
370
|
await api.signOut({ headers });
|
|
356
371
|
return true;
|
|
357
372
|
} catch (error) {
|
|
358
|
-
this.
|
|
373
|
+
if (!this.isProd) {
|
|
374
|
+
this.logger.debug(`revokeSession error: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
375
|
+
}
|
|
359
376
|
return false;
|
|
360
377
|
}
|
|
361
378
|
}
|
|
@@ -416,59 +433,86 @@ export class BetterAuthService {
|
|
|
416
433
|
* @returns Session and user data, or null if not found/expired
|
|
417
434
|
*/
|
|
418
435
|
async getSessionByToken(token: string): Promise<SessionResult> {
|
|
419
|
-
if (!this.isEnabled() || !this.connection) {
|
|
436
|
+
if (!this.isEnabled() || !this.connection?.db) {
|
|
420
437
|
return { session: null, user: null };
|
|
421
438
|
}
|
|
422
439
|
|
|
423
440
|
try {
|
|
424
441
|
const db = this.connection.db;
|
|
425
|
-
if (!db) {
|
|
426
|
-
return { session: null, user: null };
|
|
427
|
-
}
|
|
428
|
-
|
|
429
442
|
const sessionsCollection = db.collection('session');
|
|
430
|
-
// Better-Auth is configured to use 'users' (plural) as the model name
|
|
431
|
-
// This matches the existing Legacy users collection for migration compatibility
|
|
432
|
-
const usersCollection = db.collection('users');
|
|
433
443
|
|
|
434
|
-
//
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
444
|
+
// Use aggregation pipeline for single-query lookup with automatic userId type handling
|
|
445
|
+
// This handles both ObjectId and string userId formats efficiently
|
|
446
|
+
const results = await sessionsCollection
|
|
447
|
+
.aggregate([
|
|
448
|
+
// Match session by token
|
|
449
|
+
{ $match: { token } },
|
|
450
|
+
// Join with users collection - handles both ObjectId and string userId
|
|
451
|
+
{
|
|
452
|
+
$lookup: {
|
|
453
|
+
as: 'userDoc',
|
|
454
|
+
from: 'users',
|
|
455
|
+
let: { sessionUserId: '$userId' },
|
|
456
|
+
pipeline: [
|
|
457
|
+
{
|
|
458
|
+
$match: {
|
|
459
|
+
$expr: {
|
|
460
|
+
$or: [
|
|
461
|
+
// Match by _id (ObjectId comparison)
|
|
462
|
+
{ $eq: ['$_id', '$$sessionUserId'] },
|
|
463
|
+
// Match by _id with string conversion
|
|
464
|
+
{ $eq: [{ $toString: '$_id' }, { $toString: '$$sessionUserId' }] },
|
|
465
|
+
// Match by id field (string field)
|
|
466
|
+
{ $eq: ['$id', { $toString: '$$sessionUserId' }] },
|
|
467
|
+
],
|
|
468
|
+
},
|
|
469
|
+
},
|
|
470
|
+
},
|
|
471
|
+
],
|
|
472
|
+
},
|
|
473
|
+
},
|
|
474
|
+
// Unwind user document (results in null if no match)
|
|
475
|
+
{ $unwind: { path: '$userDoc', preserveNullAndEmptyArrays: true } },
|
|
476
|
+
// Project final result
|
|
477
|
+
{ $limit: 1 },
|
|
478
|
+
])
|
|
479
|
+
.toArray();
|
|
480
|
+
|
|
481
|
+
const result = results[0];
|
|
482
|
+
|
|
483
|
+
if (!result) {
|
|
484
|
+
if (!this.isProd) {
|
|
485
|
+
this.logger.debug(`getSessionByToken: session not found for token ${maskToken(token)}`);
|
|
486
|
+
}
|
|
438
487
|
return { session: null, user: null };
|
|
439
488
|
}
|
|
440
489
|
|
|
441
490
|
// Check if session is expired
|
|
442
|
-
if (
|
|
491
|
+
if (result.expiresAt && new Date(result.expiresAt) < new Date()) {
|
|
492
|
+
if (!this.isProd) {
|
|
493
|
+
this.logger.debug(`getSessionByToken: session expired`);
|
|
494
|
+
}
|
|
443
495
|
return { session: null, user: null };
|
|
444
496
|
}
|
|
445
497
|
|
|
446
|
-
|
|
447
|
-
// Better-Auth stores userId as a string, try both string id and ObjectId
|
|
448
|
-
const { ObjectId } = require('mongodb');
|
|
449
|
-
|
|
450
|
-
let user = await usersCollection.findOne({ id: session.userId });
|
|
498
|
+
const user = result.userDoc;
|
|
451
499
|
if (!user) {
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
const objectId = new ObjectId(session.userId);
|
|
455
|
-
user = await usersCollection.findOne({ _id: objectId });
|
|
456
|
-
} catch {
|
|
457
|
-
// userId might not be a valid ObjectId, try string match
|
|
458
|
-
user = await usersCollection.findOne({ _id: session.userId });
|
|
500
|
+
if (!this.isProd) {
|
|
501
|
+
this.logger.debug(`getSessionByToken: user not found for session`);
|
|
459
502
|
}
|
|
503
|
+
return { session: null, user: null };
|
|
460
504
|
}
|
|
461
505
|
|
|
462
|
-
if (!
|
|
463
|
-
|
|
506
|
+
if (!this.isProd) {
|
|
507
|
+
this.logger.debug(`getSessionByToken: found session for user ${maskEmail(user.email)}`);
|
|
464
508
|
}
|
|
465
509
|
|
|
466
510
|
return {
|
|
467
511
|
session: {
|
|
468
|
-
expiresAt:
|
|
469
|
-
id:
|
|
470
|
-
|
|
471
|
-
|
|
512
|
+
expiresAt: result.expiresAt,
|
|
513
|
+
id: result.id || result._id?.toString(),
|
|
514
|
+
token: result.token,
|
|
515
|
+
userId: result.userId?.toString(),
|
|
472
516
|
},
|
|
473
517
|
user: {
|
|
474
518
|
email: user.email,
|
|
@@ -478,7 +522,9 @@ export class BetterAuthService {
|
|
|
478
522
|
},
|
|
479
523
|
};
|
|
480
524
|
} catch (error) {
|
|
481
|
-
this.
|
|
525
|
+
if (!this.isProd) {
|
|
526
|
+
this.logger.debug(`getSessionByToken error: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
527
|
+
}
|
|
482
528
|
return { session: null, user: null };
|
|
483
529
|
}
|
|
484
530
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* CoreBetterAuth Module exports
|
|
3
3
|
*
|
|
4
4
|
* Provides integration with the better-auth authentication framework.
|
|
5
5
|
* This module supports:
|
|
@@ -11,23 +11,30 @@
|
|
|
11
11
|
* - Rate limiting for brute-force protection
|
|
12
12
|
* - Parallel operation with Legacy Auth (bcrypt compatible)
|
|
13
13
|
*
|
|
14
|
+
* Naming Convention (consistent with other Core modules):
|
|
15
|
+
* - Core* prefix: Base classes for extension (CoreBetterAuthService, CoreBetterAuthModule, etc.)
|
|
16
|
+
* - Default* prefix: Default implementations (DefaultBetterAuthResolver)
|
|
17
|
+
* - No prefix in consuming projects: Your project's implementations (BetterAuthService, BetterAuthResolver)
|
|
18
|
+
*
|
|
14
19
|
* Extension points:
|
|
15
20
|
* - CoreBetterAuthController: Abstract controller for REST extension
|
|
16
21
|
* - CoreBetterAuthResolver: Abstract resolver for GraphQL extension (isAbstract: true)
|
|
17
|
-
* -
|
|
22
|
+
* - DefaultBetterAuthResolver: Default resolver implementation (use as fallback)
|
|
18
23
|
*/
|
|
19
24
|
|
|
20
|
-
export * from './better-auth-auth.model';
|
|
21
|
-
export * from './better-auth-migration-status.model';
|
|
22
|
-
export * from './better-auth-models';
|
|
23
|
-
export * from './better-auth-rate-limit.middleware';
|
|
24
|
-
export * from './better-auth-rate-limiter.service';
|
|
25
|
-
export * from './better-auth-user.mapper';
|
|
26
25
|
export * from './better-auth.config';
|
|
27
|
-
export * from './better-auth.middleware';
|
|
28
|
-
export * from './better-auth.module';
|
|
29
26
|
export * from './better-auth.resolver';
|
|
30
|
-
export * from './better-auth.service';
|
|
31
27
|
export * from './better-auth.types';
|
|
28
|
+
export * from './core-better-auth-api.middleware';
|
|
29
|
+
export * from './core-better-auth-auth.model';
|
|
30
|
+
export * from './core-better-auth-migration-status.model';
|
|
31
|
+
export * from './core-better-auth-models';
|
|
32
|
+
export * from './core-better-auth-rate-limit.middleware';
|
|
33
|
+
export * from './core-better-auth-rate-limiter.service';
|
|
34
|
+
export * from './core-better-auth-user.mapper';
|
|
35
|
+
export * from './core-better-auth-web.helper';
|
|
32
36
|
export * from './core-better-auth.controller';
|
|
37
|
+
export * from './core-better-auth.middleware';
|
|
38
|
+
export * from './core-better-auth.module';
|
|
33
39
|
export * from './core-better-auth.resolver';
|
|
40
|
+
export * from './core-better-auth.service';
|