fe597da7aa
Passwords must be eight characters long; when passwords are changed via the users page the dialog states that passwords need to be at least four characters but only eight or more are acceptable.
304 lines
11 KiB
HTML
304 lines
11 KiB
HTML
<h2>Users</h2>
|
|
|
|
<style>
|
|
#user_table h4 { margin: 1em 0 0 0; }
|
|
#user_table tr.account_inactive td.address { color: #888; text-decoration: line-through; }
|
|
#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; }
|
|
#user_table .account_active.if_inactive { display: none; }
|
|
</style>
|
|
|
|
<h3>Add a mail user</h3>
|
|
|
|
<p>Add an email address to this system. This will create a new login username/password.</p>
|
|
|
|
<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>
|
|
<ul style="margin-top: 1em; padding-left: 1.5em; font-size: 90%;">
|
|
<li>Passwords must be at least eight characters and may not contain spaces. For best results, <a href="#" onclick="return generate_random_password()">generate a random password</a>.</li>
|
|
<li>Use <a href="#" onclick="return 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="#" onclick="return show_panel('aliases');">aliases</a> can.</li>
|
|
</ul>
|
|
|
|
<h3>Existing mail users</h3>
|
|
<table id="user_table" class="table" style="width: auto">
|
|
<thead>
|
|
<tr>
|
|
<th width="50%">Email Address</th>
|
|
<th>Actions</th>
|
|
<th>Mailbox Size</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
</tbody>
|
|
</table>
|
|
|
|
<div style="display: none">
|
|
<table>
|
|
<tr id="user-template">
|
|
<td class='address'>
|
|
</td>
|
|
<td class='actions'>
|
|
<span class='privs'>
|
|
</span>
|
|
|
|
<span class="if_active">
|
|
<a href="#" onclick="users_set_password(this); return false;" class='setpw' title="Set Password">
|
|
set password
|
|
</a>
|
|
|
|
|
</span>
|
|
|
|
<span class='add-privs'>
|
|
</span>
|
|
|
|
<a href="#" onclick="users_remove(this); return false;" class='if_active' title="Archive Account">
|
|
archive account
|
|
</a>
|
|
</td>
|
|
<td class='mailboxsize'>
|
|
</td>
|
|
</tr>
|
|
<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>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
|
|
<h3>Mail user API (advanced)</h3>
|
|
|
|
<p>Use your box’s mail user API to add/change/remove users from the command-line or custom services you build.</p>
|
|
|
|
<p>Usage:</p>
|
|
|
|
<pre>curl -X <b>VERB</b> [-d "<b>parameters</b>"] --user {email}:{password} https://{{hostname}}/admin/mail/users[<b>action</b>]</pre>
|
|
|
|
<p>Brackets denote an optional argument. Please note that the POST body <code>parameters</code> must be URL-encoded.</p>
|
|
|
|
<p>The email and password given to the <code>--user</code> option must be an administrative user on this system.</p>
|
|
|
|
<h4 style="margin-bottom: 0">Verbs</h4>
|
|
|
|
<table class="table" style="margin-top: .5em">
|
|
<thead><th>Verb</th> <th>Action</th><th></th></thead>
|
|
<tr><td>GET</td><td><i>(none)</i></td> <td>Returns a list of existing mail users. Adding <code>?format=json</code> to the URL will give JSON-encoded results.</td></tr>
|
|
<tr><td>POST</td><td>/add</td> <td>Adds a new mail user. Required POST-body parameters are <code>email</code> and <code>password</code>.</td></tr>
|
|
<tr><td>POST</td><td>/remove</td> <td>Removes a mail user. Required POST-by parameter is <code>email</code>.</td></tr>
|
|
<tr><td>POST</td><td>/privileges/add</td> <td>Used to make a mail user an admin. Required POST-body parameters are <code>email</code> and <code>privilege=admin</code>.</td></tr>
|
|
<tr><td>POST</td><td>/privileges/remove</td> <td>Used to remove the admin privilege from a mail user. Required POST-body parameter is <code>email</code>.</td></tr>
|
|
</table>
|
|
|
|
<h4>Examples:</h4>
|
|
|
|
<p>Try these examples. For simplicity the examples omit the <code>--user me@mydomain.com:yourpassword</code> command line argument which you must fill in with your administrative email address and password.</p>
|
|
|
|
<pre># Gives a JSON-encoded list of all mail users
|
|
curl -X GET https://{{hostname}}/admin/mail/users?format=json
|
|
|
|
# Adds a new email user
|
|
curl -X POST -d "email=new_user@mydomail.com" -d "password=s3curE_pa5Sw0rD" https://{{hostname}}/admin/mail/users/add
|
|
|
|
# Removes a email user
|
|
curl -X POST -d "email=new_user@mydomail.com" https://{{hostname}}/admin/mail/users/remove
|
|
|
|
# Adds admin privilege to an email user
|
|
curl -X POST -d "email=new_user@mydomail.com" -d "privilege=admin" https://{{hostname}}/admin/mail/users/privileges/add
|
|
|
|
# Removes admin privilege from an email user
|
|
curl -X POST -d "email=new_user@mydomail.com" https://{{hostname}}/admin/mail/users/privileges/remove
|
|
</pre>
|
|
|
|
<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++) {
|
|
var hdr = $("<tr><td colspan='3'><h4/></td></tr>");
|
|
hdr.find('h4').text(r[i].domain);
|
|
$('#user_table tbody').append(hdr);
|
|
|
|
for (var k = 0; k < r[i].users.length; k++) {
|
|
var user = r[i].users[k];
|
|
|
|
var n = $("#user-template").clone();
|
|
var n2 = $("#user-extra-template").clone();
|
|
n.attr('id', '');
|
|
n2.attr('id', '');
|
|
$('#user_table tbody').append(n);
|
|
$('#user_table tbody').append(n2);
|
|
|
|
n.addClass("account_" + user.status);
|
|
n2.addClass("account_" + user.status);
|
|
|
|
n.attr('data-email', user.email);
|
|
n.find('.address').text(user.email)
|
|
n.find('.mailboxsize').text(nice_size(user.mailbox_size))
|
|
n2.find('.restore_info tt').text(user.mailbox);
|
|
|
|
if (user.status == 'inactive') continue;
|
|
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
function users_set_password(elem) {
|
|
var email = $(elem).parents('tr').attr('data-email');
|
|
|
|
var yourpw = "";
|
|
if (api_credentials != null && email == api_credentials[0])
|
|
yourpw = "<p class='text-danger'>If you change your own password, you will be logged out of this control panel and will need to log in again.</p>";
|
|
|
|
show_modal_confirm(
|
|
"Set Password",
|
|
$("<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 eight characters and may not contain spaces.</small>" + yourpw + "</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);
|
|
});
|
|
});
|
|
}
|
|
|
|
function users_remove(elem) {
|
|
var email = $(elem).parents('tr').attr('data-email');
|
|
|
|
// can't remove yourself
|
|
if (api_credentials != null && email == api_credentials[0]) {
|
|
show_modal_error("Archive User", "You cannot archive your own account.");
|
|
return;
|
|
}
|
|
|
|
show_modal_confirm(
|
|
"Archive User",
|
|
$("<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>"),
|
|
"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",
|
|
$("<p>Are you sure you want to " + add_remove + " the " + priv + " privilege for <b>" + email + "</b>?</p>"),
|
|
add_remove1,
|
|
function() {
|
|
api(
|
|
"/mail/users/privileges/" + add_remove,
|
|
"POST",
|
|
{
|
|
email: email,
|
|
privilege: priv
|
|
},
|
|
function(r) {
|
|
show_users();
|
|
});
|
|
});
|
|
}
|
|
|
|
function generate_random_password() {
|
|
var pw = "";
|
|
var charset = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789"; // confusable characters skipped
|
|
for (var i = 0; i < 12; i++)
|
|
pw += charset.charAt(Math.floor(Math.random() * charset.length));
|
|
show_modal_error("Random Password", "<p>Here, try this:</p> <p><code style='font-size: 110%'>" + pw + "</code></pr");
|
|
return false; // cancel click
|
|
}
|
|
</script>
|