import jwt from "jsonwebtoken"; import { env } from "../config/env.js"; export interface AuthTokenPayload { userProfileId: number; tokenVersion: number; } export function signAuthToken(payload: AuthTokenPayload): string { // "sub" follows the JWT convention (RFC 7519) of identifying the // principal as a string; userProfileId/tokenVersion are our own claims. return jwt.sign( { sub: String(payload.userProfileId), tokenVersion: payload.tokenVersion }, env.JWT_SECRET, { expiresIn: env.JWT_EXPIRES_IN as jwt.SignOptions["expiresIn"] }, ); } export function verifyAuthToken(token: string): AuthTokenPayload { const decoded = jwt.verify(token, env.JWT_SECRET); const userProfileId = typeof decoded === "object" ? Number(decoded.sub) : Number.NaN; if ( typeof decoded !== "object" || Number.isNaN(userProfileId) || typeof decoded.tokenVersion !== "number" ) { throw new Error("Malformed auth token payload"); } return { userProfileId, tokenVersion: decoded.tokenVersion }; }