diff --git a/background.js b/background.js index 0f5aea1..3d4fc59 100644 --- a/background.js +++ b/background.js @@ -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::'; @@ -263,6 +265,7 @@ const PERSISTED_SETTING_DEFAULTS = { mail2925Mode: DEFAULT_MAIL_2925_MODE, mail2925UseAccountPool: false, emailGenerator: 'duck', + customEmailPool: [], autoDeleteUsedIcloudAlias: false, icloudHostPreference: 'auto', accountRunHistoryTextEnabled: false, @@ -640,9 +643,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'; } @@ -651,6 +666,36 @@ 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 normalizePanelMode(value = '') { return String(value || '').trim().toLowerCase() === 'sub2api' ? 'sub2api' : 'cpa'; } @@ -894,6 +939,8 @@ function normalizePersistentSettingValue(key, value) { return Boolean(value); case 'emailGenerator': return normalizeEmailGenerator(value); + case 'customEmailPool': + return normalizeCustomEmailPool(value); case 'autoDeleteUsedIcloudAlias': case 'accountRunHistoryTextEnabled': return Boolean(value); @@ -2130,6 +2177,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; @@ -2287,6 +2346,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; @@ -4999,7 +5070,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; @@ -5413,9 +5489,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 隐私邮箱'; } @@ -5515,11 +5603,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, @@ -5762,6 +5852,21 @@ async function ensureAutoEmailReady(targetRun, totalRuns, attemptRuns) { return currentState.email; } + 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', { @@ -5880,6 +5985,21 @@ async function ensureAutoEmailReady(targetRun, totalRuns, attemptRuns) { return currentState.email; } + 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', { diff --git a/background/generated-email-helpers.js b/background/generated-email-helpers.js index 3d924a7..f5ec2b3 100644 --- a/background/generated-email-helpers.js +++ b/background/generated-email-helpers.js @@ -7,11 +7,13 @@ buildGeneratedAliasEmail, buildCloudflareTempEmailHeaders, CLOUDFLARE_TEMP_EMAIL_GENERATOR, + CUSTOM_EMAIL_POOL_GENERATOR, DUCK_AUTOFILL_URL, fetch, fetchIcloudHideMyEmail, getCloudflareTempEmailAddressFromResponse, getCloudflareTempEmailConfig, + getCustomEmailPoolEmail, getState, ensureMail2925AccountForFlow, joinCloudflareTempEmailUrl, @@ -188,6 +190,24 @@ return result.email; } + async function fetchCustomEmailPoolEmail(state, options = {}) { + throwIfStopped(); + const latestState = state || await getState(); + const requestedIndex = Math.max(0, Math.floor(Number(options.poolIndex) || 0)); + const email = String(getCustomEmailPoolEmail?.(latestState, requestedIndex + 1) || '').trim().toLowerCase(); + if (!email) { + throw new Error( + requestedIndex > 0 + ? `自定义邮箱池第 ${requestedIndex + 1} 个邮箱不存在,请检查邮箱池配置。` + : '自定义邮箱池为空,请先至少填写 1 个邮箱。' + ); + } + + await setEmailState(email); + await addLog(`自定义邮箱池:已取用 ${email}`, 'ok'); + return email; + } + async function fetchManagedAliasEmail(state, options = {}) { throwIfStopped(); const provider = String(options.mailProvider || state?.mailProvider || '').trim().toLowerCase(); @@ -233,13 +253,19 @@ const mail2925Mode = options.mail2925Mode !== undefined ? options.mail2925Mode : currentState.mail2925Mode; - if (isGeneratedAliasProvider?.(provider, mail2925Mode)) { - return fetchManagedAliasEmail(currentState, options); - } const generator = normalizeEmailGenerator(options.generator ?? currentState.emailGenerator); if (generator === 'custom') { throw new Error('当前邮箱生成方式为自定义邮箱,请直接填写注册邮箱。'); } + if (generator === CUSTOM_EMAIL_POOL_GENERATOR) { + return fetchCustomEmailPoolEmail(currentState, options); + } + const shouldUseManagedAlias = typeof isGeneratedAliasProvider === 'function' + ? isGeneratedAliasProvider(currentState, mail2925Mode) + : false; + if (shouldUseManagedAlias) { + return fetchManagedAliasEmail(currentState, options); + } if (generator === 'icloud') { return fetchIcloudHideMyEmail(); } @@ -255,6 +281,7 @@ return { ensureCloudflareTempEmailConfig, fetchCloudflareEmail, + fetchCustomEmailPoolEmail, fetchCloudflareTempEmailAddress, fetchDuckEmail, fetchGeneratedEmail, diff --git a/sidepanel/sidepanel.html b/sidepanel/sidepanel.html index 835ae4b..0f3128d 100644 --- a/sidepanel/sidepanel.html +++ b/sidepanel/sidepanel.html @@ -229,12 +229,19 @@
邮箱生成
+