feat: 增强2925邮箱登录态处理,添加邮箱一致性校验与错误处理
This commit is contained in:
@@ -266,3 +266,163 @@ test('ensureMail2925MailboxSession logs in when login page is detected and accou
|
||||
assert.equal(readyCalls, 1);
|
||||
assert.equal(result.result.loggedIn, true);
|
||||
});
|
||||
|
||||
test('ensureMail2925MailboxSession relogs with selected account when mailbox page email mismatches and pool is on', async () => {
|
||||
let currentState = {
|
||||
autoRunning: false,
|
||||
mail2925UseAccountPool: true,
|
||||
mail2925Accounts: mail2925Utils.normalizeMail2925Accounts([
|
||||
{ id: 'acc-1', email: 'target@2925.com', password: 'p1', enabled: true, lastUsedAt: 10 },
|
||||
]),
|
||||
currentMail2925AccountId: 'acc-1',
|
||||
};
|
||||
const openedUrls = [];
|
||||
const sendPayloads = [];
|
||||
|
||||
const manager = api.createMail2925SessionManager({
|
||||
addLog: async () => {},
|
||||
broadcastDataUpdate: () => {},
|
||||
chrome: {
|
||||
tabs: {
|
||||
get: async () => ({ id: 9, url: openedUrls.at(-1) || 'https://2925.com/#/mailList' }),
|
||||
},
|
||||
cookies: {
|
||||
getAll: async () => [],
|
||||
remove: async () => ({ ok: true }),
|
||||
},
|
||||
browsingData: {
|
||||
removeCookies: async () => {},
|
||||
},
|
||||
},
|
||||
ensureContentScriptReadyOnTab: async () => {},
|
||||
findMail2925Account: mail2925Utils.findMail2925Account,
|
||||
getMail2925AccountStatus: mail2925Utils.getMail2925AccountStatus,
|
||||
getState: async () => currentState,
|
||||
isAutoRunLockedState: () => false,
|
||||
isMail2925AccountAvailable: mail2925Utils.isMail2925AccountAvailable,
|
||||
MAIL2925_LIMIT_COOLDOWN_MS: mail2925Utils.MAIL2925_LIMIT_COOLDOWN_MS,
|
||||
normalizeMail2925Account: mail2925Utils.normalizeMail2925Account,
|
||||
normalizeMail2925Accounts: mail2925Utils.normalizeMail2925Accounts,
|
||||
pickMail2925AccountForRun: mail2925Utils.pickMail2925AccountForRun,
|
||||
reuseOrCreateTab: async (_source, url) => {
|
||||
openedUrls.push(url);
|
||||
return 9;
|
||||
},
|
||||
sendToMailContentScriptResilient: async (_mail, message) => {
|
||||
sendPayloads.push(message.payload);
|
||||
if (sendPayloads.length === 1) {
|
||||
return {
|
||||
loggedIn: true,
|
||||
currentView: 'mailbox',
|
||||
mailboxEmail: 'wrong@2925.com',
|
||||
};
|
||||
}
|
||||
return {
|
||||
loggedIn: true,
|
||||
currentView: 'mailbox',
|
||||
mailboxEmail: 'target@2925.com',
|
||||
};
|
||||
},
|
||||
setPersistentSettings: async (payload) => {
|
||||
currentState = { ...currentState, ...payload };
|
||||
},
|
||||
setState: async (updates) => {
|
||||
currentState = { ...currentState, ...updates };
|
||||
},
|
||||
sleepWithStop: async () => {},
|
||||
throwIfStopped: () => {},
|
||||
upsertMail2925AccountInList: mail2925Utils.upsertMail2925AccountInList,
|
||||
waitForTabUrlMatch: async () => ({ url: 'https://2925.com/login/' }),
|
||||
});
|
||||
|
||||
const result = await manager.ensureMail2925MailboxSession({
|
||||
accountId: 'acc-1',
|
||||
forceRelogin: false,
|
||||
allowLoginWhenOnLoginPage: true,
|
||||
expectedMailboxEmail: 'target@2925.com',
|
||||
actionLabel: '步骤 4:确认 2925 邮箱登录态',
|
||||
});
|
||||
|
||||
assert.equal(result.result.loggedIn, true);
|
||||
assert.deepStrictEqual(openedUrls, [
|
||||
'https://2925.com/#/mailList',
|
||||
'https://2925.com/login/',
|
||||
]);
|
||||
assert.equal(sendPayloads.length, 2);
|
||||
assert.equal(sendPayloads[0].allowLoginWhenOnLoginPage, true);
|
||||
assert.equal(sendPayloads[1].forceLogin, true);
|
||||
});
|
||||
|
||||
test('ensureMail2925MailboxSession stops when mailbox page email mismatches and pool is off', async () => {
|
||||
let currentState = {
|
||||
autoRunning: true,
|
||||
autoRunPhase: 'running',
|
||||
mail2925UseAccountPool: false,
|
||||
mail2925Accounts: [],
|
||||
currentMail2925AccountId: null,
|
||||
};
|
||||
const stopCalls = [];
|
||||
let sendCalls = 0;
|
||||
|
||||
const manager = api.createMail2925SessionManager({
|
||||
addLog: async () => {},
|
||||
broadcastDataUpdate: () => {},
|
||||
chrome: {
|
||||
tabs: {
|
||||
get: async () => ({ id: 9, url: 'https://2925.com/#/mailList' }),
|
||||
},
|
||||
cookies: {
|
||||
getAll: async () => [],
|
||||
remove: async () => ({ ok: true }),
|
||||
},
|
||||
browsingData: {
|
||||
removeCookies: async () => {},
|
||||
},
|
||||
},
|
||||
ensureContentScriptReadyOnTab: async () => {},
|
||||
findMail2925Account: mail2925Utils.findMail2925Account,
|
||||
getMail2925AccountStatus: mail2925Utils.getMail2925AccountStatus,
|
||||
getState: async () => currentState,
|
||||
isAutoRunLockedState: (state) => Boolean(state?.autoRunning) && state?.autoRunPhase === 'running',
|
||||
isMail2925AccountAvailable: mail2925Utils.isMail2925AccountAvailable,
|
||||
MAIL2925_LIMIT_COOLDOWN_MS: mail2925Utils.MAIL2925_LIMIT_COOLDOWN_MS,
|
||||
normalizeMail2925Account: mail2925Utils.normalizeMail2925Account,
|
||||
normalizeMail2925Accounts: mail2925Utils.normalizeMail2925Accounts,
|
||||
pickMail2925AccountForRun: mail2925Utils.pickMail2925AccountForRun,
|
||||
requestStop: async (options = {}) => {
|
||||
stopCalls.push(options);
|
||||
},
|
||||
reuseOrCreateTab: async () => 9,
|
||||
sendToMailContentScriptResilient: async () => {
|
||||
sendCalls += 1;
|
||||
return {
|
||||
loggedIn: true,
|
||||
currentView: 'mailbox',
|
||||
mailboxEmail: 'wrong@2925.com',
|
||||
};
|
||||
},
|
||||
setPersistentSettings: async (payload) => {
|
||||
currentState = { ...currentState, ...payload };
|
||||
},
|
||||
setState: async (updates) => {
|
||||
currentState = { ...currentState, ...updates };
|
||||
},
|
||||
throwIfStopped: () => {},
|
||||
upsertMail2925AccountInList: mail2925Utils.upsertMail2925AccountInList,
|
||||
});
|
||||
|
||||
await assert.rejects(
|
||||
() => manager.ensureMail2925MailboxSession({
|
||||
accountId: null,
|
||||
forceRelogin: false,
|
||||
allowLoginWhenOnLoginPage: false,
|
||||
expectedMailboxEmail: 'target@2925.com',
|
||||
actionLabel: '步骤 4:确认 2925 邮箱登录态',
|
||||
}),
|
||||
/流程已被用户停止。/
|
||||
);
|
||||
|
||||
assert.equal(sendCalls, 1);
|
||||
assert.equal(stopCalls.length, 1);
|
||||
assert.match(stopCalls[0].logMessage, /与目标账号 target@2925\.com 不一致/);
|
||||
});
|
||||
|
||||
@@ -12,6 +12,61 @@ test('ensureMail2925Session waits 1 second after filling credentials before clic
|
||||
assert.match(source, /fillInput\(passwordInput,\s*password\);[\s\S]*?await sleep\(200\);[\s\S]*?await sleep\(1000\);[\s\S]*?simulateClick\(loginButton\);/);
|
||||
});
|
||||
|
||||
test('detectMail2925ViewState treats top mailbox email as mailbox view', () => {
|
||||
const bundle = [
|
||||
extractFunction('normalizeNodeText'),
|
||||
extractFunction('isVisibleNode'),
|
||||
extractFunction('isMailItemNode'),
|
||||
extractFunction('resolveActionTarget'),
|
||||
extractFunction('findMailItems'),
|
||||
extractFunction('extractEmails'),
|
||||
extractFunction('getMail2925DisplayedMailboxEmail'),
|
||||
extractFunction('detectMail2925ViewState'),
|
||||
].join('\n');
|
||||
|
||||
const api = new Function(`
|
||||
const MAIL_ITEM_SELECTORS = ['.mail-item'];
|
||||
const MAIL_ITEM_SELECTOR_GROUP = '.mail-item';
|
||||
const MAIL2925_REMEMBER_LOGIN_PATTERNS = [];
|
||||
const MAIL2925_AGREEMENT_PATTERNS = [];
|
||||
const document = {
|
||||
querySelectorAll(selector) {
|
||||
if (selector === '.mail-item') return [];
|
||||
if (selector === 'body *') return [headerEmail];
|
||||
if (selector.includes('[class*="user"]')) return [headerEmail];
|
||||
return [];
|
||||
},
|
||||
body: {
|
||||
innerText: 'QLHazycoder qlhazycoder@2925.com',
|
||||
textContent: 'QLHazycoder qlhazycoder@2925.com',
|
||||
},
|
||||
};
|
||||
const window = {
|
||||
innerHeight: 900,
|
||||
getComputedStyle() {
|
||||
return { display: 'block', visibility: 'visible' };
|
||||
},
|
||||
};
|
||||
const headerEmail = {
|
||||
hidden: false,
|
||||
textContent: 'qlhazycoder@2925.com',
|
||||
innerText: 'qlhazycoder@2925.com',
|
||||
getBoundingClientRect() { return { top: 40, left: 400, width: 120, height: 20 }; },
|
||||
closest() { return null; },
|
||||
};
|
||||
function detectMail2925LimitMessage() { return ''; }
|
||||
function findMail2925LoginPasswordInput() { return null; }
|
||||
function findMail2925LoginEmailInput() { return null; }
|
||||
function getPageTextSample() { return 'qlhazycoder@2925.com'; }
|
||||
${bundle}
|
||||
return { detectMail2925ViewState };
|
||||
`)();
|
||||
|
||||
const state = api.detectMail2925ViewState();
|
||||
assert.equal(state.view, 'mailbox');
|
||||
assert.equal(state.mailboxEmail, 'qlhazycoder@2925.com');
|
||||
});
|
||||
|
||||
function extractFunction(name) {
|
||||
const markers = [`async function ${name}(`, `function ${name}(`];
|
||||
const start = markers
|
||||
|
||||
@@ -176,6 +176,8 @@ const inputAccountRunHistoryHelperBaseUrl = { value: '' };
|
||||
const inputMail2925UseAccountPool = { checked: true };
|
||||
const inputInbucketHost = { value: '' };
|
||||
const inputInbucketMailbox = { value: '' };
|
||||
const inputHotmailRemoteBaseUrl = { value: '' };
|
||||
const inputHotmailLocalBaseUrl = { value: '' };
|
||||
const inputLuckmailApiKey = { value: '' };
|
||||
const inputLuckmailBaseUrl = { value: '' };
|
||||
const selectLuckmailEmailType = { value: 'ms_graph' };
|
||||
@@ -184,6 +186,13 @@ const inputTempEmailBaseUrl = { value: '' };
|
||||
const inputTempEmailAdminAuth = { value: '' };
|
||||
const inputTempEmailCustomAuth = { value: '' };
|
||||
const inputTempEmailReceiveMailbox = { value: '' };
|
||||
const inputAutoSkipFailures = { checked: false };
|
||||
const inputAutoSkipFailuresThreadIntervalMinutes = { value: '0' };
|
||||
const inputAutoDelayEnabled = { checked: false };
|
||||
const inputAutoDelayMinutes = { value: '30' };
|
||||
const inputAutoStepDelaySeconds = { value: '' };
|
||||
const inputVerificationResendCount = { value: '4' };
|
||||
const DEFAULT_VERIFICATION_RESEND_COUNT = 4;
|
||||
function getCloudflareDomainsFromState() {
|
||||
return { domains: [], activeDomain: '' };
|
||||
}
|
||||
@@ -203,6 +212,10 @@ function normalizeLuckmailEmailType(value) { return String(value || '').trim() |
|
||||
function normalizeCloudflareTempEmailBaseUrlValue(value) { return String(value || '').trim(); }
|
||||
function normalizeCloudflareTempEmailReceiveMailboxValue(value) { return String(value || '').trim(); }
|
||||
function normalizeAccountRunHistoryHelperBaseUrlValue(value) { return String(value || '').trim(); }
|
||||
function normalizeAutoRunThreadIntervalMinutes(value) { return Number(value) || 0; }
|
||||
function normalizeAutoDelayMinutes(value) { return Number(value) || 30; }
|
||||
function normalizeAutoStepDelaySeconds(value) { return value === '' ? null : Number(value); }
|
||||
function normalizeVerificationResendCount(value, fallback) { return Number(value) || fallback; }
|
||||
${bundle}
|
||||
return { collectSettingsPayload };
|
||||
`)();
|
||||
|
||||
Reference in New Issue
Block a user