feat: add 126 mail provider routing
This commit is contained in:
@@ -628,6 +628,7 @@ function normalizeMailProvider(value = '') {
|
||||
case CLOUDFLARE_TEMP_EMAIL_PROVIDER:
|
||||
case '163':
|
||||
case '163-vip':
|
||||
case '126':
|
||||
case 'qq':
|
||||
case 'inbucket':
|
||||
case '2925':
|
||||
@@ -6131,6 +6132,9 @@ function getMailConfig(state) {
|
||||
if (provider === '163-vip') {
|
||||
return { source: 'mail-163', url: 'https://webmail.vip.163.com/js6/main.jsp?df=mail163_letter#module=mbox.ListModule%7C%7B%22fid%22%3A1%2C%22order%22%3A%22date%22%2C%22desc%22%3Atrue%7D', label: '163 VIP 邮箱' };
|
||||
}
|
||||
if (provider === '126') {
|
||||
return { source: 'mail-163', url: 'https://mail.126.com/js6/main.jsp?df=mail163_letter#module=mbox.ListModule%7C%7B%22fid%22%3A1%2C%22order%22%3A%22date%22%2C%22desc%22%3Atrue%7D', label: '126 邮箱' };
|
||||
}
|
||||
if (provider === 'inbucket') {
|
||||
const host = normalizeInbucketOrigin(state.inbucketHost);
|
||||
const mailbox = (state.inbucketMailbox || '').trim();
|
||||
|
||||
+20
-5
@@ -2,13 +2,20 @@
|
||||
|
||||
const getActivationStrategy = self.MultiPageActivationUtils?.getActivationStrategy;
|
||||
|
||||
const SCRIPT_SOURCE = (() => {
|
||||
if (window.__MULTIPAGE_SOURCE) return window.__MULTIPAGE_SOURCE;
|
||||
const url = location.href;
|
||||
const hostname = location.hostname;
|
||||
function detectScriptSource({
|
||||
injectedSource,
|
||||
url = '',
|
||||
hostname = '',
|
||||
} = {}) {
|
||||
if (injectedSource) return injectedSource;
|
||||
if (url.includes('auth0.openai.com') || url.includes('auth.openai.com') || url.includes('accounts.openai.com')) return 'signup-page';
|
||||
if (hostname === 'mail.qq.com' || hostname === 'wx.mail.qq.com') return 'qq-mail';
|
||||
if (hostname === 'mail.163.com' || hostname.endsWith('.mail.163.com') || hostname === 'webmail.vip.163.com') return 'mail-163';
|
||||
if (
|
||||
hostname === 'mail.163.com'
|
||||
|| hostname.endsWith('.mail.163.com')
|
||||
|| hostname === 'webmail.vip.163.com'
|
||||
|| hostname === 'mail.126.com'
|
||||
) return 'mail-163';
|
||||
if (hostname === 'mail.google.com') return 'gmail-mail';
|
||||
if (hostname === 'www.icloud.com' || hostname === 'www.icloud.com.cn') return 'icloud-mail';
|
||||
if (url.includes('duckduckgo.com/email/settings/autofill')) return 'duck-mail';
|
||||
@@ -16,6 +23,14 @@ const SCRIPT_SOURCE = (() => {
|
||||
if (url.includes("2925.com")) return "mail-2925";
|
||||
// VPS panel — detected dynamically since URL is configurable
|
||||
return 'vps-panel';
|
||||
}
|
||||
|
||||
const SCRIPT_SOURCE = (() => {
|
||||
return detectScriptSource({
|
||||
injectedSource: window.__MULTIPAGE_SOURCE,
|
||||
url: location.href,
|
||||
hostname: location.hostname,
|
||||
});
|
||||
})();
|
||||
|
||||
const LOG_PREFIX = `[MultiPage:${SCRIPT_SOURCE}]`;
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
const HOTMAIL_PROVIDER = 'hotmail-api';
|
||||
const NETEASE_LIST_PATH = '/js6/main.jsp?df=mail163_letter#module=mbox.ListModule%7C%7B%22fid%22%3A1%2C%22order%22%3A%22date%22%2C%22desc%22%3Atrue%7D';
|
||||
|
||||
function normalizeMailProvider(value = '') {
|
||||
const normalized = String(value || '').trim().toLowerCase();
|
||||
switch (normalized) {
|
||||
case HOTMAIL_PROVIDER:
|
||||
case '163':
|
||||
case '163-vip':
|
||||
case '126':
|
||||
case 'qq':
|
||||
case 'inbucket':
|
||||
return normalized;
|
||||
default:
|
||||
return '163';
|
||||
}
|
||||
}
|
||||
|
||||
function getMailProviderConfig(state = {}, options = {}) {
|
||||
const provider = normalizeMailProvider(state.mailProvider);
|
||||
const normalizeInbucketOrigin = options.normalizeInbucketOrigin || (() => '');
|
||||
|
||||
if (provider === HOTMAIL_PROVIDER) {
|
||||
return { provider: HOTMAIL_PROVIDER, label: 'Hotmail(微软 Graph)' };
|
||||
}
|
||||
if (provider === '163') {
|
||||
return {
|
||||
source: 'mail-163',
|
||||
url: `https://mail.163.com${NETEASE_LIST_PATH}`,
|
||||
label: '163 邮箱',
|
||||
};
|
||||
}
|
||||
if (provider === '163-vip') {
|
||||
return {
|
||||
source: 'mail-163',
|
||||
url: `https://webmail.vip.163.com${NETEASE_LIST_PATH}`,
|
||||
label: '163 VIP 邮箱',
|
||||
};
|
||||
}
|
||||
if (provider === '126') {
|
||||
return {
|
||||
source: 'mail-163',
|
||||
url: `https://mail.126.com${NETEASE_LIST_PATH}`,
|
||||
label: '126 邮箱',
|
||||
};
|
||||
}
|
||||
if (provider === 'inbucket') {
|
||||
const host = normalizeInbucketOrigin(state.inbucketHost);
|
||||
const mailbox = String(state.inbucketMailbox || '').trim();
|
||||
if (!host) {
|
||||
return { error: 'Inbucket 主机地址为空或无效。' };
|
||||
}
|
||||
if (!mailbox) {
|
||||
return { error: 'Inbucket 邮箱名称为空。' };
|
||||
}
|
||||
return {
|
||||
source: 'inbucket-mail',
|
||||
url: `${host}/m/${encodeURIComponent(mailbox)}/`,
|
||||
label: `Inbucket 邮箱(${mailbox})`,
|
||||
navigateOnReuse: true,
|
||||
inject: ['content/activation-utils.js', 'content/utils.js', 'content/inbucket-mail.js'],
|
||||
injectSource: 'inbucket-mail',
|
||||
};
|
||||
}
|
||||
return { source: 'qq-mail', url: 'https://wx.mail.qq.com/', label: 'QQ 邮箱' };
|
||||
}
|
||||
|
||||
const api = {
|
||||
HOTMAIL_PROVIDER,
|
||||
getMailProviderConfig,
|
||||
normalizeMailProvider,
|
||||
};
|
||||
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
module.exports = api;
|
||||
}
|
||||
|
||||
if (typeof self !== 'undefined') {
|
||||
self.MailProviderUtils = api;
|
||||
}
|
||||
+2
-1
@@ -69,7 +69,8 @@
|
||||
"matches": [
|
||||
"https://mail.163.com/*",
|
||||
"https://*.mail.163.com/*",
|
||||
"https://webmail.vip.163.com/*"
|
||||
"https://webmail.vip.163.com/*",
|
||||
"https://mail.126.com/*"
|
||||
],
|
||||
"js": [
|
||||
"content/activation-utils.js",
|
||||
|
||||
@@ -169,6 +169,7 @@
|
||||
<option value="icloud">iCloud 邮箱</option>
|
||||
<option value="163">163 邮箱 (mail.163.com)</option>
|
||||
<option value="163-vip">163 VIP 邮箱 (vip.163.com)</option>
|
||||
<option value="126">126 邮箱 (mail.126.com)</option>
|
||||
<option value="qq">QQ 邮箱 (wx.mail.qq.com)</option>
|
||||
<option value="inbucket">Inbucket(自定义主机)</option>
|
||||
<option value="2925">2925 邮箱 (2925.com)</option>
|
||||
|
||||
@@ -444,6 +444,11 @@ const MAIL_PROVIDER_LOGIN_CONFIGS = {
|
||||
url: 'https://webmail.vip.163.com/',
|
||||
buttonLabel: '登录',
|
||||
},
|
||||
'126': {
|
||||
label: '126 邮箱',
|
||||
url: 'https://mail.126.com/',
|
||||
buttonLabel: '登录',
|
||||
},
|
||||
qq: {
|
||||
label: 'QQ 邮箱',
|
||||
url: 'https://wx.mail.qq.com/',
|
||||
@@ -1693,7 +1698,7 @@ function applySettingsState(state) {
|
||||
inputSub2ApiGroup.value = state?.sub2apiGroupName || '';
|
||||
inputSub2ApiDefaultProxy.value = state?.sub2apiDefaultProxyName || '';
|
||||
const restoredMailProvider = isCustomMailProvider(state?.mailProvider)
|
||||
|| [ICLOUD_PROVIDER, 'hotmail-api', GMAIL_PROVIDER, 'luckmail-api', '163', '163-vip', 'qq', 'inbucket', '2925', 'cloudflare-temp-email'].includes(String(state?.mailProvider || '').trim())
|
||||
|| [ICLOUD_PROVIDER, 'hotmail-api', GMAIL_PROVIDER, 'luckmail-api', '163', '163-vip', '126', 'qq', 'inbucket', '2925', 'cloudflare-temp-email'].includes(String(state?.mailProvider || '').trim())
|
||||
? String(state?.mailProvider || '163').trim()
|
||||
: (String(state?.emailGenerator || '').trim().toLowerCase() === 'custom'
|
||||
|| String(state?.emailGenerator || '').trim().toLowerCase() === 'manual'
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
const test = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('node:fs');
|
||||
|
||||
const source = fs.readFileSync('content/utils.js', 'utf8');
|
||||
|
||||
function extractFunction(name) {
|
||||
const start = source.indexOf(`function ${name}(`);
|
||||
if (start < 0) {
|
||||
throw new Error(`missing function ${name}`);
|
||||
}
|
||||
|
||||
let parenDepth = 0;
|
||||
let signatureEnded = false;
|
||||
let braceStart = -1;
|
||||
for (let index = start; index < source.length; index += 1) {
|
||||
const ch = source[index];
|
||||
if (ch === '(') {
|
||||
parenDepth += 1;
|
||||
} else if (ch === ')') {
|
||||
parenDepth -= 1;
|
||||
if (parenDepth === 0) {
|
||||
signatureEnded = true;
|
||||
}
|
||||
} else if (ch === '{' && signatureEnded) {
|
||||
braceStart = index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (braceStart < 0) {
|
||||
throw new Error(`missing body for function ${name}`);
|
||||
}
|
||||
|
||||
let depth = 0;
|
||||
let end = braceStart;
|
||||
for (; end < source.length; end += 1) {
|
||||
const ch = source[end];
|
||||
if (ch === '{') depth += 1;
|
||||
if (ch === '}') {
|
||||
depth -= 1;
|
||||
if (depth === 0) {
|
||||
end += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return source.slice(start, end);
|
||||
}
|
||||
|
||||
test('detectScriptSource maps 126 mail hosts to the shared 163 mail source', () => {
|
||||
const bundle = [extractFunction('detectScriptSource')].join('\n');
|
||||
const api = new Function(`
|
||||
${bundle}
|
||||
return { detectScriptSource };
|
||||
`)();
|
||||
|
||||
assert.equal(
|
||||
api.detectScriptSource({
|
||||
url: 'https://mail.126.com/js6/main.jsp',
|
||||
hostname: 'mail.126.com',
|
||||
}),
|
||||
'mail-163'
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,35 @@
|
||||
const test = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
|
||||
const {
|
||||
HOTMAIL_PROVIDER,
|
||||
getMailProviderConfig,
|
||||
normalizeMailProvider,
|
||||
} = require('../mail-provider-utils.js');
|
||||
|
||||
test('normalizeMailProvider accepts 126 and falls back to 163', () => {
|
||||
assert.equal(normalizeMailProvider('126'), '126');
|
||||
assert.equal(normalizeMailProvider('163-vip'), '163-vip');
|
||||
assert.equal(normalizeMailProvider('unknown-provider'), '163');
|
||||
});
|
||||
|
||||
test('getMailProviderConfig returns the shared NetEase source for 126 mail', () => {
|
||||
assert.deepEqual(
|
||||
getMailProviderConfig({ mailProvider: '126' }),
|
||||
{
|
||||
source: 'mail-163',
|
||||
url: 'https://mail.126.com/js6/main.jsp?df=mail163_letter#module=mbox.ListModule%7C%7B%22fid%22%3A1%2C%22order%22%3A%22date%22%2C%22desc%22%3Atrue%7D',
|
||||
label: '126 邮箱',
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
test('getMailProviderConfig preserves the hotmail provider sentinel', () => {
|
||||
assert.deepEqual(
|
||||
getMailProviderConfig({ mailProvider: HOTMAIL_PROVIDER }),
|
||||
{
|
||||
provider: HOTMAIL_PROVIDER,
|
||||
label: 'Hotmail(微软 Graph)',
|
||||
}
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user