Skip to content

Add token update hook for auth token persistence#185

Merged
jonasman merged 5 commits into
jonasman:masterfrom
Krillle:token-update-hook
Jun 3, 2026
Merged

Add token update hook for auth token persistence#185
jonasman merged 5 commits into
jonasman:masterfrom
Krillle:token-update-hook

Conversation

@Krillle

@Krillle Krillle commented Apr 29, 2026

Copy link
Copy Markdown
Contributor

It improves refresh token / re-login handling in two areas:

  1. Central token update hook
    This adds a central callback so apps can persist newly issued auth tokens, including rotated refresh tokens, immediately after authentication or token refresh.

Changes:

  • add public var onTokenUpdate: ((AuthToken?) -> Void)?
  • add internal updateToken(_:) helper
  • call the hook when tokens are set during:
    • web authentication
    • token refresh
    • token reuse
    • token cleanup / invalidation

Why:
Tesla refresh tokens can rotate during refreshToken(). Without a central callback, apps may miss persisting the newly issued refresh token and can end up reusing an invalidated one on the next launch.

  1. Improved concurrent refresh handling
    This also addresses refresh races when multiple API requests happen at the same time.

Problems:

  • multiple concurrent API requests could trigger multiple parallel refreshToken() calls for the same expired token
  • a later failing refresh path could clear the token state even after another request had already refreshed and stored a newer valid token

Changes:

  • add single-flight refresh handling with:
    private var refreshTask: Task<AuthToken, Error>?
  • if a refresh is already running, additional requests now await the same in-flight task instead of starting another refresh
  • add conditional token clearing with:
    clearTokenIfUnchanged(refreshToken:)
  • only clear the token when the failing refresh still matches the currently active refresh token
  • remove unconditional token clearing from the generic login_required response path

Why:
Tesla refresh tokens can rotate. In apps that trigger several requests at startup or on screen load, parallel refresh attempts can race:

  • one request refreshes successfully and stores a new token
  • another request still uses the older refresh token and fails
  • the failure path can then incorrectly clear the newer valid token

This should make refresh behavior more robust by:

  • coalescing concurrent refreshes
  • allowing apps to persist rotated tokens immediately
  • avoiding invalidation of newer token state from stale error paths

Tesla recently started requiring the `vehicle_location` scope for the `/vehicle_data` endpoint.
Without this scope, calls like `getAllData(vehicle)` fail with HTTP 403 (Forbidden).

This PR adds `.vehicleLocation = "vehicle_location"` to the `TeslaAPI.Scope` enum so developers
can request the proper scope when initializing the Fleet API client.
Patch Add support for `vehicle_location` Fleet API scope
} catch let error {
if case let TeslaError.networkError(error: internalError) = error {
if internalError.code == 302 || internalError.code == 403 {
//Handle redirection for tesla.cn

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Comment Spacing Violation: Prefer at least one space after slashes for comments. (comment_spacing)

@jonasman jonasman merged commit dd1039e into jonasman:master Jun 3, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants