diff --git a/src/routes/test/cloudron-test.js b/src/routes/test/cloudron-test.js index 1f054ed23..0bfa0c278 100644 --- a/src/routes/test/cloudron-test.js +++ b/src/routes/test/cloudron-test.js @@ -13,8 +13,9 @@ let async = require('async'), http = require('http'), nock = require('nock'), os = require('os'), - superagent = require('superagent'), server = require('../../server.js'), + speakeasy = require('speakeasy'), + superagent = require('superagent'), settings = require('../../settings.js'), tokendb = require('../../tokendb.js'); @@ -207,6 +208,218 @@ describe('Cloudron', function () { }); }); + describe('login', function () { + before(function (done) { + async.series([ + setup, + function (callback) { + superagent.post(SERVER_URL + '/api/v1/cloudron/activate') + .query({ setupToken: 'somesetuptoken' }) + .send({ username: USERNAME, password: PASSWORD, email: EMAIL }) + .end(function (error, result) { + expect(result).to.be.ok(); + + callback(); + }); + }, + ], done); + }); + + after(cleanup); + + it('fails without body', function (done) { + superagent.post(SERVER_URL + '/api/v1/cloudron/login') + .end(function (error, result) { + expect(result.statusCode).to.equal(400); + done(); + }); + }); + + it('fails without username', function (done) { + superagent.post(SERVER_URL + '/api/v1/cloudron/login') + .send({ password: PASSWORD }) + .end(function (error, result) { + expect(result.statusCode).to.equal(400); + done(); + }); + }); + + it('fails without password', function (done) { + superagent.post(SERVER_URL + '/api/v1/cloudron/login') + .send({ username: USERNAME }) + .end(function (error, result) { + expect(result.statusCode).to.equal(400); + done(); + }); + }); + + it('fails with empty username', function (done) { + superagent.post(SERVER_URL + '/api/v1/cloudron/login') + .send({ username: '', password: PASSWORD }) + .end(function (error, result) { + expect(result.statusCode).to.equal(400); + done(); + }); + }); + + it('fails with empty password', function (done) { + superagent.post(SERVER_URL + '/api/v1/cloudron/login') + .send({ username: USERNAME, password: '' }) + .end(function (error, result) { + expect(result.statusCode).to.equal(400); + done(); + }); + }); + + it('fails with unknown username', function (done) { + superagent.post(SERVER_URL + '/api/v1/cloudron/login') + .send({ username: USERNAME + USERNAME, password: PASSWORD }) + .end(function (error, result) { + expect(result.statusCode).to.equal(401); + done(); + }); + }); + + it('fails with unknown email', function (done) { + superagent.post(SERVER_URL + '/api/v1/cloudron/login') + .send({ username: USERNAME + EMAIL, password: PASSWORD }) + .end(function (error, result) { + expect(result.statusCode).to.equal(401); + done(); + }); + }); + + it('fails with wrong password', function (done) { + superagent.post(SERVER_URL + '/api/v1/cloudron/login') + .send({ username: USERNAME, password: PASSWORD.toUpperCase() }) + .end(function (error, result) { + expect(result.statusCode).to.equal(401); + done(); + }); + }); + + it('with username succeeds', function (done) { + superagent.post(SERVER_URL + '/api/v1/cloudron/login') + .send({ username: USERNAME, password: PASSWORD }) + .end(function (error, result) { + expect(result.statusCode).to.equal(200); + expect(new Date(result.body.expires).toString()).to.not.be('Invalid Date'); + expect(result.body.accessToken).to.be.a('string'); + done(); + }); + }); + + it('with uppercase username succeeds', function (done) { + superagent.post(SERVER_URL + '/api/v1/cloudron/login') + .send({ username: USERNAME.toUpperCase(), password: PASSWORD }) + .end(function (error, result) { + expect(result.statusCode).to.equal(200); + expect(new Date(result.body.expires).toString()).to.not.be('Invalid Date'); + expect(result.body.accessToken).to.be.a('string'); + done(); + }); + }); + + it('with email succeeds', function (done) { + superagent.post(SERVER_URL + '/api/v1/cloudron/login') + .send({ username: EMAIL, password: PASSWORD }) + .end(function (error, result) { + expect(result.statusCode).to.equal(200); + expect(new Date(result.body.expires).toString()).to.not.be('Invalid Date'); + expect(result.body.accessToken).to.be.a('string'); + done(); + }); + }); + + it('with uppercase email succeeds', function (done) { + superagent.post(SERVER_URL + '/api/v1/cloudron/login') + .send({ username: EMAIL.toUpperCase(), password: PASSWORD }) + .end(function (error, result) { + expect(result.statusCode).to.equal(200); + expect(new Date(result.body.expires).toString()).to.not.be('Invalid Date'); + expect(result.body.accessToken).to.be.a('string'); + done(); + }); + }); + }); + + describe('2fa login', function () { + var secret, accessToken; + + before(function (done) { + async.series([ + setup, + function (callback) { + superagent.post(`${SERVER_URL}/api/v1/cloudron/activate`).query({ setupToken: 'somesetuptoken' }).send({ username: USERNAME, password: PASSWORD, email: EMAIL }).end(function (error) { + callback(error); + }); + }, + function (callback) { + superagent.post(`${SERVER_URL}/api/v1/cloudron/login`).send({ username: USERNAME, password: PASSWORD }).end(function (error, result) { + accessToken = result.body.accessToken; + callback(error); + }); + }, + function (callback) { + superagent.post(`${SERVER_URL}/api/v1/profile/twofactorauthentication`).query({ access_token: accessToken }).end(function (error, result) { + secret = result.body.secret; + callback(error); + }); + }, + function (callback) { + var totpToken = speakeasy.totp({ + secret: secret, + encoding: 'base32' + }); + + superagent.post(`${SERVER_URL}/api/v1/profile/twofactorauthentication/enable`).query({ access_token: accessToken }).send({ totpToken: totpToken }).end(function (error) { + callback(error); + }); + } + ], done); + }); + + after(function (done) { + async.series([ + function (callback) { + superagent.post(`${SERVER_URL}/api/v1/profile/twofactorauthentication/disable`).query({ access_token: accessToken }).send({ password: PASSWORD }).end(function (error) { + callback(error); + }); + }, + cleanup + ], done); + }); + + it('fails due to missing token', function (done) { + superagent.post(`${SERVER_URL}/api/v1/cloudron/login`).send({ username: USERNAME, password: PASSWORD }).end(function (error, result) { + expect(result.statusCode).to.equal(401); + done(); + }); + }); + + it('fails due to wrong token', function (done) { + superagent.post(`${SERVER_URL}/api/v1/cloudron/login`).send({ username: USERNAME, password: PASSWORD }).send({ totpToken: 'wrongtoken' }).end(function (error, result) { + expect(result.statusCode).to.equal(401); + done(); + }); + }); + + it('succeeds', function (done) { + var totpToken = speakeasy.totp({ + secret: secret, + encoding: 'base32' + }); + + superagent.post(`${SERVER_URL}/api/v1/cloudron/login`).send({ username: USERNAME, password: PASSWORD }).send({ totpToken: totpToken }).end(function (error, result) { + expect(error).to.be(null); + expect(result.statusCode).to.equal(200); + expect(result.body).to.be.an(Object); + expect(result.body.accessToken).to.be.a('string'); + done(); + }); + }); + }); + describe('logs', function () { before(function (done) { async.series([ diff --git a/src/routes/test/developer-test.js b/src/routes/test/developer-test.js deleted file mode 100644 index e91498190..000000000 --- a/src/routes/test/developer-test.js +++ /dev/null @@ -1,248 +0,0 @@ -'use strict'; - -/* jslint node:true */ -/* global it:false */ -/* global describe:false */ -/* global before:false */ -/* global after:false */ - -var async = require('async'), - constants = require('../../constants.js'), - database = require('../../database.js'), - expect = require('expect.js'), - speakeasy = require('speakeasy'), - superagent = require('superagent'), - server = require('../../server.js'); - -var SERVER_URL = 'http://localhost:' + constants.PORT; - -var USERNAME = 'superadmin', PASSWORD = 'Foobar?1337', EMAIL ='silly@me.com'; - -function setup(done) { - async.series([ - server.start.bind(server), - database._clear - ], done); -} - -function cleanup(done) { - database._clear(function (error) { - expect(error).to.not.be.ok(); - - server.stop(done); - }); -} - -describe('Developer API', function () { - describe('login', function () { - before(function (done) { - async.series([ - setup, - function (callback) { - superagent.post(SERVER_URL + '/api/v1/cloudron/activate') - .query({ setupToken: 'somesetuptoken' }) - .send({ username: USERNAME, password: PASSWORD, email: EMAIL }) - .end(function (error, result) { - expect(result).to.be.ok(); - - callback(); - }); - }, - ], done); - }); - - after(cleanup); - - it('fails without body', function (done) { - superagent.post(SERVER_URL + '/api/v1/developer/login') - .end(function (error, result) { - expect(result.statusCode).to.equal(400); - done(); - }); - }); - - it('fails without username', function (done) { - superagent.post(SERVER_URL + '/api/v1/developer/login') - .send({ password: PASSWORD }) - .end(function (error, result) { - expect(result.statusCode).to.equal(400); - done(); - }); - }); - - it('fails without password', function (done) { - superagent.post(SERVER_URL + '/api/v1/developer/login') - .send({ username: USERNAME }) - .end(function (error, result) { - expect(result.statusCode).to.equal(400); - done(); - }); - }); - - it('fails with empty username', function (done) { - superagent.post(SERVER_URL + '/api/v1/developer/login') - .send({ username: '', password: PASSWORD }) - .end(function (error, result) { - expect(result.statusCode).to.equal(400); - done(); - }); - }); - - it('fails with empty password', function (done) { - superagent.post(SERVER_URL + '/api/v1/developer/login') - .send({ username: USERNAME, password: '' }) - .end(function (error, result) { - expect(result.statusCode).to.equal(400); - done(); - }); - }); - - it('fails with unknown username', function (done) { - superagent.post(SERVER_URL + '/api/v1/developer/login') - .send({ username: USERNAME + USERNAME, password: PASSWORD }) - .end(function (error, result) { - expect(result.statusCode).to.equal(401); - done(); - }); - }); - - it('fails with unknown email', function (done) { - superagent.post(SERVER_URL + '/api/v1/developer/login') - .send({ username: USERNAME + EMAIL, password: PASSWORD }) - .end(function (error, result) { - expect(result.statusCode).to.equal(401); - done(); - }); - }); - - it('fails with wrong password', function (done) { - superagent.post(SERVER_URL + '/api/v1/developer/login') - .send({ username: USERNAME, password: PASSWORD.toUpperCase() }) - .end(function (error, result) { - expect(result.statusCode).to.equal(401); - done(); - }); - }); - - it('with username succeeds', function (done) { - superagent.post(SERVER_URL + '/api/v1/developer/login') - .send({ username: USERNAME, password: PASSWORD }) - .end(function (error, result) { - expect(result.statusCode).to.equal(200); - expect(new Date(result.body.expires).toString()).to.not.be('Invalid Date'); - expect(result.body.accessToken).to.be.a('string'); - done(); - }); - }); - - it('with uppercase username succeeds', function (done) { - superagent.post(SERVER_URL + '/api/v1/developer/login') - .send({ username: USERNAME.toUpperCase(), password: PASSWORD }) - .end(function (error, result) { - expect(result.statusCode).to.equal(200); - expect(new Date(result.body.expires).toString()).to.not.be('Invalid Date'); - expect(result.body.accessToken).to.be.a('string'); - done(); - }); - }); - - it('with email succeeds', function (done) { - superagent.post(SERVER_URL + '/api/v1/developer/login') - .send({ username: EMAIL, password: PASSWORD }) - .end(function (error, result) { - expect(result.statusCode).to.equal(200); - expect(new Date(result.body.expires).toString()).to.not.be('Invalid Date'); - expect(result.body.accessToken).to.be.a('string'); - done(); - }); - }); - - it('with uppercase email succeeds', function (done) { - superagent.post(SERVER_URL + '/api/v1/developer/login') - .send({ username: EMAIL.toUpperCase(), password: PASSWORD }) - .end(function (error, result) { - expect(result.statusCode).to.equal(200); - expect(new Date(result.body.expires).toString()).to.not.be('Invalid Date'); - expect(result.body.accessToken).to.be.a('string'); - done(); - }); - }); - }); - - describe('2fa login', function () { - var secret, accessToken; - - before(function (done) { - async.series([ - setup, - function (callback) { - superagent.post(`${SERVER_URL}/api/v1/cloudron/activate`).query({ setupToken: 'somesetuptoken' }).send({ username: USERNAME, password: PASSWORD, email: EMAIL }).end(function (error) { - callback(error); - }); - }, - function (callback) { - superagent.post(`${SERVER_URL}/api/v1/developer/login`).send({ username: USERNAME, password: PASSWORD }).end(function (error, result) { - accessToken = result.body.accessToken; - callback(error); - }); - }, - function (callback) { - superagent.post(`${SERVER_URL}/api/v1/profile/twofactorauthentication`).query({ access_token: accessToken }).end(function (error, result) { - secret = result.body.secret; - callback(error); - }); - }, - function (callback) { - var totpToken = speakeasy.totp({ - secret: secret, - encoding: 'base32' - }); - - superagent.post(`${SERVER_URL}/api/v1/profile/twofactorauthentication/enable`).query({ access_token: accessToken }).send({ totpToken: totpToken }).end(function (error) { - callback(error); - }); - } - ], done); - }); - - after(function (done) { - async.series([ - function (callback) { - superagent.post(`${SERVER_URL}/api/v1/profile/twofactorauthentication/disable`).query({ access_token: accessToken }).send({ password: PASSWORD }).end(function (error) { - callback(error); - }); - }, - cleanup - ], done); - }); - - it('fails due to missing token', function (done) { - superagent.post(`${SERVER_URL}/api/v1/developer/login`).send({ username: USERNAME, password: PASSWORD }).end(function (error, result) { - expect(result.statusCode).to.equal(401); - done(); - }); - }); - - it('fails due to wrong token', function (done) { - superagent.post(`${SERVER_URL}/api/v1/developer/login`).send({ username: USERNAME, password: PASSWORD }).send({ totpToken: 'wrongtoken' }).end(function (error, result) { - expect(result.statusCode).to.equal(401); - done(); - }); - }); - - it('succeeds', function (done) { - var totpToken = speakeasy.totp({ - secret: secret, - encoding: 'base32' - }); - - superagent.post(`${SERVER_URL}/api/v1/developer/login`).send({ username: USERNAME, password: PASSWORD }).send({ totpToken: totpToken }).end(function (error, result) { - expect(error).to.be(null); - expect(result.statusCode).to.equal(200); - expect(result.body).to.be.an(Object); - expect(result.body.accessToken).to.be.a('string'); - done(); - }); - }); - }); -});