0
1
Fork 0

Renew token

This commit is contained in:
William Buezas 2024-10-01 14:19:34 -03:00
parent c950bf5ef1
commit 261fddb1cf
6 changed files with 168 additions and 29 deletions

View File

@ -161,5 +161,10 @@ export default {
ErrCantWrite: "No s'ha pogut escriure el fitxer al disc",
ErrExtension: "La pujada del fitxer s'ha aturat per una extensió",
ErrDefault: 'Error de pujada desconegut',
'Sync complete': 'Sincronització completa'
'Sync complete': 'Sincronització completa',
// Errors
errors: {
statusUnauthorized: 'Accés denegat',
tokenConfig: 'Error al obtenir la configuració del token'
}
};

View File

@ -194,5 +194,10 @@ export default {
ErrCantWrite: 'Failed to write file to disk',
ErrExtension: 'File upload stopped by extension',
ErrDefault: 'Unknown upload error',
'Sync complete': 'Synchronization complete'
'Sync complete': 'Synchronization complete',
// Errors
errors: {
statusUnauthorized: 'Access denied',
tokenConfig: 'Error fetching token config'
}
};

View File

@ -194,5 +194,10 @@ export default {
ErrCantWrite: 'Failed to write file to disk',
ErrExtension: 'File upload stopped by extension',
ErrDefault: 'Unknown upload error',
'Sync complete': 'Sincronización completada'
'Sync complete': 'Sincronización completada',
// Errors
errors: {
statusUnauthorized: 'Acceso denegado',
tokenConfig: 'Error al obtener configuración de token'
}
};

View File

@ -165,5 +165,11 @@ export default {
ErrCantWrite: "Échec de l'écriture du fichier sur le disque",
ErrExtension: 'Téléchargement du fichier arrêté par extension',
ErrDefault: 'Erreur de téléchargement inconnue',
'Sync complete': 'Synchronisation terminée'
'Sync complete': 'Synchronisation terminée',
// Errors
errors: {
statusUnauthorized: 'Accès refusé',
tokenConfig:
'Erreur lors de la récupération de la configuration du jeton'
}
};

View File

@ -158,5 +158,10 @@ export default {
ErrCantWrite: 'Erro ao gravar arquivo no disco',
ErrExtension: 'Erro de extensão do arquivo',
ErrDefault: 'Erro desconhecido ao subir arquivo',
'Sync complete': 'Sincronização completa'
'Sync complete': 'Sincronização completa',
// Errors
errors: {
statusUnauthorized: 'Acesso negado',
tokenConfig: 'Erro ao obter configuração do token'
}
};

View File

@ -9,12 +9,8 @@ const { notify } = useNotify();
export const useUserStore = defineStore('user', {
state: () => {
const token =
sessionStorage.getItem('vnToken') ||
localStorage.getItem('vnToken');
return {
token,
token: '',
isGuest: false,
user: null,
supplantedUser: null,
@ -24,7 +20,11 @@ export const useUserStore = defineStore('user', {
{ 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
};
},
@ -46,10 +46,77 @@ export const useUserStore = defineStore('user', {
this.updateSiteLocale();
},
async getToken() {
this.token =
getToken() {
const token =
sessionStorage.getItem('vnToken') ||
localStorage.getItem('vnToken');
this.token = token;
return token;
},
setToken(token) {
const storage = this.keepLogin ? localStorage : sessionStorage;
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'
};
const storage = this.keepLogin ? localStorage : sessionStorage;
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, storage, key)
);
}
} finally {
localStorage.clear();
sessionStorage.clear();
await Promise.allSettled(destroyTokenPromises);
this.user = null;
this.stopRenewer();
}
},
setSession(data) {
const storage = this.keepLogin ? localStorage : sessionStorage;
storage.setItem('vnToken', data.token);
storage.setItem('created', data.created);
storage.setItem('ttl', data.ttl);
sessionStorage.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() {
@ -67,22 +134,6 @@ export const useUserStore = defineStore('user', {
return false;
},
async login(user, password, remember) {
const params = { user, password };
const res = await api.post('Accounts/login', params);
if (remember) {
localStorage.setItem('vnToken', res.data.token);
} else {
sessionStorage.setItem('vnToken', res.data.token);
}
this.$patch({
token: res.data.token,
name: user
});
},
async logout() {
if (this.token != null) {
try {
@ -96,6 +147,68 @@ export const useUserStore = defineStore('user', {
useAppStore().onLogout();
},
async fetchTokenConfig() {
try {
const { data } = await api.get('AccessTokenConfigs/findOne', {
filter: { fields: ['renewInterval', 'renewPeriod'] }
});
if (!data) return;
this.tokenConfig = data;
sessionStorage.setItem('tokenConfig', data);
sessionStorage.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 tokenConfig =
this.tokenConfig ?? sessionStorage.getItem('tokenConfig');
const storage = this.keepLogin ? localStorage : sessionStorage;
const created = +storage.getItem('created');
const ttl = +storage.getItem('ttl');
if (this.isCheckingToken || !created) return;
this.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 (this.isCheckingToken = false);
}
await this.renewToken();
this.isCheckingToken = false;
},
stopRenewer() {
clearInterval(this.intervalId);
},
startInterval() {
this.stopRenewer();
const renewPeriod = +sessionStorage.getItem('renewPeriod');
if (!renewPeriod) return;
this.intervalId = setInterval(
() => this.checkValidity(),
renewPeriod * 1000
);
},
async fetchUser(userType = 'user') {
try {
const userData = await jApi.getObject(