@duosecurity/duo_api
Advanced tools
Comparing version 1.0.1 to 1.0.2
@@ -8,5 +8,4 @@ { | ||
"rules": { | ||
"camelcase": "off", | ||
"node/no-deprecated-api": "off" | ||
"camelcase": "off" | ||
} | ||
} |
@@ -68,3 +68,3 @@ var crypto = require('crypto') | ||
// Return the Authorization header for an HMAC-SHA1-signed request. | ||
// Return the Authorization header for an HMAC signed request. | ||
function sign (ikey, skey, method, host, path, params, date) { | ||
@@ -76,7 +76,3 @@ var canon = canonicalize(method, host, path, params, date) | ||
/** | ||
* Move to Buffer.from and remove no-deprecated-api | ||
* lint exception when we remove Node v4 support | ||
*/ | ||
var auth = new Buffer([ikey, sig].join(':')).toString('base64') | ||
var auth = Buffer.from([ikey, sig].join(':')).toString('base64') | ||
return 'Basic ' + auth | ||
@@ -86,3 +82,5 @@ } | ||
module.exports = { | ||
'sign': sign | ||
'sign': sign, | ||
'_canonParams': canonParams, | ||
'_canonicalize': canonicalize | ||
} |
@@ -5,2 +5,7 @@ var duo_sig = require('./duo_sig') | ||
// Constants for handling rate limit backoff and retries | ||
const _MAX_BACKOFF_WAIT_SECS = 32 | ||
const _BACKOFF_FACTOR = 2 | ||
const _RATE_LIMITED_RESP_CODE = 429 | ||
function Client (ikey, skey, host) { | ||
@@ -30,3 +35,3 @@ this.ikey = ikey | ||
var req = https.request({ | ||
const options = { | ||
'host': this.host, | ||
@@ -36,3 +41,17 @@ 'method': method, | ||
'headers': headers | ||
}, function (res) { | ||
} | ||
_request_with_backoff(options, body, callback) | ||
} | ||
function _request_with_backoff (options, body, callback, waitSecs = 1) { | ||
var req = https.request(options, function (res) { | ||
if (res.statusCode === _RATE_LIMITED_RESP_CODE && | ||
waitSecs <= _MAX_BACKOFF_WAIT_SECS) { | ||
var randomOffset = Math.floor(Math.random() * 1000) | ||
setTimeout(function () { | ||
_request_with_backoff(options, body, callback, waitSecs * _BACKOFF_FACTOR) | ||
}, waitSecs * 1000 + randomOffset) | ||
return | ||
} | ||
var buffer = '' | ||
@@ -48,2 +67,5 @@ res.setEncoding('utf8') | ||
}) | ||
req.on('error', (err) => { | ||
callback(JSON.stringify({ stat: 'ERROR', message: err.message })) | ||
}) | ||
req.write(body) | ||
@@ -50,0 +72,0 @@ req.end() |
{ | ||
"name": "@duosecurity/duo_api", | ||
"version": "1.0.1", | ||
"version": "1.0.2", | ||
"license": "BSD-3-Clause", | ||
@@ -13,3 +13,3 @@ "description": "Duo API SDK for Node.js applications", | ||
"scripts": { | ||
"test": "nodeunit tests", | ||
"test": "./node_modules/mocha/bin/mocha ./tests/*", | ||
"lint": "eslint lib/ tests/" | ||
@@ -20,7 +20,9 @@ }, | ||
"eslint-config-standard": "^11.0.0", | ||
"eslint-plugin-import": "^2.8.0", | ||
"eslint-plugin-node": "^5.2.1", | ||
"eslint-plugin-promise": "^3.7.0", | ||
"eslint-plugin-standard": "^3.0.1", | ||
"eslint-plugin-import": "^2.8.0", | ||
"eslint-plugin-node": "^5.2.1", | ||
"nodeunit": ">= 0.8.6" | ||
"mocha": "^5.2.0", | ||
"nock": "^9.6.1", | ||
"sinon": "^7.2.7" | ||
}, | ||
@@ -27,0 +29,0 @@ "optionalDependencies": { |
@@ -1,28 +0,24 @@ | ||
var sandbox = require('nodeunit').utils.sandbox | ||
var duo_api = sandbox('lib/duo_sig.js', { | ||
Buffer: Buffer, | ||
encodeURIComponent: encodeURIComponent, | ||
require: require, | ||
module: {} | ||
}) | ||
/* global describe it */ | ||
var assert = require('assert') | ||
var duo_api = require('../lib/duo_sig.js') | ||
module.exports = [] | ||
module.exports['Query Parameter Checks'] = { | ||
'zero params': function (test) { | ||
test.equals(duo_api.canonParams({}), '') | ||
test.done() | ||
}, | ||
describe('Query Parameter Checks', function () { | ||
it('zero params', function (done) { | ||
assert.equal(duo_api._canonParams({}), '') | ||
done() | ||
}) | ||
'one param': function (test) { | ||
test.equals( | ||
duo_api.canonParams({'realname': ['First Last']}), | ||
it('one param', function (done) { | ||
assert.equal( | ||
duo_api._canonParams({'realname': ['First Last']}), | ||
'realname=First%20Last' | ||
) | ||
test.done() | ||
}, | ||
done() | ||
}) | ||
'two params': function (test) { | ||
test.equals( | ||
duo_api.canonParams({ | ||
it('two params', function (done) { | ||
assert.equal( | ||
duo_api._canonParams({ | ||
'realname': ['First Last'], | ||
@@ -33,8 +29,8 @@ 'username': ['root'] | ||
) | ||
test.done() | ||
}, | ||
done() | ||
}) | ||
'list string': function (test) { | ||
test.equals( | ||
duo_api.canonParams({ | ||
it('list string', function (done) { | ||
assert.equal( | ||
duo_api._canonParams({ | ||
'realname': 'First Last', | ||
@@ -45,8 +41,8 @@ 'username': ['root'] | ||
) | ||
test.done() | ||
}, | ||
done() | ||
}) | ||
'printable ascii characters': function (test) { | ||
test.equals( | ||
duo_api.canonParams({ | ||
it('printable ascii characters', function (done) { | ||
assert.equal( | ||
duo_api._canonParams({ | ||
'digits': ['0123456789'], | ||
@@ -59,8 +55,8 @@ 'letters': ['abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'], | ||
) | ||
test.done() | ||
}, | ||
done() | ||
}) | ||
'unicode fuzz values': function (test) { | ||
test.equals( | ||
duo_api.canonParams({ | ||
it('unicode fuzz values', function (done) { | ||
assert.equal( | ||
duo_api._canonParams({ | ||
'bar': ['\u2815\uaaa3\u37cf\u4bb7\u36e9\ucc05\u668e\u8162\uc2bd\ua1f1'], | ||
@@ -73,8 +69,8 @@ 'baz': ['\u0df3\u84bd\u5669\u9985\ub8a4\uac3a\u7be7\u6f69\u934a\ub91c'], | ||
) | ||
test.done() | ||
}, | ||
done() | ||
}) | ||
'unicode fuzz keys and values': function (test) { | ||
test.equals( | ||
duo_api.canonParams({ | ||
it('unicode fuzz keys and values', function (done) { | ||
assert.equal( | ||
duo_api._canonParams({ | ||
'\u469a\u287b\u35d0\u8ef3\u6727\u502a\u0810\ud091\xc8\uc170': ['\u0f45\u1a76\u341a\u654c\uc23f\u9b09\uabe2\u8343\u1b27\u60d0'], | ||
@@ -87,8 +83,8 @@ '\u7449\u7e4b\uccfb\u59ff\ufe5f\u83b7\uadcc\u900c\ucfd1\u7813': ['\u8db7\u5022\u92d3\u42ef\u207d\u8730\uacfe\u5617\u0946\u4e30'], | ||
) | ||
test.done() | ||
}, | ||
done() | ||
}) | ||
'sort order with common prefix': function (test) { | ||
test.equals( | ||
duo_api.canonParams({ | ||
it('sort order with common prefix', function (done) { | ||
assert.equal( | ||
duo_api._canonParams({ | ||
'foo_bar': '2', | ||
@@ -99,8 +95,8 @@ 'foo': '1' | ||
) | ||
test.done() | ||
}, | ||
done() | ||
}) | ||
'sort order with real-world common prefix': function (test) { | ||
test.equals( | ||
duo_api.canonParams({ | ||
it('sort order with real-world common prefix', function (done) { | ||
assert.equal( | ||
duo_api._canonParams({ | ||
'ip_whitelist_enroll_policy': '2', | ||
@@ -111,25 +107,4 @@ 'ip_whitelist': '1' | ||
) | ||
test.done() | ||
} | ||
} | ||
module.exports['Signature Checks'] = { | ||
'HMAC-SHA1': function (test) { | ||
var actual = duo_api.sign( | ||
'test_ikey', | ||
'gtdfxv9YgVBYcF6dl2Eq17KUQJN2PLM2ODVTkvoT', | ||
'PoSt', | ||
'foO.BAr52.cOm', | ||
'/Foo/BaR2/qux', | ||
{ | ||
'\u469a\u287b\u35d0\u8ef3\u6727\u502a\u0810\ud091\xc8\uc170': ['\u0f45\u1a76\u341a\u654c\uc23f\u9b09\uabe2\u8343\u1b27\u60d0'], | ||
'\u7449\u7e4b\uccfb\u59ff\ufe5f\u83b7\uadcc\u900c\ucfd1\u7813': ['\u8db7\u5022\u92d3\u42ef\u207d\u8730\uacfe\u5617\u0946\u4e30'], | ||
'\u7470\u9314\u901c\u9eae\u40d8\u4201\u82d8\u8c70\u1d31\ua042': ['\u17d9\u0ba8\u9358\uaadf\ua42a\u48be\ufb96\u6fe9\ub7ff\u32f3'], | ||
'\uc2c5\u2c1d\u2620\u3617\u96b3F\u8605\u20e8\uac21\u5934': ['\ufba9\u41aa\ubd83\u840b\u2615\u3e6e\u652d\ua8b5\ud56bU'] | ||
}, | ||
'Fri, 07 Dec 2012 17:18:00 -0000' | ||
) | ||
test.equals(actual, 'Basic dGVzdF9pa2V5OmYwMTgxMWNiYmY5NTYxNjIzYWI0NWI4OTMwOTYyNjdmZDQ2YTUxNzg=') | ||
test.done() | ||
} | ||
} | ||
done() | ||
}) | ||
}) |
Sorry, the diff of this file is not supported yet
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
16853
11
373
0
9