Files
pure-note/README.md
T

96 lines
4.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Pure Note
极简高安全私人笔记 + 博客。最终交付 = **一个二进制程序 + 一个数据文件(目录)**:
无数据库服务、无缓存服务、无 Node 运行时、无外部依赖。
> 设计文档:[docs/design.md](docs/design.md)(v1.1);实施决策记录:[docs/decisions.md](docs/decisions.md)
## 功能
- **笔记**:Markdown CRUD、粘贴/拖拽图片上传(≤5MB、魔数校验、BLOB 入库去重)、公开/私有两态、置顶、标签
- **博客**:首页(置顶优先 + 分页 + 标签云)、详情(上一篇/下一篇)、标签页、RSS、sitemap、SEO meta 注入(仅公开内容)
- **管理**:单管理员口令登录(Argon2id)、会话 7 天滑动续期(CSRF 轮换保持不变)、防爆破限流(per-IP + per-账号)、改密
- **回收站**:删除 = 软删除,30 天内可恢复,`gc` 到期物理清除
- **运维**:`init` / `reset-password`(重设口令并吊销全部会话)/ `serve` / `backup`(在线一致快照)/ `gc`(默认 dry-run)/ `version`
## 快速开始
```bash
# 1. 构建单二进制(前端 + 后端)
make build
# 2. 初始化(设置管理员口令与站点标题)
./pure-note init
# 非交互:PN_ADMIN_PASSWORD=xxx PN_SITE_TITLE=yyy ./pure-note init
# 3. 启动
./pure-note serve --addr 127.0.0.1:8080
# 4. 访问
# 博客: http://127.0.0.1:8080/
# 管理后台:http://127.0.0.1:8080/admin
```
开发模式(本机调试,Cookie 允许非 Secure,仅限 loopback 监听):
```bash
./pure-note serve --dev --addr 127.0.0.1:8080
# 前端热重载(另开终端):
cd web && npm install && npm run dev # /api 代理到 127.0.0.1:8080
```
忘记口令(CLI 可达即具备服务器权限,可直接重设;重设后全部会话被吊销):
```bash
./pure-note reset-password
# 非交互:PN_ADMIN_PASSWORD=xxx ./pure-note reset-password
```
## 测试
```bash
make test # go vet + go test ./... + 前端 vitest
make smoke # 构建冒烟:起服务 → SPA 资源 200/MIME → meta 注入 → 可见性抽查
```
测试矩阵覆盖(§13):可见性矩阵(匿名 × 管理员 × {公开, 私有, 回收站, 不存在} × 全部出口)、
迁移与 user_version 守卫、登录限流 429、CSRF、上传魔数/去重、回收站生命周期、gc 宽限期、
slug 冲突策略、设置白名单(永不泄露口令哈希)、meta 注入转义。
## 部署(生产)
```bash
make linux # 产出 pure-note-linux-amd64
sudo cp pure-note-linux-amd64 /opt/pure-note/pure-note
sudo -u purenote ./pure-note init --data-dir /opt/pure-note/data
sudo cp deploy/pure-note.service deploy/pure-note-maint.{service,timer} /etc/systemd/system/
sudo systemctl enable --now pure-note pure-note-maint.timer
```
反向代理用 Caddy(自动 TLS),示例见 [deploy/Caddyfile](deploy/Caddyfile);
启动需带 `--behind-proxy`(取 X-Forwarded-For 最右条目)。
**升级 SOP**:`pure-note backup` → 停服 → 换二进制 → 起服(迁移自动执行;
库版本高于代码支持范围时拒绝启动,`--allow-newer` 显式放行)。
**恢复 SOP**:停服 → 删除 `data/pure-note.db-wal` 与 `-shm` → 以备份文件替换 `pure-note.db` → 起服。
## 架构
```
cmd/pure-note/ CLI(serve/init/reset-password/backup/gc/version)
internal/config/ 命令行解析(--dev loopback 守卫)
internal/store/ SQLite(modernc 纯 Go 驱动):迁移(user_version) + DAO + 备份 + gc
internal/auth/ Argon2id(PHC) + 随机 token
internal/markdown/ goldmark + bluemonday(RSS/meta 服务端渲染)
internal/middleware/ 安全头 / 日志 / 限流 / Origin 校验 / MaxBytes
internal/httpapi/ 路由与 handler(公共 / 认证 / 管理 / feed)
internal/webui/ go:embed 前端产物 + SPA fallback + index.html meta 注入
web/ React 19 + Vite + Tailwind 4 前端
deploy/ systemd 单元 ×3 + Caddyfile
```
安全要点(详见设计 §9):CSP `script-src 'self'`、CSRF 双保险(token + Origin 校验)、
`__Host-` Cookie、服务端统一可见性过滤(单一可信点)、图片并集可见性、
上传魔数校验拒绝 SVG、统一 404 防枚举、安全响应头全家桶。