import { SignJWT, jwtVerify, decodeJwt } from "jose"; import type { JWTPayload } from "jose"; const JWT_SECRET = new TextEncoder().encode( process.env.JWT_SECRET || "dev-secret-change-in-production" ); const ACCESS_TOKEN_EXPIRY = "15m"; export interface AccessTokenPayload extends JWTPayload { userId: number; sessionId: string; role: string; } export async function signAccessToken(payload: { userId: number; sessionId: string; role: string; }): Promise { return new SignJWT(payload as Record) .setProtectedHeader({ alg: "HS256" }) .setIssuedAt() .setExpirationTime(ACCESS_TOKEN_EXPIRY) .sign(JWT_SECRET); } export async function verifyAccessToken( token: string ): Promise { try { const { payload } = await jwtVerify(token, JWT_SECRET); return payload as AccessTokenPayload; } catch { return null; } } export function decodeAccessTokenNoVerify(token: string): AccessTokenPayload | null { try { return decodeJwt(token) as AccessTokenPayload; } catch { return null; } }