Merge pull request 'renew-token-check' (!98) from wbuezas/hedera-web-mindshore:renew-token-check into beta
gitea/hedera-web/pipeline/head There was a failure building this commit
Details
gitea/hedera-web/pipeline/head There was a failure building this commit
Details
Reviewed-on: #98 Reviewed-by: Javier Segarra <jsegarra@verdnatura.es>
This commit is contained in:
commit
30dca813b6
|
@ -16,6 +16,7 @@
|
||||||
"@intlify/vue-i18n-loader": "^4.2.0",
|
"@intlify/vue-i18n-loader": "^4.2.0",
|
||||||
"@quasar/app-webpack": "^3.0.0",
|
"@quasar/app-webpack": "^3.0.0",
|
||||||
"@quasar/cli": "^2.4.1",
|
"@quasar/cli": "^2.4.1",
|
||||||
|
"@quasar/vite-plugin": "^1.8.1",
|
||||||
"babel-loader": "^9.2.1",
|
"babel-loader": "^9.2.1",
|
||||||
"css-loader": "^7.1.2",
|
"css-loader": "^7.1.2",
|
||||||
"cypress": "^13.6.6",
|
"cypress": "^13.6.6",
|
||||||
|
@ -31,17 +32,22 @@
|
||||||
"eslint-plugin-vue": "^9.27.0",
|
"eslint-plugin-vue": "^9.27.0",
|
||||||
"eslint-webpack-plugin": "^3.1.1",
|
"eslint-webpack-plugin": "^3.1.1",
|
||||||
"file-loader": "^6.2.0",
|
"file-loader": "^6.2.0",
|
||||||
|
"happy-dom": "^15.11.7",
|
||||||
"json-loader": "^0.5.7",
|
"json-loader": "^0.5.7",
|
||||||
"postcss-loader": "^8.1.1",
|
"postcss-loader": "^8.1.1",
|
||||||
|
"sass-embedded": "^1.80.2",
|
||||||
"sass-loader": "^16.0.4",
|
"sass-loader": "^16.0.4",
|
||||||
"tinymce": "^6.3.0",
|
"tinymce": "^6.3.0",
|
||||||
"url-loader": "^4.1.1",
|
"url-loader": "^4.1.1",
|
||||||
|
"vitest": "^2.1.8",
|
||||||
"vue-loader": "^17.4.2",
|
"vue-loader": "^17.4.2",
|
||||||
"vue-style-loader": "^4.1.3",
|
"vue-style-loader": "^4.1.3",
|
||||||
"yaml-loader": "^0.5.0"
|
"yaml-loader": "^0.5.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@intlify/unplugin-vue-i18n": "^6.0.1",
|
||||||
"@quasar/extras": "^1.16.9",
|
"@quasar/extras": "^1.16.9",
|
||||||
|
"@vitejs/plugin-vue": "^5.2.1",
|
||||||
"axios": "^0.21.1",
|
"axios": "^0.21.1",
|
||||||
"core-js": "^3.6.5",
|
"core-js": "^3.6.5",
|
||||||
"pinia": "^2.0.11",
|
"pinia": "^2.0.11",
|
||||||
|
@ -58,6 +64,7 @@
|
||||||
"db": "cd ../salix && gulp docker",
|
"db": "cd ../salix && gulp docker",
|
||||||
"cy:open": "npm run db && cypress open",
|
"cy:open": "npm run db && cypress open",
|
||||||
"test:e2e": "npm run db && cypress run",
|
"test:e2e": "npm run db && cypress run",
|
||||||
|
"test:unit": "vitest",
|
||||||
"build": "rm -rf dist/ ; quasar build",
|
"build": "rm -rf dist/ ; quasar build",
|
||||||
"clean": "rm -rf dist/",
|
"clean": "rm -rf dist/",
|
||||||
"lint": "eslint --ext .js,.vue ./"
|
"lint": "eslint --ext .js,.vue ./"
|
||||||
|
|
12336
pnpm-lock.yaml
12336
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
|
@ -71,7 +71,8 @@ module.exports = configure(function (ctx) {
|
||||||
chain
|
chain
|
||||||
.plugin('eslint-webpack-plugin')
|
.plugin('eslint-webpack-plugin')
|
||||||
.use(ESLintPlugin, [{ extensions: ['js', 'vue'] }]);
|
.use(ESLintPlugin, [{ extensions: ['js', 'vue'] }]);
|
||||||
|
chain.resolve.alias
|
||||||
|
.set('@', path.resolve(__dirname, 'src'));
|
||||||
chain.module
|
chain.module
|
||||||
.rule('i18n-resource')
|
.rule('i18n-resource')
|
||||||
.test(/\.(json5?|ya?ml)$/)
|
.test(/\.(json5?|ya?ml)$/)
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { boot } from 'quasar/wrappers';
|
import { boot } from 'quasar/wrappers';
|
||||||
import { Connection } from '../js/db/connection';
|
import { Connection } from '../js/db/connection';
|
||||||
import { useUserStore } from 'stores/user';
|
import { useUserStore } from '@/stores/user';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import useNotify from 'src/composables/useNotify.js';
|
import useNotify from '@/composables/useNotify.js';
|
||||||
import { useAppStore } from 'src/stores/app';
|
import { useAppStore } from '@/stores/app';
|
||||||
|
import { Router } from 'src/router';
|
||||||
const { notify } = useNotify();
|
const { notify } = useNotify();
|
||||||
// Be careful when using SSR for cross-request state pollution
|
// Be careful when using SSR for cross-request state pollution
|
||||||
// due to creating a Singleton instance here;
|
// due to creating a Singleton instance here;
|
||||||
|
@ -22,6 +22,8 @@ const onRequestError = error => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const onResponseError = error => {
|
const onResponseError = error => {
|
||||||
|
const userStore = useUserStore();
|
||||||
|
|
||||||
let message = error.message;
|
let message = error.message;
|
||||||
|
|
||||||
const response = error.response;
|
const response = error.response;
|
||||||
|
@ -33,7 +35,14 @@ const onResponseError = error => {
|
||||||
|
|
||||||
notify(message, 'negative');
|
notify(message, 'negative');
|
||||||
|
|
||||||
return Promise.reject(error);
|
if (userStore.isLoggedIn && response?.status === 401) {
|
||||||
|
if (!Router) return;
|
||||||
|
|
||||||
|
Router.push({ name: 'login' });
|
||||||
|
userStore.destroy(false);
|
||||||
|
} else if (!userStore.isLoggedIn) {
|
||||||
|
return Promise.reject(error);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default boot(({ app }) => {
|
export default boot(({ app }) => {
|
||||||
|
@ -41,7 +50,8 @@ export default boot(({ app }) => {
|
||||||
const appStore = useAppStore();
|
const appStore = useAppStore();
|
||||||
function addToken(config) {
|
function addToken(config) {
|
||||||
if (userStore.token) {
|
if (userStore.token) {
|
||||||
config.headers.Authorization = userStore.token;
|
if (!config.headers.Authorization)
|
||||||
|
config.headers.Authorization = userStore.token;
|
||||||
config.headers['Accept-Language'] = appStore.siteLang;
|
config.headers['Accept-Language'] = appStore.siteLang;
|
||||||
}
|
}
|
||||||
return config;
|
return config;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { boot } from 'quasar/wrappers';
|
import { boot } from 'quasar/wrappers';
|
||||||
import { createI18n } from 'vue-i18n';
|
import { createI18n } from 'vue-i18n';
|
||||||
import messages from 'src/i18n';
|
import messages from '@/i18n';
|
||||||
|
|
||||||
const i18n = createI18n({
|
const i18n = createI18n({
|
||||||
locale: navigator.language || navigator.userLanguage,
|
locale: navigator.language || navigator.userLanguage,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Notify } from 'quasar';
|
import { Notify } from 'quasar';
|
||||||
import { i18n } from 'src/boot/i18n';
|
import { i18n } from '@/boot/i18n';
|
||||||
|
|
||||||
export default function useNotify() {
|
export default function useNotify() {
|
||||||
const notify = (message, type, icon) => {
|
const notify = (message, type, icon) => {
|
||||||
|
|
|
@ -4,9 +4,11 @@
|
||||||
class="fullscreen row justify-center items-center layout-view scroll"
|
class="fullscreen row justify-center items-center layout-view scroll"
|
||||||
>
|
>
|
||||||
<QPageContainer class="column q-pa-md row items-center justify-center">
|
<QPageContainer class="column q-pa-md row items-center justify-center">
|
||||||
<transition>
|
<router-view v-slot="{ Component }">
|
||||||
<router-view />
|
<transition>
|
||||||
</transition>
|
<component :is="Component" />
|
||||||
|
</transition>
|
||||||
|
</router-view>
|
||||||
</QPageContainer>
|
</QPageContainer>
|
||||||
</QLayout>
|
</QLayout>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -23,7 +23,7 @@ const query = `SELECT i.id, i.longName, i.size, i.category,
|
||||||
ON im.collectionFk = 'catalog'
|
ON im.collectionFk = 'catalog'
|
||||||
AND im.name = i.image
|
AND im.name = i.image
|
||||||
WHERE (i.longName LIKE CONCAT('%', #search, '%')
|
WHERE (i.longName LIKE CONCAT('%', #search, '%')
|
||||||
OR i.id = #search) AND i.isActive = 1
|
OR i.id = #search) AND i.isActive
|
||||||
ORDER BY i.longName LIMIT 50`;
|
ORDER BY i.longName LIMIT 50`;
|
||||||
|
|
||||||
const onSearch = data => (items.value = data || []);
|
const onSearch = data => (items.value = data || []);
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
import { useUserStore } from 'stores/user';
|
import { useUserStore } from 'stores/user';
|
||||||
import useNotify from 'src/composables/useNotify.js';
|
import useNotify from 'src/composables/useNotify.js';
|
||||||
import { useRouter, useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import { useAppStore } from 'src/stores/app';
|
import { useAppStore } from 'src/stores/app';
|
||||||
|
|
||||||
|
@ -14,7 +14,6 @@ const { locale } = useI18n({ useScope: 'global' });
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const appStore = useAppStore();
|
const appStore = useAppStore();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const router = useRouter();
|
|
||||||
const { siteLang, localeOptions } = storeToRefs(appStore);
|
const { siteLang, localeOptions } = storeToRefs(appStore);
|
||||||
|
|
||||||
const email = ref(null);
|
const email = ref(null);
|
||||||
|
@ -45,20 +44,14 @@ onMounted(() => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const onLogin = async () => {
|
|
||||||
await userStore.fetchUser();
|
|
||||||
await router.push({ name: 'home' });
|
|
||||||
};
|
|
||||||
|
|
||||||
const login = async () => {
|
const login = async () => {
|
||||||
await userStore.login(email.value, password.value, remember.value);
|
await userStore.login(email.value, password.value, remember.value);
|
||||||
await onLogin();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const loginAsGuest = async () => {
|
const loginAsGuest = async () => {
|
||||||
userStore.isGuest = true;
|
userStore.isGuest = true;
|
||||||
localStorage.setItem('hederaGuest', true);
|
localStorage.setItem('hederaGuest', true);
|
||||||
await onLogin();
|
await userStore.onLogin();
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -18,25 +18,25 @@ import routes from './routes';
|
||||||
* with the Router instance.
|
* with the Router instance.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
const createHistory = process.env.SERVER
|
||||||
|
? createMemoryHistory
|
||||||
|
: process.env.VUE_ROUTER_MODE === 'history'
|
||||||
|
? createWebHistory
|
||||||
|
: createWebHashHistory;
|
||||||
|
|
||||||
|
const Router = createRouter({
|
||||||
|
scrollBehavior: () => ({ left: 0, top: 0 }),
|
||||||
|
routes,
|
||||||
|
|
||||||
|
// Leave this as is and make changes in quasar.conf.js instead!
|
||||||
|
// quasar.conf.js -> build -> vueRouterMode
|
||||||
|
// quasar.conf.js -> build -> publicPath
|
||||||
|
history: createHistory(process.env.VUE_ROUTER_BASE)
|
||||||
|
});
|
||||||
|
|
||||||
|
export { Router };
|
||||||
|
|
||||||
export default route(function (/* { store, ssrContext } */) {
|
export default route(function (/* { store, ssrContext } */) {
|
||||||
const createHistory = process.env.SERVER
|
|
||||||
? createMemoryHistory
|
|
||||||
: process.env.VUE_ROUTER_MODE === 'history'
|
|
||||||
? createWebHistory
|
|
||||||
: createWebHashHistory;
|
|
||||||
|
|
||||||
const Router = createRouter({
|
|
||||||
scrollBehavior: () => ({ left: 0, top: 0 }),
|
|
||||||
routes,
|
|
||||||
|
|
||||||
// Leave this as is and make changes in quasar.conf.js instead!
|
|
||||||
// quasar.conf.js -> build -> vueRouterMode
|
|
||||||
// quasar.conf.js -> build -> publicPath
|
|
||||||
history: createHistory(
|
|
||||||
process.env.MODE === 'ssr' ? void 0 : process.env.VUE_ROUTER_BASE
|
|
||||||
)
|
|
||||||
});
|
|
||||||
|
|
||||||
Router.beforeEach((to, from, next) => {
|
Router.beforeEach((to, from, next) => {
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const allowedRoutes = ['login', 'recoverPassword'];
|
const allowedRoutes = ['login', 'recoverPassword'];
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import { jApi } from 'boot/axios';
|
import { jApi } from '@/boot/axios';
|
||||||
import useNotify from 'src/composables/useNotify.js';
|
import useNotify from '@/composables/useNotify.js';
|
||||||
import { i18n } from 'src/boot/i18n';
|
import { i18n } from '@/boot/i18n';
|
||||||
import { useQuasar } from 'quasar';
|
import { useQuasar } from 'quasar';
|
||||||
|
|
||||||
const { notify } = useNotify();
|
const { notify } = useNotify();
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import { ref, computed, watch } from 'vue';
|
import { ref, computed, watch } from 'vue';
|
||||||
import { api, jApi } from 'boot/axios';
|
import { api, jApi } from '@/boot/axios';
|
||||||
import useNotify from 'src/composables/useNotify.js';
|
import useNotify from '@/composables/useNotify.js';
|
||||||
import { useAppStore } from 'src/stores/app.js';
|
import { useAppStore } from '@/stores/app.js';
|
||||||
|
|
||||||
const { notify } = useNotify();
|
const { notify } = useNotify();
|
||||||
const TOKEN_MULTIMEDIA = 'tokenMultimedia';
|
const TOKEN_MULTIMEDIA = 'tokenMultimedia';
|
||||||
|
@ -25,7 +25,8 @@ export const useUserStore = defineStore('user', () => {
|
||||||
const storage = computed(() =>
|
const storage = computed(() =>
|
||||||
keepLogin.value ? localStorage : sessionStorage
|
keepLogin.value ? localStorage : sessionStorage
|
||||||
);
|
);
|
||||||
const isLoggedIn = computed(() => !!storage.value.getItem(TOKEN));
|
|
||||||
|
const isLoggedIn = computed(() => !!token.value);
|
||||||
|
|
||||||
const init = async _router => {
|
const init = async _router => {
|
||||||
router = _router;
|
router = _router;
|
||||||
|
@ -36,11 +37,12 @@ export const useUserStore = defineStore('user', () => {
|
||||||
if (!autoLoginStatus) {
|
if (!autoLoginStatus) {
|
||||||
router.push({ name: 'login' });
|
router.push({ name: 'login' });
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
await fetchTokenConfig();
|
||||||
|
await fetchUser();
|
||||||
|
await supplantInit();
|
||||||
|
startInterval();
|
||||||
}
|
}
|
||||||
await fetchTokenConfig();
|
|
||||||
await fetchUser();
|
|
||||||
await supplantInit();
|
|
||||||
startInterval();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const getToken = () => {
|
const getToken = () => {
|
||||||
|
@ -87,9 +89,9 @@ export const useUserStore = defineStore('user', () => {
|
||||||
let destroyTokenPromises = [];
|
let destroyTokenPromises = [];
|
||||||
try {
|
try {
|
||||||
if (destroyTokens) {
|
if (destroyTokens) {
|
||||||
const { data: isValidToken } = await api.get(
|
const response = await api.get('VnUsers/validateToken');
|
||||||
'VnUsers/validateToken'
|
const isValidToken = response?.data;
|
||||||
);
|
|
||||||
if (isValidToken) {
|
if (isValidToken) {
|
||||||
destroyTokenPromises = Object.entries(tokens).map(
|
destroyTokenPromises = Object.entries(tokens).map(
|
||||||
([key, url]) => destroyToken(url, storage.value, key)
|
([key, url]) => destroyToken(url, storage.value, key)
|
||||||
|
@ -101,6 +103,7 @@ export const useUserStore = defineStore('user', () => {
|
||||||
sessionStorage.clear();
|
sessionStorage.clear();
|
||||||
await Promise.allSettled(destroyTokenPromises);
|
await Promise.allSettled(destroyTokenPromises);
|
||||||
user.value = null;
|
user.value = null;
|
||||||
|
$reset();
|
||||||
stopRenewer();
|
stopRenewer();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -117,30 +120,43 @@ export const useUserStore = defineStore('user', () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchMultimediaToken = async data => {
|
const fetchMultimediaToken = async data => {
|
||||||
const {
|
try {
|
||||||
data: { multimediaToken }
|
const response = await api.get('VnUsers/ShareToken', {
|
||||||
} = await api.get('VnUsers/ShareToken', {
|
headers: { Authorization: data.token }
|
||||||
headers: { Authorization: data.token }
|
});
|
||||||
});
|
const multimediaToken = response?.data?.multimediaToken;
|
||||||
return 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) => {
|
const login = async (username, password, remember) => {
|
||||||
const params = { user: username, password };
|
try {
|
||||||
const { data } = await api.post('Accounts/login', params);
|
const params = { user: username, password };
|
||||||
|
const { data } = await api.post('Accounts/login', params);
|
||||||
|
|
||||||
const multimediaToken = await fetchMultimediaToken(data);
|
const multimediaToken = await fetchMultimediaToken(data);
|
||||||
if (!multimediaToken) return;
|
if (!multimediaToken) return;
|
||||||
|
|
||||||
keepLogin.value = remember;
|
keepLogin.value = remember;
|
||||||
setSession({
|
setSession({
|
||||||
created: Date.now(),
|
created: Date.now(),
|
||||||
tokenMultimedia: multimediaToken.id,
|
tokenMultimedia: multimediaToken.id,
|
||||||
username,
|
username,
|
||||||
...data
|
...data
|
||||||
});
|
});
|
||||||
await fetchTokenConfig();
|
await fetchTokenConfig();
|
||||||
startInterval();
|
startInterval();
|
||||||
|
await onLogin();
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error('Error logging in');
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const tryAutoLogin = async () => {
|
const tryAutoLogin = async () => {
|
||||||
|
@ -158,10 +174,8 @@ export const useUserStore = defineStore('user', () => {
|
||||||
|
|
||||||
const logout = async () => {
|
const logout = async () => {
|
||||||
try {
|
try {
|
||||||
await api.post('Accounts/logout');
|
await destroy();
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
destroy();
|
|
||||||
$reset();
|
|
||||||
useAppStore().onLogout();
|
useAppStore().onLogout();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -192,8 +206,8 @@ export const useUserStore = defineStore('user', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
setToken({
|
setToken({
|
||||||
_token: tokenData.data.id,
|
_token: tokenData?.data?.id || '',
|
||||||
_tokenMultimedia: tokenMultimedia.data.id
|
_tokenMultimedia: tokenMultimedia?.data?.id || ''
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -272,6 +286,7 @@ export const useUserStore = defineStore('user', () => {
|
||||||
|
|
||||||
const $reset = () => {
|
const $reset = () => {
|
||||||
token.value = '';
|
token.value = '';
|
||||||
|
tokenMultimedia.value = '';
|
||||||
isGuest.value = false;
|
isGuest.value = false;
|
||||||
user.value = null;
|
user.value = null;
|
||||||
supplantedUser.value = null;
|
supplantedUser.value = null;
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
import { vi, describe, expect, it, beforeAll } from 'vitest';
|
||||||
|
import { api } from '@/boot/axios';
|
||||||
|
import { useUserStore } from '@/stores/user';
|
||||||
|
import { createPinia, setActivePinia } from 'pinia';
|
||||||
|
|
||||||
|
describe('session', () => {
|
||||||
|
let userStore;
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
// Configura Pinia y el store
|
||||||
|
setActivePinia(createPinia());
|
||||||
|
userStore = useUserStore();
|
||||||
|
|
||||||
|
vi.mock('@/boot/axios', () => ({
|
||||||
|
api: {
|
||||||
|
post: vi.fn()
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('RenewToken', () => {
|
||||||
|
const expectedToken = 'myToken';
|
||||||
|
const expectedTokenMultimedia = 'myTokenMultimedia';
|
||||||
|
beforeAll(() => {
|
||||||
|
const tokenConfig = {
|
||||||
|
id: 1,
|
||||||
|
renewPeriod: 21600,
|
||||||
|
courtesyTime: 60,
|
||||||
|
renewInterval: 300
|
||||||
|
};
|
||||||
|
userStore.tokenConfig = tokenConfig;
|
||||||
|
sessionStorage.setItem('renewPeriod', 21600);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('NOT Should renewToken', async () => {
|
||||||
|
const data = {
|
||||||
|
username: 'myUser',
|
||||||
|
created: Date.now(),
|
||||||
|
ttl: 1,
|
||||||
|
keepLogin: false,
|
||||||
|
token: expectedToken,
|
||||||
|
tokenMultimedia: expectedTokenMultimedia
|
||||||
|
};
|
||||||
|
|
||||||
|
userStore.setSession(data);
|
||||||
|
expect(sessionStorage.getItem('created')).toBeDefined();
|
||||||
|
expect(sessionStorage.getItem('ttl')).toEqual('1');
|
||||||
|
await userStore.checkValidity();
|
||||||
|
expect(sessionStorage.getItem('token')).toEqual(expectedToken);
|
||||||
|
expect(sessionStorage.getItem('tokenMultimedia')).toEqual(
|
||||||
|
expectedTokenMultimedia
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should renewToken', async () => {
|
||||||
|
const data = {
|
||||||
|
token: expectedToken,
|
||||||
|
tokenMultimedia: expectedTokenMultimedia,
|
||||||
|
keepLogin: false,
|
||||||
|
ttl: 3600, // 1 hora
|
||||||
|
created: Date.now() - 100000000 // forzamos a que crea que el token se creó hace 100000000 ms
|
||||||
|
};
|
||||||
|
|
||||||
|
userStore.setSession(data);
|
||||||
|
|
||||||
|
// Mockea las respuestas de la API
|
||||||
|
api.post
|
||||||
|
.mockResolvedValueOnce({
|
||||||
|
data: { id: 'newToken1' }
|
||||||
|
})
|
||||||
|
.mockResolvedValueOnce({
|
||||||
|
data: { id: 'newToken2' }
|
||||||
|
});
|
||||||
|
|
||||||
|
// Verifica el estado inicial
|
||||||
|
expect(sessionStorage.getItem('keepLogin')).toBeFalsy();
|
||||||
|
expect(sessionStorage.getItem('created')).toBeDefined();
|
||||||
|
expect(sessionStorage.getItem('ttl')).toEqual('3600');
|
||||||
|
expect(sessionStorage.getItem('token')).toEqual(expectedToken);
|
||||||
|
|
||||||
|
// Llama al método que debe validar y renovar el token
|
||||||
|
await userStore.checkValidity();
|
||||||
|
|
||||||
|
// Verifica que los tokens hayan cambiado
|
||||||
|
expect(sessionStorage.getItem('token')).not.toEqual(expectedToken);
|
||||||
|
expect(sessionStorage.getItem('tokenMultimedia')).not.toEqual(
|
||||||
|
expectedTokenMultimedia
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,38 @@
|
||||||
|
import { defineConfig } from 'vitest/config';
|
||||||
|
import vue from '@vitejs/plugin-vue';
|
||||||
|
import { quasar, transformAssetUrls } from '@quasar/vite-plugin';
|
||||||
|
// import jsconfigPaths from 'vite-jsconfig-paths';
|
||||||
|
import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
// https://vitejs.dev/config/
|
||||||
|
export default defineConfig({
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'@': path.resolve(__dirname, 'src'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
test: {
|
||||||
|
environment: 'happy-dom',
|
||||||
|
include: [
|
||||||
|
// Matches vitest tests in any subfolder of 'src' or into 'test/vitest/__tests__'
|
||||||
|
// Matches all files with extension 'js', 'jsx', 'ts' and 'tsx'
|
||||||
|
'src/test/vitest/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
vue({
|
||||||
|
template: { transformAssetUrls }
|
||||||
|
}),
|
||||||
|
quasar({
|
||||||
|
sassVariables: 'src/css/quasar-variables.sass'
|
||||||
|
}),
|
||||||
|
VueI18nPlugin({
|
||||||
|
include: [
|
||||||
|
path.resolve(__dirname, 'src/i18n/**'),
|
||||||
|
path.resolve(__dirname, 'src/pages/**/locale/**'),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
// jsconfigPaths(),
|
||||||
|
],
|
||||||
|
});
|
Loading…
Reference in New Issue