Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

duo_web

Package Overview
Dependencies
Maintainers
1
Versions
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

duo_web - npm Package Compare versions

Comparing version 1.0.2 to 1.0.3

.eslintrc.json

223

duo.js

@@ -1,27 +0,27 @@

var crypto = require('crypto');
var crypto = require('crypto')
var DUO_PREFIX = "TX",
APP_PREFIX = "APP",
AUTH_PREFIX = "AUTH";
var DUO_PREFIX = 'TX'
var APP_PREFIX = 'APP'
var AUTH_PREFIX = 'AUTH'
var DUO_EXPIRE = 300,
APP_EXPIRE = 3600,
IKEY_LEN = 20,
SKEY_LEN = 40,
AKEY_LEN = 40;
var DUO_EXPIRE = 300
var APP_EXPIRE = 3600
var IKEY_LEN = 20
var SKEY_LEN = 40
var AKEY_LEN = 40
/* Exception Messages */
var ERR_USER = 'ERR|The username passed to sign_request() is invalid.',
ERR_IKEY = 'ERR|The Duo integration key passed to sign_request() is invalid',
ERR_SKEY = 'ERR|The Duo secret key passed to sign_request() is invalid',
ERR_AKEY = 'ERR|The application secret key passed to sign_request() must be at least ' + String(AKEY_LEN) + ' characters.';
var ERR_USER = 'ERR|The username passed to sign_request() is invalid.'
var ERR_IKEY = 'ERR|The Duo integration key passed to sign_request() is invalid'
var ERR_SKEY = 'ERR|The Duo secret key passed to sign_request() is invalid'
var ERR_AKEY = 'ERR|The application secret key passed to sign_request() must be at least ' + String(AKEY_LEN) + ' characters.'
exports.ERR_USER = ERR_USER;
exports.ERR_IKEY = ERR_IKEY;
exports.ERR_SKEY = ERR_SKEY;
exports.ERR_AKEY = ERR_AKEY;
exports.ERR_USER = ERR_USER
exports.ERR_IKEY = ERR_IKEY
exports.ERR_SKEY = ERR_SKEY
exports.ERR_AKEY = ERR_AKEY
/**
* @function sign a value
*
*
* @param {String} key Integration's Secret Key

@@ -31,19 +31,24 @@ * @param {String} vals Value(s) to sign

* @param {Integer} expire time till expiry
*
* @return {String} Containing the signed value in sha1-hmac with prefix
*
*
* @return {String} Containing the signed value in sha1-hmac with prefix
*
* @api private
*/
function _sign_vals(key, vals, prefix, expire) {
var exp = Math.round((new Date()).getTime() / 1000) + expire;
var val = vals + '|' + exp;
var b64 = new Buffer(val).toString('base64');
var cookie = prefix + '|' + b64;
function _sign_vals (key, vals, prefix, expire) {
var exp = Math.round((new Date()).getTime() / 1000) + expire
var sig = crypto.createHmac('sha1', key)
.update(cookie)
.digest('hex');
return cookie + '|' + sig;
var val = vals + '|' + exp
/**
* Move to Buffer.from and remove no-deprecated-api
* lint exception when we remove Node v4 support
*/
var b64 = new Buffer(val).toString('base64')
var cookie = prefix + '|' + b64
var sig = crypto.createHmac('sha1', key)
.update(cookie)
.digest('hex')
return cookie + '|' + sig
}

@@ -53,3 +58,3 @@

* @function parses a value
*
*
* @param {String} key Integration's Secret Key

@@ -61,46 +66,50 @@ * @param {String} val Value to unpack

* @return {String/Null} Returns a username on successful parse. Null if not
*
*
* @api private
*/
function _parse_vals(key, val, prefix, ikey) {
var ts = Math.round((new Date()).getTime() / 1000);
var parts = val.split('|');
if (parts.length != 3) {
return null;
}
function _parse_vals (key, val, prefix, ikey) {
var ts = Math.round((new Date()).getTime() / 1000)
var parts = val.split('|')
if (parts.length !== 3) {
return null
}
var u_prefix = parts[0];
var u_b64 = parts[1];
var u_sig = parts[2];
var u_prefix = parts[0]
var u_b64 = parts[1]
var u_sig = parts[2]
var sig = crypto.createHmac('sha1', key)
.update(u_prefix + '|' + u_b64)
.digest('hex');
if (crypto.createHmac('sha1', key).update(sig).digest('hex') != crypto.createHmac('sha1', key).update(u_sig).digest('hex')) {
return null;
}
if (u_prefix != prefix) {
return null;
}
var sig = crypto.createHmac('sha1', key)
.update(u_prefix + '|' + u_b64)
.digest('hex')
var cookie_parts = new Buffer(u_b64, 'base64').toString('utf8').split('|');
if (cookie_parts.length != 3) {
return null;
}
if (crypto.createHmac('sha1', key).update(sig).digest('hex') !== crypto.createHmac('sha1', key).update(u_sig).digest('hex')) {
return null
}
var user = cookie_parts[0];
var u_ikey = cookie_parts[1];
var exp = cookie_parts[2];
if (u_prefix !== prefix) {
return null
}
if (u_ikey != ikey) {
return null;
}
/**
* Move to Buffer.from and remove no-deprecated-api
* lint exception when we remove Node v4 support
*/
var cookie_parts = new Buffer(u_b64, 'base64').toString('utf8').split('|')
if (cookie_parts.length !== 3) {
return null
}
if (ts >= parseInt(exp)) {
return null;
}
var user = cookie_parts[0]
var u_ikey = cookie_parts[1]
var exp = cookie_parts[2]
return user;
if (u_ikey !== ikey) {
return null
}
if (ts >= parseInt(exp)) {
return null
}
return user
}

@@ -110,36 +119,36 @@

* @function sign's a login request to be passed onto Duo Security
*
*
* @param {String} ikey Integration Key
* @param {String} skey Secret Key
* @param {String} akey Application Security Key
* @param {String} username Username
*
* @param {String} username Username
*
* @return {String} Duo Signature
*
*
* @api public
*/
exports.sign_request = function (ikey, skey, akey, username) {
if (!username || username.length < 1) {
return ERR_USER;
}
if (username.indexOf('|') !== -1) {
return ERR_USER;
}
if (!ikey || ikey.length != IKEY_LEN) {
return ERR_IKEY;
}
if (!skey || skey.length != SKEY_LEN) {
return ERR_SKEY;
}
if (!akey || akey.length < AKEY_LEN) {
return ERR_AKEY;
}
if (!username || username.length < 1) {
return ERR_USER
}
if (username.indexOf('|') !== -1) {
return ERR_USER
}
if (!ikey || ikey.length !== IKEY_LEN) {
return ERR_IKEY
}
if (!skey || skey.length !== SKEY_LEN) {
return ERR_SKEY
}
if (!akey || akey.length < AKEY_LEN) {
return ERR_AKEY
}
var vals = username + '|' + ikey;
var vals = username + '|' + ikey
var duo_sig = _sign_vals(skey, vals, DUO_PREFIX, DUO_EXPIRE);
var app_sig = _sign_vals(akey, vals, APP_PREFIX, APP_EXPIRE);
var duo_sig = _sign_vals(skey, vals, DUO_PREFIX, DUO_EXPIRE)
var app_sig = _sign_vals(akey, vals, APP_PREFIX, APP_EXPIRE)
var sig_request = duo_sig + ':' + app_sig;
return sig_request;
var sig_request = duo_sig + ':' + app_sig
return sig_request
}

@@ -149,3 +158,3 @@

* @function verifies a response from Duo Security
*
*
* @param {String} ikey Integration Key

@@ -155,23 +164,23 @@ * @param {String} skey Secret Key

* @param {String} sig_response Signature Response from Duo
*
*
* @param (String/Null} Returns a string containing the username if the response checks out. Returns null if it does not.
*
*
* @api public
*/
exports.verify_response = function (ikey, skey, akey, sig_response) {
var parts = sig_response.split(':');
if (parts.length != 2) {
return null;
}
var parts = sig_response.split(':')
if (parts.length !== 2) {
return null
}
var auth_sig = parts[0];
var app_sig = parts[1];
var auth_user = _parse_vals(skey, auth_sig, AUTH_PREFIX, ikey);
var app_user = _parse_vals(akey, app_sig, APP_PREFIX, ikey);
var auth_sig = parts[0]
var app_sig = parts[1]
var auth_user = _parse_vals(skey, auth_sig, AUTH_PREFIX, ikey)
var app_user = _parse_vals(akey, app_sig, APP_PREFIX, ikey)
if (auth_user != app_user) {
return null;
}
if (auth_user !== app_user) {
return null
}
return auth_user;
return auth_user
}

@@ -1,1 +0,1 @@

module.exports = require('./duo');
module.exports = require('./duo')
{
"name": "duo_web",
"version": "1.0.2",
"description": "Duo two-factor authentication for Node.js web applications",
"homepage": "https://www.duosecurity.com/docs/duoweb",
"main": "index.js",
"scripts": {
"test": "nodeunit tests"
},
"repository": {
"type": "git",
"url": "https://github.com/duosecurity/duo_nodejs.git"
},
"keywords": [
"Duo Security",
"Two-Factor Authentication"
],
"readmeFilename": "README.md",
"bugs": {
"url": "https://github.com/duosecurity/duo_nodejs/issues"
},
"licenses": [
{
"type": "Duo License",
"url": "https://github.com/duosecurity/duo_nodejs/blob/master/LICENSE"
}
]
"name": "duo_web",
"version": "1.0.3",
"license": "BSD-3-Clause",
"description": "Duo two-factor authentication for Node.js web applications",
"homepage": "https://www.duosecurity.com/docs/duoweb",
"main": "index.js",
"repository": {
"type": "git",
"url": "https://github.com/duosecurity/duo_nodejs.git"
},
"scripts": {
"test": "nodeunit tests",
"lint": "eslint duo.js index.js tests/"
},
"devDependencies": {
"eslint": "^4.18.2",
"eslint-config-standard": "^11.0.0",
"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"
},
"dependencies": {},
"keywords": [
"Duo Security",
"Two-Factor Authentication"
],
"readmeFilename": "README.md",
"bugs": {
"url": "https://github.com/duosecurity/duo_nodejs/issues"
},
"licenses": [
{
"type": "Duo License",
"url": "https://github.com/duosecurity/duo_nodejs/blob/master/LICENSE"
}
]
}
# Overview
**duo_nodejs** - Duo two-factor authentication for Node.js web applications
[![Build Status](https://travis-ci.org/duosecurity/duo_nodejs.svg?branch=master)](https://travis-ci.org/duosecurity/duo_nodejs)
What's here:
**duo_nodejs** - Duo two-factor authentication for Node.js web applications: https://duo.com/docs/duoweb
* `js` - Duo Javascript library, to be hosted by your webserver.
* `duo.js` - Duo Node.js SDK to be integrated with your web application
* `test.js` - Unit tests for our SDK. Run using `nodeunit tests`
This package allows a web developer to quickly add Duo's interactive, self-service, two-factor authentication to any web login form - without setting up secondary user accounts, directory synchronization, servers, or hardware.
# Usage
Files located in the `js` directory should be hosted by your webserver for inclusion in web pages.
Install by dropping duo_nodejs in node_modules and including it in your project.
# Installing
```var Duo = require('duo_nodejs');```
Development:
Developer documentation: <http://www.duosecurity.com/docs/duoweb>
```
$ git clone https://github.com/duosecurity/duo_nodejs.git
$ cd duo_nodejs
$ npm install
```
System:
```
$ npm install global duo_web
```
Or run the following to add to your project:
```
$ npm install --save duo_web
```
# Using
```
$ node --interactive
> const duo_web = require('duo_web');
> duo_web.sign_request(ikey, skey, akey, username);
'TX|...TX_SIGNATURE...==|...TX_HASH...:APP|...APP_SIGNATURE...==|...APP_HASH...'
```
# Test
```
$ npm run test
...
OK: 13 assertions (42ms)
```
# Lint
```
$ npm run lint
> duo_web@1.0.1 lint /home/matt/duo/duo_nodejs
> eslint duo.js index.js tests/
```
# Support
Report any bugs, feature requests, etc. to us directly:
support@duosecurity.com
Report any bugs, feature requests, etc. to us directly: support@duosecurity.com
Have fun!
<http://www.duosecurity.com>

@@ -1,92 +0,91 @@

var Duo = require('../index');
var Duo = require('../index')
var IKEY = "DIXXXXXXXXXXXXXXXXXX",
WRONG_IKEY = "DIXXXXXXXXXXXXXXXXXY",
SKEY = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef",
AKEY = "useacustomerprovidedapplicationsecretkey",
USER = "testuser",
INVALID_RESPONSE = "AUTH|INVALID|SIG",
EXPIRED_RESPONSE = "AUTH|dGVzdHVzZXJ8RElYWFhYWFhYWFhYWFhYWFhYWFh8MTMwMDE1Nzg3NA==|cb8f4d60ec7c261394cd5ee5a17e46ca7440d702",
FUTURE_RESPONSE = "AUTH|dGVzdHVzZXJ8RElYWFhYWFhYWFhYWFhYWFhYWFh8MTYxNTcyNzI0Mw==|d20ad0d1e62d84b00a3e74ec201a5917e77b6aef",
WRONG_PARAMS_RESPONSE = "AUTH|dGVzdHVzZXJ8RElYWFhYWFhYWFhYWFhYWFhYWFh8MTYxNTcyNzI0M3xpbnZhbGlkZXh0cmFkYXRh|6cdbec0fbfa0d3f335c76b0786a4a18eac6cdca7",
WRONG_PARAMS_APP = "APP|dGVzdHVzZXJ8RElYWFhYWFhYWFhYWFhYWFhYWFh8MTYxNTcyNzI0M3xpbnZhbGlkZXh0cmFkYXRh|7c2065ea122d028b03ef0295a4b4c5521823b9b5";
var IKEY = 'DIXXXXXXXXXXXXXXXXXX'
var WRONG_IKEY = 'DIXXXXXXXXXXXXXXXXXY'
var SKEY = 'deadbeefdeadbeefdeadbeefdeadbeefdeadbeef'
var AKEY = 'useacustomerprovidedapplicationsecretkey'
var USER = 'testuser'
var INVALID_RESPONSE = 'AUTH|INVALID|SIG'
var EXPIRED_RESPONSE = 'AUTH|dGVzdHVzZXJ8RElYWFhYWFhYWFhYWFhYWFhYWFh8MTMwMDE1Nzg3NA==|cb8f4d60ec7c261394cd5ee5a17e46ca7440d702'
var FUTURE_RESPONSE = 'AUTH|dGVzdHVzZXJ8RElYWFhYWFhYWFhYWFhYWFhYWFh8MTYxNTcyNzI0Mw==|d20ad0d1e62d84b00a3e74ec201a5917e77b6aef'
var WRONG_PARAMS_RESPONSE = 'AUTH|dGVzdHVzZXJ8RElYWFhYWFhYWFhYWFhYWFhYWFh8MTYxNTcyNzI0M3xpbnZhbGlkZXh0cmFkYXRh|6cdbec0fbfa0d3f335c76b0786a4a18eac6cdca7'
var WRONG_PARAMS_APP = 'APP|dGVzdHVzZXJ8RElYWFhYWFhYWFhYWFhYWFhYWFh8MTYxNTcyNzI0M3xpbnZhbGlkZXh0cmFkYXRh|7c2065ea122d028b03ef0295a4b4c5521823b9b5'
module.exports['Signing Checks'] = {
'sign request with ikey/skey/akey and user': function (test) {
var request_sig = Duo.sign_request(IKEY, SKEY, AKEY, USER);
test.notEqual(request_sig, null, 'Invalid Request');
test.done();
},
'sign request without a user': function (test) {
var request_sig = Duo.sign_request(IKEY, SKEY, AKEY, "");
test.equal(request_sig, Duo.ERR_USER, 'Sign request user check failed');
test.done();
},
'sign request with invalid user': function (test) {
var request_sig = Duo.sign_request(IKEY, SKEY, AKEY, "in|valid");
test.equal(request_sig, Duo.ERR_USER, 'Sign request user check failed');
test.done();
},
'sign request with an invalid ikey': function(test) {
var request_sig = Duo.sign_request("invalid", SKEY, AKEY, USER);
test.equal(request_sig, Duo.ERR_IKEY, 'Sign request ikey check failed');
test.done();
},
'sign request with an invalid skey': function(test) {
var request_sig = Duo.sign_request(IKEY, "invalid", AKEY, USER);
test.equal(request_sig, Duo.ERR_SKEY, 'Sign request skey check failed');
test.done();
},
'sign request with an invalid akey': function(test) {
var request_sig = Duo.sign_request(IKEY, SKEY, "invalid", USER);
test.equal(request_sig, Duo.ERR_AKEY, 'Sign request akey check failed');
test.done();
},
};
'sign request with ikey/skey/akey and user': function (test) {
var request_sig = Duo.sign_request(IKEY, SKEY, AKEY, USER)
test.notEqual(request_sig, null, 'Invalid Request')
test.done()
},
'sign request without a user': function (test) {
var request_sig = Duo.sign_request(IKEY, SKEY, AKEY, '')
test.equal(request_sig, Duo.ERR_USER, 'Sign request user check failed')
test.done()
},
'sign request with invalid user': function (test) {
var request_sig = Duo.sign_request(IKEY, SKEY, AKEY, 'in|valid')
test.equal(request_sig, Duo.ERR_USER, 'Sign request user check failed')
test.done()
},
'sign request with an invalid ikey': function (test) {
var request_sig = Duo.sign_request('invalid', SKEY, AKEY, USER)
test.equal(request_sig, Duo.ERR_IKEY, 'Sign request ikey check failed')
test.done()
},
'sign request with an invalid skey': function (test) {
var request_sig = Duo.sign_request(IKEY, 'invalid', AKEY, USER)
test.equal(request_sig, Duo.ERR_SKEY, 'Sign request skey check failed')
test.done()
},
'sign request with an invalid akey': function (test) {
var request_sig = Duo.sign_request(IKEY, SKEY, 'invalid', USER)
test.equal(request_sig, Duo.ERR_AKEY, 'Sign request akey check failed')
test.done()
}
}
request_sig = Duo.sign_request(IKEY, SKEY, AKEY, USER);
var parts = request_sig.split(':');
var duo_sig = parts[0];
var valid_app_sig = parts[1];
var request_sig = Duo.sign_request(IKEY, SKEY, AKEY, USER)
var parts = request_sig.split(':')
var valid_app_sig = parts[1]
request_sig = Duo.sign_request(IKEY, SKEY, "invalidinvalidinvalidinvalidinvalidinvalidinvalidinvalid", USER);
parts = request_sig.split(':');
var invalid_app_sig = parts[1];
request_sig = Duo.sign_request(IKEY, SKEY, 'invalidinvalidinvalidinvalidinvalidinvalidinvalidinvalid', USER)
parts = request_sig.split(':')
var invalid_app_sig = parts[1]
module.exports['Verify Checks'] = {
'verify request': function(test) {
var user = Duo.verify_response(IKEY, SKEY, AKEY, INVALID_RESPONSE + ":" + valid_app_sig);
test.equal(user, null, 'Invalid response check failed');
test.done();
},
'expire check': function (test) {
var user = Duo.verify_response(IKEY, SKEY, AKEY, EXPIRED_RESPONSE + ":" + valid_app_sig);
test.equal(user, null, 'Expired response check failed');
test.done();
},
'invalid app sig': function (test) {
var user = Duo.verify_response(IKEY, SKEY, AKEY, FUTURE_RESPONSE + ":" + invalid_app_sig);
test.equal(user, null, 'Invalid app sig check failed');
test.done();
},
'verify response on valid signature': function (test) {
user = Duo.verify_response(IKEY, SKEY, AKEY, FUTURE_RESPONSE + ":" + valid_app_sig);
test.equal(user, USER, 'verify response failed on valid signature');
test.done();
},
'invalid response format': function (test) {
user = Duo.verify_response(IKEY, SKEY, AKEY, WRONG_PARAMS_RESPONSE + ":" + valid_app_sig);
test.equal(user, null, 'Invalid response format check failed');
test.done();
},
'invalid app sig format': function (test) {
user = Duo.verify_response(IKEY, SKEY, AKEY, FUTURE_RESPONSE + ":" + WRONG_PARAMS_APP);
test.equal(user, null, 'Invalid app sig format check failed');
test.done();
},
'wrong ikey': function (test) {
user = Duo.verify_response(WRONG_IKEY, SKEY, AKEY, FUTURE_RESPONSE + ":" + valid_app_sig);
test.equal(user, null, 'Wrong IKEY check failed');
test.done();
}
};
'verify request': function (test) {
var user = Duo.verify_response(IKEY, SKEY, AKEY, INVALID_RESPONSE + ':' + valid_app_sig)
test.equal(user, null, 'Invalid response check failed')
test.done()
},
'expire check': function (test) {
var user = Duo.verify_response(IKEY, SKEY, AKEY, EXPIRED_RESPONSE + ':' + valid_app_sig)
test.equal(user, null, 'Expired response check failed')
test.done()
},
'invalid app sig': function (test) {
var user = Duo.verify_response(IKEY, SKEY, AKEY, FUTURE_RESPONSE + ':' + invalid_app_sig)
test.equal(user, null, 'Invalid app sig check failed')
test.done()
},
'verify response on valid signature': function (test) {
var user = Duo.verify_response(IKEY, SKEY, AKEY, FUTURE_RESPONSE + ':' + valid_app_sig)
test.equal(user, USER, 'verify response failed on valid signature')
test.done()
},
'invalid response format': function (test) {
var user = Duo.verify_response(IKEY, SKEY, AKEY, WRONG_PARAMS_RESPONSE + ':' + valid_app_sig)
test.equal(user, null, 'Invalid response format check failed')
test.done()
},
'invalid app sig format': function (test) {
var user = Duo.verify_response(IKEY, SKEY, AKEY, FUTURE_RESPONSE + ':' + WRONG_PARAMS_APP)
test.equal(user, null, 'Invalid app sig format check failed')
test.done()
},
'wrong ikey': function (test) {
var user = Duo.verify_response(WRONG_IKEY, SKEY, AKEY, FUTURE_RESPONSE + ':' + valid_app_sig)
test.equal(user, null, 'Wrong IKEY check failed')
test.done()
}
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc