github-webhook-handler 0.7.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.travis.yml ADDED
@@ -0,0 +1,14 @@
1
+ sudo: false
2
+ language: node_js
3
+ node_js:
4
+ - 8
5
+ - 10
6
+ - 12
7
+ - lts/*
8
+ - current
9
+ branches:
10
+ only:
11
+ - master
12
+ notifications:
13
+ email:
14
+ - rod@vagg.org
package/README.md CHANGED
@@ -1,7 +1,8 @@
1
1
  # github-webhook-handler
2
2
 
3
- [![NPM](https://nodei.co/npm/github-webhook-handler.png?downloads=true&downloadRank=true)](https://nodei.co/npm/github-webhook-handler/)
4
- [![NPM](https://nodei.co/npm-dl/github-webhook-handler.png?months=6&height=3)](https://nodei.co/npm/github-webhook-handler/)
3
+ [![Build Status](https://travis-ci.org/rvagg/github-webhook-handler.svg?branch=master)](https://travis-ci.org/rvagg/github-webhook-handler)
4
+
5
+ [![NPM](https://nodei.co/npm/github-webhook-handler.svg)](https://nodei.co/npm/github-webhook-handler/)
5
6
 
6
7
  GitHub allows you to register **[Webhooks](https://developer.github.com/webhooks/)** for your repositories. Each time an event occurs on your repository, whether it be pushing code, filling issues or creating pull requests, the webhook address you register can be configured to be pinged with details.
7
8
 
@@ -75,4 +76,4 @@ Additionally, there is a special `'*'` even you can listen to in order to receiv
75
76
 
76
77
  ## License
77
78
 
78
- **github-webhook-handler** is Copyright (c) 2014 Rod Vagg [@rvagg](https://twitter.com/rvagg) and licensed under the MIT License. All rights not explicitly granted in the MIT License are reserved. See the included [LICENSE.md](./LICENSE.md) file for more details.
79
+ **github-webhook-handler** is Copyright (c) 2014 Rod Vagg and licensed under the MIT License. All rights not explicitly granted in the MIT License are reserved. See the included [LICENSE.md](./LICENSE.md) file for more details.
@@ -13,4 +13,6 @@ interface handler extends EventEmitter {
13
13
  (req: IncomingMessage, res: ServerResponse, callback: (err: Error) => void): void;
14
14
  }
15
15
 
16
- export default function createHandler(options: CreateHandlerOptions): handler;
16
+ declare function createHandler(options: CreateHandlerOptions|CreateHandlerOptions[]): handler;
17
+
18
+ export = createHandler;
@@ -1,29 +1,49 @@
1
- const EventEmitter = require('events').EventEmitter
2
- , inherits = require('util').inherits
3
- , crypto = require('crypto')
4
- , bl = require('bl')
5
- , bufferEq = require('buffer-equal-constant-time')
6
-
7
- function create (options) {
8
- if (typeof options != 'object')
1
+ const EventEmitter = require('events')
2
+ const crypto = require('crypto')
3
+ const bl = require('bl')
4
+
5
+ function findHandler (url, arr) {
6
+ if (!Array.isArray(arr)) {
7
+ return arr
8
+ }
9
+
10
+ let ret = arr[0]
11
+ for (let i = 0; i < arr.length; i++) {
12
+ if (url === arr[i].path) {
13
+ ret = arr[i]
14
+ }
15
+ }
16
+
17
+ return ret
18
+ }
19
+
20
+ function checkType (options) {
21
+ if (typeof options !== 'object') {
9
22
  throw new TypeError('must provide an options object')
23
+ }
10
24
 
11
- if (typeof options.path != 'string')
25
+ if (typeof options.path !== 'string') {
12
26
  throw new TypeError('must provide a \'path\' option')
27
+ }
13
28
 
14
- if (typeof options.secret != 'string')
29
+ if (typeof options.secret !== 'string') {
15
30
  throw new TypeError('must provide a \'secret\' option')
31
+ }
32
+ }
16
33
 
17
- var events
18
-
19
- if (typeof options.events == 'string' && options.events != '*')
20
- events = [ options.events ]
21
-
22
- else if (Array.isArray(options.events) && options.events.indexOf('*') == -1)
23
- events = options.events
34
+ function create (initOptions) {
35
+ let options
36
+ // validate type of options
37
+ if (Array.isArray(initOptions)) {
38
+ for (let i = 0; i < initOptions.length; i++) {
39
+ checkType(initOptions[i])
40
+ }
41
+ } else {
42
+ checkType(initOptions)
43
+ }
24
44
 
25
- // make it an EventEmitter, sort of
26
- handler.__proto__ = EventEmitter.prototype
45
+ // make it an EventEmitter
46
+ Object.setPrototypeOf(handler, EventEmitter.prototype)
27
47
  EventEmitter.call(handler)
28
48
 
29
49
  handler.sign = sign
@@ -31,54 +51,74 @@ function create (options) {
31
51
 
32
52
  return handler
33
53
 
34
-
35
54
  function sign (data) {
36
- return 'sha1=' + crypto.createHmac('sha1', options.secret).update(data).digest('hex')
55
+ return `sha1=${crypto.createHmac('sha1', options.secret).update(data).digest('hex')}`
37
56
  }
38
57
 
39
58
  function verify (signature, data) {
40
- return bufferEq(Buffer.from(signature), Buffer.from(sign(data)))
59
+ const sig = Buffer.from(signature)
60
+ const signed = Buffer.from(sign(data))
61
+ if (sig.length !== signed.length) {
62
+ return false
63
+ }
64
+ return crypto.timingSafeEqual(sig, signed)
41
65
  }
42
66
 
43
67
  function handler (req, res, callback) {
44
- if (req.url.split('?').shift() !== options.path || req.method !== 'POST')
68
+ let events
69
+
70
+ options = findHandler(req.url, initOptions)
71
+
72
+ if (typeof options.events === 'string' && options.events !== '*') {
73
+ events = [options.events]
74
+ } else if (Array.isArray(options.events) && options.events.indexOf('*') === -1) {
75
+ events = options.events
76
+ }
77
+
78
+ if (req.url !== options.path || req.method !== 'POST') {
45
79
  return callback()
80
+ }
46
81
 
47
82
  function hasError (msg) {
48
83
  res.writeHead(400, { 'content-type': 'application/json' })
49
84
  res.end(JSON.stringify({ error: msg }))
50
85
 
51
- var err = new Error(msg)
86
+ const err = new Error(msg)
52
87
 
53
88
  handler.emit('error', err, req)
54
89
  callback(err)
55
90
  }
56
91
 
57
- var sig = req.headers['x-hub-signature']
58
- , event = req.headers['x-github-event']
59
- , id = req.headers['x-github-delivery']
92
+ const sig = req.headers['x-hub-signature']
93
+ const event = req.headers['x-github-event']
94
+ const id = req.headers['x-github-delivery']
60
95
 
61
- if (!sig)
96
+ if (!sig) {
62
97
  return hasError('No X-Hub-Signature found on request')
98
+ }
63
99
 
64
- if (!event)
100
+ if (!event) {
65
101
  return hasError('No X-Github-Event found on request')
102
+ }
66
103
 
67
- if (!id)
104
+ if (!id) {
68
105
  return hasError('No X-Github-Delivery found on request')
106
+ }
69
107
 
70
- if (events && events.indexOf(event) == -1)
108
+ if (events && events.indexOf(event) === -1) {
71
109
  return hasError('X-Github-Event is not acceptable')
110
+ }
72
111
 
73
- req.pipe(bl(function (err, data) {
112
+ req.pipe(bl((err, data) => {
74
113
  if (err) {
75
114
  return hasError(err.message)
76
115
  }
77
116
 
78
- var obj
117
+ let obj
79
118
 
80
- if (!verify(sig, data))
119
+ if (!verify(sig, data)) {
81
120
  return hasError('X-Hub-Signature does not match blob signature')
121
+ }
82
122
 
83
123
  try {
84
124
  obj = JSON.parse(data.toString())
@@ -89,13 +129,14 @@ function create (options) {
89
129
  res.writeHead(200, { 'content-type': 'application/json' })
90
130
  res.end('{"ok":true}')
91
131
 
92
- var emitData = {
93
- event : event
94
- , id : id
95
- , payload : obj
96
- , protocol: req.protocol
97
- , host : req.headers['host']
98
- , url : req.url
132
+ const emitData = {
133
+ event: event,
134
+ id: id,
135
+ payload: obj,
136
+ protocol: req.protocol,
137
+ host: req.headers.host,
138
+ url: req.url,
139
+ path: options.path
99
140
  }
100
141
 
101
142
  handler.emit(event, emitData)
@@ -104,5 +145,4 @@ function create (options) {
104
145
  }
105
146
  }
106
147
 
107
-
108
148
  module.exports = create
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "github-webhook-handler",
3
- "version": "0.7.1",
3
+ "version": "1.0.0",
4
4
  "description": "Web handler / middleware for processing GitHub Webhooks",
5
5
  "main": "github-webhook-handler.js",
6
6
  "types": "github-webhook-handler.d.ts",
7
7
  "scripts": {
8
- "test": "node test.js"
8
+ "lint": "standard *.js",
9
+ "test": "npm run lint && node test.js"
9
10
  },
10
11
  "keywords": [
11
12
  "github",
@@ -18,13 +19,13 @@
18
19
  },
19
20
  "license": "MIT",
20
21
  "dependencies": {
21
- "bl": "~1.1.2",
22
- "buffer-equal-constant-time": "~1.0.1"
22
+ "bl": "~4.0.0"
23
23
  },
24
24
  "devDependencies": {
25
25
  "@types/node": "*",
26
- "run-series": "~1.1.4",
27
- "tape": "~4.6.0",
28
- "through2": "~2.0.1"
26
+ "run-series": "~1.1.8",
27
+ "standard": "~14.3.1",
28
+ "tape": "~4.11.0",
29
+ "through2": "~3.0.1"
29
30
  }
30
31
  }
package/test.js CHANGED
@@ -1,46 +1,41 @@
1
- const test = require('tape')
2
- , crypto = require('crypto')
3
- , handler = require('./')
4
- , through2 = require('through2')
5
- , series = require('run-series')
6
-
1
+ const test = require('tape')
2
+ const crypto = require('crypto')
3
+ const handler = require('./')
4
+ const through2 = require('through2')
5
+ const series = require('run-series')
7
6
 
8
7
  function signBlob (key, blob) {
9
- return 'sha1=' +
10
- crypto.createHmac('sha1', key).update(blob).digest('hex')
8
+ return `sha1=${crypto.createHmac('sha1', key).update(blob).digest('hex')}`
11
9
  }
12
10
 
13
-
14
11
  function mkReq (url, method) {
15
- var req = through2()
12
+ const req = through2()
16
13
  req.method = method || 'POST'
17
14
  req.url = url
18
15
  req.headers = {
19
- 'x-hub-signature' : 'bogus'
20
- , 'x-github-event' : 'bogus'
21
- , 'x-github-delivery' : 'bogus'
16
+ 'x-hub-signature': 'bogus',
17
+ 'x-github-event': 'bogus',
18
+ 'x-github-delivery': 'bogus'
22
19
  }
23
20
  return req
24
21
  }
25
22
 
26
-
27
23
  function mkRes () {
28
- var res = {
29
- writeHead : function (statusCode, headers) {
30
- res.$statusCode = statusCode
31
- res.$headers = headers
32
- }
33
-
34
- , end : function (content) {
35
- res.$end = content
36
- }
24
+ const res = {
25
+ writeHead: function (statusCode, headers) {
26
+ res.$statusCode = statusCode
27
+ res.$headers = headers
28
+ },
29
+
30
+ end: function (content) {
31
+ res.$end = content
32
+ }
37
33
  }
38
34
 
39
35
  return res
40
36
  }
41
37
 
42
-
43
- test('handler without full options throws', function (t) {
38
+ test('handler without full options throws', (t) => {
44
39
  t.plan(4)
45
40
 
46
41
  t.equal(typeof handler, 'function', 'handler exports a function')
@@ -52,60 +47,81 @@ test('handler without full options throws', function (t) {
52
47
  t.throws(handler.bind(null, { path: '/' }), /must provide a 'secret' option/, 'throws if no secret option')
53
48
  })
54
49
 
50
+ test('handler without full options throws in array', (t) => {
51
+ t.plan(2)
52
+
53
+ t.throws(handler.bind(null, [{}]), /must provide a 'path' option/, 'throws if no path option')
55
54
 
56
- test('handler ignores invalid urls', function (t) {
57
- var options = { path: '/some/url', secret: 'bogus' }
58
- , h = handler(options)
55
+ t.throws(handler.bind(null, [{ path: '/' }]), /must provide a 'secret' option/, 'throws if no secret option')
56
+ })
57
+
58
+ test('handler ignores invalid urls', (t) => {
59
+ const options = { path: '/some/url', secret: 'bogus' }
60
+ const h = handler(options)
59
61
 
60
62
  t.plan(6)
61
63
 
62
- h(mkReq('/'), mkRes(), function (err) {
64
+ h(mkReq('/'), mkRes(), (err) => {
63
65
  t.error(err)
64
66
  t.ok(true, 'request was ignored')
65
67
  })
66
68
 
67
69
  // near match
68
- h(mkReq('/some/url/'), mkRes(), function (err) {
70
+ h(mkReq('/some/url/'), mkRes(), (err) => {
69
71
  t.error(err)
70
72
  t.ok(true, 'request was ignored')
71
73
  })
72
74
 
73
75
  // partial match
74
- h(mkReq('/some'), mkRes(), function (err) {
76
+ h(mkReq('/some'), mkRes(), (err) => {
75
77
  t.error(err)
76
78
  t.ok(true, 'request was ignored')
77
79
  })
78
80
  })
79
81
 
80
- test('handler ingores non-POST requests', function (t) {
81
- var options = { path: '/some/url', secret: 'bogus' }
82
- , h = handler(options)
82
+ test('handler ingores non-POST requests', (t) => {
83
+ const options = { path: '/some/url', secret: 'bogus' }
84
+ const h = handler(options)
83
85
 
84
86
  t.plan(4)
85
87
 
86
- h(mkReq('/some/url', 'GET'), mkRes(), function (err) {
88
+ h(mkReq('/some/url', 'GET'), mkRes(), (err) => {
87
89
  t.error(err)
88
90
  t.ok(true, 'request was ignored')
89
91
  })
90
92
 
91
- h(mkReq('/some/url?test=param', 'GET'), mkRes(), function (err) {
93
+ h(mkReq('/some/url?test=param', 'GET'), mkRes(), (err) => {
92
94
  t.error(err)
93
95
  t.ok(true, 'request was ignored')
94
96
  })
95
97
  })
96
98
 
97
- test('handler accepts valid urls', function (t) {
98
- var options = { path: '/some/url', secret: 'bogus' }
99
- , h = handler(options)
99
+ test('handler accepts valid urls', (t) => {
100
+ const options = { path: '/some/url', secret: 'bogus' }
101
+ const h = handler(options)
102
+
103
+ t.plan(1)
104
+
105
+ h(mkReq('/some/url'), mkRes(), (err) => {
106
+ t.error(err)
107
+ t.fail(false, 'should not call')
108
+ })
109
+
110
+ setTimeout(t.ok.bind(t, true, 'done'))
111
+ })
112
+
113
+ test('handler accepts valid urls in Array', (t) => {
114
+ const options = [{ path: '/some/url', secret: 'bogus' }, { path: '/someOther/url', secret: 'bogus' }]
115
+ const h = handler(options)
100
116
 
101
117
  t.plan(1)
102
118
 
103
- h(mkReq('/some/url'), mkRes(), function (err) {
119
+ h(mkReq('/some/url'), mkRes(), (err) => {
104
120
  t.error(err)
105
121
  t.fail(false, 'should not call')
106
122
  })
107
123
 
108
- h(mkReq('/some/url?test=param'), mkRes(), function (err) {
124
+ h(mkReq('/someOther/url'), mkRes(), (err) => {
109
125
  t.error(err)
110
126
  t.fail(false, 'should not call')
111
127
  })
@@ -113,77 +129,75 @@ test('handler accepts valid urls', function (t) {
113
129
  setTimeout(t.ok.bind(t, true, 'done'))
114
130
  })
115
131
 
116
-
117
- test('handler can reject events', function (t) {
118
- var acceptableEvents = {
119
- 'undefined' : undefined
120
- , 'a string equal to the event' : 'bogus'
121
- , 'a string equal to *' : '*'
122
- , 'an array containing the event' : ['bogus']
123
- , 'an array containing *' : ['not-bogus', '*']
124
- }
125
- , unacceptableEvents = {
126
- 'a string not equal to the event or *' : 'not-bogus'
127
- , 'an array not containing the event or *' : ['not-bogus']
128
- }
129
- , acceptable = Object.keys(acceptableEvents)
130
- , unacceptable = Object.keys(unacceptableEvents)
131
- , acceptableTests = acceptable.map(function (events) {
132
- return acceptableReq.bind(null, events)
133
- })
134
- , unacceptableTests = unacceptable.map(function (events) {
135
- return unacceptableReq.bind(null, events)
136
- })
132
+ test('handler can reject events', (t) => {
133
+ const acceptableEvents = {
134
+ undefined: undefined,
135
+ 'a string equal to the event': 'bogus',
136
+ 'a string equal to *': '*',
137
+ 'an array containing the event': ['bogus'],
138
+ 'an array containing *': ['not-bogus', '*']
139
+ }
140
+ const unacceptableEvents = {
141
+ 'a string not equal to the event or *': 'not-bogus',
142
+ 'an array not containing the event or *': ['not-bogus']
143
+ }
144
+ const acceptable = Object.keys(acceptableEvents)
145
+ const unacceptable = Object.keys(unacceptableEvents)
146
+ const acceptableTests = acceptable.map((events) => {
147
+ return acceptableReq.bind(null, events)
148
+ })
149
+ const unacceptableTests = unacceptable.map((events) => {
150
+ return unacceptableReq.bind(null, events)
151
+ })
137
152
 
138
153
  t.plan(acceptable.length + unacceptable.length)
139
154
  series(acceptableTests.concat(unacceptableTests))
140
155
 
141
156
  function acceptableReq (events, callback) {
142
- var h = handler({
143
- path : '/some/url'
144
- , secret : 'bogus'
145
- , events : acceptableEvents[events]
157
+ const h = handler({
158
+ path: '/some/url',
159
+ secret: 'bogus',
160
+ events: acceptableEvents[events]
146
161
  })
147
162
 
148
- h(mkReq('/some/url'), mkRes(), function (err) {
163
+ h(mkReq('/some/url'), mkRes(), (err) => {
149
164
  t.error(err)
150
165
  t.fail(false, 'should not call')
151
166
  })
152
167
 
153
- setTimeout(function () {
168
+ setTimeout(() => {
154
169
  t.ok(true, 'accepted because options.events was ' + events)
155
170
  callback()
156
171
  })
157
172
  }
158
173
 
159
174
  function unacceptableReq (events, callback) {
160
- var h = handler({
161
- path : '/some/url'
162
- , secret : 'bogus'
163
- , events : unacceptableEvents[events]
175
+ const h = handler({
176
+ path: '/some/url',
177
+ secret: 'bogus',
178
+ events: unacceptableEvents[events]
164
179
  })
165
180
 
166
- h.on('error', function () {})
181
+ h.on('error', () => {})
167
182
 
168
- h(mkReq('/some/url'), mkRes(), function (err) {
183
+ h(mkReq('/some/url'), mkRes(), (err) => {
169
184
  t.ok(err, 'rejected because options.events was ' + events)
170
185
  callback()
171
186
  })
172
187
  }
173
188
  })
174
189
 
175
-
176
190
  // because we don't inherit in a traditional way
177
- test('handler is an EventEmitter', function (t) {
191
+ test('handler is an EventEmitter', (t) => {
178
192
  t.plan(5)
179
193
 
180
- var h = handler({ path: '/', secret: 'bogus' })
194
+ const h = handler({ path: '/', secret: 'bogus' })
181
195
 
182
196
  t.equal(typeof h.on, 'function', 'has h.on()')
183
197
  t.equal(typeof h.emit, 'function', 'has h.emit()')
184
198
  t.equal(typeof h.removeListener, 'function', 'has h.removeListener()')
185
199
 
186
- h.on('ping', function (pong) {
200
+ h.on('ping', (pong) => {
187
201
  t.equal(pong, 'pong', 'got event')
188
202
  })
189
203
 
@@ -192,85 +206,110 @@ test('handler is an EventEmitter', function (t) {
192
206
  t.throws(h.emit.bind(h, 'error', new Error('threw an error')), /threw an error/, 'acts like an EE')
193
207
  })
194
208
 
195
-
196
- test('handler accepts a signed blob', function (t) {
209
+ test('handler accepts a signed blob', (t) => {
197
210
  t.plan(4)
198
211
 
199
- var obj = { some: 'github', object: 'with', properties: true }
200
- , json = JSON.stringify(obj)
201
- , h = handler({ path: '/', secret: 'bogus' })
202
- , req = mkReq('/')
203
- , res = mkRes()
212
+ const obj = { some: 'github', object: 'with', properties: true }
213
+ const json = JSON.stringify(obj)
214
+ const h = handler({ path: '/', secret: 'bogus' })
215
+ const req = mkReq('/')
216
+ const res = mkRes()
204
217
 
205
218
  req.headers['x-hub-signature'] = signBlob('bogus', json)
206
- req.headers['x-github-event'] = 'push'
219
+ req.headers['x-github-event'] = 'push'
207
220
 
208
- h.on('push', function (event) {
209
- t.deepEqual(event, { event: 'push', id: 'bogus', payload: obj, url: '/', host: undefined, protocol: undefined })
221
+ h.on('push', (event) => {
222
+ t.deepEqual(event, { event: 'push', id: 'bogus', payload: obj, url: '/', host: undefined, protocol: undefined, path: '/' })
210
223
  t.equal(res.$statusCode, 200, 'correct status code')
211
224
  t.deepEqual(res.$headers, { 'content-type': 'application/json' })
212
225
  t.equal(res.$end, '{"ok":true}', 'got correct content')
213
226
  })
214
227
 
215
- h(req, res, function (err) {
228
+ h(req, res, (err) => {
216
229
  t.error(err)
217
230
  t.fail(true, 'should not get here!')
218
231
  })
219
232
 
220
- process.nextTick(function () {
233
+ process.nextTick(() => {
221
234
  req.end(json)
222
235
  })
223
236
  })
224
237
 
238
+ test('handler accepts multi blob in Array', (t) => {
239
+ t.plan(4)
240
+
241
+ const obj = { some: 'github', object: 'with', properties: true }
242
+ const json = JSON.stringify(obj)
243
+ const h = handler([{ path: '/', secret: 'bogus' }, { path: '/some/url', secret: 'bogus' }])
244
+ const req = mkReq('/some/url')
245
+ const res = mkRes()
246
+ req.headers['x-hub-signature'] = signBlob('bogus', json)
247
+ req.headers['x-github-event'] = 'push'
248
+
249
+ h.on('push', (event) => {
250
+ t.deepEqual(event, { event: 'push', id: 'bogus', payload: obj, url: '/some/url', host: undefined, protocol: undefined, path: '/some/url' })
251
+ t.equal(res.$statusCode, 200, 'correct status code')
252
+ t.deepEqual(res.$headers, { 'content-type': 'application/json' })
253
+ t.equal(res.$end, '{"ok":true}', 'got correct content')
254
+ })
255
+
256
+ h(req, res, (err) => {
257
+ t.error(err)
258
+ t.fail(true, 'should not get here!')
259
+ })
225
260
 
226
- test('handler accepts a signed blob with alt event', function (t) {
261
+ process.nextTick(() => {
262
+ req.end(json)
263
+ })
264
+ })
265
+
266
+ test('handler accepts a signed blob with alt event', (t) => {
227
267
  t.plan(4)
228
268
 
229
- var obj = { some: 'github', object: 'with', properties: true }
230
- , json = JSON.stringify(obj)
231
- , h = handler({ path: '/', secret: 'bogus' })
232
- , req = mkReq('/')
233
- , res = mkRes()
269
+ const obj = { some: 'github', object: 'with', properties: true }
270
+ const json = JSON.stringify(obj)
271
+ const h = handler({ path: '/', secret: 'bogus' })
272
+ const req = mkReq('/')
273
+ const res = mkRes()
234
274
 
235
275
  req.headers['x-hub-signature'] = signBlob('bogus', json)
236
- req.headers['x-github-event'] = 'issue'
276
+ req.headers['x-github-event'] = 'issue'
237
277
 
238
- h.on('push', function (event) {
278
+ h.on('push', (event) => {
239
279
  t.fail(true, 'should not get here!')
240
280
  })
241
281
 
242
- h.on('issue', function (event) {
243
- t.deepEqual(event, { event: 'issue', id: 'bogus', payload: obj, url: '/', host: undefined, protocol: undefined })
282
+ h.on('issue', (event) => {
283
+ t.deepEqual(event, { event: 'issue', id: 'bogus', payload: obj, url: '/', host: undefined, protocol: undefined, path: '/' })
244
284
  t.equal(res.$statusCode, 200, 'correct status code')
245
285
  t.deepEqual(res.$headers, { 'content-type': 'application/json' })
246
286
  t.equal(res.$end, '{"ok":true}', 'got correct content')
247
287
  })
248
288
 
249
- h(req, res, function (err) {
289
+ h(req, res, (err) => {
250
290
  t.error(err)
251
291
  t.fail(true, 'should not get here!')
252
292
  })
253
293
 
254
- process.nextTick(function () {
294
+ process.nextTick(() => {
255
295
  req.end(json)
256
296
  })
257
297
  })
258
298
 
259
-
260
- test('handler rejects a badly signed blob', function (t) {
299
+ test('handler rejects a badly signed blob', (t) => {
261
300
  t.plan(6)
262
301
 
263
- var obj = { some: 'github', object: 'with', properties: true }
264
- , json = JSON.stringify(obj)
265
- , h = handler({ path: '/', secret: 'bogus' })
266
- , req = mkReq('/')
267
- , res = mkRes()
302
+ const obj = { some: 'github', object: 'with', properties: true }
303
+ const json = JSON.stringify(obj)
304
+ const h = handler({ path: '/', secret: 'bogus' })
305
+ const req = mkReq('/')
306
+ const res = mkRes()
268
307
 
269
308
  req.headers['x-hub-signature'] = signBlob('bogus', json)
270
309
  // break signage by a tiny bit
271
310
  req.headers['x-hub-signature'] = '0' + req.headers['x-hub-signature'].substring(1)
272
311
 
273
- h.on('error', function (err, _req) {
312
+ h.on('error', (err, _req) => {
274
313
  t.ok(err, 'got an error')
275
314
  t.strictEqual(_req, req, 'was given original request object')
276
315
  t.equal(res.$statusCode, 400, 'correct status code')
@@ -278,56 +317,54 @@ test('handler rejects a badly signed blob', function (t) {
278
317
  t.equal(res.$end, '{"error":"X-Hub-Signature does not match blob signature"}', 'got correct content')
279
318
  })
280
319
 
281
- h.on('push', function (event) {
320
+ h.on('push', (event) => {
282
321
  t.fail(true, 'should not get here!')
283
322
  })
284
323
 
285
- h(req, res, function (err) {
324
+ h(req, res, (err) => {
286
325
  t.ok(err, 'got error on callback')
287
326
  })
288
327
 
289
- process.nextTick(function () {
328
+ process.nextTick(() => {
290
329
  req.end(json)
291
330
  })
292
331
  })
293
332
 
294
- test('handler responds on a bl error', function (t) {
333
+ test('handler responds on a bl error', (t) => {
295
334
  t.plan(4)
296
335
 
297
- var obj = { some: 'github', object: 'with', properties: true }
298
- , json = JSON.stringify(obj)
299
- , h = handler({ path: '/', secret: 'bogus' })
300
- , req = mkReq('/')
301
- , res = mkRes()
336
+ const obj = { some: 'github', object: 'with', properties: true }
337
+ const json = JSON.stringify(obj)
338
+ const h = handler({ path: '/', secret: 'bogus' })
339
+ const req = mkReq('/')
340
+ const res = mkRes()
302
341
 
303
342
  req.headers['x-hub-signature'] = signBlob('bogus', json)
304
- req.headers['x-github-event'] = 'issue'
343
+ req.headers['x-github-event'] = 'issue'
305
344
 
306
- h.on('push', function (event) {
345
+ h.on('push', (event) => {
307
346
  t.fail(true, 'should not get here!')
308
347
  })
309
348
 
310
- h.on('issue', function (event) {
349
+ h.on('issue', (event) => {
311
350
  t.fail(true, 'should never get here!')
312
351
  })
313
352
 
314
- h.on('error', function(err) {
353
+ h.on('error', (err) => {
315
354
  t.ok(err, 'got an error')
316
355
  t.equal(res.$statusCode, 400, 'correct status code')
317
- });
356
+ })
318
357
 
319
- h(req, res, function (err) {
358
+ h(req, res, (err) => {
320
359
  t.ok(err)
321
360
  })
322
361
 
323
- var end = res.end
324
- res.end = function () {
362
+ res.end = () => {
325
363
  t.equal(res.$statusCode, 400, 'correct status code')
326
364
  }
327
365
 
328
366
  req.write('{')
329
- process.nextTick(function() {
367
+ process.nextTick(() => {
330
368
  req.emit('error', new Error('simulated explosion'))
331
- });
332
-
369
+ })
333
370
  })
package/.jshintrc DELETED
@@ -1,59 +0,0 @@
1
- {
2
- "predef": [ ]
3
- , "bitwise": false
4
- , "camelcase": false
5
- , "curly": false
6
- , "eqeqeq": false
7
- , "forin": false
8
- , "immed": false
9
- , "latedef": false
10
- , "noarg": true
11
- , "noempty": true
12
- , "nonew": true
13
- , "plusplus": false
14
- , "quotmark": true
15
- , "regexp": false
16
- , "undef": true
17
- , "unused": true
18
- , "strict": false
19
- , "trailing": true
20
- , "maxlen": 120
21
- , "asi": true
22
- , "boss": true
23
- , "debug": true
24
- , "eqnull": true
25
- , "esnext": true
26
- , "evil": true
27
- , "expr": true
28
- , "funcscope": false
29
- , "globalstrict": false
30
- , "iterator": false
31
- , "lastsemic": true
32
- , "laxbreak": true
33
- , "laxcomma": true
34
- , "loopfunc": true
35
- , "multistr": false
36
- , "onecase": false
37
- , "proto": false
38
- , "regexdash": false
39
- , "scripturl": true
40
- , "smarttabs": false
41
- , "shadow": false
42
- , "sub": true
43
- , "supernew": false
44
- , "validthis": true
45
- , "browser": true
46
- , "couch": false
47
- , "devel": false
48
- , "dojo": false
49
- , "mootools": false
50
- , "node": true
51
- , "nonstandard": true
52
- , "prototypejs": false
53
- , "rhino": false
54
- , "worker": true
55
- , "wsh": false
56
- , "nomen": false
57
- , "onevar": false
58
- , "passfail": false
59
- }