feat: 新增 YYDS Mail 邮箱服务端点

This commit is contained in:
Q3CC
2026-05-16 21:58:14 +08:00
parent cfd2ac14e5
commit b2c8280476
14 changed files with 1211 additions and 3 deletions
+25
View File
@@ -420,6 +420,7 @@
<option value="custom">自定义邮箱</option>
<option value="hotmail-api">Hotmail(账号池)</option>
<option value="luckmail-api">LuckMailAPI 购邮)</option>
<option value="yyds-mail">YYDS Mail</option>
<option value="icloud">iCloud 邮箱</option>
<option value="163">163 邮箱 (mail.163.com) 版本老旧,请自行维护使用</option>
<option value="163-vip">163 VIP 邮箱 (vip.163.com) 版本老旧,请自行维护使用</option>
@@ -778,6 +779,29 @@
<input type="text" id="input-cloud-mail-domain" class="data-input" placeholder="例如 mail.example.com" />
</div>
</div>
<div id="yyds-mail-section" class="data-card hotmail-card" style="display:none;">
<div class="section-mini-header">
<div class="section-mini-copy">
<span class="section-label">YYDS Mail</span>
<span class="data-value">自动创建临时邮箱并通过 API 收取验证码</span>
</div>
</div>
<div class="data-row">
<span class="data-label">API Key</span>
<div class="input-with-icon">
<input type="password" id="input-yyds-mail-api-key" class="data-input data-input-with-icon mono"
placeholder="请输入 YYDS Mail API KeyAC-..." />
<button id="btn-toggle-yyds-mail-api-key" class="input-icon-btn" type="button"
data-password-toggle="input-yyds-mail-api-key" data-show-label="显示 YYDS Mail API Key"
data-hide-label="隐藏 YYDS Mail API Key" aria-label="显示 YYDS Mail API Key" title="显示 YYDS Mail API Key"></button>
</div>
</div>
<div class="data-row">
<span class="data-label">Base URL</span>
<input type="text" id="input-yyds-mail-base-url" class="data-input mono"
placeholder="https://maliapi.215.im/v1" />
</div>
</div>
<div id="hotmail-section" class="data-card hotmail-card" style="display:none;">
<div class="section-mini-header">
<div class="section-mini-copy">
@@ -1764,6 +1788,7 @@
<script src="../mail-provider-utils.js"></script>
<script src="../hotmail-utils.js"></script>
<script src="../luckmail-utils.js"></script>
<script src="../yyds-mail-utils.js"></script>
<script src="../shared/flow-capabilities.js"></script>
<script src="../data/step-definitions.js"></script>
<script src="update-service.js"></script>
+97 -3
View File
@@ -274,6 +274,9 @@ const inputCloudMailAdminEmail = document.getElementById('input-cloud-mail-admin
const inputCloudMailAdminPassword = document.getElementById('input-cloud-mail-admin-password');
const inputCloudMailReceiveMailbox = document.getElementById('input-cloud-mail-receive-mailbox');
const inputCloudMailDomain = document.getElementById('input-cloud-mail-domain');
const yydsMailSection = document.getElementById('yyds-mail-section');
const inputYydsMailApiKey = document.getElementById('input-yyds-mail-api-key');
const inputYydsMailBaseUrl = document.getElementById('input-yyds-mail-base-url');
const hotmailSection = document.getElementById('hotmail-section');
const mail2925Section = document.getElementById('mail2925-section');
const luckmailSection = document.getElementById('luckmail-section');
@@ -971,9 +974,11 @@ const ICLOUD_PROVIDER = 'icloud';
const GMAIL_PROVIDER = 'gmail';
const GMAIL_ALIAS_GENERATOR = 'gmail-alias';
const LUCKMAIL_PROVIDER = 'luckmail-api';
const YYDS_MAIL_PROVIDER = 'yyds-mail';
const CUSTOM_EMAIL_POOL_GENERATOR = 'custom-pool';
const DEFAULT_LUCKMAIL_BASE_URL = 'https://mails.luckyous.com';
const DEFAULT_LUCKMAIL_EMAIL_TYPE = 'ms_graph';
const DEFAULT_YYDS_MAIL_BASE_URL = window.YydsMailUtils?.DEFAULT_YYDS_MAIL_BASE_URL || 'https://maliapi.215.im/v1';
const DISPLAY_TIMEZONE = 'Asia/Shanghai';
const DEFAULT_ACCOUNT_RUN_HISTORY_HELPER_BASE_URL = 'http://127.0.0.1:17373';
const CONTRIBUTION_UPLOAD_URL = 'https://flowpilot.qlhazycoder.top/';
@@ -1210,6 +1215,17 @@ function getCurrentRegistrationEmailUiCopy() {
if (isCustomMailProvider()) {
return getCustomMailProviderUiCopy();
}
const useYydsMail = typeof isYydsMailProvider === 'function'
? isYydsMailProvider()
: String(selectMailProvider.value || '').trim().toLowerCase() === 'yyds-mail';
if (useYydsMail) {
return {
buttonLabel: '获取',
placeholder: '点击获取 YYDS Mail 邮箱,或手动粘贴邮箱',
successVerb: '获取',
label: 'YYDS Mail',
};
}
if (usesGeneratedAliasMailProvider()) {
return getManagedAliasProviderUiCopy();
}
@@ -1554,6 +1570,11 @@ const MAIL_PROVIDER_LOGIN_CONFIGS = {
url: 'https://github.com/QLHazyCoder/cloudflare_temp_email',
buttonLabel: '部署',
},
[YYDS_MAIL_PROVIDER]: {
label: 'YYDS Mail',
url: 'https://vip.215.im/docs',
buttonLabel: '文档',
},
'2925': {
label: '2925 邮箱',
url: 'https://2925.com/#/mailList',
@@ -2860,8 +2881,12 @@ function restoreCustomEmailPoolEntriesFromState(state = {}) {
}
function usesCustomEmailPoolGenerator(provider = selectMailProvider.value) {
const providerUsesYydsMail = typeof isYydsMailProvider === 'function'
? isYydsMailProvider(provider)
: String(provider || '').trim().toLowerCase() === 'yyds-mail';
return !isCustomMailProvider(provider)
&& !isLuckmailProvider(provider)
&& !providerUsesYydsMail
&& getSelectedEmailGenerator() === CUSTOM_EMAIL_POOL_GENERATOR;
}
@@ -3207,10 +3232,25 @@ function applyCloudMailSettingsState(state = {}) {
}
}
function applyYydsMailSettingsState(state = {}) {
const normalizeYydsBaseUrlValue = typeof normalizeYydsMailBaseUrl === 'function'
? normalizeYydsMailBaseUrl
: ((value) => String(value || '').trim() || 'https://maliapi.215.im/v1');
if (inputYydsMailApiKey) {
inputYydsMailApiKey.value = state?.yydsMailApiKey || '';
}
if (inputYydsMailBaseUrl) {
inputYydsMailBaseUrl.value = normalizeYydsBaseUrlValue(state?.yydsMailBaseUrl);
}
}
function collectSettingsPayload() {
const defaultGpcHelperApiUrl = typeof DEFAULT_GPC_HELPER_API_URL !== 'undefined'
? DEFAULT_GPC_HELPER_API_URL
: 'https://gpc.qlhazycoder.top';
const normalizeYydsBaseUrlValue = typeof normalizeYydsMailBaseUrl === 'function'
? normalizeYydsMailBaseUrl
: ((value) => String(value || '').trim() || 'https://maliapi.215.im/v1');
const { domains, activeDomain } = getCloudflareDomainsFromState();
const selectedCloudflareDomain = normalizeCloudflareDomainValue(
!cloudflareDomainEditMode ? selectCfDomain.value : activeDomain
@@ -3981,6 +4021,8 @@ function collectSettingsPayload() {
cloudMailAdminPassword: (typeof inputCloudMailAdminPassword !== 'undefined' && inputCloudMailAdminPassword) ? inputCloudMailAdminPassword.value : '',
cloudMailReceiveMailbox: normalizeCloudMailReceiveMailboxInput((typeof inputCloudMailReceiveMailbox !== 'undefined' && inputCloudMailReceiveMailbox) ? inputCloudMailReceiveMailbox.value : ''),
cloudMailDomain: normalizeCloudMailDomainInput((typeof inputCloudMailDomain !== 'undefined' && inputCloudMailDomain) ? inputCloudMailDomain.value : ''),
yydsMailApiKey: (typeof inputYydsMailApiKey !== 'undefined' && inputYydsMailApiKey) ? inputYydsMailApiKey.value.trim() : '',
yydsMailBaseUrl: normalizeYydsBaseUrlValue((typeof inputYydsMailBaseUrl !== 'undefined' && inputYydsMailBaseUrl) ? inputYydsMailBaseUrl.value : ''),
autoRunSkipFailures: inputAutoSkipFailures.checked,
autoRunFallbackThreadIntervalMinutes: normalizeAutoRunThreadIntervalMinutes(inputAutoSkipFailuresThreadIntervalMinutes.value),
step6CookieCleanupEnabled: typeof inputStep6CookieCleanupEnabled !== 'undefined' && inputStep6CookieCleanupEnabled
@@ -9359,8 +9401,11 @@ function applySettingsState(state) {
}
inputCodex2ApiUrl.value = state?.codex2apiUrl || '';
inputCodex2ApiAdminKey.value = state?.codex2apiAdminKey || '';
const yydsMailProvider = typeof YYDS_MAIL_PROVIDER === 'string'
? YYDS_MAIL_PROVIDER
: 'yyds-mail';
const restoredMailProvider = isCustomMailProvider(state?.mailProvider)
|| [ICLOUD_PROVIDER, 'hotmail-api', GMAIL_PROVIDER, 'luckmail-api', '163', '163-vip', '126', 'qq', 'inbucket', '2925', 'cloudflare-temp-email', 'cloudmail'].includes(String(state?.mailProvider || '').trim())
|| [ICLOUD_PROVIDER, 'hotmail-api', GMAIL_PROVIDER, 'luckmail-api', yydsMailProvider, '163', '163-vip', '126', 'qq', 'inbucket', '2925', 'cloudflare-temp-email', 'cloudmail'].includes(String(state?.mailProvider || '').trim())
? String(state?.mailProvider || '163').trim()
: (String(state?.emailGenerator || '').trim().toLowerCase() === 'custom'
|| String(state?.emailGenerator || '').trim().toLowerCase() === 'manual'
@@ -9442,6 +9487,9 @@ function applySettingsState(state) {
if (typeof applyCloudMailSettingsState === 'function') {
applyCloudMailSettingsState(state);
}
if (typeof applyYydsMailSettingsState === 'function') {
applyYydsMailSettingsState(state);
}
renderCloudflareDomainOptions(state?.cloudflareDomain || '');
setCloudflareDomainEditMode(false, { clearInput: true });
inputAutoSkipFailures.checked = Boolean(state?.autoRunSkipFailures);
@@ -10157,6 +10205,13 @@ function isLuckmailProvider(provider = selectMailProvider.value) {
return String(provider || '').trim().toLowerCase() === LUCKMAIL_PROVIDER;
}
function isYydsMailProvider(provider = selectMailProvider.value) {
const yydsMailProvider = typeof YYDS_MAIL_PROVIDER === 'string'
? YYDS_MAIL_PROVIDER
: 'yyds-mail';
return String(provider || '').trim().toLowerCase() === yydsMailProvider;
}
function isIcloudMailProvider(provider = selectMailProvider.value) {
return String(provider || '').trim().toLowerCase() === ICLOUD_PROVIDER;
}
@@ -10188,6 +10243,29 @@ function normalizeLuckmailEmailType(value = '') {
: DEFAULT_LUCKMAIL_EMAIL_TYPE;
}
function normalizeYydsMailBaseUrl(value = '') {
if (window.YydsMailUtils?.normalizeYydsMailBaseUrl) {
return window.YydsMailUtils.normalizeYydsMailBaseUrl(value);
}
const trimmed = String(value || '').trim();
if (!trimmed) {
return DEFAULT_YYDS_MAIL_BASE_URL;
}
const candidate = /^[a-zA-Z][a-zA-Z\d+\-.]*:\/\//.test(trimmed) ? trimmed : `https://${trimmed}`;
try {
const parsed = new URL(candidate);
if (!['http:', 'https:'].includes(parsed.protocol)) {
return DEFAULT_YYDS_MAIL_BASE_URL;
}
parsed.hash = '';
parsed.search = '';
parsed.pathname = parsed.pathname === '/' ? '' : parsed.pathname.replace(/\/+$/, '');
return `${parsed.origin}${parsed.pathname}` || DEFAULT_YYDS_MAIL_BASE_URL;
} catch {
return DEFAULT_YYDS_MAIL_BASE_URL;
}
}
function getSelectedEmailGenerator() {
const generator = String(selectEmailGenerator.value || '').trim().toLowerCase();
if (generator === 'custom' || generator === 'manual') {
@@ -10678,10 +10756,13 @@ function updateMailProviderUI() {
const useInbucket = selectMailProvider.value === 'inbucket';
const useHotmail = selectMailProvider.value === 'hotmail-api';
const useLuckmail = canShowLuckmail && isLuckmailProvider();
const useYydsMail = typeof isYydsMailProvider === 'function'
? isYydsMailProvider()
: String(selectMailProvider.value || '').trim().toLowerCase() === 'yyds-mail';
const useCustomEmail = isCustomMailProvider();
const useCustomMailProviderPool = useCustomEmail && usesCustomMailProviderPool(selectMailProvider.value);
const useIcloudProvider = isIcloudMailProvider();
const useEmailGenerator = !useHotmail && !useLuckmail && !useCustomEmail && (!useGeneratedAlias || useGmail);
const useEmailGenerator = !useHotmail && !useLuckmail && !useYydsMail && !useCustomEmail && (!useGeneratedAlias || useGmail);
const useCloudflareTempEmailProvider = selectMailProvider.value === 'cloudflare-temp-email';
const useCloudMailProvider = selectMailProvider.value === 'cloudmail';
const aliasUiCopy = useGeneratedAlias
@@ -10751,6 +10832,9 @@ function updateMailProviderUI() {
if (typeof cloudMailSection !== 'undefined' && cloudMailSection) {
cloudMailSection.style.display = showCloudMailSettings ? '' : 'none';
}
if (typeof yydsMailSection !== 'undefined' && yydsMailSection) {
yydsMailSection.style.display = useYydsMail ? '' : 'none';
}
if (typeof rowCloudMailBaseUrl !== 'undefined' && rowCloudMailBaseUrl) rowCloudMailBaseUrl.style.display = showCloudMailSettings ? '' : 'none';
if (typeof rowCloudMailAdminEmail !== 'undefined' && rowCloudMailAdminEmail) rowCloudMailAdminEmail.style.display = showCloudMailSettings ? '' : 'none';
if (typeof rowCloudMailAdminPassword !== 'undefined' && rowCloudMailAdminPassword) rowCloudMailAdminPassword.style.display = showCloudMailSettings ? '' : 'none';
@@ -10818,7 +10902,7 @@ function updateMailProviderUI() {
}
inputEmailPrefix.style.display = '';
inputEmailPrefix.readOnly = false;
selectEmailGenerator.disabled = useHotmail || useLuckmail || useCustomEmail || (useGeneratedAlias && !useGmail);
selectEmailGenerator.disabled = useHotmail || useLuckmail || useYydsMail || useCustomEmail || (useGeneratedAlias && !useGmail);
if (useGmail) {
labelEmailPrefix.textContent = 'Gmail 原邮箱';
inputEmailPrefix.placeholder = '例如 yourname@gmail.com';
@@ -12945,6 +13029,16 @@ inputVpsPassword.addEventListener('blur', () => {
});
});
[inputYydsMailApiKey, inputYydsMailBaseUrl].forEach((input) => {
input?.addEventListener('input', () => {
markSettingsDirty(true);
scheduleSettingsAutoSave();
});
input?.addEventListener('blur', () => {
saveSettings({ silent: true }).catch(() => { });
});
});
selectLuckmailEmailType?.addEventListener('change', () => {
markSettingsDirty(true);
saveSettings({ silent: true }).catch(() => { });