Merge branch 'dev' of https://github.com/QLHazyCoder/codex-oauth-automation-extension into dev
This commit is contained in:
@@ -16,6 +16,26 @@ test('navigation utils module exposes a factory', () => {
|
||||
assert.equal(typeof api?.createNavigationUtils, 'function');
|
||||
});
|
||||
|
||||
test('navigation utils treat 126 mail hosts as part of the shared NetEase mail family', () => {
|
||||
const source = fs.readFileSync('background/navigation-utils.js', 'utf8');
|
||||
const globalScope = {};
|
||||
const moduleApi = new Function('self', `${source}; return self.MultiPageBackgroundNavigationUtils;`)(globalScope);
|
||||
const navigationUtils = moduleApi.createNavigationUtils({
|
||||
DEFAULT_SUB2API_URL: 'https://example.com/admin/accounts',
|
||||
normalizeLocalCpaStep9Mode: value => value,
|
||||
});
|
||||
|
||||
assert.equal(navigationUtils.is163MailHost('mail.126.com'), true);
|
||||
assert.equal(
|
||||
navigationUtils.matchesSourceUrlFamily(
|
||||
'mail-163',
|
||||
'https://mail.126.com/js6/main.jsp',
|
||||
'https://mail.163.com/js6/main.jsp'
|
||||
),
|
||||
true
|
||||
);
|
||||
});
|
||||
|
||||
test('navigation utils support codex2api mode and url normalization', () => {
|
||||
const source = fs.readFileSync('background/navigation-utils.js', 'utf8');
|
||||
const globalScope = {};
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
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'
|
||||
);
|
||||
});
|
||||
|
||||
test('detectScriptSource maps 126 mail subdomains 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://app.mail.126.com/js6/main.jsp',
|
||||
hostname: 'app.mail.126.com',
|
||||
}),
|
||||
'mail-163'
|
||||
);
|
||||
});
|
||||
@@ -181,6 +181,7 @@ test('shouldClearHotmailCurrentSelection returns true only when account becomes
|
||||
test('extractVerificationCode returns first six-digit code from multilingual mail text', () => {
|
||||
assert.equal(extractVerificationCode('你的 ChatGPT 验证码为 370794,请勿泄露。'), '370794');
|
||||
assert.equal(extractVerificationCode('Your verification code is 654321.'), '654321');
|
||||
assert.equal(extractVerificationCode('ChatGPT Log-in Code\nIf that was you, enter this code:\n\n982219'), '982219');
|
||||
assert.equal(extractVerificationCode('No code here'), null);
|
||||
});
|
||||
|
||||
@@ -202,6 +203,15 @@ test('extractVerificationCodeFromMessage reads code from the latest message subj
|
||||
}),
|
||||
'654321'
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
extractVerificationCodeFromMessage({
|
||||
subject: 'ChatGPT Log-in Code',
|
||||
bodyPreview: 'We noticed a suspicious log-in on your account. If that was you, enter this code:\n\n982219',
|
||||
from: { emailAddress: { address: 'noreply@openai.com' } },
|
||||
}),
|
||||
'982219'
|
||||
);
|
||||
});
|
||||
|
||||
test('getHotmailListToggleLabel reflects expanded state and account count', () => {
|
||||
|
||||
@@ -81,6 +81,20 @@ return { readOpenedMailBody, extractVerificationCode };
|
||||
assert.equal(api.extractVerificationCode(bodyText), '731091');
|
||||
});
|
||||
|
||||
test('extractVerificationCode matches the new suspicious log-in mail body', () => {
|
||||
const bundle = [
|
||||
extractFunction('extractVerificationCode'),
|
||||
].join('\n');
|
||||
|
||||
const api = new Function(`
|
||||
${bundle}
|
||||
return { extractVerificationCode };
|
||||
`)();
|
||||
|
||||
const bodyText = 'ChatGPT Log-in Code\nWe noticed a suspicious log-in on your account. If that was you, enter this code:\n\n982219';
|
||||
assert.equal(api.extractVerificationCode(bodyText), '982219');
|
||||
});
|
||||
|
||||
test('readOpenedMailBody ignores conversation list rows when no detail pane is open', () => {
|
||||
const bundle = [
|
||||
extractFunction('normalizeText'),
|
||||
|
||||
@@ -68,6 +68,20 @@ test('normalizeLuckmailTokenCode and normalizeLuckmailTokenMail extract verifica
|
||||
|
||||
assert.equal(normalizedMail.verification_code, '654321');
|
||||
assert.equal(extractLuckmailVerificationCode('你的验证码为 778899'), '778899');
|
||||
assert.equal(
|
||||
extractLuckmailVerificationCode('ChatGPT Log-in Code\nIf that was you, enter this code:\n\n982219'),
|
||||
'982219'
|
||||
);
|
||||
|
||||
const suspiciousLoginMail = normalizeLuckmailTokenMail({
|
||||
message_id: 'mail-3',
|
||||
from: 'noreply@openai.com',
|
||||
subject: 'ChatGPT Log-in Code',
|
||||
body: 'We noticed a suspicious log-in on your account. If that was you, enter this code:\n\n982219',
|
||||
received_at: '2026-04-14T10:02:00Z',
|
||||
});
|
||||
|
||||
assert.equal(suspiciousLoginMail.verification_code, '982219');
|
||||
});
|
||||
|
||||
test('normalizeLuckmailProjectName and isLuckmailPurchaseForProject match openai case-insensitively', () => {
|
||||
|
||||
@@ -101,6 +101,23 @@ return { findMailItems };
|
||||
assert.equal(rows.length, 1);
|
||||
});
|
||||
|
||||
test('getNetEaseMailLabel returns the active NetEase mailbox brand', () => {
|
||||
const bundle = [
|
||||
extractFunction('getNetEaseMailLabel'),
|
||||
].join('\n');
|
||||
|
||||
const api = new Function(`
|
||||
${bundle}
|
||||
return { getNetEaseMailLabel };
|
||||
`)();
|
||||
|
||||
assert.equal(api.getNetEaseMailLabel('mail.126.com'), '126 邮箱');
|
||||
assert.equal(api.getNetEaseMailLabel('app.mail.126.com'), '126 邮箱');
|
||||
assert.equal(api.getNetEaseMailLabel('webmail.vip.163.com'), '163 VIP 邮箱');
|
||||
assert.equal(api.getNetEaseMailLabel('mail.163.com'), '163 邮箱');
|
||||
assert.equal(api.getNetEaseMailLabel('example.com'), '163 邮箱');
|
||||
});
|
||||
|
||||
test('getMailTimestamp parses visible hh:mm text even when no title attribute exists', () => {
|
||||
const bundle = [
|
||||
extractFunction('normalizeText'),
|
||||
@@ -340,14 +357,30 @@ return { openMailAndGetMessageText, mailItem };
|
||||
assert.doesNotMatch(text, /111111/);
|
||||
});
|
||||
|
||||
test('extractVerificationCode matches the new suspicious log-in mail body', () => {
|
||||
const bundle = [
|
||||
extractFunction('extractVerificationCode'),
|
||||
].join('\n');
|
||||
|
||||
const api = new Function(`
|
||||
${bundle}
|
||||
return { extractVerificationCode };
|
||||
`)();
|
||||
|
||||
const bodyText = 'ChatGPT Log-in Code\nWe noticed a suspicious log-in on your account. If that was you, enter this code:\n\n982219';
|
||||
assert.equal(api.extractVerificationCode(bodyText), '982219');
|
||||
});
|
||||
|
||||
test('handlePollEmail ignores same-minute old snapshot mail before fallback', async () => {
|
||||
const bundle = [
|
||||
extractFunction('normalizeText'),
|
||||
extractFunction('normalizeMinuteTimestamp'),
|
||||
extractFunction('getNetEaseMailLabel'),
|
||||
extractFunction('handlePollEmail'),
|
||||
].join('\n');
|
||||
|
||||
const api = new Function(`
|
||||
const location = { hostname: 'mail.126.com' };
|
||||
let currentItems = [{ id: 'old-mail' }];
|
||||
const seenCodes = new Set();
|
||||
|
||||
@@ -405,7 +438,7 @@ return { handlePollEmail };
|
||||
intervalMs: 1,
|
||||
filterAfterTimestamp: new Date(2026, 3, 22, 22, 22, 40, 0).getTime(),
|
||||
}),
|
||||
/未在 163 邮箱中找到新的匹配邮件/
|
||||
/未在 126 邮箱中找到新的匹配邮件/
|
||||
);
|
||||
});
|
||||
|
||||
@@ -413,6 +446,7 @@ test('handlePollEmail accepts a new same-minute mail that appears after the snap
|
||||
const bundle = [
|
||||
extractFunction('normalizeText'),
|
||||
extractFunction('normalizeMinuteTimestamp'),
|
||||
extractFunction('getNetEaseMailLabel'),
|
||||
extractFunction('handlePollEmail'),
|
||||
].join('\n');
|
||||
|
||||
@@ -505,6 +539,7 @@ test('handlePollEmail falls back to row text when the subject node is missing',
|
||||
const bundle = [
|
||||
extractFunction('normalizeText'),
|
||||
extractFunction('normalizeMinuteTimestamp'),
|
||||
extractFunction('getNetEaseMailLabel'),
|
||||
extractFunction('handlePollEmail'),
|
||||
].join('\n');
|
||||
|
||||
@@ -584,6 +619,7 @@ test('handlePollEmail opens matching mail body when preview has no code', async
|
||||
const bundle = [
|
||||
extractFunction('normalizeText'),
|
||||
extractFunction('normalizeMinuteTimestamp'),
|
||||
extractFunction('getNetEaseMailLabel'),
|
||||
extractFunction('handlePollEmail'),
|
||||
].join('\n');
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
const test = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('node:fs');
|
||||
|
||||
test('manifest 为网易邮箱内容脚本覆盖 126 子域名', () => {
|
||||
const manifest = JSON.parse(fs.readFileSync('manifest.json', 'utf8'));
|
||||
const mail163Script = manifest.content_scripts.find((script) => (
|
||||
Array.isArray(script.js) && script.js.includes('content/mail-163.js')
|
||||
));
|
||||
|
||||
assert.ok(mail163Script, '应存在 mail-163 内容脚本声明');
|
||||
assert.equal(
|
||||
mail163Script.matches.includes('https://mail.126.com/*'),
|
||||
true,
|
||||
'应覆盖 mail.126.com'
|
||||
);
|
||||
assert.equal(
|
||||
mail163Script.matches.includes('https://*.mail.126.com/*'),
|
||||
true,
|
||||
'应覆盖 *.mail.126.com'
|
||||
);
|
||||
});
|
||||
@@ -546,6 +546,21 @@ return {
|
||||
]);
|
||||
});
|
||||
|
||||
test('extractVerificationCode strict mode matches the new suspicious log-in mail body', () => {
|
||||
const bundle = [
|
||||
extractFunction('extractVerificationCode'),
|
||||
].join('\n');
|
||||
|
||||
const api = new Function(`
|
||||
${bundle}
|
||||
return { extractVerificationCode };
|
||||
`)();
|
||||
|
||||
const bodyText = 'ChatGPT Log-in Code\nWe noticed a suspicious log-in on your account. If that was you, enter this code:\n\n982219';
|
||||
assert.equal(api.extractVerificationCode(bodyText, true), '982219');
|
||||
assert.equal(api.extractVerificationCode(bodyText, false), '982219');
|
||||
});
|
||||
|
||||
test('openMailAndGetMessageText always returns to inbox after opening a 2925 message', async () => {
|
||||
const bundle = [
|
||||
extractFunction('returnToInbox'),
|
||||
|
||||
@@ -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)',
|
||||
}
|
||||
);
|
||||
});
|
||||
@@ -48,6 +48,7 @@ const helperBundle = [
|
||||
extractFunction(helperSource, 'parseUrlSafely'),
|
||||
extractFunction(helperSource, 'isSignupPageHost'),
|
||||
extractFunction(helperSource, 'isSignupEntryHost'),
|
||||
extractFunction(helperSource, 'is163MailHost'),
|
||||
extractFunction(helperSource, 'matchesSourceUrlFamily'),
|
||||
].join('\n');
|
||||
|
||||
@@ -153,6 +154,11 @@ return {
|
||||
true,
|
||||
'signup-page family should include legacy chat.openai.com'
|
||||
);
|
||||
assert.strictEqual(
|
||||
api.matchesSourceUrlFamily('mail-163', 'https://mail.126.com/js6/main.jsp', 'https://mail.163.com/js6/main.jsp'),
|
||||
true,
|
||||
'mail-163 family should include mail.126.com'
|
||||
);
|
||||
|
||||
api.reset({
|
||||
tabs: [
|
||||
|
||||
Reference in New Issue
Block a user