diff --git a/background.js b/background.js index cd30150..258e4ae 100644 --- a/background.js +++ b/background.js @@ -28,7 +28,7 @@ const HOTMAIL_MAILBOXES = ['INBOX', 'Junk']; const STOP_ERROR_MESSAGE = '流程已被用户停止。'; const HUMAN_STEP_DELAY_MIN = 700; const HUMAN_STEP_DELAY_MAX = 2200; -const STEP7_RESTART_MAX_ROUNDS = 8; +const STEP7_MAIL_POLLING_RECOVERY_MAX_ATTEMPTS = 8; const SUB2API_STEP1_RESPONSE_TIMEOUT_MS = 90000; const SUB2API_STEP9_RESPONSE_TIMEOUT_MS = 120000; const DEFAULT_SUB2API_URL = 'https://sub2api.hisence.fun/admin/accounts'; @@ -2208,10 +2208,6 @@ function isStep7RestartFromStep6Error(error) { || Boolean(parseStep7RestartFromStep6Marker(error)); } -function isStep7RecoverableError(error) { - return isVerificationMailPollingError(error) || isStep7RestartFromStep6Error(error); -} - function isRestartCurrentAttemptError(error) { const message = String(typeof error === 'string' ? error : error?.message || ''); return /当前邮箱已存在,需要重新开始新一轮/.test(message); @@ -5227,43 +5223,48 @@ async function rerunStep6ForStep7Recovery() { } async function executeStep7(state) { - let lastError = null; - - for (let round = 1; round <= STEP7_RESTART_MAX_ROUNDS; round++) { - const currentState = round === 1 ? state : await getState(); + let currentState = state; + let mailPollingAttempt = 1; + let lastMailPollingError = null; + while (true) { try { - if (round > 1) { - await addLog(`步骤 7:正在进行第 ${round}/${STEP7_RESTART_MAX_ROUNDS} 轮登录验证码恢复尝试。`, 'warn'); - } await runStep7Attempt(currentState); return; } catch (err) { - lastError = err; + if (isStep7RestartFromStep6Error(err)) { + await addLog('步骤 7:检测到登录页超时报错,准备从步骤 6 重新开始...', 'warn'); + await rerunStep6ForStep7Recovery(); + currentState = await getState(); + continue; + } - if (!isStep7RecoverableError(err)) { + if (!isVerificationMailPollingError(err)) { throw err; } - if (round >= STEP7_RESTART_MAX_ROUNDS) { + lastMailPollingError = err; + if (mailPollingAttempt >= STEP7_MAIL_POLLING_RECOVERY_MAX_ATTEMPTS) { break; } + mailPollingAttempt += 1; await addLog( - isStep7RestartFromStep6Error(err) - ? `步骤 7:检测到登录页超时报错,准备从步骤 6 重新开始(${round + 1}/${STEP7_RESTART_MAX_ROUNDS})...` - : `步骤 7:检测到邮箱轮询类失败,准备从步骤 6 重新开始(${round + 1}/${STEP7_RESTART_MAX_ROUNDS})...`, + `步骤 7:检测到邮箱轮询类失败,准备从步骤 6 重新开始(${mailPollingAttempt}/${STEP7_MAIL_POLLING_RECOVERY_MAX_ATTEMPTS})...`, 'warn' ); await rerunStep6ForStep7Recovery(); + currentState = await getState(); } } - if (lastError && isStep7RecoverableError(lastError)) { - throw new Error(`步骤 7:登录验证码流程在 ${STEP7_RESTART_MAX_ROUNDS} 轮恢复后仍未成功。最后一次原因:${lastError.message}`); + if (lastMailPollingError) { + throw new Error( + `步骤 7:登录验证码流程在 ${STEP7_MAIL_POLLING_RECOVERY_MAX_ATTEMPTS} 轮邮箱轮询恢复后仍未成功。最后一次原因:${lastMailPollingError.message}` + ); } - throw lastError || new Error(`步骤 7:登录验证码流程在 ${STEP7_RESTART_MAX_ROUNDS} 轮后仍未成功。`); + throw new Error('步骤 7:登录验证码流程未成功完成。'); } // ============================================================ diff --git a/content/signup-page.js b/content/signup-page.js index 73fe7b4..ea2de6b 100644 --- a/content/signup-page.js +++ b/content/signup-page.js @@ -529,10 +529,6 @@ function isAddPhonePageReady() { return ADD_PHONE_PAGE_PATTERN.test(getPageTextSnapshot()); } -function isLoginPage() { - return /\/log-in(?:[/?#]|$)/i.test(location.pathname || ''); -} - function isStep8Ready() { const continueBtn = getPrimaryContinueButton(); if (!continueBtn) return false; @@ -691,19 +687,51 @@ function getAuthRetryButton({ allowDisabled = false } = {}) { }) || null; } -function matchesAuthTimeoutErrorPage(pathPattern) { - if (!pathPattern.test(location.pathname || '')) return false; +function getAuthTimeoutErrorPageState(options = {}) { + const { pathPatterns = [] } = options; + const path = location.pathname || ''; + if (pathPatterns.length && !pathPatterns.some((pattern) => pattern.test(path))) { + return null; + } + + const retryButton = getAuthRetryButton({ allowDisabled: true }); + if (!retryButton) { + return null; + } + const text = getPageTextSnapshot(); - return Boolean( - getAuthRetryButton({ allowDisabled: true }) - && (AUTH_TIMEOUT_ERROR_TITLE_PATTERN.test(text) - || AUTH_TIMEOUT_ERROR_DETAIL_PATTERN.test(text) - || AUTH_TIMEOUT_ERROR_TITLE_PATTERN.test(document.title || '')) - ); + const titleMatched = AUTH_TIMEOUT_ERROR_TITLE_PATTERN.test(text) + || AUTH_TIMEOUT_ERROR_TITLE_PATTERN.test(document.title || ''); + const detailMatched = AUTH_TIMEOUT_ERROR_DETAIL_PATTERN.test(text); + + if (!titleMatched && !detailMatched) { + return null; + } + + return { + path, + url: location.href, + retryButton, + retryEnabled: isActionEnabled(retryButton), + titleMatched, + detailMatched, + }; +} + +function getSignupPasswordTimeoutErrorPageState() { + return getAuthTimeoutErrorPageState({ + pathPatterns: [/\/create-account\/password(?:[/?#]|$)/i], + }); +} + +function getLoginTimeoutErrorPageState() { + return getAuthTimeoutErrorPageState({ + pathPatterns: [/\/log-in(?:[/?#]|$)/i], + }); } function isSignupPasswordErrorPage() { - return matchesAuthTimeoutErrorPage(/\/create-account\/password(?:[/?#]|$)/i); + return Boolean(getSignupPasswordTimeoutErrorPageState()); } function buildStep7RestartFromStep6Marker(reason, url = location.href) { @@ -711,15 +739,16 @@ function buildStep7RestartFromStep6Marker(reason, url = location.href) { } function getStep7RestartFromStep6Signal() { - if (!isLoginPage() || !matchesAuthTimeoutErrorPage(/\/log-in(?:[/?#]|$)/i)) { + const timeoutPage = getLoginTimeoutErrorPageState(); + if (!timeoutPage) { return null; } return { - error: buildStep7RestartFromStep6Marker('login_timeout_error_page', location.href), + error: buildStep7RestartFromStep6Marker('login_timeout_error_page', timeoutPage.url), restartFromStep6: true, reason: 'login_timeout_error_page', - url: location.href, + url: timeoutPage.url, }; } @@ -737,9 +766,10 @@ function inspectSignupVerificationState() { } if (isSignupPasswordErrorPage()) { + const timeoutPage = getSignupPasswordTimeoutErrorPageState(); return { state: 'error', - retryButton: getAuthRetryButton({ allowDisabled: true }), + retryButton: timeoutPage?.retryButton || null, }; }