mailinabox/management/templates/users.html

392 lines
14 KiB
HTML
Raw Normal View History

2014-08-17 22:43:57 +00:00
<h2>Users</h2>
<style>
#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; }
#user_table .account_active.if_inactive { display: none; }
.row-center { text-align: center; }
2014-08-17 22:43:57 +00:00
</style>
<h3>Add a mail user</h3>
<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>
<div class="form-group">
<label class="sr-only" for="adduserQuota">Quota</label>
<input type="text" class="form-control" id="adduserQuota" placeholder="Quota" style="width:5em;">
</div>
2014-08-17 22:43:57 +00:00
<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 consisting of English letters and numbers only. For best results, <a href="#" onclick="return generate_random_password()">generate a random password</a>.</li>
<li>Use <a href="#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="#aliases">aliases</a> can.</li>
<li>Quotas may not contain any spaces, commas or decimal points. Suffixes of G (gigabytes) and M (megabytes) are allowed. For unlimited storage enter 0 (zero)</li>
</ul>
2014-08-17 22:43:57 +00:00
<h3>Existing mail users</h3>
<table id="user_table" class="table" style="width: auto">
<thead>
<tr>
<th width="35%">Email Address</th>
<th class="row-center">Messages</th>
<th class="row-center">Size</th>
<th class="row-center">Used</th>
<th class="row-center">Quota</th>
<th>Actions</th>
</tr>
</thead>
2014-08-17 22:43:57 +00:00
<tbody>
</tbody>
</table>
<div style="display: none">
<table>
<tr id="user-template">
<td class='address'>
</td>
<td class="box-count row-center"></td>
<td class="box-size row-center"></td>
<td class="percent row-center"></td>
<td class="quota row-center">
2019-01-28 14:19:36 +00:00
</td>
<td class='actions'>
2014-09-21 17:06:38 +00:00
<span class='privs'>
</span>
<span class="if_active">
<a href="#" onclick="users_set_quota(this); return false;" class='setquota' title="Set Quota">
set quota
</a>
|
</span>
<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>
</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>
2014-08-17 22:43:57 +00:00
</td>
</tr>
</table>
</div>
<h3>Mail user API (advanced)</h3>
2016-06-29 11:35:42 +00:00
<p>Use your box&rsquo;s mail user API to add/change/remove users from the command-line or custom services you build.</p>
2016-06-29 11:35:42 +00:00
<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>
2016-06-29 11:35:42 +00:00
<p>Brackets denote an optional argument. Please note that the POST body <code>parameters</code> must be URL-encoded.</p>
2016-06-29 11:35:42 +00:00
<p>The email and password given to the <code>--user</code> option must be an administrative user on this system.</p>
2016-06-29 11:35:42 +00:00
<h4 style="margin-bottom: 0">Verbs</h4>
<table class="table" style="margin-top: .5em">
2016-06-29 11:35:42 +00:00
<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>
2019-10-04 15:32:50 +00:00
<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>. Optional parameters: <code>privilege=admin</code> and <code>quota</code></td>
</tr>
v0.45 (May 16, 2020) Security fixes: * Fix missing brute force login protection for Roundcube logins. Software updates: * Upgraded Roundcube from 1.4.2 to 1.4.4. * Upgraded Nextcloud from 17.0.2 to 17.0.6 (with Contacts from 3.1.6 to 3.3.0 and Calendar from 1.7.1 to v2.0.3) * Upgraded Z-Push to 2.5.2. System: * Nightly backups now occur on a random minute in the 3am hour (in the system time zone). The minute is chosen during Mail-in-a-Box installation/upgrade and remains the same until the next upgrade. * Fix for mail log statistics report on leap days. * Fix Mozilla autoconfig useGlobalPreferredServer setting. Web: * Add a new hidden feature to set nginx alias in www/custom.yaml. Setup: * Improved error handling. -----BEGIN PGP SIGNATURE----- iQFDBAABCgAtFiEEX0wOcxPM10RpOyrquSBB9MEL3YEFAl7AbCoPHGp0QG9jY2Ft cy5pbmZvAAoJELkgQfTBC92BjbEIAIwmIpgNCT+age/SsUhDY8pjnFQWXBCl1nwa RFN40Ev73DoBXUP+za4RE0eyCLIw5/laCwCjaESobiBTuc6boC1QU4abFUV5NfJQ P3AnQ2qXkrtcmIQX42ge4AGsL3vMVRtjZWb+bvut2SmLB8BI5w/9XsQAS59lqSz0 kK6ShlDmFaToMgTQqwl0CW8a0vdjRca5Mq011xUZrvqTAm7ACQIvS6np4UYBGSNy bU8O1xWMJb0HlO7f+bWCDYr1I+nRS1xXMW9pKsE08YFwcRLa+C42QkDXDuS/o/zj EXBLGwYcB0DEu4wLLbih8xdbED2ZiMO2t6IHtbXPcoLtHo3Tv6I= =RUkr -----END PGP SIGNATURE----- Merge tag 'v0.45' of https://github.com/mail-in-a-box/mailinabox v0.45 (May 16, 2020) Security fixes: * Fix missing brute force login protection for Roundcube logins. Software updates: * Upgraded Roundcube from 1.4.2 to 1.4.4. * Upgraded Nextcloud from 17.0.2 to 17.0.6 (with Contacts from 3.1.6 to 3.3.0 and Calendar from 1.7.1 to v2.0.3) * Upgraded Z-Push to 2.5.2. System: * Nightly backups now occur on a random minute in the 3am hour (in the system time zone). The minute is chosen during Mail-in-a-Box installation/upgrade and remains the same until the next upgrade. * Fix for mail log statistics report on leap days. * Fix Mozilla autoconfig useGlobalPreferredServer setting. Web: * Add a new hidden feature to set nginx alias in www/custom.yaml. Setup: * Improved error handling.
2020-05-17 16:17:44 +00:00
<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>
2019-10-04 15:32:50 +00:00
<tr>
<td>GET</td>
<td>/quota</td>
<td>Get the quota for a mail user. Required POST-body parameters are <code>email</code> and will return JSON result</td>
</tr>
<tr>
<td>POST</td>
<td>/quota</td>
<td>Set the quota for a mail user. Required POST-body parameters are <code>email</code> and <code>quota</code>.</td>
</tr>
2016-06-29 11:35:42 +00:00
</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>
2016-06-29 11:35:42 +00:00
<pre># Gives a JSON-encoded list of all mail users
2016-06-29 11:35:42 +00:00
curl -X GET https://{{hostname}}/admin/mail/users?format=json
# Adds a new email user
2016-06-29 11:35:42 +00:00
curl -X POST -d "email=new_user@mydomail.com" -d "password=s3curE_pa5Sw0rD" https://{{hostname}}/admin/mail/users/add
# Removes a email user
2016-06-29 11:35:42 +00:00
curl -X POST -d "email=new_user@mydomail.com" https://{{hostname}}/admin/mail/users/remove
# Adds admin privilege to an email user
2016-06-29 11:35:42 +00:00
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
2016-06-29 11:35:42 +00:00
curl -X POST -d "email=new_user@mydomail.com" https://{{hostname}}/admin/mail/users/privileges/remove
</pre>
2014-08-17 22:43:57 +00:00
<script>
function show_users() {
api(
"/system/default-quota",
"GET",
{},
function(r) {
$('#adduserQuota').val(r['default-quota']);
}
);
2014-08-17 22:43:57 +00:00
$('#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><th colspan='6' style='background-color: #EEE'></th></tr>");
hdr.find('th').text(r[i].domain);
$('#user_table tbody').append(hdr);
2014-08-17 22:43:57 +00:00
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);
2014-08-17 22:43:57 +00:00
n.addClass("account_" + user.status);
n2.addClass("account_" + user.status);
n.attr('data-email', user.email);
n.attr('data-quota', user.quota);
2019-01-28 14:19:36 +00:00
n.find('.address').text(user.email);
n.find('.box-count').text((user.box_count).toLocaleString('en'));
if (user.box_count == '?') {
n.find('.box-count').attr('title', 'Message count is unkown')
}
n.find('.box-size').text(user.box_size);
if (user.box_size == '?') {
n.find('.box-size').attr('title', 'Mailbox size is unkown')
}
n.find('.percent').text(user.percent);
n.find('.quota').text((user.quota == '0') ? 'unlimited' : user.quota);
n2.find('.restore_info tt').text(user.mailbox);
2014-08-17 22:43:57 +00:00
if (user.status == 'inactive') continue;
2014-08-17 22:43:57 +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();
var quota = $("#adduserQuota").val();
2014-08-17 22:43:57 +00:00
api(
"/mail/users/add",
"POST",
{
email: email,
password: pw,
privileges: privs,
quota: quota
2014-08-17 22:43:57 +00:00
},
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.username)
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(
2016-05-17 23:46:10 +00:00
"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_set_quota(elem) {
var email = $(elem).parents('tr').attr('data-email');
var quota = $(elem).parents('tr').attr('data-quota');
show_modal_confirm(
"Set Quota",
$("<p>Set quota for <b>" + email + "</b>?</p>" +
"<p>" +
"<label for='users_set_quota' style='display: block; font-weight: normal'>Quota:</label>" +
"<input type='text' id='users_set_quota' value='" + quota + "'></p>" +
2019-01-31 23:35:55 +00:00
"<p><small>Quotas may not contain any spaces or commas. Suffixes of G (gigabytes) and M (megabytes) are allowed.</small></p>" +
"<p><small>For unlimited storage enter 0 (zero)</small></p>"),
"Set Quota",
function() {
api(
"/mail/users/quota",
"POST",
{
email: email,
quota: $('#users_set_quota').val()
},
function(r) {
show_users();
},
function(r) {
show_modal_error("Set Quota", r);
});
});
}
2014-08-17 22:43:57 +00:00
function users_remove(elem) {
var email = $(elem).parents('tr').attr('data-email');
// can't remove yourself
if (api_credentials != null && email == api_credentials.username) {
show_modal_error("Archive User", "You cannot archive your own account.");
return;
}
2014-08-17 22:43:57 +00:00
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>"),
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.username) {
2014-08-17 22:43:57 +00:00
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>"),
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();
});
});
}
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></p>");
return false; // cancel click
}
</script>