@ackplus/nest-auth 1.1.14 → 1.1.16

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.
Files changed (28) hide show
  1. package/README.md +82 -6
  2. package/package.json +1 -1
  3. package/src/lib/admin-console/static/index.html +4736 -432
  4. package/src/lib/auth/auth.module.d.ts.map +1 -1
  5. package/src/lib/auth/auth.module.js +2 -0
  6. package/src/lib/auth/controllers/auth.controller.d.ts +1 -0
  7. package/src/lib/auth/controllers/auth.controller.d.ts.map +1 -1
  8. package/src/lib/auth/controllers/auth.controller.js +19 -2
  9. package/src/lib/auth/dto/requests/verify-2fa.request.dto.d.ts +1 -0
  10. package/src/lib/auth/dto/requests/verify-2fa.request.dto.d.ts.map +1 -1
  11. package/src/lib/auth/dto/requests/verify-2fa.request.dto.js +8 -0
  12. package/src/lib/auth/entities/trusted-device.entity.d.ts +13 -0
  13. package/src/lib/auth/entities/trusted-device.entity.d.ts.map +1 -0
  14. package/src/lib/auth/entities/trusted-device.entity.js +51 -0
  15. package/src/lib/auth/index.d.ts +1 -0
  16. package/src/lib/auth/index.d.ts.map +1 -1
  17. package/src/lib/auth/index.js +1 -0
  18. package/src/lib/auth/services/auth.service.d.ts +1 -0
  19. package/src/lib/auth/services/auth.service.d.ts.map +1 -1
  20. package/src/lib/auth/services/auth.service.js +29 -1
  21. package/src/lib/auth/services/mfa.service.d.ts +5 -1
  22. package/src/lib/auth/services/mfa.service.d.ts.map +1 -1
  23. package/src/lib/auth/services/mfa.service.js +51 -3
  24. package/src/lib/auth.constants.d.ts +1 -0
  25. package/src/lib/auth.constants.d.ts.map +1 -1
  26. package/src/lib/auth.constants.js +2 -1
  27. package/src/lib/core/interfaces/mfa-options.interface.d.ts +2 -0
  28. package/src/lib/core/interfaces/mfa-options.interface.d.ts.map +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"auth.module.d.ts","sourceRoot":"","sources":["../../../../../../packages/nest-auth/src/lib/auth/auth.module.ts"],"names":[],"mappings":"AAsBA,qBAkCa,UAAU;CACtB"}
1
+ {"version":3,"file":"auth.module.d.ts","sourceRoot":"","sources":["../../../../../../packages/nest-auth/src/lib/auth/auth.module.ts"],"names":[],"mappings":"AAuBA,qBAmCa,UAAU;CACtB"}
@@ -17,6 +17,7 @@ const user_entity_1 = require("../user/entities/user.entity");
17
17
  const otp_entity_1 = require("./entities/otp.entity");
18
18
  const mfa_secret_entity_1 = require("./entities/mfa-secret.entity");
19
19
  const access_key_entity_1 = require("../user/entities/access-key.entity");
20
+ const trusted_device_entity_1 = require("./entities/trusted-device.entity");
20
21
  const event_emitter_1 = require("@nestjs/event-emitter");
21
22
  const user_module_1 = require("../user/user.module");
22
23
  const core_module_1 = require("../core/core.module");
@@ -36,6 +37,7 @@ exports.AuthModule = AuthModule = tslib_1.__decorate([
36
37
  mfa_secret_entity_1.NestAuthMFASecret,
37
38
  access_key_entity_1.NestAuthAccessKey,
38
39
  identity_entity_1.NestAuthIdentity,
40
+ trusted_device_entity_1.NestAuthTrustedDevice,
39
41
  ]),
40
42
  (0, common_1.forwardRef)(() => core_module_1.CoreModule),
41
43
  (0, common_1.forwardRef)(() => user_module_1.UserModule),
@@ -43,6 +43,7 @@ export declare class AuthController {
43
43
  protected handle2faResponse(res: Response, authResult: {
44
44
  accessToken: string;
45
45
  refreshToken: string;
46
+ trustToken?: string;
46
47
  }): void;
47
48
  signup(input: SignupRequestDto, res: Response): Promise<void>;
48
49
  login(input: LoginRequestDto, res: Response): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"auth.controller.d.ts","sourceRoot":"","sources":["../../../../../../../packages/nest-auth/src/lib/auth/controllers/auth.controller.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.controller.d.ts","sourceRoot":"","sources":["../../../../../../../packages/nest-auth/src/lib/auth/controllers/auth.controller.ts"],"names":[],"mappings":"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"}
@@ -27,6 +27,7 @@ const send_email_verification_request_dto_1 = require("../dto/requests/send-emai
27
27
  const verify_email_request_dto_1 = require("../dto/requests/verify-email.request.dto");
28
28
  const client_config_service_1 = require("../services/client-config.service");
29
29
  const client_config_response_dto_1 = require("../dto/responses/client-config.response.dto");
30
+ const auth_constants_1 = require("../../auth.constants");
30
31
  let AuthController = class AuthController {
31
32
  constructor(authService, cookieService, authConfig, clientConfigService) {
32
33
  this.authService = authService;
@@ -69,12 +70,27 @@ let AuthController = class AuthController {
69
70
  * Handle 2FA verification response based on configuration
70
71
  */
71
72
  handle2faResponse(res, authResult) {
73
+ if (authResult.trustToken) {
74
+ const trustCookieName = auth_config_service_1.AuthConfigService.getOptions().mfa?.trustDeviceStorageName || auth_constants_1.NEST_AUTH_TRUST_DEVICE_KEY;
75
+ const duration = auth_config_service_1.AuthConfigService.getOptions().mfa?.trustedDeviceDuration || '30d';
76
+ // Convert duration to milliseconds for maxAge
77
+ const ms = require('ms');
78
+ const maxAge = typeof duration === 'string' ? ms(duration) : duration;
79
+ res.cookie(trustCookieName, authResult.trustToken, {
80
+ httpOnly: true,
81
+ secure: process.env.NODE_ENV === 'production',
82
+ sameSite: 'lax',
83
+ path: '/',
84
+ maxAge,
85
+ });
86
+ }
72
87
  if (this.isUsingCookies()) {
73
88
  // Cookie mode: Set tokens in cookies, return success message
74
89
  this.cookieService.setTokens(res, authResult.accessToken, authResult.refreshToken);
75
90
  res.status(200).json({
76
- message: '2FA verification successful'
91
+ message: '2FA verification successful',
77
92
  // Note: No isRequiresMfa for 2FA verification (it's already verified)
93
+ trustToken: authResult.trustToken // Return trust token for mobile apps even in cookie mode
78
94
  });
79
95
  }
80
96
  else {
@@ -82,7 +98,8 @@ let AuthController = class AuthController {
82
98
  res.status(200).json({
83
99
  message: '2FA verification successful',
84
100
  accessToken: authResult.accessToken,
85
- refreshToken: authResult.refreshToken
101
+ refreshToken: authResult.refreshToken,
102
+ trustToken: authResult.trustToken
86
103
  });
87
104
  }
88
105
  }
@@ -2,5 +2,6 @@ import { MFAMethodEnum } from "../../../core";
2
2
  export declare class Verify2faRequestDto {
3
3
  method: MFAMethodEnum;
4
4
  otp: string;
5
+ rememberDevice?: boolean;
5
6
  }
6
7
  //# sourceMappingURL=verify-2fa.request.dto.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"verify-2fa.request.dto.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/nest-auth/src/lib/auth/dto/requests/verify-2fa.request.dto.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAG9C,qBAAa,mBAAmB;IAQ5B,MAAM,EAAE,aAAa,CAAC;IAUtB,GAAG,EAAE,MAAM,CAAC;CACf"}
1
+ {"version":3,"file":"verify-2fa.request.dto.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/nest-auth/src/lib/auth/dto/requests/verify-2fa.request.dto.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAG9C,qBAAa,mBAAmB;IAQ5B,MAAM,EAAE,aAAa,CAAC;IAUtB,GAAG,EAAE,MAAM,CAAC;IAOZ,cAAc,CAAC,EAAE,OAAO,CAAC;CAC5B"}
@@ -29,3 +29,11 @@ tslib_1.__decorate([
29
29
  (0, class_validator_1.IsNotEmpty)(),
30
30
  tslib_1.__metadata("design:type", String)
31
31
  ], Verify2faRequestDto.prototype, "otp", void 0);
32
+ tslib_1.__decorate([
33
+ (0, swagger_1.ApiProperty)({
34
+ description: 'Whether to trust this device for future logins',
35
+ example: true,
36
+ required: false,
37
+ }),
38
+ tslib_1.__metadata("design:type", Boolean)
39
+ ], Verify2faRequestDto.prototype, "rememberDevice", void 0);
@@ -0,0 +1,13 @@
1
+ import { NestAuthUser } from '../../user/entities/user.entity';
2
+ export declare class NestAuthTrustedDevice {
3
+ id: string;
4
+ userId: string;
5
+ user: NestAuthUser;
6
+ token: string;
7
+ userAgent: string;
8
+ ipAddress: string;
9
+ expiresAt: Date;
10
+ lastUsedAt: Date;
11
+ createdAt: Date;
12
+ }
13
+ //# sourceMappingURL=trusted-device.entity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trusted-device.entity.d.ts","sourceRoot":"","sources":["../../../../../../../packages/nest-auth/src/lib/auth/entities/trusted-device.entity.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAE/D,qBACa,qBAAqB;IAE9B,EAAE,EAAE,MAAM,CAAC;IAIX,MAAM,EAAE,MAAM,CAAC;IAIf,IAAI,EAAE,YAAY,CAAC;IAInB,KAAK,EAAE,MAAM,CAAC;IAGd,SAAS,EAAE,MAAM,CAAC;IAGlB,SAAS,EAAE,MAAM,CAAC;IAGlB,SAAS,EAAE,IAAI,CAAC;IAGhB,UAAU,EAAE,IAAI,CAAC;IAGjB,SAAS,EAAE,IAAI,CAAC;CACnB"}
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NestAuthTrustedDevice = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const typeorm_1 = require("typeorm");
6
+ const user_entity_1 = require("../../user/entities/user.entity");
7
+ let NestAuthTrustedDevice = class NestAuthTrustedDevice {
8
+ };
9
+ exports.NestAuthTrustedDevice = NestAuthTrustedDevice;
10
+ tslib_1.__decorate([
11
+ (0, typeorm_1.PrimaryGeneratedColumn)('uuid'),
12
+ tslib_1.__metadata("design:type", String)
13
+ ], NestAuthTrustedDevice.prototype, "id", void 0);
14
+ tslib_1.__decorate([
15
+ (0, typeorm_1.Column)(),
16
+ (0, typeorm_1.Index)(),
17
+ tslib_1.__metadata("design:type", String)
18
+ ], NestAuthTrustedDevice.prototype, "userId", void 0);
19
+ tslib_1.__decorate([
20
+ (0, typeorm_1.ManyToOne)(() => user_entity_1.NestAuthUser, { onDelete: 'CASCADE' }),
21
+ (0, typeorm_1.JoinColumn)({ name: 'userId' }),
22
+ tslib_1.__metadata("design:type", user_entity_1.NestAuthUser)
23
+ ], NestAuthTrustedDevice.prototype, "user", void 0);
24
+ tslib_1.__decorate([
25
+ (0, typeorm_1.Column)(),
26
+ (0, typeorm_1.Index)(),
27
+ tslib_1.__metadata("design:type", String)
28
+ ], NestAuthTrustedDevice.prototype, "token", void 0);
29
+ tslib_1.__decorate([
30
+ (0, typeorm_1.Column)({ nullable: true }),
31
+ tslib_1.__metadata("design:type", String)
32
+ ], NestAuthTrustedDevice.prototype, "userAgent", void 0);
33
+ tslib_1.__decorate([
34
+ (0, typeorm_1.Column)({ nullable: true }),
35
+ tslib_1.__metadata("design:type", String)
36
+ ], NestAuthTrustedDevice.prototype, "ipAddress", void 0);
37
+ tslib_1.__decorate([
38
+ (0, typeorm_1.Column)(),
39
+ tslib_1.__metadata("design:type", Date)
40
+ ], NestAuthTrustedDevice.prototype, "expiresAt", void 0);
41
+ tslib_1.__decorate([
42
+ (0, typeorm_1.Column)({ nullable: true }),
43
+ tslib_1.__metadata("design:type", Date)
44
+ ], NestAuthTrustedDevice.prototype, "lastUsedAt", void 0);
45
+ tslib_1.__decorate([
46
+ (0, typeorm_1.CreateDateColumn)(),
47
+ tslib_1.__metadata("design:type", Date)
48
+ ], NestAuthTrustedDevice.prototype, "createdAt", void 0);
49
+ exports.NestAuthTrustedDevice = NestAuthTrustedDevice = tslib_1.__decorate([
50
+ (0, typeorm_1.Entity)('nest_auth_trusted_devices')
51
+ ], NestAuthTrustedDevice);
@@ -38,4 +38,5 @@ export * from './dto/responses/mfa-status.response.dto';
38
38
  export * from './dto/responses/client-config.response.dto';
39
39
  export * from './entities/otp.entity';
40
40
  export * from './entities/mfa-secret.entity';
41
+ export * from './entities/trusted-device.entity';
41
42
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../packages/nest-auth/src/lib/auth/index.ts"],"names":[],"mappings":"AACA,cAAc,qBAAqB,CAAC;AACpC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAGxD,cAAc,0CAA0C,CAAC;AAGzD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yCAAyC,CAAC;AACxD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,kCAAkC,CAAC;AACjD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,mCAAmC,CAAC;AAClD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,qCAAqC,CAAC;AAGpD,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,wBAAwB,CAAC;AACvC,cAAc,kCAAkC,CAAC;AAGjD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,8BAA8B,CAAC;AAG7C,cAAc,kCAAkC,CAAC;AACjD,cAAc,mCAAmC,CAAC;AAClD,cAAc,0CAA0C,CAAC;AACzD,cAAc,yCAAyC,CAAC;AACxD,cAAc,yCAAyC,CAAC;AACxD,cAAc,4CAA4C,CAAC;AAC3D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,sDAAsD,CAAC;AACrE,cAAc,uDAAuD,CAAC;AACtE,cAAc,0CAA0C,CAAC;AACzD,cAAc,4CAA4C,CAAC;AAC3D,cAAc,uCAAuC,CAAC;AACtD,cAAc,0CAA0C,CAAC;AACzD,cAAc,uCAAuC,CAAC;AACtD,cAAc,8CAA8C,CAAC;AAC7D,cAAc,mCAAmC,CAAC;AAClD,cAAc,0CAA0C,CAAC;AACzD,cAAc,yCAAyC,CAAC;AACxD,cAAc,yCAAyC,CAAC;AACxD,cAAc,4CAA4C,CAAC;AAG3D,cAAc,uBAAuB,CAAC;AACtC,cAAc,8BAA8B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../packages/nest-auth/src/lib/auth/index.ts"],"names":[],"mappings":"AACA,cAAc,qBAAqB,CAAC;AACpC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAGxD,cAAc,0CAA0C,CAAC;AAGzD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yCAAyC,CAAC;AACxD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,kCAAkC,CAAC;AACjD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,mCAAmC,CAAC;AAClD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,qCAAqC,CAAC;AAGpD,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,wBAAwB,CAAC;AACvC,cAAc,kCAAkC,CAAC;AAGjD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,8BAA8B,CAAC;AAG7C,cAAc,kCAAkC,CAAC;AACjD,cAAc,mCAAmC,CAAC;AAClD,cAAc,0CAA0C,CAAC;AACzD,cAAc,yCAAyC,CAAC;AACxD,cAAc,yCAAyC,CAAC;AACxD,cAAc,4CAA4C,CAAC;AAC3D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,sDAAsD,CAAC;AACrE,cAAc,uDAAuD,CAAC;AACtE,cAAc,0CAA0C,CAAC;AACzD,cAAc,4CAA4C,CAAC;AAC3D,cAAc,uCAAuC,CAAC;AACtD,cAAc,0CAA0C,CAAC;AACzD,cAAc,uCAAuC,CAAC;AACtD,cAAc,8CAA8C,CAAC;AAC7D,cAAc,mCAAmC,CAAC;AAClD,cAAc,0CAA0C,CAAC;AACzD,cAAc,yCAAyC,CAAC;AACxD,cAAc,yCAAyC,CAAC;AACxD,cAAc,4CAA4C,CAAC;AAG3D,cAAc,uBAAuB,CAAC;AACtC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,kCAAkC,CAAC"}
@@ -50,3 +50,4 @@ tslib_1.__exportStar(require("./dto/responses/client-config.response.dto"), expo
50
50
  // Entities
51
51
  tslib_1.__exportStar(require("./entities/otp.entity"), exports);
52
52
  tslib_1.__exportStar(require("./entities/mfa-secret.entity"), exports);
53
+ tslib_1.__exportStar(require("./entities/trusted-device.entity"), exports);
@@ -41,6 +41,7 @@ export declare class AuthService {
41
41
  verify2fa(input: Verify2faRequestDto): Promise<{
42
42
  accessToken: string;
43
43
  refreshToken: string;
44
+ trustToken: string;
44
45
  }>;
45
46
  send2faCode(userId: string, method: MFAMethodEnum): Promise<boolean>;
46
47
  private handleSocialLogin;
@@ -1 +1 @@
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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"}
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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"}
@@ -174,7 +174,27 @@ let AuthService = class AuthService {
174
174
  user = await this.getUserWithRolesAndPermissions(user.id);
175
175
  const session = await this.sessionManager.createSessionFromUser(user);
176
176
  const tokens = await this.generateTokensFromSession(session);
177
- const isRequiresMfa = await this.mfaService.isRequiresMfa(user.id);
177
+ let isRequiresMfa = await this.mfaService.isRequiresMfa(user.id);
178
+ // Check for trusted device cookie or header if MFA is required
179
+ if (isRequiresMfa) {
180
+ const trustCookieName = auth_config_service_1.AuthConfigService.getOptions().mfa?.trustDeviceStorageName || auth_constants_1.NEST_AUTH_TRUST_DEVICE_KEY;
181
+ const req = request_context_1.RequestContext.currentRequest();
182
+ let trustToken = req.cookies?.[trustCookieName];
183
+ // If not in cookie, check header
184
+ if (!trustToken) {
185
+ trustToken = req.headers[trustCookieName];
186
+ }
187
+ if (trustToken) {
188
+ const isTrusted = await this.mfaService.validateTrustedDevice(user.id, trustToken);
189
+ if (isTrusted) {
190
+ isRequiresMfa = false;
191
+ // Update session to indicate MFA is verified by trust
192
+ await this.sessionManager.updateSession(session.id, {
193
+ data: { ...session.data, isMfaVerified: true }
194
+ });
195
+ }
196
+ }
197
+ }
178
198
  // Emit login event
179
199
  await this.eventEmitter.emitAsync(auth_constants_1.NestAuthEvents.LOGGED_IN, new user_logged_in_event_1.UserLoggedInEvent({
180
200
  user,
@@ -219,6 +239,13 @@ let AuthService = class AuthService {
219
239
  }
220
240
  });
221
241
  const tokens = await this.generateTokensFromSession(payload);
242
+ let trustToken;
243
+ if (input.rememberDevice) {
244
+ const req = request_context_1.RequestContext.currentRequest();
245
+ const userAgent = req.headers['user-agent'] || '';
246
+ const ip = req.ip || req.socket.remoteAddress || '';
247
+ trustToken = await this.mfaService.createTrustedDevice(session.userId, userAgent, ip);
248
+ }
222
249
  const user = await this.getUser();
223
250
  // Emit 2FA verified event
224
251
  this.debugLogger.debug('Emitting 2FA verified event', 'AuthService', { userId: user.id });
@@ -233,6 +260,7 @@ let AuthService = class AuthService {
233
260
  return {
234
261
  accessToken: tokens.accessToken,
235
262
  refreshToken: tokens.refreshToken,
263
+ trustToken,
236
264
  };
237
265
  }
238
266
  catch (error) {
@@ -4,13 +4,15 @@ import { MFAMethodEnum, MFAOptions } from '../../core/interfaces/mfa-options.int
4
4
  import { NestAuthUser } from '../../user/entities/user.entity';
5
5
  import { NestAuthOTP } from '../../auth/entities/otp.entity';
6
6
  import { EventEmitter2 } from '@nestjs/event-emitter';
7
+ import { NestAuthTrustedDevice } from '../entities/trusted-device.entity';
7
8
  export declare class MfaService {
8
9
  private mfaSecretRepository;
9
10
  private userRepository;
10
11
  private otpRepository;
12
+ private trustedDeviceRepository;
11
13
  private eventEmitter;
12
14
  mfaConfig: MFAOptions;
13
- constructor(mfaSecretRepository: Repository<NestAuthMFASecret>, userRepository: Repository<NestAuthUser>, otpRepository: Repository<NestAuthOTP>, eventEmitter: EventEmitter2);
15
+ constructor(mfaSecretRepository: Repository<NestAuthMFASecret>, userRepository: Repository<NestAuthUser>, otpRepository: Repository<NestAuthOTP>, trustedDeviceRepository: Repository<NestAuthTrustedDevice>, eventEmitter: EventEmitter2);
14
16
  requireMfaEnabledForApp(throwError?: boolean): boolean;
15
17
  private checkIsMfaEnabledForApp;
16
18
  getVerifiedMethods(userId: string): Promise<MFAMethodEnum[]>;
@@ -43,5 +45,7 @@ export declare class MfaService {
43
45
  }>;
44
46
  getAvailableMethods(): MFAMethodEnum[];
45
47
  hasRecoveryCode(userId: string): Promise<boolean>;
48
+ createTrustedDevice(userId: string, userAgent: string, ipAddress: string): Promise<string>;
49
+ validateTrustedDevice(userId: string, token: string): Promise<boolean>;
46
50
  }
47
51
  //# sourceMappingURL=mfa.service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mfa.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/nest-auth/src/lib/auth/services/mfa.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAY,UAAU,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAG1E,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,6CAA6C,CAAC;AAExF,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAK7D,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAKtD,qBACa,UAAU;IAMf,OAAO,CAAC,mBAAmB;IAG3B,OAAO,CAAC,cAAc;IAGtB,OAAO,CAAC,aAAa;IAErB,OAAO,CAAC,YAAY;IAZxB,SAAS,EAAE,UAAU,CAAA;gBAIT,mBAAmB,EAAE,UAAU,CAAC,iBAAiB,CAAC,EAGlD,cAAc,EAAE,UAAU,CAAC,YAAY,CAAC,EAGxC,aAAa,EAAE,UAAU,CAAC,WAAW,CAAC,EAEtC,YAAY,EAAE,aAAa;IAKvC,uBAAuB,CAAC,UAAU,GAAE,OAAc;IAUlD,OAAO,CAAC,uBAAuB;IAIzB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAiC5D,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAmC3D,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC;IAkCpE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC;IAmDpF,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAqBjG,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA6BnF,cAAc,CAAC,MAAM,EAAE,MAAM;;;;;;;;IAmB7B,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM7C,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAgB/C,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAW9C,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ/D,SAAS,CAAC,MAAM,EAAE,MAAM;IAexB,UAAU,CAAC,MAAM,EAAE,MAAM;IASzB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMjD,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAUrD,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IA6B1E,mBAAmB,IAAI,aAAa,EAAE;IAOhC,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAY1D"}
1
+ {"version":3,"file":"mfa.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/nest-auth/src/lib/auth/services/mfa.service.ts"],"names":[],"mappings":"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"}
@@ -19,11 +19,14 @@ const auth_config_service_1 = require("../../core/services/auth-config.service")
19
19
  const event_emitter_1 = require("@nestjs/event-emitter");
20
20
  const auth_constants_2 = require("../../auth.constants");
21
21
  const two_factor_code_sent_event_1 = require("../events/two-factor-code-sent.event");
22
+ const trusted_device_entity_1 = require("../entities/trusted-device.entity");
23
+ const crypto_1 = require("crypto");
22
24
  let MfaService = class MfaService {
23
- constructor(mfaSecretRepository, userRepository, otpRepository, eventEmitter) {
25
+ constructor(mfaSecretRepository, userRepository, otpRepository, trustedDeviceRepository, eventEmitter) {
24
26
  this.mfaSecretRepository = mfaSecretRepository;
25
27
  this.userRepository = userRepository;
26
28
  this.otpRepository = otpRepository;
29
+ this.trustedDeviceRepository = trustedDeviceRepository;
27
30
  this.eventEmitter = eventEmitter;
28
31
  this.mfaConfig = auth_config_service_1.AuthConfigService.getOptions().mfa;
29
32
  }
@@ -94,11 +97,25 @@ let MfaService = class MfaService {
94
97
  async sendMfaCode(userId, method) {
95
98
  this.requireMfaEnabledForApp(true);
96
99
  const code = (0, otp_1.generateOtp)(this.mfaConfig.otpLength);
97
- const expiresAt = (0, ms_1.default)(this.mfaConfig.otpExpiresIn);
100
+ let expiresAtMs;
101
+ if (typeof this.mfaConfig.otpExpiresIn === 'string') {
102
+ expiresAtMs = (0, ms_1.default)(this.mfaConfig.otpExpiresIn); // example: '15m', '1h', '1d'
103
+ }
104
+ else {
105
+ expiresAtMs = this.mfaConfig.otpExpiresIn || 900000; // Default to 15m if undefined
106
+ }
107
+ if (!expiresAtMs || isNaN(expiresAtMs) || expiresAtMs <= 0) {
108
+ throw new Error(`Invalid MFA configuration: otpExpiresIn '${this.mfaConfig.otpExpiresIn}' results in invalid duration`);
109
+ }
110
+ // Invalidate previous MFA OTPs for this user
111
+ await this.otpRepository.delete({
112
+ userId,
113
+ type: otp_interface_1.OTPTypeEnum.MFA
114
+ });
98
115
  const otp = await this.otpRepository.create({
99
116
  userId,
100
117
  type: otp_interface_1.OTPTypeEnum.MFA,
101
- expiresAt: new Date(Date.now() + expiresAt),
118
+ expiresAt: new Date(Date.now() + expiresAtMs),
102
119
  code,
103
120
  });
104
121
  await this.otpRepository.save(otp);
@@ -308,6 +325,35 @@ let MfaService = class MfaService {
308
325
  });
309
326
  return Boolean(user?.mfaRecoveryCode);
310
327
  }
328
+ async createTrustedDevice(userId, userAgent, ipAddress) {
329
+ this.requireMfaEnabledForApp(true);
330
+ const token = (0, crypto_1.randomBytes)(32).toString('hex');
331
+ const duration = this.mfaConfig.trustedDeviceDuration || '30d';
332
+ const expiresAtMs = typeof duration === 'string' ? (0, ms_1.default)(duration) : duration;
333
+ await this.trustedDeviceRepository.save({
334
+ userId,
335
+ token,
336
+ userAgent,
337
+ ipAddress,
338
+ expiresAt: new Date(Date.now() + expiresAtMs),
339
+ });
340
+ return token;
341
+ }
342
+ async validateTrustedDevice(userId, token) {
343
+ if (!token)
344
+ return false;
345
+ const device = await this.trustedDeviceRepository.findOne({
346
+ where: { userId, token },
347
+ });
348
+ if (!device)
349
+ return false;
350
+ if (device.expiresAt < new Date()) {
351
+ await this.trustedDeviceRepository.remove(device);
352
+ return false;
353
+ }
354
+ await this.trustedDeviceRepository.update(device.id, { lastUsedAt: new Date() });
355
+ return true;
356
+ }
311
357
  };
312
358
  exports.MfaService = MfaService;
313
359
  exports.MfaService = MfaService = tslib_1.__decorate([
@@ -315,7 +361,9 @@ exports.MfaService = MfaService = tslib_1.__decorate([
315
361
  tslib_1.__param(0, (0, typeorm_1.InjectRepository)(mfa_secret_entity_1.NestAuthMFASecret)),
316
362
  tslib_1.__param(1, (0, typeorm_1.InjectRepository)(user_entity_1.NestAuthUser)),
317
363
  tslib_1.__param(2, (0, typeorm_1.InjectRepository)(otp_entity_1.NestAuthOTP)),
364
+ tslib_1.__param(3, (0, typeorm_1.InjectRepository)(trusted_device_entity_1.NestAuthTrustedDevice)),
318
365
  tslib_1.__metadata("design:paramtypes", [typeorm_2.Repository,
366
+ typeorm_2.Repository,
319
367
  typeorm_2.Repository,
320
368
  typeorm_2.Repository,
321
369
  event_emitter_1.EventEmitter2])
@@ -17,6 +17,7 @@ export declare const REFRESH_TOKEN_INVALID = "REFRESH_TOKEN_INVALID";
17
17
  export declare const REFRESH_TOKEN_EXPIRED = "REFRESH_TOKEN_EXPIRED";
18
18
  export declare const ACCESS_TOKEN_COOKIE_NAME = "accessToken";
19
19
  export declare const REFRESH_TOKEN_COOKIE_NAME = "refreshToken";
20
+ export declare const NEST_AUTH_TRUST_DEVICE_KEY = "nest_auth_device_trust";
20
21
  export declare const DEFAULT_GUARD_NAME = "web";
21
22
  export declare const NestAuthEvents: {
22
23
  readonly EMAIL_VERIFICATION_REQUESTED: "email.verification.requested";
@@ -1 +1 @@
1
- {"version":3,"file":"auth.constants.d.ts","sourceRoot":"","sources":["../../../../../packages/nest-auth/src/lib/auth.constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,mBAAmB,kCAAkC,CAAC;AACnE,eAAO,MAAM,gCAAgC,qCAAqC,CAAC;AAInF,eAAO,MAAM,iBAAiB,QAAQ,CAAC;AACvC,eAAO,MAAM,oBAAoB,WAAW,CAAC;AAC7C,eAAO,MAAM,sBAAsB,aAAa,CAAC;AACjD,eAAO,MAAM,mBAAmB,UAAU,CAAC;AAC3C,eAAO,MAAM,oBAAoB,WAAW,CAAC;AAC7C,eAAO,MAAM,mBAAmB,UAAU,CAAC;AAC3C,eAAO,MAAM,mBAAmB,UAAU,CAAC;AAI3C,eAAO,MAAM,6BAA6B,mBAAmB,CAAC;AAC9D,eAAO,MAAM,2BAA2B,iBAAiB,CAAC;AAC1D,eAAO,MAAM,0BAA0B,gBAAgB,CAAC;AACxD,eAAO,MAAM,oCAAoC,0BAA0B,CAAC;AAC5E,eAAO,MAAM,uBAAuB,sBAAsB,CAAC;AAC3D,eAAO,MAAM,qBAAqB,oBAAoB,CAAC;AAEvD,eAAO,MAAM,qBAAqB,0BAA0B,CAAC;AAC7D,eAAO,MAAM,qBAAqB,0BAA0B,CAAC;AAI7D,eAAO,MAAM,wBAAwB,gBAAgB,CAAC;AACtD,eAAO,MAAM,yBAAyB,iBAAiB,CAAC;AAGxD,eAAO,MAAM,kBAAkB,QAAQ,CAAC;AAGxC,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;CA6BjB,CAAC"}
1
+ {"version":3,"file":"auth.constants.d.ts","sourceRoot":"","sources":["../../../../../packages/nest-auth/src/lib/auth.constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,mBAAmB,kCAAkC,CAAC;AACnE,eAAO,MAAM,gCAAgC,qCAAqC,CAAC;AAInF,eAAO,MAAM,iBAAiB,QAAQ,CAAC;AACvC,eAAO,MAAM,oBAAoB,WAAW,CAAC;AAC7C,eAAO,MAAM,sBAAsB,aAAa,CAAC;AACjD,eAAO,MAAM,mBAAmB,UAAU,CAAC;AAC3C,eAAO,MAAM,oBAAoB,WAAW,CAAC;AAC7C,eAAO,MAAM,mBAAmB,UAAU,CAAC;AAC3C,eAAO,MAAM,mBAAmB,UAAU,CAAC;AAI3C,eAAO,MAAM,6BAA6B,mBAAmB,CAAC;AAC9D,eAAO,MAAM,2BAA2B,iBAAiB,CAAC;AAC1D,eAAO,MAAM,0BAA0B,gBAAgB,CAAC;AACxD,eAAO,MAAM,oCAAoC,0BAA0B,CAAC;AAC5E,eAAO,MAAM,uBAAuB,sBAAsB,CAAC;AAC3D,eAAO,MAAM,qBAAqB,oBAAoB,CAAC;AAEvD,eAAO,MAAM,qBAAqB,0BAA0B,CAAC;AAC7D,eAAO,MAAM,qBAAqB,0BAA0B,CAAC;AAI7D,eAAO,MAAM,wBAAwB,gBAAgB,CAAC;AACtD,eAAO,MAAM,yBAAyB,iBAAiB,CAAC;AAExD,eAAO,MAAM,0BAA0B,2BAA2B,CAAC;AAGnE,eAAO,MAAM,kBAAkB,QAAQ,CAAC;AAGxC,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;CA6BjB,CAAC"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.NestAuthEvents = exports.DEFAULT_GUARD_NAME = exports.REFRESH_TOKEN_COOKIE_NAME = exports.ACCESS_TOKEN_COOKIE_NAME = exports.REFRESH_TOKEN_EXPIRED = exports.REFRESH_TOKEN_INVALID = exports.USER_NOT_ACTIVE_ERROR = exports.SESSION_NOT_FOUND_ERROR = exports.INVALID_REFRESH_TOKEN_EXCEPTION_CODE = exports.INVALID_MFA_EXCEPTION_CODE = exports.UNAUTHORIZED_EXCEPTION_CODE = exports.USER_NOT_FOUND_EXCEPTION_CODE = exports.PHONE_AUTH_PROVIDER = exports.EMAIL_AUTH_PROVIDER = exports.GITHUB_AUTH_PROVIDER = exports.APPLE_AUTH_PROVIDER = exports.FACEBOOK_AUTH_PROVIDER = exports.GOOGLE_AUTH_PROVIDER = exports.JWT_AUTH_PROVIDER = exports.NEST_AUTH_ASYNC_OPTIONS_PROVIDER = exports.AUTH_MODULE_OPTIONS = void 0;
3
+ exports.NestAuthEvents = exports.DEFAULT_GUARD_NAME = exports.NEST_AUTH_TRUST_DEVICE_KEY = exports.REFRESH_TOKEN_COOKIE_NAME = exports.ACCESS_TOKEN_COOKIE_NAME = exports.REFRESH_TOKEN_EXPIRED = exports.REFRESH_TOKEN_INVALID = exports.USER_NOT_ACTIVE_ERROR = exports.SESSION_NOT_FOUND_ERROR = exports.INVALID_REFRESH_TOKEN_EXCEPTION_CODE = exports.INVALID_MFA_EXCEPTION_CODE = exports.UNAUTHORIZED_EXCEPTION_CODE = exports.USER_NOT_FOUND_EXCEPTION_CODE = exports.PHONE_AUTH_PROVIDER = exports.EMAIL_AUTH_PROVIDER = exports.GITHUB_AUTH_PROVIDER = exports.APPLE_AUTH_PROVIDER = exports.FACEBOOK_AUTH_PROVIDER = exports.GOOGLE_AUTH_PROVIDER = exports.JWT_AUTH_PROVIDER = exports.NEST_AUTH_ASYNC_OPTIONS_PROVIDER = exports.AUTH_MODULE_OPTIONS = void 0;
4
4
  exports.AUTH_MODULE_OPTIONS = 'NEST_AUTH_AUTH_MODULE_OPTIONS';
5
5
  exports.NEST_AUTH_ASYNC_OPTIONS_PROVIDER = 'NEST_AUTH_ASYNC_OPTIONS_PROVIDER';
6
6
  // Provider tokens
@@ -23,6 +23,7 @@ exports.REFRESH_TOKEN_EXPIRED = 'REFRESH_TOKEN_EXPIRED';
23
23
  // Auth Cookie Names
24
24
  exports.ACCESS_TOKEN_COOKIE_NAME = 'accessToken';
25
25
  exports.REFRESH_TOKEN_COOKIE_NAME = 'refreshToken';
26
+ exports.NEST_AUTH_TRUST_DEVICE_KEY = 'nest_auth_device_trust';
26
27
  // Default values
27
28
  exports.DEFAULT_GUARD_NAME = 'web';
28
29
  // Events Const
@@ -17,6 +17,8 @@ export interface MFAOptions {
17
17
  allowUserToggle?: boolean;
18
18
  allowMethodSelection?: boolean;
19
19
  otpExpiresIn?: string | number;
20
+ trustedDeviceDuration?: string | number;
21
+ trustDeviceStorageName?: string;
20
22
  }
21
23
  export declare enum MFAMethodEnum {
22
24
  TOTP = "totp",
@@ -1 +1 @@
1
- {"version":3,"file":"mfa-options.interface.d.ts","sourceRoot":"","sources":["../../../../../../../packages/nest-auth/src/lib/core/interfaces/mfa-options.interface.ts"],"names":[],"mappings":"AACA,MAAM,WAAW,UAAU;IAEvB,OAAO,CAAC,EAAE,OAAO,CAAC;IAGlB,QAAQ,CAAC,EAAE,OAAO,CAAC;IAGnB,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;IAG1B,SAAS,CAAC,EAAE,MAAM,CAAC;IAGnB,IAAI,CAAC,EAAE;QACH,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;KAClB,CAAC;IAGF,GAAG,CAAC,EAAE;QACF,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KACpB,CAAC;IAGF,KAAK,CAAC,EAAE;QACJ,QAAQ,EAAE,MAAM,CAAC;KACpB,CAAC;IAGF,eAAe,CAAC,EAAE,OAAO,CAAC;IAG1B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAG/B,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAClC;AAED,oBAAY,aAAa;IACrB,IAAI,SAAS;IACb,GAAG,QAAQ;IACX,KAAK,UAAU;CAClB"}
1
+ {"version":3,"file":"mfa-options.interface.d.ts","sourceRoot":"","sources":["../../../../../../../packages/nest-auth/src/lib/core/interfaces/mfa-options.interface.ts"],"names":[],"mappings":"AACA,MAAM,WAAW,UAAU;IAEvB,OAAO,CAAC,EAAE,OAAO,CAAC;IAGlB,QAAQ,CAAC,EAAE,OAAO,CAAC;IAGnB,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;IAG1B,SAAS,CAAC,EAAE,MAAM,CAAC;IAGnB,IAAI,CAAC,EAAE;QACH,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;KAClB,CAAC;IAGF,GAAG,CAAC,EAAE;QACF,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KACpB,CAAC;IAGF,KAAK,CAAC,EAAE;QACJ,QAAQ,EAAE,MAAM,CAAC;KACpB,CAAC;IAGF,eAAe,CAAC,EAAE,OAAO,CAAC;IAG1B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAG/B,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAG/B,qBAAqB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAGxC,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACnC;AAED,oBAAY,aAAa;IACrB,IAAI,SAAS;IACb,GAAG,QAAQ;IACX,KAAK,UAAU;CAClB"}