0
1
Fork 0
hedera-web-mindshore/src/stores/user.js

350 lines
10 KiB
JavaScript

import { defineStore } from 'pinia';
import { ref, computed, watch } from 'vue';
import { api, jApi } from 'boot/axios';
import { i18n } from 'src/boot/i18n';
import useNotify from 'src/composables/useNotify.js';
import { useAppStore } from 'src/stores/app.js';
const { t } = i18n.global;
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 localeOptions = ref([
{ label: t('langs.en'), lang: 'en-US', value: 'en' },
{ label: t('langs.es'), lang: 'es-ES', value: 'es' },
{ label: t('langs.ca'), lang: 'ca-ES', value: 'ca' },
{ label: t('langs.fr'), lang: 'fr-FR', value: 'fr' },
{ label: t('langs.pt'), lang: 'pt-PT', value: 'pt' }
]);
const keepLogin = ref(false);
const intervalId = ref(null);
const isCheckingToken = ref(false);
const tokenConfig = ref(null);
let router;
const loggedIn = computed(() => !!token.value);
const userLocaleOption = computed(() =>
localeOptions.value?.find(l => l.value === user.value?.lang)
);
const storage = computed(() =>
keepLogin.value ? localStorage : sessionStorage
);
const init = async _router => {
router = _router;
isGuest.value = localStorage.getItem('hederaGuest') || false;
await getToken();
if (!loggedIn.value) {
const autoLoginStatus = await tryAutoLogin();
if (!autoLoginStatus) {
router.push({ name: 'login' });
}
}
await fetchTokenConfig();
await fetchUser();
await supplantInit();
updateSiteLocale();
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 { data: isValidToken } = await api.get(
'VnUsers/validateToken'
);
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;
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 => {
const {
data: { multimediaToken }
} = await api.get('VnUsers/ShareToken', {
headers: { Authorization: data.token }
});
return multimediaToken;
};
const login = async (username, password, remember) => {
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();
};
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 api.post('Accounts/logout');
} catch (e) {}
destroy();
$reset();
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 jApi.getObject(
'SELECT id, nickname, name, lang FROM account.myUser'
);
if (userType === 'user') mainUser.value = userData;
else supplantedUser.value = userData;
} 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 updateSiteLocale = (locale = null) => {
i18n.global.locale.value =
locale || userLocaleOption.value?.lang || 'en-US';
};
const updateUserLang = async lang => {
if (!user.value || user.value.lang === lang) return;
user.value.lang = lang;
updateSiteLocale();
notify(t('dataSaved'), 'positive');
};
const $reset = () => {
token.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,
isGuest,
user,
supplantedUser,
mainUser,
localeOptions,
keepLogin,
intervalId,
isCheckingToken,
tokenConfig,
loggedIn,
userLocaleOption,
storage,
getToken,
getTokenMultimedia,
setToken,
destroyToken,
destroy,
setSession,
login,
tryAutoLogin,
logout,
fetchTokenConfig,
renewToken,
checkValidity,
stopRenewer,
startInterval,
fetchUser,
supplantUser,
supplantInit,
logoutSupplantedUser,
updateSiteLocale,
updateUserLang,
init,
$reset
};
});