token refresh and exp check

This commit is contained in:
Julian Krauser 2024-08-25 10:10:11 +02:00
parent f1e6e8b8d3
commit 91ff0835fb
5 changed files with 25 additions and 12 deletions

View file

@ -1,6 +1,6 @@
import type { AxiosInstance } from "axios"; import type { AxiosInstance } from "axios";
import type { NProgress } from "nprogress"; import type { NProgress } from "nprogress";
import type { Router } from "vue-router"; import type { RouteLocationNormalizedLoaded, Router } from "vue-router";
declare module "@vue/runtime-core" { declare module "@vue/runtime-core" {
interface ComponentCustomProperties { interface ComponentCustomProperties {
@ -8,7 +8,7 @@ declare module "@vue/runtime-core" {
$http: AxiosInstance; $http: AxiosInstance;
$progress: NProgress; $progress: NProgress;
$router: Router; $router: Router;
$route: any; $route: RouteLocationNormalizedLoaded;
} }
} }

View file

@ -2,8 +2,5 @@ import { useAccountStore } from "@/stores/account";
export async function loadAccountData(to: any, from: any, next: any) { export async function loadAccountData(to: any, from: any, next: any) {
const account = useAccountStore(); const account = useAccountStore();
account.fetchAccountContests();
account.fetchAccountInvites();
account.fetchAccountLicense();
next(); next();
} }

View file

@ -2,6 +2,7 @@ import NProgress from "nprogress";
import { useAuthStore } from "@/stores/auth"; import { useAuthStore } from "@/stores/auth";
import { useAccountStore } from "@/stores/account"; import { useAccountStore } from "@/stores/account";
import { jwtDecode, type JwtPayload } from "jwt-decode"; import { jwtDecode, type JwtPayload } from "jwt-decode";
import { refreshToken } from "../serverCom";
type Payload = JwtPayload & { userId: number; username: string; firstname: string; lastname: string; mail: string }; 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<Payload> { export async function isAuthenticatedPromise(): Promise<Payload> {
return new Promise<Payload>((resolve, reject) => { return new Promise<Payload>(async (resolve, reject) => {
const auth = useAuthStore(); const auth = useAuthStore();
const account = useAccountStore(); const account = useAccountStore();
let decoded = jwtDecode<Payload>(localStorage.getItem("accessToken") ?? ""); let decoded = jwtDecode<Payload>(localStorage.getItem("accessToken") ?? "");
auth.setSuccess(); auth.setSuccess();
if (typeof decoded == "string" || !decoded) { 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; var { firstname, lastname, mail, username } = decoded;
account.setAccountData(firstname, lastname, mail, username); account.setAccountData(firstname, lastname, mail, username);
resolve(decoded); resolve(decoded);

View file

@ -50,17 +50,17 @@ http.interceptors.response.use(
} }
); );
async function refreshToken(): Promise<void> { export async function refreshToken(): Promise<void> {
return new Promise<void>(async (resolve, reject) => { return new Promise<void>(async (resolve, reject) => {
await http await http
.post(`/auth/refresh`, { .post(`/auth/refresh`, {
access: localStorage.getItem("accessToken"), accessToken: localStorage.getItem("accessToken"),
refreshToken: localStorage.getItem("refreshToken"), refreshToken: localStorage.getItem("refreshToken"),
}) })
.then((response) => { .then((response) => {
const { access, refreshToken } = response.data; const { accessToken, refreshToken } = response.data;
localStorage.setItem("accessToken", access); localStorage.setItem("accessToken", accessToken);
localStorage.setItem("refreshToken", refreshToken); localStorage.setItem("refreshToken", refreshToken);
resolve(); resolve();

View file

@ -66,7 +66,7 @@ export const useNavigationStore = defineStore("navigation", {
}, },
{ {
key: "#protocol", key: "#protocol",
title: "Prookolle", title: "Protokolle",
component: shallowRef(defineAsyncComponent(() => import("@/views/admin/members/Overview.vue"))), component: shallowRef(defineAsyncComponent(() => import("@/views/admin/members/Overview.vue"))),
}, },
], ],