# 云端全项目测试报告 ## 三库范围与推送现场复核(2026-10-03 20:58) 本节更新当前状态,下方三库核心业务证据保持原范围,不提升为三库全功能通过。本次沿用已初始化新库继续验收,未清库、未删除文件、未修改其他项目。 ### 直接复核结果 - 20:56 通过既有交互式 SSH 核对 Smail 和 Nginx 均为 active;Smail 主进程为 `2014413`,自动重启次数为 `0`。运行进程可执行文件 SHA256 为 `6f4700014014a4e660e25b76a4d04409ede3a8c770c6409da56fdf81208b222a`,与当前构建一致。本段未重新部署或重启服务。 - 复用当前 Smail 浏览器 MCP,后台为 `https://web.cdis.cn`;超管微信绑定弹窗可见,页面仍显示尚未绑定。已提示用户使用本人微信扫码,二维码有效期五分钟,不将生成二维码视为绑定成功。 - 经用户允许的外部连通性诊断,通过 `http://127.0.0.1:9000` 请求 Telegram 官方站点,不携机器人令牌,直接返回 `407 Proxy Authentication Required` 及 Basic 认证挑战,CONNECT 隧道未建立。该结果仅定位当前代理认证阻塞,不验证令牌、回调、绑定、上游可用性或实际推送。 ### 前段配置补录与协作事项 - 前段通过超管页面保存新库公众号密钥,经本人密码验证后仅显示已加密存储;配置公众号应用、模板、统一授权域名 `web.cdis.cn` 并启用。20:52:25 仅重启 Smail,个人页面重新加载后扫码入口可用。本节不记录密钥、二维码链接或授权状态参数。 - 新库微信仍待本人扫码及真实消息接收确认;旧库微信推送成功结论不继承。Telegram 待用户提供代理认证配置方案,未读取同机其他项目的代理凭据,未修改或重启代理。 - SQLite、MySQL、PostgreSQL 必须分别验收,每个实例只使用一种业务数据库;三库核心站内收发阅读及重启持久化记录见下方矩阵。25 端口可豁免或失败后略过,不计为通过;465、587、993、995 仍须真实客户端验收,不能以监听状态替代。 - 外部邮箱真人验证、附件上传发送下载、客户端协议及凭据撤销、证书续期应用、正式发布与测试遗留清理仍未完成。整体验收尚未放行。 ## Telegram 代理配置与连接续验(2026-10-03 20:47) 本节更新当前构建及 Telegram 状态,下方三库核心业务记录继续有效。当前是保留新库数据的连续验收,不是再次全新初始化。 - 前段通过超级管理员页面从空配置设置系统 Telegram 令牌、启用插件、配置本机 HTTP 代理、30 秒超时、后台域名及 HTTPS 通知链接。密钥通过本人密码验证后保存,页面仅显示加密存储状态,不回显。本文不记录密钥。 - 源码定位发现:回调检查固定创建直连客户端,不读取已保存代理;推送插件配置解析和客户端初始化另有非空代理拒绝条件。服务器代理端口有监听,但不能据此证明代理可用。 - 修改前检查点 `0502e50`、修复提交 `857491c` 均已推送。回调请求与插件统一使用专用 Telegram 客户端;仅超管配置的回环 IP HTTP 代理可用,沙箱仍经专属本地通道由主进程读取配置并代为出站,不能由插件请求指定代理。目标白名单、TLS 验证和代理配置错误时拒绝出站均保留。 - 新增回归源码覆盖代理校验、目标与重定向限制、沙箱不直接连接代理、CONNECT 请求不明文携带令牌、无效代理禁止直连回退。`credential`、插件服务、Linux hooks 及 Telegram hook 测试包仅完成编译,未运行自动化用例。Telegram Linux 插件及内嵌主程序构建成功;其余插件和前端资源未修改。 - 当前云端构建为 `review-20261003-857491c`,主程序 SHA256 为 `6f4700014014a4e660e25b76a4d04409ede3a8c770c6409da56fdf81208b222a`。20:43:35 经摘要检查、原子替换后仅重启 Smail,主进程为 `2014313`、自动重启为 `0`;运行可执行文件摘要一致,Smail 和 Nginx 均 active。 - 浏览器忽略缓存刷新后,超级管理员会话正常、原 SQLite 收件列表仍在,代理和统一域名设置正确回显;点击检查回调仍提示无法连接 Telegram。未点击启用或更新回调,未进行个人绑定或消息发送,不能标记推送验收通过。 - 后续只读检查确认主进程与代理进程处于同一网络命名空间,Smail 没有配置系统服务级 IP 拒绝规则。但代理认证、分流、上游、TLS 等失败阶段仍无直接证据,不推断具体根因。 - 细化脱敏连接提示的后续补丁被工具策略拒绝,文件未发生变化;检查点 `d913f65` 已推送,仅为空提交,与部署代码一致。没有绕过工具限制,也没有修改代理或其他项目。 结论:代理未接入的源码缺口已修复部署,但 Telegram 实机连接问题仍未闭环;整体验收保持未完成。25 端口按用户授权可豁免且不计通过,其他协议验收仍需继续。 ## 三库核心业务与管理员安全码恢复(2026-10-03 20:24) 本节替代下文旧域名、旧数据库和旧版本的当前状态描述;历史记录仅供追溯。后台为 `web.cdis.cn`,邮件域名为 `cdis.cn`,运行目录为 `/opt/smail`。业务操作仅使用浏览器键鼠,交互式 SSH 仅用于 Smail 部署及服务检查;本段未操作同机其他项目。 ### 三库验收矩阵 以下根据本线程前段连续实测记录补录,不是本段重新清库执行: | 数据库 | 已完成范围 | 邮件标识 | 重启持久化复核 | | --- | --- | --- | --- | | PostgreSQL | 全新初始化、三角色登录、双角色收信阅读及回复 | `PG全新部署-超管至双角色-20261003`、`PG-ADMIN-REPLY`、`PG-USER-REPLY` | 18:00:36 重启后复核 | | MySQL | 全新初始化、三角色登录、双角色收信阅读及回复 | `MySQL全新部署-双角色收发-20261003`、`MYSQL-ADMIN-REPLY`、`MYSQL-USER-REPLY` | 18:16:51 重启后复核 | | SQLite | 全新初始化、三角色登录、双角色收信阅读及回复 | `SQLite全新部署-双角色收发-20261003`、`SQLITE-ADMIN-REPLY`、`SQLITE-USER-REPLY` | 18:34:02 重启后复核 | 三库按不同部署逐一验证,每个运行实例只使用一种业务数据库;当前实例使用 `/opt/smail/data/smail.db`。历史 MySQL、PostgreSQL 验收库尚待最终按 Smail 范围清理,并非当前实例同时连接多个业务数据库。以上仅为核心站内业务及持久化证据,不代表各数据库全部功能、迁移、恢复或邮件客户端协议验收通过。 ### 本段恢复修复与直接浏览器证据 - 修改前检查点 `9040a4c` 已推送;修复提交 `c47155d` 已推送。仅修改公共恢复方式发现、安全码角色校验、已验证恢复令牌完成校验及对应回归源码。 - 原管理员已配置有效安全码,但匿名恢复显示没有可用方式。三个后端检查仍沿用管理员只能选择邮箱的旧条件,与管理员可任选一种恢复保障的当前要求不一致。 - 部署后,管理员在无已验证外部邮箱时获得安全码输入框;本人登录密码验证后查看安全码,经匿名流程完成验证、设置临时密码,页面显示密码已重置。 - 原管理员网页刷新后转到登录页,临时密码成功登录且原验收邮件正文可读取。恢复后页面提示安全码已失效;测试结束前将密码恢复为约定值,生成新安全码,再次退出并登录,不再提示补齐另一种恢复方式。 - 用旧批次中未使用的安全码再次恢复,页面明确拒绝并提示验证未通过或流程失效。超级管理员识别后仍提示只能使用已登录安全中心或部署端本机重置,不显示公共验证入口。 - 回归源码覆盖三角色边界、无外部邮箱、安全码重复核销、未经验证重置、旧安全状态撤销、令牌重复使用和失败次数耗尽;仅执行 `go test -c -o NUL ./services/recovery` 编译检查,没有运行自动化用例或调用业务 API。 ### 构建与部署 - Linux amd64 主程序使用 `CGO_ENABLED=0`、`bundled`、`trimpath` 构建成功,版本为 `review-20261003-c47155d`;前端及内置插件复用上一段已构建资源,本段未修改它们。 - SHA256:`f3a2f2254ce038dcfca4bcef4a345d91a638f9af7409fadf2da81479bdbec686`。 - 通过严格 SSH 主机密钥校验的密码交互式 SCP 上传;校验摘要后在 `/opt/smail` 原子替换,仅重启 Smail。运行进程 `2014009` 的可执行文件摘要与构建一致,Smail 和 Nginx 均为 active。 - 本段未清库、未创建备份、未新建辅助测试脚本、未提交原有未跟踪审计或构建产物。服务运行不等于生产放行。 ### 豁免和剩余事项 - 25 端口按用户许可可不测或失败后跳过,必须记录为豁免或未通过,不计作通过。465、587、993、995 不豁免,仍需符合浏览器键鼠或用户协助要求的真实客户端验收。 - 附件草稿已有正文但无附件且未发送;MCP 文件访问拒绝是工具边界,需用户正常选文件协助,不认定为 Smail 上传缺陷。 - 三个外部安全邮箱需真人收件验证;新库微信、Telegram 的初始化、绑定及送达不能沿用旧库成功结论。 - 新 DKIM 的 DNS 同步、证书续期及应用、协议凭据和在途连接撤销、超级管理员本机恢复、最终发布构建及仅限 Smail 的测试遗留清理尚未完成。 结论:三库核心站内业务有实测记录,管理员安全码独立恢复缺口已在当前 SQLite 实例修复复验;不能据此认定三库全功能或整个项目验收完成。 ## 隔离插件部署与收信规则续验(2026-09-30 22:55) 本节优先于以下旧状态。22:28 至 22:47 的修复和部署按同一线程交接记录补录;22:50 起继续浏览器复验。仍为保留 MySQL 单库数据的增量验收,未清库,不代表最新版本首次安装通过。业务验收仅使用浏览器键鼠;SSH 仅用于 Smail 诊断、备份与部署,未操作其他项目。 ### 受控出站修复与部署证据 - [x] 源码提交 `ceacd99a745b9180af2987417429b80c384a9230` 已推送。插件保留 chroot、独立网络命名空间与非 root 身份,经独立令牌认证的本地 Unix socket 请求主进程出站;主进程检查插件当前启用状态、网络权限及 HTTPS 目标名单,不开放公共代理。 - [x] 已补充目标、方法、令牌、请求体、请求头、撤权复查和生命周期等回归用例源码;本轮未运行自动化测试,源码存在不等于用例通过。响应上限、重定向、取消、并发预算及真实跨命名空间出站仍需验证,不能宣称所有在途请求都能即时撤销。 - [✓] 三个内置插件、Linux amd64 Go 主程序及两个配套工具完成编译;主网页前端未变更,复用既有嵌入资源。运行版本为 `ceacd99-audit`,产物仍含 `vcs.modified=true`,不属于干净可复现发布验收。 - [✓] 22:37:28 仅重启 Smail 完成程序替换。22:50:24 再次只读确认 Smail、Nginx 均为 active,主进程 `1771758`,自动重启次数 `0`。 - 主程序 SHA256:`10c88acb51aa0841f0670a0b4fb23c7e031bce973dd0b0a5a0122195ece862a3`。 - 管理工具 SHA256:`a7f40d30c7142cea481219b74cdc4ed78d7dbb28fe0c0349c8858c649a498e52`。 - 配置工具 SHA256:`ca562af4975d04b8fd89af7d93f1a423190578bf4a3860ec2cf877f4a24aa7bf`。 - [x] 部署前程序、配置数据证书归档和 Smail 单库备份位于 `/opt/smail/backups/release-20260930-2235`。SQL 在 22:35:44 完成,退出状态为 0,尾部完成标记已核对;摘要为 `5e7be88087094f5249906f0d677195ee96ee5f02459d49a34f9780837565f31d`。归档和 SQL 并非同一停机时点快照,未做恢复演练。 - [✓] 22:46 核实微信插件身份为 UID 994、GID 981,网络命名空间不同于主进程;沙箱出站 socket 权限为 0600、归属 994:981,能力位为零,NoNewPrivs 为 1。仅证明所述隔离及文件状态,不代表推送成功。 - [!] Telegram 插件仍在运行配置应用阶段失败;页面检查回调仍显示无法连接 Telegram。主机对 `api.telegram.org:443` 的不带凭据 TLS 连接诊断在 10 秒后超时,退出状态 124;尚未确定具体失败层,不直接归因为 DNS 污染或令牌无效,也不与插件隔离缺口混为一谈。未修改系统 DNS、代理或 hosts。 ### 收信规则浏览器实测 | 状态 | 场景 | 结果及边界 | | --- | --- | --- | | [✓] | 管理员个人规则命中 | 管理员创建主题等于 `验收规则-20260930-2241` 时移入广告箱的规则;超管发给自己与管理员的同封邮件,管理员副本进入广告箱。 | | [✓] | 个人规则不影响其他账号 | 同封邮件的超管副本保留在收件箱;22:50 后分别打开详情 `22` 与 `21`,发件人、两名收件人及中文正文一致。 | | [✓] | 等于条件非匹配 | 主题增加 `-非匹配` 后发送给管理员,副本进入收件箱;详情 `24` 正文读取正常,没有因包含原主题而触发精确匹配规则。 | | [✓] | 删除规则后立即失效 | 通过管理员页面只删除本轮测试规则,确认提示删除成功、列表暂无规则;再次发送完全相同主题,副本进入收件箱。详情 `26` 读取正常,正文标识为 `20260930-2254`,页面实际时间为 22:53,标识不作为发送时间证据。 | 本轮测试规则已清理,测试邮件保留。上述结论仅覆盖个人主题等于条件、移入广告箱、账号隔离和删除后停止生效,不覆盖全部规则操作、多规则优先级或所有角色组合。 ### 剩余放行缺口 微信真人扫码与通知送达、Telegram 连通性和绑定、附件收发、外部邮件往返、图形 SMTP/IMAP/POP3 客户端、通知凭据只发不收与撤权轮换仍未闭环。混合投递列表的笼统失败显示仍待修复;超管改密依赖外部安全邮箱。三种数据库部署选项、清库首次安装、备份恢复、证书到期续期和容量验收尚未完成,不能宣布可以正式发布。 ## 管理员改密与推送核查(2026-09-30 22:15) 本节为同一轮云端验收的接续,优先于以下旧状态;未重新清库、未部署新程序,运行版本仍为 `3155353-audit`。业务操作全部通过浏览器键鼠,SSH 只读核查 Smail 服务和插件进程,没有调用业务接口或运行辅助测试脚本。 ### 浏览器实测 - [✓] 管理员 `testadmin` 使用指定密码登录,修改为临时密码后自动进入 `/#/login`,页面正常,新密码登录成功;随后改回指定测试密码,仍自动进入正确登录页并成功登录,未出现 404。 - [✓] 提交超出当前密码长度限制的新密码时,页面明确显示“密码长度必须为 8-12 字节”,没有跳转;换成符合限制的密码后完成上述流程。此项仅记录现有策略的拒绝行为,不表示认可 12 字节上限作为最终安全策略。 - [x] 改密后的页面显示原安全凭据已失效;重新登录后密保问题为空,安全提醒要求重新生成安全码。未逐项提交旧凭据,不把页面状态等同于所有协议凭据撤销验证。管理员最终保持原角色和指定密码,但此前测试密保及安全码不再保持启用状态。 - [!] 超管 `xuans` 修改密码页面要求已验证外部安全邮箱,当前没有可用邮箱,验证码输入及提交均禁用;尚未完成该分支的改密跳转实测,没有绕过邮箱验证。 - [x] 超管本人微信通知仍未绑定;点击“扫码绑定”,完成当前密码确认后正常出现二维码弹窗及五分钟有效期提示,随后取消。只证明二维码入口可用,未进行真人扫码授权、绑定完成或消息送达验证。 - [!] 管理员附件草稿 `19` 重新打开后仍无附件,未发送;上传与接收闭环仍待完成。 ### 插件出站缺口与证据边界 - [✓] 22:08、22:13 SSH 核查 Smail 与 Nginx 均为 active,Smail 主进程 `1768882`、自动重启次数 `0`。本次没有停止、重启或改动其他项目。 - [x] 微信插件进程 `1768897` 与主进程网络命名空间不同;插件路由文件无条目输出,`stat` 明确确认其沙箱内 `/etc/resolv.conf` 与 `/etc/ssl/certs` 不存在。进程文件描述符仅见标准输入输出、RPC socket 和事件描述符,未见出站代理连接;Telegram 插件未存活。 - [x] 源码 `backend/hooks/plugin_isolation_linux.go` 使用 chroot、非 root 身份及 `CLONE_NEWNET`,继承标准输入输出和 RPC 监听描述符;`backend/utils/credential/credential.go` 的受限客户端仍直接进行 DNS 解析和 TCP 连接,`Proxy` 为 nil。该组合存在隔离环境缺少受控出站通道的实现缺口,不能把微信插件加载成功当作推送正常。 - [!] 22:03 前序页面点击 Telegram“检查回调”明确显示“无法连接 Telegram,请稍后重试”。此检查在主进程执行,与插件内出站是不同路径;尚未精确确定主进程失败发生于 DNS、连接或 TLS 哪个阶段,不宣称修复插件即可解决该问题。 - [!] Telegram 后台提供代理地址输入,但插件运行配置拒绝非空代理;现有启动日志将配置构建、校验及应用失败合并为同一提示,无法从该日志精确判断失败阶段。后续需补充不包含令牌、秘密或带凭据 URL 的阶段诊断,并核对界面与能力是否一致。 整改需保留现有隔离和目标白名单,不通过取消网络隔离、共享主机网络或启用任意代理绕过保护。本轮未实现或部署受控出站方案,微信及 Telegram 实际推送仍不通过验收。后续还需完成外部邮件、图形邮件客户端、通知凭据协议限制、附件、备份恢复等未完成项,全项目不作上线验收通过结论。 ## 最新部署与安全恢复复测(2026-09-30 22:00) 本节优先于后续历史章节。全项目仍未完成验收;此次是保留现有 MySQL 数据的增量升级和浏览器复测,不是清库首次安装验收。 ### 修复与部署 - [✓] 实机确认普通用户改密成功后跳往 `/login` 返回 404,手动进入 `/#/login` 可以使用新密码登录。已精确修正前端跳转为 `/#/login`,保持整页重载;现有回归用例补齐三种角色的跳转与身份清理断言。 - [x] 修复提交 `31553530b768da3e857ec0d3952d9e7b7a4149fd` 已推送。未运行辅助测试脚本;回归断言的代码补充不等于三种角色均已实机通过。 - [✓] 前端和 Linux amd64 Go 主程序、三个内置插件、管理及配置工具均完成编译。旧前端构建目录归档保留,重新生成本次嵌入资源,未删除原目录内容。 - [✓] 21:50:48 完成仅 Smail 服务的停止、程序替换与启动,Nginx 和其他项目未重启。22:00 复核 Smail 与 Nginx 均为运行中,主进程 `1768882`,自动重启次数为 `0`。 - 主程序 SHA256 为 `7b0e31ffcd890c5929cbd3a70fc6decca9dff0b17a35a5a3266a27cc52d49d92`,本地与上传及部署文件一致。构建版本为 `3155353-audit`,源码提交与上述一致;工作区既存删除及未跟踪产物未处理,构建仍带 `vcs.modified=true`,不得称为干净工作区可复现发布。 - 更新前备份目录为 `/opt/smail/backups/release-20260930-2148`,权限 0700;文件归档 `smail-files.tar.gz` 权限 0600,包含原主程序、Smail 配置、数据、证书、插件、环境文件及对应 systemd 和 Nginx 配置。原管理及配置工具另有备份,单库备份沿用 21:31 检查点。文件归档在服务运行中完成,不是与数据库同一时点的一致性快照;未执行完整恢复演练。 ### 浏览器实测结果 - [✓] 部署后忽略缓存重新加载页面,普通用户修改为临时密码后自动进入 `/#/login`,登录页正常,新密码可以登录;再恢复指定测试密码,仍自动进入正确登录页并成功登录,两次均未出现 404。 - [✓] 重新生成一批安全码后,旧批次安全码在找回页面被拒绝,同一流程改用新批次安全码通过,排除流程整体不可用造成的假拒绝。 - [✓] 新安全码验证成功后,点击重新申请,在新的恢复流程复用同一码被拒绝;换用该批次另一未使用安全码可以通过。此项证明已消费码不能重复验证,不等于恢复票据重放或并发竞争全部通过。 - [✓] 使用另一有效码完成密码重置,页面显示密码已重置,返回登录后指定测试密码可以登录。安全设置显示当前未配置有效离线恢复码;未把这一页面状态冒充剩余每个旧码均已直接提交验证。 - 21:36 至部署前的连续验收还确认:普通用户错误安全码被拒、正确码可恢复并登录;管理员未绑定外部安全邮箱时找回页面没有可用方式。源码按角色限制管理员恢复通道,未为测试放宽策略。 ### 状态与剩余事项 - 测试用户保持普通用户、默认组、指定测试密码和通知授权关闭;本轮生成的安全码已在恢复后失效,页面无有效安全码。测试管理员和超级管理员的密码、角色、本轮原有安全配置未改动。 - [ ] 管理员本人改密、超级管理员邮箱验证码改密尚未在此修复部署上复测;安全码与密保组合、旧恢复票据重放、协议凭据撤销仍待验收。 - [!] 启动日志仍出现 Telegram 插件运行配置失败;微信插件加载成功不代表真人扫码与推送完成。两者继续保留未通过状态。 - [ ] 附件收发、外部邮件往返、图形邮件客户端、三个数据库选项、恢复演练、证书续期及其余完整发布门槛继续按后续清单执行。 ## 当前续验结论(2026-09-30 21:28) 全项目尚未完成验收,不能宣布可以正式发布。本节更新此前记录;以下各历史章节仅代表当时版本和范围,不自动成为当前部署的放行证据。 ### 当前环境与证据边界 - 后台使用 `https://web.apmmk.cn`,邮件域为 `apmmk.cn`,运行目录为 `/opt/smail`。`solit.cn` 已属于其他项目,本轮未操作它。 - 本轮为已有验收环境的连续测试,未清库、未重新部署、未重启业务服务。业务验证只使用浏览器键鼠;交互式 SSH 仅用于部署状态诊断。 - Smail 与 Nginx 均为运行中;截至 21:22 复核,Smail 主进程为 `1728910`,自动重启次数为 `0`。 - 当前数据库配置为 MySQL、本机 3306、库名与用户均为 `smail`,运行进程存在本机 MySQL 连接;检查的配置和数据目录未发现 SQLite 数据库文件。此证据不等同于三个数据库选项、迁移及备份恢复全部验收通过。 - 云端主程序摘要为 `3fae92f1203e1b19a5fa9031e4ccd87f4d81ef2a13b6740cee8da58108909184`。程序中的构建信息包含源码版本 `7e792b1608cbc137fce0ec3783423647124713ff` 和 `vcs.modified=true`,尚未建立当前产物与干净源码的可复现对应关系。 - Nginx 配置使用 `/opt/smail/ssl/apmmk-fullchain.pem`;磁盘证书覆盖 `*.apmmk.cn` 与 `apmmk.cn`,有效期至 2026-12-28。此项仅证明配置及磁盘证书检查,不代替各协议握手与自动续期验收。 - 当前 Smail 主进程按源码设计保留 root 身份,用于创建插件 chroot、网络命名空间及子进程降权;不能误判为漏配服务用户。21:30 实机微信插件为 UID 994、GID 981,许可、有效及环境能力均为零,禁止提权,根目录为独立沙箱,网络命名空间不同于主进程。主进程权限范围仍需安全评估,不能直接改为低权限用户而破坏插件功能;该检查不代表全部插件隔离路径已验收。 - 21:31 使用指定数据库账户和测试密码完成 Smail 单库备份,命令正常退出,文件权限为 root 所有的 0600,摘要校验通过;目录为 `/opt/smail/backups/audit-checkpoint-20260930-2133`。目录后缀仅为标识,实际备份完成时间以此处及文件记录为准。未停止服务,未备份其他项目;此次数据库备份不等同于完整文件备份或恢复演练。 ### 本轮浏览器验收记录 - [✓] 三角色站内收发、阅读、回复闭环,邮件标识 `20260930-1909`。不代表外部邮箱往返或图形邮件客户端验收通过。 - [✓] 草稿保存重开、主送、抄送和密送的三角色收取阅读,标识 `20260930-2007`;其他账号不能读取不属于自己的邮件副本,收件页面未泄露密送地址。原始邮件头全路径仍需独立验证。 - [✓] 多组管理员配置保存、所属组成员管理、普通用户单组限制;多组降级与安全码前置校验。实际降级后,旧管理员会话提交成员修改被拒并要求重新登录,目标用户未被越权修改;恢复管理员角色后旧普通会话同样失效。 - [✓] 同组通知发信逐账号授权、生成及隐藏凭据、关闭授权;普通用户错误本人密码不能查看,正确密码可查看,撤销后入口消失。协议端真实发信及旧凭据撤销仍待验收。 - [✓] 安全码生成数量为 12;再次查看需要本人密码,错误密码不显示,正确密码显示;切换设置页后再次进入不保留明文。安全码消费、重复使用、撤销和完整找回仍待验收。 - [✓] 混合收件人投递,标识 `20260930-2109`:管理员发送至本站超级管理员和无效收件域名;超级管理员实际收到并读取邮件副本 `18`,发件详情显示已接收 1、失败 1,原因是收件域名解析失败。重试及重启后不重复投递尚未验证。 - [✓] 搜索上述唯一标识命中对应邮件;不存在的关键词显示空结果;键盘清空关键词后恢复完整收件列表。邮件从收件箱移入广告箱再移回成功,已恢复原位置。 - [x] 附件待验草稿 `19` 已保存,标识 `20260930-2119`,保留收件人、主题和中文待验说明,没有发送。 - [!] 附件上传被浏览器 MCP 的工作区路径校验拒绝,本地公开图片无法通过该工具选入。不能据此认定 Smail 上传故障,也不能标记附件收发通过;需要人工通过文件选择器添加附件后继续。 ### 缺陷与剩余发布门槛 - [ ] 部分投递成功时,发件列表仍笼统显示“发送失败”,详情才说明部分成功,存在显示不够准确的问题。 - [ ] 最新源码与部署产物对应关系、主进程权限与插件隔离安全复核、备份恢复演练和清理后首次安装完整流程。 - [ ] SQLite、MySQL、PostgreSQL 各选项的独立单库验证,以及迁移、故障恢复和运行容量。 - [ ] 外部邮箱双向往返、图形客户端 SMTP/IMAP/POP3、通知发信隔离及凭据轮换撤销。 - [!] Telegram 回调检查未通过;代理环境中配置的本机端口无监听,但源码客户端不直接使用该环境代理,不能据此直接归因。微信仍需真人扫码协助。 - [ ] 附件、完整账户找回、证书续期和其余生产安全门槛;不得以历史脚本或 API 测试替代当前要求的浏览器业务验收。 测试账户当前保持:测试管理员为管理员且属于默认组,安全码已开启;测试用户为普通用户且属于默认组,通知发信授权已关闭。两个空验收分组保留,未删除。本文不记录密码、授权码或安全码明文。 ## 以下为历史报告 测试日期:2026-09-20,时区 Asia/Shanghai。工作区:`D:\Desktop\Smail`。服务器:`47.108.78.12`,页面:`https://web.solit.cn/`。 ## 当前结论与验收边界(2026-09-26) - [~] 全项目验收尚未完成,不能据本报告的历史通过项宣布可以正式放行。 - [✓] 02:14 已部署源码 `218337d` 对应的 `review-218337d`,服务为 active,主进程为 1225013,自动重启次数为 0,8001、8002 正在监听,主程序及发布包摘要与本地构建一致。02:15 再次确认 active。此项仅是部署运行检查。 - [✓] 分组降级及会话失效后的设置面板残留修复已有专项浏览器证据,详见文末。该专项保留已有数据库,不属于清库生产全流程验收。 - [ ] 安全码结合密保的完整密码恢复、错误答案、已消费与已撤销恢复码的拒绝仍须按当前键鼠验收要求闭环。 - [ ] 通知 SMTP 的图形客户端加密认证、真实投递、旧凭据撤销、通知地址拒收及 IMAP/POP3 隔离尚未完成;通知页显示正常不能替代这些验证。 - [!] 外部邮箱最终入箱与持有人验证、自然续期长期调度、Windows 提权 IPC、外部插件及系统文件选择器等既有未通过项仍保留。 - [ ] 最新构建、仅 Smail 范围清库并重建浏览器测试上下文后的生产全流程验收尚未完成。 本报告以下早期自动化、API、脚本及协议工具结果仅为历史工程证据,不计作用户当前要求的浏览器键鼠业务验收。各节版本、时间和测试范围独立,不自动继承为当前部署全量通过。 ## 历史结论与任务状态(2026-09-20) 已完成全项目自动化测试、发现问题的修复、Linux 构建和云端部署,并完成核心账号安全、公网邮件协议和浏览器网页收发实机验证。含内置 AliDNS 挑战、生产续期入口及配置校验修复的源码完成了 66 包云端全量;后续 IMAP 搜索、邮件详情错误状态和插件密钥保存问题均已修复并完成对应回归。当前部署源码为 `54396ab`,最新前端 210 项通过;插件修复对应三个后端包在云端通过,361 个 PASS 标记、0 FAIL、1 SKIP,未将该版本表述为重新执行过 66 包全量。三个指定 163 邮箱的验证码已取得对端 accepted 记录,仍须邮箱持有人确认收件并完成绑定。当前没有未解决的自动化测试失败;外部邮箱最终收件、自然到期长期调度等仍未验收,不能宣布整个项目最终验收通过。 - [✓] 已按授权备份、清理 Smail 相关环境,重新初始化测试数据库。接续测试复用本轮数据库,没有重复清库。 - [✓] 修复测试发现的问题,相关包完成复测;最新程序已部署,云端和本地摘要一致。 - [✓] 含续期及配置校验修复的源码 `88649c8` 完成独立 Linux 后端全量,66 包成功、1971 个 PASS 标记、0 FAIL、5 SKIP。后续 IMAP 搜索、邮件详情及插件密钥保存分别完成受影响范围回归,版本和日志独立记录。 - [✓] 插件密钥独立保存、加密存储、版本冲突、权限拒绝和操作日志通过验证;临时密钥及管理员测试安全码已撤销,三个插件保持停用。 - [✓] 三类账号登录、TOTP 选择、提醒行为、邮件验证码跨场景消费、密码重置和客户端凭据撤销完成相应实机验证。 - [✓] 项目部署包只包含三个程序与四个运行目录,没有加入 Python、部署或续期脚本。 - [✓] 前期测试的临时 TOTP、站内外部邮箱绑定均已停用,账号密码保持用户指定值;07:19 后申请的三个指定 163 邮箱仍为待验证状态。 - [✓] 实时 DNS 控制面、两个权威 DNS 和公共 DNS 均确认泛解析生效;邮件记录保留,DKIM 与运行密钥匹配。 - [✓] Web 及已启用邮件 TLS、STARTTLS 入口返回同一张覆盖根域名的泛域名证书。 - [✓] 三个指定的 163 邮箱验证码发送均取得对端接收记录,发送接口实测为 2.30—3.23 秒,没有出现 504。 - [!] 三个指定的 163 邮箱尚待持有人确认最终收件并完成绑定验证。 - [✓] 本机 Node 客户端通过公网域名完成 SMTP 认证发信、IMAP 按 Message-ID 查询及读取、POP3 读取同一邮件正文;三个入口均正常校验 TLS 信任链与域名。 - [✓] 真实浏览器完成写信、发送成功、发件及收件阅读、中文附件内容校验;跨账号访问拒绝、失败重试和返回列表通过。系统文件选择器受工具限制未验收,具体边界见末节。 - [✓] 内置 AliDNS 在真实 staging CA 完成根域名及泛域名挑战、签发、记录清理;生产续期入口成功,配置变化自动触发 Nginx 同步与平滑重载。 - [!] 尚未等待证书自然进入续期窗口,未完成内置定时调度的长期运行验收。 - [!] Windows 提权 Named Pipe、依赖外部服务的插件业务等不在本轮 Linux 实机通过范围内。 ## 本轮修复 | 提交 | 问题与结果 | | --- | --- | | `c82be24` | 修复全量测试的密码容量竞态,更新与现有行为不一致的审查夹具及前端说明。 | | `b062ca6` | 项目 DNS 签发同时覆盖主域名及泛域名,保留两条同名 TXT 挑战。 | | `65e61a3` | 修复真实数据库迁移中对文本主键错误处理序列的问题,校正日志测试。 | | `b515186` | 公网地址探测支持失败回退,限制并发请求的总等待时间。 | | `7aec99d` | 密码重置同步撤销旧客户端授权码,补充事务回滚及用户隔离回归。 | | `e0baf27` | 未认证 POP3 的 QUIT 立即回复并关闭连接,不提交邮箱更新。 | | `310ad01` | 停用的外部邮箱允许所属用户重新绑定、切换用途;清除旧验证状态并要求重新验证。停用同时失效绑定和变更挑战,保留跨用户隔离及主要邮箱数量限制。 | | `747f79a`、`951fdc0`、`1790e1f` | 加入内置 AliDNS 凭据配置、受控证书导出与同步;修复只读沙箱权限检查,并拒绝硬链接私钥。 | | `62ed09f` | 修复 Nginx 配置检查在只读沙箱中无法打开 PID 文件的问题。 | | `87cd28f` | DNS 清理改用受限凭据已有授权的记录列表接口,分页后精确核对 ID、名称、类型和值,只删除本轮创建的记录。 | | `6920bff` | 续期后上一张证书的引用格式校验不再依赖当前工作目录权限,实际证书路径、权限及密钥匹配校验保留。 | | `eb5063a` | 修复 IMAP `SEARCH HEADER Message-ID` 总是返回空的问题;支持完整标识、子串、大小写及旧邮件备用标识,回归验证用户隔离。 | | `ff13d39` | 邮件详情增加加载、业务错误、网络失败及重试状态,失败时隐藏空元数据和删除按钮;切换邮件清除旧内容,并阻止旧请求覆盖当前页面。 | | `54396ab` | Telegram 与微信插件密钥改用独立状态及保存接口,复用权限、安全码、近期认证、加密和版本冲突保护;前端独立保存、清空已保存输入,操作日志不记录密钥载荷。 | 每轮代码修改前均保存中文 Git 基线并推送。一次文档基线推送出现认证失败,重试后成功。没有使用宽泛暂存或提交测试凭据。 ## 自动化测试证据 前期云端原始日志根目录:`/var/tmp/smail-cloud-tests-20260920/`。续期修复前全量位于 `/var/tmp/scf20/final-results/`,本地副本 `test-log/cloud-final-20260920/`。最新全量位于 `/var/tmp/scl20/results/`,本地证据与校验结果位于 `test-log/cloud-latest-20260920/`。 | 范围 | 结果 | 证据 | | --- | --- | --- | | Linux 后端最新单次全量 | 66 个包均退出成功,1971 个 PASS 标记、0 个 FAIL 标记、5 个 SKIP 标记 | `/var/tmp/scl20/results/summary.json`、`results.json` 及逐包日志 | | 续期修复前单次全量 | 66 包成功,1955 PASS、0 FAIL、5 SKIP,作为历史结果保留 | `/var/tmp/scf20/final-results/` | | 公网搜索修复后的 Linux 回归 | list 9 个 PASS 标记、IMAP 40 个 PASS 标记,两包退出码 0、无失败或跳过 | `/var/tmp/smail-public-fix20/list.log`、`imap.log` | | 最新前端 | 210 项通过,0 失败、0 跳过;含邮件详情与插件密钥回归 | 本地 `test-log/plugin-secret-fix-20260920/frontend-latest.log` | | 插件密钥修复的 Linux 回归 | controllers、services/plugin、http_server 三包成功,361 PASS、0 FAIL、1 SKIP;源码 `54396ab` | 云端 `/var/tmp/spi20/results/`;本地 `test-log/plugin-secret-fix-20260920/cloud-verified/` | | Windows 构建互斥与测试入口 | 4 项通过;Linux 专用项在 Windows 跳过 | 本地 `test-log/run-2026-09-19T16-13-15-667Z-3920/deployment.log` | | Linux 资源策略 | 15 项通过 | 云端 `resource-policy.log` | | 实际服务资源只读预检 | 通过,无失败项;不替代业务验收 | 云端 `final-resource-check.json` | | 邮箱重新绑定修复的本地受影响包 | externalemail、controllers、recovery、verification 均通过 | 本地 `test-log/run-2026-09-19T19-10-20-850Z-26796/backend.log` | | 邮箱重新绑定修复的 Linux 复测 | externalemail、controllers 均 EXIT=0 | 云端 `rebind/externalemail.log`、`rebind/controllers.log` | | 续期及配置校验最终本地回归 | config、ssl、controllers、cron_server 通过;smail-config 编译通过,无测试文件 | 本地 `test-log/run-2026-09-19T21-23-32-547Z-34536/backend.log` | | 最终 Linux 配置包 | 非特权 nobody 用户执行,413 个 PASS 标记、0 FAIL、0 SKIP,退出码 0 | `/var/tmp/smail-tls-20260920/runtime/config-cwd-full.log` | | 最终 Linux 证书包 | 非特权 nobody 用户执行,50 个 PASS 标记、0 FAIL、4 SKIP,退出码 0 | 同目录 `ssl-cwd-full.log` | 历史 1955 PASS 的全量运行时间为 03:58:42—04:05:54,systemd 记录耗时约 7 分 12 秒、内存峰值 256.5 MiB,结果为成功。66 个包来自同一源码快照,顺序执行,没有合并旧结果或以旧成功替换失败。PASS 标记包含父测试和子测试,不能表述为同等数量的独立案例;主包只有显式跳过的旧集成入口,退出成功不代表该入口已执行。最新 1971 PASS 的独立全量及版本边界见末尾补充记录。 该次全量的测试源码快照为 `418435cb94f62a11e0f5de7fbd913a20f05f7c24`,与当时部署源码 `310ad01` 的后端、前端、对应测试、部署及插件目录无差异。实际测试子进程使用 `nobody`(UID/GID 65534),每包使用独立临时运行目录,没有指向 Smail 运行数据库。真实 MySQL、PostgreSQL 及跨库迁移集成用例全部执行通过。04:45 后新增续期实现及修复的验证范围为上表中的受影响包,最终部署源码为 `6920bff`。 已将云端原始证据下载到本地,核对 66 个包的集合无遗漏或重复、退出码全部为 0、每个测试程序 SHA-256 与本地构建收据一致、逐包日志计数与汇总一致。源码归档摘要也与构建收据一致。 - 构建收据:`test-log/cloud-final-20260920/build-receipt.json`。 - 源码归档 SHA-256:`8b5475f0dc2e3036c819bcdf70b2fa44d3ab3e99246d7cc1c444d51a00da8c8d`。 - 证据归档:`test-log/cloud-final-20260920/final-evidence.tar.gz`。 - 证据归档 SHA-256:`3675c8f5a61a9af5373d0a6dfe3b952e53a068259a321d41cda2d49f9ccf3fe5`。 此前 `latest-summary.json`、`latest-packages.json` 的 1953 个 PASS 是首轮全量与受影响包复测合并的历史统计,仍保留用于追溯。1955 和最新 1971 个 PASS 分别来自两次独立全量,不累加统计。 五个后端跳过项: 1. `TestProductionPluginIsolationPolicy`:Windows 专用。 2. `TestSecuritySetupBrowserFixture`:需要显式启用的长期浏览器夹具。 3. `TestSystemdResultPrompt`:需要隔离的 systemd 人工交互。 4. `TestSystemdCancelledInputResult`:同上。 5. `TestMaster`:旧集成入口,需显式启用,不能直接指向运行库。 本轮另行完成真实 smail-admin 启动、安全验证、成功提示及 stop 取消操作;自动化跳过项仍按跳过记录。Windows 未提权环境未完成 Named Pipe 验收,不列为通过。 ## 云端业务验证 ### 账号与登录 - `xuans` 为超级管理员,`testadmin` 为管理员,`testuser` 为普通用户。最终均保留用户指定密码;本文不记录密码、验证码、恢复令牌或 TOTP 密钥。 - 未配置安全验证的超级管理员登录后,页面强制要求至少启用一种方式。最终浏览器重新加载后可见该中文弹窗,没有跳过保护。 - 普通用户点击“我知道了”后可继续,注销并重新登录会再次提醒未完成的安全设置。 - 三类账号均具备用户可选的 TOTP 功能。普通用户实测绑定、登录和停用;密码阶段约 473 毫秒、TOTP 验证约 83 毫秒。其他两类账号本轮早期测试完成后也已停用测试 TOTP。 - 登录密码正确后,有主要外部邮箱的账号返回验证选择,`delivery_status=idle`,没有自动发邮件;只有主动发送才进入 `sending`。 ### 邮件验证码与公开密码恢复 使用普通测试用户的真实站内收件箱临时验证管理员,邮件经项目正常投递与邮件 API 读取,没有改数据库伪造验证结果。此闭环证明应用链路,不替代 163 外部收件验收。 | 步骤 | 最后一次实测耗时 | 结果 | | --- | ---: | --- | | 停用邮箱重新绑定为主要邮箱 | 3190 毫秒 | 成功,仍须邮件验证 | | 确认重新绑定 | 84 毫秒 | 成功 | | 管理员密码阶段 | 341 毫秒 | 返回 email 选择,邮件 idle | | 主动发送登录验证码 | 71 毫秒 | 返回 sending,后台完成真实投递 | | 邮件码完成登录 | 103 毫秒 | 成功 | | 立即发起公开恢复 | 143 毫秒 | 识别管理员及 email 方式 | | 紧接着发送恢复邮件 | 2628 毫秒 | 成功,没有被登录验证码冷却阻塞 | | 邮件码验证恢复身份 | 74 毫秒 | 发放一次性重置凭证 | | 设置密码 | 307 毫秒 | 重置成功 | | 重置后密码登录 | 365 毫秒 | 成功进入验证选择 | | 再次主动发送登录码 | 89 毫秒 | 成功 | 以上为当次单请求观测,不是负载压测或全网延迟保证。公开恢复请求未携带登录 Cookie 或 CSRF 头。测试完成后通过正式接口停用临时邮箱;管理员再次直接登录约 430 毫秒,超级管理员约 307 毫秒。 ### 邮件协议与重置撤销 - 服务器本机经域名校验的 TLS 完成 SMTP 投递、IMAP 查询读取和 POP3 收取,数据库收件归属核对正常。证据:`protocol-acceptance.json`。 - 真实密码重置后,旧客户端授权码在 SMTP、IMAP、POP3 均被拒绝。证据:`revoke/live-revocation.json`。 - 未认证、输入 USER 后及错误密码后的 POP3 QUIT 均立即回应并关闭连接;相关包回归通过。证据:`revoke/live-pop3-quit.json`。 - 超级管理员登录页恢复通道保持拒绝;本机重置使用受保护 Unix Domain Socket。最终 `/run/smail/admin-control.sock` 权限为 `0600`,所属用户/组为 `smail`,未增加公网重置 TCP 监听。 - smail-admin 仅显式 start 进入交互,stop 取消;restart、reload 及变体不能开启新的重置交互。systemd 的 restart 仍可能先停止原交互,这一系统行为边界详见《管理员重置命令限制验收》。 ## 证书与网络限制 真实证书签发者为 Let's Encrypt YR1,SAN 为 `solit.cn` 和 `*.solit.cn`,有效期从 2026-09-19 16:44:26 UTC 至 2026-12-18 16:44:25 UTC。服务器通过回环和公网地址连接 443、465、993、995,使用实际域名 SNI、系统 CA 进行校验,均通过 TLS 1.3。浏览器 HTTPS 页面可访问。 早期本机系统 DNS 将三个邮件子域名解析到 `198.18.2.x`;本机 Python 不论域名连接还是强制公网 IP,连 443 也发生 TLS EOF。该失败保留,不据此归因为云端证书错误。05:59 后 Node 使用默认信任链成功连接,06:21 完成真实公网收发,更新了此前“公网路径未通过”的结论。本机 DNS 仍返回现有网络路径地址,没有修改网络设置,也没有声称定位或修复了 Python TLS EOF 的原因。 Google 公共 DNS 已查到 DKIM;对 1.1.1.1 的 UDP 查询超时,未计为通过。本轮 ACME TXT 清理仅针对新建的两个记录 ID,核对剩余为零,既有记录保留。 ### 03:32—03:44 补充实测 以下为接续时重新采集的实时证据,不依赖测试参数或历史快照判定通过。云端证据位于 `/var/tmp/smail-cloud-tests-20260920/`;本地副本位于忽略目录 `test-log/cloud-audit-20260920/`。 | 核验项 | 结果 | 证据 | | --- | --- | --- | | DNS 控制面 | 阿里云当前返回 16 条记录,`* A 47.108.78.12` 已启用 | 本地 `test-log/cloud-dns-current-20260920.json` | | 权威及公共解析 | `dns13.hichina.com`、`dns14.hichina.com`、`8.8.8.8` 共 33 次查询均返回 NOERROR;随机一级子域名、Web 和邮件服务地址均指向服务器 | `live-dns-audit.json` | | 邮件记录保留 | MX、SPF、DKIM、DMARC 均可查到;与清理前快照相比,没有删除原有记录,只新增泛解析并更新 Smail 的 `default._domainkey` 公钥 | 同上及本地清理前快照 | | DKIM 密钥匹配 | 三个 DNS 查询源中的公钥均与 `/opt/smail/ssl/dkim/dkim.priv` 推导出的公钥一致;只比较公开材料,不输出私钥 | `live-dkim-match.json` | | 运行域名 | 邮件主域名为 `solit.cn`,后台为 `web.solit.cn`,公开 HTTPS 端口为 443;域名来自部署配置 | `live-domain-configuration.json` | | 统一证书 | 回环 443、8002、465、993、995,以及服务器经公网 IP 访问 443、465、993、995,全部通过系统信任链校验且指纹一致;443、8002 额外使用根域名 SNI 校验通过 | `live-certificate-unification.json` | | STARTTLS 证书 | 回环 SMTP 25/587、POP3 110 升级为 TLS 1.3,证书指纹与上述入口一致 | `live-starttls-certificates.json` | | 浏览器状态 | 实际 HTTPS 页面为安全上下文,`/api/ping` 两次返回 200,约 314 和 164 毫秒,超级管理员强制安全设置弹窗可见 | 本地 `live-browser-check.json` 保存最后一次结果 | 统一证书 DER SHA-256:`f369937771b4b3bd4fc1ea624a8eed30e1451c8bcefdcd1c9c15043a33113018`。 DKIM 公钥 DER SHA-256:`df9958f7e8c20c7d7f8735bb062f7bd7485bbee3bbd254930d7ae8d68ae6731c`。 上述 TLS 连接共 14 次,其中服务器经公网 IP 访问内部 8002 的两次连接超时,不列为通过;回环 8002 校验通过,公开后台仍从 443 访问。本轮没有开放内部端口。IMAP 当前使用 993 隐式 TLS,源码和现行默认端口策略一致;143 未启用,连接被拒绝,没有将其计为 STARTTLS 通过。 本机系统 DNS 此次将 Web 解析到 `198.18.1.254`,邮件地址仍解析到 `198.18.2.x`。本机 curl 和经本地 HTTP 代理的 Python TLS 连接仍在握手阶段失败;浏览器 HTTPS 正常。没有因此修改系统 DNS、代理或防火墙,也没有将服务器自身访问公网 IP 等同于外部客户端验收。 另发现既有 `aliyun-cn-hangzhou._domainkey` 同名 TXT 有两条,其中一条公钥明显截断。该记录属于既有阿里云邮件链路,本轮未删除或修改;Smail 的 `default` 选择器公钥匹配已单独通过。保留 DNS 记录不代表既有阿里云邮件链路也已验收。 ### 仍未通过的项目 项目托管启用内置续期检查,手动及代理托管不触发 ACME,策略测试通过。04:45 后已补齐 AliDNS 自动管理 TXT 及 Nginx 自动同步,实测结果如下。尚未验证自然到期后的长期调度。服务器不依赖外部部署或续期脚本,没有新增外部 ACME 定时器。 截至本节早期检查,指定的三个 163 地址尚未发送测试邮件。07:19—07:23 已通过正式绑定流程分别发送一次验证码,详见末节;最终收件和绑定仍须由各邮箱持有人完成。 ## 04:45—05:40 内置续期与换证补充验收 ### 实际 DNS 挑战与记录保留 通过正式配置接口、超级管理员重新认证及临时 TOTP,保存 `management=project`、`challenge=dns`、`dnsProvider=alidns`、`dnsZone=solit.cn`。两项凭据加密保存在配置中,公开接口不回填密文或明文。测试后已通过正式接口停用临时 TOTP。 第一次 staging 签发后的清理失败,原因是受限凭据无权调用 `DescribeDomainRecordInfo`,返回 `Forbidden.RAM`。该轮明确计为失败,原始日志保留;核对并清理该轮两个记录 ID 后,改用已获授权的 `DescribeDomainRecords` 分页精确查询,无须扩大云账号权限。 修复后第二次 staging 实测 33.39 秒完成 `solit.cn` 和 `*.solit.cn` 的新挑战、签发及清理。staging 证书只保留在测试内存,没有安装至线上。修复前后的四次最终库存均与原始 16 条记录逐条一致,既有记录全部保留,本轮新增挑战没有残留。原本已有的一条 `_acme-challenge` TXT 同样保留,不将“本轮无残留”描述为所有挑战 TXT 数量为零。 ### 生产续期与 Nginx 自动同步 显式云端测试调用项目生产入口 `GenSSL(true)`,3.90 秒成功保存新证书,配置代次 3→4。生产 CA 复用了有效授权并跳过 DNS 挑战,不能声称该轮重新验证 TXT;真实新挑战由前述 staging 独立证明。为避免两个配置管理器并发,此次测试入口执行前短暂停止 Smail,完成后自动恢复,因此不作为邮件连接连续性或自然到期调度证明。 配置更新自动触发 `smail-tls-sync.path`;该原生 systemd 单元调用程序本体 `smail-config --export-project-tls`,原子更新 `/etc/nginx/smail/tls.pem`,再执行 `nginx -t` 和平滑 reload。没有 Python 或 shell 续期程序。Nginx 主 PID 始终为 `578671`,未停止或重启;本轮没有验证重载期间其他站点的长期连接连续性。 同步程序只接受项目受控平铺证书,拒绝符号链接、硬链接及不安全权限;相同内容不重复写入,失败保留原文件。同步服务的只读沙箱仅放行 `/etc/nginx/smail`、Nginx 日志及 `/run/nginx.pid`。之前只读目录 chmod 和 Nginx PID 文件访问失败均已修复并实机复测,日志保留失败与成功过程。 当前证书覆盖 `solit.cn`、`*.solit.cn`,到期时间 `2026-12-18T20:12:03Z`;DER SHA-256 为 `117d6f2b5b147ea7b98f84d44b22cd1580ffd489eddfdb680d8372f60bc6f2ba`。项目新旧两套证书均保留,Nginx 合并文件为 `0600 root:root`。Nginx 仍使用 HTTPS 8002 上游、`web.solit.cn` SNI 和系统 CA 校验。 ### 续期后配置加载问题 库存复查发现 `config.Init()` 报 `invalid SSL configuration`。在相同配置下,旧测试程序从 `/opt/smail`、`/tmp` 成功,从 `/root` 切换为 `smail` 用户后失败。原因是上一张证书引用的格式校验调用当前目录绝对路径解析,受到无权访问的工作目录影响,凭据和证书本身未损坏。 新增非特权 Linux 回归先证明旧代码失败,再改为纯引用格式检查,保留平铺名称、成对 token、路径边界及实际文件校验。修复后受限目录场景、路径逃逸/错配拒绝、配置及证书全包回归均通过;相同线上配置从 `/root` 以 `smail` 身份读取库存也成功。原始失败日志 `dns-final.log` 与 `runtime/cwd-before.log` 均保留。 ### 浏览器与证据归档 05:31 实际桌面浏览器检查 SSL 配置页:项目托管、DNS 验证、阿里云自动续期、托管域名正确显示。两项凭据输入框为空并显示“已设置”,公开接口没有密钥内容。视口 1277×613,无横向溢出、无 HTTP 4xx/5xx 资源;配置读取 67 毫秒。检查后停用临时 TOTP,05:32 确认强制安全设置提示恢复,`/api/ping` 200、155 毫秒。这是单次观测,不代表负载测试。 05:39 使用当前正式浏览器会话注销后,以用户指定的 `xuans` 账号密码重新登录:注销 162 毫秒、登录 465 毫秒,HTTP 200、业务错误码 0;认证成功后仍要求至少启用一种安全验证。测试开始时在未注销的强制设置会话内直接调用登录接口,被安全设置中间件拒绝,不能把该拒绝误判为密码错误;随后按完整注销、登录流程验证通过。没有修改账号密码。 云端原始证据:`/var/tmp/smail-tls-20260920/live/` 和 `runtime/`。本地归档:`test-log/tls-acceptance/evidence.tar.gz`,SHA-256 `4990b3502df57fe7af33593ed4c532c39cda208e30e7bce35e2026b493d3c6a2`,与云端一致。归档已下载,逐项核对 DNS 集合、失败/成功标记、数据库状态及程序摘要;核对结果为 `verified-evidence.json`,浏览器结果为 `browser-ssl-evidence.json`。 该次证书包的四项 SKIP 是需显式启用的真实云端入口;staging、生产续期及库存已在独立日志中执行,不因全包运行时跳过而冒充该次全包已执行真实签发。自然到期长期调度、指定外部邮箱的边界保留;外部邮件客户端在后续 06:21 记录中通过。 ## 最新交付与运行状态 最新部署源码:`ff13d39bd5b72dc295b3ac87b8b68ae83eff30c2`。运行版本:`test-ed82dfd9e632`。06:59:54 完成邮件详情前端修复的云端安装。此前 `eb5063a`、`test-59ee0bb94881` 为 06:19:47 的 IMAP 搜索修复版本;`6920bff`、`test-222651378aff` 为续期修复部署版本。 发布包:`out/release/Smail_linux_amd64.tar.gz`。文件结构: ```text smail/ ├── smail ├── smail-admin ├── smail-config ├── config/ ├── data/ ├── log/ └── ssl/ ``` | 文件 | SHA-256 | | --- | --- | | 发布包 | `28d9a90eb54b3d733ec3eb8f101f00f36d321ebc379266e43bb0d58447a0bf4c` | | smail | `4f6cdb0390007dadda12c13844b39f21a4d07e9d5d7c5d0d5f612978fc84c038` | | smail-admin | `ef25801c19b32c801919667f82a9074bc9578358a9a47e916ac88c87635aee53` | | smail-config | `c22df08b3ab97badd3a1818ee7a896564ecaf9b2961201a89b81e9c4427d25da` | 本地构建收据:`out/release-receipts/Smail_linux_amd64.json`。三个云端文件均与收据一致。前端和内置插件构建完成;编辑器分块大于 500 KB 的既有构建提示仍存在,没有构建失败。 05:27:58 的续期修复安装后,05:32 复核 Smail PID 为 `719778`,自动重启次数为 0,Nginx PID `578671`、active。回环 443(Web 和主域名 SNI)、8002、465、993、995 六次连接均通过系统信任链与主机名校验,使用 TLS 1.3,证书指纹一致。两个数据库 `integrity_check` 均为 `ok`;启用的 TOTP 数量为 0,未停用的外部邮箱绑定数量为 0。该次启动后的 systemd warning 级日志查询无记录。本机恢复 socket 保持 `0600 smail:smail`。06:19 的更新部署及其最终复核见末节。 最新部署前备份:`/var/backups/smail-full-test-20260920/pre-detail-fix/`,含三个旧程序及停服时的配置、数据、证书归档。同级 `pre-public-search/`、`pre-cwd-fix/`、`pre-auto-dns/`、`pre-renewal/`、`pre-rebind/` 保留前序状态。测试日志和测试二进制保留在各轮 `/var/tmp/` 测试目录,不属于运行依赖;没有擅自删除验收证据。FDM、Scert、MySQL 和 PostgreSQL 未因最后一次 Smail 更新而停启;Nginx 在真实换证时平滑重载,最终程序更新没有再次重载。 公网恢复入口已通过正式配置流程设置 `http.publicHttpsPort=443`;`/public-password-recovery` 跳转到 `https://web.solit.cn/rest/`,不再暴露内部 8002 端口,恢复页面返回 200。 ## 05:51 最终只读复核 本次接续复核没有再次清库、重启服务或签发证书。最初清理前的旧运行目录仍保存在 `/var/backups/smail-full-test-20260920/smail/smail/`,包含原配置、数据、日志、插件和证书。当前测试库复用本轮初始化结果。 - [✓] 当前配置为 `ready`,代次为 4;邮件主域名 `solit.cn`、后台 `web.solit.cn`、公开 HTTPS 端口 443。SSL 为项目托管、DNS 挑战、内置 AliDNS,凭据仍为加密存储。 - [✓] 三个运行程序的摘要与最新构建收据逐项一致;两库完整性检查均为 `ok`。账号 `xuans`、`testadmin`、`testuser` 的角色及启用状态正确。 - [✓] DNS 控制面当前 16 条记录与续期前库存逐条一致。两个权威 DNS 和 Google 公共 DNS 的 33 次查询全部成功;新随机一级子域名及 Web、邮件地址均指向服务器,MX、SPF、DKIM、DMARC 可正常查询。 - [✓] 三个 DNS 查询源中的 Smail DKIM 公钥均与运行私钥推导出的公钥一致,只输出公钥摘要。 - [✓] 通过系统 CA 和实际域名校验的 9 次回环连接全部使用 TLS 1.3、同一证书指纹及根域名与泛域名 SAN:443 的 Web 和根域名、8002、465、993、995,以及 SMTP 25/587 STARTTLS、POP3 110 STLS。证书指纹为 `117d6f2b5b147ea7b98f84d44b22cd1580ffd489eddfdb680d8372f60bc6f2ba`,到期时间为 `2026-12-18T20:12:03Z`。 - [✓] Smail、Nginx 及证书同步监听正常,Smail 自动重启次数为 0,最后启动后的 warning 级日志无记录。本机恢复 socket 为 `0600 smail:smail`。 - [✓] 实际浏览器仍为 `https://web.solit.cn/#/` 安全上下文,`/api/ping` 返回 HTTP 200、业务错误码 0、耗时 150 毫秒;超级管理员强制安全设置提示可见,无横向溢出。 - [✓] 发布压缩包重新列出目录,只有三个程序和四个运行目录,没有部署或续期脚本。 原始复核结果保存在本地 `test-log/tls-acceptance/final-audit.json`;辅助程序仅经 SSH 在内存中执行只读核验,不是服务器部署或运行依赖。浏览器复核时间为 `2026-09-20T05:51:46+08:00`。本节没有扩大先前的通过范围:三个外部邮箱的真实收件与绑定、外部邮件客户端网络路径、自然到期长期调度、Windows 提权 IPC 和外部插件业务仍需另行验收。 ## 06:02—06:25 最新全量与公网邮件闭环 ### 独立云端全量 源码 `88649c8d130d5dbc0325904285c208581da4d316` 的 66 个 Linux amd64 测试程序,在服务器 `/var/tmp/scl20` 独立执行,06:12:26 完成。systemd 记录墙钟耗时 6 分 10.700 秒、CPU 时间 3 分 1.976 秒、内存峰值 384 MiB,退出成功。所有测试子进程使用非特权 UID/GID 65534,每包独立临时目录;沙箱禁止访问运行目录、恢复 socket 目录和原始备份。MySQL/PostgreSQL 使用专用测试凭据,没有清空运行库。 结果为 66 包退出成功、1971 个 PASS 标记、0 FAIL、5 SKIP。前述五个跳过项不变。已逐包核对清单、二进制摘要、源码归档摘要、退出码及日志计数;真实 MySQL、PostgreSQL、两者间迁移及日志数据库集成均有实际 PASS 记录。 本地 `test-log/cloud-latest-20260920/verified.json` 保存复核结果;证据归档 `evidence.tar.gz` 的 SHA-256 为 `3118e86306a7a3212c02f332459a8a66fe63ca32f1dea9cb237e8e5520652c0c`。本次全量含之前续期及配置修复。后续 `eb5063a` 只修改 IMAP 搜索及其测试,完成两个受影响包回归,不表述为该提交又重跑 66 包。 ### 公网路径与修复 05:59 本机 Node TLS 客户端对 Web 443、SMTP 465、IMAP 993、POP3 995 分别使用域名和公网 IP 加正确 SNI 连接,共 8 次成功,均启用默认信任链和域名校验,TLS 1.3,证书指纹与线上一致。证据:`test-log/public-tls-latest.json`。系统 DNS 仍为现有网络路径,未修改 DNS、代理或防火墙。 06:09 首次真实 SMTP 发送成功,但 IMAP 按 Message-ID 查询为空。只读数据库确认邮件已入收件箱,排除只入队未投递。源码 `matchesHeader` 缺少 `message-id` 分支;新增回归在旧代码失败,补齐分支后通过,覆盖完整值、大小写、子串、旧邮件备用标识和跨用户隔离。云端 list 包 9 个 PASS 标记、IMAP 包 40 个 PASS 标记,均无失败和跳过。 修复构建于 06:19:47 部署。测试客户端曾因缺少 Origin 头被同源保护拒绝,补齐后正常;首次正文校验未解码 MIME Base64 也曾失败,修正客户端解码后通过。这两项属于测试客户端问题,未削弱服务端保护或更改邮件内容。失败证据保留。 06:21:34—06:21:41,从 Windows 本机通过公网域名完成新邮件闭环,账号为本轮普通测试用户,邮件只投递到其自有站内邮箱: | 步骤 | 耗时 | 结果 | | --- | ---: | --- | | 正式 API 密码登录 | 463 毫秒 | 成功 | | 临时开启协议并创建客户端授权 | 640 毫秒 | 成功 | | SMTP 465 认证及发信 | 3602 毫秒 | 认证成功,DATA 接受 | | IMAP 993 查询及读取 | 616 毫秒 | Message-ID 匹配,解码正文匹配 | | POP3 995 读取 | 840 毫秒 | 同一 Message-ID、正文匹配 | | 撤销后重试 SMTP 认证 | 538 毫秒 | 返回 535,旧授权不可用 | 三个邮件入口均使用 TLS 1.3、默认 CA 和域名验证,证书 DER SHA-256 为 `117d6f2b5b147ea7b98f84d44b22cd1580ffd489eddfdb680d8372f60bc6f2ba`。最终邮件 Message-ID:``。数据库同时存在发件成功记录和收件箱记录;没有删除测试邮件。 闭环证据:`test-log/public-mail-bdc12c69-9fc2-4d36-a1cf-2b1cb3eb34e0.json`。云端回归与安装证据本地副本:`test-log/public-mail-fix-build/evidence.tar.gz`,SHA-256 `bf2bb8e5be83a984ea12b671db300b3d67bdbdd80020a9a1ab6c757987b8822b`。临时授权只在内存使用,已撤销;测试协议开关全部恢复,测试会话已注销。本次是自有域内邮箱的公网客户端收发,不能替代 163 等外部邮件运营商的投递验收。 ### 最新运行及浏览器复核 06:23:58 只读复核:Smail PID `723515`、active、自动重启 0,Nginx PID 仍为 `578671`,证书同步监听 active;三个程序摘要与收据完全一致,两库完整性均为 `ok`,有效客户端授权数量为 0,普通测试用户三个协议开关均关闭。本机恢复 socket 为 `0600 smail:smail`,本次启动后的 warning 日志无记录。六次回环证书验证全部通过。证据:`test-log/public-mail-fix-build/runtime-audit.json`。 06:22:51 实际浏览器页面 HTTPS 安全上下文正常,ping 200、301 毫秒,强制安全设置提示可见,无横向溢出。06:24:59 在同一正式浏览器会话中注销后,用用户指定的超级管理员账号密码重新登录:注销 146 毫秒,登录 317 毫秒,HTTP 200、业务错误码 0、角色 `super_admin`。未修改账号密码。06:29:45 清理该页 Cache Storage 并重新加载后,ping 200、290 毫秒,强制提示仍可见,无横向溢出,浏览器可见资源状态没有 4xx/5xx。 仍需另行完成:三个指定 163 邮箱真实收件及绑定、自然进入证书续期窗口后的长期调度、Windows 提权 Named Pipe、依赖外部服务的插件业务。本轮没有把这些项目标记为通过。 ## 06:31—07:06 浏览器网页收发与详情修复 本次沿用同一轮已经清理和初始化的云端数据库,没有重复清库。实际桌面浏览器始终复用独立上下文内的 Smail 页面,测试前检查云端服务;部署后清理该页 Cache Storage 并重新加载,实际加载了新版 `EmailDetail-ecbfb4cc.js` 和对应样式。 ### 写信、投递与附件 普通测试账号 `testuser` 在真实写信页面向自己的 `testuser@solit.cn` 发送中文邮件,主题为“云端网页收发验收 20260920-0638”,正文标识 `web-mail-20260920-0638`。发送请求 HTTP 200、85 毫秒,页面先显示“邮件已提交,正在投递”,发件箱刷新后显示“发送成功”。发件 ID 14、收件 ID 15,共用 Message-ID `6994a5f544999fbf9711ac26d88e637b.1789857759152323508@solit.cn`,数据库归属均为 `testuser`;发送创建于 06:42:39,收件创建于 06:42:43。唯一投递队列项为 `accepted`、尝试 1 次、无错误,不能仅用发送 API 的 200 代替投递成功。 中文正文及附件名称在发件、收件详情均正常显示。附件 `中文附件.txt` 为 139 字节,SHA-256 为 `0d94d22e10ea07cb478932fec4e8ec701646574911a08c1f637c2ccab2a372ff`;本地原件、两份数据库附件及下载内容一致。首次发件、收件下载分别为 66 和 67 毫秒,均 HTTP 200;部署后 07:02 再次下载仍匹配,响应头保留 UTF-8 中文文件名。测试邮件保留,没有删除。 工具边界:MCP 上传工具拒绝项目目录路径,未能操作系统文件选择器。随后在页面创建相同内容的 `File`,通过现有文件输入框的 `change` 事件进入产品 FileReader 和发送流程。因此附件处理、投递和下载已经验证,系统文件选择器仍未验证。编辑器初次 `fill` 没有正确更新内容,刷新后用键盘输入并确认正文再发送,没有把辅助工具错误视为产品缺陷。 ### 账号隔离与错误页 正式注销普通用户后登录 `testadmin`。对 ID 14、15 的邮件详情均返回 HTTP 200、业务码 500、“读取邮件失败”;对应附件均返回 HTTP 200、业务码 100、“附件不可用”。四个响应数据为空,没有邮件正文或附件内容,跨账号隔离通过。补采证据首次遗漏 CSRF 头,被来源校验拒绝;补齐后得到上述业务拒绝结果,前者没有作为隔离验收依据。 此时页面仍显示 `?`、`<>`、空收件人模板。原因是详情逻辑没有检查业务错误码,也没有加载和错误视图。`ff13d39` 补齐中文状态、重试及明确返回邮件列表,错误状态不显示邮件元数据和删除按钮;切换路由立即清空旧内容,旧请求完成或失败不会覆盖新邮件,离开页面后也不会继续更新状态。后台权限逻辑没有修改。 前端新增六项回归覆盖业务拒绝后重试成功、网络失败、无效编号及异常响应、异常地址与附件字段、切换路由后的迟到响应、离开页面的未完成请求。全量前端为 206 项通过、0 失败、0 跳过。本次没有后端源码改动,后端全量与 IMAP 回归范围仍以前述记录为准。 06:59:54 部署后实际浏览器验证:管理员看到“邮件暂时无法查看/读取邮件失败”;点击重试仍正确拒绝,点击返回进入 `#/list`。普通用户从收件箱打开 ID 15,可见完整中文正文和附件,下载摘要匹配。随后同一详情组件切到 ID 14,附件地址同步变为 `/attachments/download/14/0`;切到不存在的 ID 999999999,显示失败且旧正文和删除按钮消失;再回 ID 15,正文正常恢复。没有横向溢出,控制台无 error 或 warning。云端页面验证的是实际业务拒绝和正常恢复;网络异常由自动化回归覆盖,没有人为中断线上服务。 ### 最终运行与证据 07:05:01 只读核对:两个 SQLite 数据库完整性均为 `ok`;Smail PID `725122`、active、自动重启 0;Nginx PID `578671`、active;证书同步监听 active。三个程序 SHA-256 与最新发布收据完全一致,本机恢复 socket 仍为 `0600 smail:smail`,此次启动后的 warning 级日志无记录。 普通测试用户正式注销后,通过页面使用用户指定密码恢复 `xuans` 登录,登录请求耗时 358 毫秒;正式用户信息接口业务码 0、角色 `super_admin`。07:05:51 确认可见“请至少启用一种安全验证后继续”强制弹窗。页面 ping 147 毫秒、业务码 0,没有可见 HTTP 4xx/5xx 资源。这些时延仅为本次观测,不是负载保证。 本地证据目录:`test-log/web-mail-20260920/`,含 `browser-evidence.json`、`isolation-before.json`、`detail-after.json`、部署收据 `install-result.json`、构建日志 `build.log`、更新前后的 `server-before-detail-fix.json` 与 `server-evidence.json`。临时 SSH 辅助文件仅用于本次测试,不进入发布包,也未安装为服务依赖。首次辅助断言误将队列状态写为 `delivered`,核对产品实现后改为真实的 `accepted` 并复核,没有改动产品投递状态。 - [✓] 网页写信、投递状态、收发详情及中文附件校验。 - [✓] 跨账号邮件和附件隔离、详情失败展示、重试和返回列表。 - [✓] 最新前端回归、Linux 打包、备份部署、程序摘要与数据库核对。 - [✓] 恢复超级管理员登录及强制安全设置提示。 - [!] 三个外部邮箱真实收件和绑定、证书自然续期长期调度、Windows 提权 IPC、外部插件业务、系统文件选择器仍未纳入通过范围。 ## 07:12—07:24 外部邮箱实际投递 本次接续沿用现有云端环境,未清库、重启、修改程序或网络规则。账号密码保持用户指定值,没有把验证码、邮件正文或会话凭据写入报告及证据。测试辅助操作没有进入发布包。 ### 网络诊断与实际结果 当前 SMTP 中继的主机、账号和密码均未配置,验证码使用项目自身投递。首次配置探测将非空密码结构误判为已配置,随后按密文字段重新核对,实际未配置;保留两次原始证据,结论以字段核对为准。 163 的四个 MX 名称均解析成功,本次解析指向 `111.124.203.43`、`111.124.203.50`。四个主机的 25 端口探测以及两个 IP 的直接 25 端口探测均超时。QQ MX 的 25 端口也未连通;服务器 UFW 默认允许出站,当前 IPv4 filter OUTPUT 链未见拒绝规则。尚未定位限制发生的网络环节,不能仅据此断言云平台封禁。 `smtp.163.com` 的 465、587 端口连接成功。进一步探测 `163mx01.mxmail.netease.com` 和 `163mx03.mxmail.netease.com` 的 465 端口,默认 CA 与主机名校验通过,均使用 TLS 1.3,EHLO 返回 250。以上探测没有发送 DATA 邮件。现有投递实现支持 MX 的 25、465、587 备用路径,因此 25 端口超时不等于整条外发链路不可用;下述正式业务请求实际投递成功。 ### 三类账号验证码发送 | 账号 | 指定邮箱 | 操作与耗时 | 云端结果 | | --- | --- | --- | --- | | `xuans` | `likb_blue@163.com` | 真实浏览器点击发送,最近认证要求先确认密码;重新认证 383 毫秒,之后绑定请求 3233 毫秒 | 验证事件 success,投递 accepted,绑定 ID 2 为 pending | | `testadmin` | `xuanspark@163.com` | 公网正式 API 登录 437 毫秒,绑定发送 2299 毫秒 | 验证事件 success,投递 accepted,绑定 ID 3 为 pending | | `testuser` | `gfxezc@163.com` | 等冷却后重新登录 583 毫秒,绑定发送 2308 毫秒 | 验证事件 success,投递 accepted,绑定 ID 5 为 pending | 三个成功绑定请求均 HTTP 200、业务码 0,并返回真实绑定和挑战信息。服务器分别在 07:19:12、07:21:43、07:22:59 记录系统安全验证邮件 accepted、acceptedCount 为 1,验证事件均为 issue/success。日志只记录发送元数据;accepted 表示对端服务器接收,不代表邮件已进入收件箱,更不代表持有人完成验证。 普通用户第一次在管理员发送后立即提交,99 毫秒返回业务码 100、“验证码发送过于频繁,请稍后再试”,对应事件为 blocked。源码确认同一来源的发送冷却为一分钟;等待超过一分钟后正式重试成功,没有清理限流状态或调整规则。失败请求创建的待验证记录由产品自身回滚,因此最终普通用户绑定 ID 为 5。这次是尚未使用验证码时的正常发送冷却,不是已完成业务后冷却没有释放;验证码消费后的跨场景释放已在前期闭环中验证。 管理员和普通用户的辅助 API 会话均已正式注销。超管浏览器保留在邮箱验证码输入步骤,显示脱敏地址及倒计时;07:23:31 页面 ping 为 139 毫秒、HTTP 200,无横向溢出。上述均为当次请求观测,不是负载测试或所有投递路径均小于五秒的保证。外部绑定仍同步等待投递,本次没有复现 504,也没有修改同步流程。 ### 待人工收件与运行复核 三个指定邮箱均为 primary、pending,verified_at 为空。没有读取外部收件箱,没有伪造验证码或直接修改验证状态,超管的安全验证要求仍有效。下一步由邮箱持有人查看收件箱及垃圾邮件,通过正式页面输入验证码;过期后重新发送即可。管理员、普通用户需要重新进入各自账号的绑定窗口,使用原指定地址申请新验证码。 07:24:28 复核:Smail PID `725122`、Nginx PID `578671` 均 active,Smail 自动重启次数仍为 0,证书同步监听 active。两个数据库完整性均为 ok,三个程序摘要与发布收据一致,三类账号启用状态正确。本机恢复 socket 保持 `0600 smail:smail`。此次只有测试报告更新,没有新产品修改,也不重复宣称重新执行全量构建和回归。 本地证据目录为 `test-log/external-mail-20260920/`:`configuration-network-before.json`、`network-probes.json`、`network-differential.json`、`superadmin-delivery.json`、`other-accounts-delivery.json`、`testuser-delivery-retry.json`、`delivery-metadata-before-retry.json`、`final-server-evidence.json`、`browser-evidence.json`。早期邮件日志查询按字符串 ID 排序未取到最新记录,最终证据按 created_at 排序核对三条新投递,不以早期查询缺少记录判定投递失败。 - [✓] 三个指定外部地址各一次实际验证码投递,对端接收及失败冷却重试证据齐全。 - [✓] 最终数据库、程序摘要、服务状态及本机恢复边界核对。 - [!] 外部邮箱最终入箱和持有人验证码验证尚未完成;其余长期调度、Windows 提权 IPC、外部插件及系统文件选择器边界保持不变。 ## 2026-09-26 管理员分组多选专项复核 ### 范围与结论 本轮从 2026-09-25 23:49 开始,修复版本为 `12cd774816a31a2df0417c3a20027f513e24359a`,已推送并部署到云端 `/opt/smail`。本节仅记录管理员分组多选专项,不代表全项目验收完成。前文 9 月 20 日的双 SQLite、接口和脚本检查均为历史记录,不能作为当前数据库架构或浏览器键鼠验收的依据。 本轮保留连续排障现场,没有清空测试数据库,没有直接查询或修改数据库。业务操作全部通过浏览器鼠标、键盘完成;SSH 仅用于 Smail 部署及运行状态检查,没有操作同机其他项目。助手使用独立浏览器上下文,没有刷新或关闭用户正在手工编辑的页面。 ### 修复内容 - 管理员分组改为直接可见的原生复选框,普通用户改为单选按钮,不再依赖多选下拉交互。 - 编辑中的角色决定可选分组数量,不再读取旧的持久化角色来限制当前草稿。 - 编辑用户内先“应用到编辑”,再通过主编辑“确认”将角色和分组在同一后端事务保存;取消主编辑不保存草稿。 - 列表独立“分组”入口保留直接保存;分组及成员归属仍由超级管理员维护,不扩大普通管理员权限。 - 旧版本通过键盘曾可保存管理员多组,因此没有证实用户原始鼠标多选故障的底层原因;本轮验证的是新复选框交互及修复后的完整保存流程。 ### 浏览器键鼠复核 | 状态 | 场景 | 实际结果 | | --- | --- | --- | | [✓] | 已有管理员多选 | 超管编辑 `reviewadmin`,鼠标勾选默认、验收甲、验收乙三组,应用并确认保存;重新打开仍为三组。 | | [✓] | 列表独立分组保存 | 取消默认组并保存,重新打开确认仅保留甲、乙两组。 | | [✓] | 编辑草稿取消 | 在编辑中加入默认组并应用,然后取消主编辑;重新打开仍只有甲、乙两组。 | | [✓] | 管理员降级限制 | 两组状态下改成普通用户,确认时明确阻止;分组窗口显示单选,选择甲组后可保存。 | | [✓] | 普通用户升级并同时配置多组 | 持久化普通用户在编辑中改为管理员,未先保存角色就能勾选甲、乙两组;一次确认成功保存角色与分组。 | | [✓] | 管理员重新登录 | `reviewadmin` 重新登录后显示管理员角色,用户管理只显示其所属甲、乙两组,不显示默认组。 | | [✓] | 普通管理员界面权限 | 乙组内可打开普通成员 `reviewb` 的编辑窗口,本人管理员行编辑禁用;没有列表分组按钮,普通成员编辑内没有角色选择和分组管理入口。仅查看并取消,未修改该成员。 | 最终 `reviewadmin` 保持管理员角色、所属甲乙两组。最后已取消普通成员编辑并执行测试账号注销;用户自己的页面未操作。 ### 构建与部署证据 以下属于构建和部署证据,不替代上面的业务验收: - `git diff --check`、前端构建、Linux Go 三程序构建及现有打包流程完成;未运行 API 或辅助脚本业务测试。 - 发布包:`Smail_linux_amd64.tar.gz`,SHA-256 为 `2a2793fa20f7b597fbbfeb4453f36c20f68cdf80bf1d955dc6dd5bd52b6f77ba`。 - 云端主程序:`/opt/smail/smail`,SHA-256 为 `c06c5514798c97005137222aac9e708cf01ead6c248645eac3d10e2045d80a57`,与本地构建一致。 - 2026-09-26 00:18 再次通过交互式 SSH 确认 `smail` 为 `active`,8001、8002 端口处于监听状态。 ### 尚未覆盖 - [✓] 新原子编辑的过期版本、并发编辑冲突拒绝,后续双页面键鼠复核已完成,详见下节。 - [✓] 普通用户登录后的账号分组管理入口隐藏,后续键鼠复核已完成,详见下节。 - [ ] 系统通知 SMTP 图形客户端真实发信以及安全码、外部邮箱等完整关联回归。 - [!] 全项目其余验收门槛仍需独立闭环,不因本次分组专项通过而标记上线验收完成。 ## 2026-09-26 界面精简与账号通知授权续验 ### 版本及验收边界 界面精简版本为 `85ccea868dc465d2466fef693e81bafb22d69c0d`,已提交、推送并部署到云端。去掉用户管理顶部、编辑用户及分组弹窗的重复说明,标题与操作按钮同行;保留字段标签、动态错误提示和简短安全提醒。本次没有修改角色、分组或通知服务的业务逻辑。 本节是连续专项验收,未清库、未直接查询或修改数据库,未调用 API 或辅助测试脚本。业务证据来自助手隔离浏览器页面的键鼠操作;用户手工页面未刷新、未关闭、未编辑。交互式 SSH 仅用于 Smail 部署和运行状态核对,未触碰其他项目。 ### 过期编辑冲突补录 此项发生于 00:23 至 00:27 的前序连续验收,运行版本为 `12cd774`,不是在界面精简版本上重跑: 1. 主页面打开 `reviewadmin` 编辑草稿,保留管理员、甲乙两组的旧状态。 2. 第二页面通过列表分组入口增加默认组并保存,账号变为默认、甲、乙三组。 3. 主页面不刷新,修改用户名、将角色改为普通用户、草稿只保留甲组,再点击确认。 4. 页面拒绝保存,提示“账号状态已变化,请刷新列表后重试”。 5. 取消旧草稿并刷新后,原用户名、管理员角色及默认甲乙三组均保留,没有部分覆盖。 6. 正式分组入口去掉默认组并保存,恢复甲乙两组;第二页面随后关闭。 ### 新版本浏览器键鼠复核 | 状态 | 场景 | 实际结果 | | --- | --- | --- | | [✓] | 精简后的显示 | 云端忽略缓存刷新后,用户管理标题与按钮同行;编辑用户及分组弹窗无原重复说明,甲乙两组仍勾选。取消两个编辑窗口,未保存草稿。 | | [✓] | 普通用户的账号分组权限 | `reviewb` 登录后显示普通用户,无用户管理入口、无账号分组管理入口。设置中的“分组”打开的是个人邮件文件夹,不是账号分组。 | | [✓] | 未授权账号状态只读 | `reviewb` 的系统通知页显示未开启、本人连接参数及限额;无授权开关、保存授权或生成凭据按钮。 | | [✓] | 管理员通知管理范围 | `reviewadmin` 的授权列表只显示本人和乙组成员 `reviewb`,不显示默认组中的 `xuans`、`reviewa`。此项证明界面可见范围,不替代绕过界面的安全测试。 | | [✓] | 同组账号单独开启 | 管理员选择 `reviewb`,切换开启并确认保存;该账号显示已开启、待生成凭据,管理员本人仍未开启。 | | [✓] | 普通用户读取授权后状态 | 注销管理员后登录 `reviewb`,显示已开启、待生成凭据,仍没有授权修改或生成凭据入口。 | | [✓] | 关闭并恢复现场 | 再次登录管理员,关闭 `reviewb` 并确认保存,点击刷新状态后显示未开启,生成凭据按钮禁用;管理员本人仍未开启。最后注销测试账号。 | 本轮没有生成通知发信凭据、没有发送邮件。因此不能将本节作为 SMTP 登录、真实投递、旧凭据撤销、通知地址拒收或 IMAP/POP3 隔离通过的证据。授权开关操作中,直接定位开关的输入节点曾不可交互,点击可见“关闭/开启”文字可正常切换;没有使用脚本修改控件。 ### 构建部署及运行核对 - 界面精简时已完成前端构建、Linux Go 三程序构建和现有发布打包流程;这些仅为构建证据。 - 发布包 `Smail_linux_amd64.tar.gz` 的 SHA-256 为 `f6d3833ba707b3a68a81eaed70379fd348e5efcac5a1e8d3c50383be7830d1c4`。 - 主程序 `/opt/smail/smail` 的 SHA-256 为 `f12a7473ba75c4b9759a3219f9943b49d8d73ec58c5aa440e9db9ef4fe7ef202`。 - 00:50 再次核对本地与云端包、主程序摘要一致,`smail` 为 `active`;本轮 00:41、00:47 的状态检查确认 8001、8002 监听正常。 - 本轮只更新现有报告,没有新增辅助文件,没有变更数据库、证书或其他项目服务。 ### 仍待完成 - [ ] 通知凭据生成、重置及关闭后旧凭据拒绝的完整键鼠验收。 - [ ] 使用允许的图形客户端完成 SMTP 加密连接、真实发信、通知地址拒收及普通邮箱不受影响的关联验收。 - [ ] 普通用户和管理员安全码、外部邮箱的完整关联回归。 - [!] 本报告前述外部邮箱最终入箱、长期证书续期、Windows 提权 IPC 和其他未闭环门槛保持未完成,不宣称全项目通过。 ## 2026-09-26 通知凭据界面验收与授权收尾 ### 范围与证据边界 本节接续同一云端版本的专项验收,时间为 00:52 至 01:08。保留连续测试现场,未清库、未重新部署,也未直接查询或修改数据库。业务操作仅使用助手隔离页面的浏览器键鼠;未操作用户手动页面。下列前序结果来自同一轮已执行的浏览器操作,01:04 后重新核对了登录和授权收尾状态,不将补录视为全部重跑。 | 状态 | 场景 | 实际结果 | | --- | --- | --- | | [✓] | 取消生成凭据 | 管理员开启 reviewb 后,在生成确认窗口取消;刷新后仍为已开启、待生成凭据。 | | [✓] | 生成及自动隐藏 | 确认生成后出现仅显示一次的凭据窗口和 60 秒倒计时;先后观察到 47 秒、19 秒,随后窗口自行消失。未记录明文凭据。 | | [✓] | 重置界面 | 点击重置并确认,出现与前次不同的新凭据;手动关闭窗口。本项仅证明界面生成了新值,不证明旧 SMTP 凭据已被实际拒绝。 | | [!] | 通知凭据网页登录负向验证 | 分别使用通知用户名、普通账号名配合通知凭据尝试网页登录,均仍停留登录页;未捕获明确失败提示,暂不作为完整隔离通过证据,未继续重复尝试。 | | [✓] | 普通密码登录不受本次操作影响 | 01:04 后改用 reviewb 的普通测试密码,成功进入收件箱,显示普通用户角色。 | | [✓] | 已生成凭据时普通用户仍只读 | reviewb 的通知页显示已开启、可发信及本人连接参数,没有授权开关、保存或生成凭据按钮;页面状态不代表实际 SMTP 发信通过。 | | [✓] | 关闭授权并刷新确认 | 注销后登录 reviewadmin,选择同组 reviewb,关闭并确认保存;刷新状态后列表和详情均显示未开启,生成凭据按钮禁用,管理员本人仍为未开启。最后注销测试账号。 | ### 运行状态与未完成项 - 01:04 通过已有交互式 SSH 会话确认 Smail 服务为 active,8001、8002 正在监听;没有停止或修改其他项目。 - 本轮只补录现有报告,没有新增辅助文件,没有变更业务代码、部署文件或证书。 - [ ] 使用图形客户端验证 SMTP TLS 登录、实际投递、重置及关闭后旧凭据拒绝、通知地址拒收,以及 IMAP/POP3 隔离。 - [ ] 网页登录负向场景的明确失败反馈仍需补证,不能用停留登录页替代完整结论。 - [ ] 安全码、外部邮箱及报告前述其他剩余门槛继续保留;全项目验收尚未完成。 ## 2026-09-26 自身安全邮箱拦截与多分组降级专项复验 ### 范围与现场 - 前序安全码与自身邮箱漏洞复现发生于 01:10 至 01:24;本次接续复验为 01:27 至 01:40,均为服务器本地时间(UTC+8)。前序操作按同一线程交接记录补录,本次没有把所有前序步骤重新执行一遍。 - 云端继续运行修复提交 `9762300` 对应的 `review-9762300` 版本。业务操作仅使用助手隔离页面的浏览器点击、键盘及表单输入,没有调用业务 API、执行浏览器脚本、协议脚本或数据库查询。 - 本次保留连续专项现场,未清库、未重新初始化、未重新部署,不能替代用户要求的清库后全量生产流程验收。未刷新、关闭或编辑用户手动页面。 ### 前序安全码操作补录 | 状态 | 场景 | 实际结果及边界 | | --- | --- | --- | | [✓] | 取消生成 | reviewb 初始未配置安全码;生成确认时取消,重新进入后仍未配置。 | | [✓] | 生成与明文生命周期 | 确认生成后显示恢复码及已配置状态;同一设置窗口内切换子项后明文仍在,关闭整个设置窗口再重新打开后不再显示明文。未在报告保留恢复码。 | | [✓] | 撤销确认与取消 | 取消撤销后仍为已配置;再次确认撤销后提示已撤销并回到未配置。本次管理员成员列表再次显示 reviewb 安全码未开启。 | | [ ] | 实际密码恢复 | 未使用生成或撤销的恢复码执行密码恢复,不能据此判定恢复链路或撤销码使用拒绝通过;前序处于近期认证窗口,不能据此判定二次身份确认已验收。 | ### 自身邮箱漏洞修复与复验 前序旧版本允许 reviewb 将 `reviewb@solit.cn` 提交为外部安全邮箱,并进入验证码步骤;自身收件箱收到验证码邮件。操作已取消,没有输入验证码或确认绑定。这与外部邮箱不能为当前用户 Smail 主邮箱的既有需求不符。 根因是原归属判断只检查独立主邮箱绑定记录,遗漏按账号名与本地邮件域名直接收信的地址。提交 `9762300` 保留原检查,补充账号、本地主域名及接收域名的归属判断,并在三个验证码确认入口重新检查,防止仅在申请阶段校验。 | 状态 | 本次浏览器场景 | 实际结果 | | --- | --- | --- | | [✓] | 自助绑定自身地址 | reviewb 输入 `reviewb@solit.cn` 并点击发送验证码,明确显示不能将当前邮箱绑定为外部安全邮箱,仍停留地址输入步骤。 | | [✓] | 大小写变体 | 改为 `REVIEWB@SOLIT.CN` 后再次提交,得到相同拒绝提示,没有进入验证码步骤。 | | [✓] | 管理员替成员设置 | reviewadmin 从乙组成员 reviewb 的编辑窗口进入外部邮箱管理,先出现当前密码确认;完成确认后自动进入目标邮箱窗口。输入目标自身地址后明确提示不能将该用户自己的邮箱绑定为外部安全邮箱。随后取消,未确认任何绑定。 | | [✓] | 关联状态 | reviewb 自助页面显示暂无外部安全邮箱,管理员页面显示未绑定、安全码未开启;本人通知服务显示未开启。 | | [ ] | 未覆盖路径 | 旧挑战确认阶段拒绝、其他接收域名、已有主邮箱绑定记录、真正外部邮箱的正向绑定及最终入箱尚未在本轮复验。列表未显示绑定不代表已检查数据库中的待验证挑战。 | ### 多分组管理员降级与恢复 初始从超级管理员页面确认 reviewadmin 为管理员,属于验收甲组、验收乙组,安全码已开启。此次未生成、替换或撤销该管理员原有安全码。 | 状态 | 场景 | 实际结果 | | --- | --- | --- | | [✓] | 多分组直接降级拦截 | 将角色改为普通用户但保留甲乙两组,点击确认,明确提示普通用户只能属于一个分组,请在分组管理中选择一个分组;窗口未关闭。 | | [✓] | 明确选择保留分组 | 打开分组管理后为单选,未擅自选定原来的某一组;手动选择乙组,应用到编辑,再确认保存,出现用户信息已保存。 | | [✓] | 保存后可见归属 | 乙组中 reviewadmin 显示普通用户;展开甲组显示本组暂无成员。之后重新以超级管理员登录并打开编辑窗口,仍为普通用户且只有乙组。 | | [✓] | 降级后登录权限 | reviewadmin 使用原普通登录密码成功登录,角色为普通用户;设置中没有用户管理和配置管理入口,系统通知页只显示本人只读状态,没有授权管理按钮。此项仅证明新登录界面的权限表现。 | | [✓] | 恢复原测试角色及分组 | 超级管理员将 reviewadmin 改回管理员,在同一次编辑中选择甲、乙两组并保存;重新打开编辑窗口确认管理员及两个分组。再登录 reviewadmin,显示管理员,用户管理仅列出甲、乙组,不显示默认分组;乙组可编辑 reviewb。 | | [ ] | 未覆盖边界 | 未保留目标账号旧会话来验证实时踢出,未通过绕过页面或故障注入检验后端拒绝及事务回滚,也未执行选择默认分组的降级保存。源码检查不能替代这些实测。 | ### 部署核对与收尾 - 前序已完成 Linux Go 三程序编译和现有打包流程;没有重建前端。发布包 SHA-256 为 `2a88d3bb451334e321153fc9c9bf57cef9088fa8221ed07eaec058afb6e4e098`,主程序 SHA-256 为 `b3b00f76f26fff27946154c82853f30dfadbc7b18fdd7f04414b8bf09e826f7e`。前序记录本地和云端摘要一致;本轮 01:27 通过已有交互式 SSH 会话再次核对云端主程序摘要一致。 - 前序部署仅替换 `/opt/smail` 内三个程序,未替换数据库、证书和配置;清理的是 `/opt` 下 `smail-release-12cd774.tar.gz`、`smail-release-4d24bf2.tar.gz`、`smail-release-7bcbfe7.tar.gz`、`smail-release-85ccea8.tar.gz`、`smail-release-9a60bd7.tar.gz`、`smail-release-b7fd2cb.tar.gz`、`smail-release-c703b3d.tar.gz` 七个明确旧包,不能扩展为所有历史目录已清理。 - 本轮 01:27、01:32、01:37 检查 Smail 服务均为 active,8001、8002 监听正常;未停止服务或触碰同机其他项目。此项是运行状态检查,不是业务验收。 - 最后已取消所有编辑窗口并注销助手测试账号。reviewadmin 恢复管理员及甲乙两组;reviewb 未绑定外部邮箱、未开启安全码,通知授权仍关闭。旧版产生的测试验证码邮件仍保留在其收件箱,本次未删除邮件或项目文件。 - [!] SMTP 图形客户端真实 TLS 登录、投递及旧凭据撤销,外部邮箱正向完整验证,安全码完整恢复链路,清库生产流程回归及本报告其他未闭环门槛继续保留;全项目验收仍未完成。 ## 2026-09-26 降级旧会话与默认分组专项 - 本轮继续保留专项现场,未清库;所有业务验证通过浏览器键鼠进行。用户的 Page4 未操作,助手使用两个隔离会话分别登录超级管理员和测试管理员。 - [✓] reviewadmin 原为甲乙两组管理员,保留其用户管理页面;超级管理员将其降为普通用户,并明确单选默认分组,保存成功。再次打开编辑窗口确认普通用户及默认分组。 - [✓] 降级前的旧页面没有立即自动跳转;点击用户管理的刷新列表后跳回登录页面。此项只证明下次受保护操作触发会话失效,不代表实时推送踢出,也不代表所有客户端协议均已验证。 - [✓] 使用原普通登录密码重新登录后显示普通用户,用户管理和配置管理入口消失。随后已通过超级管理员页面恢复管理员及甲乙两组,列表显示管理员。 - [!] 发现界面残留:旧会话失效后重新登录,设置抽屉仍自动打开,原用户管理标签已无权限,内容区域空白。源码定位为业务请求的认证失败跳转没有调用全局状态清理,而主动注销会清理该状态。 - [x] 修复认证失败跳转前清理全局登录和设置状态;登录及二次验证页面不执行该清理,避免打断正在进行的登录挑战。待最新构建云端部署及浏览器复验,不能将源码修复算作实测通过。 - [ ] 安全码完整密码恢复链路仍未开始,本轮未设置 reviewb 的密保问题或生成新恢复码。 ### 修复部署与浏览器复验补录 以下补录上轮截至 02:04 的连续执行记录;02:07 只重新检查部署状态与浏览器页面列表,没有声称再次执行全部业务场景。 - [✓] 修复提交 `b2bfa09` 已完成前端构建、Linux Go 三程序构建及现有发布流程,云端版本为 `review-b2bfa09`。仅替换三个程序并重启 Smail,未替换数据库、证书和配置,未停止其他项目。旧发布包 `smail-release-9762300.tar.gz` 已按授权清理。 - [✓] 发布包 SHA-256 为 `61d42559ca012f33d637b26630216715ea0e6600de417d9d2af255cf6152c2f9`,主程序 SHA-256 为 `da48c1f73ed938a4b3c30878784f78c1e2cfa0e4cacd789b41113d59442db628`。本地与云端一致;02:07 再次读取云端摘要仍一致。 - [✓] 两个助手隔离页面忽略缓存刷新后重新登录。管理员保持用户管理页面,超级管理员将其降为普通用户并选择默认分组;近期身份确认要求出现时,输入当前密码后继续完成保存。 - [✓] 旧会话返回登录页后,不再刷新页面,直接重新登录普通用户:设置抽屉没有自动残留;手动打开设置进入安全设置的密保问题页,内容正常,且没有用户管理或配置管理入口。上方修复待复验项在本节更新为专项复审通过。 - [✓] 已恢复 reviewadmin 为管理员及甲乙两组,并再次打开编辑窗口确认角色和两组成员关系。超级管理员随后关闭编辑和设置窗口并注销;02:07 页面列表确认两个助手页面都在登录入口。用户手动页面未操作。 - [!] 部署检查中误执行过主程序的 `--version`,该版本没有处理此参数,实际尝试启动后因本机恢复控制目录属主不匹配而退出。不能声称该尝试完全无副作用;随后复核正式服务 active、退出状态为 0,仅有原服务常驻进程,且浏览器复验正常。后续不得沿用此版本查询方式。 - [ ] 上述仅完成会话失效界面修复的连续专项复验,未清库,不包含邮件客户端旧连接撤权、完整安全码恢复或全项目生产放行。 ## 2026-09-26 发布版本查询修复及清理前置检查 ### 需求与完成状态 - [✓] 源码确认主程序此前没有处理版本参数,查询版本也会执行部署初始化。本次在主服务入口增加只读分支,识别单独的 `--version` 和 `version`,在配置迁移、日志启动、数据库和服务监听初始化之前返回。既有配置包仍会打印运行根目录,不将输出描述为单行纯版本。 - [✓] 修复提交 `218337d` 已推送,完成 Linux amd64 三程序编译及现有发布打包。前端与嵌入插件没有变化,本轮复用既有构建,不宣称重新构建或重新验收了这些部分。 - [✓] 交互式密码 SSH 和 SFTP 完成部署,只替换 `/opt/smail` 内三个程序并重启 Smail;没有调用业务 API、协议脚本或辅助测试脚本,没有修改数据库、证书和业务配置。 - [✓] 02:14 在服务器以 smail 用户分别执行新版两种版本查询,均输出 `review-218337d` 且退出码为 0;前后主进程 PID 1225013、自动重启次数 0、服务退出状态 0 保持不变。所检查的 `config/config.json`、`data/smail.db`、`log/runtime-2026-09-25.log` 大小和修改时间均未变化;这是部署命令的运行核对,不是业务验收或全文件系统无写入证明。 - [✓] 发布包 SHA-256 为 `6a0dc39e7ad8499ec8d2d86cba3c66306fbb360a43d4aa22bff05a1b4450c2ef`,主程序 SHA-256 为 `25f75e8531fe92d23ad0645aee7d69573d0400e6d7f1710ca274337344a72546`。上传包及安装后主程序均与本地一致。 - [✓] 02:15 按已授权范围清理明确的旧发布包 `/opt/smail-release-b2bfa09.tar.gz`;检查 `/opt` 顶层同名发布包仅剩本次 `smail-release-218337d.tar.gz`,没有新增云端备份。此结论不扩展到未检查的其他历史目录。 - [✓] 清理前置检查发现当前运行目录两层范围内只有 `data/smail.db` 一份 SQLite 数据库,主进程文件描述符也仅打开该数据库。此项不代替三种数据库后端在所有部署方式下的验收。 - [ ] 本轮未清库、未重新初始化、未操作用户手动页面,未执行新的浏览器业务测试。完整安全码恢复、通知 SMTP 图形客户端、外部邮箱及最终清库生产全流程等门槛继续保持未完成。 ## 2026-09-26 清库后安全恢复浏览器复验 本节记录本轮清库、初始化后的连续浏览器验收。页面操作均通过 Chrome DevTools MCP 的可见页面控件完成;未调用业务 API、未执行浏览器脚本、未使用辅助测试脚本。用户手动页面未操作。 - [✓] 超级管理员通过用户管理页面创建 `reviewb` 普通用户,使用本次测试统一密码登录成功;登录后页面显示“普通用户”,首次登录出现账户安全提示。 - [✓] `reviewb` 通过安全设置页面配置密保问题,并在安全码页面生成离线恢复码。恢复码仅用于当前浏览器验证,没有写入报告、文件或提交记录。 - [✓] 在独立恢复页面输入 `reviewb`,使用未使用的离线恢复码完成身份验证并重置密码;随后使用统一测试密码重新登录成功。 - [✓] 同一恢复码再次提交时,页面提示“验证未通过或流程已失效”,证明恢复码不可重放。 - [✓] 生成第二批测试恢复码后,通过安全设置页面执行撤销;在仍打开的恢复页面提交该批恢复码同样被拒绝,证明撤销立即生效。 - [✓] 撤销后 `reviewb` 的安全设置显示未配置有效离线恢复码;没有留下助手可继续使用的普通账号恢复凭据。 - [✓] 在独立恢复页面输入超级管理员账号 `xuans`,页面明确提示超级管理员不能通过登录页通道重置密码,需使用已登录安全中心或部署端本机恢复通道。 - [✓] 撤销超级管理员本轮测试恢复码后,页面提示至少启用一种安全验证;随后通过页面注销。当前未保留本轮生成的超级管理员恢复码。 说明:普通用户安全设置中的密保说明是“密保问题不能单独重置密码,必须与离线恢复码组合使用”;本轮公开登录页恢复入口展示的是独立的离线恢复码通道,未将密保问题单独冒充为公开恢复方式,也未将两条不同恢复入口合并宣称为同一流程。密保答案组合的部署端本机恢复路径仍未通过浏览器页面完成验收。 本轮复验后,完整密码恢复链路的“公开恢复码一次性使用、撤销即时失效、超级管理员公开入口隔离”已通过;外部邮箱真实验证、通知 SMTP 图形客户端、IMAP/POP3 隔离、密保答案组合恢复及最终生产放行仍未完成。