merge: sync origin/dev into pr-112

This commit is contained in:
Ryan Liu
2026-04-24 09:35:07 +08:00
22 changed files with 1698 additions and 84 deletions
+160 -1
View File
@@ -139,10 +139,12 @@ const ICLOUD_LOGIN_URLS = [
];
const ICLOUD_PROVIDER = 'icloud';
const GMAIL_PROVIDER = 'gmail';
const GMAIL_ALIAS_GENERATOR = 'gmail-alias';
const HOTMAIL_PROVIDER = 'hotmail-api';
const LUCKMAIL_PROVIDER = 'luckmail-api';
const CLOUDFLARE_TEMP_EMAIL_PROVIDER = 'cloudflare-temp-email';
const CLOUDFLARE_TEMP_EMAIL_GENERATOR = 'cloudflare-temp-email';
const CUSTOM_EMAIL_POOL_GENERATOR = 'custom-pool';
const HOTMAIL_MAILBOXES = ['INBOX', 'Junk'];
const STOP_ERROR_MESSAGE = '流程已被用户停止。';
const CLOUDFLARE_SECURITY_BLOCK_ERROR_PREFIX = 'CF_SECURITY_BLOCKED::';
@@ -266,6 +268,8 @@ const PERSISTED_SETTING_DEFAULTS = {
mail2925Mode: DEFAULT_MAIL_2925_MODE,
mail2925UseAccountPool: false,
emailGenerator: 'duck',
customMailProviderPool: [],
customEmailPool: [],
autoDeleteUsedIcloudAlias: false,
icloudHostPreference: 'auto',
accountRunHistoryTextEnabled: false,
@@ -647,9 +651,21 @@ function getAutoRunTimerStatusPayload(plan) {
function normalizeEmailGenerator(value = '') {
const normalized = String(value || '').trim().toLowerCase();
const customEmailPoolGenerator = typeof CUSTOM_EMAIL_POOL_GENERATOR === 'string'
? CUSTOM_EMAIL_POOL_GENERATOR
: 'custom-pool';
const gmailAliasGenerator = typeof GMAIL_ALIAS_GENERATOR === 'string'
? GMAIL_ALIAS_GENERATOR
: 'gmail-alias';
if (normalized === 'custom' || normalized === 'manual') {
return 'custom';
}
if (normalized === gmailAliasGenerator) {
return gmailAliasGenerator;
}
if (normalized === customEmailPoolGenerator) {
return customEmailPoolGenerator;
}
if (normalized === 'icloud') {
return 'icloud';
}
@@ -658,6 +674,46 @@ function normalizeEmailGenerator(value = '') {
return 'duck';
}
function normalizeCustomEmailPool(value = []) {
const source = Array.isArray(value)
? value
: String(value || '').split(/[\r\n,;]+/);
return source
.map((item) => String(item || '').trim().toLowerCase())
.filter((item) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(item));
}
function isCustomEmailPoolGenerator(stateOrValue = {}) {
const generator = typeof stateOrValue === 'string'
? stateOrValue
: stateOrValue?.emailGenerator;
const customEmailPoolGenerator = typeof CUSTOM_EMAIL_POOL_GENERATOR === 'string'
? CUSTOM_EMAIL_POOL_GENERATOR
: 'custom-pool';
return normalizeEmailGenerator(generator) === customEmailPoolGenerator;
}
function getCustomEmailPool(state = {}) {
return normalizeCustomEmailPool(state?.customEmailPool);
}
function getCustomEmailPoolEmailForRun(state = {}, targetRun = 1) {
const entries = getCustomEmailPool(state);
const numericRun = Math.max(1, Math.floor(Number(targetRun) || 1));
return entries[numericRun - 1] || '';
}
function getCustomMailProviderPool(state = {}) {
return normalizeCustomEmailPool(state?.customMailProviderPool);
}
function getCustomMailProviderPoolEmailForRun(state = {}, targetRun = 1) {
const entries = getCustomMailProviderPool(state);
const numericRun = Math.max(1, Math.floor(Number(targetRun) || 1));
return entries[numericRun - 1] || '';
}
function normalizePanelMode(value = '') {
const normalized = String(value || '').trim().toLowerCase();
if (normalized === 'sub2api') {
@@ -914,6 +970,9 @@ function normalizePersistentSettingValue(key, value) {
return Boolean(value);
case 'emailGenerator':
return normalizeEmailGenerator(value);
case 'customMailProviderPool':
case 'customEmailPool':
return normalizeCustomEmailPool(value);
case 'autoDeleteUsedIcloudAlias':
case 'accountRunHistoryTextEnabled':
case 'cloudflareTempEmailUseRandomSubdomain':
@@ -2152,6 +2211,18 @@ function parseGmailBaseEmail(rawValue) {
}
function isGeneratedAliasProvider(stateOrProvider, mail2925Mode = undefined) {
if (
stateOrProvider
&& typeof stateOrProvider === 'object'
&& !Array.isArray(stateOrProvider)
&& normalizeEmailGenerator(stateOrProvider.emailGenerator) === (
typeof CUSTOM_EMAIL_POOL_GENERATOR === 'string'
? CUSTOM_EMAIL_POOL_GENERATOR
: 'custom-pool'
)
) {
return false;
}
const provider = typeof stateOrProvider === 'string'
? stateOrProvider
: stateOrProvider?.mailProvider;
@@ -2309,6 +2380,18 @@ function getManagedAliasBaseEmail(state = {}, provider = state?.mailProvider) {
}
function isGeneratedAliasProvider(stateOrProvider, mail2925Mode = undefined) {
if (
stateOrProvider
&& typeof stateOrProvider === 'object'
&& !Array.isArray(stateOrProvider)
&& normalizeEmailGenerator(stateOrProvider.emailGenerator) === (
typeof CUSTOM_EMAIL_POOL_GENERATOR === 'string'
? CUSTOM_EMAIL_POOL_GENERATOR
: 'custom-pool'
)
) {
return false;
}
const provider = typeof stateOrProvider === 'string'
? stateOrProvider
: stateOrProvider?.mailProvider;
@@ -5054,7 +5137,12 @@ async function handleStepData(step, payload) {
});
}
await finalizeIcloudAliasAfterSuccessfulFlow(latestState);
if (shouldUseCustomRegistrationEmail(latestState) && latestState.email) {
const shouldClearCustomPoolEmail = String(latestState?.emailGenerator || '').trim().toLowerCase() === (
typeof CUSTOM_EMAIL_POOL_GENERATOR === 'string'
? CUSTOM_EMAIL_POOL_GENERATOR
: 'custom-pool'
);
if ((shouldUseCustomRegistrationEmail(latestState) || shouldClearCustomPoolEmail) && latestState.email) {
await setEmailStateSilently(null);
}
break;
@@ -5468,9 +5556,21 @@ async function executeStepAndWait(step, delayAfter = 2000) {
}
function getEmailGeneratorLabel(generator) {
const customEmailPoolGenerator = typeof CUSTOM_EMAIL_POOL_GENERATOR === 'string'
? CUSTOM_EMAIL_POOL_GENERATOR
: 'custom-pool';
const gmailAliasGenerator = typeof GMAIL_ALIAS_GENERATOR === 'string'
? GMAIL_ALIAS_GENERATOR
: 'gmail-alias';
if (generator === 'custom') {
return '自定义邮箱';
}
if (generator === gmailAliasGenerator) {
return 'Gmail +tag 邮箱';
}
if (generator === customEmailPoolGenerator) {
return '自定义邮箱池';
}
if (generator === 'icloud') {
return 'iCloud 隐私邮箱';
}
@@ -5571,11 +5671,13 @@ const generatedEmailHelpers = self.MultiPageGeneratedEmailHelpers?.createGenerat
buildGeneratedAliasEmail,
buildCloudflareTempEmailHeaders,
CLOUDFLARE_TEMP_EMAIL_GENERATOR,
CUSTOM_EMAIL_POOL_GENERATOR,
DUCK_AUTOFILL_URL,
fetch,
fetchIcloudHideMyEmail,
getCloudflareTempEmailAddressFromResponse,
getCloudflareTempEmailConfig,
getCustomEmailPoolEmail: getCustomEmailPoolEmailForRun,
getState,
ensureMail2925AccountForFlow,
joinCloudflareTempEmailUrl,
@@ -5818,6 +5920,34 @@ async function ensureAutoEmailReady(targetRun, totalRuns, attemptRuns) {
return currentState.email;
}
if (isCustomMailProvider(currentState)) {
const poolSize = getCustomMailProviderPool(currentState).length;
if (poolSize > 0) {
const queuedEmail = getCustomMailProviderPoolEmailForRun(currentState, targetRun);
if (!queuedEmail) {
throw new Error(`自定义邮箱号池第 ${targetRun} 个邮箱不存在,请检查号池数量是否与自动轮数一致。`);
}
await setEmailState(queuedEmail);
await addLog(`=== 目标 ${targetRun}/${totalRuns} 轮:自定义邮箱号池已就绪:${queuedEmail}(第 ${attemptRuns} 次尝试;第 4/8 步仍需手动输入验证码)===`, 'ok');
return queuedEmail;
}
}
if (isCustomEmailPoolGenerator(currentState)) {
const queuedEmail = getCustomEmailPoolEmailForRun(currentState, targetRun);
if (!queuedEmail) {
const poolSize = getCustomEmailPool(currentState).length;
throw new Error(
poolSize > 0
? `自定义邮箱池第 ${targetRun} 个邮箱不存在,请检查邮箱池数量是否与自动轮数一致。`
: '自定义邮箱池为空,请先至少填写 1 个邮箱。'
);
}
await setEmailState(queuedEmail);
await addLog(`=== 目标 ${targetRun}/${totalRuns} 轮:自定义邮箱池已就绪:${queuedEmail}(第 ${attemptRuns} 次尝试)===`, 'ok');
return queuedEmail;
}
if (shouldUseCustomRegistrationEmail(currentState)) {
await addLog(`=== 目标 ${targetRun}/${totalRuns} 轮已暂停:请先填写自定义注册邮箱,然后继续 ===`, 'warn');
await broadcastAutoRunStatus('waiting_email', {
@@ -5936,6 +6066,34 @@ async function ensureAutoEmailReady(targetRun, totalRuns, attemptRuns) {
return currentState.email;
}
if (isCustomMailProvider(currentState)) {
const poolSize = getCustomMailProviderPool(currentState).length;
if (poolSize > 0) {
const queuedEmail = getCustomMailProviderPoolEmailForRun(currentState, targetRun);
if (!queuedEmail) {
throw new Error(`自定义邮箱号池第 ${targetRun} 个邮箱不存在,请检查号池数量是否与自动轮数一致。`);
}
await setEmailState(queuedEmail);
await addLog(`=== 目标 ${targetRun}/${totalRuns} 轮:自定义邮箱号池已就绪:${queuedEmail}(第 ${attemptRuns} 次尝试;第 4/8 步仍需手动输入验证码)===`, 'ok');
return queuedEmail;
}
}
if (isCustomEmailPoolGenerator(currentState)) {
const queuedEmail = getCustomEmailPoolEmailForRun(currentState, targetRun);
if (!queuedEmail) {
const poolSize = getCustomEmailPool(currentState).length;
throw new Error(
poolSize > 0
? `自定义邮箱池第 ${targetRun} 个邮箱不存在,请检查邮箱池数量是否与自动轮数一致。`
: '自定义邮箱池为空,请先至少填写 1 个邮箱。'
);
}
await setEmailState(queuedEmail);
await addLog(`=== 目标 ${targetRun}/${totalRuns} 轮:自定义邮箱池已就绪:${queuedEmail}(第 ${attemptRuns} 次尝试)===`, 'ok');
return queuedEmail;
}
if (shouldUseCustomRegistrationEmail(currentState)) {
await addLog(`=== 目标 ${targetRun}/${totalRuns} 轮已暂停:请先填写自定义注册邮箱,然后继续 ===`, 'warn');
await broadcastAutoRunStatus('waiting_email', {
@@ -6259,6 +6417,7 @@ const signupFlowHelpers = self.MultiPageSignupFlowHelpers?.createSignupFlowHelpe
isGeneratedAliasProvider,
isReusableGeneratedAliasEmail,
isSignupEmailVerificationPageUrl,
isRetryableContentScriptTransportError,
isHotmailProvider,
isLuckmailProvider,
isSignupPasswordPageUrl,