Skip to content

Commit

Permalink
fix: fixes to the auto refresh alg
Browse files Browse the repository at this point in the history
  • Loading branch information
hf committed Jan 5, 2023
1 parent bc092fe commit 62df471
Showing 1 changed file with 36 additions and 19 deletions.
55 changes: 36 additions & 19 deletions src/GoTrueClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ export default class GoTrueClient {
error: new AuthUnknownError('Unexpected error during initialization', error),
}
} finally {
this._handleVisibilityChange()
await this._handleVisibilityChange()
}
}

Expand Down Expand Up @@ -1141,7 +1141,9 @@ export default class GoTrueClient {
}

// session will expire in this many ticks (or has already expired if <= 0)
const expiresInTicks = Math.floor((now - session.expires_at) / AUTO_REFRESH_TICK_DURATION)
const expiresInTicks = Math.floor(
(session.expires_at * 1000 - now) / AUTO_REFRESH_TICK_DURATION
)

if (expiresInTicks < AUTO_REFRESH_TICK_THRESHOLD) {
await this._callRefreshToken(session.refresh_token)
Expand All @@ -1156,7 +1158,7 @@ export default class GoTrueClient {
* algorithms when the browser window/tab are in foreground. On non-browser
* platforms it assumes always foreground.
*/
private _handleVisibilityChange() {
private async _handleVisibilityChange() {
if (!isBrowser() || !window?.addEventListener) {
if (this.autoRefreshToken) {
// in non-browser environments the refresh token ticker runs always
Expand All @@ -1167,27 +1169,42 @@ export default class GoTrueClient {
}

try {
window?.addEventListener('visibilitychange', async () => {
if (document.visibilityState === 'visible') {
await this.initializePromise
await this._recoverAndRefresh()

if (this.autoRefreshToken) {
// in browser environments the refresh token ticker runs only on focused tabs
// which prevents race conditions
this.startAutoRefresh()
}
} else if (document.visibilityState === 'hidden') {
if (this.autoRefreshToken) {
this.stopAutoRefresh()
}
}
})
window?.addEventListener(
'visibilitychange',
async () => await this._onVisibilityChanged(false)
)

// now immediately call the visbility changed callback to setup with the
// current visbility state
await this._onVisibilityChanged(true) // initial call
} catch (error) {
console.error('_handleVisibilityChange', error)
}
}

/**
* Callback registered with `window.addEventListener('visibilitychange')`.
*/
private async _onVisibilityChanged(isInitial: boolean) {
if (document.visibilityState === 'visible') {
if (!isInitial) {
// initial visibility change setup is handled in another flow under #initialize()
await this.initializePromise
await this._recoverAndRefresh()
}

if (this.autoRefreshToken) {
// in browser environments the refresh token ticker runs only on focused tabs
// which prevents race conditions
this.startAutoRefresh()
}
} else if (document.visibilityState === 'hidden') {
if (this.autoRefreshToken) {
this.stopAutoRefresh()
}
}
}

/**
* Generates the relevant login URL for a third-party provider.
* @param options.redirectTo A URL or mobile address to send the user to after they are confirmed.
Expand Down

0 comments on commit 62df471

Please sign in to comment.