diff --git a/src/routes/branding.js b/src/routes/branding.js index 01ce10334..d2b6de582 100644 --- a/src/routes/branding.js +++ b/src/routes/branding.js @@ -2,7 +2,9 @@ exports = module.exports = { get, - set + set, + + getCloudronAvatar }; var assert = require('assert'), diff --git a/src/routes/settings.js b/src/routes/settings.js index bc56e63e9..d7681ed97 100644 --- a/src/routes/settings.js +++ b/src/routes/settings.js @@ -2,9 +2,7 @@ exports = module.exports = { set: set, - get: get, - - getCloudronAvatar: getCloudronAvatar + get: get }; var assert = require('assert'), @@ -14,7 +12,6 @@ var assert = require('assert'), externalLdap = require('../externalldap.js'), HttpError = require('connect-lastmile').HttpError, HttpSuccess = require('connect-lastmile').HttpSuccess, - safe = require('safetydance'), settings = require('../settings.js'); function getAppAutoupdatePattern(req, res, next) { @@ -57,26 +54,6 @@ function setBoxAutoupdatePattern(req, res, next) { }); } -function setCloudronName(req, res, next) { - assert.strictEqual(typeof req.body, 'object'); - - if (typeof req.body.name !== 'string') return next(new HttpError(400, 'name is required')); - - settings.setCloudronName(req.body.name, function (error) { - if (error) return next(BoxError.toHttpError(error)); - - next(new HttpSuccess(202, {})); - }); -} - -function getCloudronName(req, res, next) { - settings.getCloudronName(function (error, name) { - if (error) return next(BoxError.toHttpError(error)); - - next(new HttpSuccess(200, { name: name })); - }); -} - function getTimeZone(req, res, next) { settings.getTimeZone(function (error, tz) { if (error) return next(BoxError.toHttpError(error)); @@ -97,26 +74,6 @@ function setTimeZone(req, res, next) { }); } -function getFooter(req, res, next) { - settings.getFooter(function (error, footer) { - if (error) return next(BoxError.toHttpError(error)); - - next(new HttpSuccess(200, { footer })); - }); -} - -function setFooter(req, res, next) { - assert.strictEqual(typeof req.body, 'object'); - - if (typeof req.body.footer !== 'string') return next(new HttpError(400, 'footer is required')); - - settings.setFooter(req.body.footer, function (error) { - if (error) return next(BoxError.toHttpError(error)); - - next(new HttpSuccess(200, {})); - }); -} - function getSupportConfig(req, res, next) { settings.getSupportConfig(function (error, supportConfig) { if (error) return next(BoxError.toHttpError(error)); @@ -125,31 +82,6 @@ function getSupportConfig(req, res, next) { }); } -function setCloudronAvatar(req, res, next) { - assert.strictEqual(typeof req.files, 'object'); - - if (!req.files.avatar) return next(new HttpError(400, 'avatar must be provided')); - var avatar = safe.fs.readFileSync(req.files.avatar.path); - - settings.setCloudronAvatar(avatar, function (error) { - if (error) return next(BoxError.toHttpError(error)); - - next(new HttpSuccess(202, {})); - }); -} - -function getCloudronAvatar(req, res, next) { - settings.getCloudronAvatar(function (error, avatar) { - if (error) return next(BoxError.toHttpError(error)); - - // avoid caching the avatar on the client to see avatar changes immediately - res.set('Cache-Control', 'no-cache'); - - res.set('Content-Type', 'image/png'); - res.status(200).send(avatar); - }); -} - function getBackupConfig(req, res, next) { settings.getBackupConfig(function (error, backupConfig) { if (error) return next(BoxError.toHttpError(error)); @@ -332,11 +264,6 @@ function get(req, res, next) { case settings.APP_AUTOUPDATE_PATTERN_KEY: return getAppAutoupdatePattern(req, res, next); case settings.BOX_AUTOUPDATE_PATTERN_KEY: return getBoxAutoupdatePattern(req, res, next); case settings.TIME_ZONE_KEY: return getTimeZone(req, res, next); - case settings.CLOUDRON_NAME_KEY: return getCloudronName(req, res, next); - - case settings.FOOTER_KEY: return getFooter(req, res, next); - - case settings.CLOUDRON_AVATAR_KEY: return getCloudronAvatar(req, res, next); case settings.SUPPORT_CONFIG_KEY: return getSupportConfig(req, res, next); @@ -359,11 +286,6 @@ function set(req, res, next) { case settings.APP_AUTOUPDATE_PATTERN_KEY: return setAppAutoupdatePattern(req, res, next); case settings.BOX_AUTOUPDATE_PATTERN_KEY: return setBoxAutoupdatePattern(req, res, next); case settings.TIME_ZONE_KEY: return setTimeZone(req, res, next); - case settings.CLOUDRON_NAME_KEY: return setCloudronName(req, res, next); - - case settings.FOOTER_KEY: return setFooter(req, res, next); - - case settings.CLOUDRON_AVATAR_KEY: return setCloudronAvatar(req, res, next); default: return next(new HttpError(404, 'No such setting')); } diff --git a/src/routes/test/branding-test.js b/src/routes/test/branding-test.js new file mode 100644 index 000000000..b35e81781 --- /dev/null +++ b/src/routes/test/branding-test.js @@ -0,0 +1,149 @@ +'use strict'; + +/* 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'), + fs = require('fs'), + paths = require('../../paths.js'), + server = require('../../server.js'), + superagent = require('superagent'); + +var SERVER_URL = 'http://localhost:' + constants.PORT; + +var USERNAME = 'superadmin', PASSWORD = 'Foobar?1337', EMAIL ='silly@me.com'; +var token = null; + +function setup(done) { + async.series([ + server.start.bind(null), + database._clear.bind(null), + + function createAdmin(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(); + expect(result.statusCode).to.eql(201); + + // stash token for further use + token = result.body.token; + + callback(); + }); + } + ], done); +} + +function cleanup(done) { + database._clear(function (error) { + expect(!error).to.be.ok(); + + server.stop(done); + }); +} + +describe('Branding API', function () { + before(setup); + after(cleanup); + + describe('cloudron_name', function () { + var name = 'foobar'; + + it('get default succeeds', function (done) { + superagent.get(SERVER_URL + '/api/v1/branding/cloudron_name') + .query({ access_token: token }) + .end(function (err, res) { + expect(res.statusCode).to.equal(200); + expect(res.body.name).to.be.ok(); + done(); + }); + }); + + it('cannot set without name', function (done) { + superagent.post(SERVER_URL + '/api/v1/branding/cloudron_name') + .query({ access_token: token }) + .end(function (err, res) { + expect(res.statusCode).to.equal(400); + done(); + }); + }); + + it('cannot set empty name', function (done) { + superagent.post(SERVER_URL + '/api/v1/branding/cloudron_name') + .query({ access_token: token }) + .send({ name: '' }) + .end(function (err, res) { + expect(res.statusCode).to.equal(400); + done(); + }); + }); + + it('set succeeds', function (done) { + superagent.post(SERVER_URL + '/api/v1/branding/cloudron_name') + .query({ access_token: token }) + .send({ name: name }) + .end(function (err, res) { + expect(res.statusCode).to.equal(202); + done(); + }); + }); + + it('get succeeds', function (done) { + superagent.get(SERVER_URL + '/api/v1/branding/cloudron_name') + .query({ access_token: token }) + .end(function (err, res) { + expect(res.statusCode).to.equal(200); + expect(res.body.name).to.eql(name); + done(); + }); + }); + }); + + describe('cloudron_avatar', function () { + it('get default succeeds', function (done) { + superagent.get(SERVER_URL + '/api/v1/branding/cloudron_avatar') + .query({ access_token: token }) + .end(function (err, res) { + expect(res.statusCode).to.equal(200); + expect(res.body).to.be.a(Buffer); + done(); + }); + }); + + it('cannot set without data', function (done) { + superagent.post(SERVER_URL + '/api/v1/branding/cloudron_avatar') + .query({ access_token: token }) + .end(function (err, res) { + expect(res.statusCode).to.equal(400); + done(); + }); + }); + + it('set succeeds', function (done) { + superagent.post(SERVER_URL + '/api/v1/branding/cloudron_avatar') + .query({ access_token: token }) + .attach('avatar', paths.CLOUDRON_DEFAULT_AVATAR_FILE) + .end(function (err, res) { + expect(res.statusCode).to.equal(202); + done(); + }); + }); + + it('get succeeds', function (done) { + superagent.get(SERVER_URL + '/api/v1/branding/cloudron_avatar') + .query({ access_token: token }) + .end(function (err, res) { + expect(res.statusCode).to.equal(200); + expect(res.body.toString()).to.eql(fs.readFileSync(paths.CLOUDRON_DEFAULT_AVATAR_FILE, 'utf-8')); + done(err); + }); + }); + }); +}); diff --git a/src/routes/test/settings-test.js b/src/routes/test/settings-test.js index 291c6528b..485d0251a 100644 --- a/src/routes/test/settings-test.js +++ b/src/routes/test/settings-test.js @@ -9,8 +9,6 @@ var async = require('async'), constants = require('../../constants.js'), database = require('../../database.js'), expect = require('expect.js'), - fs = require('fs'), - paths = require('../../paths.js'), server = require('../../server.js'), superagent = require('superagent'); @@ -195,100 +193,6 @@ describe('Settings API', function () { }); }); - describe('cloudron_name', function () { - var name = 'foobar'; - - it('get default succeeds', function (done) { - superagent.get(SERVER_URL + '/api/v1/settings/cloudron_name') - .query({ access_token: token }) - .end(function (err, res) { - expect(res.statusCode).to.equal(200); - expect(res.body.name).to.be.ok(); - done(); - }); - }); - - it('cannot set without name', function (done) { - superagent.post(SERVER_URL + '/api/v1/settings/cloudron_name') - .query({ access_token: token }) - .end(function (err, res) { - expect(res.statusCode).to.equal(400); - done(); - }); - }); - - it('cannot set empty name', function (done) { - superagent.post(SERVER_URL + '/api/v1/settings/cloudron_name') - .query({ access_token: token }) - .send({ name: '' }) - .end(function (err, res) { - expect(res.statusCode).to.equal(400); - done(); - }); - }); - - it('set succeeds', function (done) { - superagent.post(SERVER_URL + '/api/v1/settings/cloudron_name') - .query({ access_token: token }) - .send({ name: name }) - .end(function (err, res) { - expect(res.statusCode).to.equal(202); - done(); - }); - }); - - it('get succeeds', function (done) { - superagent.get(SERVER_URL + '/api/v1/settings/cloudron_name') - .query({ access_token: token }) - .end(function (err, res) { - expect(res.statusCode).to.equal(200); - expect(res.body.name).to.eql(name); - done(); - }); - }); - }); - - describe('cloudron_avatar', function () { - it('get default succeeds', function (done) { - superagent.get(SERVER_URL + '/api/v1/settings/cloudron_avatar') - .query({ access_token: token }) - .end(function (err, res) { - expect(res.statusCode).to.equal(200); - expect(res.body).to.be.a(Buffer); - done(); - }); - }); - - it('cannot set without data', function (done) { - superagent.post(SERVER_URL + '/api/v1/settings/cloudron_avatar') - .query({ access_token: token }) - .end(function (err, res) { - expect(res.statusCode).to.equal(400); - done(); - }); - }); - - it('set succeeds', function (done) { - superagent.post(SERVER_URL + '/api/v1/settings/cloudron_avatar') - .query({ access_token: token }) - .attach('avatar', paths.CLOUDRON_DEFAULT_AVATAR_FILE) - .end(function (err, res) { - expect(res.statusCode).to.equal(202); - done(); - }); - }); - - it('get succeeds', function (done) { - superagent.get(SERVER_URL + '/api/v1/settings/cloudron_avatar') - .query({ access_token: token }) - .end(function (err, res) { - expect(res.statusCode).to.equal(200); - expect(res.body.toString()).to.eql(fs.readFileSync(paths.CLOUDRON_DEFAULT_AVATAR_FILE, 'utf-8')); - done(err); - }); - }); - }); - describe('time_zone', function () { it('succeeds', function (done) { superagent.get(SERVER_URL + '/api/v1/settings/time_zone') diff --git a/src/server.js b/src/server.js index fdbf597fc..dceb7d562 100644 --- a/src/server.js +++ b/src/server.js @@ -89,7 +89,7 @@ function initializeExpressSync() { router.post('/api/v1/cloudron/activate', routes.provision.activate); router.get ('/api/v1/cloudron/status', routes.provision.getStatus); - router.get ('/api/v1/cloudron/avatar', routes.settings.getCloudronAvatar); // this is a public alias for /api/v1/settings/cloudron_avatar + router.get ('/api/v1/cloudron/avatar', routes.branding.getCloudronAvatar); // this is a public alias for /api/v1/branding/cloudron_avatar // login/logout routes router.post('/api/v1/cloudron/login', password, routes.cloudron.login); @@ -234,7 +234,7 @@ function initializeExpressSync() { router.get ('/api/v1/branding/:setting', token, authorizeOwner, routes.branding.get); router.post('/api/v1/branding/:setting', token, authorizeOwner, (req, res, next) => { return req.params.setting === 'cloudron_avatar' ? multipart(req, res, next) : next(); - }, routes.settings.set); + }, routes.branding.set); // settings routes (these are for the settings tab - avatar & name have public routes for normal users. see above) router.get ('/api/v1/settings/:setting', token, authorizeAdmin, routes.settings.get);