Commit Graph
10 Commits
Author SHA1 Message Date
tamakyi 752fad412b feat: v0.12.0 —— 表格每行绝对等高 + 管理 WebUI(2FA 绑定才能进入)
① 每行绝对等高
- 行高与内容长度彻底解耦:新增 --row-h: 72px 作为唯一基准
- 名称列改为「文本区限两行 + 徽标区固定单行」两段式;文本区用 .clamp2
- 关键点:必须用 height 而非 max-height —— 后者会让短内容缩成一行、
  长内容撑到两行,反而产生 66px/71px 两种行高(实测踩过)
- 分组标题行用 :not(.group-row) 排除在数据行规则之外
- 事件表与监控表格共用同一个 --row-h,两张表视觉上也严格对齐
- 完整值仍可通过悬停 title 查看(已加断言强制所有截断单元格带 title)
- 卡片视图同样等高(13 视口 × 250px 全一致)

② 管理 WebUI + 2FA
- 新增 /admin 与 /api/admin/*;未绑定 2FA 时除绑定流程外一律 403
- 零依赖实现 TOTP(RFC 6238),用 RFC 4226/6238 官方测试向量验证(16 个向量)
- 内置 QR 码生成器(byte 模式 / ECC L / 版本 1-10,GF(256) RS 纠错 + 掩码评分),
  用独立解码器实测:版本 1 与版本 6 均能读出逐字节一致的内容
- 绑定流程:口令 → 生成密钥(扫码/手输/otpauth 链接)→ 验证 6 位码 → 10 枚恢复码;
  完成后凭本次验证码直接换取会话
- 安全:会话 id 32 字节随机数且服务端只存哈希;HttpOnly+SameSite=Strict;
  30 分钟空闲/2 小时最长;同时间步的码防重放;恢复码一次性;
  登录失败按 IP 指数退避锁定;不解析 X-Forwarded-For
- 管理功能:运行状态、探测范围、展示口径、维护窗口增删、立即重探、通知自检、
  目标只读列表、最近事件
- 所有写操作只落 local.monitors.json(私有不入库),绝不改 public/monitors.json

过程中修掉三个真 bug:
1. 会话 cookie 的 Path=/admin 覆盖不到 /api/admin/*,登录 200 但后续全部 401
2. 恢复码登录被 verifyTotp 的 invalid-format 提前挡掉(恢复码非 6 位数字)
3. 超大请求体用 req.destroy() 硬断连接,客户端只看到 fetch failed 拿不到状态码

测试:新增 scripts/verify-admin.cjs(102 项),全项目共 7 套 274 项全部通过
2026-10-14 12:37:07 +08:00
tamakyi a3a683ff0e fix(ui): 表格行高统一 + 事件区块改为与表格同一套样式
1) 行高不一致(「狼的评论系统」明显矮一截)
   实测在线行 58px / 离线行 43px。根因是可用率列的 90 格 mini 条:
   它是 inline-flex,参与行内布局时基线把行盒抬高约 15px,于是「有可用率
   数据的行」比不带条的行高出一截。
   修复:单元格内容统一 vertical-align: middle + mini 条容器改 flex;
   实测 6 行全部 43px。

2) 「最近事件」与表格样式不统一
   去掉独立的时间线卡片风格,改为与监控表格同构的表格(相同容器圆角、
   表头、行分隔、hover、状态底色);故障行淡红、证书行淡琥珀、恢复行不染。
   刻意不共用 .monitor-table 类名 —— 共用时面板条目统计被多算 1~8 个
   (测试当场抓到),改为独立 .events-table 并显式声明所需样式。

说明:内容长度相当时保证等高;名称/地址特别长时允许换行(上一版按用户
要求做的「完整显示」),此时行更高属于数据本身需要,不再用截断换整齐。

测试:verify-views 新增「内容等长时各行等高」「事件表与监控表同构」
「事件行复用状态底色」断言(并修正了断言脚本改错文件的问题 —— 名称来自
monitors.json 而非 status.json)。六套 171 项全通过。
2026-10-14 10:49:01 +08:00
tamakyi 25b8b97970 fix: 表格完整显示 + 事件区块样式重做 + 探测范围可选(probeScope)
1) 表格显示不全
   table-layout:fixed 保证不横向滚动后,列内仍是 nowrap,实测长 URL 被截
   388px、名称截 219px、可用率条截 35px(1440 宽共 14 个单元格)。
   改为允许换行(地址 break-all)并重排列宽 —— 数据完整且仍零横向滚动。

2) 最近事件完全没样式
   根因:上次追加 CSS 的命令是 `node --check app.js && cat >> style.css`,
   --check 报错导致 && 短路,CSS 从未写入(只有 HTML 裸奔)。
   本次用编辑器写入;同时重做为时间线样式(竖线 + 类型着色圆点 + 左描边)、
   名称列按内容自适应(消除大片空白)、默认折叠最近 8 条可展开全部。

3) dataFilter=uptimerobot 时仍在探测本地目标
   新增 settings.probeScope(all|config|uptimerobot),不填则跟随 dataFilter;
   显式设 all 可保留探测。启动日志打印当前口径与范围。

顺带修复两个连带问题:
- UR 镜像目标此前不产生事件也不告警(evaluateRound 只遍历本地目标),
  配 uptimerobot 口径等于收不到任何提醒 —— 现在两类目标统一纳入
- 去抖计数被评估频率放大:evaluateRound 每秒执行,原实现每次评估都
  failStreak+1,持续离线目标 1 秒即达阈值告警。改为按探测时间戳去重,
  且无状态变化时不再反复落盘

测试:verify-views [J] 扩到 11 条(长内容不截断/仍不滚动/时间线布局/
类型着色/折叠展开),verify-notify 新增 [D3] 4 条(范围跟随、不再探测本地、
显式 all 恢复、与展示口径解耦)+ 去抖计数断言。六套 170 项全通过。
2026-10-14 10:22:05 +08:00
tamakyi 4bb5296525 feat: P1 收尾 —— 事件面板区块与 90 天响应时间趋势
事件时间线(面板侧):
- 监控列表下方「最近事件」区块(最近 20 条:时间/类型/目标/详情),
  无事件自动隐藏;维护窗口内事件带「维护」标记;窄屏隐藏详情列

响应时间趋势(P1-2):
- 当日分桶在 {total,up} 外累计 latSum/latCount/latMax(仅在线样本)
- 快照输出 lat: { avg, max, days:[{key,avg}] }
- 卡片视图:可用率条下方新增「90 天日均延迟」细柱图(最近 30 天 + 均值)
- 表格视图:可用率列 tooltip 追加「90 天日均延迟 X ms(峰值 Y ms)」
- --demo 同步生成 90 天延迟样例(含起伏),静态部署也能看到效果

验证:verify-views 新增 [J] 段 5 条断言(趋势条/30 格/tooltip/事件空态/无溢出),
六套合计 159 项全通过(17+35+26+20+39+22)。

至此 P0(通知、证书)与 P1(事件时间线、维护窗口、响应时间趋势)全部落地。
2026-10-14 00:32:59 +08:00
tamakyi bdaa31f10c feat: P0 通知(邮件 + MeoW)与 TLS 证书监控,事件时间线与维护窗口
通知(P0-1):
- 邮件:自写 SMTP 客户端,零依赖。465 隐式 TLS / 587·25 STARTTLS、
  AUTH LOGIN+PLAIN、RFC2047 中文主题、base64 正文、多收件人;
  服务器不支持 STARTTLS 时默认拒绝明文(需显式 allowInsecure)
- MeoW:按官方文档实现,昵称寻址、msgType/htmlHeight 走查询参数、
  以响应体 status 判定成功(HTTP 恒 200)、429/404/403 可读化、
  本地限流器遵守 3s/15min/60h
- 告警:连续 N 次失败去抖 + 恢复通知 + 同轮合并 + 去抖状态持久化
  (data/notify-state.json,gitignore)+ 静默时段(跨零点)
- --test-notify 自检命令、--data-dir / SHIROKO_DATA_DIR

证书(P0-2):
- 独立 TLS 握手取 notAfter(不动既有 fetch 探测路径),默认 6 小时一次
- 面板徽标 ≤14 天黄 / ≤7 天红,阈值 14/7/3 各告一次、已过期只报最严重一档
- 单个目标可用 tls: false 关闭

事件与维护(P1-1 的后端部分):
- data/events.json 追加式事件流(最近 500 条)+ GET /api/events +
  快照内附最近 20 条;redactDetails 时脱敏
- 维护窗口:窗口内不计入可用率、不发告警、显示「维护中」徽标

测试抓到并修复的三个真 bug:
1. SMTP 空闲超时无人处理 → 服务器不响应会把探针循环挂死
2. MeoW 限流器把空历史当 0 → 第一条通知永远被自己拦掉
3. 去抖状态在无事轮次不落盘 → 连续失败计数丢失、永远达不到阈值

验证:新增 verify-notify.cjs 39 项(假 SMTP / 假 MeoW / 三轮集成 / 维护窗口 /
真实证书握手),六套合计 154 项全通过。
2026-10-13 23:54:46 +08:00
tamakyi ea846dee31 fix(layout): 表格流式列宽,任何内容与视口都不再需要横向滚动
硬要求(用户明确):不允许出现需要滚动才能看全的情况。

改动:
- 表格 table-layout: fixed + 百分比列宽(8/16/21/8/7/11/17/12%),
  表头允许换行并裁剪、单元格裁剪、心率图与可用率条随宽度伸缩
- 卡片网格 minmax(min(300px,100%),1fr) + .card{min-width:0}
  (修 grid 的 min-width:auto 撑破:320px 下曾溢出 495px)
- 截断的名称/目标补 title,悬停可看完整值
- 新增 scripts/verify-layout.cjs:自带极端配置(40 目标 / 6 分组 /
  超长名称与 URL)+ 临时静态服务,扫描 13 视口 × 2 视图,26 项断言零横向滚动

验证:五套 115 项全通过(17+30+26+20+22)
2026-10-13 22:37:02 +08:00
tamakyi a7408e2bb5 feat(theme): 全局装饰遮罩 + 尺寸统一;全局审阅修复对比度/暗色/平板布局
用户反馈的两点:
1. 遮罩看不出效果 → 人物与单车统一全局半透明 settings.decoOpacity(默认 .78)
   (此前 0.92/0.80 不一致且几乎无感),各自保留边缘渐隐
2. 切视图时人物比例变化 → 删掉卡片视图专用的 300px 高度,两种视图尺寸一致
3. 保留原始素材 → 原图归档 assets-src/,处理流程固化为 scripts/prepare-artwork.py

全局审阅发现并修复:
- 无障碍对比度:两套主题的状态色当文字用时远低于 AA(最低 2.56:1)→ 双色体系
  (填充色 ≥3:1 保持鲜亮 / 文字色 ≥4.5:1 同色系加深),暗色模式同步
- 暗色模式主题失效:顶栏/卡片/表头/分组行是硬编码白色 → 改为随模式切换的变量
- 平板竖屏 768px 表格需内部横滚 242px → 自动切卡片阈值 700 → 1024
- Cloudflare Worker 快照补齐 dataUpdatedAt/updateIntervalSec/dataFilter
- 清理失效 CSS(.logo .halo)

测试脚本修掉两个自身 bug(均为误报):color(srgb/…) 与半透明底的解析、
渐变背景被误判为透明。verify-views 新增对比度断言 8 条,四套合计 89 项全通过。
2026-10-13 21:55:44 +08:00
tamakyi f0e5d91171 fix(mobile): 修移动端顶栏塌陷,窄屏默认卡片视图
问题(用户报告移动端异常):窄屏下顶栏统计挤成竖排并与标题重叠,
表格在手机上必须横向拖动,固定装饰在小屏上可能溢出或压住内容。

修复:
- 顶栏结构拆为「标题 / 统计(.stats) / 控件(.controls)」三段;
  ≤820px 改为纵向三行,统计均分视口宽度,页脚改纵向堆叠
- ≤700px 且用户未显式选择视图时自动用卡片(横竖屏切换时重算,
  显式选择仍尊重 localStorage)
- ≤820px(及横屏手机)撤掉立绘、公路车、光环水印等固定装饰

验证:
- 390x844 / 360x640 / 414x896 / 844x390 四种视口:0 横向溢出,顶栏三行
- verify-views 新增移动端 7 条断言(22/22 通过)
- 四套合计 81 项全通过(17+22+20+22)
2026-10-13 20:38:39 +08:00
tamakyi 5b417c84f4 fix(theme): 修横向拖动 + 立绘遮光环,形象换成简约风插画
问题与修复:
1. 桌面端表格/列表需要横向拖动 —— 上一版为避让立绘给 .grid/.footer 加了
   240px 右内边距,而 .grid 是 max-width:1200px,内边距吃在 1200 内部,
   1200px 以上的屏幕也必然溢出。改为立绘收窄 + 置于内容之下(z-index 低于面板)
2. 立绘遮挡光环水印 —— 光环水印移到页脚下方空带,与左下公路车、右下立绘形成
   一条互不遮挡的装饰带
3. 形象换成简约风插画(AI 生成后抠底):右下角全身立绘 + 同款半身像做 logo/favicon;
   官方立绘/头像(SchaleDB 素材)已从仓库移除

验证:
- 1280/1440/1920 三种宽度下页面与表格均 0 溢出
- verify-views 新增 4 条断言(两视图无横向溢出、立绘不影响阅读),15/15 通过
- 四套脚本合计 74 项全通过
2026-10-13 19:56:46 +08:00
tamakyi 3db3ce570a chore: v0.6.0 baseline — 主题美化前存档
已实现:HTTP/TCP/Banner 探测、90 天可用率、表格/卡片视图、
数据源过滤、UptimeRobot 双向兼容、服务端驱动的刷新节奏、
刷新接口滥用防护与信息泄露控制。
2026-10-13 18:31:58 +08:00