fix(codex-oauth): keep managed token in restore backup; fix failing tests

CI caught three test failures from the previous commit. Root cause: the Live
backup (proxy_live_backup) is local restore state that is replayed to
~/.codex/auth.json when proxy takeover ends, so it must contain the real auth to
restore a working login. Stripping it (the earlier "don't leak into backup"
change) broke restore and over-stripped a user's native login.

- Revert the backup auth stripping: remove sanitize_codex_backup_auth from the
  initial/strict snapshot paths and the forced auth={} in
  update_live_backup_from_provider_inner. The managed token belongs in the
  restore backup (the refresh_token is already persisted by CodexOAuthManager, so
  this is not a new exposure).
- Restore the ownership marker (account_id + access_token fingerprint) so backup
  cleanup can tell our managed write from a user's native `codex login` of the
  same account. extract now also tolerates the full-bundle shape (refresh_token +
  last_refresh) so it fingerprints ①'s refreshable writes. clear_codex_auth_in_backup
  and clear_codex_live_auth_for_managed_account use the marker again; the
  account_id-only helper is dropped.
- Fix the adopt unit test: adopt now invalidates the cached access token, so the
  test asserts the stored refresh_token/id_token were updated and the cache was
  cleared instead of reading it back through get_valid_token_bundle (which would
  trigger a network refresh).

Token stays out of the exported provider settings_config (backfill strip) — only
the local restore backup keeps it, matching pre-existing behavior.
This commit is contained in:
SaladDay
2026-07-01 15:43:49 +00:00
parent c72bd49213
commit d6ebc24cb3
5 changed files with 170 additions and 111 deletions
@@ -1379,14 +1379,19 @@ mod tests {
.unwrap();
assert!(changed, "rotated refresh_token should be adopted");
// 完整 bundle 反映新的 refresh_tokenaccess_token 仍取自缓存(无需联网)
let bundle = manager
.get_valid_token_bundle_for_account("acc-1")
.await
.unwrap();
assert_eq!(bundle.refresh_token, "rotated-rt");
assert_eq!(bundle.access_token, "access-cached");
assert_eq!(bundle.id_token.as_deref(), Some("id-2"));
// 存储里的 refresh_token / id_token 已更新为盘上(CLI 轮换后)的值
{
let accounts = manager.accounts.read().await;
let account = accounts.get("acc-1").expect("account present");
assert_eq!(account.refresh_token, "rotated-rt");
assert_eq!(account.id_token.as_deref(), Some("id-2"));
}
// 采纳后清掉了该账号的缓存 access_token,以便下次按新 refresh_token 重取
// (因此这里不再用 get_valid_token_bundle_for_account 断言——它会触发联网刷新)。
assert!(
!manager.access_tokens.read().await.contains_key("acc-1"),
"adopt should invalidate the cached access token"
);
// 未知账号不接管。
assert!(!manager