From b71bccaf8ad4c7477a616afffdc846df218ff27d Mon Sep 17 00:00:00 2001 From: Isulew <224964+netcookies@users.noreply.github.com> Date: Mon, 27 Apr 2026 13:57:51 +0800 Subject: [PATCH 1/4] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=202925=20?= =?UTF-8?q?=E6=94=B6=E4=BB=B6=E6=A8=A1=E5=BC=8F=E8=BD=AE=E8=AF=A2=E4=B8=8E?= =?UTF-8?q?=E9=87=8D=E5=A4=8D=E6=B3=A8=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - receive 模式下跳过 2925 邮箱页顶部账号校验 - 解析 bounce 转发地址与中文日期,避免误过滤验证码邮件 - 为内容脚本增加重复注入保护,避免重复声明导致轮询失效 --- background/steps/fetch-login-code.js | 4 ++ background/steps/fetch-signup-code.js | 4 ++ content/mail-2925.js | 60 ++++++++++++++++++++++++++- content/signup-page.js | 2 + content/utils.js | 10 ++--- tests/mail-2925-content.test.js | 1 + 6 files changed, 74 insertions(+), 7 deletions(-) diff --git a/background/steps/fetch-login-code.js b/background/steps/fetch-login-code.js index c25b2f4..41b0e3b 100644 --- a/background/steps/fetch-login-code.js +++ b/background/steps/fetch-login-code.js @@ -69,6 +69,10 @@ } function getExpectedMail2925MailboxEmail(state = {}) { + if (String(state?.mail2925Mode || '').trim().toLowerCase() === 'receive') { + return ''; + } + if (Boolean(state?.mail2925UseAccountPool)) { const currentAccountId = String(state?.currentMail2925AccountId || '').trim(); const accounts = Array.isArray(state?.mail2925Accounts) ? state.mail2925Accounts : []; diff --git a/background/steps/fetch-signup-code.js b/background/steps/fetch-signup-code.js index 88778a3..791d0c2 100644 --- a/background/steps/fetch-signup-code.js +++ b/background/steps/fetch-signup-code.js @@ -26,6 +26,10 @@ } = deps; function getExpectedMail2925MailboxEmail(state = {}) { + if (String(state?.mail2925Mode || '').trim().toLowerCase() === 'receive') { + return ''; + } + if (Boolean(state?.mail2925UseAccountPool)) { const currentAccountId = String(state?.currentMail2925AccountId || '').trim(); const accounts = Array.isArray(state?.mail2925Accounts) ? state.mail2925Accounts : []; diff --git a/content/mail-2925.js b/content/mail-2925.js index 1e698c4..4b723e2 100644 --- a/content/mail-2925.js +++ b/content/mail-2925.js @@ -1,6 +1,13 @@ // content/mail-2925.js - Content script for 2925 Mail (steps 4, 8) // Injected dynamically on: 2925.com +(function initMail2925ContentScript() { +if (window.__MULTIPAGE_MAIL2925_SCRIPT_LOADED__) { + console.log('[MultiPage:mail-2925] Duplicate injection skipped on', location.href); + return; +} +window.__MULTIPAGE_MAIL2925_SCRIPT_LOADED__ = true; + const MAIL2925_PREFIX = '[MultiPage:mail-2925]'; const isTopFrame = window === window.top; @@ -699,10 +706,29 @@ function extractEmails(text = '') { return [...new Set(matches.map((item) => item.toLowerCase()))]; } +function extractForwardedTargetEmails(text = '') { + const normalizedText = String(text || '').toLowerCase(); + const matches = normalizedText.match(/bounce\+[a-z0-9._%+-]*-([a-z0-9._%+-]+)=([a-z0-9.-]+\.[a-z]{2,})@(?:tm\d*\.openai\.com|em\d+\.tm\.openai\.com)/gi) || []; + const decoded = matches + .map((candidate) => { + const match = String(candidate || '').match(/bounce\+[a-z0-9._%+-]*-([a-z0-9._%+-]+)=([a-z0-9.-]+\.[a-z]{2,})@/i); + if (!match) { + return ''; + } + return `${match[1].toLowerCase()}@${match[2].toLowerCase()}`; + }) + .filter(Boolean); + return [...new Set(decoded)]; +} + function emailMatchesTarget(candidate, targetEmail) { const normalizedCandidate = String(candidate || '').trim().toLowerCase(); const normalizedTarget = String(targetEmail || '').trim().toLowerCase(); - return Boolean(normalizedCandidate && normalizedTarget && normalizedCandidate === normalizedTarget); + if (!normalizedCandidate || !normalizedTarget) { + return false; + } + + return normalizedCandidate === normalizedTarget; } function getTargetEmailMatchState(text, targetEmail) { @@ -717,12 +743,30 @@ function getTargetEmailMatchState(text, targetEmail) { } const extractedEmails = extractEmails(normalizedText); + const forwardedTargetEmails = extractForwardedTargetEmails(normalizedText); if (!extractedEmails.length) { + return forwardedTargetEmails.length + ? { + matches: forwardedTargetEmails.some((candidate) => emailMatchesTarget(candidate, normalizedTarget)), + hasExplicitEmail: true, + } + : { matches: true, hasExplicitEmail: false }; + } + + const targetDomain = normalizedTarget.includes('@') + ? normalizedTarget.split('@').pop() + : ''; + const comparableEmails = [...new Set( + (targetDomain + ? [...extractedEmails, ...forwardedTargetEmails].filter((candidate) => String(candidate || '').trim().toLowerCase().endsWith(`@${targetDomain}`)) + : [...extractedEmails, ...forwardedTargetEmails]) + )]; + if (!comparableEmails.length) { return { matches: true, hasExplicitEmail: false }; } return { - matches: extractedEmails.some((candidate) => emailMatchesTarget(candidate, normalizedTarget)), + matches: comparableEmails.some((candidate) => emailMatchesTarget(candidate, normalizedTarget)), hasExplicitEmail: true, }; } @@ -782,6 +826,17 @@ function parseMailItemTimestamp(item) { return date.getTime(); } + match = timeText.match(/(\d{1,2})月(\d{1,2})日(?:\s*(\d{1,2}):(\d{2}))?/); + if (match) { + date.setMonth(Number(match[1]) - 1, Number(match[2])); + if (match[3] && match[4]) { + date.setHours(Number(match[3]), Number(match[4]), 0, 0); + } else { + date.setHours(0, 0, 0, 0); + } + return date.getTime(); + } + match = timeText.match(/(\d{4})-(\d{1,2})-(\d{1,2})\s*(\d{1,2}):(\d{2})/); if (match) { return new Date( @@ -1168,3 +1223,4 @@ async function handlePollEmail(step, payload) { } } +})(); diff --git a/content/signup-page.js b/content/signup-page.js index f36207b..c742b51 100644 --- a/content/signup-page.js +++ b/content/signup-page.js @@ -2,6 +2,7 @@ // Injected on: auth0.openai.com, auth.openai.com, accounts.openai.com // Dynamically injected on: chatgpt.com +(function initSignupPageContentScript() { console.log('[MultiPage:signup-page] Content script loaded on', location.href); const SIGNUP_PAGE_LISTENER_SENTINEL = 'data-multipage-signup-page-listener'; @@ -3560,3 +3561,4 @@ async function step5_fillNameBirthday(payload) { log('步骤 5:已点击“完成帐户创建”,当前步骤直接完成,不再等待页面结果。'); return completionPayload; } +})(); diff --git a/content/utils.js b/content/utils.js index f208aca..71e711e 100644 --- a/content/utils.js +++ b/content/utils.js @@ -1,6 +1,6 @@ // content/utils.js — Shared utilities for all content scripts -const getActivationStrategy = self.MultiPageActivationUtils?.getActivationStrategy; +var getActivationStrategy = self.MultiPageActivationUtils?.getActivationStrategy; function detectScriptSource({ injectedSource, @@ -26,7 +26,7 @@ function detectScriptSource({ return 'vps-panel'; } -const SCRIPT_SOURCE = (() => { +var SCRIPT_SOURCE = (() => { return detectScriptSource({ injectedSource: window.__MULTIPAGE_SOURCE, url: location.href, @@ -38,9 +38,9 @@ function getRuntimeScriptSource() { return window.__MULTIPAGE_SOURCE || SCRIPT_SOURCE; } -const LOG_PREFIX = `[MultiPage:${SCRIPT_SOURCE}]`; -const STOP_ERROR_MESSAGE = '流程已被用户停止。'; -let flowStopped = false; +var LOG_PREFIX = `[MultiPage:${SCRIPT_SOURCE}]`; +var STOP_ERROR_MESSAGE = '流程已被用户停止。'; +var flowStopped = false; if (!window.__MULTIPAGE_UTILS_LISTENER_READY__) { window.__MULTIPAGE_UTILS_LISTENER_READY__ = true; diff --git a/tests/mail-2925-content.test.js b/tests/mail-2925-content.test.js index 29f5306..c824ee0 100644 --- a/tests/mail-2925-content.test.js +++ b/tests/mail-2925-content.test.js @@ -319,6 +319,7 @@ return { test('handlePollEmail skips explicit mismatched target emails when receive-mode matching is enabled', async () => { const bundle = [ extractFunction('extractEmails'), + extractFunction('extractForwardedTargetEmails'), extractFunction('emailMatchesTarget'), extractFunction('getTargetEmailMatchState'), extractFunction('normalizeMinuteTimestamp'), From 941102200fe2e96ec05102e465294bd3b2457e0a Mon Sep 17 00:00:00 2001 From: Isulew <224964+netcookies@users.noreply.github.com> Date: Mon, 27 Apr 2026 15:15:06 +0800 Subject: [PATCH 2/4] =?UTF-8?q?fix:=20=E6=94=BE=E5=BC=80=202925=20?= =?UTF-8?q?=E5=85=A8=E6=A8=A1=E5=BC=8F=E7=9B=AE=E6=A0=87=E9=82=AE=E7=AE=B1?= =?UTF-8?q?=E5=8C=B9=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 让 2925 提供邮箱与接收邮箱模式都启用 targetEmail 弱匹配 - 同步更新轮询测试,验证 provide 与 receive 模式行为一致 --- background/verification-flow.js | 3 +-- tests/verification-flow-polling.test.js | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/background/verification-flow.js b/background/verification-flow.js index 229bed7..84bdfb5 100644 --- a/background/verification-flow.js +++ b/background/verification-flow.js @@ -214,8 +214,7 @@ function getVerificationPollPayload(step, state, overrides = {}) { const is2925Provider = state?.mailProvider === '2925'; - const mail2925MatchTargetEmail = is2925Provider - && String(state?.mail2925Mode || '').trim().toLowerCase() === 'receive'; + const mail2925MatchTargetEmail = is2925Provider; if (step === 4) { return { filterAfterTimestamp: is2925Provider ? 0 : getHotmailVerificationRequestTimestamp(4, state), diff --git a/tests/verification-flow-polling.test.js b/tests/verification-flow-polling.test.js index 426b828..d241d93 100644 --- a/tests/verification-flow-polling.test.js +++ b/tests/verification-flow-polling.test.js @@ -43,7 +43,7 @@ test('verification flow keeps 2925 polling cadence in the default payload', () = assert.equal(step8Payload.intervalMs, 15000); }); -test('verification flow only enables 2925 target email matching in receive mode', () => { +test('verification flow enables 2925 target email matching in both provide and receive modes', () => { const helpers = api.createVerificationFlowHelpers({ addLog: async () => {}, chrome: { tabs: { update: async () => {} } }, @@ -82,7 +82,7 @@ test('verification flow only enables 2925 target email matching in receive mode' mail2925Mode: 'receive', }); - assert.equal(providePayload.mail2925MatchTargetEmail, false); + assert.equal(providePayload.mail2925MatchTargetEmail, true); assert.equal(receivePayload.mail2925MatchTargetEmail, true); }); From 9b38b0bffe1ca82a880fe572f384588914989e01 Mon Sep 17 00:00:00 2001 From: zhangkun <1184253234@qq.com> Date: Mon, 27 Apr 2026 22:33:41 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20LuckMail=20=E9=AA=8C?= =?UTF-8?q?=E8=AF=81=E7=A0=81=E8=BD=AE=E8=AF=A2=E4=B8=8E=E9=87=8D=E8=AF=95?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- background.js | 87 ++++++++++++++++++++++++--- background/steps/fetch-login-code.js | 8 ++- background/steps/fetch-signup-code.js | 9 ++- background/verification-flow.js | 8 ++- 4 files changed, 96 insertions(+), 16 deletions(-) diff --git a/background.js b/background.js index 97b85b1..e62b730 100644 --- a/background.js +++ b/background.js @@ -3509,21 +3509,16 @@ async function resolveLuckmailVerificationMail(client, token, filters = {}, toke return match || null; } -async function pollLuckmailVerificationCode(step, state, pollPayload = {}) { +async function legacyPollLuckmailVerificationCode(step, state, pollPayload = {}) { const purchase = getCurrentLuckmailPurchase(state); if (!purchase?.token) { throw new Error('LuckMail 当前没有可用 token,请先执行步骤 3 购买邮箱。'); } const client = createLuckmailClient(state); - const maxAttempts = Math.max(1, Number(pollPayload.maxAttempts) || 5); - const intervalMs = Math.max(1000, Number(pollPayload.intervalMs) || 3000); - const filters = { - afterTimestamp: pollPayload.filterAfterTimestamp || 0, - senderFilters: pollPayload.senderFilters || [], - subjectFilters: pollPayload.subjectFilters || [], - excludeCodes: pollPayload.excludeCodes || [], - }; + const maxAttempts = Math.max(1, Number(pollPayload.maxAttempts) || 3); + const intervalMs = Math.max(15000, Number(pollPayload.intervalMs) || 15000); + const excludedCodes = new Set((pollPayload.excludeCodes || []).filter(Boolean)); const initialCursor = normalizeLuckmailMailCursor((await getState()).currentLuckmailMailCursor); if (!initialCursor.messageId && !initialCursor.receivedAt) { @@ -3587,6 +3582,80 @@ async function pollLuckmailVerificationCode(step, state, pollPayload = {}) { throw lastError || new Error(`步骤 ${step}:未在 LuckMail 邮箱中找到新的匹配验证码。`); } +async function pollLuckmailVerificationCode(step, state, pollPayload = {}) { + const purchase = getCurrentLuckmailPurchase(state); + if (!purchase?.token) { + throw new Error('LuckMail 当前没有可用 token,请先执行步骤 3 购买邮箱。'); + } + + const client = createLuckmailClient(state); + const maxAttempts = Math.max(1, Number(pollPayload.maxAttempts) || 3); + const intervalMs = Math.max(15000, Number(pollPayload.intervalMs) || 15000); + const excludedCodes = new Set((pollPayload.excludeCodes || []).filter(Boolean)); + + const initialCursor = normalizeLuckmailMailCursor((await getState()).currentLuckmailMailCursor); + if (!initialCursor.messageId && !initialCursor.receivedAt) { + const mailList = await client.user.getTokenMails(purchase.token); + const baselineCursor = buildLuckmailBaselineCursor(mailList?.mails || []); + await setLuckmailMailCursorState(baselineCursor); + if (baselineCursor?.messageId || baselineCursor?.receivedAt) { + await addLog(`步骤 ${step}:LuckMail 已保存当前邮箱旧邮件快照,后续仅使用新收到的验证码。`, 'info'); + } + } + + let lastError = null; + for (let attempt = 1; attempt <= maxAttempts; attempt += 1) { + throwIfStopped(); + await addLog(`步骤 ${step}:正在通过 LuckMail /code 接口轮询验证码(${attempt}/${maxAttempts})...`, 'info'); + + try { + const tokenCode = await client.user.getTokenCode(purchase.token); + const remoteEmail = String(tokenCode?.email_address || '').trim().toLowerCase(); + const expectedEmail = String(purchase.email_address || state?.email || '').trim().toLowerCase(); + if (remoteEmail && expectedEmail && remoteEmail !== expectedEmail) { + throw new Error(`步骤 ${step}:LuckMail token 对应邮箱与当前邮箱不一致。当前邮箱:${expectedEmail};token 邮箱:${remoteEmail}`); + } + + const tokenMail = tokenCode.verification_code && tokenCode.mail && !tokenCode.mail.verification_code + ? { + ...tokenCode.mail, + verification_code: tokenCode.verification_code, + } + : tokenCode.mail; + const code = String(tokenCode?.verification_code || tokenMail?.verification_code || '').trim(); + const cursor = normalizeLuckmailMailCursor((await getState()).currentLuckmailMailCursor); + + if (!code || !tokenMail) { + lastError = new Error(`步骤 ${step}:LuckMail /code 接口暂未返回新的验证码。`); + } else if (excludedCodes.has(code)) { + lastError = new Error(`步骤 ${step}:LuckMail 返回的验证码 ${code} 已试过,等待 15 秒后再次轮询。`); + } else if (!isLuckmailMailNewerThanCursor(tokenMail, cursor)) { + lastError = new Error(`步骤 ${step}:LuckMail /code 返回的最新邮件仍是旧验证码。`); + } else { + await setLuckmailMailCursorState(buildLuckmailMailCursor(tokenMail)); + return { + ok: true, + code, + emailTimestamp: normalizeLuckmailTimestamp(tokenMail.received_at) || Date.now(), + mailId: tokenMail.message_id, + }; + } + } catch (err) { + if (isStopError(err)) { + throw err; + } + lastError = err; + await addLog(`步骤 ${step}:LuckMail /code 轮询失败:${err.message}`, 'warn'); + } + + if (attempt < maxAttempts) { + await sleepWithStop(intervalMs); + } + } + + throw lastError || new Error(`步骤 ${step}:未在 LuckMail /code 接口中获取到新的验证码。`); +} + function summarizeCloudflareTempEmailMessagesForLog(messages) { return (messages || []) .slice() diff --git a/background/steps/fetch-login-code.js b/background/steps/fetch-login-code.js index 0c1535f..0af5cd4 100644 --- a/background/steps/fetch-login-code.js +++ b/background/steps/fetch-login-code.js @@ -268,9 +268,11 @@ getRemainingTimeMs: getStep8RemainingTimeResolver(state?.oauthUrl || '', visibleStep), requestFreshCodeFirst: false, targetEmail: fixedTargetEmail, - resendIntervalMs: (mail.provider === HOTMAIL_PROVIDER || mail.provider === '2925') - ? 0 - : STANDARD_MAIL_VERIFICATION_RESEND_INTERVAL_MS, + resendIntervalMs: mail.provider === LUCKMAIL_PROVIDER + ? 15000 + : ((mail.provider === HOTMAIL_PROVIDER || mail.provider === '2925') + ? 0 + : STANDARD_MAIL_VERIFICATION_RESEND_INTERVAL_MS), }); } diff --git a/background/steps/fetch-signup-code.js b/background/steps/fetch-signup-code.js index 88778a3..fc0a646 100644 --- a/background/steps/fetch-signup-code.js +++ b/background/steps/fetch-signup-code.js @@ -149,6 +149,7 @@ const shouldRequestFreshCodeFirst = ![ HOTMAIL_PROVIDER, + LUCKMAIL_PROVIDER, CLOUDFLARE_TEMP_EMAIL_PROVIDER, ].includes(mail.provider); @@ -157,9 +158,11 @@ sessionKey: verificationSessionKey, disableTimeBudgetCap: mail.provider === '2925', requestFreshCodeFirst: shouldRequestFreshCodeFirst, - resendIntervalMs: (mail.provider === HOTMAIL_PROVIDER || mail.provider === '2925') - ? 0 - : STANDARD_MAIL_VERIFICATION_RESEND_INTERVAL_MS, + resendIntervalMs: mail.provider === LUCKMAIL_PROVIDER + ? 15000 + : ((mail.provider === HOTMAIL_PROVIDER || mail.provider === '2925') + ? 0 + : STANDARD_MAIL_VERIFICATION_RESEND_INTERVAL_MS), }); } diff --git a/background/verification-flow.js b/background/verification-flow.js index 7e8ea92..dcade7a 100644 --- a/background/verification-flow.js +++ b/background/verification-flow.js @@ -917,7 +917,7 @@ getLegacyVerificationResendCountDefault(step, { requestFreshCodeFirst }) ) : getConfiguredVerificationResendCount(step, state, { requestFreshCodeFirst }); - const maxSubmitAttempts = 15; + const maxSubmitAttempts = mail.provider === LUCKMAIL_PROVIDER ? 3 : 15; const resendIntervalMs = Math.max(0, Number(options.resendIntervalMs) || 0); let lastResendAt = Number(options.lastResendAt) || 0; @@ -1002,6 +1002,12 @@ throw new Error(`步骤 ${step}:验证码连续失败,已达到 ${maxSubmitAttempts} 次重试上限。`); } + if (mail.provider === LUCKMAIL_PROVIDER) { + await addLog(`步骤 ${step}:LuckMail 验证码提交失败,等待 15 秒后重新轮询 /code 接口(${attempt + 1}/${maxSubmitAttempts})...`, 'warn'); + await sleepWithStop(15000); + continue; + } + const remainingBeforeResendMs = resendIntervalMs > 0 && lastResendAt > 0 ? Math.max(0, resendIntervalMs - (Date.now() - lastResendAt)) : 0; From cf2a720531732c01fe4a38bbc15db4f75a73a90e Mon Sep 17 00:00:00 2001 From: Isulew <224964+netcookies@users.noreply.github.com> Date: Tue, 28 Apr 2026 00:50:29 +0800 Subject: [PATCH 4/4] =?UTF-8?q?fix:=20=E6=94=B6=E6=95=9B=202925=20?= =?UTF-8?q?=E9=82=AE=E7=AE=B1=E4=BF=AE=E5=A4=8D=E8=8C=83=E5=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 回退非必要的 2925 行为改动,仅保留已验证有效的修复 - 保留 bounce 转发地址解析、中文日期解析与邮箱页复用时的 ready 恢复 - 同步最小化测试断言,保持当前代码与测试一致 --- background/mail-2925-session.js | 20 +++++++++---------- background/steps/fetch-login-code.js | 4 ---- background/steps/fetch-signup-code.js | 4 ---- background/verification-flow.js | 3 ++- content/mail-2925.js | 8 -------- content/signup-page.js | 2 -- content/utils.js | 10 +++++----- ...background-mail2925-entry-behavior.test.js | 2 +- tests/verification-flow-polling.test.js | 4 ++-- 9 files changed, 20 insertions(+), 37 deletions(-) diff --git a/background/mail-2925-session.js b/background/mail-2925-session.js index 502362a..e80dc4c 100644 --- a/background/mail-2925-session.js +++ b/background/mail-2925-session.js @@ -537,6 +537,16 @@ } } + if (typeof ensureContentScriptReadyOnTab === 'function') { + await ensureContentScriptReadyOnTab(MAIL2925_SOURCE, tabId, { + inject: MAIL2925_INJECT, + injectSource: MAIL2925_INJECT_SOURCE, + timeoutMs: 20000, + retryDelayMs: 800, + logMessage: '步骤 0:2925 登录页内容脚本未就绪,正在等待页面稳定后继续登录...', + }); + } + if (!forceRelogin && !isMail2925LoginUrl(openedUrl) && !normalizedExpectedMailboxEmail) { await addLog('2925:当前邮箱页未跳转到登录页,将直接复用已登录会话。', 'info'); return buildSuccessPayload(); @@ -553,16 +563,6 @@ }); } - if (typeof ensureContentScriptReadyOnTab === 'function') { - await ensureContentScriptReadyOnTab(MAIL2925_SOURCE, tabId, { - inject: MAIL2925_INJECT, - injectSource: MAIL2925_INJECT_SOURCE, - timeoutMs: 20000, - retryDelayMs: 800, - logMessage: '步骤 0:2925 登录页内容脚本未就绪,正在等待页面稳定后继续登录...', - }); - } - if (forceRelogin && typeof sleepWithStop === 'function') { await addLog('2925:登录页已打开,等待 3 秒后开始检查输入框并执行登录...', 'info'); await sleepWithStop(3000); diff --git a/background/steps/fetch-login-code.js b/background/steps/fetch-login-code.js index 41b0e3b..c25b2f4 100644 --- a/background/steps/fetch-login-code.js +++ b/background/steps/fetch-login-code.js @@ -69,10 +69,6 @@ } function getExpectedMail2925MailboxEmail(state = {}) { - if (String(state?.mail2925Mode || '').trim().toLowerCase() === 'receive') { - return ''; - } - if (Boolean(state?.mail2925UseAccountPool)) { const currentAccountId = String(state?.currentMail2925AccountId || '').trim(); const accounts = Array.isArray(state?.mail2925Accounts) ? state.mail2925Accounts : []; diff --git a/background/steps/fetch-signup-code.js b/background/steps/fetch-signup-code.js index 791d0c2..88778a3 100644 --- a/background/steps/fetch-signup-code.js +++ b/background/steps/fetch-signup-code.js @@ -26,10 +26,6 @@ } = deps; function getExpectedMail2925MailboxEmail(state = {}) { - if (String(state?.mail2925Mode || '').trim().toLowerCase() === 'receive') { - return ''; - } - if (Boolean(state?.mail2925UseAccountPool)) { const currentAccountId = String(state?.currentMail2925AccountId || '').trim(); const accounts = Array.isArray(state?.mail2925Accounts) ? state.mail2925Accounts : []; diff --git a/background/verification-flow.js b/background/verification-flow.js index 84bdfb5..229bed7 100644 --- a/background/verification-flow.js +++ b/background/verification-flow.js @@ -214,7 +214,8 @@ function getVerificationPollPayload(step, state, overrides = {}) { const is2925Provider = state?.mailProvider === '2925'; - const mail2925MatchTargetEmail = is2925Provider; + const mail2925MatchTargetEmail = is2925Provider + && String(state?.mail2925Mode || '').trim().toLowerCase() === 'receive'; if (step === 4) { return { filterAfterTimestamp: is2925Provider ? 0 : getHotmailVerificationRequestTimestamp(4, state), diff --git a/content/mail-2925.js b/content/mail-2925.js index 4b723e2..d2ba01a 100644 --- a/content/mail-2925.js +++ b/content/mail-2925.js @@ -1,13 +1,6 @@ // content/mail-2925.js - Content script for 2925 Mail (steps 4, 8) // Injected dynamically on: 2925.com -(function initMail2925ContentScript() { -if (window.__MULTIPAGE_MAIL2925_SCRIPT_LOADED__) { - console.log('[MultiPage:mail-2925] Duplicate injection skipped on', location.href); - return; -} -window.__MULTIPAGE_MAIL2925_SCRIPT_LOADED__ = true; - const MAIL2925_PREFIX = '[MultiPage:mail-2925]'; const isTopFrame = window === window.top; @@ -1223,4 +1216,3 @@ async function handlePollEmail(step, payload) { } } -})(); diff --git a/content/signup-page.js b/content/signup-page.js index c742b51..f36207b 100644 --- a/content/signup-page.js +++ b/content/signup-page.js @@ -2,7 +2,6 @@ // Injected on: auth0.openai.com, auth.openai.com, accounts.openai.com // Dynamically injected on: chatgpt.com -(function initSignupPageContentScript() { console.log('[MultiPage:signup-page] Content script loaded on', location.href); const SIGNUP_PAGE_LISTENER_SENTINEL = 'data-multipage-signup-page-listener'; @@ -3561,4 +3560,3 @@ async function step5_fillNameBirthday(payload) { log('步骤 5:已点击“完成帐户创建”,当前步骤直接完成,不再等待页面结果。'); return completionPayload; } -})(); diff --git a/content/utils.js b/content/utils.js index 71e711e..f208aca 100644 --- a/content/utils.js +++ b/content/utils.js @@ -1,6 +1,6 @@ // content/utils.js — Shared utilities for all content scripts -var getActivationStrategy = self.MultiPageActivationUtils?.getActivationStrategy; +const getActivationStrategy = self.MultiPageActivationUtils?.getActivationStrategy; function detectScriptSource({ injectedSource, @@ -26,7 +26,7 @@ function detectScriptSource({ return 'vps-panel'; } -var SCRIPT_SOURCE = (() => { +const SCRIPT_SOURCE = (() => { return detectScriptSource({ injectedSource: window.__MULTIPAGE_SOURCE, url: location.href, @@ -38,9 +38,9 @@ function getRuntimeScriptSource() { return window.__MULTIPAGE_SOURCE || SCRIPT_SOURCE; } -var LOG_PREFIX = `[MultiPage:${SCRIPT_SOURCE}]`; -var STOP_ERROR_MESSAGE = '流程已被用户停止。'; -var flowStopped = false; +const LOG_PREFIX = `[MultiPage:${SCRIPT_SOURCE}]`; +const STOP_ERROR_MESSAGE = '流程已被用户停止。'; +let flowStopped = false; if (!window.__MULTIPAGE_UTILS_LISTENER_READY__) { window.__MULTIPAGE_UTILS_LISTENER_READY__ = true; diff --git a/tests/background-mail2925-entry-behavior.test.js b/tests/background-mail2925-entry-behavior.test.js index fe26b5c..8aeed04 100644 --- a/tests/background-mail2925-entry-behavior.test.js +++ b/tests/background-mail2925-entry-behavior.test.js @@ -68,7 +68,7 @@ test('ensureMail2925MailboxSession reuses current mailbox page without sending l }); assert.equal(sendCalls, 0); - assert.equal(readyCalls, 0); + assert.equal(readyCalls, 1); assert.equal(result.result.usedExistingSession, true); }); diff --git a/tests/verification-flow-polling.test.js b/tests/verification-flow-polling.test.js index d241d93..426b828 100644 --- a/tests/verification-flow-polling.test.js +++ b/tests/verification-flow-polling.test.js @@ -43,7 +43,7 @@ test('verification flow keeps 2925 polling cadence in the default payload', () = assert.equal(step8Payload.intervalMs, 15000); }); -test('verification flow enables 2925 target email matching in both provide and receive modes', () => { +test('verification flow only enables 2925 target email matching in receive mode', () => { const helpers = api.createVerificationFlowHelpers({ addLog: async () => {}, chrome: { tabs: { update: async () => {} } }, @@ -82,7 +82,7 @@ test('verification flow enables 2925 target email matching in both provide and r mail2925Mode: 'receive', }); - assert.equal(providePayload.mail2925MatchTargetEmail, true); + assert.equal(providePayload.mail2925MatchTargetEmail, false); assert.equal(receivePayload.mail2925MatchTargetEmail, true); });