Merge remote-tracking branch 'origin/dev' into codex-review-pr-226

This commit is contained in:
QLHazyCoder
2026-05-09 23:37:59 +08:00
9 changed files with 1040 additions and 64 deletions
+1 -1
View File
@@ -85,7 +85,7 @@
function fallbackSignupProfilePageUrl(rawUrl) {
const parsed = parseUrlSafely(rawUrl);
if (!parsed) return false;
return /\/create-account\/profile(?:[/?#]|$)/i.test(parsed.pathname || '');
return /\/(?:create-account\/profile|u\/signup\/profile|signup\/profile)(?:[/?#]|$)/i.test(parsed.pathname || '');
}
function resolveSignupPostIdentityState(rawUrl) {
+37
View File
@@ -33,6 +33,7 @@
setWebNavCommittedListener,
setStep8PendingReject,
setStep8TabUpdatedListener,
shouldDeferStep9CallbackTimeout,
} = deps;
const LOCALHOST_CALLBACK_LOCAL_TIMEOUT_MS = 240000;
@@ -96,6 +97,7 @@
let signupTabId = null;
const callbackWaitStartedAt = Date.now();
let timeoutCheckTimer = null;
let timeoutDeferredLogged = false;
const cleanupListener = () => {
if (timeoutCheckTimer) {
@@ -128,11 +130,46 @@
});
};
const isCallbackTimeoutDeferred = async (elapsedMs) => {
if (typeof shouldDeferStep9CallbackTimeout !== 'function') {
return false;
}
try {
const deferred = await shouldDeferStep9CallbackTimeout({
tabId: signupTabId,
visibleStep,
elapsedMs,
oauthUrl: activeState?.oauthUrl || '',
});
if (deferred && !timeoutDeferredLogged) {
timeoutDeferredLogged = true;
await addStepLog(
visibleStep,
'检测到认证页仍在安全验证/授权跳转中,暂停本地回调超时判定,继续等待 localhost 回调...',
'info'
);
}
return Boolean(deferred);
} catch (error) {
await addStepLog(
visibleStep,
`复核认证页跳转状态失败(${error?.message || error}),继续按原超时规则等待回调。`,
'warn'
);
return false;
}
};
const checkCallbackTimeout = async () => {
if (resolved) {
return;
}
const elapsedMs = Date.now() - callbackWaitStartedAt;
if (await isCallbackTimeoutDeferred(elapsedMs)) {
timeoutCheckTimer = setTimeout(checkCallbackTimeout, CALLBACK_TIMEOUT_CHECK_INTERVAL_MS);
return;
}
if (elapsedMs >= LOCALHOST_CALLBACK_LOCAL_TIMEOUT_MS) {
rejectStep9(new Error(`${Math.round(LOCALHOST_CALLBACK_LOCAL_TIMEOUT_MS / 1000)} 秒内未捕获到 localhost 回调跳转,步骤 ${visibleStep} 的点击可能被拦截了。`));
return;
+64 -15
View File
@@ -135,7 +135,7 @@
if (!['auth.openai.com', 'auth0.openai.com', 'accounts.openai.com'].includes(host)) {
return false;
}
return /\/create-account\/profile(?:[/?#]|$)/i.test(String(parsed.pathname || ''));
return /\/(?:create-account\/profile|u\/signup\/profile|signup\/profile)(?:[/?#]|$)/i.test(String(parsed.pathname || ''));
} catch {
return false;
}
@@ -225,11 +225,21 @@
const authState = String(result?.state || '').trim();
const authUrl = String(result?.url || '').trim();
const verificationErrorText = String(result?.verificationErrorText || '').trim();
lastSnapshot = {
state: authState || 'unknown',
url: authUrl,
};
if (authState === 'verification_page' && verificationErrorText) {
return {
success: false,
reason: 'invalid_code',
invalidCode: true,
errorText: verificationErrorText,
url: authUrl,
};
}
if (authState === 'oauth_consent_page') {
return {
success: true,
@@ -1068,7 +1078,8 @@
},
};
let result;
if (typeof sendToContentScriptResilient === 'function') {
const shouldAvoidReplaySubmit = step === 8;
if (typeof sendToContentScriptResilient === 'function' && !shouldAvoidReplaySubmit) {
try {
result = await sendToContentScriptResilient('signup-page', message, {
timeoutMs: Math.max(baseResponseTimeoutMs + 15000, 30000),
@@ -1131,6 +1142,56 @@
}
throw err;
}
} else if (shouldAvoidReplaySubmit) {
try {
result = await sendToContentScript('signup-page', message, {
responseTimeoutMs: baseResponseTimeoutMs,
});
} catch (err) {
if (isRetryableVerificationTransportError(err)) {
await addLog('认证页正在切换,等待页面重新就绪后继续确认验证码提交结果...', 'warn', {
step: completionStep,
stepKey: 'fetch-login-code',
});
const fallback = await detectStep8PostSubmitFallback({
step,
timeoutMs: 9000,
pollIntervalMs: 300,
});
if (fallback.invalidCode) {
return {
invalidCode: true,
errorText: fallback.errorText || '验证码被拒绝。',
url: fallback.url || '',
};
}
if (fallback.success) {
if (fallback.addPhonePage) {
await addLog('验证码提交后通信中断,但页面已进入手机号验证页,按提交成功继续。', 'warn', {
step: completionStep,
stepKey: 'fetch-login-code',
});
} else {
await addLog('验证码提交后通信中断,但页面已进入 OAuth 授权页,按提交成功继续。', 'warn', {
step: completionStep,
stepKey: 'fetch-login-code',
});
}
return {
success: true,
assumed: true,
transportRecovered: true,
addPhonePage: Boolean(fallback.addPhonePage),
url: fallback.url || '',
};
}
if (fallback.restartStep7) {
const urlPart = fallback.url ? ` URL: ${fallback.url}` : '';
throw new Error(`STEP8_RESTART_STEP7::步骤 ${completionStep}:验证码提交后认证页进入登录超时报错页,请回到步骤 ${authLoginStep} 重新开始。${urlPart}`.trim());
}
}
throw err;
}
} else {
result = await sendToContentScript('signup-page', message, {
responseTimeoutMs: baseResponseTimeoutMs,
@@ -1275,20 +1336,8 @@
continue;
}
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'
);
await sleepWithStop(Math.min(remainingBeforeResendMs, 2000));
continue;
}
if (remainingAutomaticResendCount <= 0) {
await addLog(`步骤 ${step}:已达到自动重新发送验证码次数上限,将直接使用当前时间窗口继续重试`, 'warn');
await addLog(`步骤 ${step}:已达到自动重新发送验证码次数上限,将排除已拒绝验证码并继续轮询新邮件`, 'warn');
continue;
}