import jwtDecode from "jwt-decode"; import router from "./routes"; export interface IUser { id: number, name: string, isAdmin: boolean } /** * The active JWT */ let token: string | null; /** * The decoded user object */ let user: IUser | null; /** * Check if the user is an admin */ export function isAdmin() { return user && user.isAdmin; } /** * Check if the client is authenticated */ export function isAuthenticated() { return Boolean(token); } /** * Get the logged in user (assumes authentication has been checked) */ export function getUser() { return user; } /** * Load the token from local storage */ export function loadToken() { try { token = localStorage.getItem("jwt"); user = jwtDecode(token); } catch(e) { console.log("Failed to load token"); token = null; user = null; return false; } console.log("Token loaded", token); return true; } /** * Delete the token from local storage */ export function forgetToken() { token = null; user = null; localStorage.removeItem("jwt"); } /** * Store a JWT token in local storage */ export function storeToken(jwtToken: string) { try { user = jwtDecode(jwtToken); token = jwtToken; localStorage.setItem("jwt", jwtToken); } catch(e) { user = null; token = null; return false; } return true; } /** * Fetch request providing authentication and logout upon unauthorized requests */ export async function authFetch(path: string, options: RequestInit = {}): Promise { console.log("Performing auth fetch"); options.credentials = "include"; options.headers = Object.assign(options.headers ?? {}, { "Authorization": `Bearer ${token}` }); let response = await fetch(path, options); if (response.status === 401) { // forgetToken(); console.log("Forgetting token..."); router.push({ name: "Login" }); throw Error("Unauthorized"); } return response; } /** * @TODO Remove later */ (window).forgetToken = forgetToken; (window).authFetch = authFetch; /** * Ensure the token is loaded upon startup */ loadToken();