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` ); }