import { Repository } from 'typeorm'; import { BaseVerificationToken } from '../entities'; import { EmailProvider, SMSProvider } from '../interfaces/provider.interface'; import { StorageAdapter } from '../interfaces/storage-adapter.interface'; import { NAuthConfig } from '../interfaces/config.interface'; import { ClientInfoService } from './client-info.service'; import { InternalAuthAuditService as AuthAuditService } from './auth-audit.service'; import { NAuthLogger } from '../utils/nauth-logger'; import { IUser } from '../interfaces/entities.interface'; /** * Password Reset Service (Account Recovery) * * Implements the forgot-password flow by issuing a one-time code for password reset and * validating that code when the user confirms the reset. * * Design: * - Uses `BaseVerificationToken` with type `password_reset` * - Rate limits requests to prevent abuse * - Prevents brute force by tracking attempts per token * - Records audit events for security observability * * NOTE: * - This service is intended for internal orchestration via `AuthService`. * - Consumer applications should use `AuthService.forgotPassword()` and * `AuthService.confirmForgotPassword()`. * * @example * ```typescript * await passwordResetService.requestReset(user, 'email'); * await passwordResetService.confirmReset(user, '123456', 'NewPassword123!'); * ``` */ export declare class PasswordResetService { private readonly verificationTokenRepo; private readonly emailProvider; private readonly storageAdapter; private readonly config; private readonly clientInfoService; private readonly logger; private readonly auditService?; private readonly smsProvider?; constructor(verificationTokenRepo: Repository, emailProvider: EmailProvider, storageAdapter: StorageAdapter, config: NAuthConfig, clientInfoService: ClientInfoService, logger: NAuthLogger, auditService?: AuthAuditService | undefined, smsProvider?: SMSProvider | undefined); /** * Request a password reset for the given user. * * Security: * - Rate limited per user * - Invalidates previous unused password reset tokens for the user * - Does not throw for delivery issues (delivery is best-effort; caller should keep responses non-enumerating) * * @param user - Target user * @param delivery - Delivery channel ('email' or 'sms') * @param options - Reset options (baseUrl for link generation) * @returns Delivery metadata (masked destination, medium, expiresIn) * @throws {NAuthException} RATE_LIMIT_PASSWORD_RESET when rate limit exceeded */ requestReset(user: IUser, delivery: 'email' | 'sms', options?: { baseUrl?: string; }): Promise<{ destination?: string; deliveryMedium?: 'email' | 'sms'; expiresIn?: number; }>; /** * Request password reset for admin-initiated workflow. * * Differences from requestReset(): * - No rate limiting (admin bypass) * - Uses token type 'admin_password_reset' * - Sends admin-specific email template * - Supports code + optional link delivery * - Longer default expiry (1 hour vs 15 min) * * @param user - Target user * @param delivery - Delivery channel ('email' or 'sms') * @param options - Reset options (expiresIn, baseUrl) * @returns Delivery metadata with destination, medium, expiry * @throws {NAuthException} Never throws (email delivery errors are non-blocking) * * @example * ```typescript * const result = await passwordResetService.requestAdminReset( * user, * 'email', * { expiresIn: 3600, baseUrl: 'https://myapp.com/reset' } * ); * // result: { destination: 'u***r@example.com', deliveryMedium: 'email', expiresIn: 3600 } * ``` */ requestAdminReset(user: IUser, delivery: 'email' | 'sms', options: { expiresIn: number; baseUrl?: string; }): Promise<{ destination?: string; deliveryMedium?: 'email' | 'sms'; expiresIn?: number; }>; /** * Consume and validate verification code or token. * * Enhanced to support both code (6-10 digits) and token (64-char hex). * Token-based validation has no attempt tracking (single use). * Code-based validation tracks attempts (max 3). * * @param user - Target user * @param codeOrToken - Verification code (short) or token (long) * @param tokenType - Token type ('password_reset' | 'admin_password_reset') * @returns void on success * @throws {NAuthException} PASSWORD_RESET_CODE_INVALID when code/token is invalid * @throws {NAuthException} PASSWORD_RESET_CODE_EXPIRED when token expired * @throws {NAuthException} PASSWORD_RESET_MAX_ATTEMPTS when max attempts exceeded (code only) * * @example * ```typescript * // Validate code * await passwordResetService.consumeValidCode(user, '123456', 'admin_password_reset'); * * // Validate token * await passwordResetService.consumeValidCode(user, '64-char-hex', 'admin_password_reset'); * ``` */ consumeValidCode(user: IUser, codeOrToken: string, tokenType?: 'email' | 'phone' | 'password_reset' | 'admin_password_reset'): Promise; private generateNumericCode; /** * Build a reset link by appending the verification code as a query param. * * Handles existing query params and hash fragments safely. * * @param baseUrl - Base URL provided by the consumer app * @param code - Verification code to append * @returns Full reset link with `code` query param * * @example * ```typescript * const link = this.buildResetLink('https://app.com/reset?from=admin', '123456'); * // https://app.com/reset?from=admin&code=123456 * ``` */ private buildResetLink; private generateToken; private hashToken; private maskEmail; private maskPhone; } //# sourceMappingURL=password-reset.service.d.ts.map