From 2b24e18f755c135ae7f94e284fcf58d0cdba1b98 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Mon, 22 Apr 2024 07:37:35 +0200 Subject: [PATCH] FEAT: SETiNTERVAL WITH RENEWpERIOD --- src/composables/useSession.js | 68 +++++++++++++++++++++++-------- src/composables/useTokenConfig.js | 12 +++--- src/pages/Login/LoginMain.vue | 8 +++- src/router/index.js | 2 + 4 files changed, 64 insertions(+), 26 deletions(-) diff --git a/src/composables/useSession.js b/src/composables/useSession.js index b4c5e4abb..f308bf3e2 100644 --- a/src/composables/useSession.js +++ b/src/composables/useSession.js @@ -10,6 +10,7 @@ const TOKEN = 'token'; export function useSession() { const { notify } = useNotify(); let isCheckingToken = false; + let intervalId = null; function getToken() { const localToken = localStorage.getItem(TOKEN); @@ -24,14 +25,25 @@ export function useSession() { return localTokenMultimedia || sessionTokenMultimedia || ''; } - function setToken(data) { - let keepLogin = data.keepLogin ?? sessionStorage.getItem('keepLogin'); - if (!keepLogin) keepLogin = false; + 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 { @@ -50,11 +62,15 @@ export function useSession() { tokenMultimedia: 'Accounts/logout', token: 'VnUsers/logout', }; + const storage = keepLogin() ? localStorage : sessionStorage; + for (const [key, url] of Object.entries(tokens)) { - await destroyToken(url, localStorage, key); - await destroyToken(url, sessionStorage, key); + await destroyToken(url, storage, key); } + localStorage.clear(); + sessionStorage.clear(); + const { setUser } = useState(); setUser({ @@ -68,25 +84,33 @@ export function useSession() { stopRenewer(); } - async function login(token, tokenMultimedia, keepLogin) { - setToken({ token, tokenMultimedia, keepLogin }); + async function login(data) { + setSession(data); await useRole().fetch(); await useUserConfig().fetch(); await useTokenConfig().fetch(); - - await checkValidity(); + startInterval(); } 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); + // JUST FOR TEST + // checkValidity(); + } + function stopRenewer() { - clearInterval(this.intervalId); + clearInterval(intervalId); } async function renewToken() { @@ -98,24 +122,32 @@ export function useSession() { const tokenMultimedia = await axios.post('VnUsers/renewToken', { headers: { Authorization: _tokenMultimedia }, }); - setToken({ token, tokenMultimedia }); + setToken({ token: token.data.id, tokenMultimedia: tokenMultimedia.data.id }); } async function checkValidity() { const { getTokenConfig } = useState(); - const tokenConfig = getTokenConfig(); - const created = +localStorage.getItem('created'); - const ttl = localStorage.getItem('ttl'); + 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(); - if (now.getTime() <= maxDate) return (isCheckingToken = false); + const maxDate = created + renewPeriodInSeconds; + const now = new Date().getTime(); + + //COMMENT THIS IF JUST FOR TEST + if (isNaN(renewPeriodInSeconds) || now <= maxDate) { + console.error('Token not renewed'); + return (isCheckingToken = false); + } + console.error('Token renewed'); await renewToken(); isCheckingToken = false; diff --git a/src/composables/useTokenConfig.js b/src/composables/useTokenConfig.js index afe7a5272..600122199 100644 --- a/src/composables/useTokenConfig.js +++ b/src/composables/useTokenConfig.js @@ -8,15 +8,13 @@ export function useTokenConfig() { async function fetch() { try { - let tokenConfigState = state.getTokenConfig(); - if (tokenConfigState) return tokenConfigState; - - const tokenConfig = await axios.get('AccessTokenConfigs/findOne', { + const { data } = await axios.get('AccessTokenConfigs/findOne', { filter: { fields: ['renewInterval', 'renewPeriod'] }, }); - if (!tokenConfig) return; - state.setTokenConfig(tokenConfig); - return tokenConfig; + if (!data) return; + state.setTokenConfig(data); + sessionStorage.setItem('renewPeriod', data.renewPeriod); + return data; } catch (error) { notify('errors.tokenConfig', 'negative'); console.error('Error fetching token config:', error); diff --git a/src/pages/Login/LoginMain.vue b/src/pages/Login/LoginMain.vue index fcde51edf..5a3490f50 100644 --- a/src/pages/Login/LoginMain.vue +++ b/src/pages/Login/LoginMain.vue @@ -38,7 +38,13 @@ async function onSubmit() { if (!multimediaToken) return; - await session.login(data.token, multimediaToken.id, keepLogin.value); + const login = { + ...data, + created: Date.now(), + tokenMultimedia: multimediaToken.id, + keepLogin: keepLogin.value, + }; + await session.login(login); quasar.notify({ message: t('login.loginSuccess'), diff --git a/src/router/index.js b/src/router/index.js index 3e442f0e6..7a0aedcae 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -12,6 +12,7 @@ import { useSession } from 'src/composables/useSession'; import { useRole } from 'src/composables/useRole'; import { useUserConfig } from 'src/composables/useUserConfig'; import { toLowerCamel } from 'src/filters'; +import { useTokenConfig } from 'src/composables/useTokenConfig'; const state = useState(); const session = useSession(); @@ -55,6 +56,7 @@ export default route(function (/* { store, ssrContext } */) { if (stateRoles.length === 0) { await useRole().fetch(); await useUserConfig().fetch(); + await useTokenConfig().fetch(); } const matches = to.matched; const hasRequiredRoles = matches.every((route) => {