Skip to content

Capture absolute expiresAt on AccessToken - #25

Merged
alejandrohdezma merged 2 commits into
mainfrom
bug/expires-at
Jun 1, 2026
Merged

Capture absolute expiresAt on AccessToken#25
alejandrohdezma merged 2 commits into
mainfrom
bug/expires-at

Conversation

@alejandrohdezma

Copy link
Copy Markdown
Collaborator

🚀 What's included in this PR?

Adds an expiresAt: Instant field to AccessToken alongside the existing expiresIn: ExpiresIn and fixes the absolute deadline at fetch time. The http4s entity decoder reads the wire-format (access_token, expires_in) response (also accepting id_token via an .or alternative) and computes expiresAt = now + expires_in via Clock.

This eliminates a subtle drift bug: callers that cached an AccessToken and later computed now + token.expiresIn ended up overstating the deadline by however long the token had been cached. Reading token.expiresAt directly gives the fetch-time-fixed deadline.

identity and userIdentity factories now thread expiresAt through. userIdentity(triple) collapses to a single httpClient.expect[AccessToken] call since the entity decoder handles both access_token and id_token response shapes. safetyPeriod is unchanged.

Test assertions that compared full AccessToken instances were loosened to compare only the Token value (Approach 1) so they don't have to fabricate matching Instants.

@alejandrohdezma
alejandrohdezma requested a review from a team as a code owner May 25, 2026 18:26
@github-actions github-actions Bot added 🪲 bug Bug fixes ⚖️ M Size of PR between 100 and 500 lines labels May 25, 2026
Add `expiresAt: Instant` to `AccessToken` alongside the existing
`expiresIn: ExpiresIn` and fix the deadline at fetch time. The
http4s entity decoder reads the wire-format `(access_token, expires_in)`
response (now also accepting `id_token` via an `.or` alternative) and
computes `expiresAt = now + expires_in` via `Clock`.

The `GcpLoginCallbackHandler` Kafka envelope now reads
`token.expiresAt.getEpochSecond` directly, eliminating the
`now + cached expiresIn` drift that previously overstated the
broker-visible deadline by up to the cache safety period.

`identity` and `userIdentity` factories pass `expiresAt` through;
`userIdentity(triple)` shrinks to a single `httpClient.expect[AccessToken]`
call now that the entity decoder handles both `access_token` and
`id_token` shapes. `safetyPeriod` is unchanged.

Tests using `AccessToken` equality switch to a token-only assertion
(Approach 1) to avoid having to fabricate matching `expiresAt` instants.
Base automatically changed from feat/auto to main June 1, 2026 20:25
@alejandrohdezma
alejandrohdezma merged commit e851c6a into main Jun 1, 2026
6 checks passed
@alejandrohdezma
alejandrohdezma deleted the bug/expires-at branch June 1, 2026 21:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

⚖️ M Size of PR between 100 and 500 lines 🪲 bug Bug fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants