matterbridge-roborock-vacuum-plugin
Version:
Matterbridge Roborock Vacuum Plugin
83 lines • 3.8 kB
JavaScript
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