Download src/auth/jwt-age.ts from bolikoto/zcode-api: direct link, hf CLI and curl.
- Browser
- Download file 1.37 kB
-
https://huggingface.co/spaces/bolikoto/zcode-api/resolve/main/src/auth/jwt-age.ts
- Command line
-
hf download hf://spaces/bolikoto/zcode-api/src/auth/jwt-age.ts
-
curl -L -o jwt-age.ts https://huggingface.co/spaces/bolikoto/zcode-api/resolve/main/src/auth/jwt-age.ts
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; | |
| } | |
| } | |