Files
sf-sim/packages/shared/domain/JWT.ts

73 lines
1.8 KiB
TypeScript

export type JWTHeader = {
alg: string,
typ: string,
kid: string
}
export type JWTPayload<T> = {
/** (Issuer) Quién emitió el token */
iss?: string;
/** (Subject) De quién trata el token (ej. user_id) */
sub?: string;
/** (Audience) Destinatarios del token */
aud?: string | string[];
/** (Expiration Time) Fecha de expiración (Unix timestamp) */
exp?: number;
/** (Not Before) No válido antes de esta fecha (Unix timestamp) */
nbf?: number;
/** (Issued At) Cuándo fue emitido (Unix timestamp) */
iat?: number;
/** (JWT ID) Identificador único para este token */
jti?: string;
/** (Authentication Context Class) */
acr?: string
} & T
export type JWTSignature = {
e?: string,
ktv?: string,
n?: string
}
export type JWT<T> = {
header: JWTHeader,
payload?: JWTPayload<T>,
signature: JWTSignature
}
export class JWTToken<T> {
public rawToken: string
private decodedPayload: JWTPayload<T> | undefined
constructor(
token: string
) {
this.rawToken = token
this.decodedPayload = this.decodePayload()
}
private decodePayload(): JWTPayload<T> {
if (this.rawToken == undefined) throw new Error("La clase no tiene un token definido")
const rawTokenPayload = this.rawToken.split(".")[1]
if (rawTokenPayload == undefined) throw new Error("El token no tiene payload")
return JSON.parse(Buffer.from(rawTokenPayload, "base64").toString("utf8"));
}
public isExpired() {
if (this.decodedPayload == undefined) throw new Error("Error leyendo el payload del token")
const now = new Date()
const expirationDate = this.decodedPayload.exp
if (expirationDate == undefined) return false // un token sin fecha de expiracion no expira
if (expirationDate * 1000 <= now.getTime()) return true
return false
}
}