Files
TurboTrades/utils/jwt.js
2026-01-10 04:57:43 +00:00

121 lines
2.9 KiB
JavaScript

import jwt from "jsonwebtoken";
import { config } from "../config/index.js";
/**
* Generate an access token
* @param {Object} payload - The payload to encode in the token
* @returns {string} The generated access token
*/
export const generateAccessToken = (payload) => {
return jwt.sign(payload, config.jwt.accessSecret, {
expiresIn: config.jwt.accessExpiry,
issuer: "turbotrades",
audience: "turbotrades-api",
});
};
/**
* Generate a refresh token
* @param {Object} payload - The payload to encode in the token
* @returns {string} The generated refresh token
*/
export const generateRefreshToken = (payload) => {
return jwt.sign(payload, config.jwt.refreshSecret, {
expiresIn: config.jwt.refreshExpiry,
issuer: "turbotrades",
audience: "turbotrades-api",
});
};
/**
* Generate both access and refresh tokens
* @param {Object} user - The user object
* @returns {Object} Object containing both tokens
*/
export const generateTokenPair = (user) => {
const payload = {
userId: user._id.toString(),
steamId: user.steamId,
username: user.username,
avatar: user.avatar,
staffLevel: user.staffLevel || 0,
};
return {
accessToken: generateAccessToken(payload),
refreshToken: generateRefreshToken(payload),
};
};
/**
* Verify an access token
* @param {string} token - The token to verify
* @returns {Object} The decoded token payload
*/
export const verifyAccessToken = (token) => {
try {
return jwt.verify(token, config.jwt.accessSecret, {
issuer: "turbotrades",
audience: "turbotrades-api",
});
} catch (error) {
throw new Error(`Invalid access token: ${error.message}`);
}
};
/**
* Verify a refresh token
* @param {string} token - The token to verify
* @returns {Object} The decoded token payload
*/
export const verifyRefreshToken = (token) => {
try {
return jwt.verify(token, config.jwt.refreshSecret, {
issuer: "turbotrades",
audience: "turbotrades-api",
});
} catch (error) {
throw new Error(`Invalid refresh token: ${error.message}`);
}
};
/**
* Decode a token without verification (useful for debugging)
* @param {string} token - The token to decode
* @returns {Object|null} The decoded token or null if invalid
*/
export const decodeToken = (token) => {
try {
return jwt.decode(token);
} catch (error) {
return null;
}
};
/**
* Check if a token is expired
* @param {string} token - The token to check
* @returns {boolean} True if expired, false otherwise
*/
export const isTokenExpired = (token) => {
try {
const decoded = jwt.decode(token);
if (!decoded || !decoded.exp) {
return true;
}
return Date.now() >= decoded.exp * 1000;
} catch (error) {
return true;
}
};
export default {
generateAccessToken,
generateRefreshToken,
generateTokenPair,
verifyAccessToken,
verifyRefreshToken,
decodeToken,
isTokenExpired,
};