24 June 2026, 12:00 (CST)
2026年06月24日 12:00(东八区 / 北京时间)
站点更新总结:Umami 统计 · 文章加解密 · 管理员特权 · 访客随机解密 · 编辑按钮门控
概述
本轮迭代围绕 可观测性(Umami)、内容保护(构建期加密 + 运行时解密)、特权与访客双模式 以及 编辑类按钮的可见性控制 展开。所有改动均在站点根目录 templates/、static/、scripts/、zola.toml 完成,未修改 themes/。
构建入口统一为:
./build-site.sh # encrypt-content.mjs → zola build → patch-search-index.mjs1. Umami 流量统计
1.1 问题与根因
| 现象 | 原因 |
|---|---|
| Umami 控制台长期无数据 | self_hosted_url 误填为博客域名,脚本指向不存在的 /script.js |
| 控制台 CSP 报错 | script-src / connect-src 未放行 Umami Cloud |
gateway.umami.is/api/send 被拦截 | Umami 新版上报端点未加入 CSP |
1.2 修复要点
| 配置 / 文件 | 说明 |
|---|---|
zola.toml [extra.analytics] | service = "umami";留空 self_hosted_url(走 Umami Cloud) |
zola.toml [extra.csp] connect-src | 新增 gateway.umami.is |
static/analytic/umami.js | 全站幂等加载器;zola.toml → scripts = ["analytic/umami.js"] |
static/js/nanolog.js | 合并重复副本,统一路径 |
主题 build 模式仍会注入 cloud.umami.is/script.js;站点层脚本作兜底,避免漏统计。
1.3 验证
- Network:
cloud.umami.is/script.js→ 200;gateway.umami.is/api/send无 CSP 拦截 - Umami 控制台
更细的调用链见同目录较早条目:2026-06-23T12:00:00Z.md。
2. 文章加解密(底层通用能力)
2.1 设计原则
- 构建期加密:正文不进 HTML 明文,降低「查看源代码」直接可读的风险
- 运行时解密:依赖 Web Crypto(需 HTTPS 或 localhost)
- 任意目录通用:凡 front matter 声明加密即纳入流水线,与板块路径无关
2.2 启用方式(单篇文章)
[extra.encryption]
encrypt = true建议
[extra]写在[extra.encryption]之前,避免 TOML 表顺序导致解析异常。
2.3 文件结构
| 层级 | 路径 |
|---|---|
| 站点配置 | zola.toml → [extra.encryption] |
| 构建脚本 | scripts/encrypt-content.mjs、scripts/encryption-lib.mjs |
| 密文输出 | static/encryption/pages/<相对路径>.json |
| 清单 | static/encryption/manifest.json |
| 全站注入 | templates/base.html → partials/encryption_config.html |
| 加密文章 UI | templates/partials/encrypted_article.html |
| 文章模板 | templates/article.html(判断 encrypt 后 include) |
| 前端 | static/encryption/config.js、admin.js、visitor.js、crypto.js、article.js |
| 样式 | static/encryption/admin.css、article.css |
2.4 构建与 CSP
- 配置与密文通过
<textarea hidden>注入页面,避免内联<script>触发 CSP 拦截 script-src允许'self'、cdn.jsdelivr.net(marked)、主题合并的cloud.umami.is- 未跑加密脚本仅
zola build时,页面会提示「密文未找到,请先运行./build-site.sh」
2.5 测试文章
| 路径 | 说明 |
|---|---|
content/00Read_blog_Math/2026-06-03-First Base Chater/ | 数学板块加密试点 |
content/02Engineer_blog_Debug/2026-06-23-Chrome-ReOpen/ | Debug 板块加密验证 |
3. 管理员特权模式
3.1 进入方式
连续点击左上角 #site-sidebar-header(站点图标)6 次:
| 点击次数 | 反馈 |
|---|---|
| 第 3–5 次 | Toast:「再点击 N 次可进入管理员模式」 |
| 第 6 次 | Toast:「你已经是管理员,可浏览所有加密博客啦」 |
| 已是管理员 | 鼠标悬停图标显示「你已经是管理员」 |
状态保存在 sessionStorage(blog-encryption-admin-until)。
3.2 有效期(admin_ttl_secs)
admin_ttl_secs = 60 # 秒,到期自动恢复访客- 进入特权时按 TTL 设置 精确
setTimeout,并每 500ms 兜底检查 - 到期触发
encryption-admin-expired:移除html.encryption-admin-active、文章重新上锁、看板恢复只读
3.3 管理员能力
- 解密所有
encrypt = true的文章 - 显示并可用 Nanolog / 看板上的 ReDeplog、Edit Post 等编辑入口
- 看板在
week_start~week_end窗口内可解锁拖拽;截止日当日 23:00(extra.timezone)前仍可编辑
4. 访客模式与随机解密
4.1 默认展示
- 加密文显示:「🔒 本文已加密」
- 提示语:「随机刷新时,可能会触发解密哦。」
4.2 随机解密逻辑(static/encryption/visitor.js)
visitor_refresh_min = 9
visitor_refresh_max = 20- 每篇文章、每个浏览器 session 独立计数
- 首次访问随机抽取阈值(9~20 次刷新之间)
- 刷新次数达到阈值后 自动解密(无需管理员)
- 解密状态在该 session 内对该文保持
5. 编辑类按钮门控(交互隐藏)
原则:访客只见只读;编辑入口仅在管理员特权下出现。
| 位置 | 访客 | 管理员 |
|---|---|---|
| Nanolog 列表 | 隐藏 ReDeplog、Edit Post、发布按钮 | 显示 |
| 看板明细 | 锁定按钮固定「🔒 只读」,不可解锁 | 有效期内可解锁;显示工具栏;截止日 23:00 后变「只读(已过期)」 |
| 加密文侧边栏 TOC | 非管理员隐藏 | 管理员显示 |
实现:元素加 class encryption-admin-only;html.encryption-admin-active 时由 admin.css 显示。看板逻辑在 kanban-board.js 中额外校验 EncryptionAdmin.isAdminActive()。
6. 关联改动(本轮一并收敛)
| 项 | 说明 |
|---|---|
| 看板数据源 | 统一为 content/kanban/,构建时内嵌 MD,移除多余 kanban/ 副本 |
| Nanolog 列表宽度 | sass/nanolog/style.scss 调至与正文同宽 |
nanolog.js | 移除不存在的 save-token-btn 控制台警告 |
7. 配置速查(zola.toml)
[extra]
scripts = ["analytic/umami.js"]
[extra.analytics]
service = "umami"
id = "cdf54193-b449-4454-884b-029e82434c32"
exclude_hash = true
[extra.encryption]
enabled = true
algorithm = "AES-GCM"
key = "rocky-blog-dev-key-change-in-production" # 生产环境请更换
admin_ttl_secs = 60
visitor_refresh_min = 9
visitor_refresh_max = 20CSP connect-src 需包含:gateway.umami.is(以及主题自动合并的 cloud.umami.is、*.umami.dev)。
8. 自测清单
-
./build-site.sh无报错,控制台输出encryption: N page(s) - 加密文:访客默认上锁;连点 6 次进入管理员可解密;TTL 到期后恢复上锁
- 加密文:无痕窗口反复刷新,约 9~20 次后访客随机解密
- Nanolog / 看板:访客无 Edit Post、ReDeplog;管理员可见
- 看板:截止日 23:00 前可解锁,之后只读;列表剩余天数与明细一致
- Chrome DevTools 无 CSP inline script 报错;Umami 上报 200
9. 看板列表 / 热力图 · 编辑窗口判定(追加)
9.1 列表页与热力图
| 项 | 说明 |
|---|---|
| 页头 | 移除大标题「周计划」;副标题居中加粗;补充「单个看板时间跨度 1 ~ 14 天」 |
| 年份 / 月份下拉 | 修复脚本重复加载导致菜单无法展开;月份含全年 + 1–12 月 |
| 年度视图 | 1–6 月 / 7–12 月两行;月份块间距 + 虚线分隔 |
| 周格填充 | 有效天数 / 7 比例自下而上着色;未满 7 天为部分填充 |
| 月份视图 | 切换具体月份后展开为按天网格,直观显示哪些日期纳入看板 |
| 验证数据 | content/kanban/2026-06-22.md(06-22 ~ 06-23,2 天) |
涉及文件:templates/kanban_list.html、static/js/kanban-heatmap.js、static/css/heatmap.css、sass/kanban/style.scss。
9.2 只读 / 可编辑判定(截止日 23:00)
原先按日历日比较 week_end,导致截止日当天 0 点起即只读。现改为:
- 截止日
week_end当日 23:00 之前仍可解锁、拖拽、Edit Post - 23:00 及之后(站点时区)永久只读
- 时区读取
zola.toml→[extra] timezone(当前Asia/Shanghai),经模板data-timezone注入前端
例:截止 06-23,则 6 月 23 日 22:59 仍可编辑,23:00 起变只读。
| 位置 | 行为 |
|---|---|
| 明细页锁定按钮 | 访客:🔒 只读;超期:只读(已过期);管理员且未超期:可锁定 / 解锁 |
| 列表剩余天数 | 截止日 23:00 前显示「今天」;当日 23:00 后显示「已截止」 |
公共逻辑:KanbanRules.isEditableWindow()、daysRemainingLabel()(static/js/kanban-rules.js);看板页 data-timezone 在 templates/kanban.html,列表页在 #kanban-week-list。
# zola.toml
[extra]
timezone = "Asia/Shanghai"参考: daudix.one · Umami 控制台
23 June 2026, 20:00 (CST)