UNPKG

nuxt-users

Version:

A comprehensive user management module for Nuxt 3 and Nuxt 4 applications with authentication, authorization, database support, and CLI tools

129 lines (128 loc) 3.92 kB
import { useState, useRuntimeConfig, useFetch } from "#app"; import { computed, readonly } from "vue"; let initializationPromise = null; export const useAuthentication = () => { const user = useState("user", () => null); const { public: { nuxtUsers } } = useRuntimeConfig(); const apiBasePath = nuxtUsers?.apiBasePath; const isAuthenticated = computed(() => !!user.value); const login = (userData, rememberMe = false) => { const { password: _, ...userWithoutPassword } = userData; user.value = userWithoutPassword; if (import.meta.client) { localStorage.removeItem("user"); sessionStorage.removeItem("user"); if (rememberMe) { localStorage.setItem("user", JSON.stringify(userWithoutPassword)); return; } sessionStorage.setItem("user", JSON.stringify(userWithoutPassword)); } }; const logout = async () => { try { await $fetch(`${apiBasePath}/session`, { method: "DELETE" }); user.value = null; if (import.meta.client) { localStorage.removeItem("user"); sessionStorage.removeItem("user"); } } catch (error) { console.error("Logout failed:", error); user.value = null; if (import.meta.client) { localStorage.removeItem("user"); sessionStorage.removeItem("user"); } } }; const fetchUser = async (useSSR = false) => { try { let userData = null; if (useSSR) { const { data, error } = await useFetch(`${apiBasePath}/me`, { server: true, lazy: false }); if (error.value) { throw new Error(error.value.message || "Failed to fetch user"); } userData = data.value?.user || null; } if (!useSSR) { const response = await $fetch(`${apiBasePath}/me`, { method: "GET" }); userData = response.user; } if (!userData) { throw new Error("No user data received"); } user.value = userData; if (import.meta.client) { const wasInLocalStorage = localStorage.getItem("user") !== null; const wasInSessionStorage = sessionStorage.getItem("user") !== null; if (wasInLocalStorage) { localStorage.setItem("user", JSON.stringify(userData)); } if (wasInSessionStorage) { sessionStorage.setItem("user", JSON.stringify(userData)); } if (!wasInLocalStorage && !wasInSessionStorage) { sessionStorage.setItem("user", JSON.stringify(userData)); } } return userData; } catch (error) { console.error("Failed to fetch user:", error); user.value = null; if (import.meta.client) { localStorage.removeItem("user"); sessionStorage.removeItem("user"); } return null; } }; const initializeUser = async () => { if (!import.meta.client) { return; } if (initializationPromise) { return initializationPromise; } initializationPromise = (async () => { const storedUserLocal = localStorage.getItem("user"); const storedUserSession = sessionStorage.getItem("user"); const storedUser = storedUserLocal || storedUserSession; if (storedUser) { try { user.value = JSON.parse(storedUser); await fetchUser(); } catch (error) { console.error("Failed to parse stored user:", error); localStorage.removeItem("user"); sessionStorage.removeItem("user"); user.value = null; } return; } try { await fetchUser(); } catch { } })().catch((_error) => { }); return initializationPromise; }; if (import.meta.client && !initializationPromise) { initializeUser(); } return { user: readonly(user), isAuthenticated, login, logout, fetchUser, initializeUser }; };