FlareStarter 文档
功能与集成

安全包:审计日志、两步验证、代登录

企业买家评估 SaaS 的三道必答题:出了事能不能追溯(审计日志)、账号能不能加固 (两步验证)、排障能不能留痕(代登录)。本页讲这三件事在模板里的实现与取舍。

审计日志:精选允许清单,不是 firehose

audit_log 只记安全敏感事件——20 余类,全部登记在 src/features/audit/audit.shared.ts 的 AUDIT_ACTIONS 目录里:

分组动作
账号安全(用户级)auth.sign_in / password_changed / password_reset / 2fa_enabled / 2fa_disabled / account_deleted
站点管理admin.impersonate_start/stop / user_banned / user_unbanned
组织生命周期org.created / deleted / member_added / member_removed / member_role_changed / invitation_sent / invitation_canceled
组织凭证与计费apikey.created / revoked / orgbilling.subscription_updated
终身买断席位seat.invited / invite_canceled / accepted

为什么不全量记录?全量日志属于可观测性(Sentry / Workers Logs),审计流水的价值在于 每一行都值得人看——精选清单让"审计页有一条新记录"本身就是信号。

新增一类事件,三步

  1. 把动作名加进 AUDIT_ACTIONS(点分命名:<域>.<事件>)。
  2. 两本字典(i18n/dictionaries/en.ts + zh.ts)各加一条 audit.act.<动作名,点转下划线> 标签——有 node 测试强制,漏一边直接红。
  3. 在发生变更的地方调 recordAudit(db, { action, actorId, ... })。

两条硬设计

  • recordAudit 永不 throw(内部 try/catch + console.error)——观察者不能弄坏被观察 的动作:审计写入失败,登录/邀请/撤销本身必须照常成功。
  • audit_log 故意没有外键。行要比 user/org 活得久(删号本身就是被审计的事件), 身份用冗余快照列(actorEmail、targetLabel)固化;查询侧再懒 join 当前用户表回填 没写快照的行。永不 UPDATE,append-only。

meta 是 JSON 字符串,序列化超过 2048 字节直接丢弃细节({"truncated":true})—— 审计行必须小而平,大对象请进业务表。

事件从哪里流入

分三路接线,都在"离变更最近的地方":

  • 登录统一由 better-auth 的 session.create databaseHook 覆盖(auth.server.ts)—— 邮箱密码、社交登录、2FA 二步全部经过建会话这一步,一处 hook 全收。会话上 impersonatedBy 非空即管理员代登录,记 admin.impersonate_start 而非普通登录。
  • 认证端点(改密/重置/2FA 开关/删号/封禁/停止代登录)经 hooks.after 的 AUDIT_PATH_ACTIONS 路径映射,成功才记。
  • 组织事件挂在 organization 插件的 organizationHooks 上;席位/订阅事件由各自的 server 函数与 webhook 分支落笔。

两个视图与保留期

  • 组织视图 /app/audit:org admin 可见(owner 计入),只看本组织的行。
  • 全局视图 /admin/audit:站点管理员专属(其余人 404),跨组织全量。

两者同一套游标分页(createdAt 倒序)与筛选;action 筛选值必须在目录内,过期书签里的 非法值静默降级为不过滤而不是报错。

保留期 180 天,由 每日 Cron 清理超期行——这是 append-only 表唯一的删除路径。要改期限调 AUDIT_RETENTION_DAYS;合规要求更长时,先导出再清。

两步验证(TOTP)

better-auth twoFactor 插件,账号页组件在 auth/components/two-factor-settings.tsx:

  • 开启是两步握手:enable({ password }) 只签发密钥和备份码(展示二维码), 标志位在第一次 verifyTotp 成功后才翻转——扫到一半放弃的 setup 永远不会把人锁在门外。
  • 备份码只展示一次(验证成功后),提供一键复制;丢了只能关掉重开。
  • 登录时进入 /two-factor 页:TOTP 码或备份码二选一,可勾选信任此设备跳过后续挑战。
  • 开/关都会落审计(auth.2fa_enabled / auth.2fa_disabled)。

代登录(Impersonation)

better-auth admin 插件自带:管理员在 /admin/users 一键以任意用户身份登录排障。 模板补的是全程留痕——起点由 session.create hook 识别 impersonatedBy 记 impersonate_start,终点经 /admin/stop-impersonating 端点记 impersonate_stop, 两行都带管理员与目标用户双方身份。没有留痕的代登录能力等于给自己埋雷,这两行是给 未来的你(和你的企业客户)看的。

On this page