diff --git a/src/accesscontrol.js b/src/accesscontrol.js index 2845dfbe5..9ba34c2a6 100644 --- a/src/accesscontrol.js +++ b/src/accesscontrol.js @@ -12,6 +12,8 @@ exports = module.exports = { SCOPE_CLIENTS: 'clients', SCOPE_DOMAINS: 'domains', + SCOPE_ANY: '*', + // roles are handled just like the above scopes, they are parallel to scopes // scopes enclose API groups, roles specify the usage role SCOPE_ROLE_SDK: 'roleSdk', diff --git a/src/routes/accesscontrol.js b/src/routes/accesscontrol.js index 6a9c33903..0702eb35f 100644 --- a/src/routes/accesscontrol.js +++ b/src/routes/accesscontrol.js @@ -32,7 +32,7 @@ function scope(requestedScope) { function (req, res, next) { var error = accesscontrol.validateRequestedScopes(req.authInfo || null, requestedScopes); - if (error) return next(new HttpError(401, error.message)); + if (error) return next(new HttpError(403, error.message)); next(); } diff --git a/src/routes/test/eventlog-test.js b/src/routes/test/eventlog-test.js index e9447bac0..1af1c58bb 100644 --- a/src/routes/test/eventlog-test.js +++ b/src/routes/test/eventlog-test.js @@ -6,7 +6,8 @@ 'use strict'; -var async = require('async'), +var accesscontrol = require('../../accesscontrol.js'), + async = require('async'), config = require('../../config.js'), database = require('../../database.js'), expect = require('expect.js'), @@ -62,7 +63,7 @@ function setup(done) { token_1 = tokendb.generateToken(); // HACK to get a token for second user (passwords are generated and the user should have gotten a password setup link...) - tokendb.add(token_1, USER_1_ID, 'test-client-id', Date.now() + 100000, '*', callback); + tokendb.add(token_1, USER_1_ID, 'test-client-id', Date.now() + 100000, accesscontrol.SCOPE_PROFILE, callback); } ], done); diff --git a/src/routes/test/groups-test.js b/src/routes/test/groups-test.js index 5d654e76a..9c7e6ce3a 100644 --- a/src/routes/test/groups-test.js +++ b/src/routes/test/groups-test.js @@ -6,7 +6,8 @@ 'use strict'; -var async = require('async'), +var accesscontrol = require('../../accesscontrol.js'), + async = require('async'), config = require('../../config.js'), database = require('../../database.js'), expect = require('expect.js'), @@ -69,7 +70,7 @@ function setup(done) { userId_1 = result.body.id; // HACK to get a token for second user (passwords are generated and the user should have gotten a password setup link...) - tokendb.add(token_1, userId_1, 'test-client-id', Date.now() + 100000, '*', callback); + tokendb.add(token_1, userId_1, 'test-client-id', Date.now() + 100000, accesscontrol.SCOPE_PROFILE, callback); }); } ], done); @@ -279,6 +280,20 @@ describe('Groups API', function () { }); }); + it('can add user_1 to admin', function (done) { + superagent.put(SERVER_URL + '/api/v1/users/' + userId_1 + '/groups') + .query({ access_token: token }) + .send({ groupIds: [ 'admin' ]}) + .end(function (error, result) { + expect(result.statusCode).to.equal(204); + + token_1 = tokendb.generateToken(); + + // HACK to get a token for second user (passwords are generated and the user should have gotten a password setup link...) + tokendb.add(token_1, userId_1, 'test-client-id', Date.now() + 100000, accesscontrol.SCOPE_ANY, done); + }); + }); + it('remove activation user from admin', function (done) { superagent.put(SERVER_URL + '/api/v1/users/' + userId + '/groups') .query({ access_token: token_1 }) diff --git a/src/routes/test/users-test.js b/src/routes/test/users-test.js index 23c98b23d..a501a53b0 100644 --- a/src/routes/test/users-test.js +++ b/src/routes/test/users-test.js @@ -5,7 +5,8 @@ 'use strict'; -var async = require('async'), +var accesscontrol = require('../../accesscontrol.js'), + async = require('async'), config = require('../../config.js'), constants = require('../../constants.js'), database = require('../../database.js'), @@ -174,7 +175,7 @@ describe('Users API', function () { var token = tokendb.generateToken(); var expires = Date.now() + 2000; // 1 sec - tokendb.add(token, user_0.id, null, expires, '*', function (error) { + tokendb.add(token, user_0.id, null, expires, accesscontrol.SCOPE_PROFILE, function (error) { expect(error).to.not.be.ok(); setTimeout(function () { @@ -270,7 +271,7 @@ describe('Users API', function () { expect(error).to.be.ok(); expect(result.statusCode).to.equal(400); done(); - }); + }); }); it('create second user succeeds', function (done) { @@ -287,7 +288,7 @@ describe('Users API', function () { checkMails(2, function () { // HACK to get a token for second user (passwords are generated and the user should have gotten a password setup link...) - tokendb.add(token_1, user_1.id, 'test-client-id', Date.now() + 10000, '*', done); + tokendb.add(token_1, user_1.id, 'test-client-id', Date.now() + 10000, accesscontrol.SCOPE_PROFILE, done); }); }); }); @@ -681,7 +682,7 @@ describe('Users API', function () { expect(error).to.be.ok(); expect(result.statusCode).to.equal(400); done(); - }); + }); }); it('can create user with a password', function (done) { @@ -697,7 +698,7 @@ describe('Users API', function () { token = tokendb.generateToken(); var expires = Date.now() + 2000; // 1 sec - tokendb.add(token, user_4.id, null, expires, '*', done); + tokendb.add(token, user_4.id, null, expires, accesscontrol.SCOPE_PROFILE, done); }); }); diff --git a/src/routes/users.js b/src/routes/users.js index bdbad3e7c..a2f25ef17 100644 --- a/src/routes/users.js +++ b/src/routes/users.js @@ -7,7 +7,6 @@ exports = module.exports = { create: create, remove: remove, verifyPassword: verifyPassword, - requireAdmin: requireAdmin, sendInvite: sendInvite, setGroups: setGroups }; @@ -146,17 +145,6 @@ function verifyPassword(req, res, next) { }); } -/* - Middleware which makes the route only accessable for the admin user. -*/ -function requireAdmin(req, res, next) { - assert.strictEqual(typeof req.user, 'object'); - - if (!req.user.admin) return next(new HttpError(403, 'API call requires admin rights.')); - - next(); -} - function sendInvite(req, res, next) { assert.strictEqual(typeof req.params.userId, 'string'); diff --git a/src/server.js b/src/server.js index e9c94d517..1d0d8bd44 100644 --- a/src/server.js +++ b/src/server.js @@ -116,18 +116,18 @@ function initializeExpressSync() { // cloudron routes router.get ('/api/v1/cloudron/config', cloudronScope, routes.cloudron.getConfig); - router.post('/api/v1/cloudron/update', cloudronScope, routes.users.requireAdmin, routes.cloudron.update); - router.post('/api/v1/cloudron/check_for_updates', cloudronScope, routes.users.requireAdmin, routes.cloudron.checkForUpdates); - router.post('/api/v1/cloudron/reboot', cloudronScope, routes.users.requireAdmin, routes.cloudron.reboot); - router.get ('/api/v1/cloudron/graphs', cloudronScope, routes.users.requireAdmin, routes.graphs.getGraphs); - router.get ('/api/v1/cloudron/disks', cloudronScope, routes.users.requireAdmin, routes.cloudron.getDisks); - router.get ('/api/v1/cloudron/logs', cloudronScope, routes.users.requireAdmin, routes.cloudron.getLogs); - router.get ('/api/v1/cloudron/logstream', cloudronScope, routes.users.requireAdmin, routes.cloudron.getLogStream); - router.get ('/api/v1/cloudron/ssh/authorized_keys', cloudronScope, routes.users.requireAdmin, routes.ssh.getAuthorizedKeys); - router.put ('/api/v1/cloudron/ssh/authorized_keys', cloudronScope, routes.users.requireAdmin, routes.ssh.addAuthorizedKey); - router.get ('/api/v1/cloudron/ssh/authorized_keys/:identifier', cloudronScope, routes.users.requireAdmin, routes.ssh.getAuthorizedKey); - router.del ('/api/v1/cloudron/ssh/authorized_keys/:identifier', cloudronScope, routes.users.requireAdmin, routes.ssh.delAuthorizedKey); - router.get ('/api/v1/cloudron/eventlog', cloudronScope, routes.users.requireAdmin, routes.eventlog.get); + router.post('/api/v1/cloudron/update', cloudronScope, routes.cloudron.update); + router.post('/api/v1/cloudron/check_for_updates', cloudronScope, routes.cloudron.checkForUpdates); + router.post('/api/v1/cloudron/reboot', cloudronScope, routes.cloudron.reboot); + router.get ('/api/v1/cloudron/graphs', cloudronScope, routes.graphs.getGraphs); + router.get ('/api/v1/cloudron/disks', cloudronScope, routes.cloudron.getDisks); + router.get ('/api/v1/cloudron/logs', cloudronScope, routes.cloudron.getLogs); + router.get ('/api/v1/cloudron/logstream', cloudronScope, routes.cloudron.getLogStream); + router.get ('/api/v1/cloudron/ssh/authorized_keys', cloudronScope, routes.ssh.getAuthorizedKeys); + router.put ('/api/v1/cloudron/ssh/authorized_keys', cloudronScope, routes.ssh.addAuthorizedKey); + router.get ('/api/v1/cloudron/ssh/authorized_keys/:identifier', cloudronScope, routes.ssh.getAuthorizedKey); + router.del ('/api/v1/cloudron/ssh/authorized_keys/:identifier', cloudronScope, routes.ssh.delAuthorizedKey); + router.get ('/api/v1/cloudron/eventlog', cloudronScope, routes.eventlog.get); // working off the user behind the provided token router.get ('/api/v1/user/apps', profileScope, routes.apps.getAllByUser); @@ -139,20 +139,20 @@ function initializeExpressSync() { router.post('/api/v1/user/profile/twofactorauthentication/disable', profileScope, routes.users.verifyPassword, routes.profile.disableTwoFactorAuthentication); // user routes - router.get ('/api/v1/users', usersScope, routes.users.requireAdmin, routes.users.list); - router.post('/api/v1/users', usersScope, routes.users.requireAdmin, routes.users.create); - router.get ('/api/v1/users/:userId', usersScope, routes.users.requireAdmin, routes.users.get); - router.del ('/api/v1/users/:userId', usersScope, routes.users.requireAdmin, routes.users.verifyPassword, routes.users.remove); - router.post('/api/v1/users/:userId', usersScope, routes.users.requireAdmin, routes.users.update); - router.put ('/api/v1/users/:userId/groups', usersScope, routes.users.requireAdmin, routes.users.setGroups); - router.post('/api/v1/users/:userId/invite', usersScope, routes.users.requireAdmin, routes.users.sendInvite); + router.get ('/api/v1/users', usersScope, routes.users.list); + router.post('/api/v1/users', usersScope, routes.users.create); + router.get ('/api/v1/users/:userId', usersScope, routes.users.get); + router.del ('/api/v1/users/:userId', usersScope, routes.users.verifyPassword, routes.users.remove); + router.post('/api/v1/users/:userId', usersScope, routes.users.update); + router.put ('/api/v1/users/:userId/groups', usersScope, routes.users.setGroups); + router.post('/api/v1/users/:userId/invite', usersScope, routes.users.sendInvite); // Group management - router.get ('/api/v1/groups', usersScope, routes.users.requireAdmin, routes.groups.list); - router.post('/api/v1/groups', usersScope, routes.users.requireAdmin, routes.groups.create); - router.get ('/api/v1/groups/:groupId', usersScope, routes.users.requireAdmin, routes.groups.get); - router.put ('/api/v1/groups/:groupId/members', usersScope, routes.users.requireAdmin, routes.groups.updateMembers); - router.del ('/api/v1/groups/:groupId', usersScope, routes.users.requireAdmin, routes.users.verifyPassword, routes.groups.remove); + router.get ('/api/v1/groups', usersScope, routes.groups.list); + router.post('/api/v1/groups', usersScope, routes.groups.create); + router.get ('/api/v1/groups/:groupId', usersScope, routes.groups.get); + router.put ('/api/v1/groups/:groupId/members', usersScope, routes.groups.updateMembers); + router.del ('/api/v1/groups/:groupId', usersScope, routes.users.verifyPassword, routes.groups.remove); // form based login routes used by oauth2 frame router.get ('/api/v1/session/login', csrf, routes.oauth2.loginForm); @@ -186,83 +186,83 @@ function initializeExpressSync() { router.get ('/api/v1/apps/:id', appsScope, routes.apps.getApp); router.get ('/api/v1/apps/:id/icon', routes.apps.getAppIcon); - router.post('/api/v1/apps/install', appsScope, routes.users.requireAdmin, routes.apps.installApp); - router.post('/api/v1/apps/:id/uninstall', appsScope, routes.users.requireAdmin, routes.users.verifyPassword, routes.apps.uninstallApp); - router.post('/api/v1/apps/:id/configure', appsScope, routes.users.requireAdmin, routes.apps.configureApp); - router.post('/api/v1/apps/:id/update', appsScope, routes.users.requireAdmin, routes.apps.updateApp); - router.post('/api/v1/apps/:id/restore', appsScope, routes.users.requireAdmin, routes.users.verifyPassword, routes.apps.restoreApp); - router.post('/api/v1/apps/:id/backup', appsScope, routes.users.requireAdmin, routes.apps.backupApp); - router.get ('/api/v1/apps/:id/backups', appsScope, routes.users.requireAdmin, routes.apps.listBackups); - router.post('/api/v1/apps/:id/stop', appsScope, routes.users.requireAdmin, routes.apps.stopApp); - router.post('/api/v1/apps/:id/start', appsScope, routes.users.requireAdmin, routes.apps.startApp); - router.get ('/api/v1/apps/:id/logstream', appsScope, routes.users.requireAdmin, routes.apps.getLogStream); - router.get ('/api/v1/apps/:id/logs', appsScope, routes.users.requireAdmin, routes.apps.getLogs); - router.get ('/api/v1/apps/:id/exec', appsScope, routes.users.requireAdmin, routes.apps.exec); + router.post('/api/v1/apps/install', appsScope, routes.apps.installApp); + router.post('/api/v1/apps/:id/uninstall', appsScope, routes.users.verifyPassword, routes.apps.uninstallApp); + router.post('/api/v1/apps/:id/configure', appsScope, routes.apps.configureApp); + router.post('/api/v1/apps/:id/update', appsScope, routes.apps.updateApp); + router.post('/api/v1/apps/:id/restore', appsScope, routes.users.verifyPassword, routes.apps.restoreApp); + router.post('/api/v1/apps/:id/backup', appsScope, routes.apps.backupApp); + router.get ('/api/v1/apps/:id/backups', appsScope, routes.apps.listBackups); + router.post('/api/v1/apps/:id/stop', appsScope, routes.apps.stopApp); + router.post('/api/v1/apps/:id/start', appsScope, routes.apps.startApp); + router.get ('/api/v1/apps/:id/logstream', appsScope, routes.apps.getLogStream); + router.get ('/api/v1/apps/:id/logs', appsScope, routes.apps.getLogs); + router.get ('/api/v1/apps/:id/exec', appsScope, routes.apps.exec); // websocket cannot do bearer authentication - router.get ('/api/v1/apps/:id/execws', routes.accesscontrol.websocketAuth.bind(null, [ accesscontrol.SCOPE_APPS ]), routes.users.requireAdmin, routes.apps.execWebSocket); - router.post('/api/v1/apps/:id/clone', appsScope, routes.users.requireAdmin, routes.apps.cloneApp); - router.get ('/api/v1/apps/:id/download', appsScope, routes.users.requireAdmin, routes.apps.downloadFile); - router.post('/api/v1/apps/:id/upload', appsScope, routes.users.requireAdmin, multipart, routes.apps.uploadFile); + router.get ('/api/v1/apps/:id/execws', routes.accesscontrol.websocketAuth.bind(null, [ accesscontrol.SCOPE_APPS ]), routes.apps.execWebSocket); + router.post('/api/v1/apps/:id/clone', appsScope, routes.apps.cloneApp); + router.get ('/api/v1/apps/:id/download', appsScope, routes.apps.downloadFile); + router.post('/api/v1/apps/:id/upload', appsScope, multipart, routes.apps.uploadFile); // settings routes (these are for the settings tab - avatar & name have public routes for normal users. see above) - router.get ('/api/v1/settings/app_autoupdate_pattern', settingsScope, routes.users.requireAdmin, routes.settings.getAppAutoupdatePattern); - router.post('/api/v1/settings/app_autoupdate_pattern', settingsScope, routes.users.requireAdmin, routes.settings.setAppAutoupdatePattern); - router.get ('/api/v1/settings/box_autoupdate_pattern', settingsScope, routes.users.requireAdmin, routes.settings.getBoxAutoupdatePattern); - router.post('/api/v1/settings/box_autoupdate_pattern', settingsScope, routes.users.requireAdmin, routes.settings.setBoxAutoupdatePattern); - router.get ('/api/v1/settings/cloudron_name', settingsScope, routes.users.requireAdmin, routes.settings.getCloudronName); - router.post('/api/v1/settings/cloudron_name', settingsScope, routes.users.requireAdmin, routes.settings.setCloudronName); - router.get ('/api/v1/settings/cloudron_avatar', settingsScope, routes.users.requireAdmin, routes.settings.getCloudronAvatar); - router.post('/api/v1/settings/cloudron_avatar', settingsScope, routes.users.requireAdmin, multipart, routes.settings.setCloudronAvatar); - router.get ('/api/v1/settings/backup_config', settingsScope, routes.users.requireAdmin, routes.settings.getBackupConfig); - router.post('/api/v1/settings/backup_config', settingsScope, routes.users.requireAdmin, routes.settings.setBackupConfig); + router.get ('/api/v1/settings/app_autoupdate_pattern', settingsScope, routes.settings.getAppAutoupdatePattern); + router.post('/api/v1/settings/app_autoupdate_pattern', settingsScope, routes.settings.setAppAutoupdatePattern); + router.get ('/api/v1/settings/box_autoupdate_pattern', settingsScope, routes.settings.getBoxAutoupdatePattern); + router.post('/api/v1/settings/box_autoupdate_pattern', settingsScope, routes.settings.setBoxAutoupdatePattern); + router.get ('/api/v1/settings/cloudron_name', settingsScope, routes.settings.getCloudronName); + router.post('/api/v1/settings/cloudron_name', settingsScope, routes.settings.setCloudronName); + router.get ('/api/v1/settings/cloudron_avatar', settingsScope, routes.settings.getCloudronAvatar); + router.post('/api/v1/settings/cloudron_avatar', settingsScope, multipart, routes.settings.setCloudronAvatar); + router.get ('/api/v1/settings/backup_config', settingsScope, routes.settings.getBackupConfig); + router.post('/api/v1/settings/backup_config', settingsScope, routes.settings.setBackupConfig); - router.get ('/api/v1/settings/time_zone', settingsScope, routes.users.requireAdmin, routes.settings.getTimeZone); - router.post('/api/v1/settings/time_zone', settingsScope, routes.users.requireAdmin, routes.settings.setTimeZone); - router.get ('/api/v1/settings/appstore_config', settingsScope, routes.users.requireAdmin, routes.settings.getAppstoreConfig); - router.post('/api/v1/settings/appstore_config', settingsScope, routes.users.requireAdmin, routes.settings.setAppstoreConfig); + router.get ('/api/v1/settings/time_zone', settingsScope, routes.settings.getTimeZone); + router.post('/api/v1/settings/time_zone', settingsScope, routes.settings.setTimeZone); + router.get ('/api/v1/settings/appstore_config', settingsScope, routes.settings.getAppstoreConfig); + router.post('/api/v1/settings/appstore_config', settingsScope, routes.settings.setAppstoreConfig); // email routes - router.get ('/api/v1/mail/:domain', mailScope, routes.users.requireAdmin, routes.mail.getDomain); - router.post('/api/v1/mail/:domain', mailScope, routes.users.requireAdmin, routes.mail.updateDomain); - router.post('/api/v1/mail', mailScope, routes.users.requireAdmin, routes.mail.addDomain); - router.get ('/api/v1/mail/:domain/stats', mailScope, routes.users.requireAdmin, routes.users.verifyPassword, routes.mail.getDomainStats); - router.del ('/api/v1/mail/:domain', mailScope, routes.users.requireAdmin, routes.users.verifyPassword, routes.mail.removeDomain); - router.get ('/api/v1/mail/:domain/status', mailScope, routes.users.requireAdmin, routes.mail.getStatus); - router.post('/api/v1/mail/:domain/mail_from_validation', mailScope, routes.users.requireAdmin, routes.mail.setMailFromValidation); - router.post('/api/v1/mail/:domain/catch_all', mailScope, routes.users.requireAdmin, routes.mail.setCatchAllAddress); - router.post('/api/v1/mail/:domain/relay', mailScope, routes.users.requireAdmin, routes.mail.setMailRelay); - router.post('/api/v1/mail/:domain/enable', mailScope, routes.users.requireAdmin, routes.mail.setMailEnabled); - router.post('/api/v1/mail/:domain/send_test_mail', mailScope, routes.users.requireAdmin, routes.mail.sendTestMail); - router.get ('/api/v1/mail/:domain/mailboxes', mailScope, routes.users.requireAdmin, routes.mail.getMailboxes); - router.get ('/api/v1/mail/:domain/mailboxes/:name', mailScope, routes.users.requireAdmin, routes.mail.getMailbox); - router.post('/api/v1/mail/:domain/mailboxes', mailScope, routes.users.requireAdmin, routes.mail.addMailbox); - router.post('/api/v1/mail/:domain/mailboxes/:name', mailScope, routes.users.requireAdmin, routes.mail.updateMailbox); - router.del ('/api/v1/mail/:domain/mailboxes/:name', mailScope, routes.users.requireAdmin, routes.mail.removeMailbox); - router.get ('/api/v1/mail/:domain/aliases', mailScope, routes.users.requireAdmin, routes.mail.listAliases); - router.get ('/api/v1/mail/:domain/aliases/:name', mailScope, routes.users.requireAdmin, routes.mail.getAliases); - router.put ('/api/v1/mail/:domain/aliases/:name', mailScope, routes.users.requireAdmin, routes.mail.setAliases); - router.get ('/api/v1/mail/:domain/lists', mailScope, routes.users.requireAdmin, routes.mail.getLists); - router.post('/api/v1/mail/:domain/lists', mailScope, routes.users.requireAdmin, routes.mail.addList); - router.get ('/api/v1/mail/:domain/lists/:name', mailScope, routes.users.requireAdmin, routes.mail.getList); - router.post('/api/v1/mail/:domain/lists/:name', mailScope, routes.users.requireAdmin, routes.mail.updateList); - router.del ('/api/v1/mail/:domain/lists/:name', mailScope, routes.users.requireAdmin, routes.mail.removeList); + router.get ('/api/v1/mail/:domain', mailScope, routes.mail.getDomain); + router.post('/api/v1/mail/:domain', mailScope, routes.mail.updateDomain); + router.post('/api/v1/mail', mailScope, routes.mail.addDomain); + router.get ('/api/v1/mail/:domain/stats', mailScope, routes.users.verifyPassword, routes.mail.getDomainStats); + router.del ('/api/v1/mail/:domain', mailScope, routes.users.verifyPassword, routes.mail.removeDomain); + router.get ('/api/v1/mail/:domain/status', mailScope, routes.mail.getStatus); + router.post('/api/v1/mail/:domain/mail_from_validation', mailScope, routes.mail.setMailFromValidation); + router.post('/api/v1/mail/:domain/catch_all', mailScope, routes.mail.setCatchAllAddress); + router.post('/api/v1/mail/:domain/relay', mailScope, routes.mail.setMailRelay); + router.post('/api/v1/mail/:domain/enable', mailScope, routes.mail.setMailEnabled); + router.post('/api/v1/mail/:domain/send_test_mail', mailScope, routes.mail.sendTestMail); + router.get ('/api/v1/mail/:domain/mailboxes', mailScope, routes.mail.getMailboxes); + router.get ('/api/v1/mail/:domain/mailboxes/:name', mailScope, routes.mail.getMailbox); + router.post('/api/v1/mail/:domain/mailboxes', mailScope, routes.mail.addMailbox); + router.post('/api/v1/mail/:domain/mailboxes/:name', mailScope, routes.mail.updateMailbox); + router.del ('/api/v1/mail/:domain/mailboxes/:name', mailScope, routes.mail.removeMailbox); + router.get ('/api/v1/mail/:domain/aliases', mailScope, routes.mail.listAliases); + router.get ('/api/v1/mail/:domain/aliases/:name', mailScope, routes.mail.getAliases); + router.put ('/api/v1/mail/:domain/aliases/:name', mailScope, routes.mail.setAliases); + router.get ('/api/v1/mail/:domain/lists', mailScope, routes.mail.getLists); + router.post('/api/v1/mail/:domain/lists', mailScope, routes.mail.addList); + router.get ('/api/v1/mail/:domain/lists/:name', mailScope, routes.mail.getList); + router.post('/api/v1/mail/:domain/lists/:name', mailScope, routes.mail.updateList); + router.del ('/api/v1/mail/:domain/lists/:name', mailScope, routes.mail.removeList); // feedback router.post('/api/v1/feedback', usersScope, routes.cloudron.feedback); // backup routes - router.get ('/api/v1/backups', settingsScope, routes.users.requireAdmin, routes.backups.get); - router.post('/api/v1/backups', settingsScope, routes.users.requireAdmin, routes.backups.create); + router.get ('/api/v1/backups', settingsScope, routes.backups.get); + router.post('/api/v1/backups', settingsScope, routes.backups.create); // domain routes - router.post('/api/v1/domains', domainsScope, routes.users.requireAdmin, routes.domains.add); - router.get ('/api/v1/domains', domainsScope, routes.users.requireAdmin, routes.domains.getAll); - router.get ('/api/v1/domains/:domain', domainsScope, routes.users.requireAdmin, routes.domains.get); - router.put ('/api/v1/domains/:domain', domainsScope, routes.users.requireAdmin, routes.domains.update); - router.del ('/api/v1/domains/:domain', domainsScope, routes.users.requireAdmin, routes.users.verifyPassword, routes.domains.del); + router.post('/api/v1/domains', domainsScope, routes.domains.add); + router.get ('/api/v1/domains', domainsScope, routes.domains.getAll); + router.get ('/api/v1/domains/:domain', domainsScope, routes.domains.get); + router.put ('/api/v1/domains/:domain', domainsScope, routes.domains.update); + router.del ('/api/v1/domains/:domain', domainsScope, routes.users.verifyPassword, routes.domains.del); // caas routes - router.post('/api/v1/caas/change_plan', cloudronScope, routes.users.requireAdmin, routes.users.verifyPassword, routes.caas.changePlan); + router.post('/api/v1/caas/change_plan', cloudronScope, routes.users.verifyPassword, routes.caas.changePlan); // disable server socket "idle" timeout. we use the timeout middleware to handle timeouts on a route level // we rely on nginx for timeouts on the TCP level (see client_header_timeout)