import { jwtDecode } from 'jwt-decode' import { getAuth, signInWithPopup, GoogleAuthProvider, signOut, onAuthStateChanged } from 'firebase/auth' interface User { id: string email: string username: string displayName?: string role?: string } export const useAuth = () => { const token = useCookie('xflow_token', { maxAge: 60 * 60 * 24 * 7, sameSite: 'strict' }) const user = computed(() => { if (!token.value) return null try { return jwtDecode(token.value) } catch { return null } }) const isAuthenticated = computed(() => !!token.value && !!user.value) const isAdmin = computed(() => user.value?.role === 'admin') const googleSignIn = async () => { const auth = getAuth() const provider = new GoogleAuthProvider() const result = await signInWithPopup(auth, provider) const idToken = await result.user.getIdToken() const res = await $fetch<{ token: string; user: User }>('/api/auth/google', { method: 'POST', body: { idToken } }) token.value = res.token await navigateTo('/') } const logout = async () => { try { const auth = getAuth() await signOut(auth) } catch (e) { console.warn('[Firebase] Sign out failed or not initialized', e) } finally { token.value = null navigateTo('/login') } } const initAuth = () => { const auth = getAuth() onAuthStateChanged(auth, async (firebaseUser) => { // If user is authenticated in Firebase but we lost our backend token, try to restore if (firebaseUser && !token.value) { try { const idToken = await firebaseUser.getIdToken() const res = await $fetch<{ token: string; user: User }>('/api/auth/google', { method: 'POST', body: { idToken } }) token.value = res.token if (useRoute().path === '/login') { navigateTo('/') } } catch (e) { console.error('Failed to restore backend auth from Firebase', e) } } }) } return { token, user, isAuthenticated, isAdmin, googleSignIn, logout, initAuth } }