zcode-api / src /auth /jwt-age.ts
bolikoto's picture
Deploy minimal Docker Space
67d18ac verified
Raw History Blame Contribute Delete
1.37 kB
/**
* JWT age inspection for the stored start-plan token.
*
* Informational only: the token payload carries `iat` but no `exp`, and the
* billing gateway does NOT reject by age — an 8-day-old JWT still serves
* `billing/balance` (verified live). Re-login is only needed when the gateway
* actually returns 401 / 3012. The age is surfaced so operators can see how
* fresh the credential is.
*/
export interface JwtInfo {
/** Unix seconds when the token was issued. */
iat: number;
/** Token age in hours at the time of inspection. */
ageHours: number;
userId?: string;
}
/** Decode a zcode-plan JWT payload without verifying the signature. */
export function inspectJwt(jwt: string): JwtInfo | null {
const parts = jwt.split(".");
if (parts.length !== 3) return null;
try {
const b64 = parts[1].replace(/-/g, "+").replace(/_/g, "/");
const pad = b64.length % 4 === 0 ? "" : "=".repeat(4 - (b64.length % 4));
const payload = JSON.parse(Buffer.from(b64 + pad, "base64").toString("utf8")) as {
iat?: number;
user_id?: string;
sub?: string;
};
if (typeof payload.iat !== "number") return null;
return {
iat: payload.iat,
ageHours: Math.max(0, (Date.now() / 1000 - payload.iat) / 3600),
...(payload.user_id ? { userId: payload.user_id } : {}),
};
} catch {
return null;
}
}