strategy.js 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. var passport = require('passport-strategy')
  2. , siwe = require('siwe')
  3. , url = require('url')
  4. , util = require('util')
  5. , utils = require('./utils')
  6. , SessionStore = require('./store/session');
  7. function Strategy(options, verify) {
  8. if (typeof options == 'function') {
  9. verify = options;
  10. options = {};
  11. }
  12. if (!verify) { throw new TypeError('EthereumStrategy requires a verify function'); }
  13. this.name = 'ethereum';
  14. this._verify = verify;
  15. this._passReqToCallback = options.passReqToCallback;
  16. this._store = options.store || new SessionStore();
  17. }
  18. /**
  19. * Inherit from `passport.Strategy`.
  20. */
  21. util.inherits(Strategy, passport.Strategy);
  22. Strategy.prototype.authenticate = function(req, options) {
  23. //console.log(req.body);
  24. var message = req.body.message
  25. , signature = req.body.signature;
  26. if (!message) { return this.fail({ message: 'Missing message.' }, 400); }
  27. if (!signature) { return this.fail({ message: 'Missing signature.' }, 400); }
  28. var self = this;
  29. var siweMessage;
  30. try {
  31. var siweMessage = new siwe.SiweMessage(message);
  32. } catch(ex) {
  33. return self.fail({ message: 'Malformed message.' }, 403);
  34. }
  35. var origin = utils.originalOrigin(req);
  36. if (origin !== siweMessage.uri) {
  37. return self.fail({ message: 'URI mismatch.' }, 403);
  38. }
  39. var domain = url.parse(origin).host;
  40. if (domain !== siweMessage.domain) {
  41. return self.fail({ message: 'Domain mismatch.' }, 403);
  42. }
  43. if (siweMessage.notBefore) {
  44. if (new Date(siweMessage.notBefore).getTime() > new Date().getTime()) {
  45. return self.fail({ message: 'Message not yet valid.' }, 403);
  46. }
  47. }
  48. this._store.verify(req, siweMessage.nonce, function(err, ok, info) {
  49. if (!ok) {
  50. return self.fail(info, 403);
  51. }
  52. siweMessage.validate(signature)
  53. .then(function(message) {
  54. function verified(err, user, info) {
  55. if (err) { return self.error(err); }
  56. if (!user) { return self.fail(info); }
  57. self.success(user, info);
  58. }
  59. try {
  60. if (self._passReqToCallback) {
  61. self._verify(req, message.address, verified);
  62. } else {
  63. var arity = self._verify.length;
  64. switch (arity) {
  65. case 3:
  66. return self._verify(message.address, message.chainId, verified);
  67. default:
  68. return self._verify(message.address, verified);
  69. }
  70. }
  71. } catch (ex) {
  72. return self.error(ex);
  73. }
  74. })
  75. .catch(function(err) {
  76. return self.fail({ message: err.message || 'Invalid signature.' }, 403);
  77. });
  78. });
  79. };
  80. /**
  81. * Expose `Strategy`.
  82. */
  83. module.exports = Strategy;