haumdaucher_de/src/composables/useAuth.ts

80 lines
2.2 KiB
TypeScript

import { ref, watchEffect, computed } from 'vue'
import { auth, db } from '../firebase'
import { GoogleAuthProvider, signInWithPopup, signOut, type User } from 'firebase/auth'
import { doc, onSnapshot } from 'firebase/firestore'
// Global state
const user = ref<User | null>(null)
const isAllowed = ref(false)
const isLoading = ref(true)
const error = ref<string | null>(null)
// Watch auth state
auth.onAuthStateChanged((u) => {
console.log("🔥 Auth State Changed:", u ? u.email : "Logged Out")
user.value = u
if (!u) {
isAllowed.value = false
isLoading.value = false
}
})
// Check allowlist
watchEffect((onCleanup) => {
if (!user.value) return
// Subscribe to the config/allowlist document
const allowlistRef = doc(db, 'config', 'allowlist')
const unsubscribe = onSnapshot(allowlistRef, (docSnap) => {
isLoading.value = false
if (docSnap.exists()) {
const data = docSnap.data()
const emails = data.emails || []
isAllowed.value = emails.includes(user.value?.email)
} else {
isAllowed.value = false // Config doc missing -> deny all
}
}, (err) => {
console.error("Failed to check allowlist", err)
error.value = "Failed to check allowlist: " + err.message
isLoading.value = false
})
onCleanup(() => unsubscribe())
})
export function useAuth() {
const login = async () => {
error.value = null
try {
const provider = new GoogleAuthProvider()
await signInWithPopup(auth, provider)
} catch (e: any) {
console.error("Login failed", e)
error.value = e.message
throw e
}
}
const logout = async () => {
error.value = null
try {
await signOut(auth)
user.value = null
isAllowed.value = false
} catch (e: any) {
console.error("Logout failed", e)
error.value = e.message
}
}
return {
user,
isAllowed: computed(() => isAllowed.value),
isLoading: computed(() => isLoading.value),
error: computed(() => error.value),
login,
logout
}
}