cents/docs/账号与权限.md

79 lines
3.0 KiB
Markdown
Raw Permalink 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.

# 账号与权限
## 账号创建
Cents 不开放注册。管理员生成一条应用邀请:
```bash
PUBLIC_ORIGIN=https://cents.example.com npm run bootstrap --workspace @cents/api
```
应用邀请使用 256 位随机 `key`,数据库只保存 SHA-256 摘要。链接固定 7 天过期并且只能创建一个账号。
开发环境可以直接添加用户:
```bash
npm run user:add -- '用户名' '至少8位的密码'
```
生产环境通过 Docker Compose 在 API 容器内运行 npm 脚本,宿主机不需要安装 Node.js 或 npm
```bash
docker compose -f compose.pro.yaml exec api \
npm run user:add -- '用户名' '至少8位的密码'
```
用户与个人账本在同一数据库事务内创建;用户名已存在或任一步失败时都不会留下半成品数据。
新用户打开 `/invite?key=...` 后填写姓名和密码:
- 用户 ID 由服务端生成 UUID。
- 姓名同时作为登录名,忽略首尾空格和大小写后必须唯一。
- 密码长度为 8 至 128 个字符。
- 密码使用 Argon2id 保存,参数为 19 MiB 内存、2 次迭代、并行度 1。
- 新账号自动获得唯一的“个人账本”,并成为 owner。
- 个人账本不能分享或加入其他成员,每笔账目都会由服务端强制关联到其所有者的个人账本。
已登录用户打开应用邀请时直接返回应用,不创建账号,也不消费邀请。
## 登录会话
登录成功后,服务端生成 256 位随机会话凭证,并通过 Cookie 返回:
- `HttpOnly`:前端脚本不能读取。
- `Secure`:生产环境只允许 HTTPS 发送。
- `SameSite=Lax`:限制跨站携带。
- `Path=/`:不设置 `Domain`
数据库只保存会话凭证的 SHA-256 摘要。浏览器不保存原始密码。会话最长设置为浏览器普遍支持的 400 天,并在每次有效访问时滚动续期,因此正常使用时会一直保持登录。
登录接口使用统一的“姓名或密码错误”提示,并设置更严格的请求限速。
## 密码重置
不提供公网“忘记密码”接口。管理员登录宿主机后执行:
```bash
NEW_PASSWORD='新的密码' npm run password:reset --workspace @cents/api -- '用户姓名'
```
重置成功后,该用户的所有旧会话会立即撤销,需要使用新密码重新登录。
## 邀请类型
应用邀请与账本邀请是两个不同的能力:
- `/invite?key=...`:创建应用账号,不加入别人的账本。
- `/join-ledger?key=...`:把已经登录的用户加入指定账本。
未登录用户打开账本邀请会先进入登录页,登录成功后返回原邀请继续操作。
## 权限
- 用户只能访问自己是成员的账本。
- `owner` 可以修改账本设置并创建账本邀请。
- 个人账本名称固定,且不能创建账本邀请。
- `member` 可以查看和记账,但不能创建邀请或修改账本设置。
- 服务端在每次请求时查询成员关系,不依赖前端隐藏按钮。
- 所有写请求检查 `Origin`API 同时启用安全响应头和请求限速。