accounts/docs/api/overview.md
2026-04-14 16:32:15 +08:00

12 KiB
Raw Blame History

API Overview / API 总览

中文

页面作用

本页描述 accounts.svc.plus 当前 HTTP 面的总边界:

  • 路由族如何划分。
  • 每组路由由哪些 api/*.go 文件拥有。
  • 认证链路如何叠加。
  • 成功与失败响应的公共形状是什么。

参数、返回体字段和逐接口依赖关系请继续阅读:

基础路由族

路由族 典型路径 主要 owner file 说明
健康与版本 GET /healthz GET /api/ping api/api.go 活性检查与运行时镜像版本信息。
公共认证入口 /api/auth/register /api/auth/login /api/auth/oauth/* api/api.go 注册、登录、邮箱校验、OAuth 跳转、JWT refresh。
会话保护认证面 /api/auth/session /api/auth/xworkmate/* /api/auth/subscriptions api/api.go api/xworkmate.go api/config_sync.go api/stripe.go 以 session token 为主路径的控制面接口。
Auth 作用域下的管理员接口 /api/auth/admin/* api/admin_users_metrics.go api/admin_users.go api/admin_sandbox.go api/admin_assume.go api/homepage_video.go 给 dashboard / BFF 使用的管理员接口。
公共 /api/admin/* 管理面 /api/admin/users/metrics /api/admin/traffic/* api/admin_users_metrics.go api/admin_agents.go api/accounting.go 与前端约定的管理员根路径。
内部服务接口 /api/internal/* api/internal_public_overview.go api/internal_sandbox_guest.go api/internal_network_identities.go api/accounting.go 仅供受信任服务调用,走 internal service token。
Agent 控制接口 /api/agent-server/v1/* api/agent_server.go api/user_agents.go 给 agent 或用户控制台提供节点与客户端视图。
账户读面 /api/account/* api/accounting.go 使用量、账单、策略快照读取。
Legacy alias /api/agent/nodes api/user_agents.go 旧路径别名,规范路径是 /api/agent-server/v1/nodes

认证模型

1. Session first

当前控制面的主事实来源是 API 进程内 session store

  • 登录、邮箱验证成功、密码重置确认成功、OAuth callback 都会签发 session token。
  • token 同时通过响应体字段 token 返回,并通过 xc_session cookie 下发。
  • 多数业务 handler 最终都调用 handler.lookupSession / handler.requireAuthenticatedUser 做真实鉴权。

2. Optional JWT middleware

RegisterRoutes 只在 tokenService != nil 时给 /api/auth 的保护组和 /api/admin 组叠加:

  • auth.TokenService.AuthMiddleware()
  • auth.RequireActiveUser(h.store)

因此真实行为是:

  • auth.enable 关闭时,业务仍按 session 主路径工作。
  • auth.enable 打开时,部分路由会先经过 JWT middleware然后在 handler 内继续读取 session。
  • 这就是为什么文档统一把当前模式描述为“session-first, JWT-optional”。

3. Internal service token

/api/internal/* 统一使用 auth.InternalAuthMiddleware()

  • 读取 Authorization: Bearer <token>
  • 与环境变量 INTERNAL_SERVICE_TOKEN 比较
  • 失败时直接返回简化错误 JSON

4. Agent token

/api/agent-server/v1/users/api/agent-server/v1/statusagentserver.Registry.Authenticate

  • 读取 Authorization: Bearer <agent-token>
  • 允许共享 token + X-Agent-ID / agentId 解析具体节点身份
  • 认证成功后进入 Registrystore.NodeHealthSnapshot 更新链路

响应约定

类别 典型形状 说明
通用成功 {"message": "...", ...} 或领域对象 JSON 大多数 handler 直接输出业务对象,不包统一 envelope。
会话成功 {"token": "...", "expiresAt": "...", "user": {...}} 登录、邮箱验证、密码重置确认、MFA 完成等都会返回 session 信息。
通用失败 {"error":"code","message":"..."} respondError 统一组装,是最常见错误形状。
简化失败 {"error":"..."} 多见于 agent/internal/simple GORM handlers。
Agent DTO agentproto.ClientListResponse204 No Content /users 返回结构化 DTO/status 成功时无响应体。

关键 handler owner map

文件 负责的接口面
api/api.go 注册、登录、session、OAuth、MFA、订阅、权限矩阵、/healthz/api/ping
api/xworkmate.go XWorkmate profile、secret locator、Vault-backed secret 读写、tenant bootstrap。
api/config_sync.go /api/auth/sync/config/api/auth/sync/ack
api/stripe.go Stripe checkout、portal、webhook。
api/admin_users_metrics.go /api/admin/* 路由注册、用户指标权限控制。
api/admin_users.go 创建用户、暂停/恢复、删除、renew uuid、黑名单。
api/admin_agents.go 管理面 agent 状态聚合。
api/accounting.go /api/account/*/api/admin/traffic/*、内部策略与心跳。
api/agent_server.go Agent 拉取 client 列表、上报状态。
api/user_agents.go 用户/控制台读取节点列表,含 sandbox 特判。
api/homepage_video.go 公共首页视频与管理员首页视频配置。
api/admin_sandbox.go Sandbox binding 读写。
api/admin_assume.go Root 假扮 sandbox 会话。
api/internal_* 内部 public overview、sandbox guest、network identities。

当前实现注意点

  1. /api/auth/password/reset/api/auth/password/reset/confirm 被挂在 authProtected 组下,但核心业务逻辑本身仍是邮箱 / token 驱动;启用 JWT middleware 后会多一层前置校验。
  2. /api/auth/sandbox/binding 既接受正常会话,也接受内部服务 token因为 Console Guest/Demo 需要在无本地浏览器状态时读取绑定信息。
  3. /api/agent-server/v1/nodes 没有挂在 token middleware 下,而是在 handler 内自行解析 session 或内部服务身份。
  4. /api/pingversioncommittag 来自运行时 IMAGE 环境变量解析结果,而不是 Git 本地状态。

English

What This Page Covers

This page defines the current HTTP surface of accounts.svc.plus:

  • how route families are split,
  • which api/*.go files own them,
  • how authentication layers stack,
  • and what the shared success / error shapes look like.

For endpoint-level parameters, response fields, and dependency wiring, continue with:

Route Families

Route family Example paths Main owner files Purpose
Health and version GET /healthz, GET /api/ping api/api.go Liveness and runtime image-derived version metadata.
Public auth entrypoints /api/auth/register, /api/auth/login, /api/auth/oauth/* api/api.go Registration, login, email verification, OAuth redirects, JWT refresh.
Session-protected auth surface /api/auth/session, /api/auth/xworkmate/*, /api/auth/subscriptions api/api.go, api/xworkmate.go, api/config_sync.go, api/stripe.go Primary control-plane APIs built around session tokens.
Auth-scoped admin APIs /api/auth/admin/* api/admin_users_metrics.go, api/admin_users.go, api/admin_sandbox.go, api/admin_assume.go, api/homepage_video.go Admin APIs used by the dashboard / BFF.
Public /api/admin/* admin root /api/admin/users/metrics, /api/admin/traffic/* api/admin_users_metrics.go, api/admin_agents.go, api/accounting.go Frontend-facing admin root path.
Internal service APIs /api/internal/* api/internal_public_overview.go, api/internal_sandbox_guest.go, api/internal_network_identities.go, api/accounting.go Trusted service-to-service APIs protected by the internal service token.
Agent control APIs /api/agent-server/v1/* api/agent_server.go, api/user_agents.go Node and client views for agents and the control console.
Account read models /api/account/* api/accounting.go Usage, billing, and policy snapshot reads.
Legacy alias /api/agent/nodes api/user_agents.go Backward-compatible alias for /api/agent-server/v1/nodes.

Authentication Model

1. Session-first

The primary control-plane fact source is the process-local session store:

  • login, email verification success, password reset confirmation, and OAuth callback all issue a session token,
  • the token is returned in the body as token and also set as the xc_session cookie,
  • most business handlers ultimately call handler.lookupSession or handler.requireAuthenticatedUser.

2. Optional JWT middleware

RegisterRoutes adds these middlewares to the protected /api/auth group and the /api/admin root only when tokenService != nil:

  • auth.TokenService.AuthMiddleware()
  • auth.RequireActiveUser(h.store)

So the actual runtime behavior is:

  • when auth.enable is off, business routes still work through the session-centric path,
  • when auth.enable is on, some routes first pass JWT middleware and then still load the session in the handler,
  • which is why the current system should be described as session-first and JWT-optional.

3. Internal service token

/api/internal/* is guarded by auth.InternalAuthMiddleware():

  • it reads Authorization: Bearer <token>,
  • compares it to INTERNAL_SERVICE_TOKEN,
  • and returns simplified JSON errors on failure.

4. Agent token

/api/agent-server/v1/users and /api/agent-server/v1/status authenticate through agentserver.Registry.Authenticate:

  • they read Authorization: Bearer <agent-token>,
  • support shared tokens plus X-Agent-ID / agentId to resolve the concrete node,
  • and then enter the registry and node-health persistence pipeline.

Response Conventions

Category Typical shape Notes
Generic success {"message": "...", ...} or a domain object Most handlers return domain JSON directly instead of a global envelope.
Session success {"token": "...", "expiresAt": "...", "user": {...}} Returned by login, email verification, password reset confirmation, MFA completion, and similar flows.
Standard failure {"error":"code","message":"..."} Produced by respondError; this is the most common error envelope.
Simplified failure {"error":"..."} Common in internal / agent / simple GORM-backed handlers.
Agent DTOs agentproto.ClientListResponse, 204 No Content /users returns a typed DTO, while /status returns no body on success.

Handler Ownership Map

File Owned API surface
api/api.go Registration, login, session, OAuth, MFA, subscriptions, permission matrix, /healthz, /api/ping.
api/xworkmate.go XWorkmate profile, secret locator metadata, Vault-backed secret mutation, tenant bootstrap.
api/config_sync.go /api/auth/sync/config and /api/auth/sync/ack.
api/stripe.go Stripe checkout, portal, and webhook handling.
api/admin_users_metrics.go /api/admin/* route registration plus metrics permission guards.
api/admin_users.go User creation, pause/resume, delete, renew UUID, blacklist operations.
api/admin_agents.go Aggregated admin agent status view.
api/accounting.go /api/account/*, /api/admin/traffic/*, internal policy reads, node heartbeat ingest.
api/agent_server.go Agent client-list reads and status reports.
api/user_agents.go User / console node list reads, including sandbox-specific behavior.
api/homepage_video.go Public homepage video reads plus admin homepage video settings.
api/admin_sandbox.go Sandbox binding reads and writes.
api/admin_assume.go Root-only sandbox assume session flow.
api/internal_* Internal public overview, sandbox guest, and network identity reads.

Important Current Behaviors

  1. /api/auth/password/reset and /api/auth/password/reset/confirm are mounted under the protected auth group even though their business logic is email / reset-token driven; enabling JWT middleware adds an extra precondition.
  2. /api/auth/sandbox/binding accepts either a normal session or the internal service token because the Console Guest/Demo flow must read binding state without relying on browser-local state.
  3. /api/agent-server/v1/nodes is intentionally outside token middleware and resolves sessions or trusted internal-service identity inside the handler.
  4. /api/ping derives version, commit, and tag from the runtime IMAGE environment variable, not from local Git state.