chore: merge latest dev into pr 208 fixes

This commit is contained in:
QLHazyCoder
2026-05-07 02:26:08 +08:00
28 changed files with 2713 additions and 44 deletions
+86 -1
View File
@@ -242,6 +242,7 @@ const DEFAULT_CODEX2API_URL = 'http://localhost:8080/admin/accounts';
const DEFAULT_GPC_HELPER_API_URL = 'https://gopay.hwork.pro';
const DEFAULT_SUB2API_GROUP_NAME = 'codex';
const DEFAULT_SUB2API_PROXY_NAME = '';
const DEFAULT_SUB2API_ACCOUNT_PRIORITY = 1;
const CONTRIBUTION_SOURCE_CPA = 'cpa';
const CONTRIBUTION_SOURCE_SUB2API = 'sub2api';
const CONTRIBUTION_SUB2API_DEFAULT_GROUP_NAME = 'codex号池';
@@ -574,6 +575,7 @@ const PERSISTED_SETTING_DEFAULTS = {
sub2apiPassword: '',
sub2apiGroupName: DEFAULT_SUB2API_GROUP_NAME,
sub2apiGroupNames: DEFAULT_SUB2API_GROUP_NAMES,
sub2apiAccountPriority: DEFAULT_SUB2API_ACCOUNT_PRIORITY,
sub2apiDefaultProxyName: DEFAULT_SUB2API_PROXY_NAME,
ipProxyEnabled: false,
ipProxyService: DEFAULT_IP_PROXY_SERVICE,
@@ -632,6 +634,8 @@ const PERSISTED_SETTING_DEFAULTS = {
autoRunDelayMinutes: 30,
autoStepDelaySeconds: null,
phoneVerificationEnabled: false,
freePhoneReuseEnabled: true,
freePhoneReuseAutoEnabled: true,
signupMethod: DEFAULT_SIGNUP_METHOD,
phoneSmsProvider: DEFAULT_PHONE_SMS_PROVIDER,
phoneSmsProviderOrder: [],
@@ -798,6 +802,7 @@ const DEFAULT_STATE = {
currentPhoneVerificationCountdownWindowIndex: 0,
currentPhoneVerificationCountdownWindowTotal: 0,
reusablePhoneActivation: null,
freeReusablePhoneActivation: null,
phoneReusableActivationPool: [],
signupPhoneNumber: '',
signupPhoneActivation: null,
@@ -2105,6 +2110,18 @@ function normalizeSub2ApiGroupNames(value = '') {
return names;
}
function normalizeSub2ApiAccountPriority(value, fallback = DEFAULT_SUB2API_ACCOUNT_PRIORITY) {
const rawValue = String(value ?? '').trim();
const numeric = Number(rawValue);
if (!rawValue || !Number.isSafeInteger(numeric) || numeric < 1) {
const fallbackNumber = Number(fallback);
return Number.isSafeInteger(fallbackNumber) && fallbackNumber >= 1
? fallbackNumber
: DEFAULT_SUB2API_ACCOUNT_PRIORITY;
}
return numeric;
}
function normalizePersistentSettingValue(key, value) {
switch (key) {
case 'panelMode':
@@ -2125,6 +2142,8 @@ function normalizePersistentSettingValue(key, value) {
return String(value || '').trim();
case 'sub2apiGroupNames':
return normalizeSub2ApiGroupNames(value);
case 'sub2apiAccountPriority':
return normalizeSub2ApiAccountPriority(value);
case 'sub2apiDefaultProxyName':
return String(value || '').trim();
case 'ipProxyEnabled':
@@ -2286,6 +2305,8 @@ function normalizePersistentSettingValue(key, value) {
case 'gopayHelperLocalSmsHelperEnabled':
case 'autoRunDelayEnabled':
case 'phoneVerificationEnabled':
case 'freePhoneReuseEnabled':
case 'freePhoneReuseAutoEnabled':
case 'plusModeEnabled':
return Boolean(value);
case 'phoneSmsProvider':
@@ -3093,6 +3114,7 @@ async function resetState() {
'tabRegistry',
'sourceLastUrls',
'reusablePhoneActivation',
'freeReusablePhoneActivation',
'phoneReusableActivationPool',
'luckmailApiKey',
'luckmailBaseUrl',
@@ -3132,6 +3154,19 @@ async function resetState() {
.map((entry) => normalizePhonePreferredActivation(entry))
.filter(Boolean)
: [];
const freeReusablePhoneActivation = (
prev.freeReusablePhoneActivation
&& typeof prev.freeReusablePhoneActivation === 'object'
&& !Array.isArray(prev.freeReusablePhoneActivation)
&& String(
prev.freeReusablePhoneActivation.phoneNumber
?? prev.freeReusablePhoneActivation.number
?? prev.freeReusablePhoneActivation.phone
?? ''
).trim()
)
? prev.freeReusablePhoneActivation
: null;
await chrome.storage.session.clear();
await chrome.storage.session.set({
...DEFAULT_STATE,
@@ -3154,6 +3189,8 @@ async function resetState() {
currentLuckmailMailCursor: null,
// Keep reusable phone activation across round resets so the same number can be reactivated up to maxUses.
reusablePhoneActivation,
// Keep free reuse phone activation until the user clears or the flow retires it.
freeReusablePhoneActivation,
phoneReusableActivationPool,
preferredIcloudHost: prev.preferredIcloudHost || '',
});
@@ -5448,7 +5485,6 @@ async function withIcloudLoginHelp(actionLabel, action) {
if (shouldEmitIcloudTransientLog(`${safeActionLabel}:final`)) {
await addLog(`iCloud${safeActionLabel}受网络/上下文波动影响:${getErrorMessage(err)}`, 'warn');
}
const safeActionLabel = String(actionLabel || '操作').trim() || '操作';
const transientError = new Error(`iCloud${safeActionLabel}受网络/上下文波动影响,请稍后重试。`);
transientError.code = 'ICLOUD_TRANSIENT_CONTEXT';
transientError.actionLabel = safeActionLabel;
@@ -6613,6 +6649,53 @@ async function finalizePhoneActivationAfterSuccessfulFlow(state) {
return phoneVerificationHelpers.finalizePendingPhoneActivationConfirmation(state);
}
async function clearFreeReusablePhoneActivation() {
await setState({ freeReusablePhoneActivation: null });
broadcastDataUpdate({ freeReusablePhoneActivation: null });
await addLog('已清除白嫖复用手机号记录。', 'ok');
return { ok: true, freeReusablePhoneActivation: null };
}
async function setFreeReusablePhoneActivation(record = {}) {
const phoneNumber = String(record.phoneNumber || record.number || record.phone || '').trim();
if (!phoneNumber) {
throw new Error('请先填写白嫖复用手机号。');
}
const state = await getState();
const activationId = String(record.activationId || record.id || record.activation || '').trim();
const countryId = Math.max(1, Math.floor(Number(record.countryId) || Number(state.heroSmsCountryId) || HERO_SMS_COUNTRY_ID));
const stateCountryLabel = Math.floor(Number(state.heroSmsCountryId) || 0) === countryId
? String(state.heroSmsCountryLabel || '').trim()
: '';
const countryLabel = String(
record.countryLabel
|| stateCountryLabel
|| (countryId === HERO_SMS_COUNTRY_ID ? HERO_SMS_COUNTRY_LABEL : `Country #${countryId}`)
).trim();
const activation = {
...(activationId ? { activationId } : {}),
phoneNumber,
provider: PHONE_SMS_PROVIDER_HERO,
serviceCode: HERO_SMS_SERVICE_CODE,
countryId,
...(countryLabel ? { countryLabel } : {}),
successfulUses: Math.max(0, Math.floor(Number(record.successfulUses) || 0)),
maxUses: Math.max(1, Math.floor(Number(record.maxUses) || 3)),
source: 'free-manual-reuse',
recordedAt: Date.now(),
manualOnly: !activationId,
};
await setState({ freeReusablePhoneActivation: activation });
broadcastDataUpdate({ freeReusablePhoneActivation: activation });
await addLog(
activationId
? `已手动记录白嫖复用手机号 ${phoneNumber}#${activationId})。`
: `已手动记录白嫖复用手机号 ${phoneNumber}。未填写 HeroSMS 激活 ID,仅支持手动填号复用。`,
'ok'
);
return { ok: true, freeReusablePhoneActivation: activation };
}
// ============================================================
// Tab Registry
// ============================================================
@@ -10689,6 +10772,7 @@ const messageRouter = self.MultiPageBackgroundMessageRouter?.createMessageRouter
clearAccountRunHistory: (...args) => clearAndBroadcastAccountRunHistory(...args),
deleteAccountRunHistoryRecords: (...args) => deleteAndBroadcastAccountRunHistoryRecords(...args),
clearAutoRunTimerAlarm,
clearFreeReusablePhoneActivation,
clearLuckmailRuntimeState,
clearStopRequest,
closeLocalhostCallbackTabs,
@@ -10777,6 +10861,7 @@ const messageRouter = self.MultiPageBackgroundMessageRouter?.createMessageRouter
setContributionMode,
setEmailState,
setEmailStateSilently,
setFreeReusablePhoneActivation,
setSignupPhoneState,
setSignupPhoneStateSilently,
setIcloudAliasPreservedState,