import { useState } from './useState'; import { useRole } from './useRole'; import { useAcl } from './useAcl'; import { useUserConfig } from './useUserConfig'; import axios from 'axios'; import { useRouter } from 'vue-router'; import useNotify from './useNotify'; import { useTokenConfig } from './useTokenConfig'; const TOKEN_MULTIMEDIA = 'tokenMultimedia'; const TOKEN = 'token'; export function useSession() { const router = useRouter(); const { notify } = useNotify(); let isCheckingToken = false; let intervalId = null; function getToken() { const localToken = localStorage.getItem(TOKEN); const sessionToken = sessionStorage.getItem(TOKEN); return localToken || sessionToken || ''; } function getTokenMultimedia() { const localTokenMultimedia = localStorage.getItem(TOKEN_MULTIMEDIA); const sessionTokenMultimedia = sessionStorage.getItem(TOKEN_MULTIMEDIA); return localTokenMultimedia || sessionTokenMultimedia || ''; } function setSession(data) { let keepLogin = data.keepLogin; const storage = keepLogin ? localStorage : sessionStorage; storage.setItem(TOKEN, data.token); storage.setItem(TOKEN_MULTIMEDIA, data.tokenMultimedia); storage.setItem('created', data.created); storage.setItem('ttl', data.ttl); sessionStorage.setItem('keepLogin', keepLogin); } function keepLogin() { return sessionStorage.getItem('keepLogin'); } function setToken({ token, tokenMultimedia }) { const storage = keepLogin() ? localStorage : sessionStorage; storage.setItem(TOKEN, token); storage.setItem(TOKEN_MULTIMEDIA, tokenMultimedia); } async function destroyToken(url, storage, key) { if (storage.getItem(key)) { try { await axios.post(url, null, { headers: { Authorization: storage.getItem(key) }, }); } catch (error) { notify('errors.statusUnauthorized', 'negative'); } finally { storage.removeItem(key); } } } async function destroy(destroyTokens = true) { const tokens = { tokenMultimedia: 'Accounts/logout', token: 'VnUsers/logout', }; const storage = keepLogin() ? localStorage : sessionStorage; let destroyTokenPromises = []; try { if (destroyTokens) { const { data: isValidToken } = await axios.get('VnUsers/validateToken'); if (isValidToken) destroyTokenPromises = Object.entries(tokens).map(([key, url]) => destroyToken(url, storage, key) ); } } finally { localStorage.clear(); sessionStorage.clear(); await Promise.allSettled(destroyTokenPromises); const { setUser } = useState(); setUser({ id: 0, name: '', nickname: '', lang: '', darkMode: null, }); stopRenewer(); } } async function login(data) { setSession(data); await useRole().fetch(); await useAcl().fetch(); await useUserConfig().fetch(); await useTokenConfig().fetch(); startInterval(); } async function setLogin(data) { const { data: { multimediaToken }, } = await axios.get('VnUsers/ShareToken', { headers: { Authorization: data.token }, }); if (!multimediaToken) return; await login({ ...data, created: Date.now(), tokenMultimedia: multimediaToken.id, }); notify('login.loginSuccess', 'positive'); const currentRoute = router.currentRoute.value; if (currentRoute.query?.redirect) { router.push(currentRoute.query.redirect); } else { router.push({ name: 'Dashboard' }); } } function isLoggedIn() { const localToken = localStorage.getItem(TOKEN); const sessionToken = sessionStorage.getItem(TOKEN); startInterval(); return !!(localToken || sessionToken); } function startInterval() { stopRenewer(); const renewPeriod = +sessionStorage.getItem('renewPeriod'); if (!renewPeriod) return; intervalId = setInterval(() => checkValidity(), renewPeriod * 1000); } function stopRenewer() { clearInterval(intervalId); } async function renewToken() { const _token = getToken(); const token = await axios.post('VnUsers/renewToken', { headers: { Authorization: _token }, }); const _tokenMultimedia = getTokenMultimedia(); const tokenMultimedia = await axios.post('VnUsers/renewToken', { headers: { Authorization: _tokenMultimedia }, }); setToken({ token: token.data.id, tokenMultimedia: tokenMultimedia.data.id }); } async function checkValidity() { const { getTokenConfig } = useState(); const tokenConfig = getTokenConfig() ?? sessionStorage.getItem('tokenConfig'); const storage = keepLogin() ? localStorage : sessionStorage; const created = +storage.getItem('created'); const ttl = +storage.getItem('ttl'); if (isCheckingToken || !created) return; isCheckingToken = true; const renewPeriodInSeconds = Math.min(ttl, tokenConfig.value.renewPeriod) * 1000; const maxDate = created + renewPeriodInSeconds; const now = new Date().getTime(); if (isNaN(renewPeriodInSeconds) || now <= maxDate) { return (isCheckingToken = false); } await renewToken(); isCheckingToken = false; } return { getToken, getTokenMultimedia, setToken, destroy, login, setLogin, isLoggedIn, checkValidity, setSession, renewToken, }; }