kandimat/redaktions-app/src/jwt/jwt.ts
2020-12-31 11:36:23 +01:00

49 lines
1.4 KiB
TypeScript

export const getRawJsonWebToken = (): string | null => {
return localStorage.getItem('token');
}
export const getJsonWebToken = (): JwtPayload | null => {
const rawToken = getRawJsonWebToken();
return rawToken ? parseJwt(rawToken) : null
}
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 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';
}
const claims = ["role", "person_row_id", "exp", "iat", "aud", "iss"]
const userRoles = ["candymat_editor", 'candymat_candidate', 'candymat_person']
interface JwtPayload {
"role": UserRole,
"person_row_id": number,
"exp": number,
"iat": number,
"aud": "postgraphile",
"iss": "postgraphile"
}
type UserRole = "candymat_editor" | 'candymat_candidate' | 'candymat_person'