wiki_ghostguild/app/composables/useAuth.ts

70 lines
1.7 KiB
TypeScript

import type { User } from "../types/auth";
export const useAuth = () => {
const user = useState<User | null>("auth.user", () => null);
const isAuthenticated = computed(() => !!user.value);
const login = () => {
// Redirect to login endpoint
navigateTo("/api/auth/login", { external: true });
};
const logout = async () => {
try {
await $fetch("/api/auth/logout", { method: "POST" });
user.value = null;
await navigateTo("/");
} catch (error) {
console.error("Logout failed:", error);
}
};
const fetchUser = async () => {
try {
const userData = await $fetch<User>("/api/auth/me");
user.value = userData;
return userData;
} catch (error) {
user.value = null;
return null;
}
};
const hasRole = (role: string) => {
return user.value?.roles?.includes(role) || false;
};
const hasPermission = (
permission: "canEdit" | "canModerate" | "canAdmin",
) => {
return user.value?.permissions?.[permission] || false;
};
const canAccessContent = (accessLevel: string, cohorts?: string[]) => {
if (accessLevel === "public") return true;
if (!isAuthenticated.value) return false;
switch (accessLevel) {
case "member":
return true;
case "cohort":
if (!cohorts || cohorts.length === 0) return true;
return cohorts.some((c) => hasRole(`cohort-${c}`));
case "admin":
return hasPermission("canAdmin");
default:
return false;
}
};
return {
user: readonly(user),
isAuthenticated: readonly(isAuthenticated),
login,
logout,
fetchUser,
hasRole,
hasPermission,
canAccessContent,
};
};