feat: 添加提取和验证ChatGPT登录代码的功能
This commit is contained in:
+78
-8
@@ -668,12 +668,85 @@ function matchesMailFilters(text, senderFilters, subjectFilters) {
|
||||
return senderMatch || subjectMatch;
|
||||
}
|
||||
|
||||
function extractVerificationCode(text, strictChatGPTCodeOnly = false) {
|
||||
if (strictChatGPTCodeOnly) {
|
||||
const strictMatch = String(text || '').match(/(?:your\s+chatgpt\s+code\s+is|(?:chatgpt\s+log-?in\s+code|suspicious\s+log-?in)[\s\S]{0,120}enter\s+this\s+code)[^0-9]{0,24}(\d{6})/i);
|
||||
return strictMatch ? strictMatch[1] : null;
|
||||
function extractStrictChatGPTVerificationCode(text) {
|
||||
const normalized = String(text || '');
|
||||
const patterns = [
|
||||
/your\s+(?:temporary\s+)?chatgpt\s+(?:(?:log-?in|login)\s+)?code\s+is[\s\S]{0,80}?(\d{6})/i,
|
||||
/(?:chatgpt\s+log-?in\s+code|suspicious\s+log-?in)[\s\S]{0,200}?enter\s+this\s+code[\s\S]{0,80}?(\d{6})/i,
|
||||
/enter\s+this\s+code[\s\S]{0,80}?(\d{6})/i,
|
||||
];
|
||||
|
||||
for (const pattern of patterns) {
|
||||
const match = normalized.match(pattern);
|
||||
if (match) return match[1];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function isLikelyCompactTimeValue(value = '') {
|
||||
const text = String(value || '');
|
||||
if (!/^\d{6}$/.test(text)) return false;
|
||||
|
||||
const hours = Number(text.slice(0, 2));
|
||||
const minutes = Number(text.slice(2, 4));
|
||||
const seconds = Number(text.slice(4, 6));
|
||||
return hours >= 0 && hours <= 23
|
||||
&& minutes >= 0 && minutes <= 59
|
||||
&& seconds >= 0 && seconds <= 59;
|
||||
}
|
||||
|
||||
function isLikelyHeaderTimestampCode(text, index, value) {
|
||||
const source = String(text || '');
|
||||
const candidate = String(value || '');
|
||||
if (!candidate) return false;
|
||||
|
||||
const before = source.slice(Math.max(0, index - 80), index);
|
||||
const after = source.slice(index + candidate.length, index + candidate.length + 40);
|
||||
const context = `${before}${candidate}${after}`.replace(/\s+/g, ' ');
|
||||
const beforeCompact = before.replace(/\s+/g, ' ');
|
||||
const timeLike = isLikelyCompactTimeValue(candidate);
|
||||
|
||||
if (
|
||||
timeLike
|
||||
&& /(?:\d{4}[-/.]\d{1,2}[-/.]\d{1,2}|\d{1,2}[-/.]\d{1,2})\s*$/.test(beforeCompact)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (
|
||||
timeLike
|
||||
&& /(?:\d{4}[-/.]\d{1,2}[-/.]\d{1,2}|\d{1,2}[-/.]\d{1,2})\s*(?:\d{1,2}:\d{2}(?::\d{2})?|\d{6})/.test(context)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return /(?:time|date|sent|received|received\s+at|sent\s+at|\u65f6\s*\u95f4|\u65e5\s*\u671f)[\s:\uFF1A-]*$/i.test(beforeCompact)
|
||||
&& (timeLike || /^20\d{4}$/.test(candidate));
|
||||
}
|
||||
|
||||
function findSafeStandaloneSixDigitCode(text) {
|
||||
const normalized = String(text || '');
|
||||
const pattern = /\b(\d{6})\b/g;
|
||||
let match = null;
|
||||
|
||||
while ((match = pattern.exec(normalized)) !== null) {
|
||||
const candidate = match[1];
|
||||
if (!isLikelyHeaderTimestampCode(normalized, match.index, candidate)) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function extractVerificationCode(text, strictChatGPTCodeOnly = false) {
|
||||
const strictCode = extractStrictChatGPTVerificationCode(text);
|
||||
if (strictChatGPTCodeOnly) {
|
||||
return strictCode;
|
||||
}
|
||||
if (strictCode) return strictCode;
|
||||
|
||||
const normalized = String(text || '');
|
||||
|
||||
const matchCn = normalized.match(/(?:代码为|验证码[^0-9]*?)[\s::]*(\d{6})/);
|
||||
@@ -688,10 +761,7 @@ function extractVerificationCode(text, strictChatGPTCodeOnly = false) {
|
||||
const matchEn = normalized.match(/code[:\s]+is[:\s]+(\d{6})|code[:\s]+(\d{6})/i);
|
||||
if (matchEn) return matchEn[1] || matchEn[2];
|
||||
|
||||
const match6 = normalized.match(/\b(\d{6})\b/);
|
||||
if (match6) return match6[1];
|
||||
|
||||
return null;
|
||||
return findSafeStandaloneSixDigitCode(normalized);
|
||||
}
|
||||
|
||||
function extractEmails(text = '') {
|
||||
|
||||
@@ -549,6 +549,10 @@ return {
|
||||
|
||||
test('extractVerificationCode strict mode matches the new suspicious log-in mail body', () => {
|
||||
const bundle = [
|
||||
extractFunction('extractStrictChatGPTVerificationCode'),
|
||||
extractFunction('isLikelyCompactTimeValue'),
|
||||
extractFunction('isLikelyHeaderTimestampCode'),
|
||||
extractFunction('findSafeStandaloneSixDigitCode'),
|
||||
extractFunction('extractVerificationCode'),
|
||||
].join('\n');
|
||||
|
||||
@@ -562,6 +566,32 @@ return { extractVerificationCode };
|
||||
assert.equal(api.extractVerificationCode(bodyText, false), '982219');
|
||||
});
|
||||
|
||||
test('extractVerificationCode ignores compact header time before fallback code', () => {
|
||||
const bundle = [
|
||||
extractFunction('extractStrictChatGPTVerificationCode'),
|
||||
extractFunction('isLikelyCompactTimeValue'),
|
||||
extractFunction('isLikelyHeaderTimestampCode'),
|
||||
extractFunction('findSafeStandaloneSixDigitCode'),
|
||||
extractFunction('extractVerificationCode'),
|
||||
].join('\n');
|
||||
|
||||
const api = new Function(`
|
||||
${bundle}
|
||||
return { extractVerificationCode };
|
||||
`)();
|
||||
|
||||
const bodyText = [
|
||||
'Your temporary ChatGPT login code',
|
||||
'From: otp <otp@tm1.openai.com>',
|
||||
'To: test@example.com',
|
||||
'Time: 2026-4-22 101755',
|
||||
'OpenAI',
|
||||
'371138',
|
||||
].join('\n');
|
||||
|
||||
assert.equal(api.extractVerificationCode(bodyText, false), '371138');
|
||||
});
|
||||
|
||||
test('openMailAndGetMessageText always returns to inbox after opening a 2925 message', async () => {
|
||||
const bundle = [
|
||||
extractFunction('returnToInbox'),
|
||||
|
||||
Reference in New Issue
Block a user