Comparing version 0.0.7 to 1.0.0
38
index.js
@@ -1,2 +0,1 @@ | ||
// deed - verify x-hub-signature | ||
@@ -6,16 +5,15 @@ | ||
var string_decoder = require("string_decoder") | ||
, crypto = require("crypto") | ||
, stream = require("stream") | ||
, util = require("util") | ||
; | ||
var string_decoder = require('string_decoder') | ||
var crypto = require('crypto') | ||
var stream = require('stream') | ||
var util = require('util') | ||
util.inherits(Verify, stream.Transform) | ||
function Verify (sig) { | ||
stream.Transform.call(this) | ||
this.buf = "sha1=" | ||
this.buf = 'sha1=' | ||
this.sig = sig | ||
this.dec = new string_decoder.StringDecoder("hex") | ||
this.dec = new string_decoder.StringDecoder('hex') | ||
this._readableState.objectMode = true | ||
} | ||
util.inherits(Verify, stream.Transform) | ||
@@ -34,17 +32,15 @@ Verify.prototype._transform = function (chunk, enc, cb) { | ||
function deed (secret, req, cb) { | ||
var xub = "X-Hub-Signature" | ||
, sig = req.headers[xub] || req.headers[xub.toLowerCase()] | ||
; | ||
if (!sig) return cb(new Error("no " + xub)) | ||
var hmac = crypto.createHmac("sha1", secret) | ||
, verify = new Verify(sig) | ||
; | ||
verify.once("readable", function () { | ||
verify.read() ? cb(null, req) : cb(new Error("unverified " + xub)) | ||
var xub = 'X-Hub-Signature' | ||
var sig = req.headers[xub] || req.headers[xub.toLowerCase()] | ||
if (!sig) return cb(new Error('no ' + xub)) | ||
var hmac = crypto.createHmac('sha1', secret) | ||
var verify = new Verify(sig) | ||
verify.once('readable', function () { | ||
verify.read() ? cb(null, req) : cb(new Error('unverified ' + xub)) | ||
}) | ||
verify.once("error", cb) | ||
hmac.once("error", cb) | ||
req.once("error", cb) | ||
verify.once('error', cb) | ||
hmac.once('error', cb) | ||
req.once('error', cb) | ||
req.pipe(hmac).pipe(verify) | ||
return req | ||
} |
{ | ||
"name": "deed", | ||
"version": "0.0.7", | ||
"description": "verify x-hub-signature", | ||
"version": "1.0.0", | ||
"description": "Verify x-hub-signature", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "tap --tap test/*.js" | ||
"test": "NODE_TEST=1 tap -b -C test/*.js" | ||
}, | ||
@@ -25,3 +25,3 @@ "repository": { | ||
}, | ||
"license": "ISC", | ||
"license": "MIT", | ||
"bugs": { | ||
@@ -32,3 +32,3 @@ "url": "https://github.com/michaelnisi/deed/issues" | ||
"devDependencies": { | ||
"tap": "0.4.x" | ||
"tap": "^1.4.1" | ||
}, | ||
@@ -35,0 +35,0 @@ "engines": { |
@@ -1,17 +0,16 @@ | ||
# deed - verify x-hub-signature | ||
The Deed [Node.js](http://nodejs.org/) module verifies `X-Hub-Signature` headers which are a simple way to verify HTTP POST requests. For example, this can be used to authorize requests to callback URLs, say, from [GitHub webhooks](https://developer.github.com/v3/repos/hooks/) or the [Facebook API](https://developers.facebook.com/docs/graph-api/real-time-updates/v2.0). | ||
**deed** verifies `X-Hub-Signature` headers, which are a simple way to verify HTTP POST requests. For example, this can be used to authorize requests to callback URLs, say, from [GitHub webhooks](https://developer.github.com/v3/repos/hooks/) or the [Facebook API](https://developers.facebook.com/docs/graph-api/real-time-updates/v2.0). | ||
[![Build Status](https://secure.travis-ci.org/michaelnisi/deed.svg)](http://travis-ci.org/michaelnisi/deed) [![David DM](https://david-dm.org/michaelnisi/deed.svg)](http://david-dm.org/michaelnisi/deed) | ||
[![Build Status](https://secure.travis-ci.org/michaelnisi/deed.svg)](http://travis-ci.org/michaelnisi/deed) | ||
## example | ||
## Example | ||
```js | ||
var deed = require('deed') | ||
, http = require('http') | ||
; | ||
var http = require('http') | ||
http.createServer(function (req, res) { | ||
deed('secret', req, function (er, req) { | ||
res.end(er ? 'go away' : 'ok') | ||
res.end(er ? 'sorry' : 'ok') | ||
}) | ||
@@ -21,7 +20,7 @@ }).listen(1337) | ||
## types | ||
## Types | ||
### cb (er, req) | ||
### cb(er, req) | ||
The callback receives an error, if verification failed, otherwise `null` and the authorized request are passed. | ||
The callback receives an error, if the verification failed, otherwise `null` and the authorized request are passed. | ||
@@ -31,15 +30,15 @@ - `er` The error if an error occured or verification failed. | ||
## exports | ||
## Exports | ||
### deed (secret, req, cb) | ||
### deed(secret, req, cb) | ||
The sole function exported by Deed checks if the request body hashed with the secret matches the `X-Hub-Signature` header. | ||
The sole function exported by the **deed** module checks if the request body, hashed with the secret, matches the `X-Hub-Signature` header. | ||
- `secret` The key to hash the payload. | ||
- `req` The request to verify. | ||
- `secret` `String()` The key to hash the payload with. | ||
- `req` `http.IncomingMessage()` The request to verify. | ||
- `cb` cb() | ||
The client must generate an HMAC signature of the payload and include that signature in the request headers. The `X-Hub-Signature` header's value must be `sha1=signature` where signature is a hexadecimal representation of a SHA1 signature. The signature must be computed using the HMAC algorithm with the request body as the data and the secret as the key. | ||
The client must generate an HMAC signature of the payload and include that signature in the request headers. The `X-Hub-Signature` header's value must be `sha1=signature`, where signature is a hexadecimal representation of a SHA1 signature. The signature must be computed using the HMAC algorithm with the request body as the data and the secret as the key. | ||
Deed recomputes the SHA1 signature with the shared secret using the same method as the client. If the signature does not match, the request cannot be verified and should probably be dropped. | ||
**deed** recomputes the SHA1 signature with the shared secret using the same method as the client. If the signature does not match, the request cannot be verified and should probably be dropped. | ||
@@ -50,6 +49,10 @@ Originally this technique has been decribed in the [PubSubHubbub](http://pubsubhubbub.googlecode.com/git/pubsubhubbub-core-0.3.html#authednotify) spec. | ||
[![NPM](https://nodei.co/npm/deed.svg)](https://npmjs.org/package/deed) | ||
With [npm](https://npmjs.org/package/deed) do: | ||
``` | ||
npm install deed | ||
``` | ||
## License | ||
[ISC License](https://github.com/michaelnisi/deed/blob/master/LICENSE) | ||
[MIT](https://github.com/michaelnisi/deed/blob/master/LICENSE) |
@@ -0,17 +1,15 @@ | ||
var crypto = require('crypto') | ||
var deed = require('../') | ||
var http = require('http') | ||
var test = require('tap').test | ||
var crypto = require("crypto") | ||
, deed = require("../") | ||
, http = require("http") | ||
, test = require("tap").test | ||
; | ||
var SECRET = 'secret' | ||
var SECRET = "secret" | ||
test("none", function (t) { | ||
test('none', function (t) { | ||
t.plan(3) | ||
var req = new http.IncomingMessage() | ||
deed(SECRET, req, function (er, req) { | ||
t.ok(er, "should error") | ||
t.is(er.message, "no X-Hub-Signature") | ||
t.ok(!req, "should not pass request") | ||
t.ok(er, 'should error') | ||
t.is(er.message, 'no X-Hub-Signature') | ||
t.ok(!req, 'should not pass request') | ||
t.end() | ||
@@ -23,7 +21,7 @@ }) | ||
return { | ||
hostname: "localhost" | ||
, port: 1337 | ||
, method: "POST" | ||
, headers: { | ||
"X-Hub-Signature": "sha1=" + sig | ||
hostname: 'localhost', | ||
port: 1337, | ||
method: 'POST', | ||
headers: { | ||
'X-Hub-Signature': 'sha1=' + sig | ||
} | ||
@@ -33,9 +31,9 @@ } | ||
test("unverified", function (t) { | ||
test('unverified', function (t) { | ||
t.plan(4) | ||
var server = http.createServer(function (req, res) { | ||
deed(SECRET, req, function (er, req) { | ||
t.ok(er, "should error") | ||
t.ok(!req, "should not pass request") | ||
t.is(er.message, "unverified X-Hub-Signature") | ||
t.ok(er, 'should error') | ||
t.ok(!req, 'should not pass request') | ||
t.is(er.message, 'unverified X-Hub-Signature') | ||
res.end() | ||
@@ -46,6 +44,6 @@ }) | ||
var req = http.request(opts("hello"), function (res) { | ||
res.on("end", function () { | ||
var req = http.request(opts('hello'), function (res) { | ||
res.on('end', function () { | ||
server.close(function (er) { | ||
t.error(er, "should not error") | ||
t.error(er, 'should not error') | ||
t.end() | ||
@@ -60,13 +58,13 @@ }) | ||
function sig (body) { | ||
var hmac = crypto.createHmac("sha1", SECRET) | ||
var hmac = crypto.createHmac('sha1', SECRET) | ||
hmac.update(body) | ||
return hmac.digest("hex") | ||
return hmac.digest('hex') | ||
} | ||
test("verified", function (t) { | ||
test('verified', function (t) { | ||
t.plan(3) | ||
var server = http.createServer(function (req, res) { | ||
deed(SECRET, req, function (er, req) { | ||
t.error(er, "should not error") | ||
t.ok(req, "should pass request") | ||
t.error(er, 'should not error') | ||
t.ok(req, 'should pass request') | ||
res.end() | ||
@@ -77,8 +75,8 @@ }) | ||
var body = "this is the body" | ||
var body = 'this is the body' | ||
var req = http.request(opts(sig(body)), function (res) { | ||
res.on("end", function () { | ||
res.on('end', function () { | ||
server.close(function (er) { | ||
t.error(er, "should not error") | ||
t.error(er, 'should not error') | ||
t.end() | ||
@@ -85,0 +83,0 @@ }) |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
6977
0
56
113