From 91ff0835fb7d29bcdaf20df46445e997bbd632b4 Mon Sep 17 00:00:00 2001 From: Julian Krauser Date: Sun, 25 Aug 2024 10:10:11 +0200 Subject: [PATCH] token refresh and exp check --- src/globalProperties.config.ts | 4 ++-- src/router/accountGuard.ts | 3 --- src/router/authGuards.ts | 20 ++++++++++++++++++-- src/serverCom.ts | 8 ++++---- src/stores/admin/navigation.ts | 2 +- 5 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/globalProperties.config.ts b/src/globalProperties.config.ts index 8bd0344..73264a1 100644 --- a/src/globalProperties.config.ts +++ b/src/globalProperties.config.ts @@ -1,6 +1,6 @@ import type { AxiosInstance } from "axios"; import type { NProgress } from "nprogress"; -import type { Router } from "vue-router"; +import type { RouteLocationNormalizedLoaded, Router } from "vue-router"; declare module "@vue/runtime-core" { interface ComponentCustomProperties { @@ -8,7 +8,7 @@ declare module "@vue/runtime-core" { $http: AxiosInstance; $progress: NProgress; $router: Router; - $route: any; + $route: RouteLocationNormalizedLoaded; } } diff --git a/src/router/accountGuard.ts b/src/router/accountGuard.ts index 0ab0074..af6a6ab 100644 --- a/src/router/accountGuard.ts +++ b/src/router/accountGuard.ts @@ -2,8 +2,5 @@ import { useAccountStore } from "@/stores/account"; export async function loadAccountData(to: any, from: any, next: any) { const account = useAccountStore(); - account.fetchAccountContests(); - account.fetchAccountInvites(); - account.fetchAccountLicense(); next(); } diff --git a/src/router/authGuards.ts b/src/router/authGuards.ts index 07bc5df..39260f0 100644 --- a/src/router/authGuards.ts +++ b/src/router/authGuards.ts @@ -2,6 +2,7 @@ import NProgress from "nprogress"; import { useAuthStore } from "@/stores/auth"; import { useAccountStore } from "@/stores/account"; import { jwtDecode, type JwtPayload } from "jwt-decode"; +import { refreshToken } from "../serverCom"; type Payload = JwtPayload & { userId: number; username: string; firstname: string; lastname: string; mail: string }; @@ -25,15 +26,30 @@ export async function isAuthenticated(to: any, from: any, next: any) { } export async function isAuthenticatedPromise(): Promise { - return new Promise((resolve, reject) => { + return new Promise(async (resolve, reject) => { const auth = useAuthStore(); const account = useAccountStore(); let decoded = jwtDecode(localStorage.getItem("accessToken") ?? ""); auth.setSuccess(); if (typeof decoded == "string" || !decoded) { - reject("jwt failed"); + reject("failed"); } + + // check jwt expiry + const exp = decoded.exp ?? 0; + const localTimezoneOffset = new Date().getTimezoneOffset(); + const correctedLocalTime = new Date().getTime() + localTimezoneOffset * 60000; + if (exp < Math.floor(correctedLocalTime / 1000)) { + await refreshToken() + .then(() => { + console.log("fetched new token"); + }) + .catch(() => { + reject("expired"); + }); + } + var { firstname, lastname, mail, username } = decoded; account.setAccountData(firstname, lastname, mail, username); resolve(decoded); diff --git a/src/serverCom.ts b/src/serverCom.ts index a58b0a3..cd10aeb 100644 --- a/src/serverCom.ts +++ b/src/serverCom.ts @@ -50,17 +50,17 @@ http.interceptors.response.use( } ); -async function refreshToken(): Promise { +export async function refreshToken(): Promise { return new Promise(async (resolve, reject) => { await http .post(`/auth/refresh`, { - access: localStorage.getItem("accessToken"), + accessToken: localStorage.getItem("accessToken"), refreshToken: localStorage.getItem("refreshToken"), }) .then((response) => { - const { access, refreshToken } = response.data; + const { accessToken, refreshToken } = response.data; - localStorage.setItem("accessToken", access); + localStorage.setItem("accessToken", accessToken); localStorage.setItem("refreshToken", refreshToken); resolve(); diff --git a/src/stores/admin/navigation.ts b/src/stores/admin/navigation.ts index 4275d90..da0e94d 100644 --- a/src/stores/admin/navigation.ts +++ b/src/stores/admin/navigation.ts @@ -66,7 +66,7 @@ export const useNavigationStore = defineStore("navigation", { }, { key: "#protocol", - title: "Prookolle", + title: "Protokolle", component: shallowRef(defineAsyncComponent(() => import("@/views/admin/members/Overview.vue"))), }, ],