All files / server/utils jwt.js

70.59% Statements 12/17
64.29% Branches 9/14
100% Functions 1/1
70.59% Lines 12/17
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59          1x 1x 1x   1x                                                       1x   30x         30x   30x   30x   30x   30x       30x    
/**
 * JWT utilities.
 *
 * @module server/utils/jwt
 */
const jwt = require('jsonwebtoken');
const _ = require('lodash');
const moment = require('moment');
 
const config = require('../../config');
 
/**
 * Generates a JWT token with the specified properties.
 *
 * This function will check that:
 *
 * * The `exp` claim is set and is valid.
 * * The `sub` claim is set.
 *
 * Only some JWT claims are documented in the function's parameters, but other
 * claims can be included.
 *
 * @param {object} properties - Arbitrary JWT properties (see documentation links).
 *
 * @param {number} [properties.exp] - The Unix timestamp (in seconds) at which the
 *   token will expire (defaults to 1 hour from the time the function is called).
 *
 * @param {number} [properties.iat] - The Unix timestamp (in seconds) at which the
 *   token was issued (defaults to the time the function is called).
 *
 * @param {string} properties.sub - The principal of the JWT.
 *
 * @returns {string} A JWT.
 *
 * @see https://jwt.io
 * @see https://tools.ietf.org/html/rfc7519#section-4.1
 */
exports.generateToken = function(properties) {
 
  const jwtOptions = _.extend({
    exp: properties.exp || moment().add(1, 'hour').unix(),
    iat: properties.iat || moment().unix()
  }, _.omit(properties, 'exp', 'iat'));
 
  Iif (jwtOptions.exp === undefined) {
    throw new Error(`JWT "exp" option is required`);
  } else Iif (!_.isFinite(jwtOptions.exp)) {
    throw new Error(`JWT "exp" option must be a number, got ${jwtOptions.exp} (${typeof(jwtOptions.exp)})`);
  } else Iif (jwtOptions.exp <= 0) {
    throw new Error(`JWT "exp" option must be greater than zero, got ${jwtOptions.exp}`);
  } else Iif (!jwtOptions.sub) {
    throw new Error(`JWT "sub" option is required`);
  } else Iif (!_.isString(jwtOptions.sub)) {
    throw new Error(`JWT "sub" option must be a string`);
  }
 
  return jwt.sign(jwtOptions, config.sessionSecret);
};