Files
pi-perplexity/src/auth/jwt.ts
T
2026-02-16 18:42:03 +00:00

38 lines
1.2 KiB
TypeScript

const FIVE_MINUTES_MS = 5 * 60 * 1000;
const ONE_HOUR_MS = 60 * 60 * 1000;
function decodeBase64Url(input: string): string {
const normalized = input.replace(/-/g, "+").replace(/_/g, "/");
const padded = normalized + "=".repeat((4 - (normalized.length % 4)) % 4);
return Buffer.from(padded, "base64").toString("utf8");
}
/** Decode JWT payload and extract expiry as epoch ms (with 5min safety margin). Returns fallback of now+1h on decode failure. */
export function decodeJwtExpiry(token: string): number {
const fallback = Date.now() + ONE_HOUR_MS;
try {
const payload = token.split(".")[1];
if (!payload) {
return fallback;
}
const decodedPayload = decodeBase64Url(payload);
const parsed = JSON.parse(decodedPayload) as { exp?: unknown };
if (typeof parsed.exp !== "number" || !Number.isFinite(parsed.exp)) {
return fallback;
}
const expiryMs = parsed.exp * 1000 - FIVE_MINUTES_MS;
return Number.isFinite(expiryMs) ? expiryMs : fallback;
} catch {
return fallback;
}
}
/** Returns true if the token is expired (with optional buffer). */
export function isJwtExpired(token: string, bufferMs = 0): boolean {
return decodeJwtExpiry(token) <= Date.now() + bufferMs;
}