[PR #7705] fix: getAccessToken does not refresh access token in stateless setup (#7703) #7503

Open
opened 2026-03-13 13:39:24 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/better-auth/better-auth/pull/7705
Author: @biniam0
Created: 1/30/2026
Status: 🔄 Open

Base: canaryHead: fix/stateless-get-access-token-refresh


📝 Commits (1)

  • 4217ca5 fix: getAccessToken refreshes token in stateless setup (fixes #7703)

📊 Changes

1 file changed (+12 additions, -7 deletions)

View changed files

📝 packages/better-auth/src/api/routes/account.ts (+12 -7)

📄 Description

Summary

Fixes #7703. In stateless (or cookie-cache) setups, calling getAccessToken when the access token was expired did not refresh the token and returned 400 BAD_REQUEST instead of a valid token.

Changes

  • Refresh when expiry is unknown: Attempt token refresh when we have a refresh token but no accessTokenExpiresAt (e.g. when the OAuth provider omits expires_in), so stateless and providers like Keycloak still get refreshed tokens.
  • Stateless-safe refresh: Wrapped updateAccount in try/catch. When it fails (e.g. no DB or account not in this instance’s store), we still return the new tokens and update the account cookie when storeAccountCookie is enabled, so the client gets a valid token.
  • Cookie matching: When resolving account from the cookie, match the request’s accountId to accountData.accountId (OAuth provider user id) instead of accountData.id (DB primary key), so getAccessToken({ providerId, accountId }) works when using the account cookie.

Testing

  • All 18 tests in packages/better-auth/src/api/routes/account.test.ts pass, including:
    • "should get access token using accountId from listAccounts"
    • "should refresh account_data cookie in stateless mode"
  • No API or config changes; existing behavior is preserved where a DB is used.

Summary by cubic

Fixes getAccessToken not refreshing in stateless/cookie-cache setups and returning 400. Tokens now refresh reliably even when expiry is unknown, and cookie-based account matching works with accountId.

  • Bug Fixes
    • Refresh when a refresh token exists and the access token is expired or expiry is unknown (e.g., providers without expires_in like Keycloak).
    • Wrap updateAccount in try/catch; still return refreshed tokens and update the account cookie when storeAccountCookie is enabled, even if DB update fails.
    • Match cookie account by accountId (provider user id) instead of DB id so getAccessToken({ providerId, accountId }) works with the account cookie.
    • No API or config changes.

Written for commit 4217ca5d97e17d9bc0297cff9bbb8008f293f4b7. Summary will update on new commits.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/better-auth/better-auth/pull/7705 **Author:** [@biniam0](https://github.com/biniam0) **Created:** 1/30/2026 **Status:** 🔄 Open **Base:** `canary` ← **Head:** `fix/stateless-get-access-token-refresh` --- ### 📝 Commits (1) - [`4217ca5`](https://github.com/better-auth/better-auth/commit/4217ca5d97e17d9bc0297cff9bbb8008f293f4b7) fix: getAccessToken refreshes token in stateless setup (fixes #7703) ### 📊 Changes **1 file changed** (+12 additions, -7 deletions) <details> <summary>View changed files</summary> 📝 `packages/better-auth/src/api/routes/account.ts` (+12 -7) </details> ### 📄 Description ## Summary Fixes #7703. In stateless (or cookie-cache) setups, calling `getAccessToken` when the access token was expired did not refresh the token and returned 400 BAD_REQUEST instead of a valid token. ## Changes - **Refresh when expiry is unknown:** Attempt token refresh when we have a refresh token but no `accessTokenExpiresAt` (e.g. when the OAuth provider omits `expires_in`), so stateless and providers like Keycloak still get refreshed tokens. - **Stateless-safe refresh:** Wrapped `updateAccount` in try/catch. When it fails (e.g. no DB or account not in this instance’s store), we still return the new tokens and update the account cookie when `storeAccountCookie` is enabled, so the client gets a valid token. - **Cookie matching:** When resolving account from the cookie, match the request’s `accountId` to `accountData.accountId` (OAuth provider user id) instead of `accountData.id` (DB primary key), so `getAccessToken({ providerId, accountId })` works when using the account cookie. ## Testing - All 18 tests in `packages/better-auth/src/api/routes/account.test.ts` pass, including: - "should get access token using accountId from listAccounts" - "should refresh account_data cookie in stateless mode" - No API or config changes; existing behavior is preserved where a DB is used. <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Fixes getAccessToken not refreshing in stateless/cookie-cache setups and returning 400. Tokens now refresh reliably even when expiry is unknown, and cookie-based account matching works with accountId. - **Bug Fixes** - Refresh when a refresh token exists and the access token is expired or expiry is unknown (e.g., providers without expires_in like Keycloak). - Wrap updateAccount in try/catch; still return refreshed tokens and update the account cookie when storeAccountCookie is enabled, even if DB update fails. - Match cookie account by accountId (provider user id) instead of DB id so getAccessToken({ providerId, accountId }) works with the account cookie. - No API or config changes. <sup>Written for commit 4217ca5d97e17d9bc0297cff9bbb8008f293f4b7. Summary will update on new commits.</sup> <!-- End of auto-generated description by cubic. --> --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2026-03-13 13:39:24 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#7503