parseCodexAuthJson function

ChatGptOAuthCredentials? parseCodexAuthJson(
  1. String contents
)

Parses the codex CLI's ~/.codex/auth.json session file (issue #1704): {"tokens": {access_token, refresh_token, id_token, account_id?}, "last_refresh": epochSeconds} — the shape a codex login (SSO tenants included) leaves behind. The expiry comes from the access token's own exp claim (the file carries none); a missing claim means unknown, and the runtime's reactive refresh covers it. Null when the shape is not a codex session.

Implementation

ChatGptOAuthCredentials? parseCodexAuthJson(String contents) {
  final Object? decoded;
  try {
    decoded = jsonDecode(contents);
  } on Object {
    return null;
  }
  if (decoded is! Map) return null;
  final tokens = decoded['tokens'];
  if (tokens is! Map) return null;
  String? field(String name) {
    final value = tokens[name];
    return value is String && value.isNotEmpty ? value : null;
  }

  final accessToken = field('access_token');
  final refreshToken = field('refresh_token');
  final idToken = field('id_token');
  if (accessToken == null || refreshToken == null || idToken == null) {
    return null;
  }
  final accountId = field('account_id');
  return ChatGptOAuthCredentials(
    accessToken: accessToken,
    refreshToken: refreshToken,
    idToken: idToken,
    accountId: accountId ?? _accountIdFromJwt(idToken),
    expiresAt: jwtExpClaim(accessToken),
  );
}