Merge commit 'c98715a4bc17b249639a7844ad8561aec261da87' into dev

# Conflicts:
#	sidepanel/sidepanel.js
This commit is contained in:
QLHazyCoder
2026-04-14 23:53:44 +08:00
9 changed files with 1388 additions and 19 deletions
+421 -12
View File
@@ -1,6 +1,6 @@
// background.js — Service Worker: orchestration, state, tab management, message routing
importScripts('data/names.js', 'hotmail-utils.js', 'content/activation-utils.js');
importScripts('data/names.js', 'hotmail-utils.js', 'cloudflare-temp-email-utils.js', 'content/activation-utils.js');
const {
buildHotmailMailApiLatestUrl,
@@ -17,6 +17,17 @@ const {
pickVerificationMessageWithTimeFallback,
shouldClearHotmailCurrentSelection,
} = self.HotmailUtils;
const {
DEFAULT_MAIL_PAGE_SIZE: CLOUDFLARE_TEMP_EMAIL_DEFAULT_PAGE_SIZE,
buildCloudflareTempEmailHeaders,
getCloudflareTempEmailAddressFromResponse,
joinCloudflareTempEmailUrl,
normalizeCloudflareTempEmailAddress,
normalizeCloudflareTempEmailBaseUrl,
normalizeCloudflareTempEmailDomain,
normalizeCloudflareTempEmailDomains,
normalizeCloudflareTempEmailMailApiMessages,
} = self.CloudflareTempEmailUtils;
const {
isRecoverableStep9AuthFailure,
} = self.MultiPageActivationUtils;
@@ -24,6 +35,8 @@ const {
const LOG_PREFIX = '[MultiPage:bg]';
const DUCK_AUTOFILL_URL = 'https://duckduckgo.com/email/settings/autofill';
const HOTMAIL_PROVIDER = 'hotmail-api';
const CLOUDFLARE_TEMP_EMAIL_PROVIDER = 'cloudflare-temp-email';
const CLOUDFLARE_TEMP_EMAIL_GENERATOR = 'cloudflare-temp-email';
const HOTMAIL_MAILBOXES = ['INBOX', 'Junk'];
const STOP_ERROR_MESSAGE = '流程已被用户停止。';
const HUMAN_STEP_DELAY_MIN = 700;
@@ -85,6 +98,11 @@ const PERSISTED_SETTING_DEFAULTS = {
hotmailLocalBaseUrl: DEFAULT_HOTMAIL_LOCAL_BASE_URL,
cloudflareDomain: '',
cloudflareDomains: [],
cloudflareTempEmailBaseUrl: '',
cloudflareTempEmailAdminAuth: '',
cloudflareTempEmailCustomAuth: '',
cloudflareTempEmailDomain: '',
cloudflareTempEmailDomains: [],
hotmailAccounts: [],
};
@@ -222,9 +240,8 @@ function normalizeEmailGenerator(value = '') {
if (normalized === 'custom' || normalized === 'manual') {
return 'custom';
}
if (normalized === 'cloudflare') {
return 'cloudflare';
}
if (normalized === 'cloudflare') return 'cloudflare';
if (normalized === CLOUDFLARE_TEMP_EMAIL_GENERATOR) return CLOUDFLARE_TEMP_EMAIL_GENERATOR;
return 'duck';
}
@@ -237,6 +254,7 @@ function normalizeMailProvider(value = '') {
switch (normalized) {
case 'custom':
case HOTMAIL_PROVIDER:
case CLOUDFLARE_TEMP_EMAIL_PROVIDER:
case '163':
case '163-vip':
case 'qq':
@@ -340,6 +358,16 @@ function getHotmailServiceSettings(state = {}) {
};
}
function getCloudflareTempEmailConfig(state = {}) {
return {
baseUrl: normalizeCloudflareTempEmailBaseUrl(state.cloudflareTempEmailBaseUrl),
adminAuth: String(state.cloudflareTempEmailAdminAuth || ''),
customAuth: String(state.cloudflareTempEmailCustomAuth || ''),
domain: normalizeCloudflareTempEmailDomain(state.cloudflareTempEmailDomain),
domains: normalizeCloudflareTempEmailDomains(state.cloudflareTempEmailDomains),
};
}
function normalizePersistentSettingValue(key, value) {
switch (key) {
case 'panelMode':
@@ -391,6 +419,15 @@ function normalizePersistentSettingValue(key, value) {
return normalizeCloudflareDomain(value);
case 'cloudflareDomains':
return normalizeCloudflareDomains(value);
case 'cloudflareTempEmailBaseUrl':
return normalizeCloudflareTempEmailBaseUrl(value);
case 'cloudflareTempEmailAdminAuth':
case 'cloudflareTempEmailCustomAuth':
return String(value || '');
case 'cloudflareTempEmailDomain':
return normalizeCloudflareTempEmailDomain(value);
case 'cloudflareTempEmailDomains':
return normalizeCloudflareTempEmailDomains(value);
case 'hotmailAccounts':
return normalizeHotmailAccounts(value);
default:
@@ -434,6 +471,13 @@ function buildPersistentSettingsPayload(input = {}, options = {}) {
}
payload.cloudflareDomains = domains;
}
if (payload.cloudflareTempEmailDomains) {
const domains = normalizeCloudflareTempEmailDomains(payload.cloudflareTempEmailDomains);
if (payload.cloudflareTempEmailDomain && !domains.includes(payload.cloudflareTempEmailDomain)) {
domains.unshift(payload.cloudflareTempEmailDomain);
}
payload.cloudflareTempEmailDomains = domains;
}
return payload;
}
@@ -1327,6 +1371,120 @@ function buildGeneratedAliasEmail(state) {
throw new Error(`未支持的别名邮箱类型:${provider}`);
}
function summarizeCloudflareTempEmailMessagesForLog(messages) {
return (messages || [])
.slice()
.sort((left, right) => {
const leftTime = Date.parse(left.receivedDateTime || '') || 0;
const rightTime = Date.parse(right.receivedDateTime || '') || 0;
return rightTime - leftTime;
})
.slice(0, 3)
.map((message) => {
const receivedAt = message?.receivedDateTime || '未知时间';
const sender = message?.from?.emailAddress?.address || '未知发件人';
const subject = message?.subject || '(无主题)';
const preview = String(message?.bodyPreview || '').replace(/\s+/g, ' ').trim().slice(0, 80);
const address = message?.address || '未知地址';
return `[${address}] ${receivedAt} | ${sender} | ${subject} | ${preview}`;
})
.join(' || ');
}
async function deleteCloudflareTempEmailMail(config, mailId) {
const normalizedMailId = String(mailId || '').trim();
if (!normalizedMailId) return false;
await requestCloudflareTempEmailJson(config, `/admin/mails/${encodeURIComponent(normalizedMailId)}`, {
method: 'DELETE',
});
return true;
}
async function listCloudflareTempEmailMessages(state, options = {}) {
const config = ensureCloudflareTempEmailConfig(state, { requireAdminAuth: true });
const address = normalizeCloudflareTempEmailAddress(options.address);
const payload = await requestCloudflareTempEmailJson(config, '/admin/mails', {
method: 'GET',
searchParams: {
limit: Number(options.limit) || CLOUDFLARE_TEMP_EMAIL_DEFAULT_PAGE_SIZE,
offset: Number(options.offset) || 0,
address,
},
});
const messages = normalizeCloudflareTempEmailMailApiMessages(payload).filter((message) => {
if (!address) return true;
return !message.address || normalizeCloudflareTempEmailAddress(message.address) === address;
});
return { config, messages };
}
async function pollCloudflareTempEmailVerificationCode(step, state, pollPayload = {}) {
const targetEmail = normalizeCloudflareTempEmailAddress(pollPayload.targetEmail || state.email);
if (!targetEmail) {
throw new Error('Cloudflare Temp Email 轮询前缺少目标邮箱地址。');
}
await addLog(`步骤 ${step}:正在轮询 Cloudflare Temp Email 邮件(${targetEmail}...`, 'info');
const maxAttempts = Number(pollPayload.maxAttempts) || 5;
const intervalMs = Number(pollPayload.intervalMs) || 3000;
let lastError = null;
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
throwIfStopped();
try {
const { config, messages } = await listCloudflareTempEmailMessages(state, {
address: targetEmail,
limit: pollPayload.limit || CLOUDFLARE_TEMP_EMAIL_DEFAULT_PAGE_SIZE,
offset: pollPayload.offset || 0,
});
const matchResult = pickVerificationMessageWithTimeFallback(messages, {
afterTimestamp: pollPayload.filterAfterTimestamp || 0,
senderFilters: pollPayload.senderFilters || [],
subjectFilters: pollPayload.subjectFilters || [],
excludeCodes: pollPayload.excludeCodes || [],
});
const match = matchResult.match;
if (match?.code) {
if (matchResult.usedRelaxedFilters) {
const fallbackLabel = matchResult.usedTimeFallback ? '宽松匹配 + 时间回退' : '宽松匹配';
await addLog(`步骤 ${step}:严格规则未命中,已改用 ${fallbackLabel} 并命中 Cloudflare Temp Email 验证码。`, 'warn');
}
try {
await deleteCloudflareTempEmailMail(config, match.message?.id);
} catch (err) {
await addLog(`步骤 ${step}:删除 Cloudflare Temp Email 邮件失败:${err.message}`, 'warn');
}
return {
ok: true,
code: match.code,
emailTimestamp: match.receivedAt || Date.now(),
mailId: match.message?.id || '',
};
}
lastError = new Error(`步骤 ${step}:暂未在 Cloudflare Temp Email 中找到匹配验证码(${attempt}/${maxAttempts})。`);
await addLog(lastError.message, attempt === maxAttempts ? 'warn' : 'info');
const sample = summarizeCloudflareTempEmailMessagesForLog(messages);
if (sample) {
await addLog(`步骤 ${step}:最近邮件样本:${sample}`, 'info');
}
} catch (err) {
lastError = err;
await addLog(`步骤 ${step}Cloudflare Temp Email 轮询失败:${err.message}`, 'warn');
}
if (attempt < maxAttempts) {
await sleepWithStop(intervalMs);
}
}
throw lastError || new Error(`步骤 ${step}:未在 Cloudflare Temp Email 中找到新的匹配验证码。`);
}
// ============================================================
// Tab Registry
// ============================================================
@@ -1557,11 +1715,14 @@ function buildLocalhostCleanupPrefix(rawUrl) {
async function closeTabsByUrlPrefix(prefix, options = {}) {
if (!prefix) return 0;
const { excludeTabIds = [] } = options;
const { excludeTabIds = [], excludeUrls = [], excludeLocalhostCallbacks = false } = options;
const excluded = new Set(excludeTabIds.filter(id => Number.isInteger(id)));
const excludedUrls = new Set((Array.isArray(excludeUrls) ? excludeUrls : []).filter(Boolean));
const tabs = await chrome.tabs.query({});
const matchedIds = tabs
.filter((tab) => Number.isInteger(tab.id) && !excluded.has(tab.id))
.filter((tab) => typeof tab.url === 'string' && !excludedUrls.has(tab.url))
.filter((tab) => !(excludeLocalhostCallbacks && isLocalhostOAuthCallbackUrl(tab.url)))
.filter((tab) => typeof tab.url === 'string' && tab.url.startsWith(prefix))
.map((tab) => tab.id);
@@ -2149,6 +2310,7 @@ function getSourceLabel(source) {
'inbucket-mail': 'Inbucket 邮箱',
'duck-mail': 'Duck 邮箱',
'hotmail-api': 'Hotmail(远程/本地)',
'cloudflare-temp-email': 'Cloudflare Temp Email',
};
return labels[source] || source || '未知来源';
}
@@ -3166,7 +3328,10 @@ async function handleStepData(step, payload) {
}
const localhostPrefix = buildLocalhostCleanupPrefix(payload.localhostUrl);
if (localhostPrefix) {
await closeTabsByUrlPrefix(localhostPrefix);
await closeTabsByUrlPrefix(localhostPrefix, {
excludeUrls: [payload.localhostUrl],
excludeLocalhostCallbacks: true,
});
}
if (shouldUseCustomRegistrationEmail(latestState) && latestState.email) {
await setEmailStateSilently(null);
@@ -3459,7 +3624,9 @@ function getEmailGeneratorLabel(generator) {
if (generator === 'custom') {
return '自定义邮箱';
}
return generator === 'cloudflare' ? 'Cloudflare 邮箱' : 'Duck 邮箱';
if (generator === 'cloudflare') return 'Cloudflare 邮箱';
if (generator === CLOUDFLARE_TEMP_EMAIL_GENERATOR) return 'Cloudflare Temp Email';
return 'Duck 邮箱';
}
function generateCloudflareAliasLocalPart() {
@@ -3499,6 +3666,107 @@ async function fetchCloudflareEmail(state, options = {}) {
return aliasEmail;
}
function ensureCloudflareTempEmailConfig(state, options = {}) {
const {
requireAdminAuth = false,
requireDomain = false,
} = options;
const config = getCloudflareTempEmailConfig(state);
if (!config.baseUrl) {
throw new Error('Cloudflare Temp Email 服务地址为空或格式无效。');
}
if (requireAdminAuth && !config.adminAuth) {
throw new Error('Cloudflare Temp Email 缺少 Admin Auth。');
}
if (requireDomain && !config.domain) {
throw new Error('Cloudflare Temp Email 域名为空或格式无效。');
}
return config;
}
async function requestCloudflareTempEmailJson(config, path, options = {}) {
const {
method = 'GET',
payload,
searchParams,
timeoutMs = 20000,
} = options;
const url = new URL(joinCloudflareTempEmailUrl(config.baseUrl, path));
if (searchParams && typeof searchParams === 'object') {
for (const [key, value] of Object.entries(searchParams)) {
if (value === undefined || value === null || value === '') continue;
url.searchParams.set(key, String(value));
}
}
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(new Error('timeout')), timeoutMs);
let response;
try {
response = await fetch(url.toString(), {
method,
headers: buildCloudflareTempEmailHeaders(config, {
json: payload !== undefined,
}),
body: payload !== undefined ? JSON.stringify(payload) : undefined,
signal: controller.signal,
});
} catch (err) {
const errorMessage = err?.name === 'AbortError'
? `Cloudflare Temp Email 请求超时(>${Math.round(timeoutMs / 1000)} 秒)`
: `Cloudflare Temp Email 请求失败:${err.message}`;
throw new Error(errorMessage);
} finally {
clearTimeout(timeoutId);
}
const text = await response.text();
let parsed;
try {
parsed = text ? JSON.parse(text) : {};
} catch {
parsed = text;
}
if (!response.ok) {
const payloadError = typeof parsed === 'object' && parsed
? (parsed.message || parsed.error || parsed.msg)
: '';
throw new Error(`Cloudflare Temp Email 请求失败:${payloadError || text || `HTTP ${response.status}`}`);
}
return parsed;
}
async function fetchCloudflareTempEmailAddress(state, options = {}) {
throwIfStopped();
const latestState = state || await getState();
const config = ensureCloudflareTempEmailConfig(latestState, {
requireAdminAuth: true,
requireDomain: true,
});
const requestedName = String(options.localPart || options.name || '').trim().toLowerCase() || generateCloudflareAliasLocalPart();
const payload = {
enablePrefix: true,
name: requestedName,
domain: config.domain,
};
const result = await requestCloudflareTempEmailJson(config, '/admin/new_address', {
method: 'POST',
payload,
});
const address = normalizeCloudflareTempEmailAddress(getCloudflareTempEmailAddressFromResponse(result));
if (!address) {
throw new Error('Cloudflare Temp Email 未返回可用邮箱地址。');
}
await setEmailState(address);
await addLog(`Cloudflare Temp Email:已生成 ${address}`, 'ok');
return address;
}
async function fetchDuckEmail(options = {}) {
throwIfStopped();
const { generateNew = true } = options;
@@ -3533,6 +3801,9 @@ async function fetchGeneratedEmail(state, options = {}) {
if (generator === 'cloudflare') {
return fetchCloudflareEmail(currentState, options);
}
if (generator === CLOUDFLARE_TEMP_EMAIL_GENERATOR) {
return fetchCloudflareTempEmailAddress(currentState, options);
}
return fetchDuckEmail(options);
}
@@ -3546,6 +3817,7 @@ let autoRunTotalRuns = 1;
let autoRunAttemptRun = 0;
const EMAIL_FETCH_MAX_ATTEMPTS = 5;
const VERIFICATION_POLL_MAX_ROUNDS = 5;
const STANDARD_MAIL_VERIFICATION_RESEND_INTERVAL_MS = 25000;
const AUTO_STEP_DELAYS = {
1: 2000,
2: 2000,
@@ -3635,7 +3907,10 @@ async function ensureAutoEmailReady(targetRun, totalRuns, attemptRuns) {
} catch (err) {
lastError = err;
await addLog(`${generatorLabel}自动获取失败(${attempt}/${EMAIL_FETCH_MAX_ATTEMPTS}):${err.message}`, 'warn');
if (generator === 'cloudflare' && /域名/.test(String(err.message || ''))) {
if (
(generator === 'cloudflare' && /域名/.test(String(err.message || '')))
|| (generator === CLOUDFLARE_TEMP_EMAIL_GENERATOR && /(服务地址|Admin Auth|域名)/.test(String(err.message || '')))
) {
break;
}
}
@@ -4757,6 +5032,9 @@ function getMailConfig(state) {
if (provider === HOTMAIL_PROVIDER) {
return { provider: HOTMAIL_PROVIDER, label: 'Hotmail(远程/本地)' };
}
if (provider === CLOUDFLARE_TEMP_EMAIL_PROVIDER) {
return { provider: CLOUDFLARE_TEMP_EMAIL_PROVIDER, label: 'Cloudflare Temp Email' };
}
if (provider === '163') {
return { source: 'mail-163', url: 'https://mail.163.com/js6/main.jsp?df=mail163_letter#module=mbox.ListModule%7C%7B%22fid%22%3A1%2C%22order%22%3A%22date%22%2C%22desc%22%3Atrue%7D', label: '163 邮箱' };
}
@@ -4921,6 +5199,16 @@ async function pollFreshVerificationCode(step, state, mail, pollOverrides = {})
...pollOverrides,
});
}
if (mail.provider === CLOUDFLARE_TEMP_EMAIL_PROVIDER) {
return pollCloudflareTempEmailVerificationCode(step, state, {
...getVerificationPollPayload(step, state),
...pollOverrides,
});
}
if (Number(pollOverrides.resendIntervalMs) > 0) {
return pollFreshVerificationCodeWithResendInterval(step, state, mail, pollOverrides);
}
const stateKey = getVerificationCodeStateKey(step);
const rejectedCodes = new Set();
@@ -4990,6 +5278,109 @@ async function pollFreshVerificationCode(step, state, mail, pollOverrides = {})
throw lastError || new Error(`步骤 ${step}:无法获取新的${getVerificationCodeLabel(step)}验证码。`);
}
async function pollFreshVerificationCodeWithResendInterval(step, state, mail, pollOverrides = {}) {
const stateKey = getVerificationCodeStateKey(step);
const rejectedCodes = new Set();
if (state[stateKey]) {
rejectedCodes.add(state[stateKey]);
}
for (const code of (pollOverrides.excludeCodes || [])) {
if (code) rejectedCodes.add(code);
}
const {
maxRounds: _ignoredMaxRounds,
resendIntervalMs: _ignoredResendIntervalMs,
lastResendAt: _ignoredLastResendAt,
...payloadOverrides
} = pollOverrides;
let lastError = null;
const filterAfterTimestamp = payloadOverrides.filterAfterTimestamp ?? getVerificationPollPayload(step, state).filterAfterTimestamp;
const maxRounds = pollOverrides.maxRounds || VERIFICATION_POLL_MAX_ROUNDS;
const resendIntervalMs = Math.max(0, Number(pollOverrides.resendIntervalMs) || 0);
let lastResendAt = Number(pollOverrides.lastResendAt) || 0;
for (let round = 1; round <= maxRounds; round++) {
throwIfStopped();
if (round > 1) {
lastResendAt = await requestVerificationCodeResend(step);
}
while (true) {
throwIfStopped();
const payload = getVerificationPollPayload(step, state, {
...payloadOverrides,
filterAfterTimestamp,
excludeCodes: [...rejectedCodes],
});
if (lastResendAt > 0) {
const remainingBeforeResendMs = Math.max(0, resendIntervalMs - (Date.now() - lastResendAt));
const baseMaxAttempts = Math.max(1, Number(payload.maxAttempts) || 5);
const intervalMs = Math.max(1, Number(payload.intervalMs) || 3000);
payload.maxAttempts = Math.max(1, Math.min(baseMaxAttempts, Math.floor(remainingBeforeResendMs / intervalMs) + 1));
}
try {
const result = await sendToMailContentScriptResilient(
mail,
{
type: 'POLL_EMAIL',
step,
source: 'background',
payload,
},
{
timeoutMs: 45000,
maxRecoveryAttempts: 2,
}
);
if (result && result.error) {
throw new Error(result.error);
}
if (!result || !result.code) {
throw new Error(`步骤 ${step}:邮箱轮询结束,但未获取到验证码。`);
}
if (rejectedCodes.has(result.code)) {
throw new Error(`步骤 ${step}:再次收到了相同的${getVerificationCodeLabel(step)}验证码:${result.code}`);
}
return {
...result,
lastResendAt,
};
} catch (err) {
if (isStopError(err)) {
throw err;
}
lastError = err;
await addLog(`步骤 ${step}${err.message}`, 'warn');
}
const remainingBeforeResendMs = lastResendAt > 0
? Math.max(0, resendIntervalMs - (Date.now() - lastResendAt))
: 0;
if (remainingBeforeResendMs > 0) {
await addLog(
`步骤 ${step}:距离下次重新发送验证码还差 ${Math.ceil(remainingBeforeResendMs / 1000)} 秒,继续刷新邮箱(第 ${round}/${maxRounds} 轮)...`,
'info'
);
continue;
}
if (round < maxRounds) {
await addLog(`步骤 ${step}:已到 25 秒重发间隔,准备重新发送验证码(第 ${round + 1}/${maxRounds} 轮)...`, 'warn');
}
break;
}
}
throw lastError || new Error(`步骤 ${step}:无法获取新的${getVerificationCodeLabel(step)}验证码。`);
}
async function submitVerificationCode(step, code) {
const signupTabId = await getTabId('signup-page');
if (!signupTabId) {
@@ -5034,10 +5425,12 @@ async function resolveVerificationStep(step, state, mail, options = {}) {
? Boolean(options.requestFreshCodeFirst)
: (hotmailPollConfig?.requestFreshCodeFirst ?? false);
const maxSubmitAttempts = 3;
const resendIntervalMs = Math.max(0, Number(options.resendIntervalMs) || 0);
let lastResendAt = Number(options.lastResendAt) || 0;
if (requestFreshCodeFirst) {
try {
await requestVerificationCodeResend(step);
lastResendAt = await requestVerificationCodeResend(step);
await addLog(`步骤 ${step}:已先请求一封新的${getVerificationCodeLabel(step)}验证码,再开始轮询邮箱。`, 'warn');
} catch (err) {
if (isStopError(err) || (step === 7 && isStep7RestartFromStep6Error(err))) {
@@ -5059,7 +5452,10 @@ async function resolveVerificationStep(step, state, mail, options = {}) {
const result = await pollFreshVerificationCode(step, state, mail, {
excludeCodes: [...rejectedCodes],
filterAfterTimestamp: nextFilterAfterTimestamp ?? undefined,
resendIntervalMs,
lastResendAt,
});
lastResendAt = Number(result?.lastResendAt) || lastResendAt;
throwIfStopped();
await addLog(`步骤 ${step}:已获取${getVerificationCodeLabel(step)}验证码:${result.code}`);
@@ -5074,7 +5470,18 @@ async function resolveVerificationStep(step, state, mail, options = {}) {
throw new Error(`步骤 ${step}:验证码连续失败,已达到 ${maxSubmitAttempts} 次重试上限。`);
}
await requestVerificationCodeResend(step);
const remainingBeforeResendMs = resendIntervalMs > 0 && lastResendAt > 0
? Math.max(0, resendIntervalMs - (Date.now() - lastResendAt))
: 0;
if (remainingBeforeResendMs > 0) {
await addLog(
`步骤 ${step}:提交失败后距离下次重新发送验证码还差 ${Math.ceil(remainingBeforeResendMs / 1000)} 秒,先继续刷新邮箱(${attempt + 1}/${maxSubmitAttempts}...`,
'warn'
);
continue;
}
lastResendAt = await requestVerificationCodeResend(step);
await addLog(`步骤 ${step}:提交失败后已请求新验证码(${attempt + 1}/${maxSubmitAttempts}...`, 'warn');
continue;
}
@@ -5136,7 +5543,7 @@ async function executeStep4(state) {
}
throwIfStopped();
if (mail.provider === HOTMAIL_PROVIDER) {
if (mail.provider === HOTMAIL_PROVIDER || mail.provider === CLOUDFLARE_TEMP_EMAIL_PROVIDER) {
await addLog(`步骤 4:正在通过 ${mail.label} 轮询验证码...`);
} else {
await addLog(`步骤 4:正在打开${mail.label}...`);
@@ -5164,6 +5571,7 @@ async function executeStep4(state) {
await resolveVerificationStep(4, state, mail, {
filterAfterTimestamp: mail.provider === HOTMAIL_PROVIDER ? undefined : stepStartedAt,
requestFreshCodeFirst: mail.provider === HOTMAIL_PROVIDER ? false : true,
resendIntervalMs: mail.provider === HOTMAIL_PROVIDER ? 0 : STANDARD_MAIL_VERIFICATION_RESEND_INTERVAL_MS,
});
return;
}
@@ -5271,7 +5679,7 @@ async function runStep7Attempt(state) {
}
throwIfStopped();
if (mail.provider === HOTMAIL_PROVIDER) {
if (mail.provider === HOTMAIL_PROVIDER || mail.provider === CLOUDFLARE_TEMP_EMAIL_PROVIDER) {
await addLog(`步骤 7:正在通过 ${mail.label} 轮询验证码...`);
} else {
await addLog(`步骤 7:正在打开${mail.label}...`);
@@ -5298,6 +5706,7 @@ async function runStep7Attempt(state) {
await resolveVerificationStep(7, state, mail, {
filterAfterTimestamp: mail.provider === HOTMAIL_PROVIDER ? undefined : stepStartedAt,
requestFreshCodeFirst: mail.provider === HOTMAIL_PROVIDER ? false : true,
resendIntervalMs: mail.provider === HOTMAIL_PROVIDER ? 0 : STANDARD_MAIL_VERIFICATION_RESEND_INTERVAL_MS,
});
}