Skip to content

fix(telegram): surface verification codes in mail previews - #1034

Open
liut-coder wants to merge 1 commit into
dreamhunter2333:mainfrom
liut-coder:fix/telegram-verification-code-preview
Open

fix(telegram): surface verification codes in mail previews#1034
liut-coder wants to merge 1 commit into
dreamhunter2333:mainfrom
liut-coder:fix/telegram-verification-code-preview

Conversation

@liut-coder

@liut-coder liut-coder commented May 11, 2026

Copy link
Copy Markdown

Summary

  • Add Telegram mail preview fallback from HTML bodies to readable plain text.
  • Extract likely 4-8 digit verification codes from subject/text/HTML and show them first.
  • Cover spaced, separated, entity-encoded, 4-digit, 6-digit, and 8-digit code formats.
  • Keep changelogs updated in Chinese and English.

Test Plan

  • node --test src/telegram_api/verification_code.test.ts
  • corepack pnpm lint
  • corepack pnpm build

Summary by CodeRabbit

发布说明

  • Bug 修复

    • 改进 Telegram 推送通知中的电子邮件内容处理:当仅有 HTML 时可回退到纯文本,优先识别并突出显示 4–8 位验证码,并兼容常见分隔格式与 HTML 实体,避免在小程序中只显示“解析失败”类信息。
  • 测试

    • 新增验证码提取与 HTML 转纯文本相关的测试覆盖。

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 11, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

此 PR 为 Telegram 邮件渲染添加 HTML→纯文本回退、可搜索邮件文本构建和启发式 4–8 位验证码提取,并在 parseMail 中优先显示提取出的验证码;包含单元测试和变更日志及 Pages 项目名更新。

Changes

Telegram验证码提取功能

Layer / File(s) Summary
HTML 处理工具
worker/src/telegram_api/verification_code.ts
实现 decodeHtmlEntities(含 &#...; / &#x...; 解码)、htmlToPlainText(移除 script/style、
<br>/块级标签转为换行、去零宽字符、折叠空白)、buildSearchableMailText(合并 subject/text/html->plain 为可搜索字符串)。
验证码评分引擎
worker/src/telegram_api/verification_code.ts
实现 compactCodeisDateLikegetDistanceToKeywordscoreCandidateextractVerificationCode:正则匹配 4–8 位(允许分隔符)、压缩分隔、去重、上下文切片、启发式评分并选出最优候选。
邮件解析集成
worker/src/telegram_api/telegram.ts
导入并使用上述工具:HTML→纯文本回退到 parsedEmail.text、用 buildSearchableMailText 提取可搜索文本并调用 extractVerificationCode、对正文截断至 1000 字并在 Content 字段优先展示 验证码:<code> 或回退的解析文本/解析失败提示。
测试覆盖
worker/src/telegram_api/verification_code.test.ts
新增测试覆盖:HTML-only 邮件提取、空格/分隔符/混合标点的数字规范化、4 位与 8 位支持、上下文优先选择以及 htmlToPlainText 对实体和常见标签的转换。
文档和配置更新
CHANGELOG.md, CHANGELOG_EN.md, pages/wrangler.toml
添加 v1.9.0 的 Telegram 修复说明(HTML→纯文本回退与验证码优先呈现);将 Cloudflare Pages 项目名从 temp-email-pages 改为 cloudflare-temp-email-pages

Sequence Diagram(s)

(该变更为库内部工具与 parseMail 集成,交互较局部且涉及不到 3 个独立外部组件;此处省略序列图。)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 分钟

Suggested labels

Review effort 4/5

Suggested reviewers

  • dreamhunter2333

总体概览

这个PR为Telegram的邮件内容处理添加了智能验证码提取功能。新增验证码提取工具集包括HTML实体解码、纯文本转换和基于多重启发式的验证码评分选择。parseMail函数现在优先展示提取的4-8位验证码,并从HTML回退到纯文本。包含完整的测试覆盖和变更文档更新。

变更详情

Telegram验证码提取功能

层级 / 文件 摘要
HTML处理工具
worker/src/telegram_api/verification_code.ts
实现decodeHtmlEntities转换HTML实体(含&#...;&#x...;形式)、htmlToPlainText将HTML归一化为纯文本(移除脚本/样式块、转换<br>和块标签为换行、移除零宽字符、折叠空白)、buildSearchableMailText组合主题和文本/HTML为可搜索字符串。
验证码评分引擎
worker/src/telegram_api/verification_code.ts
实现内部助手函数(compactCodeisDateLike检测格式;getDistanceToKeyword计算关键词距离;scoreCandidate基于数字长度启发式、验证关键词邻近度、"code/pin/otp"模式、过期语言提升、日期/时间惩罚和后期出现惩罚进行评分)和extractVerificationCode主函数(规范化输入、正则匹配4-8位候选、压缩分隔符、去重、提取上下文、计算评分、过滤正分数、按分数和位置排序)。
邮件解析集成
worker/src/telegram_api/telegram.ts
导入验证码提取工具;更新parseMail函数将parsedEmail.html转换为纯文本(无纯文本时使用)、提取验证码、截断超过1000字符的文本并添加"消息过长"提示、在Content字段优先展示验证码(格式:"验证码:<code>")或使用解析的文本/解析失败回退消息。
测试覆盖
worker/src/telegram_api/verification_code.test.ts
测试六位码从HTML专用邮件的提取、空格/分隔符/混合标点的码解析、4位和8位码长支持、代码相关上下文优先级、HTML实体和标签的纯文本渲染。
文档和配置更新
CHANGELOG.md, CHANGELOG_EN.md, pages/wrangler.toml
添加v1.9.0 bug修复条目说明Telegram邮件HTML转纯文本回退和4-8位验证码优先提取;将Cloudflare Pages项目名从temp-email-pages重命名为cloudflare-temp-email-pages

可能相关的PR

  • dreamhunter2333/cloudflare_temp_email#895:两个PR都修改worker/src/telegram_api/telegram.ts(一个添加HTML转纯文本和验证码提取逻辑,另一个添加附件处理/发送),因此都涉及Telegram邮件渲染/发送代码库。

建议标签

Review effort 4/5

建议审阅者

  • dreamhunter2333

代码审查工作量估计

🎯 4 (Complex) | ⏱️ ~45 分钟


🐰 验证码躲在 HTML 里,
解码归一我来寻,
四位八位皆可取,
上下文评分定真身,
Telegram 消息笑开颜 🌟

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly and specifically describes the main change: adding verification code extraction and display in Telegram mail previews, which aligns directly with the primary objective across all modified files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@liut-coder
liut-coder force-pushed the fix/telegram-verification-code-preview branch from 781fdca to 5a005ee Compare May 11, 2026 06:56

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
pages/wrangler.toml (1)

1-1: ⚡ Quick win

同步 pages/ 目录下的配置文件项目名

仓库中 pages/wrangler.toml 的项目名为 cloudflare-temp-email-pages,但 pages/package.json 中仍为 temp-email-pages。尽管生产部署时 CI/CD 通过 GitHub secrets 动态注入 wrangler.toml(减低部署风险),但仓库内的配置不一致会影响本地开发体验(如 wrangler pages dev 等本地命令)。建议将两个配置文件的项目名统一,或在文档中说明两者为何不同。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pages/wrangler.toml` at line 1, 仓库中 pages/wrangler.toml 的 name 字段值
"cloudflare-temp-email-pages" 与 pages/package.json 的 name ("temp-email-pages")
不一致;请在 pages/wrangler.toml 的 name 字段或 pages/package.json 的 name 字段中统一为同一个项目名(例如将
wrangler.toml 的 name 改为 "temp-email-pages" 或反向统一到
"cloudflare-temp-email-pages"),并在 README 中补充说明若 CI/CD 使用 secrets 在部署时覆盖
wrangler.toml 的场景,以免影响本地命令(如 wrangler pages dev)。
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@worker/src/telegram_api/telegram.ts`:
- Around line 400-402: The content concatenation hardcodes the Chinese prefix
"验证码:" which breaks i18n; update the logic that builds content (the const named
content that uses verificationCode and parsedText) to use a new LocaleMessages
key (e.g., TgVerificationCodeLabel) from msgs instead of the hardcoded string,
then add TgVerificationCodeLabel to the i18n entries for both languages (Chinese
"验证码" and English "Verification code") so content becomes
`${msgs.TgVerificationCodeLabel}:${verificationCode}` (keeping the parsedText
fallback behavior).

In `@worker/src/telegram_api/verification_code.ts`:
- Around line 17-30: The decodeHtmlEntities function can call
String.fromCodePoint with out-of-range values (e.g., parseInt("999999999")),
causing a RangeError; update its numeric-entity handling (the branches that
parse hex and decimal using parseInt) to validate the parsed charCode is an
integer within [0, 0x10FFFF] before calling String.fromCodePoint and otherwise
fall back to returning the original entity; ensure both the "#x" and "#"
branches perform this check so decodeHtmlEntities no longer throws for oversized
code points.

---

Nitpick comments:
In `@pages/wrangler.toml`:
- Line 1: 仓库中 pages/wrangler.toml 的 name 字段值 "cloudflare-temp-email-pages" 与
pages/package.json 的 name ("temp-email-pages") 不一致;请在 pages/wrangler.toml 的 name
字段或 pages/package.json 的 name 字段中统一为同一个项目名(例如将 wrangler.toml 的 name 改为
"temp-email-pages" 或反向统一到 "cloudflare-temp-email-pages"),并在 README 中补充说明若 CI/CD
使用 secrets 在部署时覆盖 wrangler.toml 的场景,以免影响本地命令(如 wrangler pages dev)。
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ee0a05e3-4c06-4020-b691-8f9f61843113

📥 Commits

Reviewing files that changed from the base of the PR and between 74c8e8f and 781fdca.

📒 Files selected for processing (6)
  • CHANGELOG.md
  • CHANGELOG_EN.md
  • pages/wrangler.toml
  • worker/src/telegram_api/telegram.ts
  • worker/src/telegram_api/verification_code.test.ts
  • worker/src/telegram_api/verification_code.ts

Comment on lines +400 to +402
const content = verificationCode
? `验证码:${verificationCode}` + (parsedText ? `\n\n${parsedText}` : "")
: (parsedText || msgs.TgParseFailedViewInAppMsg);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

验证码标签硬编码中文,破坏多语言一致性。

文件中所有面向用户的文案(TgMsgTooLongMsg / TgParseFailedViewInAppMsg / TgNoSenderMsg 等)都走 msgs: LocaleMessages,且 Bot 已通过 /lang 支持中英文切换。此处直接拼接 验证码:,英文用户也会看到中文前缀,与现有 i18n 约定不一致。建议在 LocaleMessages 中新增对应 key(如 TgVerificationCodeLabel),中文 验证码、英文 Verification code

♻️ 建议改为走 i18n
         const content = verificationCode
-            ? `验证码:${verificationCode}` + (parsedText ? `\n\n${parsedText}` : "")
+            ? `${msgs.TgVerificationCodeLabel}: ${verificationCode}` + (parsedText ? `\n\n${parsedText}` : "")
             : (parsedText || msgs.TgParseFailedViewInAppMsg);

并在 worker/src/i18n 中为中英文各加一条 TgVerificationCodeLabel(如 验证码 / Verification code)。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@worker/src/telegram_api/telegram.ts` around lines 400 - 402, The content
concatenation hardcodes the Chinese prefix "验证码:" which breaks i18n; update the
logic that builds content (the const named content that uses verificationCode
and parsedText) to use a new LocaleMessages key (e.g., TgVerificationCodeLabel)
from msgs instead of the hardcoded string, then add TgVerificationCodeLabel to
the i18n entries for both languages (Chinese "验证码" and English "Verification
code") so content becomes `${msgs.TgVerificationCodeLabel}:${verificationCode}`
(keeping the parsedText fallback behavior).

Comment on lines +17 to +30
export const decodeHtmlEntities = (value: string): string => {
return value.replace(/&(#x?[0-9a-fA-F]+|[a-zA-Z][a-zA-Z0-9]+);/g, (entity, code: string) => {
const lowerCode = code.toLowerCase();
if (lowerCode.startsWith("#x")) {
const charCode = parseInt(lowerCode.slice(2), 16);
return Number.isFinite(charCode) ? String.fromCodePoint(charCode) : entity;
}
if (lowerCode.startsWith("#")) {
const charCode = parseInt(lowerCode.slice(1), 10);
return Number.isFinite(charCode) ? String.fromCodePoint(charCode) : entity;
}
return htmlEntityMap[lowerCode] ?? entity;
});
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

String.fromCodePoint 可能因越界码点抛出 RangeError

Number.isFinite 只能拦截 NaN,但对于 &#999999999; 这类超过 0x10FFFF 的数值实体,parseInt 会返回合法的有限数,String.fromCodePoint 会抛出 RangeError。虽然 parseMail 有 try/catch 兜底,但会导致验证码提取整段失败,建议显式校验码点范围后再调用。

🛡️ 建议加入码点范围校验
 export const decodeHtmlEntities = (value: string): string => {
     return value.replace(/&(`#x`?[0-9a-fA-F]+|[a-zA-Z][a-zA-Z0-9]+);/g, (entity, code: string) => {
         const lowerCode = code.toLowerCase();
         if (lowerCode.startsWith("#x")) {
             const charCode = parseInt(lowerCode.slice(2), 16);
-            return Number.isFinite(charCode) ? String.fromCodePoint(charCode) : entity;
+            return Number.isFinite(charCode) && charCode >= 0 && charCode <= 0x10FFFF
+                ? String.fromCodePoint(charCode) : entity;
         }
         if (lowerCode.startsWith("#")) {
             const charCode = parseInt(lowerCode.slice(1), 10);
-            return Number.isFinite(charCode) ? String.fromCodePoint(charCode) : entity;
+            return Number.isFinite(charCode) && charCode >= 0 && charCode <= 0x10FFFF
+                ? String.fromCodePoint(charCode) : entity;
         }
         return htmlEntityMap[lowerCode] ?? entity;
     });
 };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const decodeHtmlEntities = (value: string): string => {
return value.replace(/&(#x?[0-9a-fA-F]+|[a-zA-Z][a-zA-Z0-9]+);/g, (entity, code: string) => {
const lowerCode = code.toLowerCase();
if (lowerCode.startsWith("#x")) {
const charCode = parseInt(lowerCode.slice(2), 16);
return Number.isFinite(charCode) ? String.fromCodePoint(charCode) : entity;
}
if (lowerCode.startsWith("#")) {
const charCode = parseInt(lowerCode.slice(1), 10);
return Number.isFinite(charCode) ? String.fromCodePoint(charCode) : entity;
}
return htmlEntityMap[lowerCode] ?? entity;
});
};
export const decodeHtmlEntities = (value: string): string => {
return value.replace(/&(`#x`?[0-9a-fA-F]+|[a-zA-Z][a-zA-Z0-9]+);/g, (entity, code: string) => {
const lowerCode = code.toLowerCase();
if (lowerCode.startsWith("#x")) {
const charCode = parseInt(lowerCode.slice(2), 16);
return Number.isFinite(charCode) && charCode >= 0 && charCode <= 0x10FFFF
? String.fromCodePoint(charCode) : entity;
}
if (lowerCode.startsWith("#")) {
const charCode = parseInt(lowerCode.slice(1), 10);
return Number.isFinite(charCode) && charCode >= 0 && charCode <= 0x10FFFF
? String.fromCodePoint(charCode) : entity;
}
return htmlEntityMap[lowerCode] ?? entity;
});
};
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@worker/src/telegram_api/verification_code.ts` around lines 17 - 30, The
decodeHtmlEntities function can call String.fromCodePoint with out-of-range
values (e.g., parseInt("999999999")), causing a RangeError; update its
numeric-entity handling (the branches that parse hex and decimal using parseInt)
to validate the parsed charCode is an integer within [0, 0x10FFFF] before
calling String.fromCodePoint and otherwise fall back to returning the original
entity; ensure both the "#x" and "#" branches perform this check so
decodeHtmlEntities no longer throws for oversized code points.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
worker/src/telegram_api/verification_code.ts (1)

17-30: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

String.fromCodePoint 仍可能因越界码点抛出 RangeError

Number.isFinite 不会拦截 &#999999999; 这类超出 0x10FFFF 的合法有限数值实体,建议显式约束码点范围到 [0, 0x10FFFF] 再调用 String.fromCodePoint,否则会触发整段验证码提取失败(仅由 parseMail 的 try/catch 兜底)。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@worker/src/telegram_api/verification_code.ts` around lines 17 - 30, The
decodeHtmlEntities function can call String.fromCodePoint with out-of-range
values (e.g., from parseInt on large numeric entities) which throws RangeError;
update the numeric-entity branches in decodeHtmlEntities to validate the parsed
charCode is an integer within 0..0x10FFFF (and non-negative) before calling
String.fromCodePoint, and otherwise fall back to returning the original entity;
leave the named-entity path using htmlEntityMap as-is.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@worker/src/telegram_api/verification_code.ts`:
- Around line 55-66: The colon+two-digits check in isLikelyDateOrTime falsely
tags 4-digit OTPs when the surrounding context has labels like "code: 1234";
change the logic so you only treat a 4-digit string as time when the context
contains the code itself split by a colon (e.g. "12:34" or "12:34") rather than
any colon followed by two digits anywhere: replace the /^\d{4}$/.test(code) &&
/[::]\s*\d{2}/.test(context) branch with a check that builds and searches for
the code split by a colon (e.g. new
RegExp(`${code.slice(0,2)}[::]\\s*${code.slice(2)}`)) or otherwise verifies the
matched HH:MM substring includes the code characters, so labels like "code:" or
"验证码:" do not trigger a time match; update isLikelyDateOrTime accordingly (and
any callers such as scoreCandidate) to avoid the -100 penalty for legitimate
OTPs.

---

Duplicate comments:
In `@worker/src/telegram_api/verification_code.ts`:
- Around line 17-30: The decodeHtmlEntities function can call
String.fromCodePoint with out-of-range values (e.g., from parseInt on large
numeric entities) which throws RangeError; update the numeric-entity branches in
decodeHtmlEntities to validate the parsed charCode is an integer within
0..0x10FFFF (and non-negative) before calling String.fromCodePoint, and
otherwise fall back to returning the original entity; leave the named-entity
path using htmlEntityMap as-is.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ae1dc80c-c2d4-4b82-8438-f8067749c2bc

📥 Commits

Reviewing files that changed from the base of the PR and between 781fdca and 5a005ee.

📒 Files selected for processing (6)
  • CHANGELOG.md
  • CHANGELOG_EN.md
  • pages/wrangler.toml
  • worker/src/telegram_api/telegram.ts
  • worker/src/telegram_api/verification_code.test.ts
  • worker/src/telegram_api/verification_code.ts
✅ Files skipped from review due to trivial changes (4)
  • pages/wrangler.toml
  • CHANGELOG_EN.md
  • worker/src/telegram_api/verification_code.test.ts
  • CHANGELOG.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • worker/src/telegram_api/telegram.ts

Comment on lines +55 to +66
const isLikelyDateOrTime = (code: string, context: string): boolean => {
if (/^(19|20)\d{2}$/.test(code)) {
return true;
}
if (/^\d{8}$/.test(code) && /(?:date|日期|时间|time|expires?|过期|有效期)/i.test(context)) {
return true;
}
if (/^\d{4}$/.test(code) && /[::]\s*\d{2}/.test(context)) {
return true;
}
return false;
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

4 位验证码会因相邻的“code: ”等上下文被误判为时间,导致 -100 惩罚后被丢弃。

第 62 行使用 /[::]\s*\d{2}/.test(context) 在 ±120 字符上下文里搜索“冒号+两位数字”。对于常见提示语 Your code: 1234验证码:1234,上下文中的 : 12/:12 同样会命中该模式,从而把合法的 4 位 OTP 标记为时间,叠加 scoreCandidate-100 的扣分,几乎一定使其得分变负而被过滤。

建议只在数字未紧邻 code 本身时判定为时间,例如把整段时间形如 HH:MM 的判断改为仅匹配 4 位代码自身被冒号一分为二的情况,或者在匹配时排除 code 自身所在区间。

🛠️ 建议修正
-    if (/^\d{4}$/.test(code) && /[::]\s*\d{2}/.test(context)) {
-        return true;
-    }
+    // 仅当 4 位代码本身呈现为 "HH:MM" 形式时才视为时间
+    if (/^\d{4}$/.test(code) && new RegExp(`${code[0]}${code[1]}[::]${code[2]}${code[3]}`).test(context)) {
+        return true;
+    }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const isLikelyDateOrTime = (code: string, context: string): boolean => {
if (/^(19|20)\d{2}$/.test(code)) {
return true;
}
if (/^\d{8}$/.test(code) && /(?:date|||time|expires?||)/i.test(context)) {
return true;
}
if (/^\d{4}$/.test(code) && /[:]\s*\d{2}/.test(context)) {
return true;
}
return false;
};
const isLikelyDateOrTime = (code: string, context: string): boolean => {
if (/^(19|20)\d{2}$/.test(code)) {
return true;
}
if (/^\d{8}$/.test(code) && /(?:date|||time|expires?||)/i.test(context)) {
return true;
}
// 仅当 4 位代码本身呈现为 "HH:MM" 形式时才视为时间
if (/^\d{4}$/.test(code) && new RegExp(`${code[0]}${code[1]}[::]${code[2]}${code[3]}`).test(context)) {
return true;
}
return false;
};
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@worker/src/telegram_api/verification_code.ts` around lines 55 - 66, The
colon+two-digits check in isLikelyDateOrTime falsely tags 4-digit OTPs when the
surrounding context has labels like "code: 1234"; change the logic so you only
treat a 4-digit string as time when the context contains the code itself split
by a colon (e.g. "12:34" or "12:34") rather than any colon followed by two
digits anywhere: replace the /^\d{4}$/.test(code) &&
/[::]\s*\d{2}/.test(context) branch with a check that builds and searches for
the code split by a colon (e.g. new
RegExp(`${code.slice(0,2)}[::]\\s*${code.slice(2)}`)) or otherwise verifies the
matched HH:MM substring includes the code characters, so labels like "code:" or
"验证码:" do not trigger a time match; update isLikelyDateOrTime accordingly (and
any callers such as scoreCandidate) to avoid the -100 penalty for legitimate
OTPs.

@dreamhunter2333

Copy link
Copy Markdown
Owner

感谢贡献,需要适配下多语言

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants