cf2a720531
- 回退非必要的 2925 行为改动,仅保留已验证有效的修复 - 保留 bounce 转发地址解析、中文日期解析与邮箱页复用时的 ready 恢复 - 同步最小化测试断言,保持当前代码与测试一致
267 lines
10 KiB
JavaScript
267 lines
10 KiB
JavaScript
(function attachBackgroundStep8(root, factory) {
|
||
root.MultiPageBackgroundStep8 = factory();
|
||
})(typeof self !== 'undefined' ? self : globalThis, function createBackgroundStep8Module() {
|
||
const MAIL_2925_FILTER_LOOKBACK_MS = 10 * 60 * 1000;
|
||
|
||
function createStep8Executor(deps = {}) {
|
||
const {
|
||
addLog,
|
||
chrome,
|
||
CLOUDFLARE_TEMP_EMAIL_PROVIDER,
|
||
confirmCustomVerificationStepBypass,
|
||
ensureMail2925MailboxSession,
|
||
ensureIcloudMailSession,
|
||
ensureStep8VerificationPageReady,
|
||
getOAuthFlowRemainingMs,
|
||
getOAuthFlowStepTimeoutMs,
|
||
getMailConfig,
|
||
getState,
|
||
getTabId,
|
||
HOTMAIL_PROVIDER,
|
||
isTabAlive,
|
||
isVerificationMailPollingError,
|
||
LUCKMAIL_PROVIDER,
|
||
resolveVerificationStep,
|
||
rerunStep7ForStep8Recovery,
|
||
reuseOrCreateTab,
|
||
setState,
|
||
shouldUseCustomRegistrationEmail,
|
||
STANDARD_MAIL_VERIFICATION_RESEND_INTERVAL_MS,
|
||
STEP7_MAIL_POLLING_RECOVERY_MAX_ATTEMPTS,
|
||
throwIfStopped,
|
||
} = deps;
|
||
|
||
function getVisibleStep(state, fallback = 8) {
|
||
const visibleStep = Math.floor(Number(state?.visibleStep) || 0);
|
||
return visibleStep > 0 ? visibleStep : fallback;
|
||
}
|
||
|
||
function getAuthLoginStepForVisibleStep(visibleStep) {
|
||
return visibleStep >= 11 ? 10 : 7;
|
||
}
|
||
|
||
async function getStep8ReadyTimeoutMs(actionLabel, expectedOauthUrl = '', visibleStep = 8) {
|
||
if (typeof getOAuthFlowStepTimeoutMs !== 'function') {
|
||
return 15000;
|
||
}
|
||
|
||
return getOAuthFlowStepTimeoutMs(15000, {
|
||
step: visibleStep,
|
||
actionLabel,
|
||
oauthUrl: expectedOauthUrl,
|
||
});
|
||
}
|
||
|
||
function getStep8RemainingTimeResolver(expectedOauthUrl = '', visibleStep = 8) {
|
||
if (typeof getOAuthFlowRemainingMs !== 'function') {
|
||
return undefined;
|
||
}
|
||
|
||
return async (details = {}) => getOAuthFlowRemainingMs({
|
||
step: visibleStep,
|
||
actionLabel: details.actionLabel || '登录验证码流程',
|
||
oauthUrl: expectedOauthUrl,
|
||
});
|
||
}
|
||
|
||
function normalizeStep8VerificationTargetEmail(value) {
|
||
return String(value || '').trim().toLowerCase();
|
||
}
|
||
|
||
function getExpectedMail2925MailboxEmail(state = {}) {
|
||
if (Boolean(state?.mail2925UseAccountPool)) {
|
||
const currentAccountId = String(state?.currentMail2925AccountId || '').trim();
|
||
const accounts = Array.isArray(state?.mail2925Accounts) ? state.mail2925Accounts : [];
|
||
const currentAccount = accounts.find((account) => String(account?.id || '') === currentAccountId) || null;
|
||
const accountEmail = String(currentAccount?.email || '').trim().toLowerCase();
|
||
if (accountEmail) {
|
||
return accountEmail;
|
||
}
|
||
}
|
||
|
||
return String(state?.mail2925BaseEmail || '').trim().toLowerCase();
|
||
}
|
||
|
||
async function focusOrOpenMailTab(mail) {
|
||
const alive = await isTabAlive(mail.source);
|
||
if (alive) {
|
||
if (mail.navigateOnReuse) {
|
||
await reuseOrCreateTab(mail.source, mail.url, {
|
||
inject: mail.inject,
|
||
injectSource: mail.injectSource,
|
||
});
|
||
return;
|
||
}
|
||
|
||
const tabId = await getTabId(mail.source);
|
||
await chrome.tabs.update(tabId, { active: true });
|
||
return;
|
||
}
|
||
|
||
await reuseOrCreateTab(mail.source, mail.url, {
|
||
inject: mail.inject,
|
||
injectSource: mail.injectSource,
|
||
});
|
||
}
|
||
|
||
async function runStep8Attempt(state) {
|
||
const visibleStep = getVisibleStep(state, 8);
|
||
const mail = getMailConfig(state);
|
||
if (mail.error) throw new Error(mail.error);
|
||
|
||
const stepStartedAt = Date.now();
|
||
const verificationFilterAfterTimestamp = mail.provider === '2925'
|
||
? Math.max(0, stepStartedAt - MAIL_2925_FILTER_LOOKBACK_MS)
|
||
: stepStartedAt;
|
||
const verificationSessionKey = `8:${stepStartedAt}`;
|
||
const authTabId = await getTabId('signup-page');
|
||
|
||
if (authTabId) {
|
||
await chrome.tabs.update(authTabId, { active: true });
|
||
} else {
|
||
if (!state.oauthUrl) {
|
||
throw new Error(`缺少登录用 OAuth 链接,请先完成步骤 ${getAuthLoginStepForVisibleStep(visibleStep)}。`);
|
||
}
|
||
await reuseOrCreateTab('signup-page', state.oauthUrl);
|
||
}
|
||
|
||
throwIfStopped();
|
||
const pageState = await ensureStep8VerificationPageReady({
|
||
visibleStep,
|
||
authLoginStep: getAuthLoginStepForVisibleStep(visibleStep),
|
||
timeoutMs: await getStep8ReadyTimeoutMs('确认登录验证码页已就绪', state?.oauthUrl || '', visibleStep),
|
||
});
|
||
const shouldCompareVerificationEmail = mail.provider !== '2925';
|
||
const displayedVerificationEmail = shouldCompareVerificationEmail
|
||
? normalizeStep8VerificationTargetEmail(pageState?.displayedEmail)
|
||
: '';
|
||
const fixedTargetEmail = shouldCompareVerificationEmail
|
||
? (displayedVerificationEmail || normalizeStep8VerificationTargetEmail(state?.email))
|
||
: '';
|
||
|
||
await setState({
|
||
step8VerificationTargetEmail: displayedVerificationEmail || '',
|
||
});
|
||
|
||
await addLog(`步骤 ${visibleStep}:登录验证码页面已就绪,开始获取验证码。`, 'info');
|
||
if (shouldCompareVerificationEmail && displayedVerificationEmail) {
|
||
await addLog(`步骤 ${visibleStep}:已固定当前验证码页显示邮箱 ${displayedVerificationEmail} 作为后续匹配目标。`, 'info');
|
||
}
|
||
|
||
if (shouldUseCustomRegistrationEmail(state)) {
|
||
await confirmCustomVerificationStepBypass(8, {
|
||
completionStep: visibleStep,
|
||
promptStep: visibleStep,
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (mail.source === 'icloud-mail' && typeof ensureIcloudMailSession === 'function') {
|
||
await addLog(`步骤 ${visibleStep}:正在确认 iCloud 邮箱登录态...`, 'info');
|
||
await ensureIcloudMailSession({
|
||
state,
|
||
step: 8,
|
||
actionLabel: `步骤 ${visibleStep}:确认 iCloud 邮箱登录态`,
|
||
});
|
||
}
|
||
|
||
throwIfStopped();
|
||
if (
|
||
mail.provider === HOTMAIL_PROVIDER
|
||
|| mail.provider === LUCKMAIL_PROVIDER
|
||
|| mail.provider === CLOUDFLARE_TEMP_EMAIL_PROVIDER
|
||
) {
|
||
await addLog(`步骤 ${visibleStep}:正在通过 ${mail.label} 轮询验证码...`);
|
||
} else {
|
||
await addLog(`步骤 ${visibleStep}:正在打开${mail.label}...`);
|
||
if (mail.provider === '2925' && typeof ensureMail2925MailboxSession === 'function') {
|
||
await ensureMail2925MailboxSession({
|
||
accountId: state.currentMail2925AccountId || null,
|
||
forceRelogin: false,
|
||
allowLoginWhenOnLoginPage: Boolean(state?.mail2925UseAccountPool),
|
||
expectedMailboxEmail: getExpectedMail2925MailboxEmail(state),
|
||
actionLabel: `Step ${visibleStep}: ensure 2925 mailbox session`,
|
||
});
|
||
} else {
|
||
await focusOrOpenMailTab(mail);
|
||
}
|
||
if (mail.provider === '2925') {
|
||
await addLog(`步骤 ${visibleStep}:将直接使用当前已登录的 ${mail.label} 轮询验证码。`, 'info');
|
||
}
|
||
}
|
||
|
||
await resolveVerificationStep(8, {
|
||
...state,
|
||
step8VerificationTargetEmail: displayedVerificationEmail || '',
|
||
}, mail, {
|
||
completionStep: visibleStep,
|
||
filterAfterTimestamp: verificationFilterAfterTimestamp,
|
||
sessionKey: verificationSessionKey,
|
||
disableTimeBudgetCap: mail.provider === '2925',
|
||
getRemainingTimeMs: getStep8RemainingTimeResolver(state?.oauthUrl || '', visibleStep),
|
||
requestFreshCodeFirst: false,
|
||
targetEmail: fixedTargetEmail,
|
||
resendIntervalMs: (mail.provider === HOTMAIL_PROVIDER || mail.provider === '2925')
|
||
? 0
|
||
: STANDARD_MAIL_VERIFICATION_RESEND_INTERVAL_MS,
|
||
});
|
||
}
|
||
|
||
function isStep8RestartStep7Error(error) {
|
||
const message = String(error?.message || error || '');
|
||
return /STEP8_RESTART_STEP7::/i.test(message);
|
||
}
|
||
|
||
async function executeStep8(state) {
|
||
let currentState = state;
|
||
let mailPollingAttempt = 1;
|
||
let lastMailPollingError = null;
|
||
|
||
while (true) {
|
||
try {
|
||
await runStep8Attempt(currentState);
|
||
return;
|
||
} catch (err) {
|
||
const visibleStep = getVisibleStep(currentState, 8);
|
||
const authLoginStep = getAuthLoginStepForVisibleStep(visibleStep);
|
||
if (!isVerificationMailPollingError(err) && !isStep8RestartStep7Error(err)) {
|
||
throw err;
|
||
}
|
||
|
||
lastMailPollingError = err;
|
||
if (mailPollingAttempt >= STEP7_MAIL_POLLING_RECOVERY_MAX_ATTEMPTS) {
|
||
break;
|
||
}
|
||
|
||
mailPollingAttempt += 1;
|
||
await addLog(
|
||
isStep8RestartStep7Error(err)
|
||
? `步骤 ${visibleStep}:检测到认证页进入重试/超时报错状态,准备从步骤 ${authLoginStep} 重新开始(${mailPollingAttempt}/${STEP7_MAIL_POLLING_RECOVERY_MAX_ATTEMPTS})...`
|
||
: `步骤 ${visibleStep}:检测到邮箱轮询类失败,准备从步骤 ${authLoginStep} 重新开始(${mailPollingAttempt}/${STEP7_MAIL_POLLING_RECOVERY_MAX_ATTEMPTS})...`,
|
||
'warn'
|
||
);
|
||
await rerunStep7ForStep8Recovery({
|
||
logMessage: isStep8RestartStep7Error(err)
|
||
? `步骤 ${visibleStep}:认证页进入重试/超时报错状态,正在回到步骤 ${authLoginStep} 重新发起登录流程...`
|
||
: `步骤 ${visibleStep}:正在回到步骤 ${authLoginStep},重新发起登录验证码流程...`,
|
||
});
|
||
currentState = await getState();
|
||
}
|
||
}
|
||
|
||
const visibleStep = getVisibleStep(currentState, 8);
|
||
if (lastMailPollingError) {
|
||
throw new Error(
|
||
`步骤 ${visibleStep}:登录验证码流程在 ${STEP7_MAIL_POLLING_RECOVERY_MAX_ATTEMPTS} 轮邮箱轮询恢复后仍未成功。最后一次原因:${lastMailPollingError.message}`
|
||
);
|
||
}
|
||
|
||
throw new Error(`步骤 ${visibleStep}:登录验证码流程未成功完成。`);
|
||
}
|
||
|
||
return { executeStep8 };
|
||
}
|
||
|
||
return { createStep8Executor };
|
||
});
|