index.js 1.4 KB

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