braintree
Version:
A library for integrating with Braintree.
104 lines (86 loc) • 3.67 kB
JavaScript
//@ sourceMappingURL=webhook_notification_gateway.map
// Generated by CoffeeScript 1.6.1
var Digest, Gateway, InvalidSignatureError, Util, WebhookNotification, WebhookNotificationGateway, xml2js, _,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
xml2js = require('xml2js');
_ = require('underscore');
Digest = require('./digest').Digest;
Gateway = require('./gateway').Gateway;
InvalidSignatureError = require('./exceptions').InvalidSignatureError;
Util = require('./util').Util;
WebhookNotification = require('./webhook_notification').WebhookNotification;
WebhookNotificationGateway = (function(_super) {
__extends(WebhookNotificationGateway, _super);
function WebhookNotificationGateway(gateway) {
this.gateway = gateway;
this.parser = new xml2js.Parser({
explicitRoot: true
});
}
WebhookNotificationGateway.prototype.parse = function(signature, payload, callback) {
var err, xmlPayload,
_this = this;
if (payload.match(/[^A-Za-z0-9+=\/\n]/)) {
callback(InvalidSignatureError("payload contains illegal characters"), null);
return;
}
err = this.validateSignature(signature, payload);
if (err) {
return callback(err, null);
}
xmlPayload = new Buffer(payload, "base64").toString("utf8");
return this.parser.parseString(xmlPayload, function(err, result) {
var attributes, handler;
attributes = Util.convertNodeToObject(result);
handler = _this.createResponseHandler("notification", WebhookNotification, function(err, result) {
return callback(null, result.notification);
});
return handler(null, attributes);
});
};
WebhookNotificationGateway.prototype.validateSignature = function(signatureString, payload) {
var matches, pair, self, signature, signaturePairs;
signaturePairs = (function() {
var _i, _len, _ref, _results;
_ref = signatureString.split("&");
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
pair = _ref[_i];
if (pair.indexOf("|") !== -1) {
_results.push(pair.split("|"));
}
}
return _results;
})();
signature = this.matchingSignature(signaturePairs);
if (!signature) {
return InvalidSignatureError("no matching public key");
}
self = this;
matches = _.some([payload, payload + '\n'], function(payload) {
return Digest.secureCompare(signature, Digest.Sha1hexdigest(self.gateway.config.privateKey, payload));
});
if (!matches) {
return InvalidSignatureError("signature does not match payload - one has been modified");
}
return null;
};
WebhookNotificationGateway.prototype.verify = function(challenge) {
var digest;
digest = Digest.Sha1hexdigest(this.gateway.config.privateKey, challenge);
return "" + this.gateway.config.publicKey + "|" + digest;
};
WebhookNotificationGateway.prototype.matchingSignature = function(signaturePairs) {
var publicKey, signature, _i, _len, _ref;
for (_i = 0, _len = signaturePairs.length; _i < _len; _i++) {
_ref = signaturePairs[_i], publicKey = _ref[0], signature = _ref[1];
if (this.gateway.config.publicKey === publicKey) {
return signature;
}
}
return null;
};
return WebhookNotificationGateway;
})(Gateway);
exports.WebhookNotificationGateway = WebhookNotificationGateway;