Repository navigation
中转管理后台,没法看到用户的SECTL用户名 #10
Description
Activity
/oc 分析
Reacted by github-actionsgithub-actions commented
on Aug 31, 2026 on Aug 31, 2026 – with GitHub ActionsContributorMore actions最大步骤已到上限(MAXIMUM STEPS REACHED)
本次任务的分析工作已完成,因达到最大步骤限制,我以纯文本形式汇报调查结论,不再执行任何工具调用。
调查结论:中转管理后台看不到用户 SECTL 用户名(名称/邮箱为 "-")
一、完整数据流(客户端视角,来自本仓库
src/electron/main.ts)- SecAgent 客户端打开
https://sectl.cn/oauth/authorize(SECTL 平台 One Stop),用户登录后拿到 OAuth code。 - 客户端向
https://appwrite.sectl.cn/api/oauth/token换取 SECTL 平台的access_token(该接口只返回 token,不含用户资料)。 - 客户端把该 token 转发给中转服务:
POST {relayUrl}/auth/oauth,body 为{ access_token, client_id, platform_id }(main.ts第 1035、1077 行)。 - 中转服务应据此解析出用户资料,返回
{ access_token, user: { id, email, name } };客户端再写入SECTL_OFFICIAL_USER_ID、SECTL_OFFICIAL_EMAIL等环境变量(第 1080-1083 行)。
二、实测证据(只读探测公开端点)
- SECTL 平台为 Appwrite(
/v1/health返回"version":"1.9.6")。 - 平台公开了
GET https://appwrite.sectl.cn/api/oauth/userinfo接口,要求Authorization: Bearer <access_token>;无效 token 时返回{"error":"invalid_token","error_description":"Invalid access token"}——说明平台确实有能力按 token 返回用户资料。 - 中转服务
https://secagent-api.sectl.cn/auth/oauth是 FastAPI(缺参时报 Pydantic 校验错误{"detail":[{"type":"missing","loc":["body","access_token"],...}]})。
三、根因判断
中转服务的
/auth/oauth处理逻辑只从 SECTLaccess_token中解析出了 用户 id(例如解码 JWT 的$id/sub声明),而没有调用平台的GET /api/oauth/userinfo去取name/email,因此中转数据库里该用户只有 id,管理后台名称/邮箱显示 "-"。备选分支:若中转确实调用了 userinfo 但拿到的 name/email 仍为空,则需检查平台 userinfo 函数返回是否完整。由于中转服务与 One Stop 平台代码均为私有(不在任何公开 SECTL 仓库中),无法进一步确认。
四、修复建议(按归属划分)
- 中转服务(主责,私有 FastAPI):在
/auth/oauth中用收到的access_token调用GET https://appwrite.sectl.cn/api/oauth/userinfo(Authorization: Bearer ...),将返回的name/email随 user 一并 upsert 到用户表。这是最直接、最正确的修复点。 - SECTL One Stop 平台:确保
/api/oauth/userinfo对有效 token 返回完整{ id, name, email }。 - 本仓库(SecAgent 客户端):无需改动。客户端已正确转发 token,自身并不持有 name/email(
SECTL_OFFICIAL_SECTL_TOKEN在第 1081 行被有意清空);由客户端补传用户资料属于身份可信度反模式,不建议。
五、受影响文件
src/electron/main.ts(第 1000-1087 行):runSectlOAuthLogin/official:oauth-login两个 OAuth 登录实现,是问题链条中本仓库唯一相关代码。- 中转服务与 One Stop 平台代码不在本仓库,需由服务端维护者处理。
六、遗留事项
- 需要中转服务维护者确认
/auth/oauth是否调用过/api/oauth/userinfo,并完成服务端修复。 - 建议服务端修复后用真实账号验证中转管理后台能正确显示名称/邮箱。
- 由于修复点在私有服务,本次未提交任何代码改动。
- SecAgent 客户端打开
/oc 继续
Reacted by github-actionsgithub-actions commented
on Aug 31, 2026 on Aug 31, 2026 – with GitHub ActionsContributorMore actions分析结论:Bug 不在 SecAgent 客户端,而在中转服务
secagent-api的/auth/oauth处理逻辑上一轮分析被步数上限截断,这里给出补全并已实测验证的最终结论。
一、完整数据流(已核对本仓库
src/electron/main.ts)- SecAgent 客户端打开
https://sectl.cn/oauth/authorize,用户登录后拿到 OAuthcode。 - 客户端向
POST https://appwrite.sectl.cn/api/oauth/token换取 SECTL 平台的access_token(main.ts:1032/:1074)。该接口只返回 token,不含用户资料。 - 客户端把 token 转发给中转服务
POST {relayUrl}/auth/oauth,body 只有{ access_token, client_id, platform_id }(main.ts:1035/:1077)。 - 中转服务解析出用户资料,返回
{ access_token, user: { id, email, name } };客户端再写入SECTL_OFFICIAL_USER_ID/SECTL_OFFICIAL_EMAIL(main.ts:1080-1083)。
客户端不持有 SECTL 用户的 name/email,只能拿到中转服务返回的
user字段。所以中转数据库里没有 name/email,管理后台就显示-。客户端不是问题根源。二、实测验证(只读探测公开端点)
中转服务
https://secagent-api.sectl.cn(私有 FastAPI,OpenAPI title = "SecAgent Official Relay"):POST /auth/oauth的请求 schema 只有access_token(必填)、platform_id、client_id——没有也不接受客户端传来的 name/email,用户资料只能由中转服务自己从 token 里取。- 无效 token 时返回
{"detail":"SECTL OAuth 令牌已失效"},说明中转服务确实会拿着 token 去问 SECTL 平台验证,但显然只取回了用户 id,没有把 name/email 落库。 - 管理后台用户列表数据源是
GET /admin/api/users(未带管理员 token 时返回{"detail":"需要管理员登录"})。
SECTL One Stop 平台
https://appwrite.sectl.cn(私有,Appwrite 1.9.6 + FastAPI 代理层):- 公开了
GET /api/oauth/userinfo,要求Authorization: Bearer <access_token>;无效 token 返回{"error":"invalid_token","error_description":"Invalid access token"}——说明平台有按 token 返回用户资料的能力。 - 平台前端 bundle 里可见用户资料集合
user_data(Appwrite collection),字段包含user_id、email、user_name、github_username、github_id、permission、user_type、login_platforms等——平台侧本来就存着用户的 name/email。 POST /api/oauth/token对未知client_id返回{"error":"invalid_client","error_description":"Platform not found"},即平台是多客户端(多平台应用)OAuth 架构,中转服务通过client_id/platform_id定位验证方。
代码归属:中转服务与 One Stop 平台均为私有服务,不在任何公开 SECTL 仓库中;本仓库 SecAgent 客户端无此问题。
三、根因
中转服务
/auth/oauth收到 SECTLaccess_token后,只从中解析/验证出用户 id(例如解码 JWT 的userId/$id,或调平台只拿 id),没有调用平台的GET /api/oauth/userinfo去取name/email,因此中转用户表里该用户只有 id,管理后台名称/邮箱显示-。四、修复方案(按归属划分)
1. 中转服务(主责,私有 FastAPI,必须改)
在/auth/oauth里用收到的access_token调一次平台用户资料接口,再把 name/email upsert 进用户表并回传给客户端:@app.post("/auth/oauth") async def oauth_login(req: OAuthLoginRequest): # 1) 用 SECTL access_token 换取平台用户资料 userinfo = await call_platform( "GET", "/api/oauth/userinfo", token=req.access_token ) # 期望 { id, name, email } # 2) upsert 到中转用户表(现在只有 id,补齐 email/name) user = upsert_user( id=userinfo["id"], email=userinfo.get("email") or "", name=userinfo.get("name") or userinfo.get("user_name") or "", platform_id=req.platform_id, client_id=req.client_id, ) relay_token = issue_relay_token(user.id, req.platform_id, req.client_id) return {"access_token": relay_token, "user": {"id": user.id, "email": user.email, "name": user.name}}
2. SECTL One Stop 平台(配合确认)
确认GET /api/oauth/userinfo对有效 token 返回完整的{ id, name, email }(把 Appwrite 账号name与user_data集合的user_name/email关联返回)。如果该接口目前只回 id,需要平台补全。3. 本仓库 SecAgent 客户端(无需改动)
客户端已正确转发 token;它自身没有 name/email,由客户端补传用户资料属于身份可信度反模式,不建议。五、遗留事项
- 需要中转服务维护者确认
/auth/oauth是否调用过/api/oauth/userinfo,并按上面伪代码补上 userinfo 拉取 + 落库。 - 修复后用真实 SECTL 账号登录一次,再到中转管理后台确认用户列表能显示名称/邮箱。
- 由于修复点在私有服务,本仓库本次无代码改动。
- SecAgent 客户端打开
github-actions commented
on Aug 31, 2026 on Aug 31, 2026 – with GitHub ActionsContributorMore actions完成情况
上一轮分析被步数上限截断,本次继续补全并实测验证,已将最终结论发布到 issue #10:#10 (comment)
核心结论
Bug 不在 SecAgent 客户端,而在中转服务
secagent-api.sectl.cn(私有 FastAPI)的/auth/oauth处理逻辑。新增的实测证据(本轮补齐)
- 中转服务 OpenAPI(
https://secagent-api.sectl.cn/openapi.json,title = "SecAgent Official Relay"):POST /auth/oauth请求 schema 只有access_token(必填)+platform_id/client_id,不接受客户端传入 name/email——用户资料只能中转服务自己取。- 无效 token 返回
{"detail":"SECTL OAuth 令牌已失效"},证明中转服务会拿 token 去问平台验证,但显然只取了用户 id。 - 管理后台数据源是
GET /admin/api/users。
- SECTL One Stop 平台(Appwrite 1.9.6 + FastAPI 代理,均为私有):
- 公开了
GET /api/oauth/userinfo(Bearer token,无效返回invalid_token),即平台具备按 token 返回用户资料的能力。 - 平台前端 bundle 显示用户资料存在 Appwrite
user_data集合,字段含user_id、email、user_name等——平台侧本来就存着 name/email。 POST /api/oauth/token按client_id定位平台应用(invalid_client: Platform not found),确认多客户端 OAuth 架构。
- 公开了
- 公开仓库排查:中转服务与 One Stop 平台均不在任何公开 SECTL 仓库中,无法在此直接修改。
根因
中转服务
/auth/oauth只从 SECTL token 解析出用户 id,没有调用平台的GET /api/oauth/userinfo取 name/email 落库,导致中转用户表只有 id,管理后台名称/邮箱显示-。修复归属
- 中转服务(主责,必须改):
/auth/oauth内用 token 调GET /api/oauth/userinfo,把{id, name, email}upsert 进用户表并回传(评论中附 FastAPI 伪代码)。 - One Stop 平台(配合确认):确认 userinfo 对有效 token 返回完整
{id, name, email}。 - 本仓库 SecAgent 客户端(无需改动):客户端已正确转发 token,自身不持有 name/email,补传属于身份可信度反模式。
验证
git status干净;本仓库本次无代码改动(修复点在私有服务),因此未创建 PR。
- 中转服务 OpenAPI(
/oc 那不是创建私有服务的pr吗,
/oc 重试
我已经完成了完整的调查。工作区保持干净,无需代码改动。让我总结对用户问题的回答。
回答:是的,这个 bug 的修复应该在私有中转服务的仓库里提 PR——但当前 runner 无法访问那个仓库
你的问题:「那不是创建私有服务的 PR 吗?」
你说得对。 这个 issue 的真正修复点确实在私有中转服务(
secagent-api.sectl.cn,FastAPI,OpenAPI title = "SecAgent Official Relay")里,正确的做法就是给那个服务提一个 PR。但经过本轮核查,这个 runner 无法创建那个 PR,原因如下:一、为什么无法给私有服务提 PR
-
中转服务与 One Stop 平台不在任何可访问的 SECTL 仓库中。我核对了:
- SECTL org 全部 76 个公开仓库(逐个列表核对),没有任何一个是中转服务或 One Stop 平台;
- 工作流自动发现并授权给 runner 的仓库清单(
SECTL_SECAGENT_REPOSITORIES,共 19 个,全是*secagent*命名的客户端/插件/connector 仓库),也没有中转服务; - 本仓库
git submodule为空,src/下没有任何 FastAPI/中转服务代码。
-
这个 runner 只能对当前 checkout 的仓库(SECTL/SecAgent)推分支、建 PR。中转服务的仓库是私有的(或不在 GitHub 上),runner 无该仓库的 token/权限。
-
因此,我无法从这里替中转服务仓库创建 PR——这不是"不想做",而是环境上没有该仓库的访问权。
二、修复内容(给中转服务维护者,可直接落地)
中转服务
/auth/oauth目前只把 SECTL token 解析出用户 id落库,没有用 token 调平台的GET /api/oauth/userinfo取name/email。修复伪代码(已在 issue 评论中给出,这里再给一个更完整的版本):@app.post("/auth/oauth") async def oauth_login(req: OAuthLoginRequest): # 1) 用 SECTL access_token 向 One Stop 平台换取用户资料 userinfo = await call_platform( "GET", "/api/oauth/userinfo", headers={"Authorization": f"Bearer {req.access_token}"}, ) # 期望 { id, name, email }(平台 user_data 集合里本来就存着 email/user_name) # 2) upsert 到中转用户表,补齐 email/name(此前只有 id) user = upsert_user( id=userinfo["id"], email=userinfo.get("email") or "", name=userinfo.get("name") or userinfo.get("user_name") or "", platform_id=req.platform_id, client_id=req.client_id, ) # 3) 签发中转 token 并回传完整 user relay_token = issue_relay_token(user.id, req.platform_id, req.client_id) return {"access_token": relay_token, "user": {"id": user.id, "email": user.email, "name": user.name}}
配套确认项(One Stop 平台侧):
GET /api/oauth/userinfo对有效 token 需返回完整{ id, name, email }(此前已实测该接口存在、无效 token 返回invalid_token,说明平台具备按 token 回传用户资料的能力)。三、本仓库(SECTL/SecAgent 客户端)无需改动
- 客户端流程正确:
src/electron/main.ts:1035/1077把{ access_token, client_id, platform_id }转给中转/auth/oauth,自身不持有 name/email; - 中转返回的
user.name/email会写入SECTL_OFFICIAL_EMAIL等环境变量(main.ts:1082-1083); - 修复在中转服务侧,客户端改任何代码都解决不了管理后台显示
-的问题。
四、下一步建议
如果你(或 SECTL 成员)能把中转服务仓库接入这个 opencode 工作流(只需让它出现在仓库发现清单里,或在本 issue 里点名该仓库),我就能直接在那里提 PR 并落地修复。当前状态下,请把上面的补丁交给中转服务仓库的维护者应用,并让 One Stop 平台确认 userinfo 返回完整字段。
本次无代码改动:
git status干净,未创建 PR(因为修复点在 runner 不可访问的私有服务仓库)。-
User opencode-agent[bot] does not have write permissions
/oc 重试
Reacted by github-actionsAPIError: Insufficient Balance
/oc
Reacted by github-actions这个 issue 线程我已完整阅读。下面是总结:
Issue #10:中转管理后台看不到用户的 SECTL 用户名
报告人:PANDAJSR(2026-08-31)
现象:中转服务管理后台的用户列表里只能看到用户 id,名称和邮箱全部显示为 "-"。
分析过程与结论
数据流(已核对本仓库
src/electron/main.ts)- SecAgent 客户端打开
https://sectl.cn/oauth/authorize登录,拿到 OAuth code - 向
appwrite.sectl.cn换取 SECTL 平台access_token(仅含 token,无用户资料) - 客户端将
{ access_token, client_id, platform_id }转发给中转服务POST {relayUrl}/auth/oauth - 中转服务返回
{ access_token, user: { id, email, name } },客户端写入环境变量
实测发现(只读探测公开端点)
- 中转服务
secagent-api.sectl.cn是私有 FastAPI(OpenAPI title = "SecAgent Official Relay");/auth/oauth的请求 schema 只有 token,不接受客户端传 name/email - SECTL 平台为 Appwrite 1.9.6,公开了
GET /api/oauth/userinfo(Bearer token 校验),具备按 token 返回用户资料的能力;平台user_data集合中本就存有email、user_name等字段 - 中转服务拿到无效 token 会报"令牌已失效",证明它确实拿 token 去平台验证过
根因:中转服务
/auth/oauth只从 SECTL token 解析出用户 id,没有调用平台的GET /api/oauth/userinfo取回name/email落库,因此中转用户表只有 id,管理后台显示 "-"。Bug 归属:不在本仓库(SecAgent 客户端),而在私有中转服务;本仓库无代码改动、未创建 PR。
后续对话进展
- PANDAJSR 追问"那不是创建私有服务的 PR 吗" → agent 确认修复点确实应在私有中转服务仓库提 PR,但 runner 无法访问该私有仓库(SECTL org 全部 76 个公开仓库及授权给 runner 的 19 个 secagent 仓库中均无中转服务),故只能给出修复伪代码(用 token 调 userinfo → upsert email/name → 回传),建议维护者自行应用
- 后续两次
/oc 重试分别因 opencode bot 无写权限、API 余额不足而失败
当前状态
- Issue 仍为 OPEN
- 已有明确的根因定位与修复方案,但修复代码需由私有中转服务维护者落地(runner 无该仓库访问权),One Stop 平台侧需配合确认 userinfo 返回完整字段
- 待办:中转服务接入该工作流或由维护者手动应用补丁后验证管理后台能正确显示名称/邮箱
- SecAgent 客户端打开
/oc 你能否看中转服务的代码
Reacted by github-actionsI've done a thorough investigation. Here's my answer.
结论:这个 runner 看不到中转服务的源代码——它不是本仓库,也不在任何可访问的仓库里
我逐一核实了所有可能的来源,确认中转服务源码不在这个运行环境可达的任何仓库中:
1. 本仓库(SECTL/SecAgent)= 纯客户端
- 全部源码是 Electron/TypeScript 客户端(
src/electron/main.ts等),无任何 Python/FastAPI/中转服务代码,无 submodule。 - 客户端只是把
{ access_token, client_id, platform_id }POST 给中转服务的/auth/oauth(main.ts:1035/1077),自己并不持有 SECTL 用户资料。
2. SECTL org 全部 76 个仓库,均无中转服务
- 我拉取了 org 全量仓库列表(
type=all,含按创建时间排序),只有SecAgent、secagent-*插件/connector、以及无关项目,没有任何 relay / official-api 服务端仓库。 - 用中转服务的特征字符串做 GitHub 全局代码搜索(
"SecAgent Official Relay"、"secagent-api.sectl.cn"、"SECTL OAuth 令牌已失效"、/auth/oauth)→ 命中数全部为 0 或只命中本仓库客户端代码。
3. runner token 权限只覆盖当前仓库
- 工作流给 opencode 的是
github.token(contents/issue/pr: write),仅对 SECTL/SecAgent 有效。 - 实测其它 SECTL 仓库 API 返回
pull:false / push:false,即无法读取或推送代码,更无法在那里建 PR。
4. 我能"看到"的只有它的对外接口(只读探测)
我抓取了线上 OpenAPI(
https://secagent-api.sectl.cn/openapi.json,title = "SecAgent Official Relay",FastAPI),这确认并细化了此前结论:POST /auth/oauth的OAuthLoginRequestschema 只接受access_token(必填)+ 可选的platform_id/client_id,不接受客户端上传 name/email;- 也就是说:中转服务在
/auth/oauth里必须自己拿 token 去平台换用户资料,但它目前只落库了用户 id,没取回name/email→ 管理后台(GET /admin/api/users)就显示-。 - 修复只能发生在中转服务端(私有),runner 无代码修改条件。
怎么才能真正看到并修复中转服务代码
要让这个自动化流程能落地修复,需要二选一:
- 把中转服务仓库加入工作流可达范围:当前工作流按
SECTL_SECAGENT_GITHUB_TOKEN自动发现 SECTL org 下名字含 "secagent" 的仓库(opencode.yml第 35–47 行)。若中转服务仓库名含 secagent 且该 token 有访问权,它就会被自动纳入并允许建 PR; - 或把中转服务源码合入/镜像到本仓库某个可达分支,由我在这里修改。
在此之前,本次无法查看中转服务源码,也不会改动任何代码(工作树保持干净,无 PR 可建)。如果中转服务仓库已经可以让工作流访问(比如改了仓库名或授权了
SECTL_SECAGENT_GITHUB_TOKEN),请告诉我仓库名,我再实际去 clone、读代码并提修复。- 全部源码是 Electron/TypeScript 客户端(
/oc 请访问 SECTL/secagent-official-relay 的代码,定位并修复这个问题,在该仓库创建 PR
/oc 重试:请继续完成之前的任务;如果任务目标是其他仓库,请使用 GH_TOKEN 访问对应仓库并直接提交代码、创建 PR。
Reacted by github-actions已完成修复,PR 已创建在私有中转服务仓库:
**PR: https://github.com/SECTL/secagent-official-relay/pull/1**(`fix: persist SECTL username/email on OAuth login`)
这次真正拿到了中转服务代码,定位到根因并完成修复
中转服务
SECTL/secagent-official-relay的部署代码是app/main.py(Dockerfileuvicorn app.main:app)。根因:
POST /auth/oauth(app/main.py)用 SECTL access token 调平台/api/oauth/introspect校验身份,但该接口(One Stopauth-oauth-api的handleIntrospect)只返回{active, user_id, client_id, exp, iat},不含 email/name。于是identity.get("email")/get("name")/get("username")恒为空 →points_accounts里 username/email 全为空 → 管理后台/admin/api/users显示-。修复(仅改
app/main.py,新增app/test_auth_oauth.py测试):- 新增
sectl_userinfo():用同一 access token(Authorization: Bearer <token>)调平台GET /api/oauth/userinfo,取回完整资料email+name(= SECTLuser_name)。 oauth_login()在 introspect 后尽力拉取 profile 并写库(复用ensure_points_accountupsert),登录响应与 relay JWT 同时带上真实 email/name。- 降级策略:userinfo 拉不到(无
user:readscope、网络异常)时静默回退为只存 user_id,不会破坏登录。
验证:
py_compile通过;unittest全部 13 个测试通过(含新增 5 个:userinfo 成功/HTTP 错误/网络错误降级、oauth_login 落库与降级路径)。说明
- 已部署代码以
app/main.py为准;仓库根目录同名main.py是历史单文件快照(不含 telemetry 路由、不能独立运行),未在改动范围。 - 存量用户:上线后这些用户下一次 OAuth 登录时会自动补齐 username/email;新登录用户立即完整显示。
配套确认(One Stop 平台侧,非本次 PR)
- 需要确认 SecAgent 平台的 OAuth 客户端授权了
user:readscope(平台默认即为user:read),这样 relay 调/api/oauth/userinfo才能取到 email/name;若无则修复会静默降级、用户仍需重新登录一次。
- 新增
任务已完成。修复已经落地到私有中转服务仓库并创建了 PR。
交付结果
**PR:https://github.com/SECTL/secagent-official-relay/pull/1**(`fix: persist SECTL username/email on OAuth login
,状态 OPEN,基于master`)同时已在 issue 上发布总结评论:SECTL/SecAgent#10 评论
过程说明
GH_TOKEN环境变量带有 BOM 前缀(\ufeff),剥离后即为有效 token(gho_…),由此获得了SECTL/secagent-official-relay(私有)以及 SECTL org 内其它仓库的读取/写权限。定位到的根因
- 中转服务实际部署代码是
app/main.py(DockerfileCMD uvicorn app.main:app;线上 OpenAPI 含 telemetry 路由可佐证)。 POST /auth/oauth用 SECTL access token 调平台/api/oauth/introspect校验,但该接口(对照 One Stopauth-oauth-api/src/handlers/oauth.js的handleIntrospect)只返回{active, user_id, client_id, exp, iat},没有 email/name。- 因此
identity.get("email")/get("name")恒为空 →points_accounts的 username/email 落库为空 →/admin/api/users显示-(管理后台只能看到 user_id)。
修复(relay 侧,仅
app/main.py+ 新增测试)- 新增
sectl_userinfo():用同一 access token 以Authorization: Bearer <token>调平台GET /api/oauth/userinfo获取email+name(= SECTLuser_name)。 oauth_login()在 introspect 后尽力拉取 profile,经既有的ensure_points_accountupsert 写库,登录响应与 relay JWT 同时携带真实 email/name。- 尽力而为降级:userinfo 拉取失败(无
user:readscope / 网络异常)时静默回退为仅存 user_id,登录不被破坏。 - 新增
app/test_auth_oauth.py(5 个用例),覆盖 userinfo 成功 / HTTP 错误 / 网络错误降级,以及 oauth_login 的落库与降级路径。
验证
py_compile通过;python -m unittest discover -s app -p 'test_*.py'共 13 个测试全部通过。- 本仓库 SECTL/SecAgent 无需改动(客户端只转发 token,根因与修复均在服务端)。
遗留说明
- 存量空
username/email记录会在对应用户下一次 OAuth 登录时被 upsert 补齐;新登录用户立即完整显示。 - 建议确认 One Stop 平台侧为 SecAgent 客户端授权了
user:readscope(平台默认即为该 scope),否则修复会静默降级。
- 中转服务实际部署代码是
/oc 继续重试:请从之前中断的位置继续完成任务,使用已修复的跨仓库 Git 认证,完成代码修改和测试后直接提交新分支并创建 PR;如果目标是中转服务,请访问 SECTL/secagent-official-relay 并在那里创建 PR。
Reacted by github-actions任务已完成。跨仓库 Git 认证已可用,修复代码经核实并补充加固后已推送到中转服务仓库,PR 已更新。
本次运行做了什么
1. 验证了之前会话的成果确实存在:
SECTL/secagent-official-relay的 PR #1(fix/relay-oauth-user-profile,基于master)已包含根因修复,且仓库内 13 个测试全部通过。2. 使用修复后的跨仓库认证实际提交:环境注入的 git extraheader 仍带格式错误的凭据(
basic <raw-token>而非 base64,导致所有 git HTTPS 请求 400)。我改用GH_TOKEN构造正确的Authorization: basic头完成认证并成功 push(fec0a49..5099bc9)。3. 本轮新增代码修改(加固最佳努力语义,避免修复本身引入登录失败路径):
app/main.pysectl_userinfo():/api/oauth/userinfo返回非 JSON 的 2xx 响应时,response.json()会抛ValueError,从而让"尽力拉取资料"变成硬性登录失败,违背了该函数的降级契约。现已捕获解析错误并静默回退为仅存 user_id。app/test_auth_oauth.py:新增test_userinfo_returns_empty_on_non_json_success用例。
4. 测试验证:
py_compile通过;python -m unittest discover -s app -p 'test_*.py'全部 14 个测试通过。最终交付
**PR:https://github.com/SECTL/secagent-official-relay/pull/1**(`fix: persist SECTL username/email on OAuth login`)
- 状态:OPEN、MERGEABLE(已核实无冲突),head =
5099bc9 - 变更:
app/main.py(+37/-1)+app/test_auth_oauth.py(+92),共 2 个文件
根因回顾
中转服务
/auth/oauth用 SECTL access token 调平台/api/oauth/introspect只能拿到{active, user_id, ...},不含 email/name;原代码因此以空email/name落库points_accounts,管理后台/admin/api/users显示-。修复后/auth/oauth会用同一 token 调GET /api/oauth/userinfo取回资料并 upsert,登录响应与 relay JWT 同时携带真实姓名/邮箱。说明与遗留
- 本仓库 SECTL/SecAgent(客户端)无需改动:客户端只转发 token,根因与修复均在服务端。本地工作区保持干净。
- 存量空记录会在对应用户下一次 OAuth 登录时被补齐;新登录用户立即完整显示。
- 建议确认 One Stop 平台侧为 SecAgent OAuth 客户端保留了
user:readscope(平台默认即为该 scope);若无,userinfo 会静默降级,用户需重新登录一次。
/oc 继续执行:请从之前中断处恢复,先确认目标仓库和当前状态;完成代码修改、测试、提交和 PR。不要只输出方案。
Reacted by github-actions状态确认:修复已完成并再次验证,PR 就绪(本次为核对运行)
本次从上次中断处恢复后,核对了目标仓库与当前状态,结论:代码修改、测试、提交、PR 均已在
SECTL/secagent-official-relay完成,无需新增改动。1. 目标仓库与状态(已确认)
- 目标仓库:
SECTL/secagent-official-relay(私有中转服务,默认分支master=144a015)。 - 修复 PR:**https://github.com/SECTL/secagent-official-relay/pull/1**(`fix: persist SECTL username/email on OAuth login`)
- 状态:OPEN、无冲突(MERGEABLE)
- head:
5099bc9(fix/relay-oauth-user-profile),含 2 个提交(fec0a49+5099bc9),基于当前master尖端,落后 0 提交、领先 2 提交 - 变更:
app/main.py(+37/-1)、app/test_auth_oauth.py(+92)
2. 本轮新增的核实(此前缺失的一环)
上次只依据接口探测推断 userinfo 返回字段。本次直接 clone 了 平台侧 One Stop OAuth 服务源码
SECTL/auth-oauth-api核实契约:GET /api/oauth/userinfo(src/main.jshandleUserinfo,第 507-517 行)对有效 token 返回:{ user_id, email, name: user.user_name, github_username, permission, role, created_at, platform_id, login_time }。- 结论:relay 修复中的字段映射
profile.get("email")与profile.get("name")与平台真实返回完全一致,/auth/oauth登录时即可把 SECTL 用户名/邮箱写入points_accounts,管理后台/admin/api/users不再显示-。 - 查不到用户资料时平台返回
{ user_id, platform_id, login_time }(无 email/name),relay 的降级路径(仅存 user_id、登录不失败)与之匹配。
3. 验证结果
py_compile app/main.py通过;- 在仓库内新建 venv 按
requirements.txt安装依赖后运行python -m unittest discover -s app -p 'test_*.py':14 个测试全部通过(含sectl_userinfo成功/HTTP 错误/网络错误/非 JSON 2xx 降级 4 例与oauth_login落库/降级 2 例)。 - 该分支没有配置 CI checks(
gh pr checks为空),已本地完整跑通代替。
4. 现状与剩余动作
- 客户端仓库
SECTL/SecAgent无需改动(客户端只转发 token),工作区干净。 - 唯一剩余动作是维护者 review 并 merge PR feat: support plugin pre-rules #1。仓库 CI 会在合并到
master后自动部署中转服务(见部署工作流),存量用户将在下次 OAuth 登录时被自动补齐 username/email,新登录用户立即完整显示。
- 目标仓库:
完成情况
本次从上次中断处恢复后完成了核对与收尾。经确认,目标仓库的代码修改、测试、提交和 PR 此前已全部完成,本轮做的不是"只输出方案",而是完成了核实工作并补齐了此前缺失的关键证据。
一、确认目标仓库与当前状态
- 目标仓库:
SECTL/secagent-official-relay(私有中转服务),默认分支master=144a015。 - 修复 PR:https://github.com/SECTL/secagent-official-relay/pull/1 —
fix: persist SECTL username/email on OAuth login- 状态:OPEN、无冲突(MERGEABLE);head =
5099bc9(分支fix/relay-oauth-user-profile) - 2 个提交(
fec0a49落库用户资料 +5099bc9非 JSON 响应降级加固),基于当前 master 尖端,领先 2 提交 - 变更:
app/main.py(+37/-1)、app/test_auth_oauth.py(+92)
- 状态:OPEN、无冲突(MERGEABLE);head =
二、本轮实际完成的工作(代码/验证,非空谈)
- 修复了跨仓库 Git 认证:环境注入的
http.https://github.com/.extraheader把裸 token 当 basic auth(未 base64)导致所有 git HTTPS 请求 400。通过剥离GIT_CONFIG_COUNT/KEY_0/VALUE_0并注入正确的Authorization: basic <base64>,成功 clone/push 到私有仓库。 - 补齐此前缺失的契约证据:直接 clone 了平台侧
SECTL/auth-oauth-api(One Stop OAuth 服务源码),核实handleUserinfo(src/main.js:507-517)对有效 token 返回{ user_id, email, name: user_name, ... }—— 与 PR 中sectl_userinfo的字段映射完全一致,排除了"平台返回字段名不匹配"这一此前无法排除的风险。 - 运行测试:在仓库内建 venv 安装
requirements.txt后执行py_compile(通过)+unittest discover—— 14 个测试全部通过(该分支无 CI,以本地全量运行为准)。 - 发布核实结论到 issue:中转管理后台,没法看到用户的SECTL用户名 #10 (comment)
三、根因与修复回顾
平台
/api/oauth/introspect只返回{active, user_id, ...},无 email/name;原/auth/oauth因此以空值落库points_accounts,管理后台/admin/api/users显示-。修复后/auth/oauth用同一 access token 调GET /api/oauth/userinfo取回完整资料并 upsert,且拉取失败时静默降级不破坏登录。客户端SECTL/SecAgent无需改动,本地工作区干净。四、剩余动作
唯一剩余动作是 maintainer review 并 merge PR #1——合并到
master后仓库的 CI 部署工作流会自动发布中转服务;存量空记录会在对应用户下次 OAuth 登录时被补齐,新用户立即完整显示。- 目标仓库:
已完成审查并合并中转服务修复 PR #1: https://github.com/SECTL/secagent-official-relay/pull/1。审查未发现阻塞问题;本地在 PR 分支安装 requirements.txt 后运行 app 全量测试,14 个测试全部通过。修复会在 OAuth 登录时通过 /api/oauth/userinfo 获取并持久化 SECTL 用户名和邮箱,userinfo 失败时保持登录降级路径。








只能看到用户id,名称和邮箱全部是-
需要查看中转服务代码和SECTL平台(One Stop)如果你没有权限就看 https://sectl.cn/docs?doc=getting-started/README.md