fix(mail163): ignore stale pre-open body text
This commit is contained in:
+23
-7
@@ -377,12 +377,13 @@ function collectOpenedMailTextCandidates() {
|
|||||||
return texts.sort((a, b) => b.length - a.length);
|
return texts.sort((a, b) => b.length - a.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
function readOpenedMailText(item) {
|
function selectOpenedMailTextCandidate(item, candidates = [], options = {}) {
|
||||||
const subject = normalizeText(getMailSubjectText(item)).toLowerCase();
|
const subject = normalizeText(getMailSubjectText(item)).toLowerCase();
|
||||||
const sender = normalizeText(getMailSenderText(item)).toLowerCase();
|
const sender = normalizeText(getMailSenderText(item)).toLowerCase();
|
||||||
const candidates = collectOpenedMailTextCandidates();
|
const excludedSet = new Set((options.excludedTexts || []).map((value) => normalizeText(value)));
|
||||||
|
const allowExcludedFallback = options.allowExcludedFallback !== false;
|
||||||
|
|
||||||
const preferred = candidates.find((candidate) => {
|
const pickCandidate = (source) => source.find((candidate) => {
|
||||||
const lower = candidate.toLowerCase();
|
const lower = candidate.toLowerCase();
|
||||||
if (subject && lower.includes(subject)) {
|
if (subject && lower.includes(subject)) {
|
||||||
return true;
|
return true;
|
||||||
@@ -391,9 +392,20 @@ function readOpenedMailText(item) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return Boolean(extractVerificationCode(candidate) && /chatgpt|openai|verification|验证码|login code/i.test(lower));
|
return Boolean(extractVerificationCode(candidate) && /chatgpt|openai|verification|验证码|login code/i.test(lower));
|
||||||
});
|
}) || source[0] || '';
|
||||||
|
|
||||||
return preferred || candidates[0] || '';
|
const filteredCandidates = candidates.filter((candidate) => !excludedSet.has(normalizeText(candidate)));
|
||||||
|
const preferred = pickCandidate(filteredCandidates);
|
||||||
|
if (preferred || !allowExcludedFallback) {
|
||||||
|
return preferred;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pickCandidate(candidates);
|
||||||
|
}
|
||||||
|
|
||||||
|
function readOpenedMailText(item, options = {}) {
|
||||||
|
const candidates = collectOpenedMailTextCandidates();
|
||||||
|
return selectOpenedMailTextCandidate(item, candidates, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function returnToInbox() {
|
async function returnToInbox() {
|
||||||
@@ -417,7 +429,8 @@ async function returnToInbox() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function openMailAndGetMessageText(item) {
|
async function openMailAndGetMessageText(item) {
|
||||||
const beforeText = readOpenedMailText(item);
|
const beforeCandidates = collectOpenedMailTextCandidates();
|
||||||
|
const beforeText = selectOpenedMailTextCandidate(item, beforeCandidates);
|
||||||
if (typeof simulateClick === 'function') {
|
if (typeof simulateClick === 'function') {
|
||||||
simulateClick(item);
|
simulateClick(item);
|
||||||
} else {
|
} else {
|
||||||
@@ -427,7 +440,10 @@ async function openMailAndGetMessageText(item) {
|
|||||||
let openedText = '';
|
let openedText = '';
|
||||||
for (let i = 0; i < 24; i += 1) {
|
for (let i = 0; i < 24; i += 1) {
|
||||||
await sleep(250);
|
await sleep(250);
|
||||||
const candidate = readOpenedMailText(item);
|
const candidate = readOpenedMailText(item, {
|
||||||
|
excludedTexts: beforeCandidates,
|
||||||
|
allowExcludedFallback: false,
|
||||||
|
});
|
||||||
if (!candidate) {
|
if (!candidate) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -147,6 +147,7 @@ test('readOpenedMailText prefers opened body content that contains the verificat
|
|||||||
const bundle = [
|
const bundle = [
|
||||||
extractFunction('normalizeText'),
|
extractFunction('normalizeText'),
|
||||||
extractFunction('collectOpenedMailTextCandidates'),
|
extractFunction('collectOpenedMailTextCandidates'),
|
||||||
|
extractFunction('selectOpenedMailTextCandidate'),
|
||||||
extractFunction('readOpenedMailText'),
|
extractFunction('readOpenedMailText'),
|
||||||
extractFunction('extractVerificationCode'),
|
extractFunction('extractVerificationCode'),
|
||||||
].join('\n');
|
].join('\n');
|
||||||
@@ -194,6 +195,7 @@ test('openMailAndGetMessageText reads opened body text and returns to inbox', as
|
|||||||
const bundle = [
|
const bundle = [
|
||||||
extractFunction('normalizeText'),
|
extractFunction('normalizeText'),
|
||||||
extractFunction('collectOpenedMailTextCandidates'),
|
extractFunction('collectOpenedMailTextCandidates'),
|
||||||
|
extractFunction('selectOpenedMailTextCandidate'),
|
||||||
extractFunction('readOpenedMailText'),
|
extractFunction('readOpenedMailText'),
|
||||||
extractFunction('returnToInbox'),
|
extractFunction('returnToInbox'),
|
||||||
extractFunction('openMailAndGetMessageText'),
|
extractFunction('openMailAndGetMessageText'),
|
||||||
@@ -262,6 +264,82 @@ return {
|
|||||||
assert.equal(api.isInInbox(), true);
|
assert.equal(api.isInInbox(), true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('openMailAndGetMessageText ignores stale pre-open text that contains an old code', async () => {
|
||||||
|
const bundle = [
|
||||||
|
extractFunction('normalizeText'),
|
||||||
|
extractFunction('collectOpenedMailTextCandidates'),
|
||||||
|
extractFunction('selectOpenedMailTextCandidate'),
|
||||||
|
extractFunction('readOpenedMailText'),
|
||||||
|
extractFunction('returnToInbox'),
|
||||||
|
extractFunction('openMailAndGetMessageText'),
|
||||||
|
extractFunction('extractVerificationCode'),
|
||||||
|
].join('\n');
|
||||||
|
|
||||||
|
const api = new Function(`
|
||||||
|
let stage = 'before';
|
||||||
|
const oldText = 'OpenAI Your temporary ChatGPT login code. Ignore this old code 111111. '.repeat(10);
|
||||||
|
const newText = 'OpenAI Your temporary ChatGPT login code. Your new code is 222222.';
|
||||||
|
const mailItem = {
|
||||||
|
click() {
|
||||||
|
stage = 'after';
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const inboxLink = {
|
||||||
|
click() {
|
||||||
|
stage = 'done';
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
function getMailSubjectText() {
|
||||||
|
return 'Your temporary ChatGPT login code';
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMailSenderText() {
|
||||||
|
return 'OpenAI';
|
||||||
|
}
|
||||||
|
|
||||||
|
const document = {
|
||||||
|
querySelector(selector) {
|
||||||
|
if (selector === '.nui-tree-item-text[title="收件箱"], [title="收件箱"]') return inboxLink;
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
querySelectorAll(selector) {
|
||||||
|
if (selector === 'iframe') {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
if (stage === 'before') {
|
||||||
|
return [{ innerText: oldText, textContent: oldText }];
|
||||||
|
}
|
||||||
|
if (stage === 'after') {
|
||||||
|
return [
|
||||||
|
{ innerText: oldText, textContent: oldText },
|
||||||
|
{ innerText: newText, textContent: newText },
|
||||||
|
];
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
body: {
|
||||||
|
innerText: '',
|
||||||
|
textContent: '',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
function findMailItems() {
|
||||||
|
return stage === 'done' ? [mailItem] : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
async function sleep() {}
|
||||||
|
|
||||||
|
${bundle}
|
||||||
|
|
||||||
|
return { openMailAndGetMessageText, mailItem };
|
||||||
|
`)();
|
||||||
|
|
||||||
|
const text = await api.openMailAndGetMessageText(api.mailItem);
|
||||||
|
assert.match(text, /222222/);
|
||||||
|
assert.doesNotMatch(text, /111111/);
|
||||||
|
});
|
||||||
|
|
||||||
test('handlePollEmail ignores same-minute old snapshot mail before fallback', async () => {
|
test('handlePollEmail ignores same-minute old snapshot mail before fallback', async () => {
|
||||||
const bundle = [
|
const bundle = [
|
||||||
extractFunction('normalizeText'),
|
extractFunction('normalizeText'),
|
||||||
|
|||||||
Reference in New Issue
Block a user