2638: further finishing touches for restful api r=mergify[bot] a=Diman0

- Fix setup utility setting correct value to env var API. It now also sets `false` when the API is disabled in the setup utility.
- Fix IF statement for enabling API in nginx.conf. Setting a different value than `API=true` in mailu.env now disabled the API endpoint in nginx.
- Use safer command for regenerating example API token. It uses crypto.getRandomValues() (as suggested by nextgens) which should be more random than the previously used method. 

## What type of PR?

bug-fix

## What does this PR do?

### Related issue(s)

## Prerequisites
Before we can consider review and merge, please make sure the following list is done and checked.
If an entry in not applicable, you can check it or remove it from the list.

- [ ] In case of feature or enhancement: documentation updated accordingly
- [ ] Unless it's docs or a minor change: add [changelog](https://mailu.io/master/contributors/workflow.html#changelog) entry file.


Co-authored-by: Dimitri Huisman <diman@huisman.xyz>
main
bors[bot] 1 year ago committed by GitHub
commit 4a24bd9e24
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -5,8 +5,7 @@ import logging as log
import sys
from socrate import system, conf
system.set_env()
args = os.environ.copy()
args = system.set_env()
log.basicConfig(stream=sys.stderr, level=args.get("LOG_LEVEL", "WARNING"))
args['TLS_PERMISSIVE'] = str(args.get('TLS_PERMISSIVE')).lower() not in ('false', 'no')
@ -18,8 +17,8 @@ with open("/etc/resolv.conf") as handle:
args["RESOLVER"] = f"[{resolver}]" if ":" in resolver else resolver
# TLS configuration
cert_name = os.getenv("TLS_CERT_FILENAME", default="cert.pem")
keypair_name = os.getenv("TLS_KEYPAIR_FILENAME", default="key.pem")
cert_name = args.get("TLS_CERT_FILENAME", "cert.pem")
keypair_name = args.get("TLS_KEYPAIR_FILENAME", "key.pem")
args["TLS"] = {
"cert": ("/certs/%s" % cert_name, "/certs/%s" % keypair_name),
"letsencrypt": ("/certs/letsencrypt/live/mailu/nginx-chain.pem",
@ -37,7 +36,7 @@ def format_for_nginx(fullchain, output):
split = '-----END CERTIFICATE-----\n'
with open(fullchain, 'r') as pem:
certs = [f'{cert}{split}' for cert in pem.read().split(split) if cert]
if len(certs)>2 and os.getenv('LETSENCRYPT_SHORTCHAIN'):
if len(certs)>2 and args.get('LETSENCRYPT_SHORTCHAIN'):
del certs[-1]
with open(output, 'w') as pem:
pem.write(''.join(certs))

@ -70,14 +70,14 @@ Then on your own frontend, point to these local ports. In practice, you only nee
REAL_IP_FROM=x.x.x.x,y.y.y.y.y
#x.x.x.x,y.y.y.y.y is the static IP address your reverse proxy uses for connecting to Mailu.
Because the admin interface is served as ``/admin``, the Webmail as ``/webmail``, the single sign on page as ``/sso``, webdav as ``/webdav``, the client-autoconfiguration and the static files endpoint as ``/static``, you may also want to use a single virtual host and serve other applications (still Nginx):
Because the admin interface is served as ``/admin``, the RESTful API as ``/api``, the Webmail as ``/webmail``, the single sign on page as ``/sso``, webdav as ``/webdav``, the client-autoconfiguration and the static files endpoint as ``/static``, you may also want to use a single virtual host and serve other applications (still Nginx):
.. code-block:: nginx
server {
# [...] here goes your standard configuration
location ~* ^/(admin|sso|static|webdav|webmail|(apple\.)?mobileconfig|(\.well\-known/autoconfig/)?mail/|Autodiscover/Autodiscover) {
location ~* ^/(admin|api|sso|static|webdav|webmail|(apple\.)?mobileconfig|(\.well\-known/autoconfig/)?mail/|Autodiscover/Autodiscover) {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass https://localhost:8443;

@ -1,12 +1,5 @@
//API_TOKEN generator
var chars = "0123456789abcdefghijklmnopqrstuvwxyz!@#$%^&*()ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var tokenLength = 12;
var token = "";
for (var i = 0; i <= tokenLength; i++) {
var randomNumber = Math.floor(Math.random() * chars.length);
token += chars.substring(randomNumber, randomNumber +1);
}
//Store API token in variable.
var token = $("#api_token").val();
$(document).ready(function() {
if ($("#webmail").val() == 'none') {
@ -44,7 +37,7 @@ $(document).ready(function() {
});
$(document).ready(function() {
if ($('#api').prop('checked')) {
if ($('#api_enabled').prop('checked')) {
$("#api_path").show();
$("#api_path").val("/api")
$("#api_token").show();
@ -53,13 +46,13 @@ $(document).ready(function() {
$("#api_token_label").show();
} else {
$("#api_path").hide();
$("#api_path").val("/api")
$("#api_path").val("")
$("#api_token").hide();
$("#api_token").prop('required',false);
$("#api_token").val("");
$("#api_token_label").hide();
}
$("#api").change(function() {
$("#api_enabled").change(function() {
if ($(this).is(":checked")) {
$("#api_path").show();
$("#api_path").val("/api");
@ -69,7 +62,7 @@ $(document).ready(function() {
$("#api_token_label").show();
} else {
$("#api_path").hide();
$("#api_path").val("/api")
$("#api_path").val("")
$("#api_token").hide();
$("#api_token").prop('required',false);
$("#api_token").val("");

@ -93,11 +93,11 @@ manage your email domains, users, etc.</p>
It is not possible to use the API without an API token.</p>
<div class="form-group">
<input type="checkbox" name="api_enabled" value="false" id="api" >
<input type="checkbox" name="api_enabled" value="true" id="api_enabled" >
<label>Enable the API (and path to the API)</label>
<input class="form-control" type="text" name="api_path" id="api_path" style="display: none">
<label name="api_token_label" id="api_token_label">API token</label>
<input class="form-control" type="text" name="api_token" id="api_token" style="display: none">
<input class="form-control" type="text" name="api_token" id="api_token" style="display: none" value="{{ secret(32) }}">
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

Loading…
Cancel
Save