2015-07-20 00:09:47 -07:00
|
|
|
/* global it:false */
|
|
|
|
|
/* global describe:false */
|
|
|
|
|
/* global before:false */
|
|
|
|
|
/* global after:false */
|
|
|
|
|
|
|
|
|
|
'use strict';
|
|
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
const BoxError = require('../boxerror.js'),
|
|
|
|
|
common = require('./common.js'),
|
2015-07-20 00:09:47 -07:00
|
|
|
expect = require('expect.js'),
|
2016-07-12 10:07:55 -07:00
|
|
|
fs = require('fs'),
|
2020-03-15 11:41:39 -07:00
|
|
|
paths = require('../paths.js'),
|
2021-06-26 09:57:07 -07:00
|
|
|
safe = require('safetydance'),
|
2020-02-21 12:17:06 -08:00
|
|
|
users = require('../users.js'),
|
2020-02-13 20:45:00 -08:00
|
|
|
_ = require('underscore');
|
2015-07-20 00:09:47 -07:00
|
|
|
|
|
|
|
|
describe('User', function () {
|
2021-07-20 09:05:21 -07:00
|
|
|
const { domainSetup, cleanup, ADMIN, USER, AUDIT_SOURCE } = common;
|
2015-07-20 00:09:47 -07:00
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
async function cleanupUsers() {
|
|
|
|
|
for (const u of await users.getAll()) {
|
|
|
|
|
await users.del(u, AUDIT_SOURCE);
|
2021-07-15 09:50:11 -07:00
|
|
|
}
|
2021-07-19 12:43:30 -07:00
|
|
|
}
|
2021-07-15 09:50:11 -07:00
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
async function createOwner() {
|
|
|
|
|
await cleanupUsers();
|
2021-07-15 09:50:11 -07:00
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
const id = await users.add(ADMIN.email, ADMIN, AUDIT_SOURCE);
|
|
|
|
|
ADMIN.id = id;
|
|
|
|
|
}
|
2021-07-15 09:50:11 -07:00
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
before(domainSetup);
|
|
|
|
|
after(cleanup);
|
2021-07-15 09:50:11 -07:00
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
function checkUser(a, b) {
|
|
|
|
|
expect(a.creationTime).to.be.a(Date);
|
|
|
|
|
expect(a.resetTokenCreationTime).to.be.a(Date);
|
2021-07-15 09:50:11 -07:00
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
const fields = [ 'id', 'username', 'email', 'fallbackEmail', 'role', 'displayName', 'source', 'permissions', 'active' ];
|
2021-07-15 09:50:11 -07:00
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
expect(_.pick(a, fields)).to.be.eql(_.pick(b, fields));
|
|
|
|
|
}
|
2021-07-15 09:50:11 -07:00
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
describe('add', function () {
|
|
|
|
|
it('fails due to short password', async function () {
|
|
|
|
|
const user = Object.assign({}, ADMIN, { password: 'Fo$%23' });
|
|
|
|
|
const [error] = await safe(users.add(user.email, user, AUDIT_SOURCE));
|
|
|
|
|
expect(error.reason).to.equal(BoxError.BAD_FIELD);
|
2021-07-15 09:50:11 -07:00
|
|
|
});
|
|
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
it('fails due to reserved username', async function () {
|
|
|
|
|
const user = Object.assign({}, ADMIN, { username: 'admin' });
|
|
|
|
|
const [error] = await safe(users.add(user.email, user, AUDIT_SOURCE));
|
|
|
|
|
expect(error.reason).to.equal(BoxError.BAD_FIELD);
|
2021-07-15 09:50:11 -07:00
|
|
|
});
|
|
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
it('fails due to invalid username', async function () {
|
|
|
|
|
const user = Object.assign({}, ADMIN, { username: 'moo+daemon' });
|
|
|
|
|
const [error] = await safe(users.add(user.email, user, AUDIT_SOURCE));
|
|
|
|
|
expect(error.reason).to.equal(BoxError.BAD_FIELD);
|
2021-07-15 09:50:11 -07:00
|
|
|
});
|
|
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
it('fails due to empty username', async function () {
|
|
|
|
|
const user = Object.assign({}, ADMIN, { username: '' });
|
|
|
|
|
const [error] = await safe(users.add(user.email, user, AUDIT_SOURCE));
|
|
|
|
|
expect(error.reason).to.equal(BoxError.BAD_FIELD);
|
2021-07-15 09:50:11 -07:00
|
|
|
});
|
|
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
it('fails due to long username', async function () {
|
|
|
|
|
const user = Object.assign({}, ADMIN, { username: new Array(257).fill('Z').join('') });
|
|
|
|
|
const [error] = await safe(users.add(user.email, user, AUDIT_SOURCE));
|
|
|
|
|
expect(error.reason).to.equal(BoxError.BAD_FIELD);
|
2021-07-15 09:50:11 -07:00
|
|
|
});
|
|
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
it('fails due to reserved app pattern', async function () {
|
|
|
|
|
const user = Object.assign({}, ADMIN, { username: 'maybe.app' });
|
|
|
|
|
const [error] = await safe(users.add(user.email, user, AUDIT_SOURCE));
|
|
|
|
|
expect(error.reason).to.equal(BoxError.BAD_FIELD);
|
2021-07-15 09:50:11 -07:00
|
|
|
});
|
|
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
it('fails because password is empty', async function () {
|
|
|
|
|
const user = Object.assign({}, ADMIN, { password: '' });
|
|
|
|
|
const [error] = await safe(users.add(user.email, user, AUDIT_SOURCE));
|
|
|
|
|
expect(error.reason).to.equal(BoxError.BAD_FIELD);
|
2021-07-15 09:50:11 -07:00
|
|
|
});
|
|
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
it('can add user', async function () {
|
|
|
|
|
const id = await users.add(ADMIN.email, ADMIN, AUDIT_SOURCE);
|
|
|
|
|
ADMIN.id = id;
|
2021-07-15 09:50:11 -07:00
|
|
|
});
|
|
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
it('cannot add user with same email again', async function () {
|
|
|
|
|
const [error] = await safe(users.add(ADMIN.email, ADMIN, AUDIT_SOURCE));
|
|
|
|
|
expect(error.reason).to.be(BoxError.ALREADY_EXISTS);
|
|
|
|
|
expect(error.message).to.equal('email already exists');
|
2021-07-15 09:50:11 -07:00
|
|
|
});
|
|
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
it('cannot add user with same username again', async function () {
|
|
|
|
|
const [error] = await safe(users.add('somethingelse@not.taken', ADMIN, AUDIT_SOURCE));
|
|
|
|
|
expect(error.reason).to.be(BoxError.ALREADY_EXISTS);
|
|
|
|
|
expect(error.message).to.equal('username already exists');
|
2021-07-15 09:50:11 -07:00
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2021-07-20 09:05:21 -07:00
|
|
|
describe('getters', function () {
|
|
|
|
|
before(cleanupUsers);
|
2016-01-20 14:50:06 +01:00
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
it('cannot get by bad user id', async function () {
|
|
|
|
|
const result = await users.get('random');
|
|
|
|
|
expect(result).to.be(null);
|
2016-04-14 16:30:31 +02:00
|
|
|
});
|
|
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
it('fails because there is no owner', async function () {
|
|
|
|
|
const owner = await users.getOwner();
|
|
|
|
|
expect(owner).to.be(null);
|
2015-07-20 00:09:47 -07:00
|
|
|
});
|
|
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
it('getOwner succeeds', async function () {
|
|
|
|
|
const id = await users.add(ADMIN.email, ADMIN, AUDIT_SOURCE);
|
|
|
|
|
ADMIN.id = id;
|
|
|
|
|
const owner = await users.getOwner();
|
|
|
|
|
checkUser(owner, ADMIN);
|
2015-07-20 00:09:47 -07:00
|
|
|
});
|
|
|
|
|
|
2021-07-20 09:05:21 -07:00
|
|
|
it('can get by user id', async function () {
|
|
|
|
|
const result = await users.get(ADMIN.id);
|
|
|
|
|
checkUser(result, ADMIN);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('can get by username', async function () {
|
|
|
|
|
const result = await users.getByUsername(ADMIN.username);
|
|
|
|
|
checkUser(result, ADMIN);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('can get by email', async function () {
|
|
|
|
|
const result = await users.getByEmail(ADMIN.email);
|
|
|
|
|
checkUser(result, ADMIN);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('add another admin', async function () {
|
|
|
|
|
const result = await users.add(USER.email, USER, AUDIT_SOURCE);
|
|
|
|
|
USER.id = result;
|
|
|
|
|
await users.update(USER, { role: users.ROLE_ADMIN }, AUDIT_SOURCE);
|
|
|
|
|
USER.role = users.ROLE_ADMIN;
|
|
|
|
|
});
|
|
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
it('getSuperadmins succeeds', async function () {
|
|
|
|
|
const results = await users.getSuperadmins();
|
|
|
|
|
expect(results.length).to.be(1);
|
|
|
|
|
checkUser(results[0], ADMIN);
|
2015-07-20 00:09:47 -07:00
|
|
|
});
|
2016-01-13 12:28:38 -08:00
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
it('getAdmins succeeds', async function () {
|
|
|
|
|
const results = await users.getAdmins();
|
2021-07-20 09:05:21 -07:00
|
|
|
expect(results.length).to.be(2);
|
|
|
|
|
checkUser(results[0], ADMIN); // owner is always the first
|
|
|
|
|
checkUser(results[1], USER);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('getByResetToken fails for empty resetToken', async function () {
|
|
|
|
|
const [error] = await safe(users.getByResetToken(''));
|
|
|
|
|
expect(error.reason).to.be(BoxError.BAD_FIELD);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('getByResetToken fails for bad resetToken', async function () {
|
|
|
|
|
const result = await users.getByResetToken(new Array(64).fill('Z').join(''));
|
|
|
|
|
expect(result).to.be(null);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('can get by resetToken', async function () {
|
|
|
|
|
USER.resetToken = new Array(64).fill('X').join('');
|
|
|
|
|
await users.update(USER, { resetToken: USER.resetToken }, AUDIT_SOURCE);
|
|
|
|
|
const user = await users.getByResetToken(USER.resetToken);
|
|
|
|
|
checkUser(user, USER);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('can getAll', async function () {
|
|
|
|
|
const results = await users.getAll();
|
|
|
|
|
expect(results.length).to.be(2);
|
|
|
|
|
checkUser(results[0], ADMIN);
|
|
|
|
|
checkUser(results[1], USER);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('can getAllPaged', async function () {
|
|
|
|
|
let results = await users.getAllPaged(null, 1, 1);
|
2021-07-19 12:43:30 -07:00
|
|
|
expect(results.length).to.be(1);
|
|
|
|
|
checkUser(results[0], ADMIN);
|
2021-07-20 09:05:21 -07:00
|
|
|
|
|
|
|
|
results = await users.getAllPaged(null, 2, 1);
|
|
|
|
|
expect(results.length).to.be(1);
|
|
|
|
|
checkUser(results[0], USER);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('can getAllPaged (search)', async function () {
|
|
|
|
|
let results = await users.getAllPaged(ADMIN.email.slice(0, 8), 1, 1);
|
|
|
|
|
expect(results.length).to.be(1);
|
|
|
|
|
checkUser(results[0], ADMIN);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
describe('update', function () {
|
|
|
|
|
before(createOwner);
|
|
|
|
|
|
|
|
|
|
it('fails due to unknown userid', async function () {
|
|
|
|
|
const user = Object.assign({}, ADMIN, { id: 'random' });
|
|
|
|
|
const [error] = await safe(users.update(user, { displayName: 'full name' }, AUDIT_SOURCE));
|
|
|
|
|
expect(error.reason).to.equal(BoxError.NOT_FOUND);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('fails due to invalid email', async function () {
|
|
|
|
|
const [error] = await safe(users.update(ADMIN, { email: 'brokenemailaddress' }, AUDIT_SOURCE));
|
|
|
|
|
expect(error.reason).to.equal(BoxError.BAD_FIELD);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
xit('cannot update the user with already existing email', async function () {
|
|
|
|
|
const result = await users.add(USER.email, USER, AUDIT_SOURCE);
|
|
|
|
|
USER.id = result;
|
|
|
|
|
|
|
|
|
|
const [error] = await safe(users.update(ADMIN, { email: USER.email }), AUDIT_SOURCE);
|
|
|
|
|
expect(error.reason).to.be(BoxError.ALREADY_EXISTS);
|
|
|
|
|
expect(error.message).to.equal('email already exists');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
xit('can update the user with already existing username', async function () {
|
|
|
|
|
const [error] = await safe(users.update(ADMIN, { username: USER.username }), AUDIT_SOURCE);
|
|
|
|
|
expect(error.reason).to.be(BoxError.ALREADY_EXISTS);
|
|
|
|
|
expect(error.message).to.equal('username already exists');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
xit('can update the user', async function () {
|
|
|
|
|
await users.update(ADMIN, { email: 'some@thing.com', displayName: 'Heiter' }, AUDIT_SOURCE);
|
|
|
|
|
const user = await users.get(ADMIN.id);
|
|
|
|
|
expect(user.email).to.equal('some@thing.com');
|
|
|
|
|
expect(user.displayName).to.equal('Heiter');
|
2016-01-13 12:28:38 -08:00
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2015-07-20 00:09:47 -07:00
|
|
|
describe('verify', function () {
|
2016-02-08 15:16:59 -08:00
|
|
|
before(createOwner);
|
2016-04-05 16:27:04 +02:00
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
it('fails due to non existing user', async function () {
|
|
|
|
|
const [error] = await safe(users.verify('somerandomid', 'somepassword', users.AP_WEBADMIN));
|
|
|
|
|
expect(error.reason).to.equal(BoxError.NOT_FOUND);
|
2016-04-05 16:27:04 +02:00
|
|
|
});
|
|
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
it('fails due to empty password', async function () {
|
|
|
|
|
const [error] = await safe(users.verify(ADMIN.id, '', users.AP_WEBADMIN));
|
|
|
|
|
expect(error.reason).to.equal(BoxError.INVALID_CREDENTIALS);
|
2016-04-05 16:27:04 +02:00
|
|
|
});
|
|
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
it('fails due to wrong password', async function () {
|
|
|
|
|
const [error] = await safe(users.verify(ADMIN.id, ADMIN.password+'x', users.AP_WEBADMIN));
|
|
|
|
|
expect(error.reason).to.equal(BoxError.INVALID_CREDENTIALS);
|
2016-04-05 16:27:04 +02:00
|
|
|
});
|
|
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
it('succeeds', async function () {
|
|
|
|
|
const result = await users.verify(ADMIN.id, ADMIN.password, users.AP_WEBADMIN);
|
|
|
|
|
expect(result).to.be.ok();
|
|
|
|
|
expect(result.appPassword).to.not.be.ok();
|
|
|
|
|
expect(result.ghost).to.not.be.ok();
|
2016-04-05 16:27:04 +02:00
|
|
|
});
|
2016-07-12 10:07:55 -07:00
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
it('fails for ghost if not enabled', async function () {
|
|
|
|
|
const [error] = await safe(users.verify(ADMIN.id, 'foobar', users.AP_WEBADMIN));
|
|
|
|
|
expect(error.reason).to.equal(BoxError.INVALID_CREDENTIALS);
|
2016-07-12 10:07:55 -07:00
|
|
|
});
|
|
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
it('fails for ghost with wrong password', async function () {
|
|
|
|
|
let ghost = { };
|
|
|
|
|
ghost[ADMIN.username] = 'testpassword';
|
|
|
|
|
await fs.promises.writeFile(paths.GHOST_USER_FILE, JSON.stringify(ghost), 'utf8');
|
2016-07-12 10:07:55 -07:00
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
const [error] = await safe(users.verify(ADMIN.id, 'foobar', users.AP_WEBADMIN));
|
|
|
|
|
await fs.promises.unlink(paths.GHOST_USER_FILE);
|
2016-07-12 10:07:55 -07:00
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
expect(error.reason).to.equal(BoxError.INVALID_CREDENTIALS);
|
2016-07-12 10:07:55 -07:00
|
|
|
});
|
|
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
it('succeeds for ghost', async function () {
|
|
|
|
|
let ghost = { };
|
|
|
|
|
ghost[ADMIN.username] = 'testpassword';
|
|
|
|
|
await fs.promises.writeFile(paths.GHOST_USER_FILE, JSON.stringify(ghost), 'utf8');
|
2016-07-12 10:07:55 -07:00
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
const result = await users.verify(ADMIN.id, 'testpassword', users.AP_WEBADMIN);
|
|
|
|
|
if (fs.existsSync(paths.GHOST_USER_FILE)) throw new Error('Ghost file exists after verification');
|
2016-07-12 10:07:55 -07:00
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
expect(result.id).to.equal(ADMIN.id);
|
|
|
|
|
expect(result.ghost).to.be(true);
|
2016-07-12 10:07:55 -07:00
|
|
|
});
|
|
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
it('succeeds for normal user password when ghost file exists', async function () {
|
|
|
|
|
let ghost = { };
|
|
|
|
|
ghost[ADMIN.username] = 'testpassword';
|
2020-03-15 11:41:39 -07:00
|
|
|
fs.writeFileSync(paths.GHOST_USER_FILE, JSON.stringify(ghost), 'utf8');
|
2016-07-12 10:07:55 -07:00
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
const result = await users.verify(ADMIN.id, ADMIN.password, users.AP_WEBADMIN);
|
|
|
|
|
if (!fs.existsSync(paths.GHOST_USER_FILE)) throw new Error('Ghost file went way without verification');
|
2016-07-12 10:07:55 -07:00
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
expect(result.id).to.equal(ADMIN.id);
|
|
|
|
|
expect(result.ghost).to.not.be.ok();
|
2016-07-12 10:07:55 -07:00
|
|
|
});
|
2016-04-05 16:27:04 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
describe('verifyWithUsername', function () {
|
|
|
|
|
before(createOwner);
|
2015-07-20 00:09:47 -07:00
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
it('fails due to non existing username', async function () {
|
|
|
|
|
const [error] = await safe(users.verifyWithUsername('someusername', 'somepass', users.AP_WEBADMIN));
|
|
|
|
|
expect(error.reason).to.equal(BoxError.NOT_FOUND);
|
2015-07-20 00:09:47 -07:00
|
|
|
});
|
|
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
it('fails due to empty password', async function () {
|
|
|
|
|
const [error] = await safe(users.verifyWithUsername(ADMIN.username, '', users.AP_WEBADMIN));
|
|
|
|
|
expect(error.reason).to.equal(BoxError.INVALID_CREDENTIALS);
|
2015-07-20 00:09:47 -07:00
|
|
|
});
|
|
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
it('fails due to wrong password', async function () {
|
|
|
|
|
const [error] = await safe(users.verifyWithUsername(ADMIN.username, 'somepass', users.AP_WEBADMIN));
|
|
|
|
|
expect(error.reason).to.equal(BoxError.INVALID_CREDENTIALS);
|
2015-07-20 00:09:47 -07:00
|
|
|
});
|
|
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
it('succeeds', async function () {
|
|
|
|
|
const result = await users.verifyWithUsername(ADMIN.username, ADMIN.password, users.AP_WEBADMIN);
|
|
|
|
|
expect(result.id).to.equal(ADMIN.id);
|
2015-07-20 00:09:47 -07:00
|
|
|
});
|
2016-04-13 12:15:49 +02:00
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
it('succeeds for different username case', async function () {
|
|
|
|
|
const result = await users.verifyWithUsername(ADMIN.username.toUpperCase(), ADMIN.password, users.AP_WEBADMIN);
|
|
|
|
|
expect(result.id).to.equal(ADMIN.id);
|
2016-04-13 12:15:49 +02:00
|
|
|
});
|
2016-07-12 10:07:55 -07:00
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
it('fails for ghost with wrong password', async function () {
|
|
|
|
|
let ghost = { };
|
|
|
|
|
ghost[ADMIN.username] = 'testpassword';
|
2016-07-12 10:07:55 -07:00
|
|
|
|
2020-03-15 11:41:39 -07:00
|
|
|
fs.writeFileSync(paths.GHOST_USER_FILE, JSON.stringify(ghost), 'utf8');
|
2016-07-12 10:07:55 -07:00
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
const [error] = await safe(users.verifyWithUsername(ADMIN.username, 'foobar', users.AP_WEBADMIN));
|
|
|
|
|
if (!fs.existsSync(paths.GHOST_USER_FILE)) throw new Error('Ghost file went way without verification');
|
|
|
|
|
fs.unlinkSync(paths.GHOST_USER_FILE);
|
2016-07-12 10:07:55 -07:00
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
expect(error.reason).to.equal(BoxError.INVALID_CREDENTIALS);
|
2016-07-12 10:07:55 -07:00
|
|
|
});
|
|
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
it('succeeds for ghost', async function () {
|
|
|
|
|
let ghost = { };
|
|
|
|
|
ghost[ADMIN.username] = 'testpassword';
|
2016-07-12 10:07:55 -07:00
|
|
|
|
2020-03-15 11:41:39 -07:00
|
|
|
fs.writeFileSync(paths.GHOST_USER_FILE, JSON.stringify(ghost), 'utf8');
|
2016-07-12 10:07:55 -07:00
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
const result = await users.verifyWithUsername(ADMIN.username, 'testpassword', users.AP_WEBADMIN);
|
|
|
|
|
if (fs.existsSync(paths.GHOST_USER_FILE)) throw new Error('Ghost file still around!');
|
|
|
|
|
expect(result.id).to.equal(ADMIN.id);
|
|
|
|
|
expect(result.ghost).to.be(true);
|
2016-07-12 10:07:55 -07:00
|
|
|
});
|
2015-07-20 00:09:47 -07:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
describe('verifyWithEmail', function () {
|
2016-02-08 15:16:59 -08:00
|
|
|
before(createOwner);
|
2015-07-20 00:09:47 -07:00
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
it('fails due to non existing user', async function () {
|
|
|
|
|
const [error] = await safe(users.verifyWithEmail('bad@email.com', ADMIN.password, users.AP_WEBADMIN));
|
|
|
|
|
expect(error.reason).to.equal(BoxError.NOT_FOUND);
|
2015-07-20 00:09:47 -07:00
|
|
|
});
|
|
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
it('fails due to empty password', async function () {
|
|
|
|
|
const [error] = await safe(users.verifyWithEmail(ADMIN.email, '', users.AP_WEBADMIN));
|
|
|
|
|
expect(error.reason).to.equal(BoxError.INVALID_CREDENTIALS);
|
2015-07-20 00:09:47 -07:00
|
|
|
});
|
|
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
it('fails due to wrong password', async function () {
|
|
|
|
|
const [error] = await safe(users.verifyWithEmail(ADMIN.email, 'badpassword', users.AP_WEBADMIN));
|
|
|
|
|
expect(error.reason).to.equal(BoxError.INVALID_CREDENTIALS);
|
2015-07-20 00:09:47 -07:00
|
|
|
});
|
|
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
it('succeeds', async function () {
|
|
|
|
|
const result = await users.verifyWithEmail(ADMIN.email, ADMIN.password, users.AP_WEBADMIN);
|
|
|
|
|
expect(result.id).to.be(ADMIN.id);
|
2015-07-20 00:09:47 -07:00
|
|
|
});
|
2016-04-13 12:15:49 +02:00
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
it('succeeds for different email case', async function () {
|
|
|
|
|
const result = await users.verifyWithEmail(ADMIN.email.toUpperCase(), ADMIN.password, users.AP_WEBADMIN);
|
|
|
|
|
expect(result.id).to.be(ADMIN.id);
|
2016-04-13 12:15:49 +02:00
|
|
|
});
|
2016-07-12 10:07:55 -07:00
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
it('fails for ghost with wrong password', async function () {
|
|
|
|
|
let ghost = { };
|
|
|
|
|
ghost[ADMIN.username] = 'testpassword';
|
2016-07-12 10:07:55 -07:00
|
|
|
|
2020-03-15 11:41:39 -07:00
|
|
|
fs.writeFileSync(paths.GHOST_USER_FILE, JSON.stringify(ghost), 'utf8');
|
2016-07-12 10:07:55 -07:00
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
const [error] = await safe(users.verifyWithEmail(ADMIN.email, 'foobar', users.AP_WEBADMIN));
|
|
|
|
|
if (!fs.existsSync(paths.GHOST_USER_FILE)) throw new Error('Ghost file not found after failed login!');
|
|
|
|
|
fs.unlinkSync(paths.GHOST_USER_FILE);
|
2016-07-12 10:07:55 -07:00
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
expect(error.reason).to.equal(BoxError.INVALID_CREDENTIALS);
|
2016-07-12 10:07:55 -07:00
|
|
|
});
|
|
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
it('succeeds for ghost', async function () {
|
|
|
|
|
let ghost = { };
|
|
|
|
|
ghost[ADMIN.username] = 'testpassword';
|
2016-07-12 10:07:55 -07:00
|
|
|
|
2020-03-15 11:41:39 -07:00
|
|
|
fs.writeFileSync(paths.GHOST_USER_FILE, JSON.stringify(ghost), 'utf8');
|
2016-07-12 10:07:55 -07:00
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
const result = await users.verifyWithEmail(ADMIN.email, 'testpassword', users.AP_WEBADMIN);
|
|
|
|
|
if (fs.existsSync(paths.GHOST_USER_FILE)) throw new Error('Ghost file still around!');
|
2016-07-12 10:07:55 -07:00
|
|
|
|
2021-07-19 12:43:30 -07:00
|
|
|
expect(result.id).to.equal(ADMIN.id);
|
|
|
|
|
expect(result.ghost).to.equal(true);
|
2016-07-12 10:07:55 -07:00
|
|
|
});
|
2015-07-20 00:09:47 -07:00
|
|
|
});
|
|
|
|
|
|
2021-07-20 09:05:21 -07:00
|
|
|
describe('active', function () {
|
|
|
|
|
before(createOwner);
|
|
|
|
|
|
|
|
|
|
it('verify fails for inactive user', async function () {
|
|
|
|
|
await users.update(ADMIN, { active: false }, AUDIT_SOURCE);
|
|
|
|
|
const [error] = await safe(users.verify(ADMIN.id, ADMIN.password, users.AP_WEBADMIN));
|
|
|
|
|
expect(error.reason).to.equal(BoxError.NOT_FOUND);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('verify succeeds for inactive user', async function () {
|
|
|
|
|
await users.update(ADMIN, { active: true }, AUDIT_SOURCE);
|
|
|
|
|
await users.verify(ADMIN.id, ADMIN.password, users.AP_WEBADMIN);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
describe('retrieving', function () {
|
|
|
|
|
before(createOwner);
|
|
|
|
|
|
|
|
|
|
it('fails due to non existing user', async function () {
|
|
|
|
|
const result = await users.get('randomid');
|
|
|
|
|
expect(result).to.be(null);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('succeeds', async function () {
|
|
|
|
|
const result = await users.get(ADMIN.id);
|
|
|
|
|
expect(result.id).to.equal(ADMIN.id);
|
|
|
|
|
expect(result.email).to.equal(ADMIN.email.toLowerCase());
|
|
|
|
|
expect(result.fallbackEmail).to.equal(ADMIN.email.toLowerCase());
|
|
|
|
|
expect(result.username).to.equal(ADMIN.username.toLowerCase());
|
|
|
|
|
expect(result.displayName).to.equal(ADMIN.displayName);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
describe('activated', function () {
|
|
|
|
|
before(cleanupUsers);
|
|
|
|
|
|
|
|
|
|
it('succeeds with no users', async function () {
|
|
|
|
|
const activated = await users.isActivated();
|
|
|
|
|
expect(activated).to.be(false);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('create admin', createOwner);
|
|
|
|
|
|
|
|
|
|
it('succeeds with users', async function () {
|
|
|
|
|
const activated = await users.isActivated();
|
|
|
|
|
expect(activated).to.be(true);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
describe('set password', function () {
|
|
|
|
|
before(createOwner);
|
|
|
|
|
|
|
|
|
|
it('fails due to unknown user', async function () {
|
|
|
|
|
const user = Object.assign({}, ADMIN, { id: 'doesnotexist' });
|
|
|
|
|
const [error] = await safe(users.setPassword(user, 'newpassword', AUDIT_SOURCE));
|
|
|
|
|
expect(error.reason).to.be(BoxError.NOT_FOUND);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('fails due to empty password', async function () {
|
|
|
|
|
const [error] = await safe(users.setPassword(ADMIN, '', AUDIT_SOURCE));
|
|
|
|
|
expect(error.reason).to.be(BoxError.BAD_FIELD);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('fails due to invalid password', async function () {
|
|
|
|
|
const [error] = await safe(users.setPassword(ADMIN, 'foobar', AUDIT_SOURCE));
|
|
|
|
|
expect(error.reason).to.be(BoxError.BAD_FIELD);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('succeeds', async function () {
|
|
|
|
|
await users.setPassword(ADMIN, 'ThisIsNew1Password', AUDIT_SOURCE);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('actually changed the password (unable to login with old pasword)', async function () {
|
|
|
|
|
const [error] = await safe(users.verify(ADMIN.id, ADMIN.password, users.AP_WEBADMIN));
|
|
|
|
|
expect(error.reason).to.equal(BoxError.INVALID_CREDENTIALS);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
xit('actually changed the password (login with new password)', async function () {
|
|
|
|
|
await users.verify(ADMIN.id, 'ThisIsNew1Password', users.AP_WEBADMIN);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
describe('sendPasswordResetByIdentifier', function () {
|
|
|
|
|
before(cleanupUsers);
|
|
|
|
|
|
|
|
|
|
it('fails due to unkown email', async function () {
|
|
|
|
|
const [error] = await safe(users.sendPasswordResetByIdentifier('unknown@mail.com', AUDIT_SOURCE));
|
|
|
|
|
expect(error.reason).to.eql(BoxError.NOT_FOUND);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('fails due to unkown username', async function () {
|
|
|
|
|
const [error] = await safe(users.sendPasswordResetByIdentifier('unknown', AUDIT_SOURCE));
|
|
|
|
|
expect(error.reason).to.eql(BoxError.NOT_FOUND);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('succeeds with email', async function () {
|
|
|
|
|
await users.sendPasswordResetByIdentifier(ADMIN.email);
|
|
|
|
|
// checkMails(1, done);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('succeeds with username', async function () {
|
|
|
|
|
await users.sendPasswordResetByIdentifier(ADMIN.username);
|
|
|
|
|
// checkMails(1, done);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
describe('invite', function () {
|
|
|
|
|
before(createOwner);
|
|
|
|
|
|
|
|
|
|
it('fails as expected', async function () {
|
|
|
|
|
const [error] = await safe(users.sendInvite(ADMIN, { }));
|
|
|
|
|
expect(error.reason).to.be(BoxError.CONFLICT);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('can create token', function (done) {
|
|
|
|
|
users.createInvite(userObject, function (error, resetToken) {
|
|
|
|
|
expect(error).to.be(null);
|
|
|
|
|
expect(resetToken).to.be.ok();
|
|
|
|
|
done();
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('send invite', function (done) {
|
|
|
|
|
users.sendInvite(userObject, { }, function (error) {
|
|
|
|
|
expect(error).to.be(null);
|
|
|
|
|
checkMails(1, done);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
describe('remove', function () {
|
|
|
|
|
before(createOwner);
|
|
|
|
|
|
|
|
|
|
it('fails for unknown user', async function () {
|
|
|
|
|
const user = Object.assign({}, ADMIN, { id: 'doesnotexist' });
|
|
|
|
|
const [error] = await safe(users.del(user, AUDIT_SOURCE));
|
|
|
|
|
expect(error.reason).to.be(BoxError.NOT_FOUND);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('can remove valid user', async function () {
|
|
|
|
|
await users.del(ADMIN, AUDIT_SOURCE);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('can re-create user after user was removed', createOwner);
|
|
|
|
|
});
|
2015-07-20 00:09:47 -07:00
|
|
|
});
|