fix: preserve oauth step metadata and resolve dev merge conflicts
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
buildLuckmailSessionSettingsPayload,
|
||||
buildPersistentSettingsPayload,
|
||||
broadcastDataUpdate,
|
||||
applyIpProxySettingsFromState,
|
||||
cancelScheduledAutoRun,
|
||||
checkIcloudSession,
|
||||
clearAccountRunHistory,
|
||||
@@ -58,6 +59,7 @@
|
||||
launchAutoRunTimerPlan,
|
||||
listIcloudAliases,
|
||||
listLuckmailPurchasesForManagement,
|
||||
refreshIpProxyPool,
|
||||
normalizeHotmailAccounts,
|
||||
normalizeMail2925Accounts,
|
||||
normalizeRunCount,
|
||||
@@ -69,11 +71,14 @@
|
||||
pollContributionStatus,
|
||||
registerTab,
|
||||
requestStop,
|
||||
probeIpProxyExit,
|
||||
handleCloudflareSecurityBlocked,
|
||||
resetState,
|
||||
resumeAutoRun,
|
||||
scheduleAutoRun,
|
||||
selectLuckmailPurchase,
|
||||
switchIpProxy,
|
||||
changeIpProxyExit,
|
||||
setCurrentMail2925Account,
|
||||
setCurrentHotmailAccount,
|
||||
setContributionMode,
|
||||
@@ -609,14 +614,138 @@
|
||||
}
|
||||
|
||||
case 'SAVE_SETTING': {
|
||||
const currentState = await getState();
|
||||
const updates = buildPersistentSettingsPayload(message.payload || {});
|
||||
const sessionUpdates = buildLuckmailSessionSettingsPayload(message.payload || {});
|
||||
const modeChanged = Object.prototype.hasOwnProperty.call(updates, 'plusModeEnabled')
|
||||
&& Boolean(currentState?.plusModeEnabled) !== Boolean(updates.plusModeEnabled);
|
||||
await setPersistentSettings(updates);
|
||||
await setState({
|
||||
const stateUpdates = {
|
||||
...updates,
|
||||
...sessionUpdates,
|
||||
};
|
||||
if (modeChanged && typeof getStepIdsForState === 'function') {
|
||||
const nextStateForSteps = { ...currentState, ...stateUpdates };
|
||||
stateUpdates.stepStatuses = Object.fromEntries(
|
||||
getStepIdsForState(nextStateForSteps).map((stepId) => [stepId, 'pending'])
|
||||
);
|
||||
stateUpdates.currentStep = 0;
|
||||
}
|
||||
await setState(stateUpdates);
|
||||
const mergedState = await getState();
|
||||
const hasIpProxyUpdates = Object.keys(updates).some((key) => key.startsWith('ipProxy'));
|
||||
const hasIpProxyEnabledUpdate = Object.prototype.hasOwnProperty.call(updates, 'ipProxyEnabled');
|
||||
const previousIpProxyEnabled = Boolean(currentState?.ipProxyEnabled);
|
||||
const nextIpProxyEnabled = hasIpProxyEnabledUpdate
|
||||
? Boolean(updates.ipProxyEnabled)
|
||||
: previousIpProxyEnabled;
|
||||
// 仅在“手动开关代理”时自动应用。
|
||||
// 其他字段改动(host/账号/地区/session 等)需由“同步/下一条/检测出口/Change”显式触发。
|
||||
const shouldApplyIpProxyOnSave = hasIpProxyUpdates
|
||||
&& hasIpProxyEnabledUpdate
|
||||
&& previousIpProxyEnabled !== nextIpProxyEnabled;
|
||||
let proxyRouting = null;
|
||||
if (shouldApplyIpProxyOnSave && typeof applyIpProxySettingsFromState === 'function') {
|
||||
const isEnablingProxy = !previousIpProxyEnabled && nextIpProxyEnabled;
|
||||
proxyRouting = await applyIpProxySettingsFromState(mergedState, {
|
||||
// 手动开启时自动应用一次代理,不做出口探测;
|
||||
// 出口探测由“同步/检测出口”按钮显式触发,避免开启即误判为失败。
|
||||
skipExitProbe: true,
|
||||
resetNetworkState: false,
|
||||
forceAuthRebind: false,
|
||||
suppressAuthRebind: !isEnablingProxy,
|
||||
}).catch((error) => ({
|
||||
applied: false,
|
||||
reason: 'apply_failed',
|
||||
error: error?.message || String(error || '代理应用失败'),
|
||||
}));
|
||||
}
|
||||
if (Boolean(currentState?.contributionMode) && typeof setContributionMode === 'function') {
|
||||
await setContributionMode(true);
|
||||
}
|
||||
if (modeChanged) {
|
||||
await addLog(
|
||||
Boolean(updates.plusModeEnabled)
|
||||
? 'Plus 模式已开启,已切换为 Plus Checkout + PayPal 步骤。'
|
||||
: 'Plus 模式已关闭,已恢复普通注册授权步骤。',
|
||||
'info'
|
||||
);
|
||||
}
|
||||
return { ok: true, state: await getState(), proxyRouting };
|
||||
}
|
||||
|
||||
case 'REFRESH_IP_PROXY_POOL': {
|
||||
if (typeof refreshIpProxyPool !== 'function') {
|
||||
throw new Error('IP 代理池能力尚未接入。');
|
||||
}
|
||||
const result = await refreshIpProxyPool({
|
||||
maxItems: message.payload?.maxItems,
|
||||
mode: message.payload?.mode,
|
||||
});
|
||||
return { ok: true, state: await getState() };
|
||||
return { ok: true, ...result };
|
||||
}
|
||||
|
||||
case 'SWITCH_IP_PROXY': {
|
||||
if (typeof switchIpProxy !== 'function') {
|
||||
throw new Error('IP 代理切换能力尚未接入。');
|
||||
}
|
||||
const result = await switchIpProxy(message.payload?.direction || 'next', {
|
||||
maxItems: message.payload?.maxItems,
|
||||
mode: message.payload?.mode,
|
||||
forceRefresh: message.payload?.forceRefresh,
|
||||
});
|
||||
return { ok: true, ...result };
|
||||
}
|
||||
|
||||
case 'CHANGE_IP_PROXY_EXIT': {
|
||||
if (typeof changeIpProxyExit !== 'function') {
|
||||
throw new Error('IP 代理 Change 能力尚未接入。');
|
||||
}
|
||||
const result = await changeIpProxyExit({
|
||||
mode: message.payload?.mode,
|
||||
});
|
||||
return { ok: true, ...result };
|
||||
}
|
||||
|
||||
case 'PROBE_IP_PROXY_EXIT': {
|
||||
if (typeof probeIpProxyExit !== 'function') {
|
||||
throw new Error('IP 代理出口检测能力尚未接入。');
|
||||
}
|
||||
const probeState = await getState();
|
||||
const mode = typeof normalizeIpProxyMode === 'function'
|
||||
? normalizeIpProxyMode(probeState?.ipProxyMode)
|
||||
: String(probeState?.ipProxyMode || 'account').trim().toLowerCase();
|
||||
const provider = typeof normalizeIpProxyProviderValue === 'function'
|
||||
? normalizeIpProxyProviderValue(probeState?.ipProxyService)
|
||||
: String(probeState?.ipProxyService || '').trim().toLowerCase();
|
||||
const is711AccountMode = mode === 'account' && provider === '711proxy';
|
||||
const previousReason = String(probeState?.ipProxyAppliedReason || '').trim().toLowerCase();
|
||||
const previousExitError = String(probeState?.ipProxyAppliedExitError || '').trim();
|
||||
const hadMissingAuthChallenge = /challenge=0|provided=0|未触发代理鉴权挑战|未收到 407/i.test(previousExitError);
|
||||
const shouldPreRebindBeforeProbe = Boolean(
|
||||
probeState?.ipProxyEnabled
|
||||
&& is711AccountMode
|
||||
&& (hadMissingAuthChallenge || previousReason === 'connectivity_failed')
|
||||
);
|
||||
const timeoutMs = Number(message.payload?.timeoutMs) > 0
|
||||
? Number(message.payload.timeoutMs)
|
||||
: (is711AccountMode ? (shouldPreRebindBeforeProbe ? 8000 : 6000) : undefined);
|
||||
|
||||
// 手动“检测出口”前先轻量应用当前配置,避免读取到旧代理链路状态。
|
||||
if (probeState?.ipProxyEnabled && typeof applyIpProxySettingsFromState === 'function') {
|
||||
await applyIpProxySettingsFromState(probeState, {
|
||||
skipExitProbe: true,
|
||||
resetNetworkState: shouldPreRebindBeforeProbe,
|
||||
forceAuthRebind: shouldPreRebindBeforeProbe,
|
||||
suppressAuthRebind: !shouldPreRebindBeforeProbe,
|
||||
}).catch(() => null);
|
||||
}
|
||||
|
||||
const result = await probeIpProxyExit({
|
||||
timeoutMs,
|
||||
authRebindMaxAttempts: is711AccountMode ? 1 : undefined,
|
||||
});
|
||||
return { ok: true, ...result };
|
||||
}
|
||||
|
||||
case 'EXPORT_SETTINGS': {
|
||||
|
||||
Reference in New Issue
Block a user