Skip to content
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

Feat/cross tab handler #184

Merged
merged 2 commits into from
Nov 18, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 35 additions & 2 deletions src/GoTrueClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const DEFAULT_OPTIONS = {
autoRefreshToken: true,
persistSession: true,
detectSessionInUrl: true,
multiTab: true,
headers: DEFAULT_HEADERS,
}

Expand Down Expand Up @@ -56,6 +57,7 @@ export default class GoTrueClient {
protected autoRefreshToken: boolean
protected persistSession: boolean
protected localStorage: SupportedStorage
protected multiTab: boolean
protected stateChangeEmitters: Map<string, Subscription> = new Map()
protected refreshTokenTimer?: ReturnType<typeof setTimeout>

Expand All @@ -66,7 +68,8 @@ export default class GoTrueClient {
* @param options.detectSessionInUrl Set to "true" if you want to automatically detects OAuth grants in the URL and signs in the user.
* @param options.autoRefreshToken Set to "true" if you want to automatically refresh the token before expiring.
* @param options.persistSession Set to "true" if you want to automatically save the user session into local storage.
* @param options.localStorage
* @param options.localStorage Provide your own local storage implementation to use instead of the browser's local storage.
* @param options.multiTab Set to "false" if you want to disable multi-tab/window events.
* @param options.cookieOptions
* @param options.fetch A custom fetch implementation.
*/
Expand All @@ -77,6 +80,7 @@ export default class GoTrueClient {
autoRefreshToken?: boolean
persistSession?: boolean
localStorage?: SupportedStorage
multiTab?: boolean
cookieOptions?: CookieOptions
fetch?: Fetch
}) {
Expand All @@ -85,6 +89,7 @@ export default class GoTrueClient {
this.currentSession = null
this.autoRefreshToken = settings.autoRefreshToken
this.persistSession = settings.persistSession
this.multiTab = settings.multiTab
this.localStorage = settings.localStorage || globalThis.localStorage
this.api = new GoTrueApi({
url: settings.url,
Expand All @@ -94,9 +99,10 @@ export default class GoTrueClient {
})
this._recoverSession()
this._recoverAndRefresh()
this._listenForMultiTabEvents()

// Handle the OAuth redirect
if (settings.detectSessionInUrl && isBrowser() && !!getParameterByName('access_token')) {
// Handle the OAuth redirect
this.getSessionFromUrl({ storeSession: true }).then(({ error }) => {
if (error) {
console.error('Error getting session from URL.', error)
Expand Down Expand Up @@ -676,4 +682,31 @@ export default class GoTrueClient {
this.refreshTokenTimer = setTimeout(() => this._callRefreshToken(), value)
if (typeof this.refreshTokenTimer.unref === 'function') this.refreshTokenTimer.unref()
}

/**
* Listens for changes to LocalStorage and updates the current session.
*/
private _listenForMultiTabEvents() {
if (!this.multiTab || !isBrowser() || !window?.addEventListener) {
// console.debug('Auth multi-tab support is disabled.')
return false
}

try {
window?.addEventListener('storage', (e: StorageEvent) => {
if (e.key === STORAGE_KEY) {
const newSession = JSON.parse(String(e.newValue))
if (newSession?.currentSession?.access_token) {
this._recoverAndRefresh()
this._notifyAllSubscribers('SIGNED_IN')
} else {
this._removeSession()
this._notifyAllSubscribers('SIGNED_OUT')
}
}
})
} catch (error) {
console.error('_listenForMultiTabEvents', error)
}
}
}