Skip to content

fix(oauth): guard expires_in parsing against NaN across token responses - #1418

Open
Bruce-Yii wants to merge 3 commits into
lidge-jun:devfrom
Bruce-Yii:fix-token-expires-in-guard
Open

fix(oauth): guard expires_in parsing against NaN across token responses#1418
Bruce-Yii wants to merge 3 commits into
lidge-jun:devfrom
Bruce-Yii:fix-token-expires-in-guard

Conversation

@Bruce-Yii

@Bruce-Yii Bruce-Yii commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #1417: OAuth token responses with an invalid expires_in (missing, NaN, string, negative, or numeric-overflowing) produce a NaN/Infinity/past expiry in stored credentials. NaN <= x is always false and Infinity never expires, so such credentials break the refresh loop. This is the token-response counterpart of the already-merged #1369 fix — same data-quality class, remaining at the upstream parse sites.

Root cause

  • src/oauth/anthropic.tsDate.now() + data.expires_in * 1000 — missing expires_inundefined * 1000 = NaN
  • src/oauth/kimi.tstypeof !== "number" check lets NaN through (typeof NaN === "number")
  • src/oauth/chatgpt.ts?? 3600 only guards null/undefined; NaN or a numeric string passes through
  • src/codex/account-store.ts — no validation at all

Additional failure modes found in review:

  • Overflow (CodeRabbit Major): a finite-but-huge expires_in (e.g. Number.MAX_VALUE) passes Number.isFinite but overflows to Infinity once multiplied by 1000 — the computed expiry must also be guarded.
  • Negative (maintainer review): a finite negative expires_in produces a finite already-past expiry, silently bypassing the malformed-response fallback.

Changes

All four sites now require typeof === "number" && Number.isFinite(...) && >= 0 (falling back to a 3600s default so the credential stays refreshable), plus a guard on the computed expiry timestamp:

  1. src/oauth/anthropic.tscredsFrom(): non-finite/negative/overflowing → 3600s default.
  2. src/oauth/kimi.tsparseTokenPayload(): non-finite, negative, or overflowing expires_in rejected as malformed.
  3. src/oauth/chatgpt.tscredsFromToken(): non-finite/negative/overflowing → 3600s default.
  4. src/codex/account-store.ts — refresh path: non-finite/negative/overflowing → 3600s default.

Per the lazy-refresh contract established in #1369, this change only guards at parse/adoption time — it does not touch getLoginStatus or expiry comparison logic.

Tests

  • tests/chatgpt-token-expiry.test.ts (new): non-finite, string, overflowing, and negative expires_in all fall back to exactly ~3600s (tolerance 30s)
  • tests/anthropic-hardening.test.ts: non-finite, overflowing, and negative → ~3300s (3600s minus the 5-minute skew)
  • tests/codex-account-store.test.ts: non-finite, overflowing, and negative → persisted expiresAt ~3600s
  • tests/kimi-oauth-identity.test.ts: non-finite, overflowing, and negative expires_in all rejected

Verification (head 355b69e5, rebased onto dev 9c05134):

  • Targeted: 55/55 pass
  • OAuth + anthropic + account-store suite: 414/414 pass
  • bun x tsc --noEmit → clean
  • hygiene: passed (maintainer-sponsored applied)
  • cross-platform CI: green (confirmed by maintainer review on exact head)
  • mergeable_state: clean

Fixes #1417

Review readiness checklist

This PR stays in draft until every box below is ticked. Tick all four boxes once the requirements are met:

  • All CI tests are green on my local testing.

  • I pushed my PR to the latest dev commit.

  • I resolved all correct Codex and CodeRabbit findings.

  • My PR is ready for review.

@github-actions github-actions Bot added the intake: hygiene-blocked Deterministic PR hygiene checks failed label Aug 10, 2026
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Deterministic hygiene checks failed.

  • unsponsored_surface — This changes an authentication, workflow, release-automation, or dependency surface. MAINTAINERS.md requires security review for these; ask a maintainer to apply maintainer-sponsored once they have reviewed it. Paths: src/oauth/anthropic.ts, src/oauth/chatgpt.ts, src/oauth/kimi.ts.

@github-actions github-actions Bot added bug Something isn't working review-ready labels Aug 10, 2026
@github-actions

github-actions Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

✅ READY

  • all PR quality gates passed; the review readiness checklist is complete.

Review readiness checklist

  • ✅ All CI tests are green on my local testing.
  • ✅ I pushed my PR to the latest dev commit.
  • ✅ I resolved all correct Codex and CodeRabbit findings.
  • ✅ My PR is ready for review.

4/4 boxes ticked.

This pull request has been marked Ready for Review.
The review-ready label marks this PR as ready; review automation runs independently. If no CodeRabbit review appears, comment @coderabbitai review to request one.
Maintainers notified: @lidge-jun @Ingwannu @Wibias

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The change validates OAuth expires_in values in Codex, Anthropic, ChatGPT, and Kimi token flows. Invalid or overflowing values use a one-hour fallback or are rejected. Regression tests cover these behaviors.

Changes

OAuth expiry hardening

Layer / File(s) Summary
Validate token expiry values
src/codex/account-store.ts, src/oauth/anthropic.ts, src/oauth/chatgpt.ts, src/oauth/kimi.ts
Codex, Anthropic, and ChatGPT use 3600 seconds when expires_in is invalid, non-finite, negative, or produces an infinite timestamp. Kimi rejects invalid values and overflowing timestamps during payload parsing.
Cover invalid expiry responses
tests/anthropic-hardening.test.ts, tests/chatgpt-token-expiry.test.ts, tests/codex-account-store.test.ts, tests/kimi-oauth-identity.test.ts
Tests cover non-finite values, invalid strings, negative values, and finite values that overflow during millisecond conversion. They verify finite future expiries or Kimi payload rejection.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related issues

  • lidge-jun/opencodex#1417: The issue directly covers invalid expires_in handling in the four OAuth token parsing paths changed here.

Possibly related PRs

Suggested labels: maintainer-sponsored

Suggested reviewers: ingwannu, lidge-jun

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main OAuth change: validating expires_in across token responses to prevent invalid expiry values.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/codex/account-store.ts`:
- Around line 496-502: Validate computed expiry values before storing or
returning them: in src/codex/account-store.ts lines 496-502,
src/oauth/anthropic.ts lines 86-91, and src/oauth/chatgpt.ts lines 54-59, use
the fallback when the calculated expiry timestamp expiresAt or expires is
non-finite; in src/oauth/kimi.ts lines 156-165, reject the payload when the
calculated expires value is non-finite.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: fe5a5394-d030-4bfd-b195-a2cb61707fab

📥 Commits

Reviewing files that changed from the base of the PR and between 0de4fd2 and 6e59b68.

📒 Files selected for processing (8)
  • src/codex/account-store.ts
  • src/oauth/anthropic.ts
  • src/oauth/chatgpt.ts
  • src/oauth/kimi.ts
  • tests/anthropic-hardening.test.ts
  • tests/chatgpt-token-expiry.test.ts
  • tests/codex-account-store.test.ts
  • tests/kimi-oauth-identity.test.ts

Comment thread src/codex/account-store.ts Outdated
@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

@github-actions[bot] I will review the current PR changes independently.

The hygiene check still requires a maintainer security review for the OAuth changes in src/oauth/anthropic.ts, src/oauth/chatgpt.ts, and src/oauth/kimi.ts. A maintainer can apply maintainer-sponsored after that review.

I am replying to the latest comment only. The earlier comment chain was not available.

⚠️ Action not completed

Already reviewed.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@github-actions
github-actions Bot marked this pull request as draft August 10, 2026 10:00
@github-actions
github-actions Bot marked this pull request as ready for review August 10, 2026 10:01
@Bruce-Yii

Copy link
Copy Markdown
Contributor Author

Addressed the CodeRabbit Major finding (computed-expiry overflow) in commit 3b7b7471: Number.MAX_VALUE passes Number.isFinite but overflows to Infinity when multiplied by 1000, so all four sites now also guard the computed expiry timestamp (fallback 3600s; Kimi rejects as malformed). Added 4 regression tests for the overflowing case. Head 3b7b7471, targeted 51/51, OAuth+anthropic+account-store suite 410/410, tsc --noEmit clean.

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== HEAD =='
git rev-parse HEAD

echo '== Changed files from parent =='
git diff --name-status HEAD^

echo '== Diff =='
git diff --unified=50 HEAD^ -- \
  src/codex/account-store.ts \
  src/oauth/anthropic.ts \
  src/oauth/chatgpt.ts \
  src/oauth/kimi.ts \
  tests/anthropic-hardening.test.ts \
  tests/chatgpt-token-expiry.test.ts \
  tests/codex-account-store.test.ts \
  tests/kimi-oauth-identity.test.ts

echo '== Production symbol outline =='
ast-grep outline src/codex/account-store.ts --items all --match 'getValidCodexToken|expiresAt|expires_in' || true
ast-grep outline src/oauth/anthropic.ts --items all --match 'credsFrom|expiresAt|expires_in' || true
ast-grep outline src/oauth/chatgpt.ts --items all --match 'credsFromToken|expiresAt|expires_in' || true
ast-grep outline src/oauth/kimi.ts --items all --match 'parseTokenPayload|expiresAt|expires_in' || true

Length of output: 38981


🏁 Script executed:

#!/bin/bash
set -euo pipefail

for spec in \
  'src/codex/account-store.ts:480:495' \
  'src/oauth/anthropic.ts:80:100' \
  'src/oauth/chatgpt.ts:45:68' \
  'src/oauth/kimi.ts:150:177' \
  'tests/anthropic-hardening.test.ts:50:85' \
  'tests/chatgpt-token-expiry.test.ts:20:50' \
  'tests/codex-account-store.test.ts:285:340' \
  'tests/kimi-oauth-identity.test.ts:70:105'
do
  file="${spec%%:*}"
  rest="${spec#*:}"
  start="${rest%%:*}"
  end="${rest##*:}"
  echo "== ${file}, Lines ${start}-${end} =="
  nl -ba "$file" | sed -n "${start},${end}p"
done

Length of output: 949


🏁 Script executed:

#!/bin/bash
set -euo pipefail

for spec in \
  'src/codex/account-store.ts:480:495' \
  'src/oauth/anthropic.ts:80:100' \
  'src/oauth/chatgpt.ts:45:68' \
  'src/oauth/kimi.ts:150:177' \
  'tests/anthropic-hardening.test.ts:50:85' \
  'tests/chatgpt-token-expiry.test.ts:20:50' \
  'tests/codex-account-store.test.ts:285:340' \
  'tests/kimi-oauth-identity.test.ts:70:105'
do
  file="${spec%%:*}"
  rest="${spec#*:}"
  start="${rest%%:*}"
  end="${rest##*:}"
  echo "== ${file}, Lines ${start}-${end} =="
  awk -v start="$start" -v end="$end" 'NR >= start && NR <= end { printf "%6d\t%s\n", NR, $0 }' "$file"
done

Length of output: 13927


@github-actions[bot] Focused review complete. I found no remaining issue in commit 3b7b7471dbdc2afbaf2eaf046c41bbf686e6d850.

  • src/oauth/anthropic.ts Lines 86-91 validates expires_in and validates the computed expiry.
  • src/oauth/chatgpt.ts Lines 54-59 applies the same computed-expiry fallback.
  • src/oauth/kimi.ts Lines 158-164 rejects an overflowing computed expiry as malformed.
  • src/codex/account-store.ts applies the finite computed-expiry fallback before it persists expiresAt.
  • The overflow regression tests cover all four paths, including the finite Number.MAX_VALUE input that becomes Infinity after multiplication by 1000.

I inspected the source and tests only. I did not execute the test suite in this sandbox.

You are interacting with an AI system.

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

git status --short
git show --no-ext-diff --format=fuller --stat 3b7b7471
git diff --no-ext-diff 3b7b7471^ 3b7b7471 -- \
  src/oauth/anthropic.ts \
  src/oauth/chatgpt.ts \
  src/oauth/kimi.ts \
  src/codex/account-store.ts \
  tests/anthropic-hardening.test.ts \
  tests/chatgpt-token-expiry.test.ts \
  tests/codex-account-store.test.ts \
  tests/kimi-oauth-identity.test.ts

for f in \
  src/oauth/anthropic.ts \
  src/oauth/chatgpt.ts \
  src/oauth/kimi.ts \
  src/codex/account-store.ts \
  tests/anthropic-hardening.test.ts \
  tests/chatgpt-token-expiry.test.ts \
  tests/codex-account-store.test.ts \
  tests/kimi-oauth-identity.test.ts
do
  echo "===== $f ====="
  ast-grep outline "$f" --items all || true
  rg -n -C 8 'expires_in|expiresAt|Number\.isFinite|MAX_VALUE|1e999' "$f" || true
done

Length of output: 64293


🏁 Script executed:

#!/bin/bash
set -euo pipefail

base="$(git merge-base HEAD origin/dev 2>/dev/null || git merge-base HEAD dev)"
echo "Merge base: $base"
git diff --no-ext-diff --name-status "$base"...HEAD
git diff --no-ext-diff --check "$base"...HEAD
git diff --no-ext-diff --unified=80 "$base"...HEAD -- \
  src/oauth/anthropic.ts \
  src/oauth/chatgpt.ts \
  src/oauth/kimi.ts \
  src/codex/account-store.ts \
  tests/anthropic-hardening.test.ts \
  tests/chatgpt-token-expiry.test.ts \
  tests/codex-account-store.test.ts \
  tests/kimi-oauth-identity.test.ts

sed -n '1,115p' tests/anthropic-hardening.test.ts
sed -n '1,85p' tests/chatgpt-token-expiry.test.ts
sed -n '1,125p' tests/kimi-oauth-identity.test.ts
sed -n '1,335p' tests/codex-account-store.test.ts

Length of output: 1091


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Local refs ==="
git branch -a
git remote -v
echo "=== PR metadata ==="
gh pr view 1418 --repo lidge-jun/opencodex \
  --json number,headRefName,headRefOid,baseRefName,baseRefOid,files \
  --jq '{number,headRefName,headRefOid,baseRefName,baseRefOid,files: [.files[].path]}'
echo "=== PR file patch metadata ==="
gh api "repos/lidge-jun/opencodex/pulls/1418/files?per_page=100" \
  --jq '.[] | {filename, status, additions, deletions, patch}'

Length of output: 15466


@github-actions[bot] Review complete. I found no new issues in PR #1418.

The full PR diff at 3b7b7471 correctly handles both invalid expires_in values and finite values that overflow during millisecond conversion:

  • src/oauth/anthropic.ts and src/oauth/chatgpt.ts use a finite 3600-second fallback when the calculated expiry is not finite.
  • src/codex/account-store.ts persists a finite fallback expiresAt.
  • src/oauth/kimi.ts rejects the malformed token response when the calculated expiry is not finite.
  • The regression tests cover Infinity, string input where applicable, and Number.MAX_VALUE overflow in all four paths.

I did not run the test suite in this sandbox. The code review found no remaining finding.

You are interacting with an AI system.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
tests/anthropic-hardening.test.ts (1)

46-70: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Verify the documented fallback duration in the regression tests.

The new tests prove only that the expiry is finite and future-dated. They do not prove that invalid values use the required 3600-second fallback.

  • tests/anthropic-hardening.test.ts#L46-L70: Assert an expiry near 3_300_000 milliseconds because the five-minute skew is applied.
  • tests/chatgpt-token-expiry.test.ts#L7-L44: Assert an expiry near 3_600_000 milliseconds.
  • tests/codex-account-store.test.ts#L264-L312: Assert persisted expiresAt near 3_600_000 milliseconds.

Use a small timing tolerance around the expected values.

This is required to verify the PR’s 3600-second fallback objective.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/anthropic-hardening.test.ts` around lines 46 - 70, Update the
regression assertions to verify the documented 3600-second fallback using a
small timing tolerance: in tests/anthropic-hardening.test.ts lines 46-70, assert
expiry is near 3,300,000 ms from now after the five-minute skew; in
tests/chatgpt-token-expiry.test.ts lines 7-44, assert expiry is near 3,600,000
ms; and in tests/codex-account-store.test.ts lines 264-312, assert persisted
expiresAt is near 3,600,000 ms. Keep the existing invalid and overflowing expiry
scenarios intact.
tests/chatgpt-token-expiry.test.ts (1)

7-19: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Assert the fallback duration.

The tests accept any finite future expiry. A regression that falls back to one second would still pass. Capture timestamps around the refresh and assert that ChatGPT’s expiry is close to 3_600_000 milliseconds.

This is required to verify the PR’s 3600-second fallback objective.

Also applies to: 21-44

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/chatgpt-token-expiry.test.ts` around lines 7 - 19, Strengthen the test
“refresh with a non-finite expires_in falls back to a finite default expiry” by
capturing the current time before and after refreshChatGPTToken, then asserting
cred.expires is approximately 3,600,000 milliseconds after the refresh
timestamp. Retain the existing finite and future-expiry checks while allowing a
reasonable timing tolerance.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/codex/account-store.ts`:
- Around line 500-501: Reject negative expiry durations across all four OAuth
paths: in src/codex/account-store.ts lines 500-501, src/oauth/anthropic.ts lines
90-91, and src/oauth/chatgpt.ts lines 58-59, require expires_in to be
non-negative before calculating the expiry timestamp; in src/oauth/kimi.ts lines
158-163, treat payload.expires_in < 0 as malformed. Preserve the existing
finite-value overflow fallback for non-negative durations.

---

Outside diff comments:
In `@tests/anthropic-hardening.test.ts`:
- Around line 46-70: Update the regression assertions to verify the documented
3600-second fallback using a small timing tolerance: in
tests/anthropic-hardening.test.ts lines 46-70, assert expiry is near 3,300,000
ms from now after the five-minute skew; in tests/chatgpt-token-expiry.test.ts
lines 7-44, assert expiry is near 3,600,000 ms; and in
tests/codex-account-store.test.ts lines 264-312, assert persisted expiresAt is
near 3,600,000 ms. Keep the existing invalid and overflowing expiry scenarios
intact.

In `@tests/chatgpt-token-expiry.test.ts`:
- Around line 7-19: Strengthen the test “refresh with a non-finite expires_in
falls back to a finite default expiry” by capturing the current time before and
after refreshChatGPTToken, then asserting cred.expires is approximately
3,600,000 milliseconds after the refresh timestamp. Retain the existing finite
and future-expiry checks while allowing a reasonable timing tolerance.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: e5dba4bc-108f-4b3e-a92f-1b37590b5dd9

📥 Commits

Reviewing files that changed from the base of the PR and between 6e59b68 and 3b7b747.

📒 Files selected for processing (8)
  • src/codex/account-store.ts
  • src/oauth/anthropic.ts
  • src/oauth/chatgpt.ts
  • src/oauth/kimi.ts
  • tests/anthropic-hardening.test.ts
  • tests/chatgpt-token-expiry.test.ts
  • tests/codex-account-store.test.ts
  • tests/kimi-oauth-identity.test.ts

Comment thread src/codex/account-store.ts

@flyingsquirrel0419 flyingsquirrel0419 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fix direction is correct and the computed-expiry overflow guard closes the original NaN/Infinity failure mode, but I cannot sponsor or approve this authentication-boundary change on the current head.

One blocker remains across all four parse sites: finite negative expires_in values are still accepted. In src/codex/account-store.ts, src/oauth/anthropic.ts, and src/oauth/chatgpt.ts, a negative duration produces a finite timestamp in the past instead of taking the malformed-response fallback; in src/oauth/kimi.ts, it should fail the required-field contract. Require expires_in >= 0 in the three fallback paths and reject < 0 in Kimi, then add negative-value regression coverage for each behavior.

Please also tighten the new fallback tests to assert the actual fallback window (approximately 3600 seconds, or approximately 3300 seconds for Anthropic after its five-minute skew), rather than only finite && future. That prevents a one-second or otherwise incorrect fallback from satisfying the tests.

The failing hygiene check is the expected unsponsored_surface gate, not a product-test failure. I will reconsider maintainer-sponsored only after these input-boundary cases are fixed and the exact-head checks are green.

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

@github-actions The PR is ready for maintainer review.

The remaining hygiene requirement is a maintainer security review of the OAuth changes in:

  • src/oauth/anthropic.ts
  • src/oauth/chatgpt.ts
  • src/oauth/kimi.ts

After that review, a maintainer can apply the maintainer-sponsored label.

You are interacting with an AI system.

@github-actions
github-actions Bot marked this pull request as draft August 10, 2026 12:11
@Bruce-Yii

Copy link
Copy Markdown
Contributor Author

Addressed the maintainer review (flyingsquirrel0419) in commit 23a42459:

1. Negative expires_in (blocker): all four sites now require expires_in >= 0 — the three fallback paths (account-store / anthropic / chatgpt) treat negative as malformed and use the 3600s default; Kimi rejects < 0 via the required-fields contract.

2. Exact fallback window in tests: the fallback tests now assert the actual window, not just finite && future:

  • chatgpt / account-store: ~3600s (tolerance 30s)
  • anthropic: ~3300s (3600s minus the 5-minute refresh skew)
  • kimi: negative rejected alongside non-finite and overflowing

3. Regression coverage: +4 negative-value tests (one per site), 55/55 targeted, OAuth+anthropic+account-store suite 414/414, tsc --noEmit clean. Head 23a42459.

The unsponsored_surface hygiene failure is the expected auth-boundary gate — ready for maintainer-sponsored after exact-head checks are green.

@Bruce-Yii
Bruce-Yii force-pushed the fix-token-expires-in-guard branch from 23a4245 to 355b69e Compare August 10, 2026 12:16
@github-actions
github-actions Bot marked this pull request as ready for review August 10, 2026 12:17
@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

@github-actions[bot] Acknowledged. PR #1418 is marked ready for review at 355b69e5b003edebe3f543d1818a9618fa075b14.

You are interacting with an AI system.

@Ingwannu Ingwannu added the maintainer-sponsored Maintainer sponsors this change to an auth, workflow, release, or dependency surface label Aug 10, 2026
@github-actions github-actions Bot removed intake: hygiene-blocked Deterministic PR hygiene checks failed review-ready labels Aug 10, 2026
@github-actions
github-actions Bot marked this pull request as draft August 10, 2026 13:39
@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

@github-actions The PR gate reports that PR #1418 is ready for review.

All four readiness checks and the deterministic hygiene checks passed. The ready state applies to head 355b69e5b003edebe3f543d1818a9618fa075b14.

You are interacting with an AI system.

@Ingwannu Ingwannu left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved on exact head 355b69e5b003edebe3f543d1818a9618fa075b14 after an explicit authentication-boundary review.

The four token-adoption paths now validate the raw duration as a non-negative finite number and validate the computed timestamp before storage or return. Anthropic, ChatGPT, and the Codex account store take the bounded one-hour fallback; Kimi rejects malformed input. The negative, overflow, non-finite, and fallback-window regressions cover the failure modes without logging or widening credential destinations.

Exact-head evidence:

  • focused OAuth/account-store tests: 414/414 pass;
  • typecheck and privacy review: pass;
  • CodeRabbit: pass, both inline blockers resolved on this head;
  • cross-platform CI rerun: Linux shards, macOS, keyring, storage policy, and package installs all pass;
  • current-dev distance: two documentation commits, within policy.

The earlier hygiene failure is the superseded pre-sponsorship run; the later hygiene run and current cross-platform gate are green. The author still needs to tick the now-proven local/CI checklist item so the automated readiness gate can move the PR out of draft. This approval does not authorize self-merge; authentication changes should still receive the additional maintainer review requested on the PR when practical.

@github-actions
github-actions Bot marked this pull request as ready for review August 10, 2026 14:26
@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

@github-actions The PR gate reports that PR #1418 is ready for review.

All four readiness checks passed at head 355b69e5b003edebe3f543d1818a9618fa075b14.

You are interacting with an AI system.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working maintainer-sponsored Maintainer sponsors this change to an auth, workflow, release, or dependency surface review-ready

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants