-
Notifications
You must be signed in to change notification settings - Fork 16
refactor: improve refresh token persistence and implement automatic session restoration logic in SupabaseAuth #4736
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -71,9 +71,8 @@ export class SupabaseAuth implements ServiceAuth { | |
| has_session: !!session, | ||
| has_refresh_token: !!session?.refresh_token, | ||
| }); | ||
| if (event === 'TOKEN_REFRESHED') { | ||
| if (session?.refresh_token) | ||
| Util.addRefreshTokenToStore(session?.refresh_token); | ||
| if (session?.refresh_token) { | ||
| Util.addRefreshTokenToStore(session.refresh_token); | ||
| } | ||
| }, | ||
| ); | ||
|
|
@@ -476,14 +475,44 @@ export class SupabaseAuth implements ServiceAuth { | |
| Util.addRefreshTokenToStore( | ||
| currentSession.data.session.refresh_token, | ||
| ); | ||
| return; | ||
| } | ||
| if (currentSession?.error) { | ||
| logger.error( | ||
| 'Unable to resolve web Supabase session:', | ||
| currentSession.error, | ||
| ); | ||
| } | ||
|
|
||
| const stored = Util.getRefreshTokenFromStore(); | ||
| if (!stored?.token) return; | ||
|
|
||
| const refreshToken = String(stored.token).replace(/"/g, ''); | ||
| const response = await this._auth?.refreshSession({ | ||
| refresh_token: refreshToken, | ||
| }); | ||
| if (response?.error) { | ||
| throw new Error( | ||
| 'Web session refresh failed: ' + response.error.message, | ||
| ); | ||
| } | ||
| if (response?.data?.session) { | ||
| const { access_token, refresh_token } = response.data.session; | ||
| await this._auth?.setSession({ access_token, refresh_token }); | ||
| Util.addRefreshTokenToStore(refresh_token); | ||
| } | ||
|
Comment on lines
+499
to
+503
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Passing if (response?.data?.session) {
const { access_token, refresh_token } = response.data.session;
await this._auth?.setSession({ access_token, refresh_token });
if (refresh_token) {
Util.addRefreshTokenToStore(refresh_token);
}
} |
||
| } catch (error) { | ||
| if (this.isInvalidRefreshTokenError(error)) { | ||
| store.dispatch(setRefreshToken(null)); | ||
| logAuthDebug( | ||
| 'Cleared stale web refresh token after refresh failure.', | ||
| { | ||
| source: 'SupabaseAuth.doRefreshSession', | ||
| reason: 'web_invalid_refresh_token', | ||
| }, | ||
| ); | ||
| return; | ||
| } | ||
| logger.error('Unexpected error while resolving web session:', error); | ||
| } | ||
| return; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When this listener now runs for every auth event, the
INITIAL_SESSIONemitted as soon asSupabaseAuth.getInstance()is created can callsetRefreshToken. That instance is constructed at module load insrc/startup/serviceBootstrap.tsbeforebootstrapServicesAndRenderwaits forpersistor.bootstrapped, so if the initial-session callback wins the startup race it modifies theauthsubtree before redux-persist handlesREHYDRATE; the default reconciler then skips the persistedauthstate, dropping the stored app user/roles and sending returning users through a logged-out or wrong-mode path. Keep this restricted to real refresh/sign-in completions or defer the dispatch until rehydration is done.Useful? React with 👍 / 👎.