mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
feat: enable navigatorLock completely, track random logouts
This commit is contained in:
1 parent
847abbf622
commit
ec95c32c7a
3 files changed
+28
-92
No files matched your search
@@ -3,8 +3,8 @@ import { GoTrueClient, navigatorLock } from '@supabase/gotrue-js'
|
||||
export const STORAGE_KEY = process.env.NEXT_PUBLIC_STORAGE_KEY || 'supabase.dashboard.auth.token'
|
||||
export const AUTH_DEBUG_KEY =
|
||||
process.env.NEXT_PUBLIC_AUTH_DEBUG_KEY || 'supabase.dashboard.auth.debug'
|
||||
export const AUTH_NAVIGATOR_LOCK_KEY =
|
||||
process.env.NEXT_PUBLIC_AUTH_NAVIGATOR_LOCK_KEY || 'supabase.dashboard.auth.navigatorLock.enabled'
|
||||
export const AUTH_NAVIGATOR_LOCK_DISABLED_KEY =
|
||||
process.env.NEXT_PUBLIC_AUTH_NAVIGATOR_LOCK_KEY || 'supabase.dashboard.auth.navigatorLock.disabled'
|
||||
|
||||
const debug =
|
||||
process.env.NEXT_PUBLIC_IS_PLATFORM === 'true' &&
|
||||
@@ -12,10 +12,14 @@ const debug =
|
||||
|
||||
const navigatorLockEnabled = !!(
|
||||
process.env.NEXT_PUBLIC_IS_PLATFORM === 'true' &&
|
||||
globalThis?.localStorage?.getItem(AUTH_NAVIGATOR_LOCK_KEY) === 'true' &&
|
||||
!(globalThis?.localStorage?.getItem(AUTH_NAVIGATOR_LOCK_DISABLED_KEY) === 'true') &&
|
||||
globalThis?.navigator?.locks
|
||||
)
|
||||
|
||||
if (!globalThis?.navigator?.locks) {
|
||||
console.warn('This browser does not support the Navigator Locks API. Please update it.')
|
||||
}
|
||||
|
||||
export const gotrueClient = new GoTrueClient({
|
||||
url: process.env.NEXT_PUBLIC_GOTRUE_URL,
|
||||
storageKey: STORAGE_KEY,
|
||||
|
||||
+9
-57
@@ -1,51 +1,21 @@
|
||||
import { IS_PLATFORM } from './constants'
|
||||
import { User, Session } from '@supabase/gotrue-js'
|
||||
import { gotrueClient } from 'common'
|
||||
|
||||
import { getFlags } from './configcat'
|
||||
import { getNavigatorLockFeatureFlagThreshold, setNavigatorLockEnabled } from './local-storage'
|
||||
|
||||
// The first time this file is imported, ConfigCat will be asked for all
|
||||
// available feature flags. The client that this is running in will have
|
||||
// determined and saved a random number [0, 100) under
|
||||
// `supabase.dashboard.ff.threshold.navigatorLock`. If there is a number-valued
|
||||
// feature flag `navigatorLockThreshold`, the
|
||||
// `supabase.dashboard.auth.navigatorLock.enabled` localStorage key will be set
|
||||
// to true if the value chosen by the browser is <= the value in the feature
|
||||
// flag.On the _following_ refresh of the page, `packages/common/gotrue.ts`
|
||||
// will read this value and enable the GoTrueClient navigatorLock.
|
||||
// ConfigCat does not have a native way to do this, as percent-based rollouts
|
||||
// are only available when ConfigCat has a user ID, and not without one, which
|
||||
// can be the case here (GoTrue is used when not authenticated too).
|
||||
async function determineNavigatorLockFeatureFlag() {
|
||||
const flags = await getFlags()
|
||||
const value = flags.find((flag) => flag.settingKey === 'navigatorLockThreshold')?.settingValue
|
||||
|
||||
if (typeof value === 'number' && value > 0) {
|
||||
const threshold = getNavigatorLockFeatureFlagThreshold()
|
||||
|
||||
if (typeof threshold === 'number') {
|
||||
setNavigatorLockEnabled(threshold <= value)
|
||||
} else {
|
||||
setNavigatorLockEnabled(false)
|
||||
}
|
||||
} else {
|
||||
setNavigatorLockEnabled(false)
|
||||
}
|
||||
}
|
||||
|
||||
export { STORAGE_KEY } from 'common'
|
||||
|
||||
export const auth = gotrueClient
|
||||
|
||||
let currentSession: Session | null = null
|
||||
let getAccessTokenPromise: Promise<string | undefined | null> | null = null
|
||||
|
||||
auth.onAuthStateChange((event, session) => {
|
||||
currentSession = session
|
||||
})
|
||||
|
||||
/**
|
||||
* Grabs the currently available access token, or starts a single getSession call.
|
||||
* Grabs the currently available access token, or calls getSession.
|
||||
*/
|
||||
export async function getAccessToken() {
|
||||
// ignore if server-side
|
||||
@@ -56,29 +26,15 @@ export async function getAccessToken() {
|
||||
: false
|
||||
|
||||
if (!currentSession || aboutToExpire) {
|
||||
if (!getAccessTokenPromise) {
|
||||
const promise = (async () => {
|
||||
try {
|
||||
const {
|
||||
data: { session },
|
||||
error,
|
||||
} = await auth.getSession()
|
||||
if (error) {
|
||||
throw error
|
||||
}
|
||||
|
||||
return session?.access_token
|
||||
} finally {
|
||||
getAccessTokenPromise = null
|
||||
}
|
||||
})()
|
||||
|
||||
getAccessTokenPromise = promise
|
||||
|
||||
return await promise
|
||||
const {
|
||||
data: { session },
|
||||
error,
|
||||
} = await auth.getSession()
|
||||
if (error) {
|
||||
throw error
|
||||
}
|
||||
|
||||
return await getAccessTokenPromise
|
||||
return session?.access_token
|
||||
}
|
||||
|
||||
return currentSession.access_token
|
||||
@@ -142,7 +98,3 @@ export const getReturnToPath = (fallback = '/projects') => {
|
||||
|
||||
return validReturnTo + (remainingSearchParams ? `?${remainingSearchParams}` : '')
|
||||
}
|
||||
|
||||
if (IS_PLATFORM && globalThis.window) {
|
||||
determineNavigatorLockFeatureFlag()
|
||||
}
|
||||
+12
-32
@@ -4,10 +4,9 @@ export const LOCAL_STORAGE_KEYS_ALLOWLIST = [
|
||||
'graphiql:theme',
|
||||
'theme',
|
||||
'supabaseDarkMode',
|
||||
'supabase.dashboard.sign_in_clicks_v2',
|
||||
'supabase.dashboard.sign_in_clicks_v3',
|
||||
'supabase.dashboard.auth.debug',
|
||||
'supabase.dashboard.auth.navigatorLock.enabled',
|
||||
'supabase.dashboard.auth.ff.threshold.navigatorLock',
|
||||
'supabase.dashboard.auth.navigatorLock.disabled',
|
||||
]
|
||||
|
||||
export function clearLocalStorage() {
|
||||
@@ -19,12 +18,17 @@ export function clearLocalStorage() {
|
||||
}
|
||||
|
||||
function inferSignInClicks() {
|
||||
if (localStorage.getItem('supabase.dashboard.sign_in_clicks_v2')) {
|
||||
// remove old data from local storage
|
||||
['', '_v2'].forEach(suffix => {
|
||||
localStorage.removeItem(`supabase.dashboard.sign_in_clicks${suffix}`)
|
||||
})
|
||||
|
||||
if (localStorage.getItem('supabase.dashboard.sign_in_clicks_v3')) {
|
||||
return
|
||||
}
|
||||
|
||||
localStorage.setItem(
|
||||
'supabase.dashboard.sign_in_clicks_v2',
|
||||
'supabase.dashboard.sign_in_clicks_v3',
|
||||
localStorage.getItem('supabase.dashboard.auth.token') ? '1' : '0'
|
||||
)
|
||||
}
|
||||
@@ -33,7 +37,7 @@ export function getSignInClicks(): number {
|
||||
let count: number | null = null
|
||||
|
||||
try {
|
||||
count = JSON.parse(localStorage.getItem('supabase.dashboard.sign_in_clicks_v2') || '0')
|
||||
count = JSON.parse(localStorage.getItem('supabase.dashboard.sign_in_clicks_v3') || '0')
|
||||
} catch (e: any) {
|
||||
// do nothing
|
||||
}
|
||||
@@ -44,7 +48,7 @@ export function getSignInClicks(): number {
|
||||
export function incrementSignInClicks(): number {
|
||||
const clicks = getSignInClicks()
|
||||
|
||||
localStorage.setItem('supabase.dashboard.sign_in_clicks_v2', JSON.stringify(clicks + 1))
|
||||
localStorage.setItem('supabase.dashboard.sign_in_clicks_v3', JSON.stringify(clicks + 1))
|
||||
|
||||
return clicks + 1
|
||||
}
|
||||
@@ -52,36 +56,12 @@ export function incrementSignInClicks(): number {
|
||||
export function resetSignInClicks(): number {
|
||||
const clicks = getSignInClicks()
|
||||
|
||||
localStorage.setItem('supabase.dashboard.sign_in_clicks_v2', '0')
|
||||
localStorage.setItem('supabase.dashboard.sign_in_clicks_v3', '0')
|
||||
|
||||
return clicks
|
||||
}
|
||||
|
||||
export function getNavigatorLockFeatureFlagThreshold() {
|
||||
const str = localStorage.getItem('supabase.dashboard.auth.ff.threshold.navigatorLock')
|
||||
|
||||
return str ? parseInt(str) : null
|
||||
}
|
||||
|
||||
function determineNavigatorLockFeatureFlagThreshold() {
|
||||
if (getNavigatorLockFeatureFlagThreshold()) {
|
||||
return
|
||||
}
|
||||
|
||||
localStorage.setItem(
|
||||
'supabase.dashboard.auth.ff.threshold.navigatorLock',
|
||||
`${Math.floor(Math.random() * 100)}`
|
||||
)
|
||||
}
|
||||
|
||||
export function setNavigatorLockEnabled(enabled: boolean) {
|
||||
localStorage.setItem('supabase.dashboard.auth.navigatorLock.enabled', enabled ? 'true' : 'false')
|
||||
}
|
||||
|
||||
if (globalThis && globalThis.localStorage && IS_PLATFORM) {
|
||||
// populate the value based on the current local storage state
|
||||
inferSignInClicks()
|
||||
|
||||
// setup the navigator lock group on initial load
|
||||
determineNavigatorLockFeatureFlagThreshold()
|
||||
}
|
||||
Reference in new issue
Block a user