342 lines
9.9 KiB
JavaScript
342 lines
9.9 KiB
JavaScript
import { defineStore } from 'pinia';
|
|
import { ref, computed, watch } from 'vue';
|
|
import { api, jApi } from '@/boot/axios';
|
|
import useNotify from '@/composables/useNotify.js';
|
|
import { useAppStore } from '@/stores/app.js';
|
|
|
|
const { notify } = useNotify();
|
|
const TOKEN_MULTIMEDIA = 'tokenMultimedia';
|
|
const TOKEN = 'token';
|
|
|
|
export const useUserStore = defineStore('user', () => {
|
|
const token = ref('');
|
|
const tokenMultimedia = ref('');
|
|
const isGuest = ref(false);
|
|
const user = ref(null); // Usuario en uso => supplantedUser || mainUser
|
|
const supplantedUser = ref(null); // Usuario suplantado
|
|
const mainUser = ref(null); // Usuario principal logueado
|
|
|
|
const keepLogin = ref(false);
|
|
const intervalId = ref(null);
|
|
const isCheckingToken = ref(false);
|
|
const tokenConfig = ref(null);
|
|
let router;
|
|
|
|
const storage = computed(() =>
|
|
keepLogin.value ? localStorage : sessionStorage
|
|
);
|
|
|
|
const isLoggedIn = computed(() => !!token.value);
|
|
|
|
const init = async _router => {
|
|
router = _router;
|
|
isGuest.value = localStorage.getItem('hederaGuest') || false;
|
|
await getToken();
|
|
if (!isLoggedIn.value) {
|
|
const autoLoginStatus = await tryAutoLogin();
|
|
if (!autoLoginStatus) {
|
|
router.push({ name: 'login' });
|
|
}
|
|
} else {
|
|
await fetchUser();
|
|
await fetchTokenConfig();
|
|
await supplantInit();
|
|
startInterval();
|
|
}
|
|
};
|
|
|
|
const getToken = () => {
|
|
const tokenValue =
|
|
sessionStorage.getItem(TOKEN) || localStorage.getItem(TOKEN);
|
|
token.value = tokenValue;
|
|
return tokenValue;
|
|
};
|
|
|
|
const getTokenMultimedia = () => {
|
|
const tokenMultimediaValue =
|
|
sessionStorage.getItem(TOKEN_MULTIMEDIA) ||
|
|
localStorage.getItem(TOKEN_MULTIMEDIA);
|
|
tokenMultimedia.value = tokenMultimediaValue;
|
|
return tokenMultimediaValue;
|
|
};
|
|
|
|
const setToken = ({ _token, _tokenMultimedia }) => {
|
|
storage.value.setItem(TOKEN, _token);
|
|
storage.value.setItem(TOKEN_MULTIMEDIA, _tokenMultimedia);
|
|
token.value = _token;
|
|
tokenMultimedia.value = _tokenMultimedia;
|
|
};
|
|
|
|
const destroyToken = async (url, storageType, key) => {
|
|
if (storageType.getItem(key)) {
|
|
try {
|
|
await api.post(url, null, {
|
|
headers: { Authorization: storageType.getItem(key) }
|
|
});
|
|
} catch (error) {
|
|
notify('errors.statusUnauthorized', 'negative');
|
|
} finally {
|
|
storageType.removeItem(key);
|
|
}
|
|
}
|
|
};
|
|
|
|
const destroy = async (destroyTokens = true) => {
|
|
const tokens = {
|
|
tokenMultimedia: 'Accounts/logout',
|
|
token: 'VnUsers/logout'
|
|
};
|
|
let destroyTokenPromises = [];
|
|
try {
|
|
if (destroyTokens) {
|
|
const response = await api.get('VnUsers/validateToken');
|
|
const isValidToken = response?.data;
|
|
|
|
if (isValidToken) {
|
|
destroyTokenPromises = Object.entries(tokens).map(
|
|
([key, url]) => destroyToken(url, storage.value, key)
|
|
);
|
|
}
|
|
}
|
|
} finally {
|
|
localStorage.clear();
|
|
sessionStorage.clear();
|
|
await Promise.allSettled(destroyTokenPromises);
|
|
user.value = null;
|
|
$reset();
|
|
stopRenewer();
|
|
}
|
|
};
|
|
|
|
const setSession = data => {
|
|
setToken({
|
|
_token: data.token,
|
|
_tokenMultimedia: data.tokenMultimedia
|
|
});
|
|
storage.value.setItem('hederaLastUser', data.username);
|
|
storage.value.setItem('created', data.created);
|
|
storage.value.setItem('ttl', data.ttl);
|
|
localStorage.setItem('keepLogin', keepLogin.value);
|
|
};
|
|
|
|
const fetchMultimediaToken = async data => {
|
|
try {
|
|
const response = await api.get('VnUsers/ShareToken', {
|
|
headers: { Authorization: data.token }
|
|
});
|
|
const multimediaToken = response?.data?.multimediaToken;
|
|
return multimediaToken;
|
|
} catch (error) {
|
|
throw new Error('Error fetching multimedia token');
|
|
}
|
|
};
|
|
|
|
const onLogin = async () => {
|
|
await fetchUser();
|
|
router.push({ name: 'home' });
|
|
};
|
|
|
|
const login = async (username, password, remember) => {
|
|
try {
|
|
const params = { user: username, password };
|
|
const { data } = await api.post('Accounts/login', params);
|
|
|
|
const multimediaToken = await fetchMultimediaToken(data);
|
|
if (!multimediaToken) return;
|
|
|
|
keepLogin.value = remember;
|
|
setSession({
|
|
created: Date.now(),
|
|
tokenMultimedia: multimediaToken.id,
|
|
username,
|
|
...data
|
|
});
|
|
await fetchTokenConfig();
|
|
startInterval();
|
|
await onLogin();
|
|
} catch (error) {
|
|
throw new Error('Error logging in');
|
|
}
|
|
};
|
|
|
|
const tryAutoLogin = async () => {
|
|
if (isGuest.value) {
|
|
localStorage.setItem('hederaGuest', true);
|
|
return true;
|
|
}
|
|
|
|
if (!token.value) getToken();
|
|
|
|
if (token.value) return true;
|
|
|
|
return false;
|
|
};
|
|
|
|
const logout = async () => {
|
|
try {
|
|
await destroy();
|
|
} catch (e) {}
|
|
useAppStore().onLogout();
|
|
};
|
|
|
|
const fetchTokenConfig = async () => {
|
|
try {
|
|
const { data } = await api.get('AccessTokenConfigs/findOne', {
|
|
filter: { fields: ['renewInterval', 'renewPeriod'] }
|
|
});
|
|
if (!data) return;
|
|
tokenConfig.value = data;
|
|
storage.value.setItem('renewPeriod', data.renewPeriod);
|
|
return data;
|
|
} catch (error) {
|
|
notify('errors.tokenConfig', 'negative');
|
|
console.error('Error fetching token config:', error);
|
|
}
|
|
};
|
|
|
|
const renewToken = async () => {
|
|
const _token = getToken();
|
|
const tokenData = await api.post('VnUsers/renewToken', {
|
|
headers: { Authorization: _token }
|
|
});
|
|
|
|
const _tokenMultimedia = getTokenMultimedia();
|
|
const tokenMultimedia = await api.post('VnUsers/renewToken', {
|
|
headers: { Authorization: _tokenMultimedia }
|
|
});
|
|
|
|
setToken({
|
|
_token: tokenData?.data?.id || '',
|
|
_tokenMultimedia: tokenMultimedia?.data?.id || ''
|
|
});
|
|
};
|
|
|
|
const checkValidity = async () => {
|
|
const created = +storage.value.getItem('created');
|
|
const ttl = +storage.value.getItem('ttl');
|
|
|
|
if (isCheckingToken.value || !created) return;
|
|
isCheckingToken.value = true;
|
|
|
|
const renewPeriodInSeconds =
|
|
Math.min(ttl, tokenConfig.value?.renewPeriod) * 1000;
|
|
const maxDate = created + renewPeriodInSeconds;
|
|
const now = new Date().getTime();
|
|
|
|
if (isNaN(renewPeriodInSeconds) || now <= maxDate) {
|
|
isCheckingToken.value = false;
|
|
return;
|
|
}
|
|
|
|
await renewToken();
|
|
isCheckingToken.value = false;
|
|
};
|
|
|
|
const stopRenewer = () => {
|
|
clearInterval(intervalId.value);
|
|
};
|
|
|
|
const startInterval = () => {
|
|
stopRenewer();
|
|
const renewPeriod = +storage.value.getItem('renewPeriod');
|
|
if (!renewPeriod) return;
|
|
intervalId.value = setInterval(
|
|
() => checkValidity(),
|
|
renewPeriod * 1000
|
|
);
|
|
};
|
|
|
|
const fetchUser = async (userType = 'user') => {
|
|
try {
|
|
const userData = await api.get('VnUsers/getCurrentUserData');
|
|
|
|
if (userType === 'user') mainUser.value = userData.data;
|
|
else supplantedUser.value = userData.data;
|
|
} catch (error) {
|
|
console.error('Error fetching user: ', error);
|
|
}
|
|
};
|
|
|
|
const supplantUser = async supplantUser => {
|
|
const json = await jApi.send('client/supplant', { supplantUser });
|
|
token.value = json;
|
|
sessionStorage.setItem('supplantUser', supplantUser);
|
|
await fetchUser('supplantedUser');
|
|
};
|
|
|
|
const supplantInit = async () => {
|
|
const user = sessionStorage.getItem('supplantUser');
|
|
if (!user) return;
|
|
await supplantUser(user);
|
|
};
|
|
|
|
const logoutSupplantedUser = async () => {
|
|
sessionStorage.removeItem('supplantUser');
|
|
supplantedUser.value = null;
|
|
await api.post('Accounts/logout');
|
|
getToken();
|
|
await fetchUser();
|
|
};
|
|
|
|
const updateUserLang = async lang => {
|
|
if (!user.value || user.value.lang === lang) return;
|
|
user.value.lang = lang;
|
|
};
|
|
|
|
const $reset = () => {
|
|
token.value = '';
|
|
tokenMultimedia.value = '';
|
|
isGuest.value = false;
|
|
user.value = null;
|
|
supplantedUser.value = null;
|
|
mainUser.value = null;
|
|
keepLogin.value = false;
|
|
intervalId.value = null;
|
|
isCheckingToken.value = false;
|
|
tokenConfig.value = null;
|
|
};
|
|
|
|
watch(
|
|
[mainUser, supplantedUser],
|
|
() => (user.value = supplantedUser.value || mainUser.value),
|
|
{ immediate: true }
|
|
);
|
|
|
|
return {
|
|
token,
|
|
tokenMultimedia,
|
|
isGuest,
|
|
user,
|
|
supplantedUser,
|
|
mainUser,
|
|
keepLogin,
|
|
intervalId,
|
|
isCheckingToken,
|
|
tokenConfig,
|
|
isLoggedIn,
|
|
storage,
|
|
getToken,
|
|
getTokenMultimedia,
|
|
setToken,
|
|
destroyToken,
|
|
destroy,
|
|
setSession,
|
|
login,
|
|
tryAutoLogin,
|
|
logout,
|
|
fetchTokenConfig,
|
|
renewToken,
|
|
checkValidity,
|
|
stopRenewer,
|
|
startInterval,
|
|
fetchUser,
|
|
supplantUser,
|
|
supplantInit,
|
|
logoutSupplantedUser,
|
|
updateUserLang,
|
|
init,
|
|
$reset,
|
|
onLogin
|
|
};
|
|
});
|