'use strict'; const crypto = require('crypto'); function b64url(input) { return Buffer.from(input).toString('base64url'); } function signHS256(payload, secret, expiresInSec = 3600) { const now = Math.floor(Date.now() / 1000); const body = { ...payload, iat: now, exp: now + expiresInSec }; const header = b64url(JSON.stringify({ alg: 'HS256', typ: 'JWT' })); const claims = b64url(JSON.stringify(body)); const data = `${header}.${claims}`; const sig = crypto.createHmac('sha256', secret).update(data).digest('base64url'); return `${data}.${sig}`; } function verifyHS256(token, secret) { if (!token || !secret) return null; const parts = String(token).split('.'); if (parts.length !== 3) return null; const [header, claims, sig] = parts; const expected = crypto.createHmac('sha256', secret).update(`${header}.${claims}`).digest('base64url'); const a = Buffer.from(sig); const b = Buffer.from(expected); if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) return null; let payload; try { payload = JSON.parse(Buffer.from(claims, 'base64url').toString('utf8')); } catch { return null; } if (payload.exp && payload.exp < Math.floor(Date.now() / 1000)) return null; return payload; } module.exports = { signHS256, verifyHS256 };