@ackplus/nest-auth 1.1.18 → 1.1.20
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/package.json +1 -1
- package/src/lib/admin-console/static/index.html +697 -177
- package/src/lib/audit/services/audit.service.d.ts +15 -0
- package/src/lib/audit/services/audit.service.d.ts.map +1 -0
- package/src/lib/audit/services/audit.service.js +143 -0
- package/src/lib/auth/controllers/auth.controller.d.ts +1 -1
- package/src/lib/auth/controllers/mfa.controller.js +5 -5
- package/src/lib/auth/dto/responses/mfa-status.response.dto.d.ts +2 -2
- package/src/lib/auth/dto/responses/mfa-status.response.dto.d.ts.map +1 -1
- package/src/lib/auth/dto/responses/mfa-status.response.dto.js +5 -5
- package/src/lib/auth/events/index.d.ts +13 -0
- package/src/lib/auth/events/index.d.ts.map +1 -0
- package/src/lib/auth/events/index.js +15 -0
- package/src/lib/auth/events/user-2fa-disabled.event.d.ts +10 -0
- package/src/lib/auth/events/user-2fa-disabled.event.d.ts.map +1 -0
- package/src/lib/auth/events/user-2fa-disabled.event.js +12 -0
- package/src/lib/auth/events/user-2fa-enabled.event.d.ts +13 -0
- package/src/lib/auth/events/user-2fa-enabled.event.d.ts.map +1 -0
- package/src/lib/auth/events/user-2fa-enabled.event.js +15 -0
- package/src/lib/auth/events/user-password-changed.event.d.ts +12 -0
- package/src/lib/auth/events/user-password-changed.event.d.ts.map +1 -0
- package/src/lib/auth/events/user-password-changed.event.js +15 -0
- package/src/lib/auth/guards/auth.guard.d.ts +19 -1
- package/src/lib/auth/guards/auth.guard.d.ts.map +1 -1
- package/src/lib/auth/guards/auth.guard.js +113 -25
- package/src/lib/auth/services/auth.service.d.ts +10 -6
- package/src/lib/auth/services/auth.service.d.ts.map +1 -1
- package/src/lib/auth/services/auth.service.js +313 -133
- package/src/lib/auth/services/mfa.service.d.ts +1 -1
- package/src/lib/auth/services/mfa.service.d.ts.map +1 -1
- package/src/lib/auth/services/mfa.service.js +46 -10
- package/src/lib/auth.constants.d.ts +181 -8
- package/src/lib/auth.constants.d.ts.map +1 -1
- package/src/lib/auth.constants.js +142 -10
- package/src/lib/core/interfaces/auth-module-options.interface.d.ts +170 -0
- package/src/lib/core/interfaces/auth-module-options.interface.d.ts.map +1 -1
- package/src/lib/core/interfaces/session-options.interface.d.ts +52 -0
- package/src/lib/core/interfaces/session-options.interface.d.ts.map +1 -1
- package/src/lib/core/interfaces/token-payload.interface.d.ts +14 -6
- package/src/lib/core/interfaces/token-payload.interface.d.ts.map +1 -1
- package/src/lib/core/services/auth-config.service.js +1 -1
- package/src/lib/nest-auth.module.d.ts.map +1 -1
- package/src/lib/nest-auth.module.js +5 -2
- package/src/lib/session/services/session-manager.service.d.ts +6 -6
- package/src/lib/session/services/session-manager.service.d.ts.map +1 -1
- package/src/lib/session/services/session-manager.service.js +54 -21
- package/src/lib/user/entities/user.entity.d.ts.map +1 -1
- package/src/lib/user/entities/user.entity.js +19 -0
- package/src/lib/user/services/user.service.d.ts +8 -6
- package/src/lib/user/services/user.service.d.ts.map +1 -1
- package/src/lib/user/services/user.service.js +51 -46
|
@@ -11,6 +11,7 @@ const access_key_service_1 = require("../../user/services/access-key.service");
|
|
|
11
11
|
const skip_mfa_decorator_1 = require("../../core/decorators/skip-mfa.decorator");
|
|
12
12
|
const permissions_decorator_1 = require("../../core/decorators/permissions.decorator");
|
|
13
13
|
const role_decorator_1 = require("../../core/decorators/role.decorator");
|
|
14
|
+
const auth_config_service_1 = require("../../core/services/auth-config.service");
|
|
14
15
|
// Key for optional auth metadata
|
|
15
16
|
exports.OPTIONAL_AUTH_KEY = 'optional_auth';
|
|
16
17
|
/**
|
|
@@ -28,11 +29,12 @@ exports.OPTIONAL_AUTH_KEY = 'optional_auth';
|
|
|
28
29
|
* Note: For automatic token refresh, enable RefreshTokenInterceptor globally.
|
|
29
30
|
*/
|
|
30
31
|
let NestAuthAuthGuard = class NestAuthAuthGuard {
|
|
31
|
-
constructor(reflector, jwtService, sessionManager, accessKeyService) {
|
|
32
|
+
constructor(reflector, jwtService, sessionManager, accessKeyService, authConfigService) {
|
|
32
33
|
this.reflector = reflector;
|
|
33
34
|
this.jwtService = jwtService;
|
|
34
35
|
this.sessionManager = sessionManager;
|
|
35
36
|
this.accessKeyService = accessKeyService;
|
|
37
|
+
this.authConfigService = authConfigService;
|
|
36
38
|
}
|
|
37
39
|
async canActivate(context) {
|
|
38
40
|
const request = context.switchToHttp().getRequest();
|
|
@@ -58,7 +60,7 @@ let NestAuthAuthGuard = class NestAuthAuthGuard {
|
|
|
58
60
|
// Required auth: throw error
|
|
59
61
|
throw new common_1.UnauthorizedException({
|
|
60
62
|
message: 'No authentication provided',
|
|
61
|
-
code:
|
|
63
|
+
code: auth_constants_1.ERROR_CODES.NO_AUTH_PROVIDED
|
|
62
64
|
});
|
|
63
65
|
}
|
|
64
66
|
}
|
|
@@ -70,7 +72,7 @@ let NestAuthAuthGuard = class NestAuthAuthGuard {
|
|
|
70
72
|
else {
|
|
71
73
|
throw new common_1.UnauthorizedException({
|
|
72
74
|
message: 'Invalid authentication format',
|
|
73
|
-
code:
|
|
75
|
+
code: auth_constants_1.ERROR_CODES.INVALID_AUTH_FORMAT
|
|
74
76
|
});
|
|
75
77
|
}
|
|
76
78
|
}
|
|
@@ -92,7 +94,7 @@ let NestAuthAuthGuard = class NestAuthAuthGuard {
|
|
|
92
94
|
else {
|
|
93
95
|
throw new common_1.UnauthorizedException({
|
|
94
96
|
message: 'Invalid authentication type',
|
|
95
|
-
code:
|
|
97
|
+
code: auth_constants_1.ERROR_CODES.INVALID_AUTH_TYPE
|
|
96
98
|
});
|
|
97
99
|
}
|
|
98
100
|
}
|
|
@@ -122,6 +124,17 @@ let NestAuthAuthGuard = class NestAuthAuthGuard {
|
|
|
122
124
|
try {
|
|
123
125
|
// Verify the JWT token
|
|
124
126
|
const payload = await this.jwtService.verifyToken(token);
|
|
127
|
+
const config = this.authConfigService.getConfig();
|
|
128
|
+
// Apply guards.beforeAuth hook if configured
|
|
129
|
+
if (config.guards?.beforeAuth) {
|
|
130
|
+
const result = await config.guards.beforeAuth(request, payload);
|
|
131
|
+
if (result && result.reject) {
|
|
132
|
+
throw new common_1.UnauthorizedException({
|
|
133
|
+
message: result.reason || 'Authentication rejected by custom guard',
|
|
134
|
+
code: auth_constants_1.ERROR_CODES.ACCESS_DENIED
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
}
|
|
125
138
|
request.user = payload;
|
|
126
139
|
request.authType = 'jwt';
|
|
127
140
|
// Verify session exists
|
|
@@ -136,13 +149,33 @@ let NestAuthAuthGuard = class NestAuthAuthGuard {
|
|
|
136
149
|
else {
|
|
137
150
|
throw new common_1.UnauthorizedException({
|
|
138
151
|
message: 'Session not found',
|
|
139
|
-
code: auth_constants_1.
|
|
152
|
+
code: auth_constants_1.ERROR_CODES.SESSION_NOT_FOUND
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
// Apply jwt.validateToken hook if configured
|
|
157
|
+
if (config.jwt?.validateToken) {
|
|
158
|
+
const isValid = await config.jwt.validateToken(payload, session);
|
|
159
|
+
if (!isValid) {
|
|
160
|
+
throw new common_1.UnauthorizedException({
|
|
161
|
+
message: 'Token validation failed',
|
|
162
|
+
code: auth_constants_1.ERROR_CODES.INVALID_TOKEN
|
|
140
163
|
});
|
|
141
164
|
}
|
|
142
165
|
}
|
|
143
166
|
request.session = session;
|
|
144
167
|
// Check MFA requirements
|
|
145
168
|
await this.checkMfa(context, payload, isOptional);
|
|
169
|
+
// Apply guards.afterAuth hook if configured
|
|
170
|
+
if (config.guards?.afterAuth) {
|
|
171
|
+
// We need the full user object for the hook if possible, but the signature asks for NestAuthUser
|
|
172
|
+
// The payload is just the JWT payload. The session has the user data.
|
|
173
|
+
// Let's try to use session.data.user if available, otherwise we might need to fetch it or cast payload
|
|
174
|
+
// The interface says user: NestAuthUser. session.data.user is usually the user object.
|
|
175
|
+
if (session.data?.user) {
|
|
176
|
+
await config.guards.afterAuth(request, session.data.user, session);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
146
179
|
return true;
|
|
147
180
|
}
|
|
148
181
|
catch (error) {
|
|
@@ -155,7 +188,7 @@ let NestAuthAuthGuard = class NestAuthAuthGuard {
|
|
|
155
188
|
else {
|
|
156
189
|
throw new common_1.UnauthorizedException({
|
|
157
190
|
message: 'Invalid or expired token',
|
|
158
|
-
code: auth_constants_1.
|
|
191
|
+
code: auth_constants_1.ERROR_CODES.INVALID_TOKEN
|
|
159
192
|
});
|
|
160
193
|
}
|
|
161
194
|
}
|
|
@@ -171,7 +204,7 @@ let NestAuthAuthGuard = class NestAuthAuthGuard {
|
|
|
171
204
|
else {
|
|
172
205
|
throw new common_1.UnauthorizedException({
|
|
173
206
|
message: 'Invalid API key format',
|
|
174
|
-
code:
|
|
207
|
+
code: auth_constants_1.ERROR_CODES.INVALID_API_KEY_FORMAT
|
|
175
208
|
});
|
|
176
209
|
}
|
|
177
210
|
}
|
|
@@ -186,7 +219,7 @@ let NestAuthAuthGuard = class NestAuthAuthGuard {
|
|
|
186
219
|
else {
|
|
187
220
|
throw new common_1.UnauthorizedException({
|
|
188
221
|
message: 'Invalid API key',
|
|
189
|
-
code:
|
|
222
|
+
code: auth_constants_1.ERROR_CODES.INVALID_API_KEY
|
|
190
223
|
});
|
|
191
224
|
}
|
|
192
225
|
}
|
|
@@ -229,7 +262,7 @@ let NestAuthAuthGuard = class NestAuthAuthGuard {
|
|
|
229
262
|
else {
|
|
230
263
|
throw new common_1.UnauthorizedException({
|
|
231
264
|
message: 'Multi-factor authentication is required',
|
|
232
|
-
code: auth_constants_1.
|
|
265
|
+
code: auth_constants_1.ERROR_CODES.MFA_REQUIRED
|
|
233
266
|
});
|
|
234
267
|
}
|
|
235
268
|
}
|
|
@@ -248,15 +281,18 @@ let NestAuthAuthGuard = class NestAuthAuthGuard {
|
|
|
248
281
|
const user = request.user;
|
|
249
282
|
// Check if user exists
|
|
250
283
|
if (!user) {
|
|
251
|
-
throw new common_1.ForbiddenException(
|
|
284
|
+
throw new common_1.ForbiddenException({
|
|
285
|
+
message: 'Access denied: User not authenticated',
|
|
286
|
+
code: auth_constants_1.ERROR_CODES.UNAUTHORIZED,
|
|
287
|
+
});
|
|
252
288
|
}
|
|
253
289
|
// Check roles if required
|
|
254
290
|
if (requiredRoles.length > 0) {
|
|
255
|
-
this.checkRoles(user, requiredRoles);
|
|
291
|
+
await this.checkRoles(user, requiredRoles);
|
|
256
292
|
}
|
|
257
293
|
// Check permissions if required
|
|
258
294
|
if (requiredPermissions.length > 0) {
|
|
259
|
-
this.checkPermissions(user, requiredPermissions);
|
|
295
|
+
await this.checkPermissions(user, requiredPermissions);
|
|
260
296
|
}
|
|
261
297
|
}
|
|
262
298
|
/**
|
|
@@ -284,35 +320,86 @@ let NestAuthAuthGuard = class NestAuthAuthGuard {
|
|
|
284
320
|
/**
|
|
285
321
|
* Check if user has required roles
|
|
286
322
|
*/
|
|
287
|
-
|
|
323
|
+
/**
|
|
324
|
+
* Check if user has required roles
|
|
325
|
+
*/
|
|
326
|
+
/**
|
|
327
|
+
* Helper to resolve user roles
|
|
328
|
+
*/
|
|
329
|
+
async resolveUserRoles(user) {
|
|
330
|
+
const config = this.authConfigService.getConfig();
|
|
331
|
+
// Apply authorization.resolveRoles hook if configured
|
|
332
|
+
if (config.authorization?.resolveRoles) {
|
|
333
|
+
return await config.authorization.resolveRoles(user);
|
|
334
|
+
}
|
|
335
|
+
// Default behavior
|
|
288
336
|
if (!user.roles || !Array.isArray(user.roles)) {
|
|
289
|
-
|
|
337
|
+
// Return empty array instead of throwing, let the caller decide
|
|
338
|
+
return [];
|
|
290
339
|
}
|
|
291
340
|
// Get active role names
|
|
292
|
-
|
|
293
|
-
.filter(role => role.isActive)
|
|
294
|
-
.map(role => role.name);
|
|
341
|
+
return user.roles
|
|
342
|
+
.filter((role) => role.isActive)
|
|
343
|
+
.map((role) => role.name);
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Check if user has required roles
|
|
347
|
+
*/
|
|
348
|
+
async checkRoles(user, requiredRoles) {
|
|
349
|
+
const userRoleNames = await this.resolveUserRoles(user);
|
|
350
|
+
if (userRoleNames.length === 0 && (!user.roles || !Array.isArray(user.roles))) {
|
|
351
|
+
throw new common_1.ForbiddenException({
|
|
352
|
+
message: 'Access denied: No roles assigned',
|
|
353
|
+
code: auth_constants_1.ERROR_CODES.NO_ROLES_ASSIGNED,
|
|
354
|
+
});
|
|
355
|
+
}
|
|
295
356
|
// Check if user has all required roles
|
|
296
357
|
const hasAllRoles = requiredRoles.every(role => userRoleNames.includes(role));
|
|
297
358
|
if (!hasAllRoles) {
|
|
298
359
|
const missingRoles = requiredRoles.filter(role => !userRoleNames.includes(role));
|
|
299
|
-
throw new common_1.ForbiddenException(
|
|
360
|
+
throw new common_1.ForbiddenException({
|
|
361
|
+
message: `Access denied: Missing required roles: ${missingRoles.join(', ')}`,
|
|
362
|
+
code: auth_constants_1.ERROR_CODES.MISSING_REQUIRED_ROLES,
|
|
363
|
+
});
|
|
300
364
|
}
|
|
301
365
|
}
|
|
302
366
|
/**
|
|
303
367
|
* Check if user has required permissions
|
|
304
368
|
*/
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
369
|
+
/**
|
|
370
|
+
* Check if user has required permissions
|
|
371
|
+
*/
|
|
372
|
+
/**
|
|
373
|
+
* Check if user has required permissions
|
|
374
|
+
*/
|
|
375
|
+
async checkPermissions(user, requiredPermissions) {
|
|
376
|
+
const config = this.authConfigService.getConfig();
|
|
377
|
+
let userPermissions = [];
|
|
378
|
+
// Apply authorization.resolvePermissions hook if configured
|
|
379
|
+
if (config.authorization?.resolvePermissions) {
|
|
380
|
+
// Resolve roles first as they are needed for the hook
|
|
381
|
+
const roles = await this.resolveUserRoles(user);
|
|
382
|
+
userPermissions = await config.authorization.resolvePermissions(user, roles);
|
|
383
|
+
}
|
|
384
|
+
else {
|
|
385
|
+
// Default behavior
|
|
386
|
+
if (!user.roles || !Array.isArray(user.roles)) {
|
|
387
|
+
throw new common_1.ForbiddenException({
|
|
388
|
+
message: 'Access denied: No roles assigned for permission check',
|
|
389
|
+
code: auth_constants_1.ERROR_CODES.NO_ROLES_ASSIGNED,
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
// Get all permissions from user's roles
|
|
393
|
+
userPermissions = this.getUserPermissions(user.roles);
|
|
308
394
|
}
|
|
309
|
-
// Get all permissions from user's roles
|
|
310
|
-
const userPermissions = this.getUserPermissions(user.roles);
|
|
311
395
|
// Check if user has all required permissions
|
|
312
396
|
const hasAllPermissions = requiredPermissions.every(permission => userPermissions.includes(permission));
|
|
313
397
|
if (!hasAllPermissions) {
|
|
314
398
|
const missingPermissions = requiredPermissions.filter(permission => !userPermissions.includes(permission));
|
|
315
|
-
throw new common_1.ForbiddenException(
|
|
399
|
+
throw new common_1.ForbiddenException({
|
|
400
|
+
message: `Access denied: Missing required permissions: ${missingPermissions.join(', ')}`,
|
|
401
|
+
code: auth_constants_1.ERROR_CODES.MISSING_REQUIRED_PERMISSIONS,
|
|
402
|
+
});
|
|
316
403
|
}
|
|
317
404
|
}
|
|
318
405
|
/**
|
|
@@ -339,5 +426,6 @@ exports.NestAuthAuthGuard = NestAuthAuthGuard = tslib_1.__decorate([
|
|
|
339
426
|
tslib_1.__metadata("design:paramtypes", [core_1.Reflector,
|
|
340
427
|
jwt_service_1.JwtService,
|
|
341
428
|
session_manager_service_1.SessionManagerService,
|
|
342
|
-
access_key_service_1.AccessKeyService
|
|
429
|
+
access_key_service_1.AccessKeyService,
|
|
430
|
+
auth_config_service_1.AuthConfigService])
|
|
343
431
|
], NestAuthAuthGuard);
|
|
@@ -22,6 +22,8 @@ import { VerifyOtpResponseDto } from '../dto/responses/verify-otp.response.dto';
|
|
|
22
22
|
import { SendEmailVerificationRequestDto } from '../dto/requests/send-email-verification.request.dto';
|
|
23
23
|
import { VerifyEmailRequestDto } from '../dto/requests/verify-email.request.dto';
|
|
24
24
|
import { AuthConfigService } from '../../core/services/auth-config.service';
|
|
25
|
+
import { AuthTokensResponseDto } from '../dto/responses/auth.response.dto';
|
|
26
|
+
import { UserService } from '../../user/services/user.service';
|
|
25
27
|
export declare class AuthService {
|
|
26
28
|
private readonly userRepository;
|
|
27
29
|
private otpRepository;
|
|
@@ -33,9 +35,10 @@ export declare class AuthService {
|
|
|
33
35
|
private readonly tenantService;
|
|
34
36
|
private readonly debugLogger;
|
|
35
37
|
private readonly authConfigService;
|
|
36
|
-
|
|
38
|
+
private readonly userService;
|
|
39
|
+
constructor(userRepository: Repository<NestAuthUser>, otpRepository: Repository<NestAuthOTP>, authProviderRegistry: AuthProviderRegistryService, mfaService: MfaService, sessionManager: SessionManagerService, jwtService: JwtService, eventEmitter: EventEmitter2, tenantService: TenantService, debugLogger: DebugLoggerService, authConfigService: AuthConfigService, userService: UserService);
|
|
37
40
|
getUserWithRolesAndPermissions(userId: string, relations?: string[]): Promise<NestAuthUser>;
|
|
38
|
-
getUser(): Promise<NestAuthUser
|
|
41
|
+
getUser(): Promise<Partial<NestAuthUser>>;
|
|
39
42
|
signup(input: SignupRequestDto): Promise<AuthResponseDto>;
|
|
40
43
|
login(input: LoginRequestDto): Promise<AuthResponseDto>;
|
|
41
44
|
verify2fa(input: Verify2faRequestDto): Promise<{
|
|
@@ -45,10 +48,7 @@ export declare class AuthService {
|
|
|
45
48
|
}>;
|
|
46
49
|
send2faCode(userId: string, method: MFAMethodEnum): Promise<boolean>;
|
|
47
50
|
private handleSocialLogin;
|
|
48
|
-
refreshToken(refreshToken: string): Promise<
|
|
49
|
-
accessToken: string;
|
|
50
|
-
refreshToken: string;
|
|
51
|
-
}>;
|
|
51
|
+
refreshToken(refreshToken: string): Promise<AuthTokensResponseDto>;
|
|
52
52
|
changePassword(input: ChangePasswordRequestDto): Promise<AuthResponseDto>;
|
|
53
53
|
forgotPassword(input: ForgotPasswordRequestDto): Promise<true | {
|
|
54
54
|
message: string;
|
|
@@ -65,6 +65,10 @@ export declare class AuthService {
|
|
|
65
65
|
message: string;
|
|
66
66
|
}>;
|
|
67
67
|
private generateTokensPayload;
|
|
68
|
+
/**
|
|
69
|
+
* Handle errors using the errorHandler hook if configured
|
|
70
|
+
*/
|
|
71
|
+
private handleError;
|
|
68
72
|
private generateTokensFromSession;
|
|
69
73
|
}
|
|
70
74
|
//# sourceMappingURL=auth.service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/nest-auth/src/lib/auth/services/auth.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"auth.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/nest-auth/src/lib/auth/services/auth.service.ts"],"names":[],"mappings":"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"}
|