Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
169 changes: 157 additions & 12 deletions background/message-router.js
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,129 @@
|| status === 'skipped';
}

function isPhoneSignupStepPayload(payload = {}, state = {}) {
const payloadIdentifierType = String(payload?.accountIdentifierType || '').trim().toLowerCase();
if (payloadIdentifierType === 'email') {
return false;
}

const stateIdentifierType = String(state?.accountIdentifierType || '').trim().toLowerCase();
return payloadIdentifierType === 'phone'
|| Boolean(resolveSignupPhonePayload(payload))
|| stateIdentifierType === 'phone'
|| Boolean(String(state?.signupPhoneNumber || '').trim())
|| Boolean(state?.signupPhoneActivation)
|| Boolean(state?.signupPhoneCompletedActivation);
}

function isLoginPasswordPagePayload(payload = {}) {
const passwordPageMode = String(payload?.passwordPageMode || '').trim().toLowerCase();
if (passwordPageMode === 'login') {
return true;
}
const rawPath = String(payload?.passwordPagePath || '').trim();
if (/\/log-in\/password(?:[/?#]|$)/i.test(rawPath)) {
return true;
}
const rawUrl = String(payload?.passwordPageUrl || '').trim();
if (!rawUrl) {
return false;
}
try {
return /\/log-in\/password(?:[/?#]|$)/i.test(new URL(rawUrl).pathname || '');
} catch {
return /\/log-in\/password(?:[/?#]|$)/i.test(rawUrl);
}
}

function isSignupPasswordPagePayload(payload = {}) {
const passwordPageMode = String(payload?.passwordPageMode || '').trim().toLowerCase();
if (passwordPageMode === 'signup') {
return true;
}
const rawPath = String(payload?.passwordPagePath || '').trim();
if (/\/(?:create-account|u\/signup|signup)\/password(?:[/?#]|$)/i.test(rawPath)) {
return true;
}
const rawUrl = String(payload?.passwordPageUrl || '').trim();
if (!rawUrl) {
return false;
}
try {
return /\/(?:create-account|u\/signup|signup)\/password(?:[/?#]|$)/i.test(new URL(rawUrl).pathname || '');
} catch {
return /\/(?:create-account|u\/signup|signup)\/password(?:[/?#]|$)/i.test(rawUrl);
}
}

function isSuccessfulLoginPasswordFlowPayload(payload = {}) {
if (!isLoginPasswordPagePayload(payload)) {
return false;
}
const state = String(payload?.state || payload?.successState || '').trim().toLowerCase();
return Boolean(payload?.ready)
|| Boolean(payload?.alreadyVerified)
|| Boolean(payload?.passwordLoginFlow)
|| state === 'verification'
|| state === 'verification_page'
|| state === 'phone_verification_page'
|| state === 'oauth_consent_page'
|| state === 'logged_in_home';
}

function shouldSkipPhoneSignupRegistrationTailAfterPassword(payload = {}, state = {}) {
if (!isPhoneSignupStepPayload(payload, state)) {
return false;
}
if (isSignupPasswordPagePayload(payload)) {
return false;
}
return isSuccessfulLoginPasswordFlowPayload(payload);
}

function shouldSkipPhoneSignupRegistrationTailBeforePasswordFinalize(payload = {}, state = {}) {
if (!isPhoneSignupStepPayload(payload, state)) {
return false;
}
if (!Boolean(payload?.deferredSubmit)) {
return false;
}
if (isSignupPasswordPagePayload(payload)) {
return false;
}
return isLoginPasswordPagePayload(payload);
}

async function skipPhoneSignupRegistrationTailAfterPassword(currentStep, payload = {}) {
const latestState = await getState();
const skippedSteps = [];
for (const stepKey of ['fetch-signup-code', 'fill-profile', 'wait-registration-success']) {
const skippedStep = findStepByKeyAfter(currentStep, stepKey, latestState);
if (!skippedStep) {
continue;
}
const status = getNodeStatusByStep(skippedStep, latestState);
if (isStepProtectedFromAutoSkip(status)) {
continue;
}
await setNodeStatusByStep(skippedStep, 'skipped', latestState);
skippedSteps.push(skippedStep);
}

await setState({ signupVerificationRequestedAt: null });
if (skippedSteps.length) {
await addLog(
`步骤 ${currentStep}:手机号密码提交后已确认账号进入登录后续状态,已自动跳过步骤 ${skippedSteps.join('/')},流程将直接进入 OAuth 后续节点。`,
'warn',
{ step: currentStep, stepKey: 'fill-password' }
);
}
return {
...payload,
skipRegistrationFlow: true,
};
}

function findStepByKeyAfter(currentOrder, targetKey, state = {}) {
const activeStepIds = typeof getStepIdsForState === 'function'
? getStepIdsForState(state)
Expand Down Expand Up @@ -847,15 +970,20 @@
break;
case 3:
await syncStepAccountIdentityFromPayload(payload);
if (payload.signupVerificationRequestedAt) {
await setState({ signupVerificationRequestedAt: payload.signupVerificationRequestedAt });
}
if (payload.skipProfileStep) {
{
const latestState = await getState();
const step5Status = getNodeStatusByStep(5, latestState);
if (step5Status !== 'running' && step5Status !== 'completed' && step5Status !== 'manual_completed') {
await setNodeStatusByStep(5, 'skipped', latestState);
await addLog('步骤 3:页面已直接进入已登录态,已自动跳过步骤 5。', 'warn');
const skipRegistrationTail = shouldSkipPhoneSignupRegistrationTailAfterPassword(payload, latestState);
if (payload.signupVerificationRequestedAt && !skipRegistrationTail) {
await setState({ signupVerificationRequestedAt: payload.signupVerificationRequestedAt });
}
if (skipRegistrationTail) {
await skipPhoneSignupRegistrationTailAfterPassword(step, payload);
} else if (payload.skipProfileStep) {
const step5Status = getNodeStatusByStep(5, latestState);
if (step5Status !== 'running' && step5Status !== 'completed' && step5Status !== 'manual_completed') {
await setNodeStatusByStep(5, 'skipped', latestState);
await addLog('步骤 3:页面已直接进入已登录态,已自动跳过步骤 5。', 'warn');
}
}
}
if (payload.loginVerificationRequestedAt) {
Expand Down Expand Up @@ -967,9 +1095,26 @@
notifyNodeError(nodeId, '流程已被用户停止。');
return { ok: true };
}
let completionPayload = message.payload || {};
try {
if (nodeId === 'fill-password' && typeof finalizeStep3Completion === 'function') {
await finalizeStep3Completion(message.payload || {});
const skipStep3FinalizeForPhoneLoginPassword = nodeId === 'fill-password'
&& shouldSkipPhoneSignupRegistrationTailBeforePasswordFinalize(completionPayload, await getState());
if (skipStep3FinalizeForPhoneLoginPassword) {
completionPayload = {
...completionPayload,
signupVerificationRequestedAt: null,
passwordLoginFlow: true,
skipRegistrationFlow: true,
state: 'login_password_page',
};
} else if (nodeId === 'fill-password' && typeof finalizeStep3Completion === 'function') {
const finalizedPayload = await finalizeStep3Completion(message.payload || {});
if (finalizedPayload && typeof finalizedPayload === 'object') {
completionPayload = {
...completionPayload,
...finalizedPayload,
};
}
}
} catch (error) {
if (typeof isCloudflareSecurityBlockedError === 'function' && isCloudflareSecurityBlockedError(error)) {
Expand Down Expand Up @@ -1004,11 +1149,11 @@
stepKey: nodeId,
});
}
await handleStepData(resolvedStep, message.payload);
await handleStepData(resolvedStep, completionPayload);
if (isFinalNode && typeof appendAccountRunRecord === 'function') {
await appendAccountRunRecord('success', completionState);
}
notifyNodeComplete(nodeId, message.payload);
notifyNodeComplete(nodeId, completionPayload);
return { ok: true };
}

Expand Down
42 changes: 41 additions & 1 deletion flows/openai/content/openai-auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -2624,6 +2624,19 @@ async function step2_clickRegister(payload = {}) {
// ============================================================

async function step3_fillEmailPassword(payload) {
const resolvePasswordPageInfo = (rawUrl = '') => {
const url = String(rawUrl || '').trim();
let path = '';
try {
path = new URL(url || location.href, 'https://auth.openai.com').pathname || '';
} catch {
path = String(location.pathname || '');
}
const mode = /\/log-in\/password(?:[/?#]|$)/i.test(path)
? 'login'
: (/\/(?:create-account|u\/signup|signup)\/password(?:[/?#]|$)/i.test(path) ? 'signup' : '');
return { url: url || location.href, path, mode };
};
const performOperationWithDelay = typeof getOperationDelayRunner === 'function'
? getOperationDelayRunner()
: async (metadata, operation) => {
Expand Down Expand Up @@ -2693,6 +2706,7 @@ async function step3_fillEmailPassword(payload) {
throw new Error(`当前密码页邮箱为 ${snapshot.displayedEmail},与目标邮箱 ${email} 不一致,请先回到步骤 1 重新开始。`);
}

const passwordPageInfo = resolvePasswordPageInfo(snapshot.url || location.href);
await humanPause(600, 1500);
await performOperationWithDelay({ stepKey: 'fill-password', kind: 'fill', label: 'signup-password' }, async () => {
fillInput(snapshot.passwordInput, password);
Expand All @@ -2709,14 +2723,19 @@ async function step3_fillEmailPassword(payload) {
logSignupPasswordDiagnostics('步骤 3:当前密码页同时存在一次性验证码入口', 'info');
}

const signupVerificationRequestedAt = submitBtn ? Date.now() : null;
const isLoginPasswordPage = passwordPageInfo.mode === 'login';
const signupVerificationRequestedAt = submitBtn && !isLoginPasswordPage ? Date.now() : null;
const completionPayload = {
email,
phoneNumber: String(payload?.phoneNumber || '').trim(),
accountIdentifierType,
accountIdentifier,
signupVerificationRequestedAt,
deferredSubmit: Boolean(submitBtn),
passwordPageUrl: passwordPageInfo.url,
passwordPagePath: passwordPageInfo.path,
passwordPageMode: passwordPageInfo.mode,
...(isLoginPasswordPage ? { passwordLoginFlow: true } : {}),
};

reportComplete(3, completionPayload);
Expand Down Expand Up @@ -4762,6 +4781,13 @@ function inspectSignupVerificationState() {
};
}

if (typeof isOAuthConsentPage === 'function' && isOAuthConsentPage()) {
return {
state: 'oauth_consent_page',
url: location.href,
};
}

if (typeof isPhoneVerificationPageReady === 'function' && isPhoneVerificationPageReady()) {
return {
state: 'verification',
Expand Down Expand Up @@ -4804,6 +4830,7 @@ async function waitForSignupVerificationTransition(timeout = 5000) {
if (
snapshot.state === 'step5'
|| snapshot.state === 'logged_in_home'
|| snapshot.state === 'oauth_consent_page'
|| snapshot.state === 'verification'
|| snapshot.state === 'contact_verification_server_error'
|| snapshot.state === 'error'
Expand Down Expand Up @@ -4901,6 +4928,19 @@ async function prepareSignupVerificationFlow(payload = {}, timeout = 30000) {
};
}

if (snapshot.state === 'oauth_consent_page') {
log(`${prepareLogLabel}:页面已直接进入 OAuth 授权页,本步骤按已完成处理。`, 'ok');
return {
ready: true,
alreadyVerified: true,
state: 'oauth_consent_page',
skipLoginVerificationStep: true,
directOAuthConsentPage: true,
retried: recoveryRound,
prepareSource,
};
}

if (snapshot.state === 'verification') {
await waitForDocumentLoadComplete(15000, `${prepareLogLabel}:注册验证码页面`);
await waitForVerificationCodeTarget(15000);
Expand Down
Loading