Skip to content

feat: unify cross-provider identity and Resin affinity#695

Merged
chenyme merged 1 commit into
mainfrom
provide
Jul 18, 2026
Merged

feat: unify cross-provider identity and Resin affinity#695
chenyme merged 1 commit into
mainfrom
provide

Conversation

@chenyme

@chenyme chenyme commented Jul 18, 2026

Copy link
Copy Markdown
Owner

Summary

以 Grok Web 为中心建立 Web ↔ BuildWeb ↔ Console 弱关联,并为关联账号统一 Resin 粘性代理身份。

关联仅用于出口身份、来源展示与防止重复创建。各 Provider 的额度、健康、冷却、并发、模型能力、计费和路由状态仍完全独立。

同时完善 Grok Web 账号脚本状态记录,使批量任务只执行尚未记录完成的步骤。

Account linking

  • 新增 Web / Console 一对一关联模型。
  • 保留现有 Web / Build 关联关系。
  • 支持通过以下高可信条件自动关联:
    • Web 转换生成的 Console/Build 来源关系。
    • 唯一匹配的稳定上游 userId/sub
  • 多候选、关系冲突或身份不足时跳过,不覆盖已有关系。
  • Email 仅用于管理端展示和检索,不作为自动关联键或 Resin 身份。
  • 删除 Web 账号只删除关联记录,不删除对应 Build/Console 账号。

Identity synchronization

  • Web 和 Console 通过 /api/auth/session 补充:
    • Email
    • User ID
    • Organization ID
  • 兼容真实的嵌套 session 响应结构。
  • Session 请求复用统一 Web 出口链路:
    • 账号代理节点
    • Resin 粘性身份
    • User-Agent
    • Cloudflare Cookie
    • Chromium Client Hints
  • 身份成功同步一次后不再重复请求上游。
  • 同步失败不回滚导入、不改变账号健康和额度状态,缺少身份的账号可在后续同步时重试。
  • 同账号并发同步通过 singleflight 合并,避免重复访问上游。

Resin affinity

  • Web Profile 持久化匿名 egressIdentity
  • 关联的 Web、Build、Console 使用同一个 Resin {account}
  • 身份由 SSO 摘要派生,不保存或暴露原始 Token,也不使用 Email。
  • Token 更新不会导致已持久化的 Resin 身份轮换。
  • 未关联账号继续使用原有 Provider/账号身份回退逻辑。
  • 启动迁移从合法的历史 Web source_key 回填出口身份,不联网、不解密凭据、不扫描建立新关系。

Web account scripts

  • 持久化记录:
    • 服务协议接受时间
    • 生日设置时间
    • NSFW 开启时间
  • 单账号和批量账号脚本只执行尚未记录完成的步骤。
  • 已开启 NSFW 的历史账号自动视为生日已设置,避免重复请求触发生日锁定。
  • 上游返回“生日已经设置”时记录为成功状态。
  • NSFW 流程会在需要时自动先设置 20–40 岁的随机生日。
  • 同账号脚本串行执行,避免并发重复修改。

Admin UI

  • 账号列统一展示关联 Provider 图标。
  • 使用一个聚合 Tooltip 展示所有关联渠道及对应账号信息。
  • Web、Build、Console 页面均可反向查看关联关系。
  • 展示同步到的 Email 和 User ID。
  • ToS 和 NSFW 状态可在关联账号间统一展示:
    • ToS 使用粉色 Handshake
    • NSFW 使用黄色 VenusAndMars
  • NSFW Tooltip 显示:已开启 NSFW · 时间
  • 账号脚本弹窗统一使用 Handshake / Cake / VenusAndMars 图标。
  • 弹窗明确提示仅执行未记录的步骤。
  • 账号行和凭据续期信息调整为更紧凑的单行布局。

Persistence and migration

  • 新增 Web / Console 关联表及一对一唯一约束。
  • Web Profile 新增出口身份、ToS 和生日状态字段。
  • SQLite 与 PostgreSQL 使用一致的数据模型和约束。
  • 迁移可重复执行,并保留现有账号、凭据、额度、健康状态及 Web/Build 关系。
  • 删除账号时仅按外键规则清理关联数据,不跨 Provider 删除账号。

Performance

  • 账号选择阶段使用候选下标过滤,避免为每个请求复制完整账号结构。
  • 在 25ms 窗口内合并相同候选池的并发快照读取。
  • 并发快照只参与候选排序,最终容量仍由原子 Acquire 校验,不会突破账号并发上限。
  • 出口客户端缓存增加:
    • 30 分钟空闲回收
    • 4096 个客户端上限
    • 最久未使用淘汰
  • 保留每个 Resin 身份独立的连接池,避免高并发下频繁重建连接。

Compatibility

  • 保留原有单关联 API 字段,新增统一的 linkedAccounts[]
  • 未关联账号的路由和出口行为不变。
  • 不合并不同 Provider 的额度、可用性、冷却、并发、模型能力或计费数据。
  • 身份同步和关联失败不影响正常推理请求。

Test plan

  • go test ./... -count=1
  • go vet ./...
  • go build ./cmd/grok2api
  • pnpm lint
  • pnpm build
  • git diff --check
  • SQLite 迁移与重复初始化测试
  • PostgreSQL schema、唯一约束与级联关系测试
  • Web / Build / Console 唯一身份关联与冲突场景测试
  • Resin 身份继承、Token 更新及未关联账号回退测试
  • Session 响应解析、统一出口及 Client Hints 测试
  • ToS、生日、NSFW 状态记录与重复执行跳过测试
  • 高并发候选选择与出口客户端缓存测试

@chenyme chenyme linked an issue Jul 18, 2026 that may be closed by this pull request
3 tasks
@chenyme
chenyme merged commit 6a8d3ce into main Jul 18, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: 打通三个 Provider 之间的账号联系

1 participant