diff --git a/src/test/directoryserver-test.js b/src/test/directoryserver-test.js index e9b9f5c5a..7e3d6165e 100644 --- a/src/test/directoryserver-test.js +++ b/src/test/directoryserver-test.js @@ -13,8 +13,7 @@ const async = require('async'), expect = require('expect.js'), groups = require('../groups.js'), ldap = require('ldapjs'), - safe = require('safetydance'), - settings = require('../settings.js'); + safe = require('safetydance'); async function ldapBind(dn, password) { return new Promise((resolve, reject) => { diff --git a/src/test/users-test.js b/src/test/users-test.js index b81613468..406315fe5 100644 --- a/src/test/users-test.js +++ b/src/test/users-test.js @@ -9,6 +9,7 @@ const BoxError = require('../boxerror.js'), common = require('./common.js'), expect = require('expect.js'), safe = require('safetydance'), + speakeasy = require('speakeasy'), tokens = require('../tokens.js'), users = require('../users.js'), _ = require('underscore'); @@ -383,6 +384,60 @@ describe('User', function () { }); }); + describe('setup 2fa', function () { + before(createOwner); + + let twofa; + + it('create secret', async function () { + twofa = await users.setTwoFactorAuthenticationSecret(admin.id, auditSource); + expect(twofa.secret).to.be.a('string'); + expect(twofa.qrcode).to.be.a('string'); + }); + + it('can create secret again', async function () { + twofa = await users.setTwoFactorAuthenticationSecret(admin.id, auditSource); + expect(twofa.secret).to.be.a('string'); + expect(twofa.qrcode).to.be.a('string'); + }); + + it('enable 2fa', async function () { + const totpToken = speakeasy.totp({ secret: twofa.secret, encoding: 'base32' }); + await users.enableTwoFactorAuthentication(admin.id, totpToken, auditSource); + + const u = await users.get(admin.id); + expect(u.twoFactorAuthenticationEnabled).to.be(true); + }); + + it('cannot re-create secret', async function () { + const [error] = await safe(users.setTwoFactorAuthenticationSecret(admin.id, auditSource)); + expect(error.reason).to.be(BoxError.ALREADY_EXISTS); + }); + + it('cannot re-enable 2fa', async function () { + const totpToken = speakeasy.totp({ secret: twofa.secret, encoding: 'base32' }); + const [error] = await safe(users.enableTwoFactorAuthentication(admin.id, totpToken, auditSource)); + expect(error.reason).to.be(BoxError.ALREADY_EXISTS); + }); + + it('verify fails without 2fa', async function () { + const [error] = await safe(users.verifyWithUsername(admin.username, admin.password, users.AP_WEBADMIN, {})); + expect(error.reason).to.equal(BoxError.INVALID_CREDENTIALS); + expect(error.message).to.be('A totpToken must be provided'); + }); + + it('verify succeeds with relaxed 2fa', async function () { + const user = await users.verifyWithUsername(admin.username, admin.password, users.AP_WEBADMIN, { relaxedTotpCheck: true }); + expect(user.id).to.be(admin.id); + }); + + it('verify fails with relaxed 2fa but incorrect totp', async function () { + const [error] = await safe(users.verifyWithUsername(admin.username, admin.password, users.AP_WEBADMIN, { totpToken: 'schlecht', relaxedTotpCheck: true })); + expect(error.reason).to.equal(BoxError.INVALID_CREDENTIALS); + expect(error.message).to.be('Invalid totpToken'); + }); + }); + describe('active', function () { before(createOwner); @@ -398,7 +453,7 @@ describe('User', function () { }); }); - describe('retrieving', function () { + describe('get', function () { before(createOwner); it('fails due to non existing user', async function () {