git subrepo clone https://github.com/mailcow/mailcow-dockerized.git mailcow/src/mailcow-dockerized

subrepo: subdir:   "mailcow/src/mailcow-dockerized"
  merged:   "a832becb"
upstream: origin:   "https://github.com/mailcow/mailcow-dockerized.git"
  branch:   "master"
  commit:   "a832becb"
git-subrepo: version:  "0.4.3"
  origin:   "???"
  commit:   "???"
Change-Id: If5be2d621a211e164c9b6577adaa7884449f16b5
diff --git a/mailcow/src/mailcow-dockerized/data/assets/mysql/docker-entrypoint.sh b/mailcow/src/mailcow-dockerized/data/assets/mysql/docker-entrypoint.sh
new file mode 100755
index 0000000..94e394a
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/assets/mysql/docker-entrypoint.sh
@@ -0,0 +1,192 @@
+#!/bin/bash
+set -eo pipefail
+shopt -s nullglob
+
+openssl req -x509 -sha256 -newkey rsa:2048 -keyout /var/lib/mysql/sql.key -out /var/lib/mysql/sql.crt -days 3650 -nodes -subj '/CN=mysql'
+
+# if command starts with an option, prepend mysqld
+if [ "${1:0:1}" = '-' ]; then
+	set -- mysqld "$@"
+fi
+
+# skip setup if they want an option that stops mysqld
+wantHelp=
+for arg; do
+	case "$arg" in
+		-'?'|--help|--print-defaults|-V|--version)
+			wantHelp=1
+			break
+			;;
+	esac
+done
+
+# usage: file_env VAR [DEFAULT]
+#    ie: file_env 'XYZ_DB_PASSWORD' 'example'
+# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of
+#  "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature)
+file_env() {
+	local var="$1"
+	local fileVar="${var}_FILE"
+	local def="${2:-}"
+	if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then
+		echo >&2 "error: both $var and $fileVar are set (but are exclusive)"
+		exit 1
+	fi
+	local val="$def"
+	if [ "${!var:-}" ]; then
+		val="${!var}"
+	elif [ "${!fileVar:-}" ]; then
+		val="$(< "${!fileVar}")"
+	fi
+	export "$var"="$val"
+	unset "$fileVar"
+}
+
+_check_config() {
+	toRun=( "$@" --verbose --help --log-bin-index="$(mktemp -u)" )
+	if ! errors="$("${toRun[@]}" 2>&1 >/dev/null)"; then
+		cat >&2 <<-EOM
+
+			ERROR: mysqld failed while attempting to check config
+			command was: "${toRun[*]}"
+
+			$errors
+		EOM
+		exit 1
+	fi
+}
+
+# Fetch value from server config
+# We use mysqld --verbose --help instead of my_print_defaults because the
+# latter only show values present in config files, and not server defaults
+_get_config() {
+	local conf="$1"; shift
+	"$@" --verbose --help --log-bin-index="$(mktemp -u)" 2>/dev/null | awk '$1 == "'"$conf"'" { print $2; exit }'
+}
+
+# allow the container to be started with `--user`
+if [ "$1" = 'mysqld' -a -z "$wantHelp" -a "$(id -u)" = '0' ]; then
+	_check_config "$@"
+	DATADIR="$(_get_config 'datadir' "$@")"
+	mkdir -p "$DATADIR"
+	chown -R mysql:mysql "$DATADIR"
+	exec gosu mysql "$BASH_SOURCE" "$@"
+fi
+
+if [ "$1" = 'mysqld' -a -z "$wantHelp" ]; then
+	# still need to check config, container may have started with --user
+	_check_config "$@"
+	# Get config
+	DATADIR="$(_get_config 'datadir' "$@")"
+
+	if [ ! -d "$DATADIR/mysql" ]; then
+		file_env 'MYSQL_ROOT_PASSWORD'
+		if [ -z "$MYSQL_ROOT_PASSWORD" -a -z "$MYSQL_ALLOW_EMPTY_PASSWORD" -a -z "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then
+			echo >&2 'error: database is uninitialized and password option is not specified '
+			echo >&2 '  You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD'
+			exit 1
+		fi
+
+		mkdir -p "$DATADIR"
+
+		echo 'Initializing database'
+		# "Other options are passed to mysqld." (so we pass all "mysqld" arguments directly here)
+		mysql_install_db --datadir="$DATADIR" --rpm "${@:2}"
+		echo 'Database initialized'
+
+		SOCKET="$(_get_config 'socket' "$@")"
+		"$@" --skip-networking --socket="${SOCKET}" &
+		pid="$!"
+
+		mysql=( mysql --protocol=socket -uroot -hlocalhost --socket="${SOCKET}" )
+
+		for i in {30..0}; do
+			if echo 'SELECT 1' | "${mysql[@]}" &> /dev/null; then
+				break
+			fi
+			echo 'MySQL init process in progress...'
+			sleep 1
+		done
+		if [ "$i" = 0 ]; then
+			echo >&2 'MySQL init process failed.'
+			exit 1
+		fi
+
+		if [ -z "$MYSQL_INITDB_SKIP_TZINFO" ]; then
+			# sed is for https://bugs.mysql.com/bug.php?id=20545
+			mysql_tzinfo_to_sql /usr/share/zoneinfo | sed 's/Local time zone must be set--see zic manual page/FCTY/' | "${mysql[@]}" mysql
+		fi
+
+		if [ ! -z "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then
+			export MYSQL_ROOT_PASSWORD="$(pwgen -1 32)"
+			echo "GENERATED ROOT PASSWORD: $MYSQL_ROOT_PASSWORD"
+		fi
+
+		rootCreate=
+		# default root to listen for connections from anywhere
+		file_env 'MYSQL_ROOT_HOST' '%'
+		if [ ! -z "$MYSQL_ROOT_HOST" -a "$MYSQL_ROOT_HOST" != 'localhost' ]; then
+			# no, we don't care if read finds a terminating character in this heredoc
+			# https://unix.stackexchange.com/questions/265149/why-is-set-o-errexit-breaking-this-read-heredoc-expression/265151#265151
+			read -r -d '' rootCreate <<-EOSQL || true
+				CREATE USER 'root'@'${MYSQL_ROOT_HOST}' IDENTIFIED BY '${MYSQL_ROOT_PASSWORD}' ;
+				GRANT ALL ON *.* TO 'root'@'${MYSQL_ROOT_HOST}' WITH GRANT OPTION ;
+			EOSQL
+		fi
+
+		"${mysql[@]}" <<-EOSQL
+			-- What's done in this file shouldn't be replicated
+			--  or products like mysql-fabric won't work
+			SET @@SESSION.SQL_LOG_BIN=0;
+
+			DELETE FROM mysql.user WHERE user NOT IN ('mysql.sys', 'mysqlxsys', 'root') OR host NOT IN ('localhost') ;
+			SET PASSWORD FOR 'root'@'localhost'=PASSWORD('${MYSQL_ROOT_PASSWORD}') ;
+			GRANT ALL ON *.* TO 'root'@'localhost' WITH GRANT OPTION ;
+			${rootCreate}
+			DROP DATABASE IF EXISTS test ;
+			FLUSH PRIVILEGES ;
+		EOSQL
+
+		if [ ! -z "$MYSQL_ROOT_PASSWORD" ]; then
+			mysql+=( -p"${MYSQL_ROOT_PASSWORD}" )
+		fi
+
+		file_env 'MYSQL_DATABASE'
+		if [ "$MYSQL_DATABASE" ]; then
+			echo "CREATE DATABASE IF NOT EXISTS \`$MYSQL_DATABASE\` ;" | "${mysql[@]}"
+			mysql+=( "$MYSQL_DATABASE" )
+		fi
+
+		file_env 'MYSQL_USER'
+		file_env 'MYSQL_PASSWORD'
+		if [ "$MYSQL_USER" -a "$MYSQL_PASSWORD" ]; then
+			echo "CREATE USER '$MYSQL_USER'@'%' IDENTIFIED BY '$MYSQL_PASSWORD' ;" | "${mysql[@]}"
+
+			if [ "$MYSQL_DATABASE" ]; then
+				echo "GRANT ALL ON \`$MYSQL_DATABASE\`.* TO '$MYSQL_USER'@'%' ;" | "${mysql[@]}"
+			fi
+		fi
+
+		echo
+		for f in /docker-entrypoint-initdb.d/*; do
+			case "$f" in
+				*.sh)     echo "$0: running $f"; . "$f" ;;
+				*.sql)    echo "$0: running $f"; "${mysql[@]}" < "$f"; echo ;;
+				*.sql.gz) echo "$0: running $f"; gunzip -c "$f" | "${mysql[@]}"; echo ;;
+				*)        echo "$0: ignoring $f" ;;
+			esac
+			echo
+		done
+
+		if ! kill -s TERM "$pid" || ! wait "$pid"; then
+			echo >&2 'MySQL init process failed.'
+			exit 1
+		fi
+
+		echo
+		echo 'MySQL init process done. Ready for start up.'
+		echo
+	fi
+fi
+
+exec "$@"
diff --git a/mailcow/src/mailcow-dockerized/data/assets/nextcloud/nextcloud.conf b/mailcow/src/mailcow-dockerized/data/assets/nextcloud/nextcloud.conf
new file mode 100644
index 0000000..e143a79
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/assets/nextcloud/nextcloud.conf
@@ -0,0 +1,122 @@
+map $http_x_forwarded_proto $client_req_scheme_nc {
+     default $scheme;
+     https https;
+}
+
+server {
+  include /etc/nginx/conf.d/listen_ssl.active;
+  include /etc/nginx/conf.d/listen_plain.active;
+  include /etc/nginx/mime.types;
+  charset utf-8;
+  override_charset on;
+
+  ssl_certificate /etc/ssl/mail/cert.pem;
+  ssl_certificate_key /etc/ssl/mail/key.pem;
+  ssl_protocols TLSv1.2 TLSv1.3;
+  ssl_prefer_server_ciphers on;
+  ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
+  ssl_ecdh_curve X25519:X448:secp384r1:secp256k1;
+  ssl_session_cache shared:SSL:50m;
+  ssl_session_timeout 1d;
+  ssl_session_tickets off;
+  add_header Referrer-Policy "no-referrer" always;
+  add_header X-Content-Type-Options "nosniff" always;
+  add_header X-Download-Options "noopen" always;
+  add_header X-Frame-Options "SAMEORIGIN" always;
+  add_header X-Permitted-Cross-Domain-Policies "none" always;
+  add_header X-Robots-Tag "none" always;
+  add_header X-XSS-Protection "1; mode=block" always;
+
+  fastcgi_hide_header X-Powered-By;
+
+  server_name NC_SUBD;
+
+  root /web/nextcloud/;
+
+  location = /robots.txt {
+    allow all;
+    log_not_found off;
+    access_log off;
+  }
+
+  location = /.well-known/carddav {
+    return 301 $client_req_scheme_nc://$host/remote.php/dav;
+  }
+
+  location = /.well-known/caldav {
+    return 301 $client_req_scheme_nc://$host/remote.php/dav;
+  }
+
+  location ^~ /.well-known/acme-challenge/ {
+    default_type "text/plain";
+    root /web;
+  }
+
+  fastcgi_buffers 64 4K;
+
+  gzip on;
+  gzip_vary on;
+  gzip_comp_level 4;
+  gzip_min_length 256;
+  gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
+  gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
+  set_real_ip_from fc00::/7;
+  set_real_ip_from 10.0.0.0/8;
+  set_real_ip_from 172.16.0.0/12;
+  set_real_ip_from 192.168.0.0/16;
+  real_ip_header X-Forwarded-For;
+  real_ip_recursive on;
+
+  location / {
+    rewrite ^ /index.php$uri;
+  }
+
+  location ~ ^\/(?:build|tests|config|lib|3rdparty|templates|data)\/ {
+    deny all;
+  }
+  location ~ ^\/(?:\.|autotest|occ|issue|indie|db_|console) {
+    deny all;
+  }
+
+  location ~ ^\/(?:index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+)\.php(?:$|\/) {
+    fastcgi_split_path_info ^(.+?\.php)(\/.*|)$;
+    set $path_info $fastcgi_path_info;
+    try_files $fastcgi_script_name =404;
+    include fastcgi_params;
+    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+    fastcgi_param PATH_INFO $path_info;
+    fastcgi_param HTTPS on;
+    # Avoid sending the security headers twice
+    fastcgi_param modHeadersAvailable true;
+    # Enable pretty urls
+    fastcgi_param front_controller_active true;
+    fastcgi_pass phpfpm:9002;
+    fastcgi_intercept_errors on;
+    fastcgi_request_buffering off;
+    client_max_body_size 0;
+    fastcgi_read_timeout 1200;
+  }
+
+  location ~ ^\/(?:updater|oc[ms]-provider)(?:$|\/) {
+    try_files $uri/ =404;
+    index index.php;
+  }
+
+  location ~ \.(?:css|js|woff2?|svg|gif|map)$ {
+    try_files $uri /index.php$request_uri;
+    add_header Cache-Control "public, max-age=15778463";
+    add_header Referrer-Policy "no-referrer" always;
+    add_header X-Content-Type-Options "nosniff" always;
+    add_header X-Download-Options "noopen" always;
+    add_header X-Frame-Options "SAMEORIGIN" always;
+    add_header X-Permitted-Cross-Domain-Policies "none" always;
+    add_header X-Robots-Tag "none" always;
+    add_header X-XSS-Protection "1; mode=block" always;
+    access_log off;
+  }
+
+  location ~ \.(?:png|html|ttf|ico|jpg|jpeg|bcmap)$ {
+    try_files $uri /index.php$request_uri;
+    access_log off;
+  }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/assets/nextcloud/occ b/mailcow/src/mailcow-dockerized/data/assets/nextcloud/occ
new file mode 100755
index 0000000..5113ac0
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/assets/nextcloud/occ
@@ -0,0 +1,2 @@
+#!/bin/bash
+docker exec -it -u www-data $(docker ps -f name=php-fpm-mailcow -q) php /web/nextcloud/occ ${@}
diff --git a/mailcow/src/mailcow-dockerized/data/assets/passwd/generate_passwords.sh b/mailcow/src/mailcow-dockerized/data/assets/passwd/generate_passwords.sh
new file mode 100755
index 0000000..7861315
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/assets/passwd/generate_passwords.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+echo DBPASS=$(openssl rand -base64 32 | tr -dc _A-Z-a-z-0-9)
+echo DBROOT=$(openssl rand -base64 32 | tr -dc _A-Z-a-z-0-9)
diff --git a/mailcow/src/mailcow-dockerized/data/assets/ssl-example/cert.pem b/mailcow/src/mailcow-dockerized/data/assets/ssl-example/cert.pem
new file mode 100644
index 0000000..96d16be
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/assets/ssl-example/cert.pem
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDBDCCAe6gAwIBAgIQeJMoL/3dxhxhT9EwuRTL/DALBgkqhkiG9w0BAQswEjEQ
+MA4GA1UEChMHbWFpbGNvdzAeFw0xNjEyMTMxMDExMDBaFw0xOTExMjgxMDExMDBa
+MC0xEDAOBgNVBAoTB21haWxjb3cxGTAXBgNVBAMTEG1haWwuZXhhbXBsZS5vcmcw
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRg0xT3At9DSb3H5OMp3K1
+MpXAgYyotSK6TS61fC0QEHy2fMXiws7Agcye6Ln7CG63Fe1eN2jkdlefy9xJivS8
+y5w0M8i168v5znzC8fnylL2iOiSYfK/B/oEqfU7YH4RcegO53oDDIUZmi4Frgnu7
+39VVOU1ZyHEVqGJ2H2aAIkoZRjGzumD9Ym4LWGidtKJzBgFt/qmhUeWXipM8w281
+XkQnJU79+x2ywnJSvEZ3r/ZVJC7kbjiVw+/k15k9Cxk6Ik8wmJ0X/+xWxoZomHQI
+1LM0VKAS/iaU95dn2bplvL6jTiiyWAbrMjSKs4XbPt/fIbOicNkj6+CFy0MVfyyH
+AgMBAAGjPzA9MA4GA1UdDwEB/wQEAwIAqDAdBgNVHSUEFjAUBggrBgEFBQcDAgYI
+KwYBBQUHAwEwDAYDVR0TAQH/BAIwADALBgkqhkiG9w0BAQsDggEBAI/jBJa1P8nB
+eHUN5muQmjBVDVOYyWAAEapOe2HYsBcpjaB2H8Iw3DQzJtz6peYeYSCmHRVqFLCm
+VPrq36l9mPUotyPDPlQQAxCj9R2+WbGaJO+N/E1F8FQ94dr3jqwUyfjVPoqEjmIH
+NFkvbA0RJOeBm9oYGdhM0wjOBV9c9MTHFG82nQ/zQeTuPb7GXuKIOXYCxoLNOZMw
+UJ02Cqjv5ImrgOhcstAKX3Ip0urSvZUGvtPla4CGh+M6yDFJ08GzX6OiMIH207RW
+jAbUXXERSUv/7hysdDjGo5HZjCeMzVu9KAxoZXqnmvkk8g2swKWtWBRcoeU1VGx0
+Bx4Q4KMjuYQ=
+-----END CERTIFICATE-----
diff --git a/mailcow/src/mailcow-dockerized/data/assets/ssl-example/dhparams.pem b/mailcow/src/mailcow-dockerized/data/assets/ssl-example/dhparams.pem
new file mode 100644
index 0000000..b245f05
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/assets/ssl-example/dhparams.pem
@@ -0,0 +1,8 @@
+-----BEGIN DH PARAMETERS-----
+MIIBCAKCAQEA9iHB0CRDhV8wfBgqnmvuJpl0fzL3qL75R4ZvQHlfMNLrxuIz2x9D
+9zcDhPcBTVzV5Ay0AAkke4wP6r6wDQqXqBP4Y8IOkYAyLh3jM40jfHQzQt+5JdQl
+ond3kiscBsFOch/vMfSLMu3lAb0YhPNTvrxhMz7LcVAWYl82swASupdiKR+MgaQr
+XsugpmDKsHW60VmIM9B7K9Y+rNHwvMWkmISd0KxA8oOy1WJvsVEissMALZDE3c4w
+2xHmO2lXxgEx3aez28736t4m/KW3g9Zr31a1M0KusmfY//fGkPk4NUrLBOS2xrgp
+Y/rG1qSBdcVyerM0Ki93qCyHKYu4ene0OwIBAg==
+-----END DH PARAMETERS-----
diff --git a/mailcow/src/mailcow-dockerized/data/assets/ssl-example/key.pem b/mailcow/src/mailcow-dockerized/data/assets/ssl-example/key.pem
new file mode 100644
index 0000000..cedf35a
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/assets/ssl-example/key.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEA0YNMU9wLfQ0m9x+TjKdytTKVwIGMqLUiuk0utXwtEBB8tnzF
+4sLOwIHMnui5+whutxXtXjdo5HZXn8vcSYr0vMucNDPItevL+c58wvH58pS9ojok
+mHyvwf6BKn1O2B+EXHoDud6AwyFGZouBa4J7u9/VVTlNWchxFahidh9mgCJKGUYx
+s7pg/WJuC1honbSicwYBbf6poVHll4qTPMNvNV5EJyVO/fsdssJyUrxGd6/2VSQu
+5G44lcPv5NeZPQsZOiJPMJidF//sVsaGaJh0CNSzNFSgEv4mlPeXZ9m6Zby+o04o
+slgG6zI0irOF2z7f3yGzonDZI+vghctDFX8shwIDAQABAoIBAQC9kiLnIgxXGyZt
+pmmYdA6re1jatZ2zLSp+DcY8ul3/0hs195IKCyCOOSQPiR520Pt0t+duP46uYZIJ
+aakp9gxaI5Vz+oMacH/AyaBDuDTj1Mf9WMSyIOfbDVCMRJOppGLcVh62+Gfjp2EO
++h2hTJBuvypFkbK2kVIZOaHVpbXWKw1oYuEcTftk9XfxxvfSMw1HQ12/P2CAcbaa
+jPmVbisunv6kpXtewSBTcaLSYWJf1MYD5Hi8fzkD2FJSXYbfQd8RKvT2rj6FA7ux
+CDMzbYhdnd7lc63OARCIjfCRNtDT1cZ3gR1CQHD98lWxmPQIZukv+w7s/bSrFgnQ
+ROZ0ghBJAoGBAOmE/3d5FDmp0aJNxXynKcRGdpEEM4O40RIdqa2eR6Pa7aTRosao
+z0qVgdFuJrqjlB3jgedxXEX1M0abCUzzM9Q5F7JLl+KsjwRwpkIOkPiyUncLp7LK
+QbY3tvYBIdpjlF1USOMGRL4j11hqr4vQC/yPBF7jj81kCZDTbmZhp82jAoGBAOWu
+ql5QFUOlmqkuWIAFkiLEZhOu+ptqkE+zG50CCGMJIX0dJ2PHXFyNGInomAeT0nbI
+pbnK3x7KeEKiGrAqZFNCTHhApTwkrIj0L/RQbMDZ7u7j1AEUVNFEhIm62kg84FtG
+xtfxVxredE+NQc/tyV3hXegdNZxegALirlcMKIvNAoGAWFwIxk48Ru1o8z72QQqH
+lUsMRicOzwK5qV8r+xPvC6MlVL42F3F8rj4QFwzU/r4yp3SUjNyqC5aSRl8Xj9Re
+gijwPHi6Cf09SHLPliMo29GtvnnchJxfbPF7+23GP3p6gy4HPk/65u9s5nnH3uFk
+B7ad8sGsgg0eSXyXQ4okEn0CgYEAnogPuedGthlxBgMiPMMbmfm7hyyId4t3Ljuu
+/JExnsHnpobf8EPjoVIWNOIhRWGnrCtUEEhR9tvDZCKljyDDfKBPTdU496lMmX8K
+NnToi7gg7iy84T3aSVMktDgPgDrclMPmbZh8CeSvnVUfrtgu3Ci4+4Rlw5eKffNe
+aGDQ/6UCgYAbUq9mRT2WOXIo+Dchi9VzDWgtfOw5VEyqkSpb7hPiIYx5jNaENnVK
+cAi3iqbBgPJBuMlTrKmmaxdmssGOEZNJLuuXLDbCU+f5cpu5PQ4crC6UtRI5rlhp
+8Yc+oiv3HWbSw3sVRpMFB6NP4DnvgFW3B2Wdfb/lNzPCKWqBsX7gWw==
+-----END RSA PRIVATE KEY-----
diff --git a/mailcow/src/mailcow-dockerized/data/assets/templates/quarantine.tpl b/mailcow/src/mailcow-dockerized/data/assets/templates/quarantine.tpl
new file mode 100644
index 0000000..8fa88c5
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/assets/templates/quarantine.tpl
@@ -0,0 +1,69 @@
+<html>
+  <head>
+  <meta name="x-apple-disable-message-reformatting" />
+  <style>
+  body {
+    font-family: Helvetica, Arial, Sans-Serif;
+  }
+  table {
+    border-collapse: collapse;
+    width: 100%;
+    margin-bottom: 20px;
+  }
+  th, td {
+    padding: 8px;
+    text-align: left;
+    border-bottom: 1px solid #ddd;
+    vertical-align: top;
+  }
+  td.fixed {
+    white-space: nowrap;
+  }
+  th {
+    background-color: #56B04C;
+    color: white;
+  }
+  tr:nth-child(even) {
+    background-color: #f2f2f2;
+  }
+  /* mobile devices */
+  @media all and (max-width: 480px) {
+    .mob {
+    display: none;
+    }    
+  }
+  </style>
+  </head>
+  <body>
+    <p>Hi {{username}}!<br>
+    {% if counter == 1 %}
+    There is 1 new message waiting in quarantine:<br>
+    {% else %}
+    There are {{counter}} new messages waiting in quarantine:<br>
+    {% endif %}
+    <table>
+    <tr><th>Subject</th><th>Sender</th><th class="mob">Score</th><th class="mob">Action</th><th class="mob">Arrived on</th>{% if quarantine_acl == 1 %}<th>Actions</th>{% endif %}</tr>
+    {% for line in meta|reverse %}
+    <tr>
+    <td>{{ line.subject|e }}</td>
+    <td>{{ line.sender|e }}</td>
+    <td class="mob">{{ line.score }}</td>
+    {% if line.action == "reject" %}
+      <td class="mob">Rejected</td>
+    {% else %}
+      <td class="mob">Sent to Junk folder</td>
+    {% endif %}
+    <td class="mob">{{ line.created }}</td>
+    {% if quarantine_acl == 1 %}
+      {% if line.action == "reject" %}
+        <td class="fixed"><a href="https://{{ hostname }}/qhandler/release/{{ line.qhash }}">Release to inbox</a> | <a href="https://{{ hostname }}/qhandler/delete/{{ line.qhash }}">delete</a></td>
+      {% else %}
+        <td class="fixed"><a href="https://{{ hostname }}/qhandler/release/{{ line.qhash }}">Send copy to inbox</a> | <a href="https://{{ hostname }}/qhandler/delete/{{ line.qhash }}">delete</a></td>
+      {% endif %}
+    {% endif %}
+    </tr>
+    {% endfor %}
+    </table>
+    </p>
+  </body>
+</html>
diff --git a/mailcow/src/mailcow-dockerized/data/assets/templates/quota.tpl b/mailcow/src/mailcow-dockerized/data/assets/templates/quota.tpl
new file mode 100644
index 0000000..b6ad644
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/assets/templates/quota.tpl
@@ -0,0 +1,73 @@
+<html>
+    <head>
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+        <style>
+            body {
+            font-family: Calibri, Arial, Verdana;
+            }
+            table {
+            border: 0;
+            border-collapse: collapse;
+            <!--[if mso]>
+            border-spacing: 0px;
+            table-layout: fixed;
+            <![endif]-->
+            }
+            tr {
+            display: flex;
+            }
+            #progressbar {
+            color: #000;
+            background-color: #f1f1f1;
+            width: 100%;
+            }
+            {% if (percent >= 95) %}
+            #progressbar {
+            color: #fff;
+            background-color: #FF0000;
+            text-align: center;
+            width: {{percent}}%;
+            }
+            {% elif (percent < 95) and (percent >= 80) %}
+            #progressbar {
+            color: #fff;
+            background-color: #FF8C00;
+            text-align: center;
+            width: {{percent}}%;
+            }
+            {% else %}
+            #progressbar {
+            color: #fff;
+            background-color: #00B000;
+            text-align: center;
+            width: {{percent}}%;
+            }
+            {% endif %}
+            #graybar {
+            background-color: #D8D8D8;
+            width: {{100 - percent}}%;
+            }
+            a:link, a:visited {
+            color: #858585;
+            text-decoration: none;
+            }
+            a:hover, a:active {
+            color: #4a81bf;
+            }
+        </style>
+    </head>
+    <body>
+        <table>
+            <tr>
+                <td colspan="2">
+                    Hi {{username}}!<br /><br />
+                    Your mailbox is now {{percent}}% full, please consider deleting old messages to still be able to receive new mails in the future.<br /><br />
+                </td>
+            </tr>
+            <tr>
+                <td id="progressbar">{{percent}}%</td>
+                <td id="graybar"></td>
+            </tr>
+        </table>
+    </body>
+</html>