Renew token
This commit is contained in:
parent
c950bf5ef1
commit
261fddb1cf
|
@ -161,5 +161,10 @@ export default {
|
||||||
ErrCantWrite: "No s'ha pogut escriure el fitxer al disc",
|
ErrCantWrite: "No s'ha pogut escriure el fitxer al disc",
|
||||||
ErrExtension: "La pujada del fitxer s'ha aturat per una extensió",
|
ErrExtension: "La pujada del fitxer s'ha aturat per una extensió",
|
||||||
ErrDefault: 'Error de pujada desconegut',
|
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'
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -194,5 +194,10 @@ export default {
|
||||||
ErrCantWrite: 'Failed to write file to disk',
|
ErrCantWrite: 'Failed to write file to disk',
|
||||||
ErrExtension: 'File upload stopped by extension',
|
ErrExtension: 'File upload stopped by extension',
|
||||||
ErrDefault: 'Unknown upload error',
|
ErrDefault: 'Unknown upload error',
|
||||||
'Sync complete': 'Synchronization complete'
|
'Sync complete': 'Synchronization complete',
|
||||||
|
// Errors
|
||||||
|
errors: {
|
||||||
|
statusUnauthorized: 'Access denied',
|
||||||
|
tokenConfig: 'Error fetching token config'
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -194,5 +194,10 @@ export default {
|
||||||
ErrCantWrite: 'Failed to write file to disk',
|
ErrCantWrite: 'Failed to write file to disk',
|
||||||
ErrExtension: 'File upload stopped by extension',
|
ErrExtension: 'File upload stopped by extension',
|
||||||
ErrDefault: 'Unknown upload error',
|
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'
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -165,5 +165,11 @@ export default {
|
||||||
ErrCantWrite: "Échec de l'écriture du fichier sur le disque",
|
ErrCantWrite: "Échec de l'écriture du fichier sur le disque",
|
||||||
ErrExtension: 'Téléchargement du fichier arrêté par extension',
|
ErrExtension: 'Téléchargement du fichier arrêté par extension',
|
||||||
ErrDefault: 'Erreur de téléchargement inconnue',
|
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'
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -158,5 +158,10 @@ export default {
|
||||||
ErrCantWrite: 'Erro ao gravar arquivo no disco',
|
ErrCantWrite: 'Erro ao gravar arquivo no disco',
|
||||||
ErrExtension: 'Erro de extensão do arquivo',
|
ErrExtension: 'Erro de extensão do arquivo',
|
||||||
ErrDefault: 'Erro desconhecido ao subir 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'
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,12 +9,8 @@ const { notify } = useNotify();
|
||||||
|
|
||||||
export const useUserStore = defineStore('user', {
|
export const useUserStore = defineStore('user', {
|
||||||
state: () => {
|
state: () => {
|
||||||
const token =
|
|
||||||
sessionStorage.getItem('vnToken') ||
|
|
||||||
localStorage.getItem('vnToken');
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
token,
|
token: '',
|
||||||
isGuest: false,
|
isGuest: false,
|
||||||
user: null,
|
user: null,
|
||||||
supplantedUser: null,
|
supplantedUser: null,
|
||||||
|
@ -24,7 +20,11 @@ export const useUserStore = defineStore('user', {
|
||||||
{ label: t('langs.ca'), lang: 'ca-ES', value: 'ca' },
|
{ label: t('langs.ca'), lang: 'ca-ES', value: 'ca' },
|
||||||
{ label: t('langs.fr'), lang: 'fr-FR', value: 'fr' },
|
{ label: t('langs.fr'), lang: 'fr-FR', value: 'fr' },
|
||||||
{ label: t('langs.pt'), lang: 'pt-PT', value: 'pt' }
|
{ 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();
|
this.updateSiteLocale();
|
||||||
},
|
},
|
||||||
|
|
||||||
async getToken() {
|
getToken() {
|
||||||
this.token =
|
const token =
|
||||||
sessionStorage.getItem('vnToken') ||
|
sessionStorage.getItem('vnToken') ||
|
||||||
localStorage.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() {
|
async tryAutoLogin() {
|
||||||
|
@ -67,22 +134,6 @@ export const useUserStore = defineStore('user', {
|
||||||
return false;
|
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() {
|
async logout() {
|
||||||
if (this.token != null) {
|
if (this.token != null) {
|
||||||
try {
|
try {
|
||||||
|
@ -96,6 +147,68 @@ export const useUserStore = defineStore('user', {
|
||||||
useAppStore().onLogout();
|
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') {
|
async fetchUser(userType = 'user') {
|
||||||
try {
|
try {
|
||||||
const userData = await jApi.getObject(
|
const userData = await jApi.getObject(
|
||||||
|
|
Loading…
Reference in New Issue