Compare commits
13 commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
4d68d1f08e | ||
![]() |
197aa5fdaa | ||
![]() |
f3994d8b89 | ||
![]() |
222ae0d960 | ||
![]() |
701e214929 | ||
![]() |
1d857c7f00 | ||
![]() |
d5f327755c | ||
![]() |
9193dbe56b | ||
![]() |
289f311c4f | ||
![]() |
465bd4dc57 | ||
![]() |
f9815662c1 | ||
![]() |
74d88787c8 | ||
![]() |
9215b011f8 |
13 changed files with 69 additions and 42 deletions
5
.gitattributes
vendored
Normal file
5
.gitattributes
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
# All text should use Unix-style Line-endings
|
||||
* text eol=lf
|
||||
|
||||
# Except mta-sts.txt (RFC 8461)
|
||||
mta-sts.txt text eol=crlf
|
|
@ -1,5 +1,5 @@
|
|||
# Power Mail-in-a-Box
|
||||
## **[Installation](#installation)** (current version: v60.4)
|
||||
## **[Installation](#installation)** (current version: v60.5)
|
||||
## **[Upgrading Quick Start](#upgrading)**
|
||||
|
||||
[](https://ko-fi.com/davness)
|
||||
|
@ -98,4 +98,4 @@ curl -L https://power-mailinabox.net/<VERSION>/setup.sh | sudo bash
|
|||
```
|
||||
Where `<VERSION>` is the version you want to install. (**Example:** `v60.0`).
|
||||
|
||||
> ⚠️ **Downgrading might not always be possible and is not supported!** Make sure you know what you're doing before doing so.
|
||||
> ⚠️ **Downgrading might not always be possible and is not supported!** Make sure you know what you're doing before doing so.
|
||||
|
|
3
Vagrantfile
vendored
3
Vagrantfile
vendored
|
@ -49,9 +49,6 @@ Vagrant.configure("2") do |config|
|
|||
m.vm.network "private_network", ip: "192.168.168.#{ip+n}"
|
||||
|
||||
m.vm.provision "shell", :inline => <<-SH
|
||||
# Make sure we have IPv6 loopback (::1)
|
||||
sysctl -w net.ipv6.conf.lo.disable_ipv6=0
|
||||
echo -e "fs.inotify.max_user_instances=1024\nnet.ipv6.conf.lo.disable_ipv6=0" > /etc/sysctl.conf
|
||||
git config --global --add safe.directory /vagrant
|
||||
|
||||
# Set environment variables so that the setup script does
|
||||
|
|
|
@ -15,7 +15,7 @@ info:
|
|||
license:
|
||||
name: CC0 1.0 Universal
|
||||
url: https://creativecommons.org/publicdomain/zero/1.0/legalcode
|
||||
version: 60.4
|
||||
version: 60.5
|
||||
x-logo:
|
||||
url: https://mailinabox.email/static/logo.png
|
||||
altText: Mail-in-a-Box logo
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
version: STSv1
|
||||
mode: MODE
|
||||
mx: PRIMARY_HOSTNAME
|
||||
max_age: 604800
|
||||
version: STSv1
|
||||
mode: MODE
|
||||
mx: PRIMARY_HOSTNAME
|
||||
max_age: 604800
|
||||
|
|
|
@ -240,7 +240,9 @@ def get_duplicity_target_url(config):
|
|||
# via get_duplicity_additional_args. Move the first part of the
|
||||
# path (the bucket name) into the hostname URL component, and leave
|
||||
# the rest for the path.
|
||||
target[1], target[2] = target[2].lstrip('/').split('/', 1)
|
||||
target_bucket = target[2].lstrip('/').split('/', 1)
|
||||
target[1] = target_bucket[0]
|
||||
target[2] = target_bucket[1] if len(target_bucket) > 1 else ''
|
||||
|
||||
target = urlunsplit(target)
|
||||
|
||||
|
|
|
@ -886,30 +886,39 @@ def smtp_relay_set():
|
|||
newconf = request.form
|
||||
|
||||
# Is DKIM configured?
|
||||
sel = newconf.get("dkim_selector")
|
||||
sel = newconf.get("dkim_selector", "")
|
||||
rr = newconf.get("dkim_rr", "")
|
||||
check_dkim = True
|
||||
if sel is None or sel.strip() == "":
|
||||
config["SMTP_RELAY_DKIM_SELECTOR"] = None
|
||||
# Check that the key RR doesn't exist either, otherwise we cannot be
|
||||
# sure that the user wants to remove it.
|
||||
if rr.strip() != "":
|
||||
return ("Cannot publish a DKIM key without a selector!\n\
|
||||
If you want to set up a relay without a DKIM record, both the selector and the key need to be empty.", 400)
|
||||
config["SMTP_RELAY_DKIM_RR"] = None
|
||||
check_dkim = False
|
||||
elif re.fullmatch(r"[a-z\d\._][a-z\d\._\-]*", sel.strip()) is None:
|
||||
return ("The DKIM selector is invalid!", 400)
|
||||
|
||||
# DKIM selector looks good, try processing the RR
|
||||
rr = newconf.get("dkim_rr", "")
|
||||
if rr.strip() == "":
|
||||
return ("Cannot publish a selector with an empty key!", 400)
|
||||
if check_dkim:
|
||||
# DKIM selector looks good, try processing the RR
|
||||
if rr.strip() == "":
|
||||
return ("Cannot publish a selector with an empty key!\n\
|
||||
If you want to set up a relay without a DKIM record, both the selector and the key need to be empty.", 400)
|
||||
|
||||
components = {}
|
||||
for r in re.split(r"[;\s]+", rr):
|
||||
sp = re.split(r"\=", r)
|
||||
if len(sp) != 2:
|
||||
return ("DKIM public key RR is malformed!", 400)
|
||||
components[sp[0]] = sp[1]
|
||||
components = {}
|
||||
for r in re.split(r"[;\s]+", rr):
|
||||
sp = re.split(r"\=", r)
|
||||
if len(sp) != 2:
|
||||
return ("DKIM public key RR is malformed!", 400)
|
||||
components[sp[0]] = sp[1]
|
||||
|
||||
if not components.get("p"):
|
||||
return ("The DKIM public key doesn't exist!", 400)
|
||||
if not components.get("p"):
|
||||
return ("The DKIM public key doesn't exist!", 400)
|
||||
|
||||
config["SMTP_RELAY_DKIM_SELECTOR"] = sel
|
||||
config["SMTP_RELAY_DKIM_RR"] = components
|
||||
config["SMTP_RELAY_DKIM_SELECTOR"] = sel
|
||||
config["SMTP_RELAY_DKIM_RR"] = components
|
||||
|
||||
relay_on = False
|
||||
implicit_tls = False
|
||||
|
@ -928,7 +937,7 @@ def smtp_relay_set():
|
|||
implicit_tls = True
|
||||
except ssl.SSLError as sle:
|
||||
# Couldn't connect via TLS, configure Postfix to send via STARTTLS
|
||||
print(sle.reason)
|
||||
pass
|
||||
except (socket.herror, socket.gaierror) as he:
|
||||
return (
|
||||
f"Unable to resolve hostname (it probably is incorrect): {he.strerror}",
|
||||
|
|
|
@ -78,7 +78,7 @@
|
|||
|
||||
<h3>DKIM Configuration</h3>
|
||||
<p>DKIM allows receivers to verify that the email was sent by the relay you configured (this is, somebody you
|
||||
trust). <b>Not doing so will have your email sent to spam.</b></p>
|
||||
trust). <b>If your relay provider does not provide you with this information, it's probably safe to skip this step.</b></p>
|
||||
|
||||
<div class="col-lg-6 col-md-8 col-12">
|
||||
<div class="input-group">
|
||||
|
|
|
@ -304,6 +304,15 @@
|
|||
$("#backup-target-type").val("s3");
|
||||
var hostpath = r.target.substring(5).split('/');
|
||||
var host = hostpath.shift();
|
||||
let s3_options = $("#backup-target-s3-host-select option").map(function() {return this.value}).get()
|
||||
$("#backup-target-s3-host-select").val("other")
|
||||
for (let h of s3_options) {
|
||||
console.log(h)
|
||||
if (h == host) {
|
||||
$("#backup-target-s3-host-select").val(host)
|
||||
break
|
||||
}
|
||||
}
|
||||
$("#backup-target-s3-host").val(host);
|
||||
$("#backup-target-s3-path").val(hostpath.join('/'));
|
||||
} else if (r.target.substring(0, 5) == "b2://") {
|
||||
|
@ -365,18 +374,18 @@
|
|||
}
|
||||
|
||||
function init_inputs(target_type) {
|
||||
function set_host(host) {
|
||||
function set_host(host, overwrite_other) {
|
||||
if (host !== 'other') {
|
||||
$("#backup-target-s3-host").val(host);
|
||||
} else {
|
||||
} else if (overwrite_other) {
|
||||
$("#backup-target-s3-host").val('');
|
||||
}
|
||||
}
|
||||
if (target_type == "s3") {
|
||||
$('#backup-target-s3-host-select').off('change').on('change', function () {
|
||||
set_host($('#backup-target-s3-host-select').val());
|
||||
set_host($('#backup-target-s3-host-select').val(), true);
|
||||
});
|
||||
set_host($('#backup-target-s3-host-select').val());
|
||||
set_host($('#backup-target-s3-host-select').val(), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ if [ -z "$TAG" ]; then
|
|||
[ "$(echo $OS | grep -o 'Ubuntu 20.04')" == "Ubuntu 20.04" ] ||
|
||||
[ "$(echo $OS | grep -o 'Ubuntu 22.04')" == "Ubuntu 22.04" ]
|
||||
then
|
||||
TAG=v60.4
|
||||
TAG=v60.5
|
||||
elif [ "$OS" == "Debian GNU/Linux 10 (buster)" ]; then
|
||||
echo "We are going to install the last version of Power Mail-in-a-Box supporting Debian 10 (buster)."
|
||||
echo "IF THIS IS A NEW INSTALLATION, STOP NOW, AND USE A SUPPORTED DISTRIBUTION INSTEAD (ONE OF THESE):"
|
||||
|
@ -86,7 +86,7 @@ if [ ! -d $HOME/mailinabox ]; then
|
|||
echo Downloading Mail-in-a-Box $TAG. . .
|
||||
git clone \
|
||||
-b $TAG --depth 1 \
|
||||
https://github.com/ddavness/power-mailinabox \
|
||||
https://git.nibbletools.com/beenull/power-mailinabox \
|
||||
$HOME/mailinabox \
|
||||
< /dev/null 2> /dev/null
|
||||
|
||||
|
|
|
@ -25,8 +25,11 @@ if [ ! -f $db_path ]; then
|
|||
echo "CREATE TABLE noreply (id INTEGER PRIMARY KEY AUTOINCREMENT, email TEXT NOT NULL UNIQUE);" | sqlite3 $db_path
|
||||
echo "CREATE TABLE mfa (id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER NOT NULL, type TEXT NOT NULL, secret TEXT NOT NULL, mru_token TEXT, label TEXT, FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE);" | sqlite3 $db_path;
|
||||
echo "CREATE TABLE auto_aliases (id INTEGER PRIMARY KEY AUTOINCREMENT, source TEXT NOT NULL UNIQUE, destination TEXT NOT NULL, permitted_senders TEXT);" | sqlite3 $db_path;
|
||||
elif sqlite3 $db_path ".schema users" | grep --invert-match quota; then
|
||||
echo "ALTER TABLE users ADD COLUMN quota TEXT NOT NULL DEFAULT '0';" | sqlite3 $db_path;
|
||||
else
|
||||
sql=$(sqlite3 $db_path "SELECT sql FROM sqlite_master WHERE name = 'users'");
|
||||
if echo $sql | grep --invert-match quota; then
|
||||
echo "ALTER TABLE users ADD COLUMN quota TEXT NOT NULL DEFAULT '0';" | sqlite3 $db_path;
|
||||
fi
|
||||
fi
|
||||
|
||||
# Recover the database if it was hit by the Roundcube password changer "bug" (#85)
|
||||
|
@ -34,7 +37,7 @@ fi
|
|||
# be able to send or receive mail.
|
||||
#
|
||||
# This operation is idempotent so it's safe to run even in healthy databases, too.
|
||||
echo "PRAGMA journal_mode=delete;" | sqlite3 $db_path;
|
||||
echo "PRAGMA journal_mode=delete;" | sqlite3 $db_path > /dev/null
|
||||
|
||||
# ### User Authentication
|
||||
|
||||
|
|
|
@ -81,12 +81,13 @@ mkdir -p $assets_dir
|
|||
|
||||
# jQuery CDN URL
|
||||
jquery_version=3.6.1
|
||||
jquery_url=https://code.jquery.com
|
||||
jquery_url=https://code.jquery.com # Check this link for new versions
|
||||
|
||||
# Get jQuery
|
||||
wget_verify $jquery_url/jquery-$jquery_version.min.js ea61688671d0c3044f2c5b2f2c4af0a6620ac6c2 $assets_dir/jquery.min.js
|
||||
|
||||
# Bootstrap CDN URL
|
||||
# See https://github.com/twbs/bootstrap/releases to check for new versions
|
||||
bootstrap_version=5.2.2
|
||||
bootstrap_url=https://github.com/twbs/bootstrap/releases/download/v$bootstrap_version/bootstrap-$bootstrap_version-dist.zip
|
||||
|
||||
|
@ -97,11 +98,12 @@ mv $assets_dir/bootstrap-$bootstrap_version-dist $assets_dir/bootstrap
|
|||
rm -f /tmp/bootstrap.zip
|
||||
|
||||
# FontAwesome CDN URL
|
||||
fontawesome_version=6.2.0
|
||||
# See https://github.com/FortAwesome/Font-Awesome/releases to check for new versions
|
||||
fontawesome_version=6.2.1
|
||||
fontawesome_url=https://github.com/FortAwesome/Font-Awesome/releases/download/$fontawesome_version/fontawesome-free-$fontawesome_version-web.zip
|
||||
|
||||
# Get FontAwesome
|
||||
wget_verify $fontawesome_url cd6250deeb38ab707240200c573d2357eaf732a0 /tmp/fontawesome.zip
|
||||
wget_verify $fontawesome_url cd0f2bcc9653b56e3e2dd82d6598aa6bbca8d796 /tmp/fontawesome.zip
|
||||
unzip -q /tmp/fontawesome.zip -d $assets_dir
|
||||
mv $assets_dir/fontawesome-free-$fontawesome_version-web $assets_dir/fontawesome
|
||||
rm -f /tmp/fontawesome.zip
|
||||
|
|
|
@ -30,8 +30,8 @@ apt_install \
|
|||
# whether we have the latest version of everything.
|
||||
# For the latest versions, see:
|
||||
# https://github.com/roundcube/roundcubemail/releases
|
||||
# https://github.com/mfreiholz/persistent_login/commits/master
|
||||
# https://github.com/stremlau/html5_notifier/commits/master
|
||||
# https://github.com/mfreiholz/persistent_login/
|
||||
# https://github.com/stremlau/html5_notifier/
|
||||
# https://github.com/mstilkerich/rcmcarddav/releases
|
||||
# The easiest way to get the package hashes is to run this script and get the hash from
|
||||
# the error message.
|
||||
|
|
Loading…
Add table
Reference in a new issue