fix: preserve phone identity on oauth-login completion

- Merge latest origin/dev into PR #245 for the current review baseline.\n- Sync Step 7 completion identity before oauth-login step-key handling returns.\n- Cover the real oauth-login stepKey route in the message-router regression test.
This commit is contained in:
QLHazyCoder
2026-05-15 03:10:34 +08:00
66 changed files with 6953 additions and 542 deletions
+89 -4
View File
@@ -51,13 +51,67 @@
getStepIdsForState,
getLastStepIdForState,
normalizeSignupMethod = (value = '') => String(value || '').trim().toLowerCase() === 'phone' ? 'phone' : 'email',
canUsePhoneSignup = (state = {}) => Boolean(state?.phoneVerificationEnabled)
&& !Boolean(state?.plusModeEnabled)
&& !Boolean(state?.contributionMode),
canUsePhoneSignup = (state = {}) => {
const rootScope = typeof self !== 'undefined' ? self : globalThis;
const capabilityRegistry = rootScope.MultiPageFlowCapabilities?.createFlowCapabilityRegistry?.({
defaultFlowId: 'openai',
}) || null;
if (capabilityRegistry?.canUsePhoneSignup) {
return capabilityRegistry.canUsePhoneSignup(state);
}
return Boolean(state?.phoneVerificationEnabled)
&& !Boolean(state?.plusModeEnabled)
&& !Boolean(state?.contributionMode);
},
resolveSignupMethod = (state = {}) => {
const method = normalizeSignupMethod(state?.signupMethod);
const rootScope = typeof self !== 'undefined' ? self : globalThis;
const capabilityRegistry = rootScope.MultiPageFlowCapabilities?.createFlowCapabilityRegistry?.({
defaultFlowId: 'openai',
}) || null;
if (capabilityRegistry?.resolveSignupMethod) {
return capabilityRegistry.resolveSignupMethod(state, method);
}
return method === 'phone' && canUsePhoneSignup(state) ? 'phone' : 'email';
},
validateAutoRunStart = (state = {}, options = {}) => {
const validationState = options?.state || state;
const rootScope = typeof self !== 'undefined' ? self : globalThis;
const capabilityRegistry = rootScope.MultiPageFlowCapabilities?.createFlowCapabilityRegistry?.({
defaultFlowId: 'openai',
}) || null;
if (!capabilityRegistry?.validateAutoRunStart) {
return { ok: true, errors: [] };
}
return capabilityRegistry.validateAutoRunStart({
activeFlowId: options?.activeFlowId ?? validationState?.activeFlowId,
panelMode: options?.panelMode ?? validationState?.panelMode,
signupMethod: options?.signupMethod ?? validationState?.signupMethod,
state: validationState,
});
},
validateModeSwitch = (state = {}, options = {}) => {
const validationState = options?.state || state;
const rootScope = typeof self !== 'undefined' ? self : globalThis;
const capabilityRegistry = rootScope.MultiPageFlowCapabilities?.createFlowCapabilityRegistry?.({
defaultFlowId: 'openai',
}) || null;
if (!capabilityRegistry?.validateModeSwitch) {
return {
ok: true,
changedKeys: Array.isArray(options?.changedKeys) ? options.changedKeys : [],
errors: [],
normalizedUpdates: {},
};
}
return capabilityRegistry.validateModeSwitch({
activeFlowId: options?.activeFlowId ?? validationState?.activeFlowId,
changedKeys: options?.changedKeys,
panelMode: options?.panelMode ?? validationState?.panelMode,
signupMethod: options?.signupMethod ?? validationState?.signupMethod,
state: validationState,
});
},
getTabId,
getStopRequested,
handleAutoRunLoopUnhandledError,
@@ -421,6 +475,9 @@
if (payload.sub2apiSessionId !== undefined) updates.sub2apiSessionId = payload.sub2apiSessionId || null;
if (payload.sub2apiOAuthState !== undefined) updates.sub2apiOAuthState = payload.sub2apiOAuthState || null;
if (payload.sub2apiGroupId !== undefined) updates.sub2apiGroupId = payload.sub2apiGroupId || null;
if (payload.sub2apiGroupIds !== undefined) updates.sub2apiGroupIds = Array.isArray(payload.sub2apiGroupIds)
? payload.sub2apiGroupIds
: [];
if (payload.sub2apiDraftName !== undefined) updates.sub2apiDraftName = payload.sub2apiDraftName || null;
if (payload.sub2apiProxyId !== undefined) updates.sub2apiProxyId = payload.sub2apiProxyId || null;
if (payload.cpaOAuthState !== undefined) updates.cpaOAuthState = payload.cpaOAuthState || null;
@@ -437,6 +494,7 @@
const stepKey = getStepKeyForState(step, stateForStep);
if (stepKey === 'oauth-login') {
await syncStepAccountIdentityFromPayload(payload);
if (payload.skipLoginVerificationStep) {
await setState({ loginVerificationRequestedAt: null });
const latestState = await getState();
@@ -938,6 +996,10 @@
}
}
const state = await getState();
const autoRunStartValidation = validateAutoRunStart(state, { state });
if (autoRunStartValidation?.ok === false) {
throw new Error(autoRunStartValidation.errors?.[0]?.message || '当前设置不支持启动自动流程。');
}
if (getPendingAutoRunTimerPlan(state)) {
throw new Error('已有自动运行倒计时计划,请先取消或立即开始。');
}
@@ -965,6 +1027,11 @@
});
}
}
const state = await getState();
const autoRunStartValidation = validateAutoRunStart(state, { state });
if (autoRunStartValidation?.ok === false) {
throw new Error(autoRunStartValidation.errors?.[0]?.message || '当前设置不支持启动自动流程。');
}
const totalRuns = normalizeRunCount(message.payload?.totalRuns || 1);
return await scheduleAutoRun(totalRuns, {
delayMinutes: message.payload?.delayMinutes,
@@ -1036,6 +1103,16 @@
const currentState = await getState();
const updates = buildPersistentSettingsPayload(message.payload || {});
const sessionUpdates = buildLuckmailSessionSettingsPayload(message.payload || {});
const modeValidation = validateModeSwitch({
...currentState,
...updates,
resolvedSignupMethod: null,
}, {
changedKeys: Object.keys(updates),
});
if (modeValidation?.normalizedUpdates && Object.keys(modeValidation.normalizedUpdates).length > 0) {
Object.assign(updates, modeValidation.normalizedUpdates);
}
const nextSignupState = {
...currentState,
...updates,
@@ -1045,6 +1122,9 @@
Object.prototype.hasOwnProperty.call(updates, 'phoneVerificationEnabled')
|| Object.prototype.hasOwnProperty.call(updates, 'plusModeEnabled')
|| Object.prototype.hasOwnProperty.call(updates, 'signupMethod')
|| Object.prototype.hasOwnProperty.call(updates, 'panelMode')
|| Object.prototype.hasOwnProperty.call(updates, 'activeFlowId')
|| Object.prototype.hasOwnProperty.call(updates, 'contributionMode')
) {
updates.signupMethod = resolveSignupMethod(nextSignupState);
}
@@ -1145,7 +1225,12 @@
);
await addLog(`Plus 支付方式已切换为 ${selectedPlusPaymentMethod},已更新对应的 Plus 步骤。`, 'info');
}
return { ok: true, state: await getState(), proxyRouting };
return {
ok: true,
modeValidation,
proxyRouting,
state: await getState(),
};
}
case 'REFRESH_GPC_CARD_BALANCE': {