Files
pagodera/lib/auth/jwt.ts
T
Evandro Fonseca Junior 7f42def478 feat(market): add Minha Intenções tab with panel, hook, and badge
- Introduced "Minhas Intenções" tab visible only to logged-in users.
- Integrated MyPurchaseIntentionsPanel and useMyPurchaseIntentions hook.
- Added tab badge showing count of pending intentions.
- Extended session API to include user’s main character for downstream features.
2025-11-07 17:25:51 -03:00

134 lines
2.6 KiB
TypeScript

/**
* Módulo de geração e validação de tokens JWT
* Access tokens (15min) e Refresh tokens (7 dias)
*/
import jwt from "jsonwebtoken";
interface TokenPayload {
userId: number;
username: string;
type: "access" | "refresh";
}
/**
* Obtém o secret do JWT (lazy loading)
*/
function getJWTSecret(): string {
const secret = process.env.JWT_SECRET;
if (!secret) {
throw new Error("JWT_SECRET não está definido nas variáveis de ambiente");
}
return secret;
}
/**
* Obtém o refresh secret do JWT (lazy loading)
*/
function getJWTRefreshSecret(): string {
const secret = process.env.JWT_REFRESH_SECRET;
if (!secret) {
throw new Error(
"JWT_REFRESH_SECRET não está definido nas variáveis de ambiente"
);
}
return secret;
}
// Tempos de expiração
const ACCESS_TOKEN_EXPIRY = "1h"; // 1 hora
const REFRESH_TOKEN_EXPIRY = "7d"; // 7 dias
/**
* Gera access token JWT
* @param userId - ID do usuário
* @param username - Nome de usuário
* @returns Access token
*/
export function generateAccessToken(
userId: number,
username: string
): string {
const payload: TokenPayload = {
userId,
username,
type: "access",
};
return jwt.sign(payload, getJWTSecret(), {
expiresIn: ACCESS_TOKEN_EXPIRY,
});
}
/**
* Gera refresh token JWT
* @param userId - ID do usuário
* @param username - Nome de usuário
* @returns Refresh token
*/
export function generateRefreshToken(
userId: number,
username: string
): string {
const payload: TokenPayload = {
userId,
username,
type: "refresh",
};
return jwt.sign(payload, getJWTRefreshSecret(), {
expiresIn: REFRESH_TOKEN_EXPIRY,
});
}
/**
* Valida e decodifica access token
* @param token - Access token
* @returns Payload do token ou null se inválido
*/
export function verifyAccessToken(token: string): {
userId: number;
username: string;
} | null {
try {
const decoded = jwt.verify(token, getJWTSecret()) as TokenPayload;
if (decoded.type !== "access") {
return null;
}
return {
userId: decoded.userId,
username: decoded.username,
};
} catch (error) {
return null;
}
}
/**
* Valida e decodifica refresh token
* @param token - Refresh token
* @returns Payload do token ou null se inválido
*/
export function verifyRefreshToken(token: string): {
userId: number;
username: string;
} | null {
try {
const decoded = jwt.verify(token, getJWTRefreshSecret()) as TokenPayload;
if (decoded.type !== "refresh") {
return null;
}
return {
userId: decoded.userId,
username: decoded.username,
};
} catch (error) {
return null;
}
}