1
0
mirror of https://github.com/mail-in-a-box/mailinabox.git synced 2026-03-15 17:37:22 +01:00

include changes from v0.53. Remove some POWER modifications to closer follow original mialinabox

This commit is contained in:
github@kiekerjan.isdronken.nl
2021-04-13 09:50:23 +02:00
parent 40adef2261
commit c24ca5abd4
39 changed files with 577 additions and 1063 deletions

View File

@@ -94,10 +94,10 @@
<tr id="alias-template">
<td class='actions'>
<a href="#" onclick="aliases_edit(this); scroll_top(); return false;" class='edit' title="Edit Alias">
<span class="fas fa-pen"></span>
<span class="glyphicon glyphicon-pencil"></span>
</a>
<a href="#" onclick="aliases_remove(this); return false;" class='remove' title="Remove Alias">
<span class="fas fa-trash"></span>
<span class="glyphicon glyphicon-trash"></span>
</a>
</td>
<td class='address'> </td>
@@ -153,8 +153,8 @@ function show_aliases() {
function(r) {
$('#alias_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);
var hdr = $("<tr><th colspan='4' style='background-color: #EEE'></th></tr>");
hdr.find('th').text(r[i].domain);
$('#alias_table tbody').append(hdr);
for (var k = 0; k < r[i].aliases.length; k++) {

View File

@@ -57,7 +57,13 @@
</div>
</form>
<table id="custom-dns-current" class="table" style="width: auto; display: none">
<div style="text-align: right; font-size; 90%; margin-top: 1em;">
sort by:
<a href="#" onclick="window.miab_custom_dns_data_sort_order='qname'; show_current_custom_dns_update_after_sort(); return false;">domain name</a>
|
<a href="#" onclick="window.miab_custom_dns_data_sort_order='created'; show_current_custom_dns_update_after_sort(); return false;">created</a>
</div>
<table id="custom-dns-current" class="table" style="width: auto; display: none; margin-top: 0;">
<thead>
<th>Domain Name</th>
<th>Record Type</th>
@@ -192,36 +198,38 @@ function show_current_custom_dns() {
$('#custom-dns-current').fadeIn();
else
$('#custom-dns-current').fadeOut();
var reverse_fqdn = function(el) {
el.qname = el.qname.split('.').reverse().join('.');
return el;
}
var sort = function(a, b) {
if(a.qname === b.qname) {
if(a.rtype === b.rtype) {
return a.value > b.value ? 1 : -1;
}
return a.rtype > b.rtype ? 1 : -1;
}
return a.qname > b.qname ? 1 : -1;
}
window.miab_custom_dns_data = data;
show_current_custom_dns_update_after_sort();
});
}
data = data.map(reverse_fqdn).sort(sort).map(reverse_fqdn);
function show_current_custom_dns_update_after_sort() {
var data = window.miab_custom_dns_data;
var sort_key = window.miab_custom_dns_data_sort_order || "qname";
$('#custom-dns-current').find("tbody").text('');
data.sort(function(a, b) { return a["sort-order"][sort_key] - b["sort-order"][sort_key] });
var tbody = $('#custom-dns-current').find("tbody");
tbody.text('');
var last_zone = null;
for (var i = 0; i < data.length; i++) {
if (sort_key == "qname" && data[i].zone != last_zone) {
var r = $("<tr><th colspan=4 style='background-color: #EEE'></th></tr>");
r.find("th").text(data[i].zone);
tbody.append(r);
last_zone = data[i].zone;
}
var tr = $("<tr/>");
$('#custom-dns-current').find("tbody").append(tr);
tbody.append(tr);
tr.attr('data-qname', data[i].qname);
tr.attr('data-rtype', data[i].rtype);
tr.attr('data-value', data[i].value);
tr.append($('<td class="long"/>').text(data[i].qname));
tr.append($('<td/>').text(data[i].rtype));
tr.append($('<td class="long"/>').text(data[i].value));
tr.append($('<td class="long" style="max-width: 40em"/>').text(data[i].value));
tr.append($('<td>[<a href="#" onclick="return delete_custom_dns_record(this)">delete</a>]</td>'));
}
});
}
function delete_custom_dns_record(elem) {

View File

@@ -36,7 +36,7 @@
<p class="alert" role="alert">
<span class="fas fa-info-circle"></span>
<span class="glyphicon glyphicon-info-sign"></span>
You may encounter zone file errors when attempting to create a TXT record with a long string.
<a href="http://tools.ietf.org/html/rfc4408#section-3.1.3">RFC 4408</a> states a TXT record is allowed to contain multiple strings, and this technique can be used to construct records that would exceed the 255-byte maximum length.
You may need to adopt this technique when adding DomainKeys. Use a tool like <code>named-checkzone</code> to validate your zone file.
@@ -50,7 +50,7 @@
<label for="downloadZonefile" class="control-label sr-only">Zone</label>
<select id="downloadZonefile" class="form-control" style="width: auto"> </select>
</div>
<button type="submit" style="margin-left: 20px" class="btn btn-primary">Download</button>
<button type="submit" class="btn btn-primary">Download</button>
</div>
</form>

View File

@@ -9,10 +9,7 @@
<meta name="robots" content="noindex, nofollow">
<link rel="stylesheet" href="/admin/assets/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="/admin/assets/fontawesome/css/fontawesome.min.css">
<link rel="stylesheet" href="/admin/assets/fontawesome/css/solid.min.css">
<link rel="stylesheet" href="/admin/assets/bootstrap/css/bootstrap.min.css">
<style>
body {
overflow-y: scroll;
@@ -66,6 +63,7 @@
margin-bottom: 1em;
}
</style>
<link rel="stylesheet" href="/admin/assets/bootstrap/css/bootstrap-theme.min.css">
</head>
<body>
@@ -73,52 +71,53 @@
<!--[if gt IE 7]><!-->
<div class="navbar navbar-inverse navbar-static-top" role="navigation">
<div class="container bg-light">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">{{hostname}}</a>
</div>
<div class="navbar navbar-expand-lg">
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="btn dropdown">
<a style="color: black;" href="#" class="dropdown-toggle" data-toggle="dropdown">System <b class="caret"></b></a>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">System <b class="caret"></b></a>
<ul class="dropdown-menu">
<li class="dropdown-item"><a href="#system_status" onclick="return show_panel(this);">Status Checks</a></li>
<li class="dropdown-item"><a href="#tls" onclick="return show_panel(this);">TLS (SSL) Certificates</a></li>
<li class="dropdown-item"><a href="#system_backup" onclick="return show_panel(this);">Backup Status</a></li>
<li class="dropdown-item"><a href="#smtp_relays" onclick="return show_panel(this);">SMTP Relays</a></li>
<li><a href="#system_status" onclick="return show_panel(this);">Status Checks</a></li>
<li><a href="#tls" onclick="return show_panel(this);">TLS (SSL) Certificates</a></li>
<li><a href="#system_backup" onclick="return show_panel(this);">Backup Status</a></li>
<li class="divider"></li>
<li class="dropdown-header">Advanced Pages</li>
<li class="dropdown-item"><a href="#custom_dns" onclick="return show_panel(this);">Custom DNS</a></li>
<li class="dropdown-item"><a href="#external_dns" onclick="return show_panel(this);">External DNS</a></li>
<li class="dropdown-item"><a href="/admin/munin" target="_blank">Munin Monitoring</a></li>
<li><a href="#custom_dns" onclick="return show_panel(this);">Custom DNS</a></li>
<li><a href="#external_dns" onclick="return show_panel(this);">External DNS</a></li>
<li><a href="/admin/munin" target="_blank">Munin Monitoring</a></li>
</ul>
</li>
<li class="btn dropdown">
<a style="color: black;" href="#" class="dropdown-toggle" data-toggle="dropdown">Mail &amp; Users <b class="caret"></b></a>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Mail &amp; Users <b class="caret"></b></a>
<ul class="dropdown-menu">
<li class="dropdown-item"><a href="#mail-guide" onclick="return show_panel(this);">Instructions</a></li>
<li class="dropdown-item"><a href="#users" onclick="return show_panel(this);">Users</a></li>
<li class="dropdown-item"><a href="#aliases" onclick="return show_panel(this);">Aliases</a></li>
<li><a href="#mail-guide" onclick="return show_panel(this);">Instructions</a></li>
<li><a href="#users" onclick="return show_panel(this);">Users</a></li>
<li><a href="#aliases" onclick="return show_panel(this);">Aliases</a></li>
<li class="divider"></li>
<li class="dropdown-header">Your Account</li>
<li class="dropdown-item"><a href="#mfa" onclick="return show_panel(this);">Two-Factor Authentication</a></li>
<li><a href="#mfa" onclick="return show_panel(this);">Two-Factor Authentication</a></li>
</ul>
</li>
<li class="btn"><a style="color: black;" href="#sync_guide" onclick="return show_panel(this);">Contacts/Calendar</a></li>
<li class="btn"><a style="color: black;" href="#web" onclick="return show_panel(this);">Web</a></li>
<li><a href="#sync_guide" onclick="return show_panel(this);">Contacts/Calendar</a></li>
<li><a href="#web" onclick="return show_panel(this);">Web</a></li>
</ul>
<ul class="btn nav navbar-nav navbar-right">
<li><a href="#" onclick="do_logout(); return false;" style="color: black; font-weight: bold;">Log out</a></li>
<ul class="nav navbar-nav navbar-right">
<li><a href="#" onclick="do_logout(); return false;" style="color: white">Log out</a></li>
</ul>
</div><!--/.navbar-collapse -->
</div>
</div>
<div class="container">
<div id="panel_smtp_relays" class="admin_panel">
{% include "smtp-relays.html" %}
</div>
<div id="panel_system_status" class="admin_panel">
{% include "system-status.html" %}
</div>
@@ -170,7 +169,7 @@
<hr>
<footer>
<p>This is a <a href="https://github.com/ddavness/power-mailinabox">Power Mail-in-a-Box</a> - {{distname}}</p>
<p>This is a <a href="https://mailinabox.email">Mail-in-a-Box</a>.</p>
</footer>
</div> <!-- /container -->
@@ -185,8 +184,8 @@
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="errorModalTitle"> </h4>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title" id="errorModalTitle"> </h4>
</div>
<div class="modal-body">
<p> </p>

View File

@@ -51,19 +51,19 @@ sudo management/cli.py user make-admin me@{{hostname}}</pre>
<form id="loginForm" class="form-horizontal" role="form" onsubmit="do_login(); return false;" method="get">
<div class="form-group">
<label for="inputEmail3" class="col-sm-3 control-label">Email</label>
<div class="col-sm-12">
<div class="col-sm-9">
<input name="email" type="email" class="form-control" id="loginEmail" placeholder="Email">
</div>
</div>
<div class="form-group">
<label for="inputPassword3" class="col-sm-3 control-label">Password</label>
<div class="col-sm-12">
<div class="col-sm-9">
<input name="password" type="password" class="form-control" id="loginPassword" placeholder="Password">
</div>
</div>
<div class="form-group" id="loginOtp">
<label for="loginOtpInput" class="col-sm-3 control-label">Code</label>
<div class="col-sm-12">
<div class="col-sm-9">
<input type="text" class="form-control" id="loginOtpInput" placeholder="6-digit code">
<div class="help-block" style="margin-top: 5px; font-size: 90%">Enter the six-digit code generated by your two factor authentication app.</div>
</div>

View File

@@ -36,11 +36,11 @@
<p>When two-factor authentication is enabled, you will be prompted to enter a six digit code from an
authenticator app (usually on your phone) when you log into this control panel.</p>
<div class="card">
<div class="card-header text-white bg-danger">
<div class="panel panel-danger">
<div class="panel-heading">
Enabling two-factor authentication does not protect access to your email
</div>
<div class="card-body bg-light">
<div class="panel-body">
Enabling two-factor authentication on this page only limits access to this control panel. Remember that most websites allow you to
reset your password by checking your email, so anyone with access to your email can typically take over
your other accounts. Additionally, if your email address or any alias that forwards to your email
@@ -81,7 +81,7 @@ and ensure every administrator account for this control panel does the same.</st
<div class="form-group">
<p>When you click Enable Two-Factor Authentication, you will be logged out of the control panel and will have to log in
again, now using your two-factor authentication app.</p>
<button id="totp-setup-submit" disabled type="submit" class="btn btn-primary">Enable Two-Factor Authentication</button>
<button id="totp-setup-submit" disabled type="submit" class="btn">Enable Two-Factor Authentication</button>
</div>
</form>
@@ -95,8 +95,8 @@ and ensure every administrator account for this control panel does the same.</st
</div>
</form>
<div id="output-2fa" class="card bg-light">
<div class="card-body"></div>
<div id="output-2fa" class="panel panel-danger">
<div class="panel-body"></div>
</div>
</div>
@@ -155,12 +155,12 @@ and ensure every administrator account for this control panel does the same.</st
}
function hide_error() {
el.output.querySelector('.card-body').innerHTML = '';
el.output.querySelector('.panel-body').innerHTML = '';
el.output.classList.remove('visible');
}
function render_error(msg) {
el.output.querySelector('.card-body').innerHTML = msg;
el.output.querySelector('.panel-body').innerHTML = msg;
el.output.classList.add('visible');
}

View File

@@ -1,135 +0,0 @@
<style>
</style>
<h2>SMTP Relays</h2>
<p>SMTP Relays are third-party services you can hand off the responsability of getting the mail delivered. They
can be useful when, for example, port 25 is blocked.</p>
<p>Here, you can configure an authenticated SMTP relay (for example, <a href="https://sendgrid.com/"
target="_blank">SendGrid</a>) over port 587.</p>
<div id="smtp_relay_config">
<h3>SMTP Relay Configuration</h3>
<form class="form-horizontal" role="form" onsubmit="set_smtp_relay_config(); return false;">
<div class="form-group">
<table id="smtp-relays" class="table" style="width: 600px">
<tr>
<td>
<label for="use_relay" class="col-sm-1 control-label">Use Relay?</label>
</td>
<td>
<div class="col-sm-10">
<input type="checkbox" id="use_relay" name="use_relay" value="true"
onclick="checkfields();">
</div>
</td>
</tr>
<tr>
<td>
<label for="relay_host" class="col-sm-1 control-label">Hostname</label>
</td>
<td>
<div class="col-sm-10">
<input type="text" class="form-control" id="relay_host" placeholder="host.domain.tld">
</div>
</td>
<td style="padding: 0; font-weight: bold;">:587</td>
</tr>
<tr>
<td>
<label for="relay_use_auth" class="col-sm-1 control-label">Authenticate</label>
</td>
<td>
<div class="col-sm-10">
<input checked type="checkbox" id="relay_use_auth" name="relay_use_auth" value="true"
onclick="checkfields();">
</div>
</td>
</tr>
<tr>
<td>
<label for="relay_auth_user" class="col-sm-1 control-label">Username</label>
</td>
<td>
<div class="col-sm-10">
<input type="text" class="form-control" id="relay_auth_user" placeholder="user">
</div>
</td>
</tr>
<tr>
<td>
<label for="relay_auth_pass" class="col-sm-1 control-label">Password/Key</label>
</td>
<td>
<div class="col-sm-10">
<input type="password" class="form-control" id="relay_auth_pass" placeholder="password">
</div>
</td>
</tr>
</table>
</div>
<div>
<button type="submit" class="btn btn-primary">Update</button>
</div>
</form>
</div>
<script>
const use_relay = document.getElementById("use_relay")
const relay_host = document.getElementById("relay_host")
const relay_use_auth = document.getElementById("relay_use_auth")
const relay_auth_user = document.getElementById("relay_auth_user")
const relay_auth_pass = document.getElementById("relay_auth_pass")
function checkfields() {
let relay_enabled = use_relay.checked
let auth_enabled = relay_use_auth.checked
relay_host.disabled = !relay_enabled
relay_use_auth.disabled = !relay_enabled
relay_auth_user.disabled = !(relay_enabled && auth_enabled)
relay_auth_pass.disabled = !(relay_enabled && auth_enabled)
}
function show_smtp_relays() {
api(
"/system/smtp/relay",
"GET",
{},
data => {
use_relay.checked = data.enabled
relay_host.value = data.host
relay_use_auth.checked = data.auth_enabled
relay_auth_user.value = data.user
relay_auth_pass.value = ""
checkfields()
}
)
}
function set_smtp_relay_config() {
api(
"/system/smtp/relay",
"POST",
{
enabled: use_relay.checked,
host: relay_host.value,
auth_enabled: relay_use_auth.checked,
user: relay_auth_user.value,
key: relay_auth_pass.value
},
() => {
show_modal_error("Done!", "The configuration has been updated and Postfix was restarted successfully. Please make sure everything is functioning as intended.", () => {
return false
})
}
)
}
</script>

View File

@@ -12,7 +12,6 @@
<div id="ssl_provision_p" style="display: none; margin-top: 1.5em">
<button onclick='return provision_tls_cert();' class='btn btn-primary' style="float: left; margin: 0 1.5em 1em 0;">Provision</button>
<p><b>By provisioning the certificates, you&rsquo;re agreeing to the <a href="https://acme-v01.api.letsencrypt.org/terms">Let&rsquo;s Encrypt Subscriber Agreement</a>.</b></p>
<p>A TLS certificate can be automatically provisioned from <a href="https://letsencrypt.org/" target="_blank">Let&rsquo;s Encrypt</a>, a free TLS certificate provider, for:<br>
<span class="text-primary"></span></p>
</div>

View File

@@ -12,12 +12,13 @@
<form class="form-horizontal" role="form" onsubmit="set_custom_backup(); return false;">
<div class="form-group">
<label for="backup-target-type" class="col-sm-2 control-label">Backup to:</label>
<div class="col-sm-3">
<div class="col-sm-2">
<select class="form-control" rows="1" id="backup-target-type" onchange="toggle_form()">
<option value="off">Nowhere (Disable Backups)</option>
<option value="local">{{hostname}}</option>
<option value="rsync">rsync</option>
<option value="s3">Amazon S3</option>
<option value="b2">Backblaze B2</option>
</select>
</div>
</div>
@@ -165,11 +166,6 @@
<tbody>
</tbody>
</table>
<!-- Hide these buttons until we're sure we can use them :) -->
<button id="create-full-backup-button" class="btn btn-primary" onclick="do_backup(true)" style="display: none;">Create Full Backup Now</button>
<button id="create-incremental-backup-button" class="btn btn-primary" onclick="do_backup(false)" style="display: none;">Create Incremental Backup Now</button>
<script>
function toggle_form() {
@@ -216,17 +212,12 @@ function show_system_backup() {
if (typeof r.backups == "undefined") {
var tr = $('<tr><td colspan="3">Backups are turned off.</td></tr>');
$('#backup-status tbody').append(tr);
$('#create-full-backup-button').css("display","none")
$('#create-incremental-backup-button').css("display","none")
return;
} else if (r.backups.length == 0) {
var tr = $('<tr><td colspan="3">No backups have been made yet.</td></tr>');
$('#backup-status tbody').append(tr);
}
// Backups ARE enabled.
$('#create-full-backup-button').css("display","unset")
$('#create-incremental-backup-button').css("display","unset")
for (var i = 0; i < r.backups.length; i++) {
var b = r.backups[i];
var tr = $('<tr/>');
@@ -352,29 +343,4 @@ function init_inputs(target_type) {
set_host($('#backup-target-s3-host-select').val());
}
}
function do_backup(is_full) {
let disclaimer = "The backup process will pause some services (such as PHP, Postfix and Dovecot). Depending on the size of the data this can take a while."
if (!is_full) {
disclaimer += "\nDepending on the amount of incremental backups done after the last full backup, the box may decide to do a full backup instead."
}
show_modal_confirm("Warning!", disclaimer, "Start Backup", () => {
api(
"/system/backup/new",
"POST",
{
full: is_full
},
function(r) {
// use .text() --- it's a text response, not html
show_modal_error("Backup configuration", $("<p/>").text(r), function() { if (r == "OK") show_system_backup(); }); // refresh after modal on success
},
function(r) {
// use .text() --- it's a text response, not html
show_modal_error("Backup configuration", $("<p/>").text(r));
});
return false;
})
}
</script>
</script>

View File

@@ -1,168 +1,160 @@
<h2>System Status Checks</h2>
<style>
#system-checks .heading td {
font-weight: bold;
font-size: 120%;
padding-top: 1.5em;
}
#system-checks .heading.first td {
border-top: none;
padding-top: 0;
}
#system-checks .status-error td {
color: rgb(140, 0, 0);
}
#system-checks .status-warning td {
color: rgb(170, 120, 0);
}
#system-checks .status-ok td {
color: rgb(0, 140, 0);
}
#system-checks div.extra {
display: none;
margin-top: 1em;
max-width: 50em;
word-wrap: break-word;
}
#system-checks .showhide {
display: none;
font-size: 85%;
}
#system-checks .pre {
margin: 1em;
font-family: monospace;
white-space: pre-wrap;
}
#system-checks .heading td {
font-weight: bold;
font-size: 120%;
padding-top: 1.5em;
}
#system-checks .heading.first td {
border-top: none;
padding-top: 0;
}
#system-checks .status-error td {
color: #733;
}
#system-checks .status-warning td {
color: #770;
}
#system-checks .status-ok td {
color: #040;
}
#system-checks div.extra {
display: none;
margin-top: 1em;
max-width: 50em;
word-wrap: break-word;
}
#system-checks a.showhide {
display: none;
font-size: 85%;
}
#system-checks .pre {
margin: 1em;
font-family: monospace;
white-space: pre-wrap;
}
</style>
<div>
<div>
<div class="row">
<div class="col-md-push-9 col-md-3">
<div id="system-reboot-required" style="display: none; margin-bottom: 1em;">
<button type="button" class="btn btn-danger" onclick="confirm_reboot(); return false;">Reboot Box</button>
<div>No reboot is necessary.</div>
</div>
<div id="system-reboot-required" style="display: none; margin-bottom: 1em;">
<button type="button" class="btn btn-danger" onclick="confirm_reboot(); return false;">Reboot Box</button>
<div>No reboot is necessary.</div>
</div>
<div id="system-privacy-setting" style="display: none">
<div><a onclick="return enable_privacy(!current_privacy_setting)" href="#"><span>Enable/Disable</span>
New-Version Check</a></div>
<p style="line-height: 125%"><small>(When enabled, status checks phone-home to check for a new release of
Mail-in-a-Box.)</small></p>
</div>
<div id="system-privacy-setting" style="display: none">
<div><a onclick="return enable_privacy(!current_privacy_setting)" href="#"><span>Enable/Disable</span> New-Version Check</a></div>
<p style="line-height: 125%"><small>(When enabled, status checks phone-home to check for a new release of Mail-in-a-Box.)</small></p>
</div>
</div> <!-- /col -->
<br>
<div>
<div class="col-md-pull-3 col-md-8">
<table id="system-checks" class="table">
<thead></thead>
<tbody></tbody>
</table>
<table id="system-checks" class="table" style="max-width: 60em">
<thead>
</thead>
<tbody>
</tbody>
</table>
</div> <!-- /col -->
</div> <!-- /row -->
<script>
function show_system_status() {
$('#system-checks tbody').html("<tr><td class='text-muted'>Loading...</td></tr>")
function show_system_status() {
$('#system-checks tbody').html("<tr><td colspan='2' class='text-muted'>Loading...</td></tr>")
api(
"/system/privacy",
"GET",
{},
function (r) {
current_privacy_setting = r;
$('#system-privacy-setting').show();
$('#system-privacy-setting a span').text(r ? "Enable" : "Disable");
$('#system-privacy-setting p').toggle(r);
});
api(
"/system/privacy",
"GET",
{ },
function(r) {
current_privacy_setting = r;
$('#system-privacy-setting').show();
$('#system-privacy-setting a span').text(r ? "Enable" : "Disable");
$('#system-privacy-setting p').toggle(r);
});
api(
"/system/reboot",
"GET",
{},
function (r) {
$('#system-reboot-required').show(); // show when r becomes available
$('#system-reboot-required').find('button').toggle(r);
$('#system-reboot-required').find('div').toggle(!r);
});
api(
"/system/reboot",
"GET",
{ },
function(r) {
$('#system-reboot-required').show(); // show when r becomes available
$('#system-reboot-required').find('button').toggle(r);
$('#system-reboot-required').find('div').toggle(!r);
});
api(
"/system/status",
"POST",
{},
function (r) {
$('#system-checks tbody').html("");
for (var i = 0; i < r.length; i++) {
var n = $("<tr><td class='status'/><td class='message'><p style='margin: 0'/><p class='showhide btn btn-light' href='#'/><div class='extra'></div></tr>");
if (i == 0) n.addClass('first')
if (r[i].type == "heading")
n.addClass(r[i].type)
else
n.addClass("status-" + r[i].type)
if (r[i].type == "ok") n.find('td.status').text("✔️")
if (r[i].type == "error") n.find('td.status').text("")
if (r[i].type == "warning") n.find('td.status').text("⚠️")
n.find('td.message p').text(r[i].text)
$('#system-checks tbody').append(n);
api(
"/system/status",
"POST",
{ },
function(r) {
$('#system-checks tbody').html("");
for (var i = 0; i < r.length; i++) {
var n = $("<tr><td class='status'/><td class='message'><p style='margin: 0'/><div class='extra'/><a class='showhide' href='#'/></tr>");
if (i == 0) n.addClass('first')
if (r[i].type == "heading")
n.addClass(r[i].type)
else
n.addClass("status-" + r[i].type)
if (r[i].type == "ok") n.find('td.status').text("")
if (r[i].type == "error") n.find('td.status').text("")
if (r[i].type == "warning") n.find('td.status').text("?")
n.find('td.message p').text(r[i].text)
$('#system-checks tbody').append(n);
if (r[i].extra.length > 0) {
n.find('.showhide').show().text("Show More").click(function () {
$(this).hide();
$(this).parent().find('.extra').fadeIn();
return false;
});
}
if (r[i].extra.length > 0) {
n.find('a.showhide').show().text("show more").click(function() {
$(this).hide();
$(this).parent().find('.extra').fadeIn();
return false;
});
}
for (var j = 0; j < r[i].extra.length; j++) {
for (var j = 0; j < r[i].extra.length; j++) {
var m = $("<div/>").text(r[i].extra[j].text)
if (r[i].extra[j].monospace)
m.addClass("pre");
n.find('> td.message > div').append(m);
}
}
})
var m = $("<div/>").text(r[i].extra[j].text)
if (r[i].extra[j].monospace)
m.addClass("pre");
n.find('> td.message > div').append(m);
}
}
})
}
}
var current_privacy_setting = null;
function enable_privacy(status) {
api(
"/system/privacy",
"POST",
{
value: (status ? "private" : "off")
},
function (res) {
show_system_status();
});
return false; // disable link
}
var current_privacy_setting = null;
function enable_privacy(status) {
api(
"/system/privacy",
"POST",
{
value: (status ? "private" : "off")
},
function(res) {
show_system_status();
});
return false; // disable link
}
function confirm_reboot() {
show_modal_confirm(
"Reboot",
$("<p>This will reboot your Mail-in-a-Box <code>{{hostname}}</code>.</p> <p>Until the machine is fully restarted, your users will not be able to send and receive email, and you will not be able to connect to this control panel or with SSH. The reboot cannot be cancelled.</p>"),
"Reboot Now",
function () {
api(
"/system/reboot",
"POST",
{},
function (r) {
var msg = "<p>Please reload this page after a minute or so.</p>";
if (r) msg = "<p>The reboot command said:</p> <pre>" + $("<pre/>").text(r).html() + "</pre>"; // successful reboots don't produce any output; the output must be HTML-escaped
show_modal_error("Reboot", msg);
});
});
}
function confirm_reboot() {
show_modal_confirm(
"Reboot",
$("<p>This will reboot your Mail-in-a-Box <code>{{hostname}}</code>.</p> <p>Until the machine is fully restarted, your users will not be able to send and receive email, and you will not be able to connect to this control panel or with SSH. The reboot cannot be cancelled.</p>"),
"Reboot Now",
function() {
api(
"/system/reboot",
"POST",
{ },
function(r) {
var msg = "<p>Please reload this page after a minute or so.</p>";
if (r) msg = "<p>The reboot command said:</p> <pre>" + $("<pre/>").text(r).html() + "</pre>"; // successful reboots don't produce any output; the output must be HTML-escaped
show_modal_error("Reboot", msg);
});
});
}
</script>

View File

@@ -1,7 +1,6 @@
<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; }
@@ -134,8 +133,8 @@ function show_users() {
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);
var hdr = $("<tr><th colspan='2' style='background-color: #EEE'></th></tr>");
hdr.find('th').text(r[i].domain);
$('#user_table tbody').append(hdr);
for (var k = 0; k < r[i].users.length; k++) {