kandimat/redaktions-app/src/jwt/jwt.ts
2021-02-07 23:06:58 +01:00

62 lines
1.7 KiB
TypeScript

import { client } from "../backend/helper";
type UserRole = "candymat_editor" | "candymat_candidate" | "candymat_person";
interface JwtPayload {
role: UserRole;
person_row_id: number;
exp: number;
iat: number;
aud: "postgraphile";
iss: "postgraphile";
}
const claims = ["role", "person_row_id", "exp", "iat", "aud", "iss"];
const userRoles = ["candymat_editor", "candymat_candidate", "candymat_person"];
export const getRawJsonWebToken = (): string | null => {
return localStorage.getItem("token");
};
export const isJwtPayloadValid = (jwtPayload: JwtPayload): boolean => {
return (
claims.every((claim) => Object.keys(jwtPayload).includes(claim)) &&
userRoles.includes(jwtPayload.role) &&
typeof jwtPayload.person_row_id === "number" &&
typeof jwtPayload.exp === "number" &&
typeof jwtPayload.iat === "number"
);
};
export const parseJwt = (token: string): JwtPayload | null => {
try {
const base64Url = token.split(".")[1];
const base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/");
const jsonPayload = decodeURIComponent(
atob(base64)
.split("")
.map((c) => "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2))
.join("")
);
const jwtPayload = JSON.parse(jsonPayload);
return isJwtPayloadValid(jwtPayload) ? jwtPayload : null;
} catch {
return null;
}
};
export const getJsonWebToken = (): JwtPayload | null => {
const rawToken = getRawJsonWebToken();
return rawToken ? parseJwt(rawToken) : null;
};
export const logoutUser = async (): Promise<void> => {
try {
await client.cache.reset();
} catch (e) {
console.error(e);
}
localStorage.removeItem("token");
location.reload();
};