Last active
September 21, 2022 19:12
-
-
Save miguelespinoza/59d8dc57aaeae27ffac87989f06e8f0e to your computer and use it in GitHub Desktop.
Support supabase v2 refresh token logic for browser extensions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const EXPIRY_MARGIN = 10 * 1000; | |
class Auth { | |
initialize = async () => { | |
// Get the latest session, token may be refreshed | |
const { data, error } = await supabase.auth.getSession(); | |
if (error) throw error; | |
if (data.session?.expires_at) { | |
// Create an alarm 10 seconds before token expiring | |
browser.alarms.create('token-expired', { | |
when: data.session.expires_at * 1000 - EXPIRY_MARGIN, | |
}); | |
} | |
}; | |
refreshToken = async () => { | |
// Wrap in network retry timeout similar to https://github.com/supabase/gotrue-js/blob/master/src/GoTrueClient.ts#L761-L770 | |
await this._callRefreshToken(); | |
}; | |
private _callRefreshToken = async () => { | |
const { data, error } = await supabase.auth.getSession(); | |
if (error) throw error; | |
if (data.session) { | |
const { data: newSessionData, error: newSessionError } = await supabase.auth.setSession(data.session.refresh_token); | |
if (newSessionError) throw newSessionError; | |
if (newSessionData.session?.expires_at) { | |
// Create a new alarm for the next token expiration | |
browser.alarms.create('token-expired', { | |
when: newSessionData.session.expires_at * 1000 - EXPIRY_MARGIN, | |
}); | |
} | |
} | |
}; | |
} | |
export default new Auth(); | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
browser.alarms.onAlarm.addListener(async (alarm) => { | |
if (alarm.name === 'token-expired) { | |
await Auth.refreshToken(); | |
return; | |
} | |
}); | |
// Call in your initialization logic | |
Auth.initialize(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { createClient, SupportedStorage } from '@supabase/supabase-js'; | |
import { browser } from 'webextension-polyfill-ts'; | |
const supabaseUrl = process.env.SUPABASE_URL as string; | |
const supabaseKey = process.env.SUPABASE_PUBLIC_KEY as string; | |
const browserStorageInterface: SupportedStorage = { | |
async getItem(key: string): Promise<string | null> { | |
const storage = await browser.storage.local.get(key); | |
return storage?.[key]; | |
}, | |
async setItem(key: string, value: string): Promise<void> { | |
await browser.storage.local.set({ | |
[key]: value, | |
}); | |
}, | |
async removeItem(key: string): Promise<void> { | |
await browser.storage.local.remove(key); | |
}, | |
}; | |
const supabase = createClient(supabaseUrl, supabaseKey, { | |
auth: { | |
persistSession: true, | |
// This configuration is important, since now the extension is reponsible for refreshing the token | |
autoRefreshToken: false, | |
detectSessionInUrl: false, | |
storage: browserStorageInterface, | |
}, | |
}); | |
export default supabase; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment