diff --git a/src/App.vue b/src/App.vue
index 1e865e99..2771cb35 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -2,11 +2,14 @@
import { useAppStore } from 'stores/app';
import { useUserStore } from 'stores/user';
import { onBeforeMount } from 'vue';
+import { useRouter } from 'vue-router';
+
const appStore = useAppStore();
const userStore = useUserStore();
+const router = useRouter();
onBeforeMount(async () => {
- await userStore.init();
+ await userStore.init(router);
await appStore.init();
});
diff --git a/src/layouts/MainLayout.vue b/src/layouts/MainLayout.vue
index 94daa6f8..228a342c 100644
--- a/src/layouts/MainLayout.vue
+++ b/src/layouts/MainLayout.vue
@@ -13,7 +13,7 @@ const appStore = useAppStore();
const hiddenMenuItems = new Set(['Reports']);
const refreshContentKey = ref(0);
-const { user, supplantedUser } = storeToRefs(userStore);
+const { mainUser, supplantedUser } = storeToRefs(userStore);
const { menuEssentialLinks, title, subtitle, useRightDrawer, rightDrawerOpen } =
storeToRefs(appStore);
const actions = ref(null);
@@ -82,7 +82,7 @@ const logoutSupplantedUser = async () => {
- {{ user?.nickname }}
+ {{ mainUser?.nickname }}
diff --git a/src/stores/app.js b/src/stores/app.js
index ed16085e..8f480997 100644
--- a/src/stores/app.js
+++ b/src/stores/app.js
@@ -68,7 +68,6 @@ export const useAppStore = defineStore('hedera', {
},
async init() {
- // this.router.push({ name: 'login' });
this.getBasketOrderId();
this.getLocaleDates();
},
@@ -155,6 +154,10 @@ export const useAppStore = defineStore('hedera', {
isTablet() {
const $q = useQuasar();
return $q?.screen?.width <= 1024;
+ },
+ isDesktop() {
+ const $q = useQuasar();
+ return $q?.screen?.width > 1024;
}
}
});
diff --git a/src/stores/user.js b/src/stores/user.js
index 11ec29c6..0042fe41 100644
--- a/src/stores/user.js
+++ b/src/stores/user.js
@@ -1,4 +1,5 @@
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';
@@ -7,254 +8,308 @@ import { useAppStore } from 'src/stores/app.js';
const { t } = i18n.global;
const { notify } = useNotify();
-export const useUserStore = defineStore('user', {
- state: () => {
- return {
- token: '',
- isGuest: false,
- user: null,
- supplantedUser: null,
- localeOptions: [
- { 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' }
- ],
- keepLogin: false,
- intervalId: null,
- isCheckingToken: false,
- tokenConfig: null
- };
- },
+export const useUserStore = defineStore('user', () => {
+ const token = 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;
- getters: {
- loggedIn: state => !!state.token,
- userLocaleOption: state =>
- state.localeOptions?.find(l => l.value === state?.user?.lang),
- storage: state => (state.keepLogin ? localStorage : sessionStorage)
- },
+ const loggedIn = computed(() => !!token.value);
+ const userLocaleOption = computed(() =>
+ localeOptions.value?.find(l => l.value === user.value?.lang)
+ );
+ const storage = computed(() =>
+ keepLogin.value ? localStorage : sessionStorage
+ );
- actions: {
- async init() {
- this.isGuest = localStorage.getItem('hederaGuest') || false;
- await this.getToken();
- if (!this.loggedIn) {
- const autoLoginStatus = await this.tryAutoLogin();
- if (!autoLoginStatus) {
- this.router.push({ name: 'login' });
- }
- return;
+ const init = async _router => {
+ router = _router;
+ isGuest.value = localStorage.getItem('hederaGuest') || false;
+ console.log('isGuest.value', isGuest.value);
+ await getToken();
+ if (!loggedIn.value) {
+ const autoLoginStatus = await tryAutoLogin();
+ if (!autoLoginStatus) {
+ router.push({ name: 'login' });
}
- await this.fetchTokenConfig();
- await this.fetchUser();
- await this.supplantInit();
- this.updateSiteLocale();
- this.startInterval();
- },
-
- getToken() {
- const token =
- sessionStorage.getItem('vnToken') ||
- localStorage.getItem('vnToken');
- this.token = token;
- return token;
- },
-
- setToken(token) {
- this.storage.setItem('vnToken', token);
- this.token = token;
- },
-
- async destroyToken(url, storage, key) {
- if (storage.getItem(key)) {
- try {
- await api.post(url, null, {
- headers: { Authorization: storage.getItem(key) }
- });
- } catch (error) {
- notify('errors.statusUnauthorized', 'negative');
- } finally {
- storage.removeItem(key);
- }
- }
- },
-
- async destroy(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]) =>
- this.destroyToken(url, this.storage, key)
- );
- }
- } finally {
- localStorage.clear();
- sessionStorage.clear();
- await Promise.allSettled(destroyTokenPromises);
- this.user = null;
- this.stopRenewer();
- }
- },
-
- isLoggedIn() {
- const token = this.getToken();
- return !!token;
- },
-
- setSession(data) {
- this.storage.setItem('created', data.created);
- this.storage.setItem('ttl', data.ttl);
- localStorage.setItem('keepLogin', this.keepLogin);
- },
-
- async login(user, password, remember) {
- const params = { user, password };
- const { data } = await api.post('Accounts/login', params);
- this.name = user;
- this.keepLogin = remember;
- this.setToken(data.token);
- this.setSession({ created: Date.now(), ...data });
- await this.fetchTokenConfig();
- this.startInterval();
- },
-
- async tryAutoLogin() {
- const guest = localStorage.getItem('hederaGuest');
-
- if (this.isGuest || guest) {
- localStorage.setItem('hederaGuest', true);
- return true;
- }
-
- if (!this.token) this.getToken();
-
- if (this.token) return true;
-
- return false;
- },
-
- async logout() {
- try {
- await api.post('Accounts/logout');
- } catch (e) {}
- this.destroy();
- this.$reset();
- useAppStore().onLogout();
- },
-
- async fetchTokenConfig() {
- try {
- const { data } = await api.get('AccessTokenConfigs/findOne', {
- filter: { fields: ['renewInterval', 'renewPeriod'] }
- });
- if (!data) return;
- this.tokenConfig = data;
- this.storage.setItem('renewPeriod', data.renewPeriod);
- return data;
- } catch (error) {
- notify('errors.tokenConfig', 'negative');
- console.error('Error fetching token config:', error);
- }
- },
-
- async renewToken() {
- const _token = this.getToken();
- const token = await api.post('VnUsers/renewToken', {
- headers: { Authorization: _token }
- });
-
- this.setToken(token.data.id);
- },
-
- async checkValidity() {
- const created = +this.storage.getItem('created');
- const ttl = +this.storage.getItem('ttl');
-
- if (this.isCheckingToken || !created) return;
- this.isCheckingToken = true;
-
- const renewPeriodInSeconds =
- Math.min(ttl, this.tokenConfig?.renewPeriod) * 1000;
- const maxDate = created + renewPeriodInSeconds;
- const now = new Date().getTime();
-
- if (isNaN(renewPeriodInSeconds) || now <= maxDate) {
- return (this.isCheckingToken = false);
- }
-
- await this.renewToken();
- this.isCheckingToken = false;
- },
-
- stopRenewer() {
- clearInterval(this.intervalId);
- },
-
- startInterval() {
- this.stopRenewer();
- const renewPeriod = +this.storage.getItem('renewPeriod');
- if (!renewPeriod) return;
- this.intervalId = setInterval(
- () => this.checkValidity(),
- renewPeriod * 1000
- );
- },
-
- async fetchUser(userType = 'user') {
- try {
- const userData = await jApi.getObject(
- 'SELECT id, nickname, name, lang FROM account.myUser'
- );
- this.$patch({ [userType]: userData });
- } catch (error) {
- console.error('Error fetching user: ', error);
- }
- },
-
- async supplantUser(supplantUser) {
- const json = await jApi.send('client/supplant', {
- supplantUser
- });
- this.token = json;
- sessionStorage.setItem('supplantUser', supplantUser);
- await this.fetchUser('supplantedUser');
- },
-
- async supplantInit() {
- const user = sessionStorage.getItem('supplantUser');
- if (user == null) return;
- await this.supplantUser(user);
- },
-
- async logoutSupplantedUser() {
- sessionStorage.removeItem('supplantUser');
- this.supplantedUser = null;
- await api.post('Accounts/logout');
- this.getToken();
- await this.fetchUser();
- },
-
- updateSiteLocale(locale = null) {
- i18n.global.locale.value =
- locale || this.userLocaleOption.lang || 'en-US';
- },
-
- async updateUserLang(lang) {
- if (!this.user || this.user.lang === lang) return;
-
- this.user.lang = lang;
- this.updateSiteLocale();
- notify(t('dataSaved'), 'positive');
}
- }
+ await fetchTokenConfig();
+ await fetchUser();
+ await supplantInit();
+ updateSiteLocale();
+ startInterval();
+ };
+
+ const getToken = () => {
+ const tokenValue =
+ sessionStorage.getItem('vnToken') ||
+ localStorage.getItem('vnToken');
+ token.value = tokenValue;
+ return tokenValue;
+ };
+
+ const setToken = _token => {
+ storage.value.setItem('vnToken', _token);
+ token.value = _token;
+ };
+
+ 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 => {
+ storage.value.setItem('created', data.created);
+ storage.value.setItem('ttl', data.ttl);
+ localStorage.setItem('keepLogin', keepLogin.value);
+ };
+
+ const login = async (username, password, remember) => {
+ const params = { user: username, password };
+ const { data } = await api.post('Accounts/login', params);
+ keepLogin.value = remember;
+ storage.value.setItem('hederaLastUser', username);
+ setToken(data.token);
+ setSession({ created: Date.now(), ...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 }
+ });
+ setToken(tokenData.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();
+ console.log('renewPeriodInSeconds', renewPeriodInSeconds);
+ console.log('maxDate', maxDate);
+ console.log('now', now);
+
+ 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');
+ const renewPeriod = 5;
+ 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;
+ console.log('mainUser.value', mainUser.value);
+ console.log('supplantedUser.value', supplantedUser.value);
+ console.log('user.value', user.value);
+ },
+ { immediate: true }
+ );
+
+ return {
+ token,
+ isGuest,
+ user,
+ supplantedUser,
+ mainUser,
+ localeOptions,
+ keepLogin,
+ intervalId,
+ isCheckingToken,
+ tokenConfig,
+ loggedIn,
+ userLocaleOption,
+ storage,
+ getToken,
+ setToken,
+ destroyToken,
+ destroy,
+ setSession,
+ login,
+ tryAutoLogin,
+ logout,
+ fetchTokenConfig,
+ renewToken,
+ checkValidity,
+ stopRenewer,
+ startInterval,
+ fetchUser,
+ supplantUser,
+ supplantInit,
+ logoutSupplantedUser,
+ updateSiteLocale,
+ updateUserLang,
+ init,
+ $reset
+ };
});