68 lines
1.9 KiB
TypeScript
68 lines
1.9 KiB
TypeScript
import { createAuthClient } from 'better-auth/client'
|
|
import type {
|
|
InferSessionFromClient,
|
|
InferUserFromClient,
|
|
BetterAuthClientOptions,
|
|
} from 'better-auth/client'
|
|
import type { RouteLocationRaw } from 'vue-router'
|
|
|
|
|
|
export function useAuth() {
|
|
const url = useRequestURL()
|
|
const headers = import.meta.server ? useRequestHeaders() : undefined
|
|
|
|
const authClient = createAuthClient({
|
|
baseURL: url.origin,
|
|
fetchOptions: {
|
|
headers,
|
|
},
|
|
})
|
|
|
|
const session = useState<InferSessionFromClient<BetterAuthClientOptions> | null>('auth:session', () => null)
|
|
const user = useState<InferUserFromClient<BetterAuthClientOptions> | null>('auth:user', () => null)
|
|
const pending = import.meta.server ? ref(false) : useState('auth:sessionFetching', () => false)
|
|
|
|
const fetchSession = async () => {
|
|
if (pending.value) {
|
|
console.log('already fetching session')
|
|
return
|
|
}
|
|
|
|
pending.value = true
|
|
const { data } = await authClient.getSession({
|
|
fetchOptions: {
|
|
headers,
|
|
},
|
|
})
|
|
|
|
session.value = data?.session || null
|
|
user.value = data?.user || null
|
|
pending.value = false
|
|
return data
|
|
}
|
|
|
|
if (import.meta.client) {
|
|
authClient.$store.listen('$sessionSignal', async (signal) => {
|
|
if (!signal) return
|
|
await fetchSession()
|
|
})
|
|
}
|
|
|
|
return {
|
|
session,
|
|
user,
|
|
pending,
|
|
loggedIn: computed(() => !!session.value),
|
|
signIn: authClient.signIn,
|
|
signUp: authClient.signUp,
|
|
async signOut() {
|
|
const res = await authClient.signOut()
|
|
session.value = null
|
|
user.value = null
|
|
await navigateTo('/auth/login')
|
|
return res
|
|
},
|
|
fetchSession,
|
|
authClient,
|
|
}
|
|
} |