import api from "src/api"; import { permissionStore } from "src/stores/permission"; import { useAuthStorage } from "src/composables/useAuthStorage"; import { APPROVAL_STATUS, useProviderApproval } from "src/composables/useProviderApproval"; import { usePushNotifications } from "src/composables/usePushNotifications"; import { userStore } from "src/stores/user"; let refreshPromise = null; export const useAuth = () => { const { setRefreshToken, getRefreshToken, clearRefreshToken } = useAuthStorage(); const clearAuthData = async () => { userStore().resetUser(); permissionStore().resetScopes(); await clearRefreshToken(); }; const setAuthDataFromPayload = async (tokens) => { const { access_token, refresh_token, user } = tokens; const store = userStore(); store.setUser(user); store.accessToken = access_token; await setRefreshToken(refresh_token); // Fire-and-forget: o boot só consegue registrar o token quando o app abre // já autenticado. Quem acabou de se cadastrar ou de entrar registra aqui. registerPushDevice(); if (String(user?.type).toUpperCase() === "PROVIDER" && !user?.provider) { await store.fetchUser(); } if (useProviderApproval().isPendingProvider.value) { permissionStore().resetScopes(); return; } await permissionStore().fetchScopes(); }; /** * Reconsulta o cadastro do prestador em análise e, se ele já tiver sido * aprovado, carrega os escopos para liberar o app sem exigir novo login. * * @return {Promise} true quando o cadastro acabou de ser aprovado. */ const refreshApprovalStatus = async () => { const { approvalStatus, isPendingProvider } = useProviderApproval(); if (!isPendingProvider.value) { return false; } await userStore().fetchUser(); if (approvalStatus.value !== APPROVAL_STATUS.ACCEPTED) { return false; } await permissionStore().fetchScopes(); return true; }; /** * Garante que o dispositivo esteja apto a receber push depois do login: * envia o token já capturado e (re)solicita o registro no FCM. */ const registerPushDevice = async () => { const { isSupported, requestPermissionAndRegister, syncDeviceToken } = usePushNotifications(); if (!isSupported()) { return; } try { await syncDeviceToken(); await requestPermissionAndRegister(); } catch (error) { console.error(error); } }; // const login = async (email, password) => { try { const response = await api.post("/login", { email: email, password: password, }); if (response.status === 200) { await setAuthDataFromPayload(response.data.payload); } return response; } catch (error) { return Promise.reject(error); } }; const logout = async () => { try { // Precisa acontecer antes do /logout, enquanto o token ainda é válido. await usePushNotifications().unregisterDeviceToken(); const response = await api.post("/logout"); if (response.status === 200) { await clearAuthData(); } } catch (error) { console.error(error); await clearAuthData(); } }; // const doRefresh = async () => { try { const refreshToken = await getRefreshToken(); if (!refreshToken) { return Promise.reject(new Error("No refresh token available")); } const response = await api.post("/refresh-app", { refresh_token: refreshToken, }); if (response.status === 200) { await setAuthDataFromPayload(response.data.payload); } return response; } catch (error) { await clearAuthData(); return Promise.reject(error); } }; const refresh = () => { if (!refreshPromise) { refreshPromise = doRefresh().finally(() => { refreshPromise = null; }); } return refreshPromise; }; return { clearAuthData, login, logout, refresh, refreshApprovalStatus, setAuthDataFromPayload, }; };