@lenne.tech/nest-server 11.7.1 → 11.7.2
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/core/common/interfaces/server-options.interface.d.ts +18 -15
- package/dist/core/modules/auth/core-auth.controller.js +2 -2
- package/dist/core/modules/auth/core-auth.controller.js.map +1 -1
- package/dist/core/modules/auth/core-auth.resolver.js +2 -2
- package/dist/core/modules/auth/core-auth.resolver.js.map +1 -1
- package/dist/core/modules/auth/services/legacy-auth-rate-limiter.service.js +1 -1
- package/dist/core/modules/auth/services/legacy-auth-rate-limiter.service.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth-rate-limiter.service.js +1 -1
- package/dist/core/modules/better-auth/better-auth-rate-limiter.service.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth-user.mapper.js +7 -55
- package/dist/core/modules/better-auth/better-auth-user.mapper.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth.config.js +29 -10
- package/dist/core/modules/better-auth/better-auth.config.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth.middleware.d.ts +1 -0
- package/dist/core/modules/better-auth/better-auth.middleware.js +55 -1
- package/dist/core/modules/better-auth/better-auth.middleware.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth.module.d.ts +1 -1
- package/dist/core/modules/better-auth/better-auth.module.js +46 -18
- package/dist/core/modules/better-auth/better-auth.module.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth.resolver.js +0 -11
- package/dist/core/modules/better-auth/better-auth.resolver.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth.service.d.ts +22 -1
- package/dist/core/modules/better-auth/better-auth.service.js +209 -8
- package/dist/core/modules/better-auth/better-auth.service.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth.types.d.ts +2 -0
- package/dist/core/modules/better-auth/better-auth.types.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth.resolver.d.ts +5 -0
- package/dist/core/modules/better-auth/core-better-auth.resolver.js +58 -12
- package/dist/core/modules/better-auth/core-better-auth.resolver.js.map +1 -1
- package/dist/core.module.js +6 -3
- package/dist/core.module.js.map +1 -1
- package/dist/server/modules/better-auth/better-auth.module.d.ts +1 -1
- package/dist/server/modules/better-auth/better-auth.module.js +2 -1
- package/dist/server/modules/better-auth/better-auth.module.js.map +1 -1
- package/dist/server/modules/better-auth/better-auth.resolver.d.ts +3 -0
- package/dist/server/modules/better-auth/better-auth.resolver.js +14 -11
- package/dist/server/modules/better-auth/better-auth.resolver.js.map +1 -1
- package/dist/server/modules/user/user.controller.js +0 -8
- package/dist/server/modules/user/user.controller.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/core/common/interfaces/server-options.interface.ts +129 -58
- package/src/core/modules/auth/core-auth.controller.ts +2 -2
- package/src/core/modules/auth/core-auth.resolver.ts +2 -2
- package/src/core/modules/auth/services/legacy-auth-rate-limiter.service.ts +1 -1
- package/src/core/modules/better-auth/INTEGRATION-CHECKLIST.md +12 -11
- package/src/core/modules/better-auth/README.md +82 -43
- package/src/core/modules/better-auth/better-auth-rate-limiter.service.ts +1 -1
- package/src/core/modules/better-auth/better-auth-user.mapper.ts +9 -77
- package/src/core/modules/better-auth/better-auth.config.ts +45 -15
- package/src/core/modules/better-auth/better-auth.middleware.ts +85 -2
- package/src/core/modules/better-auth/better-auth.module.ts +83 -27
- package/src/core/modules/better-auth/better-auth.resolver.ts +0 -11
- package/src/core/modules/better-auth/better-auth.service.ts +367 -12
- package/src/core/modules/better-auth/better-auth.types.ts +16 -0
- package/src/core/modules/better-auth/core-better-auth.resolver.ts +111 -16
- package/src/core.module.ts +9 -3
- package/src/server/modules/better-auth/better-auth.module.ts +9 -3
- package/src/server/modules/better-auth/better-auth.resolver.ts +9 -11
- package/src/server/modules/user/user.controller.ts +1 -9
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import { BadRequestException, Logger, UnauthorizedException
|
|
1
|
+
import { BadRequestException, Logger, UnauthorizedException } from '@nestjs/common';
|
|
2
2
|
import { Args, Context, Mutation, Query, Resolver } from '@nestjs/graphql';
|
|
3
3
|
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 { AuthGuardStrategy } from '../auth/auth-guard-strategy.enum';
|
|
8
|
-
import { AuthGuard } from '../auth/guards/auth.guard';
|
|
9
7
|
import { BetterAuthAuthModel } from './better-auth-auth.model';
|
|
10
8
|
import { BetterAuthMigrationStatusModel } from './better-auth-migration-status.model';
|
|
11
9
|
import {
|
|
@@ -83,7 +81,6 @@ export class CoreBetterAuthResolver {
|
|
|
83
81
|
nullable: true,
|
|
84
82
|
})
|
|
85
83
|
@Roles(RoleEnum.S_USER)
|
|
86
|
-
@UseGuards(AuthGuard(AuthGuardStrategy.JWT))
|
|
87
84
|
async betterAuthSession(@Context() ctx: { req: Request }): Promise<BetterAuthSessionModel | null> {
|
|
88
85
|
if (!this.betterAuthService.isEnabled()) {
|
|
89
86
|
return null;
|
|
@@ -131,6 +128,27 @@ export class CoreBetterAuthResolver {
|
|
|
131
128
|
};
|
|
132
129
|
}
|
|
133
130
|
|
|
131
|
+
/**
|
|
132
|
+
* Get a fresh JWT token for the current session.
|
|
133
|
+
*
|
|
134
|
+
* Use this when your JWT has expired but your session is still valid.
|
|
135
|
+
* The JWT can be used for stateless authentication with other services
|
|
136
|
+
* that verify tokens via JWKS (`/iam/jwks`).
|
|
137
|
+
*
|
|
138
|
+
* Returns null if:
|
|
139
|
+
* - Better-Auth is not enabled
|
|
140
|
+
* - JWT plugin is not enabled
|
|
141
|
+
* - No valid session exists
|
|
142
|
+
*/
|
|
143
|
+
@Query(() => String, {
|
|
144
|
+
description: 'Get fresh JWT token for the current session (requires valid session)',
|
|
145
|
+
nullable: true,
|
|
146
|
+
})
|
|
147
|
+
@Roles(RoleEnum.S_USER)
|
|
148
|
+
async betterAuthToken(@Context() ctx: { req: Request }): Promise<null | string> {
|
|
149
|
+
return this.betterAuthService.getToken(ctx.req);
|
|
150
|
+
}
|
|
151
|
+
|
|
134
152
|
/**
|
|
135
153
|
* Get migration status from Legacy Auth to Better-Auth (IAM)
|
|
136
154
|
*
|
|
@@ -165,6 +183,9 @@ export class CoreBetterAuthResolver {
|
|
|
165
183
|
* This mutation wraps Better-Auth's sign-in endpoint and returns a response
|
|
166
184
|
* compatible with the existing auth system.
|
|
167
185
|
*
|
|
186
|
+
* Features automatic legacy user migration: If a user exists in Legacy Auth
|
|
187
|
+
* but not in IAM, they will be automatically migrated on first IAM sign-in.
|
|
188
|
+
*
|
|
168
189
|
* Override this method to add custom pre/post sign-in logic.
|
|
169
190
|
*/
|
|
170
191
|
@Mutation(() => BetterAuthAuthModel, {
|
|
@@ -184,12 +205,38 @@ export class CoreBetterAuthResolver {
|
|
|
184
205
|
throw new BadRequestException('Better-Auth API not available');
|
|
185
206
|
}
|
|
186
207
|
|
|
208
|
+
// Try to sign in, with automatic legacy user migration
|
|
209
|
+
return this.attemptSignIn(email, password, api, true);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Attempt sign-in with optional legacy user migration
|
|
214
|
+
* @param email - User email
|
|
215
|
+
* @param password - User password (plain or SHA256)
|
|
216
|
+
* @param api - Better-Auth API instance
|
|
217
|
+
* @param allowMigration - Whether to attempt legacy migration on failure
|
|
218
|
+
*/
|
|
219
|
+
protected async attemptSignIn(
|
|
220
|
+
email: string,
|
|
221
|
+
password: string,
|
|
222
|
+
api: ReturnType<BetterAuthService['getApi']>,
|
|
223
|
+
allowMigration: boolean,
|
|
224
|
+
): Promise<BetterAuthAuthModel> {
|
|
187
225
|
try {
|
|
188
|
-
//
|
|
189
|
-
const response = (await api
|
|
226
|
+
// Try sign-in with original password first (for native IAM users)
|
|
227
|
+
const response = (await api!.signInEmail({
|
|
190
228
|
body: { email, password },
|
|
191
229
|
})) as BetterAuthSignInResponse | null;
|
|
192
230
|
|
|
231
|
+
this.logger.debug(`[SignIn] API response for ${email}: ${JSON.stringify(response)?.substring(0, 200)}`);
|
|
232
|
+
|
|
233
|
+
// Check if response indicates an error (Better-Auth returns error objects, not throws)
|
|
234
|
+
const responseAny = response as any;
|
|
235
|
+
if (responseAny?.error || responseAny?.code === 'CREDENTIAL_ACCOUNT_NOT_FOUND') {
|
|
236
|
+
this.logger.debug(`[SignIn] API returned error for ${email}: ${responseAny?.error || responseAny?.code}`);
|
|
237
|
+
throw new Error(responseAny?.error || responseAny?.code || 'Credential account not found');
|
|
238
|
+
}
|
|
239
|
+
|
|
193
240
|
if (!response) {
|
|
194
241
|
throw new UnauthorizedException('Invalid credentials');
|
|
195
242
|
}
|
|
@@ -208,8 +255,11 @@ export class CoreBetterAuthResolver {
|
|
|
208
255
|
const sessionUser: BetterAuthSessionUser = response.user;
|
|
209
256
|
const mappedUser = await this.userMapper.mapSessionUser(sessionUser);
|
|
210
257
|
|
|
211
|
-
//
|
|
212
|
-
|
|
258
|
+
// Return the session token for session-based authentication
|
|
259
|
+
// Note: If JWT plugin is enabled, accessToken may be in response or in set-auth-jwt header
|
|
260
|
+
// For GraphQL responses, we return the session token and let clients use it for session auth
|
|
261
|
+
const responseAny = response as any;
|
|
262
|
+
const token = responseAny.accessToken || responseAny.token;
|
|
213
263
|
|
|
214
264
|
return {
|
|
215
265
|
requiresTwoFactor: false,
|
|
@@ -222,9 +272,61 @@ export class CoreBetterAuthResolver {
|
|
|
222
272
|
|
|
223
273
|
throw new UnauthorizedException('Invalid credentials');
|
|
224
274
|
} catch (error) {
|
|
225
|
-
this.logger.debug(
|
|
275
|
+
this.logger.debug(
|
|
276
|
+
`[SignIn] Sign-in failed for ${email}: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
277
|
+
);
|
|
278
|
+
|
|
279
|
+
// If migration is allowed, try to migrate legacy user and retry
|
|
280
|
+
if (allowMigration) {
|
|
281
|
+
this.logger.debug(`[SignIn] Attempting migration for ${email}...`);
|
|
282
|
+
// Pass the original password for legacy verification
|
|
283
|
+
const migrated = await this.userMapper.migrateAccountToIam(email, password);
|
|
284
|
+
this.logger.debug(`[SignIn] Migration result for ${email}: ${migrated}`);
|
|
285
|
+
if (migrated) {
|
|
286
|
+
this.logger.debug(`[SignIn] Migrated legacy user ${email} to IAM, retrying sign-in`);
|
|
287
|
+
// Retry sign-in after migration with normalized password (as migrateAccountToIam stores it)
|
|
288
|
+
const normalizedPassword = this.userMapper.normalizePasswordForIam(password);
|
|
289
|
+
return this.attemptSignInDirect(email, normalizedPassword, api);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
throw new UnauthorizedException('Invalid credentials');
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Direct sign-in attempt without migration logic (used after migration)
|
|
299
|
+
*/
|
|
300
|
+
private async attemptSignInDirect(
|
|
301
|
+
email: string,
|
|
302
|
+
password: string,
|
|
303
|
+
api: ReturnType<BetterAuthService['getApi']>,
|
|
304
|
+
): Promise<BetterAuthAuthModel> {
|
|
305
|
+
const response = (await api!.signInEmail({
|
|
306
|
+
body: { email, password },
|
|
307
|
+
})) as BetterAuthSignInResponse | null;
|
|
308
|
+
|
|
309
|
+
if (!response || !hasUser(response)) {
|
|
226
310
|
throw new UnauthorizedException('Invalid credentials');
|
|
227
311
|
}
|
|
312
|
+
|
|
313
|
+
if (requires2FA(response)) {
|
|
314
|
+
return { requiresTwoFactor: true, success: false, user: null };
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const sessionUser: BetterAuthSessionUser = response.user;
|
|
318
|
+
const mappedUser = await this.userMapper.mapSessionUser(sessionUser);
|
|
319
|
+
// Return accessToken if available (JWT), otherwise fall back to session token
|
|
320
|
+
const responseAny = response as any;
|
|
321
|
+
const token = responseAny.accessToken || responseAny.token;
|
|
322
|
+
|
|
323
|
+
return {
|
|
324
|
+
requiresTwoFactor: false,
|
|
325
|
+
session: hasSession(response) ? this.mapSessionInfo(response.session) : null,
|
|
326
|
+
success: true,
|
|
327
|
+
token,
|
|
328
|
+
user: mappedUser ? this.mapToUserModel(mappedUser) : null,
|
|
329
|
+
};
|
|
228
330
|
}
|
|
229
331
|
|
|
230
332
|
/**
|
|
@@ -292,7 +394,6 @@ export class CoreBetterAuthResolver {
|
|
|
292
394
|
*/
|
|
293
395
|
@Mutation(() => Boolean, { description: 'Sign out via Better-Auth' })
|
|
294
396
|
@Roles(RoleEnum.S_USER)
|
|
295
|
-
@UseGuards(AuthGuard(AuthGuardStrategy.JWT))
|
|
296
397
|
async betterAuthSignOut(@Context() ctx: { req: Request }): Promise<boolean> {
|
|
297
398
|
if (!this.betterAuthService.isEnabled()) {
|
|
298
399
|
return false;
|
|
@@ -386,7 +487,6 @@ export class CoreBetterAuthResolver {
|
|
|
386
487
|
description: 'Enable 2FA for the current user',
|
|
387
488
|
})
|
|
388
489
|
@Roles(RoleEnum.S_USER)
|
|
389
|
-
@UseGuards(AuthGuard(AuthGuardStrategy.JWT))
|
|
390
490
|
async betterAuthEnable2FA(
|
|
391
491
|
@Args('password') password: string,
|
|
392
492
|
@Context() ctx: { req: Request },
|
|
@@ -441,7 +541,6 @@ export class CoreBetterAuthResolver {
|
|
|
441
541
|
description: 'Disable 2FA for the current user',
|
|
442
542
|
})
|
|
443
543
|
@Roles(RoleEnum.S_USER)
|
|
444
|
-
@UseGuards(AuthGuard(AuthGuardStrategy.JWT))
|
|
445
544
|
async betterAuthDisable2FA(@Args('password') password: string, @Context() ctx: { req: Request }): Promise<boolean> {
|
|
446
545
|
this.ensureEnabled();
|
|
447
546
|
|
|
@@ -487,7 +586,6 @@ export class CoreBetterAuthResolver {
|
|
|
487
586
|
nullable: true,
|
|
488
587
|
})
|
|
489
588
|
@Roles(RoleEnum.S_USER)
|
|
490
|
-
@UseGuards(AuthGuard(AuthGuardStrategy.JWT))
|
|
491
589
|
async betterAuthGenerateBackupCodes(@Context() ctx: { req: Request }): Promise<null | string[]> {
|
|
492
590
|
this.ensureEnabled();
|
|
493
591
|
|
|
@@ -534,7 +632,6 @@ export class CoreBetterAuthResolver {
|
|
|
534
632
|
description: 'Get passkey registration challenge for WebAuthn',
|
|
535
633
|
})
|
|
536
634
|
@Roles(RoleEnum.S_USER)
|
|
537
|
-
@UseGuards(AuthGuard(AuthGuardStrategy.JWT))
|
|
538
635
|
async betterAuthGetPasskeyChallenge(@Context() ctx: { req: Request }): Promise<BetterAuthPasskeyChallengeModel> {
|
|
539
636
|
this.ensureEnabled();
|
|
540
637
|
|
|
@@ -580,7 +677,6 @@ export class CoreBetterAuthResolver {
|
|
|
580
677
|
nullable: true,
|
|
581
678
|
})
|
|
582
679
|
@Roles(RoleEnum.S_USER)
|
|
583
|
-
@UseGuards(AuthGuard(AuthGuardStrategy.JWT))
|
|
584
680
|
async betterAuthListPasskeys(@Context() ctx: { req: Request }): Promise<BetterAuthPasskeyModel[] | null> {
|
|
585
681
|
if (!this.betterAuthService.isEnabled() || !this.betterAuthService.isPasskeyEnabled()) {
|
|
586
682
|
return null;
|
|
@@ -627,7 +723,6 @@ export class CoreBetterAuthResolver {
|
|
|
627
723
|
description: 'Delete a passkey by ID',
|
|
628
724
|
})
|
|
629
725
|
@Roles(RoleEnum.S_USER)
|
|
630
|
-
@UseGuards(AuthGuard(AuthGuardStrategy.JWT))
|
|
631
726
|
async betterAuthDeletePasskey(
|
|
632
727
|
@Args('passkeyId') passkeyId: string,
|
|
633
728
|
@Context() ctx: { req: Request },
|
package/src/core.module.ts
CHANGED
|
@@ -233,11 +233,17 @@ export class CoreModule implements NestModule {
|
|
|
233
233
|
// Add BetterAuthModule based on mode
|
|
234
234
|
// IAM-only mode: Always register BetterAuthModule (required for subscription auth)
|
|
235
235
|
// Legacy mode: Only register if autoRegister is explicitly true
|
|
236
|
-
|
|
237
|
-
|
|
236
|
+
// betterAuth can be: boolean | IBetterAuth | undefined
|
|
237
|
+
const betterAuthConfig = config.betterAuth;
|
|
238
|
+
const isBetterAuthEnabled =
|
|
239
|
+
betterAuthConfig === true || (typeof betterAuthConfig === 'object' && betterAuthConfig?.enabled !== false);
|
|
240
|
+
const isAutoRegister = typeof betterAuthConfig === 'object' && betterAuthConfig?.autoRegister === true;
|
|
241
|
+
|
|
242
|
+
if (isBetterAuthEnabled) {
|
|
243
|
+
if (isIamOnlyMode || isAutoRegister) {
|
|
238
244
|
imports.push(
|
|
239
245
|
BetterAuthModule.forRoot({
|
|
240
|
-
config:
|
|
246
|
+
config: betterAuthConfig === true ? {} : betterAuthConfig || {},
|
|
241
247
|
// Pass JWT secrets for backwards compatibility fallback
|
|
242
248
|
fallbackSecrets: [config.jwt?.secret, config.jwt?.refresh?.secret],
|
|
243
249
|
}),
|
|
@@ -10,9 +10,13 @@ import { BetterAuthResolver } from './better-auth.resolver';
|
|
|
10
10
|
*/
|
|
11
11
|
export interface ServerBetterAuthModuleOptions {
|
|
12
12
|
/**
|
|
13
|
-
* Better-auth configuration
|
|
13
|
+
* Better-auth configuration.
|
|
14
|
+
* Accepts:
|
|
15
|
+
* - `true`: Enable with all defaults (including JWT)
|
|
16
|
+
* - `false`: Disable BetterAuth
|
|
17
|
+
* - `{ ... }`: Enable with custom configuration
|
|
14
18
|
*/
|
|
15
|
-
config: IBetterAuth;
|
|
19
|
+
config: boolean | IBetterAuth;
|
|
16
20
|
|
|
17
21
|
/**
|
|
18
22
|
* Fallback secrets for backwards compatibility with JWT config.
|
|
@@ -63,7 +67,9 @@ export class BetterAuthModule {
|
|
|
63
67
|
const { config, fallbackSecrets } = options;
|
|
64
68
|
|
|
65
69
|
// If better-auth is explicitly disabled, return minimal module
|
|
66
|
-
|
|
70
|
+
// Supports: false, { enabled: false }, or undefined/null
|
|
71
|
+
const isDisabled = config === false || (typeof config === 'object' && config?.enabled === false);
|
|
72
|
+
if (isDisabled) {
|
|
67
73
|
return {
|
|
68
74
|
exports: [],
|
|
69
75
|
module: BetterAuthModule,
|
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
import { UseGuards } from '@nestjs/common';
|
|
2
1
|
import { Args, Context, Mutation, Query, Resolver } from '@nestjs/graphql';
|
|
3
2
|
import { Request, Response } from 'express';
|
|
4
3
|
|
|
5
4
|
import { Roles } from '../../../core/common/decorators/roles.decorator';
|
|
6
5
|
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
6
|
import { BetterAuthAuthModel } from '../../../core/modules/better-auth/better-auth-auth.model';
|
|
10
7
|
import { BetterAuthMigrationStatusModel } from '../../../core/modules/better-auth/better-auth-migration-status.model';
|
|
11
8
|
import {
|
|
@@ -62,7 +59,6 @@ export class BetterAuthResolver extends CoreBetterAuthResolver {
|
|
|
62
59
|
nullable: true,
|
|
63
60
|
})
|
|
64
61
|
@Roles(RoleEnum.S_USER)
|
|
65
|
-
@UseGuards(AuthGuard(AuthGuardStrategy.JWT))
|
|
66
62
|
override async betterAuthSession(@Context() ctx: { req: Request }): Promise<BetterAuthSessionModel | null> {
|
|
67
63
|
return super.betterAuthSession(ctx);
|
|
68
64
|
}
|
|
@@ -87,12 +83,20 @@ export class BetterAuthResolver extends CoreBetterAuthResolver {
|
|
|
87
83
|
return super.betterAuthMigrationStatus();
|
|
88
84
|
}
|
|
89
85
|
|
|
86
|
+
@Query(() => String, {
|
|
87
|
+
description: 'Get fresh JWT token for the current session (requires valid session)',
|
|
88
|
+
nullable: true,
|
|
89
|
+
})
|
|
90
|
+
@Roles(RoleEnum.S_USER)
|
|
91
|
+
override async betterAuthToken(@Context() ctx: { req: Request }): Promise<null | string> {
|
|
92
|
+
return super.betterAuthToken(ctx);
|
|
93
|
+
}
|
|
94
|
+
|
|
90
95
|
@Query(() => [BetterAuthPasskeyModel], {
|
|
91
96
|
description: 'List passkeys for the current user',
|
|
92
97
|
nullable: true,
|
|
93
98
|
})
|
|
94
99
|
@Roles(RoleEnum.S_USER)
|
|
95
|
-
@UseGuards(AuthGuard(AuthGuardStrategy.JWT))
|
|
96
100
|
override async betterAuthListPasskeys(@Context() ctx: { req: Request }): Promise<BetterAuthPasskeyModel[] | null> {
|
|
97
101
|
return super.betterAuthListPasskeys(ctx);
|
|
98
102
|
}
|
|
@@ -127,7 +131,6 @@ export class BetterAuthResolver extends CoreBetterAuthResolver {
|
|
|
127
131
|
|
|
128
132
|
@Mutation(() => Boolean, { description: 'Sign out via Better-Auth' })
|
|
129
133
|
@Roles(RoleEnum.S_USER)
|
|
130
|
-
@UseGuards(AuthGuard(AuthGuardStrategy.JWT))
|
|
131
134
|
override async betterAuthSignOut(@Context() ctx: { req: Request }): Promise<boolean> {
|
|
132
135
|
return super.betterAuthSignOut(ctx);
|
|
133
136
|
}
|
|
@@ -151,7 +154,6 @@ export class BetterAuthResolver extends CoreBetterAuthResolver {
|
|
|
151
154
|
description: 'Enable 2FA for the current user',
|
|
152
155
|
})
|
|
153
156
|
@Roles(RoleEnum.S_USER)
|
|
154
|
-
@UseGuards(AuthGuard(AuthGuardStrategy.JWT))
|
|
155
157
|
override async betterAuthEnable2FA(
|
|
156
158
|
@Args('password') password: string,
|
|
157
159
|
@Context() ctx: { req: Request },
|
|
@@ -163,7 +165,6 @@ export class BetterAuthResolver extends CoreBetterAuthResolver {
|
|
|
163
165
|
description: 'Disable 2FA for the current user',
|
|
164
166
|
})
|
|
165
167
|
@Roles(RoleEnum.S_USER)
|
|
166
|
-
@UseGuards(AuthGuard(AuthGuardStrategy.JWT))
|
|
167
168
|
override async betterAuthDisable2FA(
|
|
168
169
|
@Args('password') password: string,
|
|
169
170
|
@Context() ctx: { req: Request },
|
|
@@ -176,7 +177,6 @@ export class BetterAuthResolver extends CoreBetterAuthResolver {
|
|
|
176
177
|
nullable: true,
|
|
177
178
|
})
|
|
178
179
|
@Roles(RoleEnum.S_USER)
|
|
179
|
-
@UseGuards(AuthGuard(AuthGuardStrategy.JWT))
|
|
180
180
|
override async betterAuthGenerateBackupCodes(@Context() ctx: { req: Request }): Promise<null | string[]> {
|
|
181
181
|
return super.betterAuthGenerateBackupCodes(ctx);
|
|
182
182
|
}
|
|
@@ -189,7 +189,6 @@ export class BetterAuthResolver extends CoreBetterAuthResolver {
|
|
|
189
189
|
description: 'Get passkey registration challenge for WebAuthn',
|
|
190
190
|
})
|
|
191
191
|
@Roles(RoleEnum.S_USER)
|
|
192
|
-
@UseGuards(AuthGuard(AuthGuardStrategy.JWT))
|
|
193
192
|
override async betterAuthGetPasskeyChallenge(
|
|
194
193
|
@Context() ctx: { req: Request },
|
|
195
194
|
): Promise<BetterAuthPasskeyChallengeModel> {
|
|
@@ -200,7 +199,6 @@ export class BetterAuthResolver extends CoreBetterAuthResolver {
|
|
|
200
199
|
description: 'Delete a passkey by ID',
|
|
201
200
|
})
|
|
202
201
|
@Roles(RoleEnum.S_USER)
|
|
203
|
-
@UseGuards(AuthGuard(AuthGuardStrategy.JWT))
|
|
204
202
|
override async betterAuthDeletePasskey(
|
|
205
203
|
@Args('passkeyId') passkeyId: string,
|
|
206
204
|
@Context() ctx: { req: Request },
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Body, Controller, Delete, Get, Param, Patch, Post, Query
|
|
1
|
+
import { Body, Controller, Delete, Get, Param, Patch, Post, Query } from '@nestjs/common';
|
|
2
2
|
import {
|
|
3
3
|
ApiBearerAuth,
|
|
4
4
|
ApiBody,
|
|
@@ -15,8 +15,6 @@ import { CurrentUser } from '../../../core/common/decorators/current-user.decora
|
|
|
15
15
|
import { Roles } from '../../../core/common/decorators/roles.decorator';
|
|
16
16
|
import { RoleEnum } from '../../../core/common/enums/role.enum';
|
|
17
17
|
import { ServiceOptions } from '../../../core/common/interfaces/service-options.interface';
|
|
18
|
-
import { AuthGuardStrategy } from '../../../core/modules/auth/auth-guard-strategy.enum';
|
|
19
|
-
import { AuthGuard } from '../../../core/modules/auth/guards/auth.guard';
|
|
20
18
|
import { UserCreateInput } from './inputs/user-create.input';
|
|
21
19
|
import { UserInput } from './inputs/user.input';
|
|
22
20
|
import { FindAndCountUsersResult } from './outputs/find-and-count-users-result.output';
|
|
@@ -48,7 +46,6 @@ export class UserController {
|
|
|
48
46
|
@ApiOperation({ description: 'Find users (via filter)', summary: 'Get all users' })
|
|
49
47
|
@Get()
|
|
50
48
|
@Roles(RoleEnum.ADMIN)
|
|
51
|
-
@UseGuards(AuthGuard(AuthGuardStrategy.JWT))
|
|
52
49
|
async findUsers(@CurrentUser() currentUser: User): Promise<User[]> {
|
|
53
50
|
const serviceOptions: ServiceOptions = {
|
|
54
51
|
currentUser,
|
|
@@ -67,7 +64,6 @@ export class UserController {
|
|
|
67
64
|
})
|
|
68
65
|
@Get('count')
|
|
69
66
|
@Roles(RoleEnum.ADMIN)
|
|
70
|
-
@UseGuards(AuthGuard(AuthGuardStrategy.JWT))
|
|
71
67
|
async findAndCountUsers(@CurrentUser() currentUser: User): Promise<FindAndCountUsersResult> {
|
|
72
68
|
const serviceOptions: ServiceOptions = {
|
|
73
69
|
currentUser,
|
|
@@ -99,7 +95,6 @@ export class UserController {
|
|
|
99
95
|
@ApiParam({ description: 'User ID', name: 'id', type: String })
|
|
100
96
|
@Get(':id')
|
|
101
97
|
@Roles(RoleEnum.S_USER)
|
|
102
|
-
@UseGuards(AuthGuard(AuthGuardStrategy.JWT))
|
|
103
98
|
async getUser(@CurrentUser() currentUser: User, @Param('id') id: string): Promise<User> {
|
|
104
99
|
const serviceOptions: ServiceOptions = {
|
|
105
100
|
currentUser,
|
|
@@ -121,7 +116,6 @@ export class UserController {
|
|
|
121
116
|
@ApiOperation({ description: 'Create a new user', summary: 'Create user' })
|
|
122
117
|
@Post()
|
|
123
118
|
@Roles(RoleEnum.ADMIN)
|
|
124
|
-
@UseGuards(AuthGuard(AuthGuardStrategy.JWT))
|
|
125
119
|
async createUser(@CurrentUser() currentUser: User, @Body() input: UserCreateInput): Promise<User> {
|
|
126
120
|
const serviceOptions: ServiceOptions = {
|
|
127
121
|
currentUser,
|
|
@@ -208,7 +202,6 @@ export class UserController {
|
|
|
208
202
|
@ApiParam({ description: 'User ID', name: 'id', type: String })
|
|
209
203
|
@Patch(':id')
|
|
210
204
|
@Roles(RoleEnum.S_USER)
|
|
211
|
-
@UseGuards(AuthGuard(AuthGuardStrategy.JWT))
|
|
212
205
|
async updateUser(@CurrentUser() currentUser: User, @Param('id') id: string, @Body() input: UserInput): Promise<User> {
|
|
213
206
|
const serviceOptions: ServiceOptions = {
|
|
214
207
|
currentUser,
|
|
@@ -231,7 +224,6 @@ export class UserController {
|
|
|
231
224
|
@ApiParam({ description: 'User ID', name: 'id', type: String })
|
|
232
225
|
@Delete(':id')
|
|
233
226
|
@Roles(RoleEnum.S_USER)
|
|
234
|
-
@UseGuards(AuthGuard(AuthGuardStrategy.JWT))
|
|
235
227
|
async deleteUser(@CurrentUser() currentUser: User, @Param('id') id: string): Promise<User> {
|
|
236
228
|
const serviceOptions: ServiceOptions = {
|
|
237
229
|
currentUser,
|