70 lines
1.7 KiB
TypeScript
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,
|
|
};
|
|
};
|