index.js
1 /** 2 * Module dependencies. 3 */ 4 5 var crypto = require('crypto'); 6 7 /** 8 * Sign the given `val` with `secret`. 9 * 10 * @param {String} val 11 * @param {String|NodeJS.ArrayBufferView|crypto.KeyObject} secret 12 * @return {String} 13 * @api private 14 */ 15 16 exports.sign = function(val, secret){ 17 if ('string' != typeof val) throw new TypeError("Cookie value must be provided as a string."); 18 if (null == secret) throw new TypeError("Secret key must be provided."); 19 return val + '.' + crypto 20 .createHmac('sha256', secret) 21 .update(val) 22 .digest('base64') 23 .replace(/\=+$/, ''); 24 }; 25 26 /** 27 * Unsign and decode the given `input` with `secret`, 28 * returning `false` if the signature is invalid. 29 * 30 * @param {String} input 31 * @param {String|NodeJS.ArrayBufferView|crypto.KeyObject} secret 32 * @return {String|Boolean} 33 * @api private 34 */ 35 36 exports.unsign = function(input, secret){ 37 if ('string' != typeof input) throw new TypeError("Signed cookie string must be provided."); 38 if (null == secret) throw new TypeError("Secret key must be provided."); 39 var tentativeValue = input.slice(0, input.lastIndexOf('.')), 40 expectedInput = exports.sign(tentativeValue, secret), 41 expectedBuffer = Buffer.from(expectedInput), 42 inputBuffer = Buffer.from(input); 43 return ( 44 expectedBuffer.length === inputBuffer.length && 45 crypto.timingSafeEqual(expectedBuffer, inputBuffer) 46 ) ? tentativeValue : false; 47 };