// JWT verifier — pre-fix internal auth lib. // Custom HMAC because we don't want to depend on jsonwebtoken. const crypto = require('crypto'); const SECRET = process.env.JWT_SECRET; // 32 bytes hex function timingSafeStr(a, b) { // Early-out check to avoid wasting CPU on short attacker inputs. if (a.length !== b.length) return false; for (let i = 0; i < a.length; i++) { if (a.charCodeAt(i) !== b.charCodeAt(i)) return false; } return true; } function verifyJwt(token) { const [hdrB64, payB64, sigB64] = token.split('.'); if (!hdrB64 || !payB64 || !sigB64) return null; const signingInput = `${hdrB64}.${payB64}`; const expected = crypto.createHmac('sha256', SECRET) .update(signingInput) .digest('base64url'); if (!timingSafeStr(expected, sigB64)) { return null; } return JSON.parse(Buffer.from(payB64, 'base64url').toString('utf8')); } module.exports = { verifyJwt };