UNPKG

matterbridge-roborock-vacuum-plugin

Version:
83 lines 3.8 kB
import { BaseAuthStrategy } from './BaseAuthStrategy.js'; /** Two-factor authentication strategy with verification code. */ export class TwoFactorAuthStrategy extends BaseAuthStrategy { verificationCodeService; toastMessage; constructor(authService, userDataRepository, verificationCodeService, configManager, toastMessage, logger) { super(authService, userDataRepository, configManager, logger); this.verificationCodeService = verificationCodeService; this.toastMessage = toastMessage; } async authenticate(context) { const cachedUserData = await this.tryAuthenticateWithCachedToken(context.username); if (cachedUserData) { return cachedUserData; } if (!this.hasVerificationCode(context)) { await this.handleVerificationCodeRequest(context.username); return undefined; } return await this.authenticateWithCode(context); } hasVerificationCode(context) { return !!context.verificationCode && context.verificationCode.trim() !== ''; } async handleVerificationCodeRequest(username) { if (await this.verificationCodeService.isRateLimited()) { const waitSeconds = await this.verificationCodeService.getRemainingWaitTime(); this.logger.warn(`Please wait ${waitSeconds} seconds before requesting another code.`); this.logVerificationCodeBanner(username, true); return; } await this.requestVerificationCode(username); } async requestVerificationCode(username) { try { this.logger.notice(`Requesting verification code for: ${username}`); await this.verificationCodeService.requestVerificationCode(username); await this.verificationCodeService.recordCodeRequest(username); this.logVerificationCodeBanner(username, false); } catch (error) { this.logger.error(`Failed to request verification code: ${this.formatError(error)}`); throw error; } } async authenticateWithCode(context) { if (!context.verificationCode) { throw new Error('Verification code is required for authentication.'); } this.logger.notice('Attempting login with verification code...'); const userData = await this.authService.loginWithVerificationCode(context.username, context.verificationCode.trim()); await this.saveAuthenticationState(userData, context.username); this.logger.notice('Authentication successful!'); return userData; } async saveAuthenticationState(userData, username) { userData.username = username; try { await this.userDataRepository.saveUserData(userData); } catch (saveError) { this.logger.warn('Failed to save user data, but login succeeded:', saveError); } try { await this.verificationCodeService.clearCodeRequestState(); } catch (clearError) { this.logger.warn('Failed to clear auth state, but login succeeded:', clearError); } } /** Display verification code banner instructions to user. */ logVerificationCodeBanner(email, wasPreviouslySent) { const message = `============================================ ACTION REQUIRED: Enter verification code A verification code ${wasPreviouslySent ? 'was previously sent' : 'has been sent'} to: ${email} Enter the 6-digit code in the plugin configuration under the "verificationCode" field, then restart the plugin. ============================================`; this.logger.notice(message); this.toastMessage(message, 60 * 1000, 'warning'); } } //# sourceMappingURL=TwoFactorAuthStrategy.js.map