From 0dc8033c6be8bb57ace9e124ef81a606dcbf0654 Mon Sep 17 00:00:00 2001 From: laoyang Date: Tue, 3 Nov 2026 10:48:07 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9C=AC=E4=BA=BA=E5=9B=9E=E5=A4=8D=E8=87=AA?= =?UTF-8?q?=E5=B7=B1=E7=9A=84=E5=8F=8D=E9=A6=88=E4=B8=8D=E5=8F=91=E9=80=9A?= =?UTF-8?q?=E7=9F=A5=E4=BF=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 用户:「他自己回复他自己的反馈,不要再给他发邮件了 —— 他自己说的,他发给他自己,不是很奇怪吗?但如果是别人回复他的,就可以发。」 原逻辑在 mailer 里有个「自己通知自己」判断,但写成了: !empty($extra["is_admin"]) === false 双重否定绕,读起来要停一下才知道在判什么,而且没有覆盖空格差异。 改法: - 改成直接判 $isAdminNotice,条件意图一眼可见 - 邮箱比较前 trim + strcasecmp,覆盖 大小写不同 / 前后空格 两种写法 - 拦下时写 notify_log 并给出明确原因「本人回复自己的反馈,不发信」, 以后排查「为什么没收到信」能直接看到 验证(5 种情形 + 完整 DB 路径): 同邮箱 → 拦下;大小写不同 → 拦下;带空格 → 拦下; 别人邮箱 → 正常发;管理员邮箱 → 正常通知提交人。 另在库里真插一条本人回复走 fb_notify_event,同样被拦下。 关于「带 token 能否修改原反馈」:确认后决定不做。 理由:反馈一旦公开,别人已看过/回复过,改了会让讨论对不上号; 补充信息用回复完全够用。现状只能看和回复。 --- lib/bootstrap.php | 2 +- lib/mailer.php | 27 +++++++++++++++++++++------ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/lib/bootstrap.php b/lib/bootstrap.php index a3603f4..cff0f6a 100644 --- a/lib/bootstrap.php +++ b/lib/bootstrap.php @@ -8,7 +8,7 @@ if (!defined('FB_ROOT')) { define('FB_ROOT', dirname(__DIR__)); // 静态资源版本号:改 assets/ 下的 css/js 后把这个数字 +1, // 让浏览器与 CDN 缓存失效。全站只此一处,别再往页面里写死数字。 - if (!defined('FB_ASSET_V')) { define('FB_ASSET_V', 31); } + if (!defined('FB_ASSET_V')) { define('FB_ASSET_V', 32); } } /* ------------------------------------------------------------------ diff --git a/lib/mailer.php b/lib/mailer.php index b2867fa..3cf693f 100644 --- a/lib/mailer.php +++ b/lib/mailer.php @@ -737,12 +737,27 @@ if (!function_exists('fb_notify_event')) { return [false, $why]; } - // ---- 3. 自己通知自己就别发了 ---- - if (!$isAdminNotice && !empty($extra['is_admin']) === false - && !empty($extra['reply']['author_email'])) { - if (strcasecmp(trim((string)$extra['reply']['author_email']), $to) === 0) { - $log($to, 0, '自己回复自己,不发'); - return [false, '自己回复自己,不发']; + /* ---- 3. 自己通知自己就别发了 ---- + * + * 用户 2026-11-03:「他自己回复他自己的反馈,不要再给他发邮件了 —— + * 他自己说的,他发给他自己,不是很奇怪吗?但如果是别人回复他的, + * 就可以给他发邮件。」 + * + * 覆盖三种「其实是同一个人」的情形: + * ① 提交人自己回复(带 token 进来,服务端会把邮箱强制设为原作者); + * ② 回复者填的邮箱与提交人相同(普通访客碰巧同邮箱); + * ③ 邮箱大小写 / 前后空格不同(DAO@x.com vs dao@x.com)。 + * + * ⚠️ 旧写法是 `!empty($extra['is_admin']) === false` —— 双重否定绕, + * 读起来要停一下才知道在判什么。这里改成直接判 is_admin。 + * ⚠️ 官方(管理员)回复不在豁免之列:管理员邮箱通常与提交人不同, + * 但万一相同(管理员给自己提的反馈回复),也不该给自己发信。 */ + if (!$isAdminNotice) { + $replyMail = isset($extra['reply']['author_email']) + ? trim((string)$extra['reply']['author_email']) : ''; + if ($replyMail !== '' && strcasecmp($replyMail, $to) === 0) { + $log($to, 0, '本人回复自己的反馈,不发信'); + return [false, '本人回复自己的反馈,不发信']; } }