// Gate for server-side /internal/* routes. The only caller is the bot process, // on its own boot, over the private compose network — never expose this route // through the public reverse proxy. Timing-safe compare so response time can't // be used to brute-force the shared secret one byte at a time. Same pattern as // bot/src/internal/requireInternalKey.js on the other side of this call. const crypto = require('crypto') function requireInternalKey(req, res, next) { const expected = process.env.BOT_INTERNAL_KEY || '' const provided = req.get('X-Internal-Key') || '' const a = Buffer.from(expected) const b = Buffer.from(provided) const match = expected.length > 0 && a.length === b.length && crypto.timingSafeEqual(a, b) if (!match) return res.status(401).json({ message: 'Unauthorized' }) return next() } module.exports = requireInternalKey