mirror of
https://github.com/supabase/supabase.git
synced 2026-05-07 17:30:25 -04:00
cac225b24a
* Clean up barrel files part 4 * nit
108 lines
3.3 KiB
TypeScript
108 lines
3.3 KiB
TypeScript
import type { JwtPayload } from '@supabase/supabase-js'
|
|
import { type User } from 'common/auth'
|
|
import { gotrueClient } from 'common/gotrue'
|
|
|
|
export const auth = gotrueClient
|
|
|
|
export const DEFAULT_FALLBACK_PATH = '/organizations'
|
|
|
|
export const validateReturnTo = (
|
|
returnTo: string,
|
|
fallback: string = DEFAULT_FALLBACK_PATH
|
|
): string => {
|
|
// Block protocol-relative URLs and external URLs
|
|
if (returnTo.startsWith('//') || returnTo.includes('://')) {
|
|
return fallback
|
|
}
|
|
|
|
// For internal paths:
|
|
// 1. Must start with /
|
|
// 2. Only allow alphanumeric chars, slashes, hyphens, underscores
|
|
// 3. For query params, also allow =, &, and ?
|
|
const safePathPattern = /^\/[a-zA-Z0-9/\-_]*(?:\?[a-zA-Z0-9\-_=&]*)?$/
|
|
return safePathPattern.test(returnTo) ? returnTo : fallback
|
|
}
|
|
|
|
export const getUserClaims = async (
|
|
token: String
|
|
): Promise<{ error: any | null; claims: JwtPayload | null }> => {
|
|
try {
|
|
const { data, error } = await auth.getClaims(token.replace(/bearer /i, ''))
|
|
if (error) throw error
|
|
|
|
return { claims: data?.claims ?? null, error: null }
|
|
} catch (err) {
|
|
console.error(err)
|
|
return { claims: null, error: err }
|
|
}
|
|
}
|
|
|
|
export const getAuth0Id = (provider: String, providerId: String): String => {
|
|
return `${provider}|${providerId}`
|
|
}
|
|
|
|
export const getIdentity = (gotrueUser: User) => {
|
|
try {
|
|
if (gotrueUser !== undefined && gotrueUser.identities !== undefined) {
|
|
return { identity: gotrueUser.identities[0], error: null }
|
|
}
|
|
throw 'Missing identity'
|
|
} catch (err) {
|
|
return { identity: null, error: err }
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Transfers the search params from the current location path to a newly built path
|
|
*/
|
|
export const buildPathWithParams = (pathname: string) => {
|
|
const [basePath, existingParams] = pathname.split('?', 2)
|
|
|
|
const pathnameSearchParams = new URLSearchParams(existingParams || '')
|
|
|
|
// Merge the parameters, with pathname parameters taking precedence
|
|
// over the current location's search parameters
|
|
const mergedParams = new URLSearchParams(location.search)
|
|
for (const [key, value] of pathnameSearchParams.entries()) {
|
|
mergedParams.set(key, value)
|
|
}
|
|
|
|
const queryString = mergedParams.toString()
|
|
return queryString ? `${basePath}?${queryString}` : basePath
|
|
}
|
|
|
|
export const getReturnToPath = (fallback = DEFAULT_FALLBACK_PATH) => {
|
|
// If we're in a server environment, return the fallback
|
|
if (typeof location === 'undefined') {
|
|
return fallback
|
|
}
|
|
|
|
const searchParams = new URLSearchParams(location.search)
|
|
|
|
let returnTo = searchParams.get('returnTo') ?? fallback
|
|
|
|
if (process.env.NEXT_PUBLIC_BASE_PATH) {
|
|
returnTo = returnTo.replace(process.env.NEXT_PUBLIC_BASE_PATH, '')
|
|
}
|
|
|
|
searchParams.delete('returnTo')
|
|
|
|
const remainingSearchParams = searchParams.toString()
|
|
const validReturnTo = validateReturnTo(returnTo, fallback)
|
|
|
|
const [path, existingQuery] = validReturnTo.split('?')
|
|
|
|
const finalSearchParams = new URLSearchParams(existingQuery || '')
|
|
|
|
// Add all remaining search params to the final search params
|
|
if (remainingSearchParams) {
|
|
const remainingParams = new URLSearchParams(remainingSearchParams)
|
|
remainingParams.forEach((value, key) => {
|
|
finalSearchParams.append(key, value)
|
|
})
|
|
}
|
|
|
|
const finalQuery = finalSearchParams.toString()
|
|
return path + (finalQuery ? `?${finalQuery}` : '')
|
|
}
|