Skip to content

Add login_with_refresh_token() for token-only authentication - #26

Merged
nshp merged 1 commit into
nshp:mainfrom
epheterson:feat/login-with-refresh-token
Aug 11, 2026
Merged

Add login_with_refresh_token() for token-only authentication#26
nshp merged 1 commit into
nshp:mainfrom
epheterson:feat/login-with-refresh-token

Conversation

@epheterson

Copy link
Copy Markdown
Contributor

Currently the only public way to authenticate is login(username, password), so anything that wants to keep a session across restarts has to reach into a private attribute:

api = LucidAPI()
api._refresh_token = stored_token   # private
await api.authentication_refresh()

This adds login_with_refresh_token(token) and a public refresh_token property, so the round trip has a supported path.

Why it matters beyond tidiness. Lucid permits one account per car and the mobile app has no secondary logins, so a stored password is the primary account credential — it unlocks the doors and opens the frunk, and it can't be revoked without a password change. A refresh token can be revoked with "log out all devices." Letting integrations store the weaker secret is a meaningful difference for anything unattended.

One caveat, documented in the docstring: GetNewJWTTokenResponse carries only session_info — no user_profile and no user_vehicle_data — so api.user stays None after a token login until fetch_vehicles() is called. Worth knowing for downstreams that assert on api.user after authenticating.

Tested against a real vehicle (Gravity, 1.4.1 + this patch):

session valid for: 5:59:59
api.user is None (documented): True
public refresh_token property matches input: True
vehicles after fetch_vehicles(): ['TARS']
invalid token raises: APIError

black --check clean.

A behavioural note you may want to document separately: the refresh token does not appear to rotate. Three consecutive authentication_refresh() calls returned a byte-identical token, and replaying an earlier one still worked. That's convenient — several processes can share a stored token without coordination — but it does mean it's a long-lived bearer credential rather than a self-rotating one, and SessionInfo carries no expiry field for it, so its lifetime isn't discoverable from the API. I've described it that way in the property docstring; happy to soften or drop that wording if it doesn't match your understanding.

Lets an application persist a session across restarts without storing the
account password. Previously the only way was to set the private
_refresh_token attribute and call authentication_refresh().
@nshp

nshp commented Aug 11, 2026

Copy link
Copy Markdown
Owner

Looks good to me, thanks!

@nshp
nshp merged commit 2916450 into nshp:main Aug 11, 2026
2 checks passed
@epheterson
epheterson deleted the feat/login-with-refresh-token branch August 11, 2026 16:16
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.

2 participants