feat(frontend): Use betterAuth implementation from nuxthub-better-auth project

This commit is contained in:
2025-04-20 09:54:16 +02:00
parent 4e7a962a06
commit eec15dd7ef
17 changed files with 209 additions and 66 deletions

View File

@@ -0,0 +1,84 @@
// Copied from https://github.com/atinux/nuxthub-better-auth
import { defu } from 'defu'
import { createAuthClient } from 'better-auth/client'
import type { InferSessionFromClient, InferUserFromClient, ClientOptions } from 'better-auth/client'
import { organizationClient } from 'better-auth/client/plugins'
import type { RouteLocationRaw } from 'vue-router'
interface RuntimeAuthConfig {
redirectUserTo: RouteLocationRaw | string
redirectGuestTo: RouteLocationRaw | string
}
export function useAuth() {
const url = useRequestURL()
const headers = import.meta.server ? useRequestHeaders() : undefined
const client = createAuthClient({
baseURL: url.origin,
fetchOptions: {
headers
},
plugins: [organizationClient()]
})
const options = defu(useRuntimeConfig().public.auth as Partial<RuntimeAuthConfig>, {
redirectUserTo: '/',
redirectGuestTo: '/login'
})
const session = useState<InferSessionFromClient<ClientOptions> | null>('auth:session', () => null)
const user = useState<InferUserFromClient<ClientOptions> | null>('auth:user', () => null)
const sessionFetching = import.meta.server ? ref(false) : useState('auth:sessionFetching', () => false)
const fetchSession = async () => {
if (sessionFetching.value) {
console.log('already fetching session')
return
}
sessionFetching.value = true
const { data } = await client.getSession({
fetchOptions: {
headers
}
})
session.value = data?.session || null
user.value = data?.user || null
sessionFetching.value = false
return data
}
if (import.meta.client) {
client.$store.listen('$sessionSignal', async (signal) => {
if (!signal) return
await fetchSession()
})
}
async function signOut({ redirectTo }: { redirectTo?: RouteLocationRaw } = {}) {
const res = await client.signOut()
if (res.error) {
console.error('Error signing out:', res.error)
return res
}
session.value = null
user.value = null
if (redirectTo) {
await navigateTo(redirectTo)
}
return res
}
return {
session,
user,
loggedIn: computed(() => !!session.value),
signIn: client.signIn,
signUp: client.signUp,
signOut,
organization: client.organization,
options,
fetchSession,
client
}
}

View File

@@ -3,6 +3,7 @@ const selectedOrgId = ref<string | undefined>(undefined)
export function useBetterAuth() {
const toast = useToast()
const { organization } = useAuth()
async function createOrganization(name: string, slug: string, logo?: string) {
await organization.create(
@@ -25,7 +26,7 @@ export function useBetterAuth() {
}
async function deleteOrganization() {
await authClient.organization.delete(
await organization.delete(
{ organizationId: activeOrganization.value?.id ?? '' },
{
onSuccess: () => {
@@ -41,7 +42,7 @@ export function useBetterAuth() {
}
async function getInvitation(invitationId: string): Promise<CustomInvitation> {
return authClient.organization.getInvitation({
return organization.getInvitation({
query: { id: invitationId },
fetchOptions: {
throw: true,
@@ -56,7 +57,7 @@ export function useBetterAuth() {
}
async function inviteMember(email: string, role: 'member' | 'admin') {
await authClient.organization.inviteMember({
await organization.inviteMember({
email,
role,
fetchOptions: {
@@ -77,7 +78,7 @@ export function useBetterAuth() {
}
async function acceptInvitation(invitationId: string) {
await authClient.organization.acceptInvitation({
await organization.acceptInvitation({
invitationId,
fetchOptions: {
throw: true,
@@ -93,7 +94,7 @@ export function useBetterAuth() {
}
async function rejectInvitation(invitationId: string) {
await authClient.organization.rejectInvitation({
await organization.rejectInvitation({
invitationId,
fetchOptions: {
throw: true,