用户指南
这是给普通用户的 CircleChat 功能手册。管理员专属的治理功能见管理后台,接口细节见 API 参考。
注册与登录
- 打开根路径
/会自动跳到登录页login.html。 - 开放注册开启时,可以在登录页切到注册表单。注册需要:用户名、密码、邮箱。用户名允许中文 / 字母 / 数字 / 下划线 / 点 / 连字符,长度 2–20;密码强度要求 ≥8 位且同时包含数字、小写、大写、特殊符号。
- 注册提交后进入
pending(待审核)状态,审核通过前无法登录。登录时若账号还是 pending 或已被拒绝,会返回对应提示(403 类)。 - 登录失败连续 5 次,同 IP 会被限速 10 分钟,期间再试直接被拒。
- 如果账号开了两步验证(TOTP),第一次登录只拿回一个挑战码(
need2fa: true),要再去/api/twofa/verify校验 6 位动态码才真正建立会话。 - 顶部「语言」菜单可在 zh / en / ja 之间切换,选择记到
localStorage,下次自动沿用。
界面组成
聊天主界面 AppChat 是一块三栏布局:
- 左侧栏(Sidebar):会话列表(群组 / 私聊)、好友入口、群入口,顶部一个铃铛是站内信箱(有未读会红点)。
- 中间主区:当前会话的消息流 + 底部输入栏
InputBar。 - 右侧抽屉:群成员面板、聊天记录搜索、GitHub 仓库详情等,按需拉出。
界面还有几个常驻浮层:个人资料卡、我的资料、主题 / 强调色设置、好友搜索、建群对话框、消息上下文菜单、转发选择、合并转发查看器、图片 / 视频 / 文件查看器、信箱面板,以及强制改密的拦截层(账号被标记 mustChange 时一进来就先弹改密)。
主题和强调色在设置里调,加载时先 initTheme() 防止闪白。
私聊
- 发私聊前必须互为好友:在好友搜索里发出请求,对方接受后关系才建立。
- 私聊走 WebSocket 的
pm字段定向推给对方,非好友的私聊请求会被服务端静默拒绝(防陌生人骚扰)。 - 在线状态、正在输入提示都只对好友可见;对方不在线或隐身时看不到「正在输入」。
- 私聊支持「窗口抖动」(
shake),仅限私聊且 5 秒限频,纯属提醒作用。 - 好友备注:在侧栏好友项上点 ✎ 可给对方起个只有你能看到的别名,列表里显示备注,鼠标悬停仍能看到真实账号名。传空串可清除。
群组
群以 gid(16 位 hex)标识。可执行的操作:
- 创建群:填群名(可选简介),自己成为群主。
- 搜索 / 加入群:公开群直接
join;需要审核的群发request,群主 / 管理员在「入群申请」里通过或拒绝。 - 群主 / 管理员可:解散、重命名、设群公告(最长 500 字)、设群头像(只接受
http(s)链接)、移出成员、审核入群、转让群主、删除群文件。 - 群主不能退群(退群接口会拒绝 owner);转让群主时新群主必须是群成员。
- 群内多人实时聊天,群公告在群会话顶部以横幅展示。
群成员与权限
| 项目 | 谁可以 | 说明 |
|---|---|---|
| 设 / 取消管理员 | 群主 | 群主的角色不可改;管理员不能改别人的角色 |
| 禁言某个成员 | 群主、管理员 | 不能禁言群主,也不能禁言自己 |
| 全员禁言 | 群主、管理员 | 开启后只有群主与管理员能发言,其余成员输入区会提示「全员禁言」 |
| 移出成员 | 群主 | 管理员无此权限 |
| 审核入群申请 | 群主 | 同上 |
邀请入群与审批
- 任何群成员都能邀请别人,但群主可以开启「成员邀请需审批」:普通成员发起的邀请先由群主 / 管理员同意,才会发给被邀请人。
- 被邀请方若开了「允许任何人邀请我」(设置里),邀请会直接生效、自动入群,不需要再点接受。
- 收到的邀请在侧栏的「群邀请」入口里接受或拒绝;邀请人、被邀请人、管理者都可以撤销(拒绝)一条还没处理的邀请。
名字相关的三种设置
很容易混淆,这里一次说清:
| 名称 | 谁能看到 | 在哪设置 | 作用 |
|---|---|---|---|
| 群内昵称 | 同群所有人 | 群成员面板里改自己的 | 你在这个群里显示的名字(其他群不受影响) |
| 群备注 | 只有你自己 | 群会话里改 | 你给这个群起的别名,侧栏列表里替代群名显示 |
| 好友备注 | 只有你自己 | 侧栏好友项上的 ✎ | 你给某个好友起的别名,列表里替代账号名,悬停仍可看到真实账号 |
备注都是单向的:你给对方起的备注,对方看不到。
发消息
文本消息默认渲染 Markdown,并支持:
- 代码高亮(highlight.js,约 35 种常见语言,本地自托管
public/vendor/highlight.min.js;文件缺失时自动降级成纯文本)。 - 数学公式(MathJax)。
- 流程图 / 时序图等(Mermaid)。
- 引用回复:右键 / 长按消息选「引用回复」,发送时带上
replyTo,服务端校验引用必须同房间且未撤回。
消息类型共有六种:text / image / file / video / audio / merge(合并转发)。文本长度上限 4096 字符,合并转发上限 100 条 / 8000 字符。
上传文件
- 单文件上限 100MB。小于 5MB 走单次上传(
multipart);更大走分片断点续传,每片 5MB。 - 分片续传四步:
upload/init(开会话,带uploadId就是续传,返回已收分片,只需补传缺失片)→upload/chunk?uploadId=&index=(逐片)→upload/complete(合并落盘)→upload/abort(出错清理)。界面有分段进度条和总百分比,文件面板出现时消息自动上移。 - 上传不限类型,但图片按魔数嗅探归类;伪装成图片的非图片内容会被降级存成
.bin。相同内容按 sha256 去重,同名内容只落盘一次。 - 类型白名单 + 图片魔数校验 + 路径穿越防护在服务端做,非白名单或伪造会被拒。
- 上传文件按
FILE_TTL_DAYS(默认 15 天)过期清理硬盘文件,但消息记录保留并标file_expired,不会凭空消失成乱码。
表情回应
对任意一条未撤回的消息,可以加 / 切换 / 取消 emoji 回应(react)。同一人点同一个表情即取消;emoji 按码点截断,最多 4 个码点。回应变更会广播给房间其他人(reaction)。
撤回消息
- 可撤回自己的消息(
recall)。撤回是软删除:标记recalled / recalled_by / recalled_at,并清掉孤儿硬盘文件;消息占位仍在,只是内容被收起。 - 管理员可撤回任意人的消息,前端会标记为「管理员代删」(
admin: true)。 - 私聊里只有双方能撤回。
消息上下文菜单
消息上右键(移动端长按)弹出菜单,常用操作:
- 引用回复
- 表情回应
- 撤回(仅当具备相应权限)
- 举报:填原因提交,进入管理员待处理队列(见管理后台 · 举报与处罚)
- 转发 / 合并转发(多选多条后合成
merge转发) - 音视频可拖动进度、可下载
站内信箱
点顶部铃铛打开信箱,三个标签:
- 公告:系统级全局公告(管理员发布,全员可见)。
- 通知:面向个人的通知,比如处罚结果;可批量标记已读。
- 我的处罚:个人的历史处罚记录(禁言 / 封禁 / IP 封禁及期限)。
个人中心与账号安全
在个人中心可以:
- 改昵称、签名、头像(头像走上传,存成
/uploads/...)。 - 改密码(需要旧密码,
/api/pass)。 - 设在线 / 隐身 / 离开状态——这里改的是持久设置,实时状态也能通过 WebSocket
status消息即时切换(隐身对他人显示离线,away 是在线但离开)。 - 开启 / 关闭两步验证(TOTP):
twofa/setup生成密钥和otpauth://二维码(前端用lib/qrcode.ts画码,可直接扫进 Google Authenticator 等),twofa/enable绑定,twofa/disable关闭。 - 管理 API Key(「API Key」页签):给脚本 / 机器人签发受限凭据,详见下节。
API Key
- 创建时填备注名、勾选 scope、可选限速与有效期;明文形如
cc_<前缀>_<密钥>,只在创建那一刻显示一次,服务端只存哈希,忘了只能删掉重建。 - 调用方式:
Authorization: Bearer <key>或X-API-Key: <key>,与会话 Cookie 二选一。 - 常用 scope:
profile.read/write、friends.read/write、messages.read/send、groups.read/write/manage、files.upload、security、admin(仅管理员可授)。 - 限速默认 60 次/分钟(创建时可改,上限 6000),超限返回
429+Retry-After: 60。 - 可以改名、改 scope、改限速 / 有效期,或吊销(立即失效);
lastUsed能看出哪把 Key 还在用。 /api/keys*自身不接受 Key 调用(防提权),必须用会话 Cookie。- 完整字段与示例见 API Key。
账号安全
- 密码 SHA256 加盐存储;会话用 HttpOnly Cookie,默认 7 天。
- 若为管理员,部署后应尽快改掉内置
admin默认密码。 - 被禁言 / 封禁后,发消息会被服务端拦下并推
penalty帧,前端直接禁用输入框,不用前端自己判断。 - 登录失败连续 5 次同 IP 锁 10 分钟。
- API Key 泄漏的影响面等于「拿到哪些 scope 就等于能做什么」,怀疑泄漏先吊销,不用改密码。
聊天记录搜索
右侧抽屉的搜索面板走 GET /api/messages/search,只搜 text 类型,按关键字 LIKE 匹配(百分号 / 下划线已转义,避免被当成通配符)。结果按会话展示,点开可定位。
GitHub 仓库卡片
消息里贴 GitHub 仓库链接(如 https://github.com/owner/repo)时,前端识别后拉仓库卡片:主信息 + 最近提交,详情里还有贡献者 / 语言 / Release / 提交。owner/name 经 FULL_RE 正则校验防路径穿越;服务端的 GitHub 令牌只留服务端,结果缓存 10 分钟(失败缓存 1 分钟,遇限流返回旧数据),不会把令牌泄露到前端。
小提示
- 心跳每 30 秒一次,断线后如果会话已失效(内存会话随进程重启清空)会直接跳登录页,而不是无限重连。
- 整屏拖文件到聊天区即可上传;上传进度在输入栏上方显示。
- 设置面板里可调通知音、发送键(Enter / Ctrl+Enter)、强调色。