200 lines
6.0 KiB
JavaScript
200 lines
6.0 KiB
JavaScript
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,
|
|
};
|
|
}
|