docs: refresh public docs for current codebase, add SECURITY.md
- README: real counts (44 commands, 61 integration asserts, demo=25 records + 4 semesters + 7 attachments), add resume/assessment module features, env vars incl. LSKY, doc navigation table, done-roadmap items checked - docs/api.md: /auth/logout, admin users/demo-rebuild/sync-lsky routes, attachment thumb/download channels, profile_upsert top-key merge semantics, full footprint_list query reference, 44-command table - sync-server/README: replace stale ADMIN_TOKEN/X-Admin-Token admin section (actual is_admin Bearer model), add go-live checklist, backup note for WAL - CHANGELOG: add Unreleased section (resume/assessment modules, security fixes, perf tuning) - CONTRIBUTING: 61 asserts, security-sensitive-change guidance, perf baseline table, security issue routing - docs/SECURITY.md: new - report channel, threat model table, hardening summary, known tradeoffs - LICENSE: ensure MIT file matches README badge
This commit is contained in:
+31
-20
@@ -1,7 +1,7 @@
|
||||
# Footprints 自建同步服务
|
||||
|
||||
个人留痕系统的多端同步服务端。零 npm 依赖(Node 内置 node:sqlite),SQLite 单文件存储,
|
||||
专为单用户/小规模多设备设计。协议:行级 LWW(HLC 仲裁)+ seq 游标增量拉取。
|
||||
个人留痕系统的多端同步服务端。零 npm 依赖(Node 内置 node:sqlite),SQLite 单文件存储。
|
||||
协议:行级 LWW(HLC 仲裁)+ seq 游标增量拉取;每个用户一个独立 SQLite 档案库。
|
||||
|
||||
## 部署(Docker)
|
||||
|
||||
@@ -24,41 +24,51 @@
|
||||
docker compose up -d --build
|
||||
# 默认只绑定 127.0.0.1:8788,交给宿主上的反代;需要直连时改为 "8788:8788"
|
||||
|
||||
数据全部落在 `./data/`(SQLite 库 + 附件 Blob),备份 = 复制该目录。
|
||||
数据全部落在 `./data/`(SQLite 库 + 附件),备份 = 复制该目录(WAL 模式建议连同 `-wal`/`-shm` 一起拷,或先 `wal_checkpoint(TRUNCATE)`)。
|
||||
|
||||
- 首次部署 `REGISTER_ENABLED=true`,注册自己的账号后改为 `false` 再 `docker compose up -d` 关闭注册
|
||||
- 验证:curl https://footpr.linyux.cn/health 应返回 {"ok":true,...}
|
||||
### 上线检查清单
|
||||
|
||||
- [ ] `INVITE_CODE` 改掉示例默认值 `please-change-me`(或留空改用管理页动态码)
|
||||
- [ ] 第一个真实账号注册完成后 `REGISTER_ENABLED=false` 再 `docker compose up -d`
|
||||
- [ ] `MAX_USERS` 按需限额(0 = 不限)
|
||||
- [ ] `curl https://你的域名/health` 返回 `{"ok":true,...}`
|
||||
- [ ] `./data/` 已纳入备份计划
|
||||
|
||||
## 多用户
|
||||
|
||||
不止一人使用时,服务端天然按账号隔离数据(变更/附件/设备均挂 user_id),无需分库:
|
||||
服务端天然按账号隔离数据(每用户独立 `users/<uid>.db` 档案库,附件按用户子目录隔离),无需分库:
|
||||
|
||||
- 邀请码:`INVITE_CODE` 设置后,注册请求必须携带 `invite_code` 字段——把邀请码发给你信任的人即可
|
||||
- 邀请码:`INVITE_CODE` 设置后,注册请求必须携带 `invite_code` 字段——把邀请码发给你信任的人即可;动态码由管理员在「管理」页生成(支持备注/启停/删除/批量)
|
||||
- 名额:`MAX_USERS` 限制用户总数(0 = 不限),防滥用
|
||||
- 管理:设置 `ADMIN_TOKEN` 后,`GET /admin/users`(请求头 `X-Admin-Token`)可查看全部用户、设备数、记录数与附件占用
|
||||
- 管理:首位真实注册账号自动成为管理员(内置 demo 账号不占席位且永不为管理员);管理员登录后「管理」页可查看全部用户(设备数/记录数/附件占用)、删除用户(级联清理其图床文件/档案库/附件/会话)、重建演示账号
|
||||
- 客户端:各用户安装桌面应用或 PWA,登录自己的账号即得到独立档案;同一台电脑可切换多个账号(本地档案按账号隔离)
|
||||
- 数据安全:账号间完全隔离;管理员也只能看到元数据(用户名/设备数/存储占用),看不到档案内容
|
||||
|
||||
## 安全要点
|
||||
## 安全
|
||||
|
||||
- 必须经 HTTPS 访问(Caddy 自动证书);裸 HTTP 暴露公网不可接受
|
||||
- 数据(SQLite + 附件 Blob)全在 `./data/`,定期备份该目录即可
|
||||
- 服务端不解释业务字段;表间引用由客户端以 uuid 表达
|
||||
- 口令 scrypt 散列 + `timingSafeEqual` 校验;Bearer Token 365 天有效期,支持服务端吊销(`POST /auth/logout`)
|
||||
- 登录限速:同 IP + 同用户名连续失败 5 次冷却 10 分钟
|
||||
- 用户档案库仅用参数化 SQL;附件以 SHA-256 内容寻址命名(无路径可穿越)、哈希声明校验、100MB 单文件上限
|
||||
- 详见 [`../docs/SECURITY.md`](../docs/SECURITY.md)
|
||||
|
||||
## API
|
||||
|
||||
完整参考见 [`../docs/api.md`](../docs/api.md)。同步面速览:
|
||||
|
||||
| 方法 | 路径 | 说明 |
|
||||
|---|---|---|
|
||||
| GET | /health | 健康检查(Docker healthcheck 使用) |
|
||||
| POST | /auth/register | 注册 {username, password, device_name},返回 {token, device_id} |
|
||||
| POST | /auth/register | 注册 {username, password, invite_code, device_name},返回 {token, device_id} |
|
||||
| POST | /auth/login | 登录,同上;同名设备复用 device_id |
|
||||
| POST | /auth/logout | 吊销当前 Bearer Token |
|
||||
| GET | /auth/me | 当前用户信息 |
|
||||
| POST | /sync/push | 推送变更 {changes:[{table,row_uuid,op,hlc,data}]},返回 {accepted, stale, invalid} |
|
||||
| GET | /sync/pull?cursor=N | 增量拉取,返回 {changes, cursor, has_more} |
|
||||
| POST | /sync/attachment | 上传附件 {sha256,size,mime,file_name,data_b64},返回 {dedup} |
|
||||
| GET | /sync/attachment/:sha256 | 下载附件(内容寻址,跨设备去重) |
|
||||
| GET | /sync/status | 账号统计 |
|
||||
| POST | /api/footprint_list 等 | 业务命令层 `POST /api/<command>`(44 个命令,按用户隔离) |
|
||||
| POST | /api/attachment_download | 附件落盘下载(Content-Disposition 带原始文件名) |
|
||||
|
||||
鉴权:`Authorization: Bearer <token>`(/sync/* 全部需要)。
|
||||
鉴权:`Authorization: Bearer <token>`(除 /health /auth/register /auth/login 外全部需要)。
|
||||
|
||||
### 同步语义
|
||||
|
||||
@@ -69,14 +79,15 @@
|
||||
|
||||
## 目录
|
||||
|
||||
src/index.mjs HTTP 路由
|
||||
src/db.mjs SQLite schema 与连接
|
||||
src/auth.mjs 注册/登录/token(scrypt)
|
||||
src/index.mjs HTTP 路由(静态/认证/管理/同步/命令层)
|
||||
src/db.mjs Service 主库 schema(users/devices/tokens/invites)
|
||||
src/auth.mjs 注册/登录/token/登出(scrypt + 限速)
|
||||
src/sync.mjs push(LWW)/ pull(seq 游标)
|
||||
src/app-commands.mjs 桥接共用命令层(app/server/db.mjs)
|
||||
src/attachments.mjs 附件内容寻址存储
|
||||
|
||||
## 相关文件
|
||||
|
||||
- `docker-compose.caddy.yml`:与既有 Caddy 容器网络配合(推荐)
|
||||
- `docker-compose.yml`:独立部署(本机回环端口)
|
||||
- `Caddyfile.snippet`:Caddyfile 增量片段
|
||||
- `Caddyfile.snippet`:Caddyfile 增量片段
|
||||
|
||||
Reference in New Issue
Block a user