| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- import { computed, readonly, ref } from "vue";
- import { loginRequest, logoutRequest, refreshTokenRequest } from "../api/auth.js";
- import { setAccessToken, setRefreshCallback, setAuthErrorCallback } from "../api/client.js";
- import { resetChatSingleton } from "./useChat.js";
- const LOCAL_STORAGE_KEY = "auth.session";
- const SESSION_STORAGE_KEY = "auth.session.temp";
- function getStorage(kind) {
- if (typeof window === "undefined") return null;
- return kind === "local" ? window.localStorage : window.sessionStorage;
- }
- function loadStoredSession() {
- for (const kind of ["local", "session"]) {
- try {
- const storage = getStorage(kind);
- const raw = storage?.getItem(kind === "local" ? LOCAL_STORAGE_KEY : SESSION_STORAGE_KEY);
- if (!raw) continue;
- const parsed = JSON.parse(raw);
- if (parsed?.usuario) return parsed;
- } catch {}
- }
- return null;
- }
- function persistSession(sess) {
- try {
- getStorage("local")?.removeItem(LOCAL_STORAGE_KEY);
- getStorage("session")?.removeItem(SESSION_STORAGE_KEY);
- if (sess?.rememberMe) {
- getStorage("local")?.setItem(LOCAL_STORAGE_KEY, JSON.stringify(sess));
- return;
- }
- if (sess) {
- getStorage("session")?.setItem(SESSION_STORAGE_KEY, JSON.stringify(sess));
- }
- } catch {}
- }
- const session = ref(loadStoredSession());
- const user = computed(() => session.value?.usuario ?? null);
- const isAuthenticated = computed(() => Boolean(user.value?.Id));
- let _proactiveRefreshTimer = null;
- function scheduleProactiveRefresh(token) {
- clearTimeout(_proactiveRefreshTimer);
- if (!token) return;
- try {
- const payload = JSON.parse(atob(token.split(".")[1]));
- const delay = payload.exp * 1000 - Date.now() - 60_000;
- if (delay <= 0) return;
- _proactiveRefreshTimer = setTimeout(async () => {
- const rt = session.value?.refreshToken;
- if (!rt) return;
- try {
- const result = await refreshTokenRequest({ refreshToken: rt });
- session.value = { ...session.value, accessToken: result.accessToken };
- persistSession(session.value);
- setAccessToken(result.accessToken);
- scheduleProactiveRefresh(result.accessToken);
- } catch {
- // 401 interceptor handles expired token on next request
- }
- }, delay);
- } catch {
- // token não é JWT válido, ignora
- }
- }
- function setupAuth() {
- const token = session.value?.accessToken ?? null;
- setAccessToken(token);
- if (!token) return;
- scheduleProactiveRefresh(token);
- setRefreshCallback(async () => {
- const rt = session.value?.refreshToken;
- if (!rt) throw new Error("no_refresh_token");
- const result = await refreshTokenRequest({ refreshToken: rt });
- session.value = { ...session.value, accessToken: result.accessToken };
- persistSession(session.value);
- setAccessToken(result.accessToken);
- scheduleProactiveRefresh(result.accessToken);
- return result.accessToken;
- });
- setAuthErrorCallback(() => {
- clearTimeout(_proactiveRefreshTimer);
- resetChatSingleton();
- session.value = null;
- persistSession(null);
- setAccessToken(null);
- setRefreshCallback(null);
- setAuthErrorCallback(null);
- window.location.href = "/login";
- });
- }
- setupAuth();
- async function login({ login, senha, rememberMe = false }) {
- const payload = await loginRequest({ login, senha, rememberMe });
- session.value = {
- usuario: payload.usuario,
- accessToken: payload.accessToken ?? null,
- refreshToken: payload.refreshToken ?? null,
- rememberMe,
- savedAt: new Date().toISOString()
- };
- persistSession(session.value);
- setupAuth();
- return payload;
- }
- async function logout() {
- clearTimeout(_proactiveRefreshTimer);
- const rt = session.value?.refreshToken;
- try {
- await logoutRequest({ refreshToken: rt });
- } finally {
- resetChatSingleton();
- session.value = null;
- persistSession(null);
- setAccessToken(null);
- setRefreshCallback(null);
- setAuthErrorCallback(null);
- }
- }
- function clearSession() {
- session.value = null;
- persistSession(null);
- setAccessToken(null);
- setRefreshCallback(null);
- setAuthErrorCallback(null);
- }
- export function useAuth() {
- return {
- session: readonly(session),
- user,
- isAuthenticated,
- login,
- logout,
- clearSession
- };
- }
|