kandimat/redaktions-app/src/jwt/jwt.ts

86 lines
2.1 KiB
TypeScript

import { client } from "../backend/helper";
type Claim = "role" | "person_row_id" | "exp" | "iat" | "aud" | "iss";
export type UppercaseUserRole =
| "KANDIMAT_PERSON"
| "KANDIMAT_EDITOR"
| "KANDIMAT_CANDIDATE";
export type UserRole =
| "kandimat_editor"
| "kandimat_candidate"
| "kandimat_person";
export interface JwtPayload {
role: UserRole;
person_row_id: number;
exp: number;
iat: number;
aud: "postgraphile";
iss: "postgraphile";
}
const CLAIMS: Claim[] = ["role", "person_row_id", "exp", "iat", "aud", "iss"];
export const UPPERCASE_USER_ROLES: UppercaseUserRole[] = [
"KANDIMAT_PERSON",
"KANDIMAT_EDITOR",
"KANDIMAT_CANDIDATE",
];
export const USER_ROLES: UserRole[] = [
"kandimat_editor",
"kandimat_candidate",
"kandimat_person",
];
export const getRawJsonWebToken = (): string | null => {
return localStorage.getItem("token");
};
export const isJwtPayloadValid = (jwtPayload: unknown): boolean => {
const jwt = Object(jwtPayload);
return (
CLAIMS.every((claim) => Object.keys(jwt).includes(claim)) &&
USER_ROLES.includes(jwt.role) &&
typeof jwt.person_row_id === "number" &&
typeof jwt.exp === "number" &&
typeof jwt.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");
window.location.reload();
};
export const isLoggedIn = (): boolean => !!getJsonWebToken();