@nauth-toolkit/core 0.1.61 → 0.1.62

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 (93) hide show
  1. package/dist/bootstrap.d.ts.map +1 -1
  2. package/dist/bootstrap.js +0 -22
  3. package/dist/bootstrap.js.map +1 -1
  4. package/dist/dto/change-password-request.dto.d.ts +5 -2
  5. package/dist/dto/change-password-request.dto.d.ts.map +1 -1
  6. package/dist/dto/change-password-request.dto.js +6 -1
  7. package/dist/dto/change-password-request.dto.js.map +1 -1
  8. package/dist/dto/logout-all.dto.d.ts +5 -2
  9. package/dist/dto/logout-all.dto.d.ts.map +1 -1
  10. package/dist/dto/logout-all.dto.js +6 -1
  11. package/dist/dto/logout-all.dto.js.map +1 -1
  12. package/dist/dto/refresh-token.dto.d.ts +19 -7
  13. package/dist/dto/refresh-token.dto.d.ts.map +1 -1
  14. package/dist/dto/refresh-token.dto.js +20 -6
  15. package/dist/dto/refresh-token.dto.js.map +1 -1
  16. package/dist/dto/setup-mfa.dto.d.ts +5 -2
  17. package/dist/dto/setup-mfa.dto.d.ts.map +1 -1
  18. package/dist/dto/setup-mfa.dto.js +6 -1
  19. package/dist/dto/setup-mfa.dto.js.map +1 -1
  20. package/dist/dto/update-user-attributes-request.dto.d.ts +5 -2
  21. package/dist/dto/update-user-attributes-request.dto.d.ts.map +1 -1
  22. package/dist/dto/update-user-attributes-request.dto.js +6 -1
  23. package/dist/dto/update-user-attributes-request.dto.js.map +1 -1
  24. package/dist/interfaces/config.interface.d.ts +306 -76
  25. package/dist/interfaces/config.interface.d.ts.map +1 -1
  26. package/dist/interfaces/hooks.interface.d.ts +753 -7
  27. package/dist/interfaces/hooks.interface.d.ts.map +1 -1
  28. package/dist/interfaces/provider.interface.d.ts +143 -0
  29. package/dist/interfaces/provider.interface.d.ts.map +1 -1
  30. package/dist/interfaces/template.interface.d.ts +20 -43
  31. package/dist/interfaces/template.interface.d.ts.map +1 -1
  32. package/dist/interfaces/template.interface.js +8 -0
  33. package/dist/interfaces/template.interface.js.map +1 -1
  34. package/dist/internal.d.ts +5 -0
  35. package/dist/internal.d.ts.map +1 -1
  36. package/dist/internal.js +7 -1
  37. package/dist/internal.js.map +1 -1
  38. package/dist/schemas/auth-config.schema.d.ts +445 -104
  39. package/dist/schemas/auth-config.schema.d.ts.map +1 -1
  40. package/dist/schemas/auth-config.schema.js +55 -8
  41. package/dist/schemas/auth-config.schema.js.map +1 -1
  42. package/dist/services/adaptive-mfa-decision.service.d.ts +25 -1
  43. package/dist/services/adaptive-mfa-decision.service.d.ts.map +1 -1
  44. package/dist/services/adaptive-mfa-decision.service.js +91 -8
  45. package/dist/services/adaptive-mfa-decision.service.js.map +1 -1
  46. package/dist/services/auth-audit.service.d.ts.map +1 -1
  47. package/dist/services/auth-audit.service.js +25 -4
  48. package/dist/services/auth-audit.service.js.map +1 -1
  49. package/dist/services/auth-flow-context-builder.service.d.ts.map +1 -1
  50. package/dist/services/auth-flow-context-builder.service.js +8 -1
  51. package/dist/services/auth-flow-context-builder.service.js.map +1 -1
  52. package/dist/services/auth-service-internal-helpers.d.ts +3 -1
  53. package/dist/services/auth-service-internal-helpers.d.ts.map +1 -1
  54. package/dist/services/auth-service-internal-helpers.js +28 -1
  55. package/dist/services/auth-service-internal-helpers.js.map +1 -1
  56. package/dist/services/auth.service.d.ts.map +1 -1
  57. package/dist/services/auth.service.js +84 -27
  58. package/dist/services/auth.service.js.map +1 -1
  59. package/dist/services/email-notifications.hook.d.ts +14 -0
  60. package/dist/services/email-notifications.hook.d.ts.map +1 -0
  61. package/dist/services/email-notifications.hook.js +254 -0
  62. package/dist/services/email-notifications.hook.js.map +1 -0
  63. package/dist/services/email-verification.service.d.ts.map +1 -1
  64. package/dist/services/email-verification.service.js +55 -0
  65. package/dist/services/email-verification.service.js.map +1 -1
  66. package/dist/services/hook-registry.service.d.ts +222 -1
  67. package/dist/services/hook-registry.service.d.ts.map +1 -1
  68. package/dist/services/hook-registry.service.js +391 -0
  69. package/dist/services/hook-registry.service.js.map +1 -1
  70. package/dist/services/mfa-base.service.d.ts +3 -1
  71. package/dist/services/mfa-base.service.d.ts.map +1 -1
  72. package/dist/services/mfa-base.service.js +70 -1
  73. package/dist/services/mfa-base.service.js.map +1 -1
  74. package/dist/services/mfa.service.d.ts +3 -1
  75. package/dist/services/mfa.service.d.ts.map +1 -1
  76. package/dist/services/mfa.service.js +32 -1
  77. package/dist/services/mfa.service.js.map +1 -1
  78. package/dist/services/password-reset.service.d.ts.map +1 -1
  79. package/dist/services/password-reset.service.js +5 -3
  80. package/dist/services/password-reset.service.js.map +1 -1
  81. package/dist/services/phone-verification.service.d.ts.map +1 -1
  82. package/dist/services/phone-verification.service.js +56 -2
  83. package/dist/services/phone-verification.service.js.map +1 -1
  84. package/dist/services/user.service.d.ts.map +1 -1
  85. package/dist/services/user.service.js +84 -1
  86. package/dist/services/user.service.js.map +1 -1
  87. package/dist/utils/setup/init-services.d.ts.map +1 -1
  88. package/dist/utils/setup/init-services.js +22 -23
  89. package/dist/utils/setup/init-services.js.map +1 -1
  90. package/dist/validators/template.validator.d.ts.map +1 -1
  91. package/dist/validators/template.validator.js +8 -0
  92. package/dist/validators/template.validator.js.map +1 -1
  93. package/package.json +1 -1
@@ -125,6 +125,69 @@ export interface SignupMetadata {
125
125
  */
126
126
  profilePicture?: string | null;
127
127
  }
128
+ /**
129
+ * Onboarding completion source
130
+ *
131
+ * Indicates what caused onboarding to become "complete":
132
+ * - `signup`: Signup did not require verification (verificationMethod = 'none')
133
+ * - `email_verification`: Email verification completed onboarding
134
+ * - `phone_verification`: Phone verification completed onboarding
135
+ */
136
+ export type OnboardingCompletionSource = 'signup' | 'email_verification' | 'phone_verification';
137
+ /**
138
+ * Onboarding completed metadata
139
+ *
140
+ * Fired exactly once when the user has satisfied the configured signup verification requirements.
141
+ *
142
+ * @remarks
143
+ * This is the correct lifecycle event for sending “welcome” style emails because it represents
144
+ * "the user can now proceed" — either immediately after signup (no verification required) or
145
+ * after the required verification(s) succeed.
146
+ */
147
+ export interface OnboardingCompletedMetadata {
148
+ /**
149
+ * Configured signup verification method at the time of completion
150
+ *
151
+ * @example 'none' | 'email' | 'phone' | 'both'
152
+ */
153
+ verificationMethod: 'none' | 'email' | 'phone' | 'both';
154
+ /**
155
+ * What completed onboarding
156
+ */
157
+ source: OnboardingCompletionSource;
158
+ /**
159
+ * When onboarding was completed
160
+ */
161
+ completedAt: Date;
162
+ }
163
+ /**
164
+ * Onboarding completed hook interface
165
+ *
166
+ * Executes actions after onboarding becomes complete (non-blocking).
167
+ *
168
+ * @example
169
+ * ```typescript
170
+ * export class WelcomeAnalyticsHook implements IOnboardingCompletedHook {
171
+ * async execute(user: IUser, metadata: OnboardingCompletedMetadata): Promise<void> {
172
+ * // Track onboarding completion event
173
+ * await this.analytics.track('onboarding_completed', {
174
+ * userSub: user.sub,
175
+ * verificationMethod: metadata.verificationMethod,
176
+ * source: metadata.source,
177
+ * });
178
+ * }
179
+ * }
180
+ * ```
181
+ */
182
+ export interface IOnboardingCompletedHook {
183
+ /**
184
+ * Execute onboarding completed actions
185
+ *
186
+ * @param user - User entity (IUser interface)
187
+ * @param metadata - Completion metadata (verification method, source, timestamp)
188
+ */
189
+ execute(user: IUser, metadata: OnboardingCompletedMetadata): Promise<void>;
190
+ }
128
191
  /**
129
192
  * User profile update source
130
193
  *
@@ -173,14 +236,9 @@ export interface UserProfileUpdatedMetadata {
173
236
  */
174
237
  performedBy?: string;
175
238
  /**
176
- * Client information (IP address, user agent)
239
+ * Client information (IP address, user agent, location)
177
240
  */
178
- clientInfo?: {
179
- ipAddress?: string;
180
- userAgent?: string;
181
- ipCountry?: string;
182
- ipCity?: string;
183
- };
241
+ clientInfo?: import('./client-info.interface').ClientInfo;
184
242
  }
185
243
  /**
186
244
  * User profile updated hook interface
@@ -226,4 +284,692 @@ export interface IUserProfileUpdatedHook {
226
284
  */
227
285
  execute(metadata: UserProfileUpdatedMetadata): Promise<void>;
228
286
  }
287
+ /**
288
+ * Password changed metadata
289
+ *
290
+ * Provides context about password change events.
291
+ */
292
+ export interface PasswordChangedMetadata {
293
+ /**
294
+ * User whose password was changed
295
+ */
296
+ user: IUser;
297
+ /**
298
+ * How the password was changed
299
+ *
300
+ * - 'user': User changed their own password
301
+ * - 'admin': Admin set new password
302
+ * - 'reset': Password reset via forgot-password flow
303
+ */
304
+ changedBy: 'user' | 'admin' | 'reset';
305
+ /**
306
+ * Number of sessions revoked (optional)
307
+ */
308
+ sessionsRevoked?: number;
309
+ /**
310
+ * Client information (IP address, user agent, location)
311
+ */
312
+ clientInfo?: import('./client-info.interface').ClientInfo;
313
+ }
314
+ /**
315
+ * Password changed hook interface
316
+ *
317
+ * Executes actions after password is changed (non-blocking).
318
+ * Errors are logged but do not affect the password change operation.
319
+ *
320
+ * @remarks
321
+ * This hook is triggered when:
322
+ * - User changes their password via `changePassword()`
323
+ * - Admin sets new password via `adminSetPassword()`
324
+ * - User completes password reset via `confirmPasswordReset()`
325
+ *
326
+ * The hook is non-blocking. If it throws an error, the error is logged
327
+ * but the password has already been changed when the hook is called.
328
+ *
329
+ * Use cases:
330
+ * - Send security alert email
331
+ * - Log to SIEM
332
+ * - Trigger account re-enrollment
333
+ * - Update external systems
334
+ *
335
+ * @example
336
+ * ```typescript
337
+ * export class PasswordChangedEmailHook implements IPasswordChangedHook {
338
+ * async execute(metadata: PasswordChangedMetadata): Promise<void> {
339
+ * const { user, changedBy, sessionsRevoked } = metadata;
340
+ * await this.emailService.sendPasswordChangedEmail(
341
+ * user.email,
342
+ * { changedBy, sessionsRevoked }
343
+ * );
344
+ * }
345
+ * }
346
+ * ```
347
+ */
348
+ export interface IPasswordChangedHook {
349
+ /**
350
+ * Execute password changed actions
351
+ *
352
+ * @param metadata - Password change context with user and change details
353
+ */
354
+ execute(metadata: PasswordChangedMetadata): Promise<void>;
355
+ }
356
+ /**
357
+ * MFA device removed metadata
358
+ *
359
+ * Provides context about MFA device removal events.
360
+ */
361
+ export interface MFADeviceRemovedMetadata {
362
+ /**
363
+ * User whose MFA device was removed
364
+ */
365
+ user: IUser;
366
+ /**
367
+ * Type of MFA device that was removed
368
+ */
369
+ deviceType: import('../enums/mfa-method.enum').MFADeviceMethod;
370
+ /**
371
+ * Device name (optional, user-provided label)
372
+ */
373
+ deviceName?: string;
374
+ /**
375
+ * Who removed the device
376
+ *
377
+ * - 'user': User removed their own device
378
+ * - 'system': System removed device (e.g., after email/phone change)
379
+ */
380
+ removedBy: 'user' | 'system';
381
+ /**
382
+ * Reason for removal
383
+ *
384
+ * - 'email_changed': Email changed, email MFA device removed
385
+ * - 'phone_changed': Phone changed, SMS MFA device removed
386
+ * - 'user_request': User requested removal
387
+ * - 'admin_action': Admin removed device
388
+ */
389
+ reason?: string;
390
+ /**
391
+ * Number of MFA devices remaining after removal
392
+ */
393
+ remainingDeviceCount: number;
394
+ /**
395
+ * Client information (IP address, user agent, location)
396
+ */
397
+ clientInfo?: import('./client-info.interface').ClientInfo;
398
+ }
399
+ /**
400
+ * MFA device removed hook interface
401
+ *
402
+ * Executes actions after MFA device is removed (non-blocking).
403
+ * Errors are logged but do not affect the removal operation.
404
+ *
405
+ * @remarks
406
+ * This hook is triggered when:
407
+ * - User removes MFA device via `removeDevices()`
408
+ * - System removes device due to email/phone change via `updateUserAttributes()`
409
+ *
410
+ * The hook is non-blocking. If it throws an error, the error is logged
411
+ * but the device has already been removed when the hook is called.
412
+ *
413
+ * Use cases:
414
+ * - Send security alert email
415
+ * - Log to SIEM
416
+ * - Warn if last device removed
417
+ * - Update external systems
418
+ *
419
+ * @example
420
+ * ```typescript
421
+ * export class MFADeviceRemovedAlertHook implements IMFADeviceRemovedHook {
422
+ * async execute(metadata: MFADeviceRemovedMetadata): Promise<void> {
423
+ * const { user, deviceType, remainingDeviceCount } = metadata;
424
+ * if (remainingDeviceCount === 0) {
425
+ * await this.emailService.sendMFADeviceRemovedEmail(
426
+ * user.email,
427
+ * { deviceType, warning: 'No MFA devices remaining' }
428
+ * );
429
+ * }
430
+ * }
431
+ * }
432
+ * ```
433
+ */
434
+ export interface IMFADeviceRemovedHook {
435
+ /**
436
+ * Execute MFA device removed actions
437
+ *
438
+ * @param metadata - Device removal context with user and device details
439
+ */
440
+ execute(metadata: MFADeviceRemovedMetadata): Promise<void>;
441
+ }
442
+ /**
443
+ * Adaptive MFA risk detected metadata
444
+ *
445
+ * Provides context about adaptive MFA risk evaluation events.
446
+ */
447
+ export interface AdaptiveMFARiskDetectedMetadata {
448
+ /**
449
+ * User being authenticated
450
+ */
451
+ user: IUser;
452
+ /**
453
+ * Risk score (0-100)
454
+ */
455
+ riskScore: number;
456
+ /**
457
+ * Risk level classification
458
+ */
459
+ riskLevel: 'low' | 'medium' | 'high';
460
+ /**
461
+ * Detected risk factors
462
+ */
463
+ riskFactors: import('../enums/risk-factor.enum').RiskFactor[];
464
+ /**
465
+ * Action taken based on risk level
466
+ *
467
+ * - 'allow': No MFA required
468
+ * - 'require_mfa': MFA verification required
469
+ * - 'block_signin': Sign-in blocked
470
+ */
471
+ action: 'allow' | 'require_mfa' | 'block_signin';
472
+ /**
473
+ * Authentication method used
474
+ */
475
+ authMethod: string;
476
+ /**
477
+ * Client information (IP address, user agent, location)
478
+ */
479
+ clientInfo: import('./client-info.interface').ClientInfo;
480
+ /**
481
+ * Event timestamp
482
+ */
483
+ timestamp: Date;
484
+ }
485
+ /**
486
+ * Adaptive MFA risk detected hook interface
487
+ *
488
+ * Executes actions when adaptive MFA evaluates risk (non-blocking).
489
+ * Only triggered when notifyUser is true in risk level config.
490
+ * Errors are logged but do not affect authentication flow.
491
+ *
492
+ * @remarks
493
+ * This hook is triggered when:
494
+ * - Adaptive MFA evaluates login and detects risk factors
495
+ * - Risk level configuration has `notifyUser: true`
496
+ *
497
+ * The hook is non-blocking. If it throws an error, the error is logged
498
+ * but authentication flow continues normally.
499
+ *
500
+ * Use cases:
501
+ * - Send risk alert email
502
+ * - Log to SIEM
503
+ * - Trigger additional verification
504
+ * - Update fraud detection systems
505
+ *
506
+ * @example
507
+ * ```typescript
508
+ * export class AdaptiveMFARiskAlertHook implements IAdaptiveMFARiskDetectedHook {
509
+ * async execute(metadata: AdaptiveMFARiskDetectedMetadata): Promise<void> {
510
+ * const { user, riskScore, riskLevel, riskFactors } = metadata;
511
+ * if (riskLevel === 'high') {
512
+ * await this.emailService.sendRiskAlertEmail(
513
+ * user.email,
514
+ * { riskScore, riskFactors }
515
+ * );
516
+ * }
517
+ * }
518
+ * }
519
+ * ```
520
+ */
521
+ export interface IAdaptiveMFARiskDetectedHook {
522
+ /**
523
+ * Execute adaptive MFA risk detected actions
524
+ *
525
+ * @param metadata - Risk evaluation context with user and risk details
526
+ */
527
+ execute(metadata: AdaptiveMFARiskDetectedMetadata): Promise<void>;
528
+ }
529
+ /**
530
+ * Account status changed metadata
531
+ *
532
+ * Provides context about account enable/disable events.
533
+ */
534
+ export interface AccountStatusChangedMetadata {
535
+ /**
536
+ * User whose account status changed
537
+ */
538
+ user: IUser;
539
+ /**
540
+ * New account status
541
+ *
542
+ * - 'disabled': Account was disabled
543
+ * - 'enabled': Account was enabled
544
+ */
545
+ status: 'disabled' | 'enabled';
546
+ /**
547
+ * Reason for status change
548
+ */
549
+ reason?: string;
550
+ /**
551
+ * Admin who performed the action (admin sub)
552
+ */
553
+ performedBy?: string;
554
+ /**
555
+ * Number of sessions revoked (for disable action)
556
+ */
557
+ revokedSessions?: number;
558
+ /**
559
+ * Client information (IP address, user agent, location)
560
+ */
561
+ clientInfo?: import('./client-info.interface').ClientInfo;
562
+ }
563
+ /**
564
+ * Account status changed hook interface
565
+ *
566
+ * Executes actions after account is enabled or disabled (non-blocking).
567
+ * Errors are logged but do not affect the status change operation.
568
+ *
569
+ * @remarks
570
+ * This hook is triggered when:
571
+ * - Admin disables user account via `disableUser()`
572
+ * - Admin enables user account via `enableUser()`
573
+ *
574
+ * The hook is non-blocking. If it throws an error, the error is logged
575
+ * but the account status has already been changed when the hook is called.
576
+ *
577
+ * Use cases:
578
+ * - Notify user of account status change
579
+ * - Log to compliance system
580
+ * - Trigger CRM/support workflows
581
+ * - Update external systems
582
+ *
583
+ * @example
584
+ * ```typescript
585
+ * export class AccountStatusNotificationHook implements IAccountStatusChangedHook {
586
+ * async execute(metadata: AccountStatusChangedMetadata): Promise<void> {
587
+ * const { user, status, reason } = metadata;
588
+ * if (status === 'disabled') {
589
+ * await this.emailService.sendAccountDisabledEmail(
590
+ * user.email,
591
+ * { reason }
592
+ * );
593
+ * }
594
+ * }
595
+ * }
596
+ * ```
597
+ */
598
+ export interface IAccountStatusChangedHook {
599
+ /**
600
+ * Execute account status changed actions
601
+ *
602
+ * @param metadata - Status change context with user and change details
603
+ */
604
+ execute(metadata: AccountStatusChangedMetadata): Promise<void>;
605
+ }
606
+ /**
607
+ * Email changed metadata
608
+ *
609
+ * Provides context about email change events.
610
+ */
611
+ export interface EmailChangedMetadata {
612
+ /**
613
+ * User whose email was changed
614
+ */
615
+ user: IUser;
616
+ /**
617
+ * Old email address (before change)
618
+ */
619
+ oldEmail: string;
620
+ /**
621
+ * New email address (after change)
622
+ */
623
+ newEmail: string;
624
+ /**
625
+ * Source of the email change
626
+ */
627
+ updateSource: UserProfileUpdateSource;
628
+ /**
629
+ * Number of MFA devices deactivated due to email change
630
+ */
631
+ deactivatedMFADevices?: number;
632
+ /**
633
+ * Client information (IP address, user agent, location)
634
+ */
635
+ clientInfo?: import('./client-info.interface').ClientInfo;
636
+ }
637
+ /**
638
+ * Email changed hook interface
639
+ *
640
+ * Executes actions after email address is changed (non-blocking).
641
+ * Errors are logged but do not affect the email change operation.
642
+ *
643
+ * @remarks
644
+ * This hook is triggered when:
645
+ * - User changes email via `updateUserAttributes()`
646
+ *
647
+ * The hook is non-blocking. If it throws an error, the error is logged
648
+ * but the email has already been changed when the hook is called.
649
+ *
650
+ * **Important:** This hook triggers TWO emails for security:
651
+ * 1. Alert to OLD email address (security notification)
652
+ * 2. Confirmation to NEW email address
653
+ *
654
+ * Use cases:
655
+ * - Send security alert to old email
656
+ * - Send confirmation to new email
657
+ * - Log to audit system
658
+ * - Update external systems
659
+ *
660
+ * @example
661
+ * ```typescript
662
+ * export class EmailChangedNotificationHook implements IEmailChangedHook {
663
+ * async execute(metadata: EmailChangedMetadata): Promise<void> {
664
+ * const { oldEmail, newEmail, deactivatedMFADevices } = metadata;
665
+ *
666
+ * // Alert to old email
667
+ * await this.emailService.sendEmailChangedAlertEmail(
668
+ * oldEmail,
669
+ * { newEmail, deactivatedMFADevices }
670
+ * );
671
+ *
672
+ * // Confirmation to new email
673
+ * await this.emailService.sendEmailChangedConfirmationEmail(
674
+ * newEmail
675
+ * );
676
+ * }
677
+ * }
678
+ * ```
679
+ */
680
+ export interface IEmailChangedHook {
681
+ /**
682
+ * Execute email changed actions
683
+ *
684
+ * @param metadata - Email change context with old and new addresses
685
+ */
686
+ execute(metadata: EmailChangedMetadata): Promise<void>;
687
+ }
688
+ /**
689
+ * Account locked metadata
690
+ *
691
+ * Provides context about account lockout events.
692
+ */
693
+ export interface AccountLockedMetadata {
694
+ /**
695
+ * User whose account was locked
696
+ */
697
+ user: IUser;
698
+ /**
699
+ * Reason for lockout
700
+ */
701
+ reason: string;
702
+ /**
703
+ * Type of lock
704
+ *
705
+ * - 'temporary': Temporary lockout (auto-unlocks)
706
+ * - 'permanent': Permanent lock (requires admin intervention)
707
+ */
708
+ lockType: 'temporary' | 'permanent';
709
+ /**
710
+ * Lock duration in seconds (for temporary locks)
711
+ */
712
+ lockDuration?: number;
713
+ /**
714
+ * When the lock expires (for temporary locks)
715
+ */
716
+ lockedUntil?: Date;
717
+ /**
718
+ * IP address that triggered the lockout
719
+ */
720
+ ipAddress?: string;
721
+ /**
722
+ * Number of failed attempts that triggered lockout
723
+ */
724
+ failedAttempts?: number;
725
+ }
726
+ /**
727
+ * Account locked hook interface
728
+ *
729
+ * Executes actions after account is locked (non-blocking).
730
+ * Errors are logged but do not affect the lockout operation.
731
+ *
732
+ * @remarks
733
+ * This hook is triggered when:
734
+ * - Account lockout threshold is reached via `handleFailedLogin()`
735
+ *
736
+ * The hook is non-blocking. If it throws an error, the error is logged
737
+ * but the account has already been locked when the hook is called.
738
+ *
739
+ * Use cases:
740
+ * - Notify user of lockout
741
+ * - Log to security system
742
+ * - Trigger fraud detection
743
+ * - Alert admins for high-risk lockouts
744
+ *
745
+ * @example
746
+ * ```typescript
747
+ * export class AccountLockedNotificationHook implements IAccountLockedHook {
748
+ * async execute(metadata: AccountLockedMetadata): Promise<void> {
749
+ * const { user, reason, lockDuration } = metadata;
750
+ * await this.emailService.sendAccountLockedEmail(
751
+ * user.email,
752
+ * { reason, lockDuration }
753
+ * );
754
+ * }
755
+ * }
756
+ * ```
757
+ */
758
+ export interface IAccountLockedHook {
759
+ /**
760
+ * Execute account locked actions
761
+ *
762
+ * @param metadata - Lockout context with user and lock details
763
+ */
764
+ execute(metadata: AccountLockedMetadata): Promise<void>;
765
+ }
766
+ /**
767
+ * Sessions revoked metadata
768
+ *
769
+ * Provides context about session revocation events.
770
+ */
771
+ export interface SessionsRevokedMetadata {
772
+ /**
773
+ * User whose sessions were revoked
774
+ */
775
+ user: IUser;
776
+ /**
777
+ * Number of sessions revoked
778
+ */
779
+ revokedCount: number;
780
+ /**
781
+ * Reason for revocation
782
+ */
783
+ reason: string;
784
+ /**
785
+ * Who initiated the revocation
786
+ *
787
+ * - 'user': User revoked their own sessions
788
+ * - 'admin': Admin revoked sessions
789
+ * - 'system': System revoked sessions (e.g., password change)
790
+ */
791
+ initiatedBy: 'user' | 'admin' | 'system';
792
+ /**
793
+ * Trigger event (optional)
794
+ *
795
+ * - 'password_changed': Password change triggered revocation
796
+ * - 'account_disabled': Account disable triggered revocation
797
+ * - 'user_request': User manually revoked sessions
798
+ */
799
+ triggerEvent?: string;
800
+ }
801
+ /**
802
+ * Sessions revoked hook interface
803
+ *
804
+ * Executes actions after sessions are revoked (non-blocking).
805
+ * Errors are logged but do not affect the revocation operation.
806
+ *
807
+ * @remarks
808
+ * This hook is triggered when:
809
+ * - Sessions are revoked via `revokeAllUserSessions()` when NOT user-initiated
810
+ *
811
+ * The hook is non-blocking. If it throws an error, the error is logged
812
+ * but the sessions have already been revoked when the hook is called.
813
+ *
814
+ * **Note:** Hook is NOT triggered for user-initiated revocations (when user
815
+ * explicitly logs out or revokes sessions) to avoid notification spam.
816
+ *
817
+ * Use cases:
818
+ * - Send security alert about forced logout
819
+ * - Log to security system
820
+ * - Update external systems
821
+ *
822
+ * @example
823
+ * ```typescript
824
+ * export class SessionsRevokedAlertHook implements ISessionsRevokedHook {
825
+ * async execute(metadata: SessionsRevokedMetadata): Promise<void> {
826
+ * const { user, revokedCount, reason } = metadata;
827
+ * if (reason === 'password_changed') {
828
+ * await this.emailService.sendSessionsRevokedEmail(
829
+ * user.email,
830
+ * { revokedCount, reason }
831
+ * );
832
+ * }
833
+ * }
834
+ * }
835
+ * ```
836
+ */
837
+ export interface ISessionsRevokedHook {
838
+ /**
839
+ * Execute sessions revoked actions
840
+ *
841
+ * @param metadata - Revocation context with user and session details
842
+ */
843
+ execute(metadata: SessionsRevokedMetadata): Promise<void>;
844
+ }
845
+ /**
846
+ * MFA first enabled metadata
847
+ *
848
+ * Provides context about first MFA device enrollment.
849
+ */
850
+ export interface MFAFirstEnabledMetadata {
851
+ /**
852
+ * User who enabled their first MFA device
853
+ */
854
+ user: IUser;
855
+ /**
856
+ * Type of first MFA device
857
+ */
858
+ firstMethod: import('../enums/mfa-method.enum').MFADeviceMethod;
859
+ /**
860
+ * Device name (optional, user-provided label)
861
+ */
862
+ deviceName?: string;
863
+ /**
864
+ * When MFA was first enforced for this user
865
+ */
866
+ enforcedAt: Date;
867
+ /**
868
+ * Client information (IP address, user agent, location)
869
+ */
870
+ clientInfo?: import('./client-info.interface').ClientInfo;
871
+ }
872
+ /**
873
+ * MFA first enabled hook interface
874
+ *
875
+ * Executes actions when user enables their first MFA device (non-blocking).
876
+ * Errors are logged but do not affect the MFA enrollment operation.
877
+ *
878
+ * @remarks
879
+ * This hook is triggered when:
880
+ * - User enables their first MFA device via `enableMFAForUser()` when `isFirstDevice = true`
881
+ *
882
+ * The hook is non-blocking. If it throws an error, the error is logged
883
+ * but the MFA device has already been enabled when the hook is called.
884
+ *
885
+ * Use cases:
886
+ * - Send confirmation email
887
+ * - Log to audit system
888
+ * - Update onboarding status
889
+ * - Update external systems
890
+ *
891
+ * @example
892
+ * ```typescript
893
+ * export class MFAFirstEnabledConfirmationHook implements IMFAFirstEnabledHook {
894
+ * async execute(metadata: MFAFirstEnabledMetadata): Promise<void> {
895
+ * const { user, firstMethod } = metadata;
896
+ * await this.emailService.sendMFAFirstEnabledEmail(
897
+ * user.email,
898
+ * { method: firstMethod }
899
+ * );
900
+ * }
901
+ * }
902
+ * ```
903
+ */
904
+ export interface IMFAFirstEnabledHook {
905
+ /**
906
+ * Execute MFA first enabled actions
907
+ *
908
+ * @param metadata - MFA enrollment context with user and device details
909
+ */
910
+ execute(metadata: MFAFirstEnabledMetadata): Promise<void>;
911
+ }
912
+ /**
913
+ * MFA method added metadata
914
+ *
915
+ * Provides context when a user adds an additional MFA method (e.g., adding Passkey
916
+ * after already having TOTP enabled).
917
+ */
918
+ export interface MFAMethodAddedMetadata {
919
+ /**
920
+ * User who added an MFA method
921
+ */
922
+ user: IUser;
923
+ /**
924
+ * MFA method that was added
925
+ */
926
+ method: import('../enums/mfa-method.enum').MFADeviceMethod;
927
+ /**
928
+ * Device name (optional, user-provided label)
929
+ */
930
+ deviceName?: string;
931
+ /**
932
+ * Whether this method addition is also the user's first MFA method
933
+ */
934
+ isFirstMethod: boolean;
935
+ /**
936
+ * Enabled MFA methods after the change
937
+ */
938
+ enabledMethods: import('../enums/mfa-method.enum').MFADeviceMethod[];
939
+ /**
940
+ * Event timestamp
941
+ */
942
+ timestamp: Date;
943
+ /**
944
+ * Client information (IP address, user agent, location)
945
+ */
946
+ clientInfo?: import('./client-info.interface').ClientInfo;
947
+ }
948
+ /**
949
+ * MFA method added hook interface
950
+ *
951
+ * Executes actions after a user adds an MFA method (non-blocking).
952
+ * Errors are logged but do not affect the MFA enrollment operation.
953
+ *
954
+ * @example
955
+ * ```typescript
956
+ * export class MFAMethodAddedNotificationHook implements IMFAMethodAddedHook {
957
+ * async execute(metadata: MFAMethodAddedMetadata): Promise<void> {
958
+ * const { user, method, enabledMethods } = metadata;
959
+ * await this.emailService.sendMFAMethodAddedEmail(user.email, {
960
+ * method,
961
+ * enabledMethods,
962
+ * });
963
+ * }
964
+ * }
965
+ * ```
966
+ */
967
+ export interface IMFAMethodAddedHook {
968
+ /**
969
+ * Execute MFA method added actions
970
+ *
971
+ * @param metadata - MFA method addition context
972
+ */
973
+ execute(metadata: MFAMethodAddedMetadata): Promise<void>;
974
+ }
229
975
  //# sourceMappingURL=hooks.interface.d.ts.map