Move files from app to src and tests in root directory + adding more tests
parent
d7d743bdfa
commit
e13315eb92
|
@ -1,3 +1,7 @@
|
||||||
|
|
||||||
node_modules/
|
node_modules/
|
||||||
|
|
||||||
|
coverage/
|
||||||
|
|
||||||
|
*.swp
|
||||||
|
|
||||||
|
|
37
app/index.js
37
app/index.js
|
@ -1,37 +0,0 @@
|
||||||
|
|
||||||
var express = require('express');
|
|
||||||
var bodyParser = require('body-parser');
|
|
||||||
var cookieParser = require('cookie-parser');
|
|
||||||
var routes = require('./lib/routes');
|
|
||||||
var ldap = require('ldapjs');
|
|
||||||
var speakeasy = require('speakeasy');
|
|
||||||
|
|
||||||
var totpSecret = process.env.SECRET;
|
|
||||||
var LDAP_URL = process.env.LDAP_URL || 'ldap://127.0.0.1:389';
|
|
||||||
var USERS_DN = process.env.USERS_DN;
|
|
||||||
var PORT = process.env.PORT || 80
|
|
||||||
var JWT_SECRET = 'this is the secret';
|
|
||||||
var EXPIRATION_TIME = process.env.EXPIRATION_TIME || '1h';
|
|
||||||
|
|
||||||
var ldap_client = ldap.createClient({
|
|
||||||
url: LDAP_URL
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
var app = express();
|
|
||||||
app.use(cookieParser());
|
|
||||||
app.use(express.static(__dirname + '/public_html'));
|
|
||||||
app.use(bodyParser.urlencoded({ extended: false }));
|
|
||||||
|
|
||||||
app.set('view engine', 'ejs');
|
|
||||||
|
|
||||||
app.get ('/login', routes.login);
|
|
||||||
app.post ('/login', routes.login);
|
|
||||||
|
|
||||||
app.get ('/logout', routes.logout);
|
|
||||||
app.get ('/_auth', routes.auth);
|
|
||||||
|
|
||||||
app.listen(PORT, function(err) {
|
|
||||||
console.log('Listening on %d...', PORT);
|
|
||||||
});
|
|
||||||
|
|
|
@ -2,9 +2,10 @@
|
||||||
"name": "ldap-totp-nginx-auth",
|
"name": "ldap-totp-nginx-auth",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "app/index.js",
|
"main": "src/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "./node_modules/.bin/mocha",
|
||||||
|
"coverage": "./node_modules/.bin/istanbul cover _mocha -- -R spec"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -29,6 +30,7 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"mocha": "^3.2.0",
|
"mocha": "^3.2.0",
|
||||||
|
"request": "^2.79.0",
|
||||||
"should": "^11.1.1",
|
"should": "^11.1.1",
|
||||||
"sinon": "^1.17.6",
|
"sinon": "^1.17.6",
|
||||||
"sinon-promise": "^0.1.3"
|
"sinon-promise": "^0.1.3"
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
|
||||||
|
var server = require('./lib/server');
|
||||||
|
|
||||||
|
var ldap = require('ldapjs');
|
||||||
|
|
||||||
|
var config = {
|
||||||
|
port: process.env.PORT || 8080
|
||||||
|
totp_secret: process.env.TOTP_SECRET,
|
||||||
|
ldap_url: process.env.LDAP_URL || 'ldap://127.0.0.1:389',
|
||||||
|
ldap_users_dn: process.env.LDAP_USERS_DN,
|
||||||
|
jwt_secret: process.env.JWT_SECRET,
|
||||||
|
jwt_expiration_time: process.env.JWT_EXPIRATION_TIME || '1h'
|
||||||
|
}
|
||||||
|
|
||||||
|
var ldap_client = ldap.createClient({
|
||||||
|
url: config.ldap_url
|
||||||
|
});
|
||||||
|
|
||||||
|
server.run(config, ldap_client);
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
'authenticate': authenticate,
|
'authenticate': authenticate,
|
||||||
'verify_authentication': verify_authentication
|
'verify': verify_authentication
|
||||||
}
|
}
|
||||||
|
|
||||||
var objectPath = require('object-path');
|
var objectPath = require('object-path');
|
||||||
var Jwt = require('./jwt');
|
|
||||||
var ldap_checker = require('./ldap_checker');
|
var ldap_checker = require('./ldap_checker');
|
||||||
var totp_checker = require('./totp_checker');
|
var totp_checker = require('./totp_checker');
|
||||||
var replies = require('./replies');
|
var replies = require('./replies');
|
||||||
|
@ -13,38 +12,42 @@ var Q = require('q');
|
||||||
var utils = require('./utils');
|
var utils = require('./utils');
|
||||||
|
|
||||||
|
|
||||||
function authenticate(req, res, args) {
|
function authenticate(req, res) {
|
||||||
var defer = Q.defer();
|
var defer = Q.defer();
|
||||||
var username = req.body.username;
|
var username = req.body.username;
|
||||||
var password = req.body.password;
|
var password = req.body.password;
|
||||||
var token = req.body.token;
|
var token = req.body.token;
|
||||||
console.log('Start authentication');
|
console.log('Start authentication of user %s', username);
|
||||||
|
|
||||||
if(!username || !password || !token) {
|
if(!username || !password || !token) {
|
||||||
replies.authentication_failed(res);
|
replies.authentication_failed(res);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var totp_promise = totp_checker.validate(args.totp_interface, token, args.totp_secret);
|
var jwt_engine = req.app.get('jwt engine');
|
||||||
var credentials_promise = ldap_checker.validate(args.ldap_interface, username, password, args.users_dn);
|
var ldap_client = req.app.get('ldap client');
|
||||||
|
var totp_engine = req.app.get('totp engine');
|
||||||
|
var config = req.app.get('config');
|
||||||
|
|
||||||
|
var totp_promise = totp_checker.validate(totp_engine, token, config.totp_secret);
|
||||||
|
var credentials_promise = ldap_checker.validate(ldap_client, username, password, config.ldap_users_dn);
|
||||||
|
|
||||||
Q.all([totp_promise, credentials_promise])
|
Q.all([totp_promise, credentials_promise])
|
||||||
.then(function() {
|
.then(function() {
|
||||||
var token = args.jwt.sign({ user: username }, args.jwt_expiration_time);
|
var token = jwt_engine.sign({ user: username }, config.jwt_expiration_time);
|
||||||
res.cookie('access_token', token);
|
replies.authentication_succeeded(res, username, token);
|
||||||
res.redirect('/');
|
|
||||||
console.log('Authentication succeeded');
|
console.log('Authentication succeeded');
|
||||||
defer.resolve();
|
defer.resolve();
|
||||||
})
|
})
|
||||||
.fail(function(err1, err2) {
|
.fail(function(err1, err2) {
|
||||||
res.render('login');
|
|
||||||
console.log('Authentication failed', err1, err2);
|
console.log('Authentication failed', err1, err2);
|
||||||
|
replies.authentication_failed(res);
|
||||||
defer.reject();
|
defer.reject();
|
||||||
});
|
});
|
||||||
return defer.promise;
|
return defer.promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
function verify_authentication(req, res, args) {
|
function verify_authentication(req, res) {
|
||||||
console.log('Verify authentication');
|
console.log('Verify authentication');
|
||||||
|
|
||||||
if(!objectPath.has(req, 'cookies.access_token')) {
|
if(!objectPath.has(req, 'cookies.access_token')) {
|
||||||
|
@ -52,6 +55,6 @@ function verify_authentication(req, res, args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var jsonWebToken = req.cookies['access_token'];
|
var jsonWebToken = req.cookies['access_token'];
|
||||||
return args.jwt.verify(jsonWebToken);
|
return req.app.get('jwt engine').verify(jsonWebToken);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,19 +11,17 @@ function authentication_failed(res) {
|
||||||
res.send('Authentication failed');
|
res.send('Authentication failed');
|
||||||
}
|
}
|
||||||
|
|
||||||
function send_success(res, username, msg) {
|
function authentication_succeeded(res, username, token) {
|
||||||
|
console.log('Reply: authentication succeeded');
|
||||||
res.status(200);
|
res.status(200);
|
||||||
res.set({ 'X-Remote-User': username });
|
res.set({ 'X-Remote-User': username });
|
||||||
res.send(msg);
|
res.send(token);
|
||||||
}
|
|
||||||
|
|
||||||
function authentication_succeeded(res, username) {
|
|
||||||
console.log('Reply: authentication succeeded');
|
|
||||||
send_success(res, username, 'Authentication succeeded');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function already_authenticated(res, username) {
|
function already_authenticated(res, username) {
|
||||||
console.log('Reply: already authenticated');
|
console.log('Reply: already authenticated');
|
||||||
send_success(res, username, 'Authentication succeeded');
|
res.status(204);
|
||||||
|
res.set({ 'X-Remote-User': username });
|
||||||
|
res.send();
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,15 @@ var authentication = require('./authentication');
|
||||||
var replies = require('./replies');
|
var replies = require('./replies');
|
||||||
|
|
||||||
function serveAuth(req, res) {
|
function serveAuth(req, res) {
|
||||||
|
if(req.method == 'POST') {
|
||||||
|
serveAuthPost(req, res);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
serveAuthGet(req, res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function serveAuthGet(req, res) {
|
||||||
authentication.verify(req, res)
|
authentication.verify(req, res)
|
||||||
.then(function(user) {
|
.then(function(user) {
|
||||||
replies.already_authenticated(res, user);
|
replies.already_authenticated(res, user);
|
||||||
|
@ -19,14 +28,12 @@ function serveAuth(req, res) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function serveAuthPost(req, res) {
|
||||||
|
authentication.authenticate(req, res);
|
||||||
|
}
|
||||||
|
|
||||||
function serveLogin(req, res) {
|
function serveLogin(req, res) {
|
||||||
console.log('METHOD=%s', req.method);
|
res.render('login');
|
||||||
if(req.method == 'POST') {
|
|
||||||
authentication.authenticate(req, res);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
res.render('login');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function serveLogout(req, res) {
|
function serveLogout(req, res) {
|
|
@ -0,0 +1,37 @@
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
run: run
|
||||||
|
}
|
||||||
|
|
||||||
|
var routes = require('./routes');
|
||||||
|
var Jwt = require('./jwt');
|
||||||
|
|
||||||
|
var express = require('express');
|
||||||
|
var bodyParser = require('body-parser');
|
||||||
|
var cookieParser = require('cookie-parser');
|
||||||
|
var speakeasy = require('speakeasy');
|
||||||
|
|
||||||
|
function run(config, ldap_client) {
|
||||||
|
var app = express();
|
||||||
|
app.set('views', './src/views');
|
||||||
|
app.use(cookieParser());
|
||||||
|
app.use(express.static(__dirname + '/public_html'));
|
||||||
|
app.use(bodyParser.urlencoded({ extended: false }));
|
||||||
|
|
||||||
|
app.set('view engine', 'ejs');
|
||||||
|
|
||||||
|
app.set('jwt engine', new Jwt(config.jwt_secret));
|
||||||
|
app.set('ldap client', ldap_client);
|
||||||
|
app.set('totp engine', speakeasy);
|
||||||
|
app.set('config', config);
|
||||||
|
|
||||||
|
app.get ('/login', routes.login);
|
||||||
|
app.get ('/logout', routes.logout);
|
||||||
|
|
||||||
|
app.get ('/_auth', routes.auth);
|
||||||
|
app.post ('/_auth', routes.auth);
|
||||||
|
|
||||||
|
app.listen(config.port, function(err) {
|
||||||
|
console.log('Listening on %d...', config.port);
|
||||||
|
});
|
||||||
|
}
|
|
@ -5,9 +5,9 @@ module.exports = {
|
||||||
|
|
||||||
var Q = require('q');
|
var Q = require('q');
|
||||||
|
|
||||||
function validate(speakeasy, token, totp_secret) {
|
function validate(totp_engine, token, totp_secret) {
|
||||||
var defer = Q.defer();
|
var defer = Q.defer();
|
||||||
var real_token = speakeasy.totp({
|
var real_token = totp_engine.totp({
|
||||||
secret: totp_secret,
|
secret: totp_secret,
|
||||||
encoding: 'base32'
|
encoding: 'base32'
|
||||||
});
|
});
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
var authentication = require('../lib/authentication');
|
var authentication = require('../src/lib/authentication');
|
||||||
var create_res_mock = require('./res_mock');
|
var create_res_mock = require('./res_mock');
|
||||||
var sinon = require('sinon');
|
var sinon = require('sinon');
|
||||||
var sinonPromise = require('sinon-promise');
|
var sinonPromise = require('sinon-promise');
|
||||||
|
@ -17,6 +17,9 @@ function create_req_mock(token) {
|
||||||
},
|
},
|
||||||
cookies: {
|
cookies: {
|
||||||
'access_token': 'cookie_token'
|
'access_token': 'cookie_token'
|
||||||
|
},
|
||||||
|
app: {
|
||||||
|
get: sinon.stub()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,6 +58,14 @@ function create_mocks() {
|
||||||
totp_interface: totp_interface_mock
|
totp_interface: totp_interface_mock
|
||||||
}
|
}
|
||||||
|
|
||||||
|
req_mock.app.get.withArgs('ldap client').returns(args.ldap_interface);
|
||||||
|
req_mock.app.get.withArgs('jwt engine').returns(args.jwt);
|
||||||
|
req_mock.app.get.withArgs('totp engine').returns(args.totp_interface);
|
||||||
|
req_mock.app.get.withArgs('config').returns({
|
||||||
|
totp_secret: 'totp_secret',
|
||||||
|
ldap_users_dn: 'ou=users,dc=example,dc=com'
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
req: req_mock,
|
req: req_mock,
|
||||||
res: res_mock,
|
res: res_mock,
|
||||||
|
@ -70,11 +81,11 @@ describe('test jwt', function() {
|
||||||
var jwt_token = 'jwt_token';
|
var jwt_token = 'jwt_token';
|
||||||
var clock = sinon.useFakeTimers();
|
var clock = sinon.useFakeTimers();
|
||||||
var mocks = create_mocks();
|
var mocks = create_mocks();
|
||||||
authentication.authenticate(mocks.req, mocks.res, mocks.args)
|
authentication.authenticate(mocks.req, mocks.res)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
clock.restore();
|
clock.restore();
|
||||||
assert(mocks.res.cookie.calledWith('access_token', jwt_token));
|
assert(mocks.res.status.calledWith(200));
|
||||||
assert(mocks.res.redirect.calledWith('/'));
|
assert(mocks.res.send.calledWith(jwt_token));
|
||||||
done();
|
done();
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
@ -83,7 +94,7 @@ describe('test jwt', function() {
|
||||||
var clock = sinon.useFakeTimers();
|
var clock = sinon.useFakeTimers();
|
||||||
var mocks = create_mocks();
|
var mocks = create_mocks();
|
||||||
mocks.totp.returns('wrong token');
|
mocks.totp.returns('wrong token');
|
||||||
authentication.authenticate(mocks.req, mocks.res, mocks.args)
|
authentication.authenticate(mocks.req, mocks.res)
|
||||||
.fail(function(err) {
|
.fail(function(err) {
|
||||||
clock.restore();
|
clock.restore();
|
||||||
done();
|
done();
|
||||||
|
@ -96,8 +107,11 @@ describe('test jwt', function() {
|
||||||
it('should be already authenticated', function(done) {
|
it('should be already authenticated', function(done) {
|
||||||
var mocks = create_mocks();
|
var mocks = create_mocks();
|
||||||
var data = { user: 'username' };
|
var data = { user: 'username' };
|
||||||
mocks.jwt.verify = sinon.promise().resolves(data);
|
mocks.req.app.get.withArgs('jwt engine').returns({
|
||||||
authentication.verify_authentication(mocks.req, mocks.res, mocks.args)
|
verify: sinon.promise().resolves(data)
|
||||||
|
});
|
||||||
|
|
||||||
|
authentication.verify(mocks.req, mocks.res)
|
||||||
.then(function(actual_data) {
|
.then(function(actual_data) {
|
||||||
assert.equal(actual_data, data);
|
assert.equal(actual_data, data);
|
||||||
done();
|
done();
|
||||||
|
@ -107,8 +121,10 @@ describe('test jwt', function() {
|
||||||
it('should not be already authenticated', function(done) {
|
it('should not be already authenticated', function(done) {
|
||||||
var mocks = create_mocks();
|
var mocks = create_mocks();
|
||||||
var data = { user: 'username' };
|
var data = { user: 'username' };
|
||||||
mocks.jwt.verify = sinon.promise().rejects('Error with JWT token');
|
mocks.req.app.get.withArgs('jwt engine').returns({
|
||||||
return authentication.verify_authentication(mocks.req, mocks.res, mocks.args)
|
verify: sinon.promise().rejects('Error with JWT token')
|
||||||
|
});
|
||||||
|
return authentication.verify(mocks.req, mocks.res, mocks.args)
|
||||||
.fail(function() {
|
.fail(function() {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
var Jwt = require('../lib/jwt');
|
var Jwt = require('../src/lib/jwt');
|
||||||
var sinon = require('sinon');
|
var sinon = require('sinon');
|
||||||
var sinonPromise = require('sinon-promise');
|
var sinonPromise = require('sinon-promise');
|
||||||
sinonPromise(sinon);
|
sinonPromise(sinon);
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
var ldap_checker = require('../lib/ldap_checker');
|
var ldap_checker = require('../src/lib/ldap_checker');
|
||||||
var sinon = require('sinon');
|
var sinon = require('sinon');
|
||||||
var sinonPromise = require('sinon-promise');
|
var sinonPromise = require('sinon-promise');
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
var replies = require('../lib/replies');
|
var replies = require('../src/lib/replies');
|
||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
var sinon = require('sinon');
|
var sinon = require('sinon');
|
||||||
var sinonPromise = require('sinon-promise');
|
var sinonPromise = require('sinon-promise');
|
||||||
|
@ -36,7 +36,7 @@ describe('test jwt', function() {
|
||||||
|
|
||||||
replies.already_authenticated(res_mock, username);
|
replies.already_authenticated(res_mock, username);
|
||||||
|
|
||||||
assert(res_mock.status.calledWith(200));
|
assert(res_mock.status.calledWith(204));
|
||||||
assert(res_mock.set.calledWith({'X-Remote-User': username }));
|
assert(res_mock.set.calledWith({'X-Remote-User': username }));
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
|
||||||
|
var request = require('request');
|
||||||
|
var assert = require('assert');
|
||||||
|
var server = require('../src/lib/server');
|
||||||
|
var Jwt = require('../src/lib/jwt');
|
||||||
|
var speakeasy = require('speakeasy');
|
||||||
|
var sinon = require('sinon');
|
||||||
|
|
||||||
|
describe('test the server', function() {
|
||||||
|
var jwt = new Jwt('jwt_secret');
|
||||||
|
var ldap_client = {
|
||||||
|
bind: sinon.mock()
|
||||||
|
};
|
||||||
|
|
||||||
|
before(function() {
|
||||||
|
var config = {
|
||||||
|
port: 8080,
|
||||||
|
totp_secret: 'totp_secret',
|
||||||
|
ldap_url: 'ldap://127.0.0.1:389',
|
||||||
|
ldap_users_dn: 'ou=users,dc=example,dc=com',
|
||||||
|
jwt_secret: 'jwt_secret',
|
||||||
|
jwt_expiration_time: '1h'
|
||||||
|
};
|
||||||
|
|
||||||
|
// ldap_client.bind.yields(undefined);
|
||||||
|
ldap_client.bind.withArgs('cn=test_ok,ou=users,dc=example,dc=com',
|
||||||
|
'password').yields(undefined);
|
||||||
|
// ldap_client.bind.withArgs('cn=test_nok,ou=users,dc=example,dc=com',
|
||||||
|
// 'password').yields(undefined, 'error');
|
||||||
|
server.run(config, ldap_client);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should serve the login page', function(done) {
|
||||||
|
request.get('http://localhost:8080/login')
|
||||||
|
.on('response', function(response) {
|
||||||
|
assert.equal(response.statusCode, 200);
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return status code 401 when user is not authenticated', function(done) {
|
||||||
|
request.get('http://localhost:8080/_auth')
|
||||||
|
.on('response', function(response) {
|
||||||
|
assert.equal(response.statusCode, 401);
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return status code 204 when user is authenticated', function(done) {
|
||||||
|
var j = request.jar();
|
||||||
|
var r = request.defaults({jar: j});
|
||||||
|
var token = jwt.sign({ user: 'test' }, '1h');
|
||||||
|
var cookie = r.cookie('access_token=' + token);
|
||||||
|
j.setCookie(cookie, 'http://localhost:8080/_auth');
|
||||||
|
|
||||||
|
r.get('http://localhost:8080/_auth')
|
||||||
|
.on('response', function(response) {
|
||||||
|
assert.equal(response.statusCode, 204);
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return the JWT token when authentication is successful', function(done) {
|
||||||
|
var clock = sinon.useFakeTimers();
|
||||||
|
var real_token = speakeasy.totp({
|
||||||
|
secret: 'totp_secret',
|
||||||
|
encoding: 'base32'
|
||||||
|
});
|
||||||
|
var expectedJwt = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoidGVzdF9vayIsImlhdCI6MCwiZXhwIjozNjAwfQ.ihvaljGjO5h3iSO_h3PkNNSCYeePyB8Hr5lfVZZYyrQ';
|
||||||
|
|
||||||
|
request.post('http://localhost:8080/_auth', {
|
||||||
|
form: {
|
||||||
|
username: 'test_ok',
|
||||||
|
password: 'password',
|
||||||
|
token: real_token
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function (error, response, body) {
|
||||||
|
if (!error && response.statusCode == 200) {
|
||||||
|
assert.equal(body, expectedJwt);
|
||||||
|
clock.restore();
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
var totp_checker = require('../lib/totp_checker');
|
var totp_checker = require('../src/lib/totp_checker');
|
||||||
var sinon = require('sinon');
|
var sinon = require('sinon');
|
||||||
var sinonPromise = require('sinon-promise');
|
var sinonPromise = require('sinon-promise');
|
||||||
sinonPromise(sinon);
|
sinonPromise(sinon);
|
Loading…
Reference in New Issue