mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 09:20:22 +08:00
feat(oauth): 新增 Codex account_user_id 和 organizations 字段采集、展示与判重
- 从 Codex id_token claims 和 token_response 中提取 account_user_id 和 organizations - OAuth 判重逻辑改为优先按 account_user_id 匹配,支持同用户不同 Team 不误判 - 号池和 Provider 详情页展示组织标签、account ID 和 account_user_id - 前端重复的 OAuth identity 工具函数提取到 utils/oauthIdentity.ts - 后端重复的 normalize_oauth_organizations 提取到 core/provider_oauth_utils.py
This commit is contained in:
@@ -326,6 +326,21 @@ def _extract_codex_fields_from_claims(claims: dict[str, Any]) -> dict[str, Any]:
|
||||
if account_id:
|
||||
result["account_id"] = account_id
|
||||
|
||||
account_user_id = _first_non_empty_str(
|
||||
[
|
||||
auth.get("chatgpt_account_user_id"),
|
||||
auth.get("chatgptAccountUserId"),
|
||||
auth.get("account_user_id"),
|
||||
auth.get("accountUserId"),
|
||||
claims.get("chatgpt_account_user_id"),
|
||||
claims.get("chatgptAccountUserId"),
|
||||
claims.get("account_user_id"),
|
||||
claims.get("accountUserId"),
|
||||
]
|
||||
)
|
||||
if account_user_id:
|
||||
result["account_user_id"] = account_user_id
|
||||
|
||||
plan_type = _first_non_empty_str(
|
||||
[
|
||||
auth.get("chatgpt_plan_type"),
|
||||
@@ -357,6 +372,10 @@ def _extract_codex_fields_from_claims(claims: dict[str, Any]) -> dict[str, Any]:
|
||||
if user_id:
|
||||
result["user_id"] = user_id
|
||||
|
||||
organizations = auth.get("organizations")
|
||||
if isinstance(organizations, list) and organizations:
|
||||
result["organizations"] = organizations
|
||||
|
||||
return result
|
||||
|
||||
|
||||
@@ -509,3 +528,35 @@ async def enrich_auth_config(
|
||||
if enricher:
|
||||
return await enricher(auth_config, token_response, access_token, proxy_config)
|
||||
return auth_config
|
||||
|
||||
|
||||
def normalize_oauth_organizations(raw: Any) -> list[dict[str, Any]]:
|
||||
"""Normalize raw organizations list from OAuth auth_config into a clean list of dicts."""
|
||||
if not isinstance(raw, list):
|
||||
return []
|
||||
|
||||
result: list[dict[str, Any]] = []
|
||||
for item in raw:
|
||||
if not isinstance(item, dict):
|
||||
continue
|
||||
|
||||
normalized: dict[str, Any] = {}
|
||||
org_id = item.get("id")
|
||||
if isinstance(org_id, str) and org_id.strip():
|
||||
normalized["id"] = org_id.strip()
|
||||
|
||||
title = item.get("title")
|
||||
if isinstance(title, str) and title.strip():
|
||||
normalized["title"] = title.strip()
|
||||
|
||||
role = item.get("role")
|
||||
if isinstance(role, str) and role.strip():
|
||||
normalized["role"] = role.strip()
|
||||
|
||||
if "is_default" in item:
|
||||
normalized["is_default"] = bool(item.get("is_default"))
|
||||
|
||||
if normalized:
|
||||
result.append(normalized)
|
||||
|
||||
return result
|
||||
|
||||
Reference in New Issue
Block a user