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

43 lines
1.4 KiB
TypeScript

import { afterEach, beforeEach, describe, expect, test } from "bun:test";
import { decodeJwtExpiry, isJwtExpired } from "../../src/auth/jwt.js";
const FIXED_NOW = Date.UTC(2026, 1, 16, 12, 0, 0);
function createJwt(expSeconds: number): string {
const header = Buffer.from(JSON.stringify({ alg: "HS256", typ: "JWT" })).toString("base64url");
const payload = Buffer.from(JSON.stringify({ exp: expSeconds })).toString("base64url");
return `${header}.${payload}.signature`;
}
describe("jwt helpers", () => {
const originalNow = Date.now;
beforeEach(() => {
Date.now = () => FIXED_NOW;
});
afterEach(() => {
Date.now = originalNow;
});
test("decodeJwtExpiry returns expiry in ms with 5 minute safety margin", () => {
const expSeconds = Math.floor((FIXED_NOW + 2 * 60 * 60 * 1000) / 1000);
const token = createJwt(expSeconds);
expect(decodeJwtExpiry(token)).toBe(expSeconds * 1000 - 5 * 60 * 1000);
});
test("decodeJwtExpiry falls back to now + 1h when token is malformed", () => {
expect(decodeJwtExpiry("not-a-jwt")).toBe(FIXED_NOW + 60 * 60 * 1000);
});
test("isJwtExpired honors additional caller-provided buffer", () => {
const expSeconds = Math.floor((FIXED_NOW + 20 * 60 * 1000) / 1000);
const token = createJwt(expSeconds);
expect(isJwtExpired(token)).toBe(false);
expect(isJwtExpired(token, 16 * 60 * 1000)).toBe(true);
});
});