Add multiselect to enable mailboxes per user and domain
This commit is contained in:
@@ -91,13 +91,8 @@
|
|||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<form name="useredit_form" role="form" ng-submit="useredit.submit()" autocomplete="off">
|
<form name="useredit_form" role="form" ng-submit="useredit.submit()" autocomplete="off">
|
||||||
<input type="password" style="display: none;">
|
<input type="password" style="display: none;">
|
||||||
<div class="form-group" ng-show="mailConfig.enabled">
|
|
||||||
<label class="control-label">Email</label>
|
|
||||||
<input type="email" class="form-control" placeholder="Will be assigned when user signs up" ng-model="useredit.userInfo.email" disabled>
|
|
||||||
</div>
|
|
||||||
<div class="form-group" ng-class="{ 'has-error': (useredit_form.email.$dirty && useredit_form.email.$invalid) || (!useredit_form.email.$dirty && useredit.error.email) }">
|
<div class="form-group" ng-class="{ 'has-error': (useredit_form.email.$dirty && useredit_form.email.$invalid) || (!useredit_form.email.$dirty && useredit.error.email) }">
|
||||||
<label class="control-label" ng-show="mailConfig.enabled">Password recovery email</label>
|
<label class="control-label" >Email</label>
|
||||||
<label class="control-label" ng-hide="mailConfig.enabled">Email</label>
|
|
||||||
<div class="control-label" ng-show="(!useredit_form.email.$dirty && useredit.error.email) || (useredit_form.email.$dirty && useredit_form.email.$invalid) || (!useredit_form.email.$dirty && useredit.error.email)">
|
<div class="control-label" ng-show="(!useredit_form.email.$dirty && useredit.error.email) || (useredit_form.email.$dirty && useredit_form.email.$invalid) || (!useredit_form.email.$dirty && useredit.error.email)">
|
||||||
<small ng-show="useredit_form.email.$error.required">An email is required</small>
|
<small ng-show="useredit_form.email.$error.required">An email is required</small>
|
||||||
<small ng-show="useredit_form.email.$error.email">This is not a valid email</small>
|
<small ng-show="useredit_form.email.$error.email">This is not a valid email</small>
|
||||||
@@ -105,6 +100,15 @@
|
|||||||
</div>
|
</div>
|
||||||
<input type="email" class="form-control" ng-model="useredit.email" name="email" required>
|
<input type="email" class="form-control" ng-model="useredit.email" name="email" required>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group" ng-class="{ 'has-error': (useredit_form.fallbackEmail.$dirty && useredit_form.fallbackEmail.$invalid) || (!useredit_form.fallbackEmail.$dirty && useredit.error.fallbackEmail) }">
|
||||||
|
<label class="control-label" >Password recovery email</label>
|
||||||
|
<div class="control-label" ng-show="(!useredit_form.fallbackEmail.$dirty && useredit.error.fallbackEmail) || (useredit_form.fallbackEmail.$dirty && useredit_form.fallbackEmail.$invalid) || (!useredit_form.fallbackEmail.$dirty && useredit.error.fallbackEmail)">
|
||||||
|
<small ng-show="useredit_form.fallbackEmail.$error.required">An email is required</small>
|
||||||
|
<small ng-show="useredit_form.fallbackEmail.$error.fallbackEmail">This is not a valid email</small>
|
||||||
|
<small ng-show="!useredit_form.fallbackEmail.$dirty && useredit.error.fallbackEmail">{{ useredit.error.fallbackEmail }}</small>
|
||||||
|
</div>
|
||||||
|
<input type="fallbackEmail" class="form-control" ng-model="useredit.fallbackEmail" name="fallbackEmail" required>
|
||||||
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label">Groups</label>
|
<label class="control-label">Groups</label>
|
||||||
<div>
|
<div>
|
||||||
@@ -114,7 +118,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<div ng-show="groups.length <= 1">No groups available.</div>
|
<div ng-show="groups.length <= 1">No groups available.</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group" ng-show="useredit.userInfo.username && mailConfig.enabled" ng-class="{ 'has-error': useredit.error.aliases }">
|
<div class="form-group">
|
||||||
|
<label class="control-label">Email Address on Domains</label>
|
||||||
|
<div>
|
||||||
|
<multiselect ng-model="useredit.emailAddresses" options="a for a in useredit.availableEmailAddresses" data-multiple="true"></multiselect>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group" ng-show="useredit.userInfo.username" ng-class="{ 'has-error': useredit.error.aliases }">
|
||||||
<label class="control-label">Email aliases</label>
|
<label class="control-label">Email aliases</label>
|
||||||
|
|
||||||
<div class="control-label" ng-show="useredit.error.aliases">
|
<div class="control-label" ng-show="useredit.error.aliases">
|
||||||
|
|||||||
@@ -2,6 +2,22 @@
|
|||||||
|
|
||||||
/* global Clipboard */
|
/* global Clipboard */
|
||||||
|
|
||||||
|
// poor man's async
|
||||||
|
function asyncForEach(items, handler, callback) {
|
||||||
|
var cur = 0;
|
||||||
|
|
||||||
|
if (items.length === 0) return callback();
|
||||||
|
|
||||||
|
(function iterator() {
|
||||||
|
handler(items[cur], function () {
|
||||||
|
if (cur >= items.length-1) return callback();
|
||||||
|
++cur;
|
||||||
|
|
||||||
|
iterator();
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
|
||||||
angular.module('Application').controller('UsersController', ['$scope', '$location', '$timeout', 'Client', function ($scope, $location, $timeout, Client) {
|
angular.module('Application').controller('UsersController', ['$scope', '$location', '$timeout', 'Client', function ($scope, $location, $timeout, Client) {
|
||||||
Client.onReady(function () { if (!Client.getUserInfo().admin) $location.path('/'); });
|
Client.onReady(function () { if (!Client.getUserInfo().admin) $location.path('/'); });
|
||||||
|
|
||||||
@@ -11,6 +27,7 @@ angular.module('Application').controller('UsersController', ['$scope', '$locatio
|
|||||||
$scope.groupsById = { };
|
$scope.groupsById = { };
|
||||||
$scope.config = Client.getConfig();
|
$scope.config = Client.getConfig();
|
||||||
$scope.userInfo = Client.getUserInfo();
|
$scope.userInfo = Client.getUserInfo();
|
||||||
|
$scope.emailDomains = [];
|
||||||
|
|
||||||
// FIXME this needs a whole lot of rework as it is used for alias ui, which now needs to be multidomain aware
|
// FIXME this needs a whole lot of rework as it is used for alias ui, which now needs to be multidomain aware
|
||||||
$scope.mailConfig = {
|
$scope.mailConfig = {
|
||||||
@@ -150,6 +167,8 @@ angular.module('Application').controller('UsersController', ['$scope', '$locatio
|
|||||||
email: '',
|
email: '',
|
||||||
fallbackEmail: '',
|
fallbackEmail: '',
|
||||||
aliases: '',
|
aliases: '',
|
||||||
|
emailAddresses: [],
|
||||||
|
availableEmailAddresses: [],
|
||||||
superuser: false,
|
superuser: false,
|
||||||
|
|
||||||
show: function (userInfo) {
|
show: function (userInfo) {
|
||||||
@@ -160,14 +179,29 @@ angular.module('Application').controller('UsersController', ['$scope', '$locatio
|
|||||||
$scope.useredit.groupIds = angular.copy(userInfo.groupIds);
|
$scope.useredit.groupIds = angular.copy(userInfo.groupIds);
|
||||||
$scope.useredit.superuser = userInfo.groupIds.indexOf('admin') !== -1;
|
$scope.useredit.superuser = userInfo.groupIds.indexOf('admin') !== -1;
|
||||||
|
|
||||||
|
$scope.useredit.availableEmailAddresses = $scope.emailDomains.map(function (d) { return userInfo.username + '@' + d.domain; });
|
||||||
|
$scope.useredit.emailAddresses = [];
|
||||||
$scope.useredit.aliases = '';
|
$scope.useredit.aliases = '';
|
||||||
|
|
||||||
Client.getAliases(userInfo.id, function (error, aliases) {
|
Client.getAliases(userInfo.id, function (error, aliases) {
|
||||||
if (error) console.error(error);
|
if (error) console.error(error);
|
||||||
|
|
||||||
$scope.useredit.aliases = aliases.join(',');
|
$scope.useredit.aliases = aliases.join(',');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var tmp = [];
|
||||||
|
asyncForEach($scope.emailDomains, function (domain, callback) {
|
||||||
|
Client.getUserMailbox(domain.domain, userInfo.id, function (error) {
|
||||||
|
if (error) return callback();
|
||||||
|
|
||||||
|
tmp.push(userInfo.username + '@' + domain.domain);
|
||||||
|
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
}, function () {
|
||||||
|
// we need this copy as angular multiselect cannot deal with dynamic arrays!
|
||||||
|
$scope.useredit.emailAddresses = tmp;
|
||||||
|
});
|
||||||
|
|
||||||
$scope.useredit_form.$setPristine();
|
$scope.useredit_form.$setPristine();
|
||||||
$scope.useredit_form.$setUntouched();
|
$scope.useredit_form.$setUntouched();
|
||||||
|
|
||||||
@@ -195,7 +229,8 @@ angular.module('Application').controller('UsersController', ['$scope', '$locatio
|
|||||||
|
|
||||||
var data = {
|
var data = {
|
||||||
id: $scope.useredit.userInfo.id,
|
id: $scope.useredit.userInfo.id,
|
||||||
email: $scope.useredit.email
|
email: $scope.useredit.email,
|
||||||
|
fallbackEmail: $scope.useredit.fallbackEmail
|
||||||
};
|
};
|
||||||
|
|
||||||
Client.updateUser(data, function (error) {
|
Client.updateUser(data, function (error) {
|
||||||
@@ -222,30 +257,44 @@ angular.module('Application').controller('UsersController', ['$scope', '$locatio
|
|||||||
Client.setGroups(data.id, $scope.useredit.groupIds, function (error) {
|
Client.setGroups(data.id, $scope.useredit.groupIds, function (error) {
|
||||||
if (error) return console.error('Unable to update groups for user:', error);
|
if (error) return console.error('Unable to update groups for user:', error);
|
||||||
|
|
||||||
var aliases = $scope.useredit.aliases ? $scope.useredit.aliases.split(',') : [ ];
|
// var aliases = $scope.useredit.aliases ? $scope.useredit.aliases.split(',') : [ ];
|
||||||
var setAliasesFunc = Client.setAliases.bind(null, $scope.useredit.userInfo.id, aliases);
|
// var setAliasesFunc = Client.setAliases.bind(null, $scope.useredit.userInfo.id, aliases);
|
||||||
|
|
||||||
// cannot set aliases without username
|
// // cannot set aliases without username
|
||||||
if (!$scope.useredit.userInfo.username) setAliasesFunc = function (next) { return next(); };
|
// if (!$scope.useredit.userInfo.username) setAliasesFunc = function (next) { return next(); };
|
||||||
|
|
||||||
setAliasesFunc(function (error) {
|
// setAliasesFunc(function (error) {
|
||||||
|
|
||||||
|
// if (error) {
|
||||||
|
// if (error.statusCode === 400) {
|
||||||
|
// $scope.useredit.error.aliases = 'One or more aliases is invalid';
|
||||||
|
// } else if (error.statusCode === 409) {
|
||||||
|
// $scope.useredit.error.aliases = 'One or more aliases already taken';
|
||||||
|
// } else {
|
||||||
|
// console.error('Unable to update aliases for user:', error);
|
||||||
|
// }
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
asyncForEach($scope.useredit.availableEmailAddresses, function (address, callback) {
|
||||||
|
var isEnabled = !!$scope.useredit.emailAddresses.find(function (a) { return a === address; });
|
||||||
|
|
||||||
|
var domain = $scope.emailDomains.find(function (d) { return address.split('@')[1] === d.domain; });
|
||||||
|
if (!domain) console.error('Domain not found. Internal error should not happen.');
|
||||||
|
|
||||||
|
// TODO we could be smarter and check if the selection has actually changed
|
||||||
|
if (isEnabled) Client.enableUserMailbox(domain.domain, $scope.useredit.userInfo.id, callback);
|
||||||
|
else Client.disableUserMailbox(domain.domain, $scope.useredit.userInfo.id, callback);
|
||||||
|
}, function (error) {
|
||||||
$scope.useredit.busy = false;
|
$scope.useredit.busy = false;
|
||||||
|
|
||||||
if (error) {
|
if (error) return console.error('unable to adjust email addresses.', error);
|
||||||
if (error.statusCode === 400) {
|
|
||||||
$scope.useredit.error.aliases = 'One or more aliases is invalid';
|
|
||||||
} else if (error.statusCode === 409) {
|
|
||||||
$scope.useredit.error.aliases = 'One or more aliases already taken';
|
|
||||||
} else {
|
|
||||||
console.error('Unable to update aliases for user:', error);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$scope.useredit.userInfo = {};
|
$scope.useredit.userInfo = {};
|
||||||
$scope.useredit.email = '';
|
$scope.useredit.email = '';
|
||||||
$scope.useredit.superuser = false;
|
$scope.useredit.superuser = false;
|
||||||
$scope.useredit.groupIds = [];
|
$scope.useredit.groupIds = [];
|
||||||
|
$scope.useredit.emailAddresses = [];
|
||||||
$scope.useredit.aliases = '';
|
$scope.useredit.aliases = '';
|
||||||
|
|
||||||
$scope.useredit_form.$setPristine();
|
$scope.useredit_form.$setPristine();
|
||||||
@@ -408,9 +457,31 @@ angular.module('Application').controller('UsersController', ['$scope', '$locatio
|
|||||||
|
|
||||||
$scope.users = result;
|
$scope.users = result;
|
||||||
|
|
||||||
|
Client.getDomains(function (error, result) {
|
||||||
|
if (error) return console.error('Unable to get domain listing.', error);
|
||||||
|
|
||||||
|
// reset so we can push the fresh config
|
||||||
|
$scope.emailDomains = [];
|
||||||
|
|
||||||
|
asyncForEach(result, function (domain, callback) {
|
||||||
|
Client.getMailConfigForDomain(domain.domain, function (error, mailConfig) {
|
||||||
|
if (error) return callback(error);
|
||||||
|
|
||||||
|
domain.mailConfig = mailConfig;
|
||||||
|
|
||||||
|
// only collect domains where email is enabled
|
||||||
|
if (mailConfig.enabled) $scope.emailDomains.push(domain);
|
||||||
|
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
}, function (error) {
|
||||||
|
if (error) return console.error('Unable to get mail config for domains.', error);
|
||||||
|
|
||||||
$scope.ready = true;
|
$scope.ready = true;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Client.onReady(refresh);
|
Client.onReady(refresh);
|
||||||
|
|||||||
Reference in New Issue
Block a user