Skip to content

Commit 4e31b36

Browse files
committed
feat: add support for x-forwarded-host
Adds `trustProxy` option to HMAC_SHA1 and Provider constructor. It overloads the Provider constructor with the third argument being either a nonceStore or an options object (for a nonceStore, a signer and the trustProxy flag): new Provider(key: string, secret: string, options: NonceStore|Options, signer: Algo)
1 parent 4df2936 commit 4e31b36

File tree

2 files changed

+32
-10
lines changed

2 files changed

+32
-10
lines changed

src/hmac-sha1.coffee

+22-6
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ _clean_request_body = (body, query) ->
4040

4141
class HMAC_SHA1
4242

43+
constructor: (options) ->
44+
@trustProxy = options and options.trustProxy
45+
4346
toString: () ->
4447
'HMAC_SHA1'
4548

@@ -52,24 +55,37 @@ class HMAC_SHA1
5255

5356
@sign_string sig.join('&'), consumer_secret, token
5457

58+
host: (req) ->
59+
if not @trustProxy
60+
return req.headers.host
61+
62+
req.headers['x-forwarded-host'] or req.headers.host
63+
64+
protocol: (req) ->
65+
xprotocol = req.headers['x-forwarded-proto']
66+
if @trustProxy and xproto
67+
return xproto
68+
69+
if req.protocol
70+
return req.protocol
71+
72+
if req.connection.encrypted then 'https' else 'http'
73+
5574
build_signature: (req, body, consumer_secret, token) ->
5675
hapiRawReq = req.raw and req.raw.req
5776
if hapiRawReq
5877
req = hapiRawReq
5978

6079
originalUrl = req.originalUrl or req.url
61-
protocol = req.protocol
80+
host = @host req
81+
protocol = @protocol req
6282

6383
# Since canvas includes query parameters in the body we can omit the query string
6484
if body.tool_consumer_info_product_family_code == 'canvas'
6585
originalUrl = url.parse(originalUrl).pathname
6686

67-
if protocol is undefined
68-
encrypted = req.connection.encrypted
69-
protocol = (encrypted and 'https') or 'http'
70-
7187
parsedUrl = url.parse originalUrl, true
72-
hitUrl = protocol + '://' + req.headers.host + parsedUrl.pathname
88+
hitUrl = protocol + '://' + host + parsedUrl.pathname
7389

7490
@build_signature_raw hitUrl, parsedUrl, req.method, body, consumer_secret, token
7591

src/provider.coffee

+10-4
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,25 @@ extensions = require './extensions'
66

77

88
class Provider
9-
constructor: (consumer_key, consumer_secret, nonceStore, signature_method=(new HMAC_SHA1()) ) ->
9+
constructor: (consumer_key, consumer_secret, optionsOrNonceStore, signature_method) ->
1010

1111
if typeof consumer_key is 'undefined' or consumer_key is null
1212
throw new errors.ConsumerError 'Must specify consumer_key'
1313

1414
if typeof consumer_secret is 'undefined' or consumer_secret is null
1515
throw new errors.ConsumerError 'Must specify consumer_secret'
1616

17-
if not nonceStore
17+
if optionsOrNonceStore and optionsOrNonceStore.isNonceStore?()
18+
nonceStore = optionsOrNonceStore
19+
options = {
20+
trustProxy: false
21+
}
22+
else
1823
nonceStore = new MemoryNonceStore()
24+
options = optionsOrNonceStore or {}
1925

20-
if not nonceStore.isNonceStore?()
21-
throw new errors.ParameterError 'Fourth argument must be a nonceStore object'
26+
if not signature_method
27+
signature_method = options.signer or new HMAC_SHA1(options)
2228

2329
@consumer_key = consumer_key
2430
@consumer_secret = consumer_secret

0 commit comments

Comments
 (0)