2014-08-17 22:43:57 +00:00
< h2 > Users< / h2 >
< style >
2015-03-22 13:59:05 +00:00
#user_table h4 { margin: 1em 0 0 0; }
2014-10-07 20:24:11 +00:00
#user_table tr.account_inactive td.address { color: #888; text-decoration: line-through; }
2014-09-21 17:06:38 +00:00
#user_table .actions { margin-top: .33em; font-size: 95%; }
#user_table .account_inactive .if_active { display: none; }
#user_table .account_active .if_inactive { display: none; }
2015-03-22 13:59:05 +00:00
#user_table .account_active.if_inactive { display: none; }
2014-08-17 22:43:57 +00:00
< / style >
< h3 > Add a mail user< / h3 >
internationalized domain names (DNS, web, CSRs, normalize to Unicode in database, prohibit non-ASCII characters in user account names)
* For non-ASCII domain names, we will keep the Unicode encoding in our users/aliases table. This is nice for the user and also simplifies things like sorting domain names (using Unicode lexicographic order is good, using ASCII lexicogrpahic order on IDNA is confusing).
* Write nsd config, nsd zone files, nginx config, and SSL CSRs with domains in IDNA-encoded ASCII.
* When checking SSL certificates, treat the CN and SANs as IDNA.
* Since Chrome has an interesting feature of converting Unicode to IDNA in <input type="email"> form fields, we'll also forcibly convert IDNA to Unicode in the domain part of email addresses before saving email addresses in the users/aliases tables so that the table is normalized to Unicode.
* Don't allow non-ASCII characters in user account email addresses. Dovecot gets confused when querying the Sqlite database (which we observed even for non-word ASCII characters too, so it may not be related to the character encoding).
2015-01-17 13:41:53 +00:00
< p > Add an email address to this system. This will create a new login username/password.< / p >
2014-08-17 22:43:57 +00:00
< form class = "form-inline" role = "form" onsubmit = "return do_add_user(); return false;" >
< div class = "form-group" >
< label class = "sr-only" for = "adduserEmail" > Email address< / label >
< input type = "email" class = "form-control" id = "adduserEmail" placeholder = "Email Address" >
< / div >
< div class = "form-group" >
< label class = "sr-only" for = "adduserPassword" > Password< / label >
< input type = "password" class = "form-control" id = "adduserPassword" placeholder = "Password" >
< / div >
< div class = "form-group" >
< select class = "form-control" id = "adduserPrivs" >
< option value = "" > Normal User< / option >
< option value = "admin" > Administrator< / option >
< / select >
< / div >
< button type = "submit" class = "btn btn-primary" > Add User< / button >
< / form >
internationalized domain names (DNS, web, CSRs, normalize to Unicode in database, prohibit non-ASCII characters in user account names)
* For non-ASCII domain names, we will keep the Unicode encoding in our users/aliases table. This is nice for the user and also simplifies things like sorting domain names (using Unicode lexicographic order is good, using ASCII lexicogrpahic order on IDNA is confusing).
* Write nsd config, nsd zone files, nginx config, and SSL CSRs with domains in IDNA-encoded ASCII.
* When checking SSL certificates, treat the CN and SANs as IDNA.
* Since Chrome has an interesting feature of converting Unicode to IDNA in <input type="email"> form fields, we'll also forcibly convert IDNA to Unicode in the domain part of email addresses before saving email addresses in the users/aliases tables so that the table is normalized to Unicode.
* Don't allow non-ASCII characters in user account email addresses. Dovecot gets confused when querying the Sqlite database (which we observed even for non-word ASCII characters too, so it may not be related to the character encoding).
2015-01-17 13:41:53 +00:00
< ul style = "margin-top: 1em; padding-left: 1.5em; font-size: 90%;" >
< li > Passwords must be at least four characters and may not contain spaces.< / li >
< li > Use < a href = "javascript:show_panel('aliases')" > aliases< / a > to create email addresses that forward to existing accounts.< / li >
< li > Administrators get access to this control panel.< / li >
< li > User accounts cannot contain any international (non-ASCII) characters, but < a href = "javascript:show_panel('aliases')" > aliases< / a > can.< / li >
< / ul >
2014-08-17 22:43:57 +00:00
< h3 > Existing mail users< / h3 >
< table id = "user_table" class = "table" style = "width: auto" >
2014-10-07 20:24:11 +00:00
< thead >
< tr >
< th width = "50%" > Email Address< / th >
< th > Actions< / th >
< th > Mailbox Size< / th >
< / tr >
< / thead >
2014-08-17 22:43:57 +00:00
< tbody >
< / tbody >
< / table >
< div style = "display: none" >
< table >
< tr id = "user-template" >
2014-10-07 20:24:11 +00:00
< td class = 'address' >
< / td >
< td class = 'actions' >
2014-09-21 17:06:38 +00:00
< span class = 'privs' >
< / span >
2014-09-21 17:24:01 +00:00
< span class = "if_active" >
< a href = "#" onclick = "users_set_password(this); return false;" class = 'setpw' title = "Set Password" >
set password
< / a >
|
< / span >
2014-09-21 17:06:38 +00:00
< span class = 'add-privs' >
< / span >
< a href = "#" onclick = "users_remove(this); return false;" class = 'if_active' title = "Archive Account" >
archive account
< / a >
2014-10-07 20:24:11 +00:00
< / td >
< td class = 'mailboxsize' >
< / td >
< / tr >
2015-03-22 13:59:05 +00:00
< tr id = "user-extra-template" class = "if_inactive" >
< td colspan = "3" style = "border: 0; padding-top: 0" >
< div class = 'restore_info' style = 'color: #888; font-size: 90%' > To restore account, create a new account with this email address. Or to permanently delete the mailbox, delete the directory < tt > < / tt > on the machine.< / div >
2014-08-17 22:43:57 +00:00
< / td >
< / tr >
< / table >
< / div >
< script >
function show_users() {
$('#user_table tbody').html("< tr > < td colspan = '2' class = 'text-muted' > Loading...< / td > < / tr > ")
api(
"/mail/users",
"GET",
{ format: 'json' },
function(r) {
$('#user_table tbody').html("");
for (var i = 0; i < r.length ; i + + ) {
2015-03-22 13:59:05 +00:00
var hdr = $("< tr > < td colspan = '3' > < h4 / > < / td > < / tr > ");
2014-10-07 19:28:07 +00:00
hdr.find('h4').text(r[i].domain);
$('#user_table tbody').append(hdr);
2014-08-17 22:43:57 +00:00
2014-10-07 19:28:07 +00:00
for (var k = 0; k < r [ i ] . users . length ; k + + ) {
var user = r[i].users[k];
2014-09-03 10:17:46 +00:00
2014-10-07 19:28:07 +00:00
var n = $("#user-template").clone();
2014-10-07 20:24:11 +00:00
var n2 = $("#user-extra-template").clone();
2014-10-07 19:28:07 +00:00
n.attr('id', '');
2014-10-07 20:24:11 +00:00
n2.attr('id', '');
$('#user_table tbody').append(n);
$('#user_table tbody').append(n2);
2014-08-17 22:43:57 +00:00
2014-10-07 19:28:07 +00:00
n.addClass("account_" + user.status);
2014-10-07 20:24:11 +00:00
n2.addClass("account_" + user.status);
2014-10-07 19:28:07 +00:00
n.attr('data-email', user.email);
2014-10-07 20:24:11 +00:00
n.find('.address').text(user.email)
n.find('.mailboxsize').text(nice_size(user.mailbox_size))
n2.find('.restore_info tt').text(user.mailbox);
2014-08-17 22:43:57 +00:00
2014-10-07 19:28:07 +00:00
if (user.status == 'inactive') continue;
2014-08-17 22:43:57 +00:00
2014-10-07 19:28:07 +00:00
var add_privs = ["admin"];
for (var j = 0; j < user.privileges.length ; j + + ) {
var p = $("< span > < b > < span class = 'name' > < / span > < / b > (< a href = '#' onclick = 'mod_priv(this, \"remove\"); return false;' title = 'Remove Privilege' > remove privilege< / a > ) |< / span > ");
p.find('span.name').text(user.privileges[j]);
n.find('.privs').append(p);
if (add_privs.indexOf(user.privileges[j]) >= 0)
add_privs.splice(add_privs.indexOf(user.privileges[j]), 1);
}
for (var j = 0; j < add_privs.length ; j + + ) {
var p = $("< span > < a href = '#' onclick = 'mod_priv(this, \"add\"); return false;' title = 'Add Privilege' > make < span class = 'name' > < / span > < / a > | < / span > ");
p.find('span.name').text(add_privs[j]);
n.find('.add-privs').append(p);
}
2014-08-17 22:43:57 +00:00
}
}
})
}
function do_add_user() {
var email = $("#adduserEmail").val();
var pw = $("#adduserPassword").val();
var privs = $("#adduserPrivs").val();
api(
"/mail/users/add",
"POST",
{
email: email,
password: pw,
privileges: privs
},
function(r) {
// Responses are multiple lines of pre-formatted text.
show_modal_error("Add User", $("< pre / > ").text(r));
show_users()
},
function(r) {
show_modal_error("Add User", r);
});
return false;
}
2014-09-21 17:24:01 +00:00
function users_set_password(elem) {
var email = $(elem).parents('tr').attr('data-email');
show_modal_confirm(
"Archive User",
$("< p > Set a new password for < b > " + email + "< / b > ?< / p > < p > < label for = 'users_set_password_pw' style = 'display: block; font-weight: normal' > New Password:< / label > < input type = 'password' id = 'users_set_password_pw' > < / p > < p > < small > Passwords must be at least four characters and may not contain spaces.< / small > < / p > "),
"Set Password",
function() {
api(
"/mail/users/password",
"POST",
{
email: email,
password: $('#users_set_password_pw').val()
},
function(r) {
// Responses are multiple lines of pre-formatted text.
show_modal_error("Set Password", $("< pre / > ").text(r));
},
function(r) {
show_modal_error("Set Password", r);
});
});
}
2014-08-17 22:43:57 +00:00
function users_remove(elem) {
var email = $(elem).parents('tr').attr('data-email');
show_modal_confirm(
"Archive User",
2014-09-21 17:24:01 +00:00
$("< p > Are you sure you want to archive < b > " + email + "< / b > ?< / p > < p > The user's mailboxes will not be deleted (you can do that later), but the user will no longer be able to log into any services on this machine.< / p > "),
2014-08-17 22:43:57 +00:00
"Archive",
function() {
api(
"/mail/users/remove",
"POST",
{
email: email
},
function(r) {
// Responses are multiple lines of pre-formatted text.
show_modal_error("Remove User", $("< pre / > ").text(r));
show_users();
},
function(r) {
show_modal_error("Remove User", r);
});
});
}
function mod_priv(elem, add_remove) {
var email = $(elem).parents('tr').attr('data-email');
var priv = $(elem).parents('td').find('.name').text();
// can't remove your own admin access
if (priv == "admin" & & add_remove == "remove" & & api_credentials != null & & email == api_credentials[0]) {
show_modal_error("Modify Privileges", "You cannot remove the admin privilege from yourself.");
return;
}
var add_remove1 = add_remove.charAt(0).toUpperCase() + add_remove.substring(1);
show_modal_confirm(
"Modify Privileges",
2014-09-21 17:24:01 +00:00
"Are you sure you want to " + add_remove + " the " + priv + " privilege for < b > " + email + "< / b > ?",
2014-08-17 22:43:57 +00:00
add_remove1,
function() {
api(
"/mail/users/privileges/" + add_remove,
"POST",
{
email: email,
privilege: priv
},
function(r) {
show_users();
});
});
}
2014-09-03 10:17:46 +00:00
< / script >