@lenne.tech/nest-server 11.7.1 → 11.7.3
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/guards/roles.guard.d.ts +12 -2
- package/dist/core/modules/auth/guards/roles.guard.js +192 -5
- package/dist/core/modules/auth/guards/roles.guard.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/modules/user/core-user.service.d.ts +1 -0
- package/dist/core/modules/user/core-user.service.js +12 -0
- package/dist/core/modules/user/core-user.service.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/guards/roles.guard.ts +298 -5
- 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/modules/user/core-user.service.ts +27 -0
- 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
|
@@ -91,6 +91,33 @@ export abstract class CoreUserService<
|
|
|
91
91
|
return this.process(async () => dbObject, { dbObject, serviceOptions });
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
+
/**
|
|
95
|
+
* Get user by MongoDB ID or BetterAuth IAM ID
|
|
96
|
+
*
|
|
97
|
+
* This method is used by RolesGuard to resolve users from BetterAuth JWT tokens.
|
|
98
|
+
* The sub claim in BetterAuth JWTs can contain either:
|
|
99
|
+
* - The MongoDB _id of the user
|
|
100
|
+
* - The BetterAuth iamId
|
|
101
|
+
*
|
|
102
|
+
* @param idOrIamId - MongoDB _id or BetterAuth iamId
|
|
103
|
+
* @returns User object or null if not found
|
|
104
|
+
*/
|
|
105
|
+
async getByIdOrIamId(idOrIamId: string): Promise<null | TUser> {
|
|
106
|
+
try {
|
|
107
|
+
// First, try to find by MongoDB _id
|
|
108
|
+
const byId = await this.mainDbModel.findById(idOrIamId).exec();
|
|
109
|
+
if (byId) {
|
|
110
|
+
return byId as TUser;
|
|
111
|
+
}
|
|
112
|
+
} catch {
|
|
113
|
+
// Invalid ObjectId format - try iamId instead
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Try to find by iamId
|
|
117
|
+
const byIamId = await this.mainDbModel.findOne({ iamId: idOrIamId }).exec();
|
|
118
|
+
return byIamId as null | TUser;
|
|
119
|
+
}
|
|
120
|
+
|
|
94
121
|
/**
|
|
95
122
|
* Get verified state of user by token
|
|
96
123
|
*/
|
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,
|