Files
codey.lol/src/utils/jwt.js

58 lines
1.6 KiB
JavaScript
Raw Normal View History

2025-08-09 07:10:04 -04:00
import jwt from 'jsonwebtoken';
import fs from 'fs';
import path from 'path';
import os from 'os';
// JWT keys location - can be configured via environment variable
// In production, prefer using a secret management service (Vault, AWS Secrets Manager, etc.)
const secretFilePath = import.meta.env.JWT_KEYS_PATH || path.join(
2025-08-09 07:10:04 -04:00
os.homedir(),
'.config',
'api_jwt_keys.json'
);
// Warn if using default location in production
if (!import.meta.env.JWT_KEYS_PATH && !import.meta.env.DEV) {
console.warn(
'[SECURITY WARNING] JWT_KEYS_PATH not set. Using default location ~/.config/api_jwt_keys.json. ' +
'Consider using a secret management service in production.'
);
}
2025-08-09 07:10:04 -04:00
// Load and parse keys JSON once at startup
let keyFileData;
try {
keyFileData = JSON.parse(fs.readFileSync(secretFilePath, 'utf-8'));
} catch (err) {
console.error(`[CRITICAL] Failed to load JWT keys from ${secretFilePath}:`, err.message);
throw new Error('JWT keys file not found or invalid. Set JWT_KEYS_PATH environment variable.');
}
2025-08-09 07:10:04 -04:00
export function verifyToken(token) {
if (!token) {
return null;
}
try {
const decoded = jwt.decode(token, { complete: true });
if (!decoded?.header?.kid) {
throw new Error('No kid in token header');
}
const kid = decoded.header.kid;
const key = keyFileData.keys[kid];
if (!key) {
throw new Error(`Unknown kid: ${kid}`);
}
// Verify using the correct key and HS256 algo
const payload = jwt.verify(token, key, { algorithms: ['HS256'] });
return payload;
} catch (error) {
console.error('JWT verification failed:', error.message);
return null;
}
}