@nauth-toolkit/core 0.1.18 → 0.1.21
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/adapters/storage.factory.d.ts.map +1 -1
- package/dist/adapters/storage.factory.js +250 -18
- package/dist/adapters/storage.factory.js.map +1 -1
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +2 -1
- package/dist/bootstrap.js.map +1 -1
- package/dist/dto/admin-signup.dto.d.ts +196 -0
- package/dist/dto/admin-signup.dto.d.ts.map +1 -0
- package/dist/dto/admin-signup.dto.js +317 -0
- package/dist/dto/admin-signup.dto.js.map +1 -0
- package/dist/dto/index.d.ts +1 -0
- package/dist/dto/index.d.ts.map +1 -1
- package/dist/dto/index.js +1 -0
- package/dist/dto/index.js.map +1 -1
- package/dist/handlers/csrf.handler.d.ts.map +1 -1
- package/dist/handlers/csrf.handler.js +7 -2
- package/dist/handlers/csrf.handler.js.map +1 -1
- package/dist/handlers/social-redirect.handler.d.ts +126 -0
- package/dist/handlers/social-redirect.handler.d.ts.map +1 -0
- package/dist/handlers/social-redirect.handler.js +346 -0
- package/dist/handlers/social-redirect.handler.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/interfaces/config.interface.d.ts +43 -0
- package/dist/interfaces/config.interface.d.ts.map +1 -1
- package/dist/interfaces/index.d.ts +1 -0
- package/dist/interfaces/index.d.ts.map +1 -1
- package/dist/interfaces/index.js +1 -0
- package/dist/interfaces/index.js.map +1 -1
- package/dist/interfaces/social-auth-state-store.interface.d.ts +100 -0
- package/dist/interfaces/social-auth-state-store.interface.d.ts.map +1 -0
- package/dist/interfaces/social-auth-state-store.interface.js +3 -0
- package/dist/interfaces/social-auth-state-store.interface.js.map +1 -0
- package/dist/interfaces/storage-adapter.interface.d.ts +2 -2
- package/dist/interfaces/storage-adapter.interface.d.ts.map +1 -1
- package/dist/internal.d.ts +5 -0
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +7 -1
- package/dist/internal.js.map +1 -1
- package/dist/schemas/auth-config.schema.d.ts +107 -28
- package/dist/schemas/auth-config.schema.d.ts.map +1 -1
- package/dist/schemas/auth-config.schema.js +20 -1
- package/dist/schemas/auth-config.schema.js.map +1 -1
- package/dist/services/auth.service.d.ts +39 -0
- package/dist/services/auth.service.d.ts.map +1 -1
- package/dist/services/auth.service.js +221 -9
- package/dist/services/auth.service.js.map +1 -1
- package/dist/services/social-auth-base.service.d.ts +5 -10
- package/dist/services/social-auth-base.service.d.ts.map +1 -1
- package/dist/services/social-auth-base.service.js +11 -59
- package/dist/services/social-auth-base.service.js.map +1 -1
- package/dist/services/social-auth-state-store.service.d.ts +58 -0
- package/dist/services/social-auth-state-store.service.d.ts.map +1 -0
- package/dist/services/social-auth-state-store.service.js +261 -0
- package/dist/services/social-auth-state-store.service.js.map +1 -0
- package/dist/storage/account-lockout-storage.service.d.ts +2 -2
- package/dist/storage/account-lockout-storage.service.d.ts.map +1 -1
- package/dist/storage/account-lockout-storage.service.js +2 -2
- package/dist/storage/account-lockout-storage.service.js.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/password-generator.d.ts +29 -0
- package/dist/utils/password-generator.d.ts.map +1 -0
- package/dist/utils/password-generator.js +98 -0
- package/dist/utils/password-generator.js.map +1 -0
- package/dist/utils/setup/init-social.d.ts +2 -5
- package/dist/utils/setup/init-social.d.ts.map +1 -1
- package/dist/utils/setup/init-social.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.service.d.ts","sourceRoot":"","sources":["../../src/services/auth.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,aAAa,EAAwB,MAAM,aAAa,CAAC;AAC9F,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AAC7E,OAAO,EAAE,4BAA4B,EAAE,MAAM,4CAA4C,CAAC;AAC1F,OAAO,EAAE,wBAAwB,IAAI,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACpF,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAGhE,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,wBAAwB,EAAE,MAAM,oCAAoC,CAAC;AAC9E,OAAO,EAAE,yBAAyB,EAAE,MAAM,qCAAqC,CAAC;AAChF,OAAO,EAAE,8BAA8B,EAAE,MAAM,2CAA2C,CAAC;AAC3F,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAY1E,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AAC/E,OAAO,EAAE,gCAAgC,EAAE,MAAM,8CAA8C,CAAC;AAChG,OAAO,EAAE,mBAAmB,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AACjG,OAAO,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AAC1F,OAAO,EAAE,wBAAwB,EAAE,gCAAgC,EAAE,MAAM,oCAAoC,CAAC;AAChH,OAAO,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAC;AAC1E,OAAO,EAAE,0BAA0B,EAAE,MAAM,uCAAuC,CAAC;AAInF,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAEhE,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"auth.service.d.ts","sourceRoot":"","sources":["../../src/services/auth.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -47,6 +47,7 @@ const error_codes_enum_1 = require("../enums/error-codes.enum");
|
|
|
47
47
|
const mfa_method_enum_1 = require("../enums/mfa-method.enum");
|
|
48
48
|
const class_validator_1 = require("class-validator");
|
|
49
49
|
const crypto = __importStar(require("crypto"));
|
|
50
|
+
const password_generator_1 = require("../utils/password-generator");
|
|
50
51
|
/**
|
|
51
52
|
* Dummy Argon2 hash for constant-time response
|
|
52
53
|
*
|
|
@@ -289,6 +290,199 @@ class AuthService {
|
|
|
289
290
|
return response;
|
|
290
291
|
}
|
|
291
292
|
// ============================================================================
|
|
293
|
+
// Admin Signup
|
|
294
|
+
// ============================================================================
|
|
295
|
+
/**
|
|
296
|
+
* Administrative user creation with override capabilities
|
|
297
|
+
*
|
|
298
|
+
* Allows administrators to create user accounts with:
|
|
299
|
+
* - Bypass email/phone verification requirements
|
|
300
|
+
* - Force password change on first login
|
|
301
|
+
* - Auto-generate secure passwords
|
|
302
|
+
*
|
|
303
|
+
* Security:
|
|
304
|
+
* - No built-in authentication - endpoint must be protected by framework adapter
|
|
305
|
+
* - All duplicate checks still enforced
|
|
306
|
+
* - Password policy still enforced (unless auto-generated)
|
|
307
|
+
* - Audit trail records admin-created accounts
|
|
308
|
+
*
|
|
309
|
+
* @param dto - Admin signup DTO with override flags
|
|
310
|
+
* @returns User object and optionally generated password
|
|
311
|
+
* @throws {NAuthException} EMAIL_EXISTS | USERNAME_EXISTS | PHONE_EXISTS | WEAK_PASSWORD
|
|
312
|
+
*
|
|
313
|
+
* @example
|
|
314
|
+
* ```typescript
|
|
315
|
+
* // Create user with pre-verified email
|
|
316
|
+
* const result = await authService.adminSignup({
|
|
317
|
+
* email: 'user@example.com',
|
|
318
|
+
* password: 'SecurePass123!',
|
|
319
|
+
* isEmailVerified: true,
|
|
320
|
+
* });
|
|
321
|
+
*
|
|
322
|
+
* // Create user with auto-generated password
|
|
323
|
+
* const result = await authService.adminSignup({
|
|
324
|
+
* email: 'user@example.com',
|
|
325
|
+
* generatePassword: true,
|
|
326
|
+
* isEmailVerified: true,
|
|
327
|
+
* mustChangePassword: true,
|
|
328
|
+
* });
|
|
329
|
+
* // result.generatedPassword contains the temporary password
|
|
330
|
+
* ```
|
|
331
|
+
*/
|
|
332
|
+
async adminSignup(dto) {
|
|
333
|
+
// Get client info from request context (transparent!)
|
|
334
|
+
const clientInfo = this.clientInfoService.get();
|
|
335
|
+
this.logger?.log?.(`Admin signup attempt for email: ${dto.email}`);
|
|
336
|
+
this.logger?.debug?.(`Admin signup details: { email: ${dto.email}, username: ${dto.username || 'none'}, ip: ${clientInfo.ipAddress} }`);
|
|
337
|
+
// Skip signup.enabled check (admin bypass)
|
|
338
|
+
// Check if user already exists (email and username)
|
|
339
|
+
this.logger?.debug?.(`Checking if user exists: ${dto.email}`);
|
|
340
|
+
const existingUserByEmail = await this.userRepository.findOne({
|
|
341
|
+
where: { email: dto.email },
|
|
342
|
+
});
|
|
343
|
+
if (existingUserByEmail) {
|
|
344
|
+
this.logger?.warn?.(`Admin signup failed - user already exists: ${dto.email}`);
|
|
345
|
+
throw new nauth_exception_1.NAuthException(error_codes_enum_1.AuthErrorCode.EMAIL_EXISTS, 'User with this email already exists');
|
|
346
|
+
}
|
|
347
|
+
// Check for duplicate username if provided
|
|
348
|
+
if (dto.username) {
|
|
349
|
+
this.logger?.debug?.(`Checking if username exists: ${dto.username}`);
|
|
350
|
+
const existingUserByUsername = await this.userRepository.findOne({
|
|
351
|
+
where: { username: dto.username },
|
|
352
|
+
});
|
|
353
|
+
if (existingUserByUsername) {
|
|
354
|
+
this.logger?.warn?.(`Admin signup failed - username already exists: ${dto.username}`);
|
|
355
|
+
throw new nauth_exception_1.NAuthException(error_codes_enum_1.AuthErrorCode.USERNAME_EXISTS, 'Username is already taken');
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
// Check for duplicate phone if provided and duplicates not allowed
|
|
359
|
+
if (dto.phone && !this.config.signup?.allowDuplicatePhones) {
|
|
360
|
+
this.logger?.debug?.(`Checking if phone exists: ${dto.phone}`);
|
|
361
|
+
const existingUserByPhone = await this.userRepository.findOne({
|
|
362
|
+
where: { phone: dto.phone },
|
|
363
|
+
});
|
|
364
|
+
if (existingUserByPhone) {
|
|
365
|
+
this.logger?.warn?.(`Admin signup failed - phone already exists: ${dto.phone}`);
|
|
366
|
+
throw new nauth_exception_1.NAuthException(error_codes_enum_1.AuthErrorCode.PHONE_EXISTS, 'Phone number is already registered');
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
// Handle password
|
|
370
|
+
let passwordHash;
|
|
371
|
+
let generatedPassword;
|
|
372
|
+
if (dto.generatePassword) {
|
|
373
|
+
// Generate secure random password
|
|
374
|
+
generatedPassword = (0, password_generator_1.generateSecurePassword)(16);
|
|
375
|
+
this.logger?.debug?.(`Generated password for admin-created user: ${dto.email}`);
|
|
376
|
+
passwordHash = await this.passwordService.hashPassword(generatedPassword);
|
|
377
|
+
}
|
|
378
|
+
else {
|
|
379
|
+
// Validate password policy
|
|
380
|
+
if (!dto.password) {
|
|
381
|
+
throw new nauth_exception_1.NAuthException(error_codes_enum_1.AuthErrorCode.WEAK_PASSWORD, 'Password is required when generatePassword is false');
|
|
382
|
+
}
|
|
383
|
+
this.logger?.debug?.('Validating password against policy');
|
|
384
|
+
const passwordValidation = await this.passwordService.validatePassword(dto.password, {
|
|
385
|
+
email: dto.email,
|
|
386
|
+
username: dto.username,
|
|
387
|
+
});
|
|
388
|
+
if (!passwordValidation.valid) {
|
|
389
|
+
this.logger?.warn?.(`Password validation failed for ${dto.email}: ${passwordValidation.errors.join(', ')}`);
|
|
390
|
+
throw new nauth_exception_1.NAuthException(error_codes_enum_1.AuthErrorCode.WEAK_PASSWORD, passwordValidation.errors.join(', '), {
|
|
391
|
+
errors: passwordValidation.errors,
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
// Hash password
|
|
395
|
+
passwordHash = await this.passwordService.hashPassword(dto.password);
|
|
396
|
+
}
|
|
397
|
+
// Create user with override flags
|
|
398
|
+
this.logger?.debug?.(`Creating admin user record for: ${dto.email} || ${dto.username} || ${dto.phone} (isEmailVerified: ${dto.isEmailVerified || false}, isPhoneVerified: ${dto.isPhoneVerified || false})`);
|
|
399
|
+
const user = this.userRepository.create({
|
|
400
|
+
email: dto.email,
|
|
401
|
+
username: dto.username,
|
|
402
|
+
firstName: dto.firstName,
|
|
403
|
+
lastName: dto.lastName,
|
|
404
|
+
phone: dto.phone,
|
|
405
|
+
passwordHash,
|
|
406
|
+
passwordChangedAt: new Date(),
|
|
407
|
+
isEmailVerified: dto.isEmailVerified ?? false, // Use DTO value or default to false
|
|
408
|
+
isPhoneVerified: dto.isPhoneVerified ?? false, // Use DTO value or default to false
|
|
409
|
+
mustChangePassword: dto.mustChangePassword ?? false, // Use DTO value or default to false
|
|
410
|
+
isActive: true, // Always active
|
|
411
|
+
metadata: dto.metadata,
|
|
412
|
+
});
|
|
413
|
+
let savedUser;
|
|
414
|
+
try {
|
|
415
|
+
savedUser = (await this.userRepository.save(user));
|
|
416
|
+
this.logger?.log?.(`Admin user created successfully: ${dto.email} (sub: ${savedUser.sub})`);
|
|
417
|
+
// ============================================================================
|
|
418
|
+
// Audit: Record account creation by admin
|
|
419
|
+
// ============================================================================
|
|
420
|
+
try {
|
|
421
|
+
await this.auditService?.recordEvent({
|
|
422
|
+
userId: savedUser.id,
|
|
423
|
+
eventType: auth_audit_event_type_enum_1.AuthAuditEventType.ACCOUNT_CREATED,
|
|
424
|
+
eventStatus: 'INFO',
|
|
425
|
+
authMethod: 'admin',
|
|
426
|
+
// Client info automatically included from context
|
|
427
|
+
metadata: {
|
|
428
|
+
email: savedUser.email,
|
|
429
|
+
username: savedUser.username || null,
|
|
430
|
+
createdByAdmin: true,
|
|
431
|
+
adminIdentifier: clientInfo.ipAddress || 'unknown',
|
|
432
|
+
isEmailVerified: savedUser.isEmailVerified,
|
|
433
|
+
isPhoneVerified: savedUser.isPhoneVerified,
|
|
434
|
+
mustChangePassword: savedUser.mustChangePassword,
|
|
435
|
+
passwordGenerated: !!generatedPassword,
|
|
436
|
+
},
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
catch (auditError) {
|
|
440
|
+
// Non-blocking: Log but continue
|
|
441
|
+
const errorMessage = auditError instanceof Error ? auditError.message : 'Unknown error';
|
|
442
|
+
this.logger?.error?.(`Failed to record ACCOUNT_CREATED audit event: ${errorMessage}`, {
|
|
443
|
+
error: auditError,
|
|
444
|
+
userId: savedUser.id,
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
catch (error) {
|
|
449
|
+
// Handle database constraint violations gracefully
|
|
450
|
+
if (error && typeof error === 'object' && 'code' in error && error.code === '23505') {
|
|
451
|
+
// PostgreSQL unique constraint violation
|
|
452
|
+
const dbError = error;
|
|
453
|
+
if (dbError.detail?.includes('email')) {
|
|
454
|
+
this.logger?.warn?.(`Admin signup failed - email constraint violation: ${dto.email}`);
|
|
455
|
+
throw new nauth_exception_1.NAuthException(error_codes_enum_1.AuthErrorCode.EMAIL_EXISTS, 'User with this email already exists');
|
|
456
|
+
}
|
|
457
|
+
else if (dbError.detail?.includes('username')) {
|
|
458
|
+
this.logger?.warn?.(`Admin signup failed - username constraint violation: ${dto.username}`);
|
|
459
|
+
throw new nauth_exception_1.NAuthException(error_codes_enum_1.AuthErrorCode.USERNAME_EXISTS, 'Username is already taken');
|
|
460
|
+
}
|
|
461
|
+
else if (dbError.detail?.includes('phone')) {
|
|
462
|
+
this.logger?.warn?.(`Admin signup failed - phone constraint violation: ${dto.phone}`);
|
|
463
|
+
throw new nauth_exception_1.NAuthException(error_codes_enum_1.AuthErrorCode.PHONE_EXISTS, 'Phone number is already registered');
|
|
464
|
+
}
|
|
465
|
+
else {
|
|
466
|
+
this.logger?.error?.(`Admin signup failed - database constraint violation: ${dbError.message}`);
|
|
467
|
+
throw new nauth_exception_1.NAuthException(error_codes_enum_1.AuthErrorCode.EMAIL_EXISTS, 'User with this information already exists', {
|
|
468
|
+
conflictType: 'unknown',
|
|
469
|
+
});
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
// Re-throw other database errors
|
|
473
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown database error';
|
|
474
|
+
this.logger?.error?.(`Admin signup failed - database error: ${errorMessage}`);
|
|
475
|
+
throw error;
|
|
476
|
+
}
|
|
477
|
+
// No tokens, no challenge system, no verification emails - pure user creation
|
|
478
|
+
// Return sanitized user object (excludes passwordHash and other sensitive fields)
|
|
479
|
+
const userDto = user_response_dto_1.UserResponseDto.fromEntity(savedUser);
|
|
480
|
+
return {
|
|
481
|
+
user: userDto,
|
|
482
|
+
generatedPassword,
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
// ============================================================================
|
|
292
486
|
// User Login
|
|
293
487
|
// ============================================================================
|
|
294
488
|
/**
|
|
@@ -794,10 +988,19 @@ class AuthService {
|
|
|
794
988
|
});
|
|
795
989
|
}
|
|
796
990
|
}
|
|
797
|
-
//
|
|
798
|
-
//
|
|
799
|
-
//
|
|
800
|
-
|
|
991
|
+
// ============================================================================
|
|
992
|
+
// Lifecycle Hook: afterLogin
|
|
993
|
+
// ============================================================================
|
|
994
|
+
if (this.config.hooks?.afterLogin) {
|
|
995
|
+
try {
|
|
996
|
+
await this.config.hooks.afterLogin(user, session);
|
|
997
|
+
}
|
|
998
|
+
catch (hookError) {
|
|
999
|
+
const errorMessage = hookError instanceof Error ? hookError.message : 'Unknown error';
|
|
1000
|
+
// Non-blocking: auth succeeded; hook errors should not break login
|
|
1001
|
+
this.logger?.error?.(`afterLogin hook failed (continuing): ${errorMessage}`, { error: hookError });
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
801
1004
|
// ============================================================================
|
|
802
1005
|
// Trusted Device Token Management (Remember Device Feature)
|
|
803
1006
|
// ============================================================================
|
|
@@ -3008,7 +3211,7 @@ class AuthService {
|
|
|
3008
3211
|
const attempts = await this.accountLockoutStorage.recordFailedAttempt(ipAddress);
|
|
3009
3212
|
// Lock IP if max attempts reached
|
|
3010
3213
|
if (attempts >= (this.config.lockout.maxAttempts || 5)) {
|
|
3011
|
-
await this.accountLockoutStorage.
|
|
3214
|
+
await this.accountLockoutStorage.lockIpAddress(ipAddress, this.config.lockout.duration || 900, // 15 minutes default
|
|
3012
3215
|
'Too many failed login attempts from this IP');
|
|
3013
3216
|
// // Execute hook with IP address
|
|
3014
3217
|
// if (this.config.hooks?.afterAccountLock) {
|
|
@@ -3016,10 +3219,19 @@ class AuthService {
|
|
|
3016
3219
|
// }
|
|
3017
3220
|
}
|
|
3018
3221
|
}
|
|
3019
|
-
//
|
|
3020
|
-
//
|
|
3021
|
-
//
|
|
3022
|
-
|
|
3222
|
+
// ============================================================================
|
|
3223
|
+
// Lifecycle Hook: afterLoginFailed
|
|
3224
|
+
// ============================================================================
|
|
3225
|
+
if (this.config.hooks?.afterLoginFailed) {
|
|
3226
|
+
try {
|
|
3227
|
+
await this.config.hooks.afterLoginFailed(identifier, reason || 'unknown');
|
|
3228
|
+
}
|
|
3229
|
+
catch (hookError) {
|
|
3230
|
+
const errorMessage = hookError instanceof Error ? hookError.message : 'Unknown error';
|
|
3231
|
+
// Non-blocking: login already failed; do not throw
|
|
3232
|
+
this.logger?.error?.(`afterLoginFailed hook failed (continuing): ${errorMessage}`, { error: hookError });
|
|
3233
|
+
}
|
|
3234
|
+
}
|
|
3023
3235
|
}
|
|
3024
3236
|
/**
|
|
3025
3237
|
* Records a login attempt with client context.
|