const { JWT_SECRETS, JWT_SECRET, JWT_ALG } = require('./config'); const debug = require('debug')('talk:secrets'); const jwt = require('./services/jwt'); if (JWT_SECRETS) { if (!Array.isArray(JWT_SECRETS)) { throw new Error('TALK_JWT_SECRETS must be a JSON array in the form [{"kid": kid, ["secret": secret | "private": private, "public": public]}, ...]'); } if (JWT_SECRETS.length === 0) { throw new Error('TALK_JWT_SECRETS must be a JSON array with non zero length'); } // Wrap a multi-secret around the available secrets. module.exports.jwt = new jwt.MultiSecret(JWT_SECRETS.map((secret) => { if (!('kid' in secret)) { throw new Error('when multiple keys are specified, kid\'s must be specified'); } if (typeof secret.kid !== 'string' || secret.kid.length === 0) { throw new Error('kid must be a unique string'); } // HMAC secrets do not have public/private keys. if (JWT_ALG.startsWith('HS')) { return new jwt.SharedSecret(secret, JWT_ALG); } if (!('public' in secret)) { throw new Error('all symetric keys must provide a PEM encoded public key'); } return new jwt.AsymmetricSecret(secret, JWT_ALG); })); debug(`loaded ${JWT_SECRETS.length} ${JWT_ALG.startsWith('HS') ? 'shared' : 'asymmetric'} secrets`); } else if (JWT_SECRET) { if (JWT_ALG.startsWith('HS')) { module.exports.jwt = new jwt.SharedSecret({ secret: JWT_SECRET }, JWT_ALG); } else { module.exports.jwt = new jwt.AsymmetricSecret(JSON.parse(JWT_SECRET), JWT_ALG); } debug(`loaded a ${JWT_ALG.startsWith('HS') ? 'shared' : 'asymmetric'} secret`); }