From 1157868370d2767009fc587601fa71b0e2f7f7e9 Mon Sep 17 00:00:00 2001 From: Florent Daigniere Date: Thu, 23 Sep 2021 16:08:52 +0200 Subject: [PATCH 01/33] Document how to setup autoconfig --- docs/faq.rst | 52 +++++++++++++++++++++++++ towncrier/newsfragments/224.enhancement | 1 + 2 files changed, 53 insertions(+) create mode 100644 towncrier/newsfragments/224.enhancement diff --git a/docs/faq.rst b/docs/faq.rst index 01557237..177e65d7 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -394,6 +394,58 @@ Mailu can serve an `MTA-STS policy`_; To configure it you will need to: .. _`1798`: https://github.com/Mailu/Mailu/issues/1798 .. _`MTA-STS policy`: https://datatracker.ietf.org/doc/html/rfc8461 +How do I setup client autoconfiguration? +```````````````````````````````````````` + +Mailu can serve an `XML file for autoconfiguration`_; To configure it you will need to: + +1. add ``autoconfig.example.com`` to the ``HOSTNAMES`` configuration variable (and ensure that a valid SSL certificate is available for it; this may mean restarting your smtp container) + +2. configure an override with the policy itself; for example, your ``overrides/nginx/autoconfiguration.conf`` could read: + +.. code-block:: bash + + location ^~ /mail/config-v1.1.xml { + return 200 " + + + %EMAILDOMAIN% + + Email + Email + + + mailu.example.com + 993 + SSL + %EMAILADDRESS% + password-cleartext + + + + mailu.example.com + 465 + SSL + %EMAILADDRESS% + password-cleartext + true + true + + + + Configure your email client + + + \r\n"; + } + +3. setup the appropriate DNS/CNAME record (``autoconfig.example.com`` -> ``mailu.example.com``). + +*issue reference:* `224`_. + +.. _`224`: https://github.com/Mailu/Mailu/issues/224 +.. _`XML file for autoconfiguration`: https://wiki.mozilla.org/Thunderbird:Autoconfiguration:ConfigFileFormat + Technical issues ---------------- diff --git a/towncrier/newsfragments/224.enhancement b/towncrier/newsfragments/224.enhancement new file mode 100644 index 00000000..9e4edccf --- /dev/null +++ b/towncrier/newsfragments/224.enhancement @@ -0,0 +1 @@ +Document how to setup client autoconfig using an override From 16691e83adcdcae01948cfa3b6601dd9f0450894 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 24 Sep 2021 18:15:00 +0200 Subject: [PATCH 02/33] re-enable mod_rewrite in roundcube moved chown/mkdir/symlink from start.py to Dockerfile --- webmails/roundcube/Dockerfile | 10 +++++++--- webmails/roundcube/start.py | 6 +----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/webmails/roundcube/Dockerfile b/webmails/roundcube/Dockerfile index df83bc83..32f71ea5 100644 --- a/webmails/roundcube/Dockerfile +++ b/webmails/roundcube/Dockerfile @@ -33,13 +33,17 @@ RUN apt-get update && apt-get install -y \ && mv roundcubemail-* html \ && mv carddav html/plugins/ \ && cd html \ - && rm -rf CHANGELOG INSTALL LICENSE README.md UPGRADING composer.json-dist installer \ + && rm -rf CHANGELOG INSTALL LICENSE README.md UPGRADING composer.json-dist installer composer.* \ && sed -i 's,mod_php5.c,mod_php7.c,g' .htaccess \ && sed -i 's,^php_value.*post_max_size,#&,g' .htaccess \ && sed -i 's,^php_value.*upload_max_filesize,#&,g' .htaccess \ - && chown -R www-data: logs temp \ + && ln -sf index.php /var/www/html/sso.php \ + && chown -R root:root . \ + && touch logs/errors.log \ + && chown -R www-data:www-data logs temp \ + && chmod -R a+rX . \ && rm -rf /var/lib/apt/lists \ - && a2enmod deflate expires headers + && a2enmod rewrite deflate expires headers COPY php.ini /php.ini COPY config.inc.php /var/www/html/config/ diff --git a/webmails/roundcube/start.py b/webmails/roundcube/start.py index cd42ba06..82c4c26f 100755 --- a/webmails/roundcube/start.py +++ b/webmails/roundcube/start.py @@ -34,11 +34,7 @@ else: conf.jinja("/php.ini", os.environ, "/usr/local/etc/php/conf.d/roundcube.ini") # Create dirs, setup permissions -os.system("mkdir -p /data/gpg /var/www/html/logs") -os.system("touch /var/www/html/logs/errors.log") -os.system("chown -R www-data:www-data /var/www/html/logs") -os.system("chmod -R a+rX /var/www/html/") -os.system("ln -sf /var/www/html/index.php /var/www/html/sso.php") +os.system("mkdir -p /data/gpg") try: print("Initializing database") From e9f84d7d994656162e41136e375d6cdfa86446ed Mon Sep 17 00:00:00 2001 From: Florent Daigniere Date: Sat, 25 Sep 2021 16:25:59 +0200 Subject: [PATCH 03/33] Improve the unbound configuration --- optional/unbound/unbound.conf | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/optional/unbound/unbound.conf b/optional/unbound/unbound.conf index 6c8fc64d..42b2d4d8 100644 --- a/optional/unbound/unbound.conf +++ b/optional/unbound/unbound.conf @@ -1,19 +1,21 @@ server: verbosity: 1 interface: 0.0.0.0 - interface: ::0 + {{ 'interface: ::0' if SUBNET6 }} logfile: "" do-ip4: yes - do-ip6: yes + do-ip6: {{ 'yes' if SUBNET6 else 'no' }} do-udp: yes do-tcp: yes do-daemonize: no access-control: {{ SUBNET }} allow + {{ 'access-control: {{ SUBNET6 }} allow' if SUBNET6 }} directory: "/etc/unbound" username: unbound auto-trust-anchor-file: trusted-key.key root-hints: "/etc/unbound/root.hints" hide-identity: yes hide-version: yes - max-udp-size: 4096 - msg-buffer-size: 65552 + cache-min-ttl: 300 + qname-minimisation: yes + From 739702a0349d099bf70cb71f18a2bd12180897ab Mon Sep 17 00:00:00 2001 From: Florent Daigniere Date: Sat, 25 Sep 2021 16:31:11 +0200 Subject: [PATCH 04/33] doc --- towncrier/newsfragments/1992.enhancement | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 towncrier/newsfragments/1992.enhancement diff --git a/towncrier/newsfragments/1992.enhancement b/towncrier/newsfragments/1992.enhancement new file mode 100644 index 00000000..56a11538 --- /dev/null +++ b/towncrier/newsfragments/1992.enhancement @@ -0,0 +1,3 @@ +Make unbound work with ipv6 +Add a cache-min-ttl of 5minutes +Enable qname minimisation (privacy) From 1cf0f76b529389b47eff0c7e9800c53263e073af Mon Sep 17 00:00:00 2001 From: Florent Daigniere Date: Mon, 27 Sep 2021 09:04:15 +0200 Subject: [PATCH 05/33] not required anymore --- optional/unbound/unbound.conf | 1 - 1 file changed, 1 deletion(-) diff --git a/optional/unbound/unbound.conf b/optional/unbound/unbound.conf index 42b2d4d8..df0c76ff 100644 --- a/optional/unbound/unbound.conf +++ b/optional/unbound/unbound.conf @@ -17,5 +17,4 @@ server: hide-identity: yes hide-version: yes cache-min-ttl: 300 - qname-minimisation: yes From 65133a960af543687c00c09068cdbdf10c2f7ff1 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Tue, 28 Sep 2021 10:38:37 +0200 Subject: [PATCH 06/33] Prevent traceback when using non-email in login There's a traceback when the username used to log via SMTPAUTH in is not an email address: === before === ``` [...] ERROR in app: Exception on /internal/auth/email [GET] Traceback (most recent call last): File "/usr/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 1179, in _execute_context context = constructor(dialect, self, conn, *args) File "/usr/lib/python3.9/site-packages/sqlalchemy/engine/default.py", line 719, in _init_compiled param.append(processors[key](compiled_params[key])) File "/usr/lib/python3.9/site-packages/sqlalchemy/sql/type_api.py", line 1201, in process return process_param(value, dialect) File "/app/mailu/models.py", line 60, in process_bind_param localpart, domain_name = value.lower().rsplit('@', 1) ValueError: not enough values to unpack (expected 2, got 1) [...] [parameters: [{'%(140657157923216 param)s': 'foobar'}]] ``` === after === ``` [...] WARNING in nginx: Invalid user 'foobar': (builtins.ValueError) invalid email address (no "@") ``` --- core/admin/mailu/internal/nginx.py | 23 ++++++++++++++--------- core/admin/mailu/models.py | 2 ++ 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/core/admin/mailu/internal/nginx.py b/core/admin/mailu/internal/nginx.py index 167341e2..f011bf5a 100644 --- a/core/admin/mailu/internal/nginx.py +++ b/core/admin/mailu/internal/nginx.py @@ -5,6 +5,7 @@ import re import urllib import ipaddress import socket +import sqlalchemy.exc import tenacity SUPPORTED_AUTH_METHODS = ["none", "plain"] @@ -90,15 +91,19 @@ def handle_authentication(headers): except: app.logger.warn(f'Received undecodable user/password from nginx: {raw_user_email!r}/{raw_password!r}') else: - user = models.User.query.get(user_email) - ip = urllib.parse.unquote(headers["Client-Ip"]) - if check_credentials(user, password, ip, protocol): - server, port = get_server(headers["Auth-Protocol"], True) - return { - "Auth-Status": "OK", - "Auth-Server": server, - "Auth-Port": port - } + try: + user = models.User.query.get(user_email) + except sqlalchemy.exc.StatementError as exc: + exc = str(exc).split('\n', 1)[0] + app.logger.warn(f'Invalid user {user_email!r}: {exc}') + else: + if check_credentials(user, password, urllib.parse.unquote(headers["Client-Ip"]), protocol): + server, port = get_server(headers["Auth-Protocol"], True) + return { + "Auth-Status": "OK", + "Auth-Server": server, + "Auth-Port": port + } status, code = get_status(protocol, "authentication") return { "Auth-Status": status, diff --git a/core/admin/mailu/models.py b/core/admin/mailu/models.py index f93b158f..01711a60 100644 --- a/core/admin/mailu/models.py +++ b/core/admin/mailu/models.py @@ -57,6 +57,8 @@ class IdnaEmail(db.TypeDecorator): def process_bind_param(self, value, dialect): """ encode unicode domain part of email address to punycode """ + if not '@' in value: + raise ValueError('invalid email address (no "@")') localpart, domain_name = value.lower().rsplit('@', 1) if '@' in localpart: raise ValueError('email local part must not contain "@"') From cd17aa0c43f33821a36fbc6fca50bf9cd059a3ff Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Tue, 28 Sep 2021 11:06:59 +0200 Subject: [PATCH 07/33] repair failing health-check --- webmails/roundcube/Dockerfile | 2 +- webmails/roundcube/mailu.php | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/webmails/roundcube/Dockerfile b/webmails/roundcube/Dockerfile index 32f71ea5..2905d30e 100644 --- a/webmails/roundcube/Dockerfile +++ b/webmails/roundcube/Dockerfile @@ -55,4 +55,4 @@ VOLUME ["/data"] CMD /start.py -HEALTHCHECK CMD curl -f -L http://localhost/ || exit 1 +HEALTHCHECK CMD curl -f -L -H 'User-Agent: health' http://localhost/ || exit 1 diff --git a/webmails/roundcube/mailu.php b/webmails/roundcube/mailu.php index bb4d65e9..f5079e98 100644 --- a/webmails/roundcube/mailu.php +++ b/webmails/roundcube/mailu.php @@ -52,6 +52,12 @@ class mailu extends rcube_plugin } function login_failed($args) { + $ua = $_SERVER['HTTP_USER_AGENT']; + $ra = $_SERVER['REMOTE_ADDR']; + if ($ua == 'health' and ($ra == '127.0.0.1' or $ra == '::1')) { + echo "OK"; + exit; + } header('Location: sso.php'); exit(); } From 7380b248cf9cca970f7cb26e2cc54ff8d2553888 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Tue, 28 Sep 2021 11:16:40 +0200 Subject: [PATCH 08/33] direct logging of php errors to stderr --- webmails/roundcube/Dockerfile | 4 ++-- webmails/roundcube/start.py | 3 --- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/webmails/roundcube/Dockerfile b/webmails/roundcube/Dockerfile index 2905d30e..c751b6bf 100644 --- a/webmails/roundcube/Dockerfile +++ b/webmails/roundcube/Dockerfile @@ -38,9 +38,9 @@ RUN apt-get update && apt-get install -y \ && sed -i 's,^php_value.*post_max_size,#&,g' .htaccess \ && sed -i 's,^php_value.*upload_max_filesize,#&,g' .htaccess \ && ln -sf index.php /var/www/html/sso.php \ + && ln -sf /dev/stderr /var/www/html/logs/errors.log \ && chown -R root:root . \ - && touch logs/errors.log \ - && chown -R www-data:www-data logs temp \ + && chown www-data:www-data logs temp \ && chmod -R a+rX . \ && rm -rf /var/lib/apt/lists \ && a2enmod rewrite deflate expires headers diff --git a/webmails/roundcube/start.py b/webmails/roundcube/start.py index 82c4c26f..efaac357 100755 --- a/webmails/roundcube/start.py +++ b/webmails/roundcube/start.py @@ -57,8 +57,5 @@ except subprocess.CalledProcessError as e: # Setup database permissions os.system("chown -R www-data:www-data /data") -# Tail roundcube logs -subprocess.Popen(["tail", "-f", "-n", "0", "/var/www/html/logs/errors.log"]) - # Run apache os.execv("/usr/local/bin/apache2-foreground", ["apache2-foreground"]) From ef9e1ac27997128ee982fb92c5183ade34accf4c Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Tue, 28 Sep 2021 12:29:57 +0200 Subject: [PATCH 09/33] remove health check from log --- webmails/roundcube/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/webmails/roundcube/Dockerfile b/webmails/roundcube/Dockerfile index c751b6bf..1f788918 100644 --- a/webmails/roundcube/Dockerfile +++ b/webmails/roundcube/Dockerfile @@ -11,7 +11,8 @@ FROM build_${QEMU} RUN apt-get update && apt-get install -y \ python3 curl python3-pip git python3-multidict \ && rm -rf /var/lib/apt/lists \ - && echo "ServerSignature Off" >> /etc/apache2/apache2.conf + && echo "ServerSignature Off\nServerName roundcube" >> /etc/apache2/apache2.conf \ + && sed -i 's,CustomLog.*combined$,\0 "'"expr=!(%{HTTP_USER_AGENT}=='health'\&\&(-R '127.0.0.1/8' || -R '::1'))"'",' /etc/apache2/sites-available/000-default.conf # Shared layer between nginx, dovecot, postfix, postgresql, rspamd, unbound, rainloop, roundcube RUN pip3 install socrate From 995ce8d4374e501e3733ea2cf2f1d96070b172ef Mon Sep 17 00:00:00 2001 From: Florent Daigniere Date: Fri, 1 Oct 2021 14:54:04 +0200 Subject: [PATCH 10/33] Remove OUTCLEAN_ADDRESS I believe that this isn't relevant anymore as we don't use OpenDKIM anymore Background on: https://bofhskull.wordpress.com/2014/03/25/postfix-opendkim-and-missing-from-header/ --- core/postfix/conf/outclean_header_filter.cf | 5 +---- core/postfix/start.py | 9 --------- towncrier/newsfragments/446.feature | 1 + 3 files changed, 2 insertions(+), 13 deletions(-) create mode 100644 towncrier/newsfragments/446.feature diff --git a/core/postfix/conf/outclean_header_filter.cf b/core/postfix/conf/outclean_header_filter.cf index 7e0e92d3..6a5d6b5b 100644 --- a/core/postfix/conf/outclean_header_filter.cf +++ b/core/postfix/conf/outclean_header_filter.cf @@ -1,10 +1,7 @@ # This configuration was copied from Mailinabox. The original version is available at: # https://raw.githubusercontent.com/mail-in-a-box/mailinabox/master/conf/postfix_outgoing_mail_header_filters -# Remove the first line of the Received: header. Note that we cannot fully remove the Received: header -# because OpenDKIM requires that a header be present when signing outbound mail. The first line is -# where the user's home IP address would be. -/^\s*Received:[^\n]*(.*)/ REPLACE Received: from authenticated-user ({{OUTCLEAN}} [{{OUTCLEAN_ADDRESS}}])$1 +/^\s*Received:[^\n]*(.*)/ IGNORE # Remove other typically private information. /^\s*User-Agent:/ IGNORE diff --git a/core/postfix/start.py b/core/postfix/start.py index 12610bd0..c889dce1 100755 --- a/core/postfix/start.py +++ b/core/postfix/start.py @@ -46,15 +46,6 @@ os.environ["FRONT_ADDRESS"] = system.get_host_address_from_environment("FRONT", os.environ["ADMIN_ADDRESS"] = system.get_host_address_from_environment("ADMIN", "admin") os.environ["ANTISPAM_MILTER_ADDRESS"] = system.get_host_address_from_environment("ANTISPAM_MILTER", "antispam:11332") os.environ["LMTP_ADDRESS"] = system.get_host_address_from_environment("LMTP", "imap:2525") -os.environ["OUTCLEAN"] = os.environ["HOSTNAMES"].split(",")[0] -try: - _to_lookup = os.environ["OUTCLEAN"] - # Ensure we lookup a FQDN: @see #1884 - if not _to_lookup.endswith('.'): - _to_lookup += '.' - os.environ["OUTCLEAN_ADDRESS"] = system.resolve_hostname(_to_lookup) -except: - os.environ["OUTCLEAN_ADDRESS"] = "10.10.10.10" for postfix_file in glob.glob("/conf/*.cf"): conf.jinja(postfix_file, os.environ, os.path.join("/etc/postfix", os.path.basename(postfix_file))) diff --git a/towncrier/newsfragments/446.feature b/towncrier/newsfragments/446.feature new file mode 100644 index 00000000..12049b94 --- /dev/null +++ b/towncrier/newsfragments/446.feature @@ -0,0 +1 @@ +Remove the Received header with PRIMARY_HOSTNAME [PUBLIC_IP] From 10d78a888bf4a509e36bb96cd0548cd11ee2b585 Mon Sep 17 00:00:00 2001 From: Florent Daigniere Date: Fri, 1 Oct 2021 15:00:10 +0200 Subject: [PATCH 11/33] Derive a new subkey for SRS --- core/admin/mailu/__init__.py | 1 + core/admin/mailu/internal/views/postfix.py | 4 ++-- towncrier/newsfragments/1999.enhancement | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 towncrier/newsfragments/1999.enhancement diff --git a/core/admin/mailu/__init__.py b/core/admin/mailu/__init__.py index 9b712512..51532968 100644 --- a/core/admin/mailu/__init__.py +++ b/core/admin/mailu/__init__.py @@ -29,6 +29,7 @@ def create_app_from_config(config): utils.migrate.init_app(app, models.db) app.temp_token_key = hmac.new(bytearray(app.secret_key, 'utf-8'), bytearray('WEBMAIL_TEMP_TOKEN_KEY', 'utf-8'), 'sha256').digest() + app.srs_key = hmac.new(bytearray(app.secret_key, 'utf-8'), bytearray('SRS_KEY', 'utf-8'), 'sha256').digest() # Initialize list of translations config.translations = { diff --git a/core/admin/mailu/internal/views/postfix.py b/core/admin/mailu/internal/views/postfix.py index 330fed5b..928f4faf 100644 --- a/core/admin/mailu/internal/views/postfix.py +++ b/core/admin/mailu/internal/views/postfix.py @@ -108,7 +108,7 @@ def postfix_recipient_map(recipient): This is meant for bounces to go back to the original sender. """ - srs = srslib.SRS(flask.current_app.config["SECRET_KEY"]) + srs = srslib.SRS(flask.current_app.srs_key) if srslib.SRS.is_srs_address(recipient): try: return flask.jsonify(srs.reverse(recipient)) @@ -123,7 +123,7 @@ def postfix_sender_map(sender): This is for bounces to come back the reverse path properly. """ - srs = srslib.SRS(flask.current_app.config["SECRET_KEY"]) + srs = srslib.SRS(flask.current_app.srs_key) domain = flask.current_app.config["DOMAIN"] try: localpart, domain_name = models.Email.resolve_domain(sender) diff --git a/towncrier/newsfragments/1999.enhancement b/towncrier/newsfragments/1999.enhancement new file mode 100644 index 00000000..bd025141 --- /dev/null +++ b/towncrier/newsfragments/1999.enhancement @@ -0,0 +1 @@ +Derive a new subkey (from SECRET_KEY) for SRS From 65ee1c1ef27eb7fe3e8c6c6f8b116180c6fcd7bc Mon Sep 17 00:00:00 2001 From: Florent Daigniere Date: Fri, 1 Oct 2021 15:04:45 +0200 Subject: [PATCH 12/33] doh --- towncrier/newsfragments/{446.feature => 466.feature} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename towncrier/newsfragments/{446.feature => 466.feature} (100%) diff --git a/towncrier/newsfragments/446.feature b/towncrier/newsfragments/466.feature similarity index 100% rename from towncrier/newsfragments/446.feature rename to towncrier/newsfragments/466.feature From 4a78d646db1648a0277c4ffe4684cdc435da0391 Mon Sep 17 00:00:00 2001 From: Florent Daigniere Date: Fri, 1 Oct 2021 15:05:38 +0200 Subject: [PATCH 13/33] doh --- towncrier/newsfragments/{1999.enhancement => 2002.enhancement} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename towncrier/newsfragments/{1999.enhancement => 2002.enhancement} (100%) diff --git a/towncrier/newsfragments/1999.enhancement b/towncrier/newsfragments/2002.enhancement similarity index 100% rename from towncrier/newsfragments/1999.enhancement rename to towncrier/newsfragments/2002.enhancement From a349190e5232fddd927b460215f71325caf76b05 Mon Sep 17 00:00:00 2001 From: Florent Daigniere Date: Sat, 2 Oct 2021 10:19:57 +0200 Subject: [PATCH 14/33] simplify --- core/postfix/conf/outclean_header_filter.cf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/postfix/conf/outclean_header_filter.cf b/core/postfix/conf/outclean_header_filter.cf index 6a5d6b5b..35b90ff5 100644 --- a/core/postfix/conf/outclean_header_filter.cf +++ b/core/postfix/conf/outclean_header_filter.cf @@ -1,7 +1,7 @@ # This configuration was copied from Mailinabox. The original version is available at: # https://raw.githubusercontent.com/mail-in-a-box/mailinabox/master/conf/postfix_outgoing_mail_header_filters -/^\s*Received:[^\n]*(.*)/ IGNORE +/^\s*Received:[^\n]*/ IGNORE # Remove other typically private information. /^\s*User-Agent:/ IGNORE From 502affbe66eafb6a8eba4f8d36ab8fef94e5eeb7 Mon Sep 17 00:00:00 2001 From: Florent Daigniere Date: Sun, 3 Oct 2021 10:14:49 +0200 Subject: [PATCH 15/33] Use the regexp engine since we have one --- core/postfix/conf/outclean_header_filter.cf | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/core/postfix/conf/outclean_header_filter.cf b/core/postfix/conf/outclean_header_filter.cf index 35b90ff5..9c880843 100644 --- a/core/postfix/conf/outclean_header_filter.cf +++ b/core/postfix/conf/outclean_header_filter.cf @@ -1,14 +1,8 @@ # This configuration was copied from Mailinabox. The original version is available at: # https://raw.githubusercontent.com/mail-in-a-box/mailinabox/master/conf/postfix_outgoing_mail_header_filters -/^\s*Received:[^\n]*/ IGNORE - -# Remove other typically private information. -/^\s*User-Agent:/ IGNORE -/^\s*X-Enigmail:/ IGNORE -/^\s*X-Mailer:/ IGNORE -/^\s*X-Originating-IP:/ IGNORE -/^\s*X-Pgp-Agent:/ IGNORE +# Remove typically private information. +/^\s*(Received|User-Agent|X-(Enigmail|Mailer|Originating-IP|Pgp-Agent)):/ IGNORE # The Mime-Version header can leak the user agent too, e.g. in Mime-Version: 1.0 (Mac OS X Mail 8.1 \(2010.6\)). /^\s*(Mime-Version:\s*[0-9\.]+)\s.+/ REPLACE $1 From b48779ea7084278d494e436386d06fd5e55161d6 Mon Sep 17 00:00:00 2001 From: Florent Daigniere Date: Fri, 8 Oct 2021 10:17:03 +0200 Subject: [PATCH 16/33] SESSION_COOKIE_SECURE and HTTP won't work --- core/admin/mailu/ui/templates/login.html | 12 ++++++++++++ towncrier/newsfragments/1996.enhancement | 1 + 2 files changed, 13 insertions(+) create mode 100644 towncrier/newsfragments/1996.enhancement diff --git a/core/admin/mailu/ui/templates/login.html b/core/admin/mailu/ui/templates/login.html index fb8e5bd4..118173cb 100644 --- a/core/admin/mailu/ui/templates/login.html +++ b/core/admin/mailu/ui/templates/login.html @@ -7,3 +7,15 @@ {%- block subtitle %} {% trans %}to access the administration tools{% endtrans %} {%- endblock %} + +{%+ block content %} +{% if config["SESSION_COOKIE_SECURE"] %} + +{% endif %} +{{ super() }} +{%+ endblock %} diff --git a/towncrier/newsfragments/1996.enhancement b/towncrier/newsfragments/1996.enhancement new file mode 100644 index 00000000..d1bc2ccf --- /dev/null +++ b/towncrier/newsfragments/1996.enhancement @@ -0,0 +1 @@ +Disable the login page if SESSION_COOKIE_SECURE is incompatible with how Mailu is accessed as this seems to be a common misconfiguration. From aaf3ddd002b87dfccd09e82a00830364a19aeed1 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 8 Oct 2021 19:54:31 +0200 Subject: [PATCH 17/33] moved javascript to app.js --- core/admin/assets/app.js | 7 +++++++ core/admin/mailu/ui/templates/login.html | 15 ++++++--------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/core/admin/assets/app.js b/core/admin/assets/app.js index dc3414f2..5df8052c 100644 --- a/core/admin/assets/app.js +++ b/core/admin/assets/app.js @@ -66,5 +66,12 @@ $('document').ready(function() { // init clipboard.js new ClipboardJS('.btn-clip'); + // disable login if not possible + var l = $('#login_needs_https'); + if (l.length && window.location.protocol != 'https:') { + l.removeClass("d-none"); + $('form :input').prop('disabled', true); + } + }); diff --git a/core/admin/mailu/ui/templates/login.html b/core/admin/mailu/ui/templates/login.html index 118173cb..4c38d134 100644 --- a/core/admin/mailu/ui/templates/login.html +++ b/core/admin/mailu/ui/templates/login.html @@ -8,14 +8,11 @@ {% trans %}to access the administration tools{% endtrans %} {%- endblock %} -{%+ block content %} {% if config["SESSION_COOKIE_SECURE"] %} - -{% endif %} +{%- block content %} + {{ super() }} -{%+ endblock %} +{%- endblock %} +{% endif %} From d131d863baca9616bb2251aa44dd658167888966 Mon Sep 17 00:00:00 2001 From: Florent Daigniere Date: Sat, 9 Oct 2021 15:44:56 +0200 Subject: [PATCH 18/33] The if needs to be inside the block --- core/admin/mailu/ui/templates/login.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/admin/mailu/ui/templates/login.html b/core/admin/mailu/ui/templates/login.html index 4c38d134..d4d115db 100644 --- a/core/admin/mailu/ui/templates/login.html +++ b/core/admin/mailu/ui/templates/login.html @@ -8,11 +8,11 @@ {% trans %}to access the administration tools{% endtrans %} {%- endblock %} -{% if config["SESSION_COOKIE_SECURE"] %} {%- block content %} +{% if config["SESSION_COOKIE_SECURE"] %} +{% endif %} {{ super() }} {%- endblock %} -{% endif %} From 1d571dedfc5df67dd9b47d1f235edbc1198afbca Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Sat, 9 Oct 2021 17:11:12 +0200 Subject: [PATCH 19/33] split localpart into user and tag --- core/admin/mailu/internal/views/postfix.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/admin/mailu/internal/views/postfix.py b/core/admin/mailu/internal/views/postfix.py index 928f4faf..d2c9f877 100644 --- a/core/admin/mailu/internal/views/postfix.py +++ b/core/admin/mailu/internal/views/postfix.py @@ -140,7 +140,8 @@ def postfix_sender_login(sender): localpart, domain_name = models.Email.resolve_domain(sender) if localpart is None: return flask.jsonify(",".join(wildcard_senders)) if wildcard_senders else flask.abort(404) - destination = models.Email.resolve_destination(localpart, domain_name, True) + user, plus = localpart.split("+", 1) + destination = models.Email.resolve_destination(user, domain_name, True) destination = [*destination, *wildcard_senders] if destination else [*wildcard_senders] return flask.jsonify(",".join(destination)) if destination else flask.abort(404) From 22ed2b7f904271d2a7b524b390ccbbc00536fdfd Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Sat, 9 Oct 2021 17:17:40 +0200 Subject: [PATCH 20/33] add newsfragment --- towncrier/newsfragments/2006.enhancement | 1 + 1 file changed, 1 insertion(+) create mode 100644 towncrier/newsfragments/2006.enhancement diff --git a/towncrier/newsfragments/2006.enhancement b/towncrier/newsfragments/2006.enhancement new file mode 100644 index 00000000..802e6d36 --- /dev/null +++ b/towncrier/newsfragments/2006.enhancement @@ -0,0 +1 @@ +allow sending emails as user+detail@domain.tld From 6a8066c0ae1597fc0b85d9130978ff1af778d70f Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Sat, 9 Oct 2021 17:18:53 +0200 Subject: [PATCH 21/33] renamed newsfragment --- towncrier/newsfragments/{2006.enhancement => 2007.enhancement} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename towncrier/newsfragments/{2006.enhancement => 2007.enhancement} (100%) diff --git a/towncrier/newsfragments/2006.enhancement b/towncrier/newsfragments/2007.enhancement similarity index 100% rename from towncrier/newsfragments/2006.enhancement rename to towncrier/newsfragments/2007.enhancement From 8c59f3569760513774ad8a48d1a30d336ce2f259 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 9 Oct 2021 17:43:09 +0200 Subject: [PATCH 22/33] use RECIPIENT_DELIMITER for splitting --- core/admin/mailu/configuration.py | 1 + core/admin/mailu/internal/views/postfix.py | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/core/admin/mailu/configuration.py b/core/admin/mailu/configuration.py index 4401888a..8d4d334a 100644 --- a/core/admin/mailu/configuration.py +++ b/core/admin/mailu/configuration.py @@ -49,6 +49,7 @@ DEFAULT_CONFIG = { 'DKIM_PATH': '/dkim/{domain}.{selector}.key', 'DEFAULT_QUOTA': 1000000000, 'MESSAGE_RATELIMIT': '200/day', + 'RECIPIENT_DELIMITER': None, # Web settings 'SITENAME': 'Mailu', 'WEBSITE': 'https://mailu.io', diff --git a/core/admin/mailu/internal/views/postfix.py b/core/admin/mailu/internal/views/postfix.py index d2c9f877..44a685c9 100644 --- a/core/admin/mailu/internal/views/postfix.py +++ b/core/admin/mailu/internal/views/postfix.py @@ -140,8 +140,9 @@ def postfix_sender_login(sender): localpart, domain_name = models.Email.resolve_domain(sender) if localpart is None: return flask.jsonify(",".join(wildcard_senders)) if wildcard_senders else flask.abort(404) - user, plus = localpart.split("+", 1) - destination = models.Email.resolve_destination(user, domain_name, True) + if delim := flask.current_app.config.get('RECIPIENT_DELIMITER'): + localpart = localpart.split(delim, 1)[0] + destination = models.Email.resolve_destination(localpart, domain_name, True) destination = [*destination, *wildcard_senders] if destination else [*wildcard_senders] return flask.jsonify(",".join(destination)) if destination else flask.abort(404) From 14360f8926461c62c019c62338fef1be2308f133 Mon Sep 17 00:00:00 2001 From: Florent Daigniere Date: Sat, 9 Oct 2021 18:28:50 +0200 Subject: [PATCH 23/33] RECIPIENT_DELIMITER can have several characters --- core/admin/mailu/configuration.py | 2 +- core/admin/mailu/internal/views/postfix.py | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/core/admin/mailu/configuration.py b/core/admin/mailu/configuration.py index 8d4d334a..1f2a9239 100644 --- a/core/admin/mailu/configuration.py +++ b/core/admin/mailu/configuration.py @@ -49,7 +49,7 @@ DEFAULT_CONFIG = { 'DKIM_PATH': '/dkim/{domain}.{selector}.key', 'DEFAULT_QUOTA': 1000000000, 'MESSAGE_RATELIMIT': '200/day', - 'RECIPIENT_DELIMITER': None, + 'RECIPIENT_DELIMITER': '', # Web settings 'SITENAME': 'Mailu', 'WEBSITE': 'https://mailu.io', diff --git a/core/admin/mailu/internal/views/postfix.py b/core/admin/mailu/internal/views/postfix.py index 44a685c9..ab965967 100644 --- a/core/admin/mailu/internal/views/postfix.py +++ b/core/admin/mailu/internal/views/postfix.py @@ -140,8 +140,7 @@ def postfix_sender_login(sender): localpart, domain_name = models.Email.resolve_domain(sender) if localpart is None: return flask.jsonify(",".join(wildcard_senders)) if wildcard_senders else flask.abort(404) - if delim := flask.current_app.config.get('RECIPIENT_DELIMITER'): - localpart = localpart.split(delim, 1)[0] + localpart = localpart[:next((i for i, ch in enumerate(localpart) if ch in flask.current_app.config.get('RECIPIENT_DELIMITER')), None)] destination = models.Email.resolve_destination(localpart, domain_name, True) destination = [*destination, *wildcard_senders] if destination else [*wildcard_senders] return flask.jsonify(",".join(destination)) if destination else flask.abort(404) From e127e6b32f8cf83123a5bcfa9431f4caeab80e22 Mon Sep 17 00:00:00 2001 From: Florent Daigniere Date: Sat, 9 Oct 2021 18:58:51 +0200 Subject: [PATCH 24/33] clarify the documentation --- docs/configuration.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/configuration.rst b/docs/configuration.rst index 5f17b57e..5d8e87b1 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -93,9 +93,10 @@ go and fetch new email if available. Do not use too short delays if you do not want to be blacklisted by external services, but not too long delays if you want to receive your email in time. -The ``RECIPIENT_DELIMITER`` is a character used to delimit localpart from a -custom address part. For instance, if set to ``+``, users can use addresses -like ``localpart+custom@domain.tld`` to deliver mail to ``localpart@domain.tld``. +The ``RECIPIENT_DELIMITER`` is a list of characters used to delimit localpart +from a custom address part. For instance, if set to ``+-``, users can use +addresses like ``localpart+custom@example.com`` or ``localpart-custom@example.com`` +to deliver mail to ``localpart@example.com``. This is useful to provide external parties with different email addresses and later classify incoming mail based on the custom part. From 251eea55539856eeb984fa6ac93e601b5017f1a2 Mon Sep 17 00:00:00 2001 From: qy117121 Date: Thu, 14 Oct 2021 15:03:23 +0800 Subject: [PATCH 25/33] Update messages.po Updated translation --- .../zh_CN/LC_MESSAGES/messages.po | 546 +++++++++--------- 1 file changed, 261 insertions(+), 285 deletions(-) diff --git a/core/admin/mailu/translations/zh_CN/LC_MESSAGES/messages.po b/core/admin/mailu/translations/zh_CN/LC_MESSAGES/messages.po index ee204fec..a3363169 100644 --- a/core/admin/mailu/translations/zh_CN/LC_MESSAGES/messages.po +++ b/core/admin/mailu/translations/zh_CN/LC_MESSAGES/messages.po @@ -3,9 +3,11 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: POEditor.com\n" +"X-Generator: Poedit 1.5.7\n" "Project-Id-Version: Mailu\n" -"Language: zh-CN\n" +"Language: zh\n" +"Last-Translator: Chris Chuan \n" +"Language-Team: \n" #: mailu/ui/forms.py:32 msgid "Invalid email address." @@ -28,7 +30,7 @@ msgstr "密码" #: mailu/ui/forms.py:42 mailu/ui/templates/login.html:4 #: mailu/ui/templates/sidebar.html:111 msgid "Sign in" -msgstr "注册" +msgstr "登录" #: mailu/ui/forms.py:46 mailu/ui/forms.py:56 #: mailu/ui/templates/domain/details.html:27 @@ -44,6 +46,14 @@ msgstr "最大用户数" msgid "Maximum alias count" msgstr "最大别名数" +#: mailu/ui/forms.py:49 +msgid "Maximum user quota" +msgstr "最大用户配额" + +#: mailu/ui/forms.py:50 +msgid "Enable sign-up" +msgstr "启用注册" + #: mailu/ui/forms.py:51 mailu/ui/forms.py:72 mailu/ui/forms.py:83 #: mailu/ui/forms.py:128 mailu/ui/forms.py:140 #: mailu/ui/templates/alias/list.html:21 mailu/ui/templates/domain/list.html:21 @@ -57,10 +67,30 @@ msgstr "说明" msgid "Create" msgstr "创建" +#: mailu/ui/forms.py:57 +msgid "Initial admin" +msgstr "初始管理员" + +#: mailu/ui/forms.py:58 +msgid "Admin password" +msgstr "管理员密码" + #: mailu/ui/forms.py:59 mailu/ui/forms.py:79 mailu/ui/forms.py:91 msgid "Confirm password" msgstr "确认密码" +#: mailu/ui/forms.py:65 +msgid "Alternative name" +msgstr "备用名称" + +#: mailu/ui/forms.py:70 +msgid "Relayed domain name" +msgstr "中继域域名" + +#: mailu/ui/forms.py:71 mailu/ui/templates/relay/list.html:18 +msgid "Remote host" +msgstr "远程主机" + #: mailu/ui/forms.py:80 mailu/ui/templates/user/list.html:22 #: mailu/ui/templates/user/signup_domain.html:16 msgid "Quota" @@ -68,16 +98,30 @@ msgstr "配额" #: mailu/ui/forms.py:81 msgid "Allow IMAP access" -msgstr "允许IMAP访问" +msgstr "允许 IMAP 访问" #: mailu/ui/forms.py:82 msgid "Allow POP3 access" -msgstr "允许POP3访问" +msgstr "允许 POP3 访问" + +#: mailu/ui/forms.py:84 +msgid "Enabled" +msgstr "启用" #: mailu/ui/forms.py:85 msgid "Save" msgstr "保存" +#: mailu/ui/forms.py:89 +msgid "Email address" +msgstr "邮件地址" + +#: mailu/ui/forms.py:93 mailu/ui/templates/sidebar.html:117 +#: mailu/ui/templates/user/signup.html:4 +#: mailu/ui/templates/user/signup_domain.html:4 +msgid "Sign up" +msgstr "注册" + #: mailu/ui/forms.py:97 msgid "Displayed name" msgstr "显示名称" @@ -86,10 +130,23 @@ msgstr "显示名称" msgid "Enable spam filter" msgstr "启用垃圾邮件过滤" -#: mailu/ui/forms.py:80 -msgid "Spam filter threshold" +#: mailu/ui/forms.py:99 +msgid "Spam filter tolerance" msgstr "垃圾邮件过滤器阈值" +#: mailu/ui/forms.py:100 +msgid "Enable forwarding" +msgstr "启用转发" + +#: mailu/ui/forms.py:101 +msgid "Keep a copy of the emails" +msgstr "保留电子邮件副本" + +#: mailu/ui/forms.py:103 mailu/ui/forms.py:139 +#: mailu/ui/templates/alias/list.html:20 +msgid "Destination" +msgstr "目的地址" + #: mailu/ui/forms.py:105 msgid "Save settings" msgstr "保存设置" @@ -102,19 +159,6 @@ msgstr "检查密码" msgid "Update password" msgstr "更新密码" -#: mailu/ui/forms.py:100 -msgid "Enable forwarding" -msgstr "启用转发" - -#: mailu/ui/forms.py:103 mailu/ui/forms.py:139 -#: mailu/ui/templates/alias/list.html:20 -msgid "Destination" -msgstr "目的地址" - -#: mailu/ui/forms.py:120 -msgid "Update" -msgstr "更新" - #: mailu/ui/forms.py:115 msgid "Enable automatic reply" msgstr "启用自动回复" @@ -127,6 +171,22 @@ msgstr "回复主题" msgid "Reply body" msgstr "回复正文" +#: mailu/ui/forms.py:119 +msgid "End of vacation" +msgstr "假期结束" + +#: mailu/ui/forms.py:120 +msgid "Update" +msgstr "更新" + +#: mailu/ui/forms.py:125 +msgid "Your token (write it down, as it will never be displayed again)" +msgstr "您的令牌(请记录,它只显示这一次)" + +#: mailu/ui/forms.py:130 mailu/ui/templates/token/list.html:20 +msgid "Authorized IP" +msgstr "授权 IP" + #: mailu/ui/forms.py:136 msgid "Alias" msgstr "别名" @@ -169,70 +229,67 @@ msgstr "启用TLS" msgid "Username" msgstr "用户名" +#: mailu/ui/forms.py:163 +msgid "Keep emails on the server" +msgstr "在服务器上保留电子邮件" + +#: mailu/ui/forms.py:168 +msgid "Announcement subject" +msgstr "公告主题" + +#: mailu/ui/forms.py:170 +msgid "Announcement body" +msgstr "公告正文" + +#: mailu/ui/forms.py:172 +msgid "Send" +msgstr "发送" + +#: mailu/ui/templates/announcement.html:4 +msgid "Public announcement" +msgstr "公开公告" + +#: mailu/ui/templates/client.html:4 mailu/ui/templates/sidebar.html:82 +msgid "Client setup" +msgstr "客户端设置" + +#: mailu/ui/templates/client.html:16 mailu/ui/templates/client.html:43 +msgid "Mail protocol" +msgstr "邮件协议" + +#: mailu/ui/templates/client.html:24 mailu/ui/templates/client.html:51 +msgid "Server name" +msgstr "服务器名称" + #: mailu/ui/templates/confirm.html:4 msgid "Confirm action" msgstr "确认操作" #: mailu/ui/templates/confirm.html:13 +#, python-format msgid "You are about to %(action)s. Please confirm your action." msgstr "即将%(action)s,请确认您的操作。" #: mailu/ui/templates/docker-error.html:4 msgid "Docker error" -msgstr "Docker错误" +msgstr "Docker 错误" #: mailu/ui/templates/docker-error.html:12 msgid "An error occurred while talking to the Docker server." msgstr "Docker服务器通信出错" -#: mailu/admin/templates/login.html:6 -msgid "Your account" -msgstr "你的帐户" - #: mailu/ui/templates/login.html:8 msgid "to access the administration tools" -msgstr "访问管理员工具" - -#: mailu/ui/templates/services.html:4 mailu/ui/templates/sidebar.html:39 -msgid "Services status" -msgstr "服务状态" - -#: mailu/ui/templates/services.html:10 -msgid "Service" -msgstr "服务" - -#: mailu/ui/templates/fetch/list.html:23 mailu/ui/templates/services.html:11 -msgid "Status" -msgstr "状态" - -#: mailu/ui/templates/services.html:12 -msgid "PID" -msgstr "进程ID" - -#: mailu/ui/templates/services.html:13 -msgid "Image" -msgstr "镜像" - -#: mailu/ui/templates/services.html:14 -msgid "Started" -msgstr "已开始" - -#: mailu/ui/templates/services.html:15 -msgid "Last update" -msgstr "最后更新" +msgstr "访问管理工具" #: mailu/ui/templates/sidebar.html:8 msgid "My account" -msgstr "我的帐户" +msgstr "我的账户" #: mailu/ui/templates/sidebar.html:11 mailu/ui/templates/user/list.html:34 msgid "Settings" msgstr "设置" -#: mailu/ui/templates/user/settings.html:22 -msgid "Auto-forward" -msgstr "自动转发" - #: mailu/ui/templates/sidebar.html:21 mailu/ui/templates/user/list.html:35 msgid "Auto-reply" msgstr "自动回复" @@ -240,39 +297,71 @@ msgstr "自动回复" #: mailu/ui/templates/fetch/list.html:4 mailu/ui/templates/sidebar.html:26 #: mailu/ui/templates/user/list.html:36 msgid "Fetched accounts" -msgstr "代收帐户" +msgstr "代收账户" -#: mailu/ui/templates/sidebar.html:105 -msgid "Sign out" -msgstr "登出" +#: mailu/ui/templates/sidebar.html:31 mailu/ui/templates/token/list.html:4 +msgid "Authentication tokens" +msgstr "认证令牌" #: mailu/ui/templates/sidebar.html:35 msgid "Administration" msgstr "管理" +#: mailu/ui/templates/sidebar.html:44 +msgid "Announcement" +msgstr "公告" + #: mailu/ui/templates/sidebar.html:49 msgid "Administrators" msgstr "管理员" +#: mailu/ui/templates/sidebar.html:54 +msgid "Relayed domains" +msgstr "中继域" + +#: mailu/ui/templates/sidebar.html:59 mailu/ui/templates/user/settings.html:15 +msgid "Antispam" +msgstr "发垃圾邮件" + #: mailu/ui/templates/sidebar.html:66 msgid "Mail domains" msgstr "邮件域" +#: mailu/ui/templates/sidebar.html:72 +msgid "Go to" +msgstr "转到" + +#: mailu/ui/templates/sidebar.html:76 +msgid "Webmail" +msgstr "网页邮箱" + +#: mailu/ui/templates/sidebar.html:87 +msgid "Website" +msgstr "网站" + #: mailu/ui/templates/sidebar.html:92 msgid "Help" msgstr "帮助" +#: mailu/ui/templates/domain/signup.html:4 mailu/ui/templates/sidebar.html:98 +msgid "Register a domain" +msgstr "注册域名" + +#: mailu/ui/templates/sidebar.html:105 +msgid "Sign out" +msgstr "登出" + #: mailu/ui/templates/working.html:4 msgid "We are still working on this feature!" msgstr "该功能开发中……" #: mailu/ui/templates/admin/create.html:4 msgid "Add a global administrator" -msgstr "添加超级管理员" +msgstr "添加全局管理员" #: mailu/ui/templates/admin/list.html:4 msgid "Global administrators" -msgstr "超级管理员" +msgstr "全局管理员" #: mailu/ui/templates/admin/list.html:9 msgid "Add administrator" @@ -323,7 +412,7 @@ msgstr "添加别名" #: mailu/ui/templates/relay/list.html:20 mailu/ui/templates/token/list.html:21 #: mailu/ui/templates/user/list.html:24 msgid "Created" -msgstr "创建" +msgstr "已创建" #: mailu/ui/templates/alias/list.html:23 mailu/ui/templates/domain/list.html:23 #: mailu/ui/templates/fetch/list.html:25 mailu/ui/templates/relay/list.html:21 @@ -337,6 +426,22 @@ msgstr "上次编辑" msgid "Edit" msgstr "编辑" +#: mailu/ui/templates/alternative/create.html:4 +msgid "Create alternative domain" +msgstr "创建替代域" + +#: mailu/ui/templates/alternative/list.html:4 +msgid "Alternative domain list" +msgstr "替代域名列表" + +#: mailu/ui/templates/alternative/list.html:12 +msgid "Add alternative" +msgstr "添加替代" + +#: mailu/ui/templates/alternative/list.html:19 +msgid "Name" +msgstr "名称" + #: mailu/ui/templates/domain/create.html:4 #: mailu/ui/templates/domain/list.html:9 msgid "New domain" @@ -344,11 +449,15 @@ msgstr "新域" #: mailu/ui/templates/domain/details.html:4 msgid "Domain details" -msgstr "域详情" +msgstr "域详细信息" #: mailu/ui/templates/domain/details.html:15 msgid "Regenerate keys" -msgstr "重新生成密钥" +msgstr "重新生成秘钥" + +#: mailu/ui/templates/domain/details.html:17 +msgid "Generate keys" +msgstr "生成秘钥" #: mailu/ui/templates/domain/details.html:31 msgid "DNS MX entry" @@ -356,19 +465,19 @@ msgstr "DNS MX条目" #: mailu/ui/templates/domain/details.html:35 msgid "DNS SPF entries" -msgstr "DNS SPF条目" +msgstr "DNS SPF 条目" #: mailu/ui/templates/domain/details.html:42 msgid "DKIM public key" -msgstr "DKIM公钥" +msgstr "DKIM 公钥" #: mailu/ui/templates/domain/details.html:46 msgid "DNS DKIM entry" -msgstr "DNS DKIM条目" +msgstr "DNS DKIM 条目" #: mailu/ui/templates/domain/details.html:50 msgid "DNS DMARC entry" -msgstr "DNS DMARC条目" +msgstr "DNS DMARC 条目" #: mailu/ui/templates/domain/edit.html:4 msgid "Edit domain" @@ -392,7 +501,7 @@ msgstr "别名数量" #: mailu/ui/templates/domain/list.html:28 msgid "Details" -msgstr "详情" +msgstr "详细信息" #: mailu/ui/templates/domain/list.html:35 msgid "Users" @@ -406,26 +515,60 @@ msgstr "别名" msgid "Managers" msgstr "管理员" +#: mailu/ui/templates/domain/list.html:39 +msgid "Alternatives" +msgstr "备选方案" + +#: mailu/ui/templates/domain/signup.html:13 +msgid "" +"In order to register a new domain, you must first setup the\n" +" domain zone so that the domain MX points to this server" +msgstr "在注册一个新的域名前,您必须先为该域名设置 MX 记录,并使其指向本服务器" + +#: mailu/ui/templates/domain/signup.html:18 +msgid "" +"If you do not know how to setup an MX record for your DNS " +"zone,\n" +" please contact your DNS provider or administrator. Also, please wait " +"a\n" +" couple minutes after the MX is set so the local server " +"cache\n" +" expires." +msgstr "如果您不知道如何为域名设置 MX 记录,请联系你的DNS提供商或者系统管理员。在设置完成 MX 记录后,请等待本地域名服务器的缓存过期。" + + #: mailu/ui/templates/fetch/create.html:4 msgid "Add a fetched account" -msgstr "添加一个代收帐户" +msgstr "添加一个代收账户" #: mailu/ui/templates/fetch/edit.html:4 msgid "Update a fetched account" -msgstr "更新代收帐户" +msgstr "更新代收账户" #: mailu/ui/templates/fetch/list.html:12 msgid "Add an account" -msgstr "添加一个帐户" +msgstr "添加一个账户" #: mailu/ui/templates/fetch/list.html:19 msgid "Endpoint" msgstr "端点" +#: mailu/ui/templates/fetch/list.html:21 +msgid "Keep emails" +msgstr "保留电子邮件" + #: mailu/ui/templates/fetch/list.html:22 msgid "Last check" msgstr "上次检查" +#: mailu/ui/templates/fetch/list.html:35 +msgid "yes" +msgstr "是" + +#: mailu/ui/templates/fetch/list.html:35 +msgid "no" +msgstr "否" + #: mailu/ui/templates/manager/create.html:4 msgid "Add a manager" msgstr "添加一个管理员" @@ -438,41 +581,49 @@ msgstr "管理员列表" msgid "Add manager" msgstr "添加管理员" -#: mailu/ui/forms.py:168 -msgid "Announcement subject" -msgstr "公告主题" +#: mailu/ui/templates/relay/create.html:4 +msgid "New relay domain" +msgstr "新的中继域" -#: mailu/ui/forms.py:170 -msgid "Announcement body" -msgstr "公告正文" +#: mailu/ui/templates/relay/edit.html:4 +msgid "Edit relayd domain" +msgstr "编辑中继域" -#: mailu/ui/forms.py:172 -msgid "Send" -msgstr "发送" +#: mailu/ui/templates/relay/list.html:4 +msgid "Relayed domain list" +msgstr "中继域列表" -#: mailu/ui/templates/announcement.html:4 -msgid "Public announcement" -msgstr "公告" +#: mailu/ui/templates/relay/list.html:9 +msgid "New relayed domain" +msgstr "新的中继域" -#: mailu/ui/templates/announcement.html:8 -msgid "from" -msgstr "来自" +#: mailu/ui/templates/token/create.html:4 +msgid "Create an authentication token" +msgstr "创建一个认证令牌" -#: mailu/ui/templates/sidebar.html:44 -msgid "Announcement" -msgstr "公告" +#: mailu/ui/templates/token/list.html:12 +msgid "New token" +msgstr "新令牌" #: mailu/ui/templates/user/create.html:4 msgid "New user" msgstr "新用户" +#: mailu/ui/templates/user/create.html:15 +msgid "General" +msgstr "通用" + +#: mailu/ui/templates/user/create.html:22 +msgid "Features and quotas" +msgstr "功能和配额" + #: mailu/ui/templates/user/edit.html:4 msgid "Edit user" msgstr "编辑用户" #: mailu/ui/templates/user/forward.html:4 msgid "Forward emails" -msgstr "转发电子邮件" +msgstr "转发邮件" #: mailu/ui/templates/user/list.html:4 msgid "User list" @@ -492,201 +643,15 @@ msgstr "功能" #: mailu/ui/templates/user/password.html:4 msgid "Password update" -msgstr "密码更新" +msgstr "更新密码" #: mailu/ui/templates/user/reply.html:4 msgid "Automatic reply" msgstr "自动回复" -#: mailu/ui/forms.py:49 -msgid "Maximum user quota" -msgstr "最大用户容量" - -#: mailu/ui/forms.py:101 -msgid "Keep a copy of the emails" -msgstr "保留电子邮件副本" - -#: mailu/ui/forms.py:163 -msgid "Keep emails on the server" -msgstr "保留电子邮件在服务器上" - -#: mailu/ui/templates/fetch/list.html:21 -msgid "Keep emails" -msgstr "保存电子邮件" - -#: mailu/ui/templates/fetch/list.html:35 -msgid "yes" -msgstr "是" - -#: mailu/ui/templates/fetch/list.html:35 -msgid "no" -msgstr "否" - -#: mailu/ui/forms.py:65 -msgid "Alternative name" -msgstr "替代名称" - -#: mailu/ui/forms.py:70 -msgid "Relayed domain name" -msgstr "中继域域名" - -#: mailu/ui/forms.py:71 mailu/ui/templates/relay/list.html:18 -msgid "Remote host" -msgstr "远程主机" - -#: mailu/ui/templates/sidebar.html:54 -msgid "Relayed domains" -msgstr "中继域" - -#: mailu/ui/templates/alternative/create.html:4 -msgid "Create alternative domain" -msgstr "创建替代域" - -#: mailu/ui/templates/alternative/list.html:4 -msgid "Alternative domain list" -msgstr "替代域名列表" - -#: mailu/ui/templates/alternative/list.html:12 -msgid "Add alternative" -msgstr "添加替代" - -#: mailu/ui/templates/alternative/list.html:19 -msgid "Name" -msgstr "名称" - -#: mailu/ui/templates/domain/list.html:39 -msgid "Alternatives" -msgstr "备择方案" - -#: mailu/ui/templates/relay/create.html:4 -msgid "New relay domain" -msgstr "新的中继域" - -#: mailu/ui/templates/relay/edit.html:4 -msgid "Edit relayd domain" -msgstr "编辑中继域" - -#: mailu/ui/templates/relay/list.html:4 -msgid "Relayed domain list" -msgstr "中继域列表" - -#: mailu/ui/templates/relay/list.html:9 -msgid "New relayed domain" -msgstr "新的中继域" - -#: mailu/ui/forms.py:125 -msgid "Your token (write it down, as it will never be displayed again)" -msgstr "您的令牌(请记录,它只显示这一次)" - -#: mailu/ui/forms.py:130 mailu/ui/templates/token/list.html:20 -msgid "Authorized IP" -msgstr "授权IP" - -#: mailu/ui/templates/sidebar.html:31 mailu/ui/templates/token/list.html:4 -msgid "Authentication tokens" -msgstr "认证令牌" - -#: mailu/ui/templates/sidebar.html:72 -msgid "Go to" -msgstr "转到" - -#: mailu/ui/templates/sidebar.html:76 -msgid "Webmail" -msgstr "网页邮箱" - -#: mailu/ui/templates/sidebar.html:87 -msgid "Website" -msgstr "网站" - -#: mailu/ui/templates/token/create.html:4 -msgid "Create an authentication token" -msgstr "创建一个认证令牌" - -#: mailu/ui/templates/token/list.html:12 -msgid "New token" -msgstr "新的令牌" - -#: mailu/ui/templates/user/create.html:15 -msgid "General" -msgstr "通用" - -#: mailu/ui/templates/user/create.html:22 -msgid "Features and quotas" -msgstr "功能和配额" - -#: mailu/ui/templates/user/settings.html:14 -msgid "General settings" -msgstr "常规设置" - -#: mailu/ui/templates/sidebar.html:59 mailu/ui/templates/user/settings.html:15 -msgid "Antispam" -msgstr "反垃圾邮件" - -#: mailu/ui/forms.py:99 -msgid "Spam filter tolerance" -msgstr "垃圾邮件过滤器容忍度" - -#: mailu/ui/forms.py:50 -msgid "Enable sign-up" -msgstr "启用用户注册" - -#: mailu/ui/forms.py:57 -msgid "Initial admin" -msgstr "初始管理员" - -#: mailu/ui/forms.py:58 -msgid "Admin password" -msgstr "管理员密码" - -#: mailu/ui/forms.py:84 -msgid "Enabled" -msgstr "启用" - -#: mailu/ui/forms.py:89 -msgid "Email address" -msgstr "邮件地址" - -#: mailu/ui/forms.py:93 mailu/ui/templates/sidebar.html:117 -#: mailu/ui/templates/user/signup.html:4 -#: mailu/ui/templates/user/signup_domain.html:4 -msgid "Sign up" -msgstr "注册" - -#: mailu/ui/forms.py:119 -msgid "End of vacation" -msgstr "假期结束" - -#: mailu/ui/templates/client.html:4 mailu/ui/templates/sidebar.html:82 -msgid "Client setup" -msgstr "客户端设置" - -#: mailu/ui/templates/client.html:16 mailu/ui/templates/client.html:43 -msgid "Mail protocol" -msgstr "邮件协议" - -#: mailu/ui/templates/client.html:24 mailu/ui/templates/client.html:51 -msgid "Server name" -msgstr "服务器名" - -#: mailu/ui/templates/domain/signup.html:4 mailu/ui/templates/sidebar.html:98 -msgid "Register a domain" -msgstr "注册域名" - -#: mailu/ui/templates/domain/details.html:17 -msgid "Generate keys" -msgstr "生成密钥" - -#: mailu/ui/templates/domain/signup.html:13 -msgid "In order to register a new domain, you must first setup the\n" -" domain zone so that the domain MX points to this server" -msgstr "在注册一个新的域名前,您必须先为该域名设置 MX 记录,并使其指向本服务器" - -#: mailu/ui/templates/domain/signup.html:18 -msgid "If you do not know how to setup an MX record for your DNS zone,\n" -" please contact your DNS provider or administrator. Also, please wait a\n" -" couple minutes after the MX is set so the local server cache\n" -" expires." -msgstr "如果您不知道如何为域名设置 MX 记录,请联系你的DNS提供商或者系统管理员。在设置完成 MX 记录后,请等待本地域名服务器的缓存过期。" +#: mailu/ui/templates/user/settings.html:22 +msgid "Auto-forward" +msgstr "自动转发" #: mailu/ui/templates/user/signup_domain.html:8 msgid "pick a domain for the new account" @@ -700,3 +665,14 @@ msgstr "域名" msgid "Available slots" msgstr "可用" +#~ msgid "Your account" +#~ msgstr "" + +#~ msgid "Spam filter threshold" +#~ msgstr "" + +#~ msgid "from" +#~ msgstr "" + +#~ msgid "General settings" +#~ msgstr "" From 866f784d06348b0328a17565203526c890c48564 Mon Sep 17 00:00:00 2001 From: qy117121 Date: Thu, 14 Oct 2021 15:05:32 +0800 Subject: [PATCH 26/33] Create messages.po Update the translation --- .../translations/zh/LC_MESSAGES/messages.po | 678 ++++++++++++++++++ 1 file changed, 678 insertions(+) create mode 100644 core/admin/mailu/translations/zh/LC_MESSAGES/messages.po diff --git a/core/admin/mailu/translations/zh/LC_MESSAGES/messages.po b/core/admin/mailu/translations/zh/LC_MESSAGES/messages.po new file mode 100644 index 00000000..a3363169 --- /dev/null +++ b/core/admin/mailu/translations/zh/LC_MESSAGES/messages.po @@ -0,0 +1,678 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.5.7\n" +"Project-Id-Version: Mailu\n" +"Language: zh\n" +"Last-Translator: Chris Chuan \n" +"Language-Team: \n" + +#: mailu/ui/forms.py:32 +msgid "Invalid email address." +msgstr "无效的邮件地址" + +#: mailu/ui/forms.py:36 +msgid "Confirm" +msgstr "确认" + +#: mailu/ui/forms.py:40 mailu/ui/forms.py:77 +msgid "E-mail" +msgstr "电子邮件" + +#: mailu/ui/forms.py:41 mailu/ui/forms.py:78 mailu/ui/forms.py:90 +#: mailu/ui/forms.py:109 mailu/ui/forms.py:162 +#: mailu/ui/templates/client.html:32 mailu/ui/templates/client.html:59 +msgid "Password" +msgstr "密码" + +#: mailu/ui/forms.py:42 mailu/ui/templates/login.html:4 +#: mailu/ui/templates/sidebar.html:111 +msgid "Sign in" +msgstr "登录" + +#: mailu/ui/forms.py:46 mailu/ui/forms.py:56 +#: mailu/ui/templates/domain/details.html:27 +#: mailu/ui/templates/domain/list.html:18 mailu/ui/templates/relay/list.html:17 +msgid "Domain name" +msgstr "域名" + +#: mailu/ui/forms.py:47 +msgid "Maximum user count" +msgstr "最大用户数" + +#: mailu/ui/forms.py:48 +msgid "Maximum alias count" +msgstr "最大别名数" + +#: mailu/ui/forms.py:49 +msgid "Maximum user quota" +msgstr "最大用户配额" + +#: mailu/ui/forms.py:50 +msgid "Enable sign-up" +msgstr "启用注册" + +#: mailu/ui/forms.py:51 mailu/ui/forms.py:72 mailu/ui/forms.py:83 +#: mailu/ui/forms.py:128 mailu/ui/forms.py:140 +#: mailu/ui/templates/alias/list.html:21 mailu/ui/templates/domain/list.html:21 +#: mailu/ui/templates/relay/list.html:19 mailu/ui/templates/token/list.html:19 +#: mailu/ui/templates/user/list.html:23 +msgid "Comment" +msgstr "说明" + +#: mailu/ui/forms.py:52 mailu/ui/forms.py:61 mailu/ui/forms.py:66 +#: mailu/ui/forms.py:73 mailu/ui/forms.py:132 mailu/ui/forms.py:141 +msgid "Create" +msgstr "创建" + +#: mailu/ui/forms.py:57 +msgid "Initial admin" +msgstr "初始管理员" + +#: mailu/ui/forms.py:58 +msgid "Admin password" +msgstr "管理员密码" + +#: mailu/ui/forms.py:59 mailu/ui/forms.py:79 mailu/ui/forms.py:91 +msgid "Confirm password" +msgstr "确认密码" + +#: mailu/ui/forms.py:65 +msgid "Alternative name" +msgstr "备用名称" + +#: mailu/ui/forms.py:70 +msgid "Relayed domain name" +msgstr "中继域域名" + +#: mailu/ui/forms.py:71 mailu/ui/templates/relay/list.html:18 +msgid "Remote host" +msgstr "远程主机" + +#: mailu/ui/forms.py:80 mailu/ui/templates/user/list.html:22 +#: mailu/ui/templates/user/signup_domain.html:16 +msgid "Quota" +msgstr "配额" + +#: mailu/ui/forms.py:81 +msgid "Allow IMAP access" +msgstr "允许 IMAP 访问" + +#: mailu/ui/forms.py:82 +msgid "Allow POP3 access" +msgstr "允许 POP3 访问" + +#: mailu/ui/forms.py:84 +msgid "Enabled" +msgstr "启用" + +#: mailu/ui/forms.py:85 +msgid "Save" +msgstr "保存" + +#: mailu/ui/forms.py:89 +msgid "Email address" +msgstr "邮件地址" + +#: mailu/ui/forms.py:93 mailu/ui/templates/sidebar.html:117 +#: mailu/ui/templates/user/signup.html:4 +#: mailu/ui/templates/user/signup_domain.html:4 +msgid "Sign up" +msgstr "注册" + +#: mailu/ui/forms.py:97 +msgid "Displayed name" +msgstr "显示名称" + +#: mailu/ui/forms.py:98 +msgid "Enable spam filter" +msgstr "启用垃圾邮件过滤" + +#: mailu/ui/forms.py:99 +msgid "Spam filter tolerance" +msgstr "垃圾邮件过滤器阈值" + +#: mailu/ui/forms.py:100 +msgid "Enable forwarding" +msgstr "启用转发" + +#: mailu/ui/forms.py:101 +msgid "Keep a copy of the emails" +msgstr "保留电子邮件副本" + +#: mailu/ui/forms.py:103 mailu/ui/forms.py:139 +#: mailu/ui/templates/alias/list.html:20 +msgid "Destination" +msgstr "目的地址" + +#: mailu/ui/forms.py:105 +msgid "Save settings" +msgstr "保存设置" + +#: mailu/ui/forms.py:110 +msgid "Password check" +msgstr "检查密码" + +#: mailu/ui/forms.py:111 mailu/ui/templates/sidebar.html:16 +msgid "Update password" +msgstr "更新密码" + +#: mailu/ui/forms.py:115 +msgid "Enable automatic reply" +msgstr "启用自动回复" + +#: mailu/ui/forms.py:116 +msgid "Reply subject" +msgstr "回复主题" + +#: mailu/ui/forms.py:117 +msgid "Reply body" +msgstr "回复正文" + +#: mailu/ui/forms.py:119 +msgid "End of vacation" +msgstr "假期结束" + +#: mailu/ui/forms.py:120 +msgid "Update" +msgstr "更新" + +#: mailu/ui/forms.py:125 +msgid "Your token (write it down, as it will never be displayed again)" +msgstr "您的令牌(请记录,它只显示这一次)" + +#: mailu/ui/forms.py:130 mailu/ui/templates/token/list.html:20 +msgid "Authorized IP" +msgstr "授权 IP" + +#: mailu/ui/forms.py:136 +msgid "Alias" +msgstr "别名" + +#: mailu/ui/forms.py:138 +msgid "Use SQL LIKE Syntax (e.g. for catch-all aliases)" +msgstr "使用SQL LIKE语法(例如,用于全部别名)" + +#: mailu/ui/forms.py:145 +msgid "Admin email" +msgstr "管理员邮箱" + +#: mailu/ui/forms.py:146 mailu/ui/forms.py:151 mailu/ui/forms.py:164 +msgid "Submit" +msgstr "提交" + +#: mailu/ui/forms.py:150 +msgid "Manager email" +msgstr "管理员邮箱" + +#: mailu/ui/forms.py:155 +msgid "Protocol" +msgstr "协议" + +#: mailu/ui/forms.py:158 +msgid "Hostname or IP" +msgstr "主机名或IP" + +#: mailu/ui/forms.py:159 mailu/ui/templates/client.html:20 +#: mailu/ui/templates/client.html:47 +msgid "TCP port" +msgstr "TCP端口" + +#: mailu/ui/forms.py:160 +msgid "Enable TLS" +msgstr "启用TLS" + +#: mailu/ui/forms.py:161 mailu/ui/templates/client.html:28 +#: mailu/ui/templates/client.html:55 mailu/ui/templates/fetch/list.html:20 +msgid "Username" +msgstr "用户名" + +#: mailu/ui/forms.py:163 +msgid "Keep emails on the server" +msgstr "在服务器上保留电子邮件" + +#: mailu/ui/forms.py:168 +msgid "Announcement subject" +msgstr "公告主题" + +#: mailu/ui/forms.py:170 +msgid "Announcement body" +msgstr "公告正文" + +#: mailu/ui/forms.py:172 +msgid "Send" +msgstr "发送" + +#: mailu/ui/templates/announcement.html:4 +msgid "Public announcement" +msgstr "公开公告" + +#: mailu/ui/templates/client.html:4 mailu/ui/templates/sidebar.html:82 +msgid "Client setup" +msgstr "客户端设置" + +#: mailu/ui/templates/client.html:16 mailu/ui/templates/client.html:43 +msgid "Mail protocol" +msgstr "邮件协议" + +#: mailu/ui/templates/client.html:24 mailu/ui/templates/client.html:51 +msgid "Server name" +msgstr "服务器名称" + +#: mailu/ui/templates/confirm.html:4 +msgid "Confirm action" +msgstr "确认操作" + +#: mailu/ui/templates/confirm.html:13 +#, python-format +msgid "You are about to %(action)s. Please confirm your action." +msgstr "即将%(action)s,请确认您的操作。" + +#: mailu/ui/templates/docker-error.html:4 +msgid "Docker error" +msgstr "Docker 错误" + +#: mailu/ui/templates/docker-error.html:12 +msgid "An error occurred while talking to the Docker server." +msgstr "Docker服务器通信出错" + +#: mailu/ui/templates/login.html:8 +msgid "to access the administration tools" +msgstr "访问管理工具" + +#: mailu/ui/templates/sidebar.html:8 +msgid "My account" +msgstr "我的账户" + +#: mailu/ui/templates/sidebar.html:11 mailu/ui/templates/user/list.html:34 +msgid "Settings" +msgstr "设置" + +#: mailu/ui/templates/sidebar.html:21 mailu/ui/templates/user/list.html:35 +msgid "Auto-reply" +msgstr "自动回复" + +#: mailu/ui/templates/fetch/list.html:4 mailu/ui/templates/sidebar.html:26 +#: mailu/ui/templates/user/list.html:36 +msgid "Fetched accounts" +msgstr "代收账户" + +#: mailu/ui/templates/sidebar.html:31 mailu/ui/templates/token/list.html:4 +msgid "Authentication tokens" +msgstr "认证令牌" + +#: mailu/ui/templates/sidebar.html:35 +msgid "Administration" +msgstr "管理" + +#: mailu/ui/templates/sidebar.html:44 +msgid "Announcement" +msgstr "公告" + +#: mailu/ui/templates/sidebar.html:49 +msgid "Administrators" +msgstr "管理员" + +#: mailu/ui/templates/sidebar.html:54 +msgid "Relayed domains" +msgstr "中继域" + +#: mailu/ui/templates/sidebar.html:59 mailu/ui/templates/user/settings.html:15 +msgid "Antispam" +msgstr "发垃圾邮件" + +#: mailu/ui/templates/sidebar.html:66 +msgid "Mail domains" +msgstr "邮件域" + +#: mailu/ui/templates/sidebar.html:72 +msgid "Go to" +msgstr "转到" + +#: mailu/ui/templates/sidebar.html:76 +msgid "Webmail" +msgstr "网页邮箱" + +#: mailu/ui/templates/sidebar.html:87 +msgid "Website" +msgstr "网站" + +#: mailu/ui/templates/sidebar.html:92 +msgid "Help" +msgstr "帮助" + +#: mailu/ui/templates/domain/signup.html:4 mailu/ui/templates/sidebar.html:98 +msgid "Register a domain" +msgstr "注册域名" + +#: mailu/ui/templates/sidebar.html:105 +msgid "Sign out" +msgstr "登出" + +#: mailu/ui/templates/working.html:4 +msgid "We are still working on this feature!" +msgstr "该功能开发中……" + +#: mailu/ui/templates/admin/create.html:4 +msgid "Add a global administrator" +msgstr "添加全局管理员" + +#: mailu/ui/templates/admin/list.html:4 +msgid "Global administrators" +msgstr "全局管理员" + +#: mailu/ui/templates/admin/list.html:9 +msgid "Add administrator" +msgstr "添加管理员" + +#: mailu/ui/templates/admin/list.html:16 mailu/ui/templates/alias/list.html:18 +#: mailu/ui/templates/alternative/list.html:18 +#: mailu/ui/templates/domain/list.html:16 mailu/ui/templates/fetch/list.html:18 +#: mailu/ui/templates/manager/list.html:18 +#: mailu/ui/templates/relay/list.html:16 mailu/ui/templates/token/list.html:18 +#: mailu/ui/templates/user/list.html:18 +msgid "Actions" +msgstr "操作" + +#: mailu/ui/templates/admin/list.html:17 mailu/ui/templates/alias/list.html:19 +#: mailu/ui/templates/manager/list.html:19 mailu/ui/templates/user/list.html:20 +msgid "Email" +msgstr "电子邮件" + +#: mailu/ui/templates/admin/list.html:22 mailu/ui/templates/alias/list.html:29 +#: mailu/ui/templates/alternative/list.html:25 +#: mailu/ui/templates/domain/list.html:31 mailu/ui/templates/fetch/list.html:31 +#: mailu/ui/templates/manager/list.html:24 +#: mailu/ui/templates/relay/list.html:27 mailu/ui/templates/token/list.html:26 +#: mailu/ui/templates/user/list.html:31 +msgid "Delete" +msgstr "删除" + +#: mailu/ui/templates/alias/create.html:4 +msgid "Create alias" +msgstr "创建别名" + +#: mailu/ui/templates/alias/edit.html:4 +msgid "Edit alias" +msgstr "编辑别名" + +#: mailu/ui/templates/alias/list.html:4 +msgid "Alias list" +msgstr "别名列表" + +#: mailu/ui/templates/alias/list.html:12 +msgid "Add alias" +msgstr "添加别名" + +#: mailu/ui/templates/alias/list.html:22 +#: mailu/ui/templates/alternative/list.html:20 +#: mailu/ui/templates/domain/list.html:22 mailu/ui/templates/fetch/list.html:24 +#: mailu/ui/templates/relay/list.html:20 mailu/ui/templates/token/list.html:21 +#: mailu/ui/templates/user/list.html:24 +msgid "Created" +msgstr "已创建" + +#: mailu/ui/templates/alias/list.html:23 mailu/ui/templates/domain/list.html:23 +#: mailu/ui/templates/fetch/list.html:25 mailu/ui/templates/relay/list.html:21 +#: mailu/ui/templates/user/list.html:25 +msgid "Last edit" +msgstr "上次编辑" + +#: mailu/ui/templates/alias/list.html:28 mailu/ui/templates/domain/list.html:30 +#: mailu/ui/templates/fetch/list.html:30 mailu/ui/templates/relay/list.html:26 +#: mailu/ui/templates/user/list.html:30 +msgid "Edit" +msgstr "编辑" + +#: mailu/ui/templates/alternative/create.html:4 +msgid "Create alternative domain" +msgstr "创建替代域" + +#: mailu/ui/templates/alternative/list.html:4 +msgid "Alternative domain list" +msgstr "替代域名列表" + +#: mailu/ui/templates/alternative/list.html:12 +msgid "Add alternative" +msgstr "添加替代" + +#: mailu/ui/templates/alternative/list.html:19 +msgid "Name" +msgstr "名称" + +#: mailu/ui/templates/domain/create.html:4 +#: mailu/ui/templates/domain/list.html:9 +msgid "New domain" +msgstr "新域" + +#: mailu/ui/templates/domain/details.html:4 +msgid "Domain details" +msgstr "域详细信息" + +#: mailu/ui/templates/domain/details.html:15 +msgid "Regenerate keys" +msgstr "重新生成秘钥" + +#: mailu/ui/templates/domain/details.html:17 +msgid "Generate keys" +msgstr "生成秘钥" + +#: mailu/ui/templates/domain/details.html:31 +msgid "DNS MX entry" +msgstr "DNS MX条目" + +#: mailu/ui/templates/domain/details.html:35 +msgid "DNS SPF entries" +msgstr "DNS SPF 条目" + +#: mailu/ui/templates/domain/details.html:42 +msgid "DKIM public key" +msgstr "DKIM 公钥" + +#: mailu/ui/templates/domain/details.html:46 +msgid "DNS DKIM entry" +msgstr "DNS DKIM 条目" + +#: mailu/ui/templates/domain/details.html:50 +msgid "DNS DMARC entry" +msgstr "DNS DMARC 条目" + +#: mailu/ui/templates/domain/edit.html:4 +msgid "Edit domain" +msgstr "编辑域" + +#: mailu/ui/templates/domain/list.html:4 +msgid "Domain list" +msgstr "域列表" + +#: mailu/ui/templates/domain/list.html:17 +msgid "Manage" +msgstr "管理" + +#: mailu/ui/templates/domain/list.html:19 +msgid "Mailbox count" +msgstr "邮箱数量" + +#: mailu/ui/templates/domain/list.html:20 +msgid "Alias count" +msgstr "别名数量" + +#: mailu/ui/templates/domain/list.html:28 +msgid "Details" +msgstr "详细信息" + +#: mailu/ui/templates/domain/list.html:35 +msgid "Users" +msgstr "用户" + +#: mailu/ui/templates/domain/list.html:36 +msgid "Aliases" +msgstr "别名" + +#: mailu/ui/templates/domain/list.html:37 +msgid "Managers" +msgstr "管理员" + +#: mailu/ui/templates/domain/list.html:39 +msgid "Alternatives" +msgstr "备选方案" + +#: mailu/ui/templates/domain/signup.html:13 +msgid "" +"In order to register a new domain, you must first setup the\n" +" domain zone so that the domain MX points to this server" +msgstr "在注册一个新的域名前,您必须先为该域名设置 MX 记录,并使其指向本服务器" + +#: mailu/ui/templates/domain/signup.html:18 +msgid "" +"If you do not know how to setup an MX record for your DNS " +"zone,\n" +" please contact your DNS provider or administrator. Also, please wait " +"a\n" +" couple minutes after the MX is set so the local server " +"cache\n" +" expires." +msgstr "如果您不知道如何为域名设置 MX 记录,请联系你的DNS提供商或者系统管理员。在设置完成 MX 记录后,请等待本地域名服务器的缓存过期。" + + +#: mailu/ui/templates/fetch/create.html:4 +msgid "Add a fetched account" +msgstr "添加一个代收账户" + +#: mailu/ui/templates/fetch/edit.html:4 +msgid "Update a fetched account" +msgstr "更新代收账户" + +#: mailu/ui/templates/fetch/list.html:12 +msgid "Add an account" +msgstr "添加一个账户" + +#: mailu/ui/templates/fetch/list.html:19 +msgid "Endpoint" +msgstr "端点" + +#: mailu/ui/templates/fetch/list.html:21 +msgid "Keep emails" +msgstr "保留电子邮件" + +#: mailu/ui/templates/fetch/list.html:22 +msgid "Last check" +msgstr "上次检查" + +#: mailu/ui/templates/fetch/list.html:35 +msgid "yes" +msgstr "是" + +#: mailu/ui/templates/fetch/list.html:35 +msgid "no" +msgstr "否" + +#: mailu/ui/templates/manager/create.html:4 +msgid "Add a manager" +msgstr "添加一个管理员" + +#: mailu/ui/templates/manager/list.html:4 +msgid "Manager list" +msgstr "管理员列表" + +#: mailu/ui/templates/manager/list.html:12 +msgid "Add manager" +msgstr "添加管理员" + +#: mailu/ui/templates/relay/create.html:4 +msgid "New relay domain" +msgstr "新的中继域" + +#: mailu/ui/templates/relay/edit.html:4 +msgid "Edit relayd domain" +msgstr "编辑中继域" + +#: mailu/ui/templates/relay/list.html:4 +msgid "Relayed domain list" +msgstr "中继域列表" + +#: mailu/ui/templates/relay/list.html:9 +msgid "New relayed domain" +msgstr "新的中继域" + +#: mailu/ui/templates/token/create.html:4 +msgid "Create an authentication token" +msgstr "创建一个认证令牌" + +#: mailu/ui/templates/token/list.html:12 +msgid "New token" +msgstr "新令牌" + +#: mailu/ui/templates/user/create.html:4 +msgid "New user" +msgstr "新用户" + +#: mailu/ui/templates/user/create.html:15 +msgid "General" +msgstr "通用" + +#: mailu/ui/templates/user/create.html:22 +msgid "Features and quotas" +msgstr "功能和配额" + +#: mailu/ui/templates/user/edit.html:4 +msgid "Edit user" +msgstr "编辑用户" + +#: mailu/ui/templates/user/forward.html:4 +msgid "Forward emails" +msgstr "转发邮件" + +#: mailu/ui/templates/user/list.html:4 +msgid "User list" +msgstr "用户列表" + +#: mailu/ui/templates/user/list.html:12 +msgid "Add user" +msgstr "添加用户" + +#: mailu/ui/templates/user/list.html:19 mailu/ui/templates/user/settings.html:4 +msgid "User settings" +msgstr "用户设置" + +#: mailu/ui/templates/user/list.html:21 +msgid "Features" +msgstr "功能" + +#: mailu/ui/templates/user/password.html:4 +msgid "Password update" +msgstr "更新密码" + +#: mailu/ui/templates/user/reply.html:4 +msgid "Automatic reply" +msgstr "自动回复" + +#: mailu/ui/templates/user/settings.html:22 +msgid "Auto-forward" +msgstr "自动转发" + +#: mailu/ui/templates/user/signup_domain.html:8 +msgid "pick a domain for the new account" +msgstr "为新用户选择一个域名" + +#: mailu/ui/templates/user/signup_domain.html:14 +msgid "Domain" +msgstr "域名" + +#: mailu/ui/templates/user/signup_domain.html:15 +msgid "Available slots" +msgstr "可用" + +#~ msgid "Your account" +#~ msgstr "" + +#~ msgid "Spam filter threshold" +#~ msgstr "" + +#~ msgid "from" +#~ msgstr "" + +#~ msgid "General settings" +#~ msgstr "" From 632ce663ee41277e57ad56f522d29e213a030f81 Mon Sep 17 00:00:00 2001 From: Florent Daigniere Date: Thu, 14 Oct 2021 18:04:49 +0200 Subject: [PATCH 27/33] Prevent logins with no password --- core/admin/mailu/models.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/admin/mailu/models.py b/core/admin/mailu/models.py index 01711a60..3c79e661 100644 --- a/core/admin/mailu/models.py +++ b/core/admin/mailu/models.py @@ -562,6 +562,8 @@ class User(Base, Email): """ verifies password against stored hash and updates hash if outdated """ + if password == '': + return False cache_result = self._credential_cache.get(self.get_id()) current_salt = self.password.split('$')[3] if len(self.password.split('$')) == 5 else None if cache_result and current_salt: From 893705169e38bc9fbc82873f2f8fef0bad146d0d Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Thu, 14 Oct 2021 19:07:11 +0200 Subject: [PATCH 28/33] PoC rspamd use dkimkeys from admin using vault api --- core/admin/mailu/internal/views/__init__.py | 2 +- core/admin/mailu/internal/views/rspamd.py | 30 +++++++++++++++++++++ core/rspamd/conf/arc.conf | 8 +++--- core/rspamd/conf/dkim_signing.conf | 6 +++-- core/rspamd/start.py | 1 + 5 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 core/admin/mailu/internal/views/rspamd.py diff --git a/core/admin/mailu/internal/views/__init__.py b/core/admin/mailu/internal/views/__init__.py index a32106c0..762b2a38 100644 --- a/core/admin/mailu/internal/views/__init__.py +++ b/core/admin/mailu/internal/views/__init__.py @@ -1,3 +1,3 @@ __all__ = [ - 'auth', 'postfix', 'dovecot', 'fetch' + 'auth', 'postfix', 'dovecot', 'fetch', 'rspamd' ] diff --git a/core/admin/mailu/internal/views/rspamd.py b/core/admin/mailu/internal/views/rspamd.py new file mode 100644 index 00000000..61e27a59 --- /dev/null +++ b/core/admin/mailu/internal/views/rspamd.py @@ -0,0 +1,30 @@ +from mailu import models, dkim +from mailu.internal import internal + +import flask + +def vault_error(*messages, status=404): + return flask.make_response(flask.jsonify({'errors':messages}), status) + +# rspamd key format: +# {"selectors":[{"pubkey":"...","domain":"...","valid_start":TS,"valid_end":TS,"key":"...","selector":"...","bits":...,"alg":"..."}]} + +# hashicorp vault answer format: +# {"request_id":"...","lease_id":"","renewable":false,"lease_duration":2764800,"data":{...see above...},"wrap_info":null,"warnings":null,"auth":null} + +@internal.route("/rspamd/vault/v1/dkim/") +def rspamd_dkim_key(domain_name): + domain = models.Domain.query.get(domain_name) or flask.abort(vault_error('unknown domain')) + key = domain.dkim_key or flask.abort(vault_error('no dkim key', status=400)) + return flask.jsonify({ + 'data': { + 'selectors': [ + { + 'domain' : domain.name, + 'key' : key.decode('utf8'), + 'selector': 'dkim', + } + ] + } + }) + diff --git a/core/rspamd/conf/arc.conf b/core/rspamd/conf/arc.conf index 205d4284..93414a96 100644 --- a/core/rspamd/conf/arc.conf +++ b/core/rspamd/conf/arc.conf @@ -1,4 +1,6 @@ -try_fallback = true; -path = "/dkim/$domain.$selector.key"; -selector = "dkim" +try_fallback = false; use_esld = false; +allow_username_mismatch = true; +use_vault = true; +vault_url = "http://{{ ADMIN_ADDRESS }}/internal/rspamd/vault"; +vault_token = "mailu"; diff --git a/core/rspamd/conf/dkim_signing.conf b/core/rspamd/conf/dkim_signing.conf index e00e8d67..93414a96 100644 --- a/core/rspamd/conf/dkim_signing.conf +++ b/core/rspamd/conf/dkim_signing.conf @@ -1,4 +1,6 @@ -try_fallback = true; -path = "/dkim/$domain.$selector.key"; +try_fallback = false; use_esld = false; allow_username_mismatch = true; +use_vault = true; +vault_url = "http://{{ ADMIN_ADDRESS }}/internal/rspamd/vault"; +vault_token = "mailu"; diff --git a/core/rspamd/start.py b/core/rspamd/start.py index e2e72bcb..fcb33a97 100755 --- a/core/rspamd/start.py +++ b/core/rspamd/start.py @@ -11,6 +11,7 @@ log.basicConfig(stream=sys.stderr, level=os.environ.get("LOG_LEVEL", "WARNING")) # Actual startup script os.environ["REDIS_ADDRESS"] = system.get_host_address_from_environment("REDIS", "redis") +os.environ["ADMIN_ADDRESS"] = system.get_host_address_from_environment("ADMIN", "admin") if os.environ.get("ANTIVIRUS") == 'clamav': os.environ["ANTIVIRUS_ADDRESS"] = system.get_host_address_from_environment("ANTIVIRUS", "antivirus:3310") From dc9f970a91b0aeb9ae8e710c9bfc328587056608 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Thu, 14 Oct 2021 23:15:42 +0200 Subject: [PATCH 29/33] removed zh_CN and updated locale-map for datatables --- core/admin/Dockerfile | 2 +- .../zh_CN/LC_MESSAGES/messages.po | 678 ------------------ 2 files changed, 1 insertion(+), 679 deletions(-) delete mode 100644 core/admin/mailu/translations/zh_CN/LC_MESSAGES/messages.po diff --git a/core/admin/Dockerfile b/core/admin/Dockerfile index 083c0f39..cdc426c6 100644 --- a/core/admin/Dockerfile +++ b/core/admin/Dockerfile @@ -13,7 +13,7 @@ COPY webpack.config.js ./ COPY assets ./assets RUN set -eu \ && sed -i 's/#007bff/#55a5d9/' node_modules/admin-lte/build/scss/_bootstrap-variables.scss \ - && for l in ca da de:de_de en:en-gb es:es_es eu fr:fr_fr he hu is it:it_it ja nb_NO:no_nb nl:nl_nl pl pt:pt_pt ru sv:sv_se zh_CN:zh; do \ + && for l in ca da de:de_de en:en-gb es:es_es eu fr:fr_fr he hu is it:it_it ja nb_NO:no_nb nl:nl_nl pl pt:pt_pt ru sv:sv_se zh; do \ cp node_modules/datatables.net-plugins/i18n/${l#*:}.json assets/${l%:*}.json; \ done \ && node_modules/.bin/webpack-cli --color diff --git a/core/admin/mailu/translations/zh_CN/LC_MESSAGES/messages.po b/core/admin/mailu/translations/zh_CN/LC_MESSAGES/messages.po deleted file mode 100644 index a3363169..00000000 --- a/core/admin/mailu/translations/zh_CN/LC_MESSAGES/messages.po +++ /dev/null @@ -1,678 +0,0 @@ -msgid "" -msgstr "" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 1.5.7\n" -"Project-Id-Version: Mailu\n" -"Language: zh\n" -"Last-Translator: Chris Chuan \n" -"Language-Team: \n" - -#: mailu/ui/forms.py:32 -msgid "Invalid email address." -msgstr "无效的邮件地址" - -#: mailu/ui/forms.py:36 -msgid "Confirm" -msgstr "确认" - -#: mailu/ui/forms.py:40 mailu/ui/forms.py:77 -msgid "E-mail" -msgstr "电子邮件" - -#: mailu/ui/forms.py:41 mailu/ui/forms.py:78 mailu/ui/forms.py:90 -#: mailu/ui/forms.py:109 mailu/ui/forms.py:162 -#: mailu/ui/templates/client.html:32 mailu/ui/templates/client.html:59 -msgid "Password" -msgstr "密码" - -#: mailu/ui/forms.py:42 mailu/ui/templates/login.html:4 -#: mailu/ui/templates/sidebar.html:111 -msgid "Sign in" -msgstr "登录" - -#: mailu/ui/forms.py:46 mailu/ui/forms.py:56 -#: mailu/ui/templates/domain/details.html:27 -#: mailu/ui/templates/domain/list.html:18 mailu/ui/templates/relay/list.html:17 -msgid "Domain name" -msgstr "域名" - -#: mailu/ui/forms.py:47 -msgid "Maximum user count" -msgstr "最大用户数" - -#: mailu/ui/forms.py:48 -msgid "Maximum alias count" -msgstr "最大别名数" - -#: mailu/ui/forms.py:49 -msgid "Maximum user quota" -msgstr "最大用户配额" - -#: mailu/ui/forms.py:50 -msgid "Enable sign-up" -msgstr "启用注册" - -#: mailu/ui/forms.py:51 mailu/ui/forms.py:72 mailu/ui/forms.py:83 -#: mailu/ui/forms.py:128 mailu/ui/forms.py:140 -#: mailu/ui/templates/alias/list.html:21 mailu/ui/templates/domain/list.html:21 -#: mailu/ui/templates/relay/list.html:19 mailu/ui/templates/token/list.html:19 -#: mailu/ui/templates/user/list.html:23 -msgid "Comment" -msgstr "说明" - -#: mailu/ui/forms.py:52 mailu/ui/forms.py:61 mailu/ui/forms.py:66 -#: mailu/ui/forms.py:73 mailu/ui/forms.py:132 mailu/ui/forms.py:141 -msgid "Create" -msgstr "创建" - -#: mailu/ui/forms.py:57 -msgid "Initial admin" -msgstr "初始管理员" - -#: mailu/ui/forms.py:58 -msgid "Admin password" -msgstr "管理员密码" - -#: mailu/ui/forms.py:59 mailu/ui/forms.py:79 mailu/ui/forms.py:91 -msgid "Confirm password" -msgstr "确认密码" - -#: mailu/ui/forms.py:65 -msgid "Alternative name" -msgstr "备用名称" - -#: mailu/ui/forms.py:70 -msgid "Relayed domain name" -msgstr "中继域域名" - -#: mailu/ui/forms.py:71 mailu/ui/templates/relay/list.html:18 -msgid "Remote host" -msgstr "远程主机" - -#: mailu/ui/forms.py:80 mailu/ui/templates/user/list.html:22 -#: mailu/ui/templates/user/signup_domain.html:16 -msgid "Quota" -msgstr "配额" - -#: mailu/ui/forms.py:81 -msgid "Allow IMAP access" -msgstr "允许 IMAP 访问" - -#: mailu/ui/forms.py:82 -msgid "Allow POP3 access" -msgstr "允许 POP3 访问" - -#: mailu/ui/forms.py:84 -msgid "Enabled" -msgstr "启用" - -#: mailu/ui/forms.py:85 -msgid "Save" -msgstr "保存" - -#: mailu/ui/forms.py:89 -msgid "Email address" -msgstr "邮件地址" - -#: mailu/ui/forms.py:93 mailu/ui/templates/sidebar.html:117 -#: mailu/ui/templates/user/signup.html:4 -#: mailu/ui/templates/user/signup_domain.html:4 -msgid "Sign up" -msgstr "注册" - -#: mailu/ui/forms.py:97 -msgid "Displayed name" -msgstr "显示名称" - -#: mailu/ui/forms.py:98 -msgid "Enable spam filter" -msgstr "启用垃圾邮件过滤" - -#: mailu/ui/forms.py:99 -msgid "Spam filter tolerance" -msgstr "垃圾邮件过滤器阈值" - -#: mailu/ui/forms.py:100 -msgid "Enable forwarding" -msgstr "启用转发" - -#: mailu/ui/forms.py:101 -msgid "Keep a copy of the emails" -msgstr "保留电子邮件副本" - -#: mailu/ui/forms.py:103 mailu/ui/forms.py:139 -#: mailu/ui/templates/alias/list.html:20 -msgid "Destination" -msgstr "目的地址" - -#: mailu/ui/forms.py:105 -msgid "Save settings" -msgstr "保存设置" - -#: mailu/ui/forms.py:110 -msgid "Password check" -msgstr "检查密码" - -#: mailu/ui/forms.py:111 mailu/ui/templates/sidebar.html:16 -msgid "Update password" -msgstr "更新密码" - -#: mailu/ui/forms.py:115 -msgid "Enable automatic reply" -msgstr "启用自动回复" - -#: mailu/ui/forms.py:116 -msgid "Reply subject" -msgstr "回复主题" - -#: mailu/ui/forms.py:117 -msgid "Reply body" -msgstr "回复正文" - -#: mailu/ui/forms.py:119 -msgid "End of vacation" -msgstr "假期结束" - -#: mailu/ui/forms.py:120 -msgid "Update" -msgstr "更新" - -#: mailu/ui/forms.py:125 -msgid "Your token (write it down, as it will never be displayed again)" -msgstr "您的令牌(请记录,它只显示这一次)" - -#: mailu/ui/forms.py:130 mailu/ui/templates/token/list.html:20 -msgid "Authorized IP" -msgstr "授权 IP" - -#: mailu/ui/forms.py:136 -msgid "Alias" -msgstr "别名" - -#: mailu/ui/forms.py:138 -msgid "Use SQL LIKE Syntax (e.g. for catch-all aliases)" -msgstr "使用SQL LIKE语法(例如,用于全部别名)" - -#: mailu/ui/forms.py:145 -msgid "Admin email" -msgstr "管理员邮箱" - -#: mailu/ui/forms.py:146 mailu/ui/forms.py:151 mailu/ui/forms.py:164 -msgid "Submit" -msgstr "提交" - -#: mailu/ui/forms.py:150 -msgid "Manager email" -msgstr "管理员邮箱" - -#: mailu/ui/forms.py:155 -msgid "Protocol" -msgstr "协议" - -#: mailu/ui/forms.py:158 -msgid "Hostname or IP" -msgstr "主机名或IP" - -#: mailu/ui/forms.py:159 mailu/ui/templates/client.html:20 -#: mailu/ui/templates/client.html:47 -msgid "TCP port" -msgstr "TCP端口" - -#: mailu/ui/forms.py:160 -msgid "Enable TLS" -msgstr "启用TLS" - -#: mailu/ui/forms.py:161 mailu/ui/templates/client.html:28 -#: mailu/ui/templates/client.html:55 mailu/ui/templates/fetch/list.html:20 -msgid "Username" -msgstr "用户名" - -#: mailu/ui/forms.py:163 -msgid "Keep emails on the server" -msgstr "在服务器上保留电子邮件" - -#: mailu/ui/forms.py:168 -msgid "Announcement subject" -msgstr "公告主题" - -#: mailu/ui/forms.py:170 -msgid "Announcement body" -msgstr "公告正文" - -#: mailu/ui/forms.py:172 -msgid "Send" -msgstr "发送" - -#: mailu/ui/templates/announcement.html:4 -msgid "Public announcement" -msgstr "公开公告" - -#: mailu/ui/templates/client.html:4 mailu/ui/templates/sidebar.html:82 -msgid "Client setup" -msgstr "客户端设置" - -#: mailu/ui/templates/client.html:16 mailu/ui/templates/client.html:43 -msgid "Mail protocol" -msgstr "邮件协议" - -#: mailu/ui/templates/client.html:24 mailu/ui/templates/client.html:51 -msgid "Server name" -msgstr "服务器名称" - -#: mailu/ui/templates/confirm.html:4 -msgid "Confirm action" -msgstr "确认操作" - -#: mailu/ui/templates/confirm.html:13 -#, python-format -msgid "You are about to %(action)s. Please confirm your action." -msgstr "即将%(action)s,请确认您的操作。" - -#: mailu/ui/templates/docker-error.html:4 -msgid "Docker error" -msgstr "Docker 错误" - -#: mailu/ui/templates/docker-error.html:12 -msgid "An error occurred while talking to the Docker server." -msgstr "Docker服务器通信出错" - -#: mailu/ui/templates/login.html:8 -msgid "to access the administration tools" -msgstr "访问管理工具" - -#: mailu/ui/templates/sidebar.html:8 -msgid "My account" -msgstr "我的账户" - -#: mailu/ui/templates/sidebar.html:11 mailu/ui/templates/user/list.html:34 -msgid "Settings" -msgstr "设置" - -#: mailu/ui/templates/sidebar.html:21 mailu/ui/templates/user/list.html:35 -msgid "Auto-reply" -msgstr "自动回复" - -#: mailu/ui/templates/fetch/list.html:4 mailu/ui/templates/sidebar.html:26 -#: mailu/ui/templates/user/list.html:36 -msgid "Fetched accounts" -msgstr "代收账户" - -#: mailu/ui/templates/sidebar.html:31 mailu/ui/templates/token/list.html:4 -msgid "Authentication tokens" -msgstr "认证令牌" - -#: mailu/ui/templates/sidebar.html:35 -msgid "Administration" -msgstr "管理" - -#: mailu/ui/templates/sidebar.html:44 -msgid "Announcement" -msgstr "公告" - -#: mailu/ui/templates/sidebar.html:49 -msgid "Administrators" -msgstr "管理员" - -#: mailu/ui/templates/sidebar.html:54 -msgid "Relayed domains" -msgstr "中继域" - -#: mailu/ui/templates/sidebar.html:59 mailu/ui/templates/user/settings.html:15 -msgid "Antispam" -msgstr "发垃圾邮件" - -#: mailu/ui/templates/sidebar.html:66 -msgid "Mail domains" -msgstr "邮件域" - -#: mailu/ui/templates/sidebar.html:72 -msgid "Go to" -msgstr "转到" - -#: mailu/ui/templates/sidebar.html:76 -msgid "Webmail" -msgstr "网页邮箱" - -#: mailu/ui/templates/sidebar.html:87 -msgid "Website" -msgstr "网站" - -#: mailu/ui/templates/sidebar.html:92 -msgid "Help" -msgstr "帮助" - -#: mailu/ui/templates/domain/signup.html:4 mailu/ui/templates/sidebar.html:98 -msgid "Register a domain" -msgstr "注册域名" - -#: mailu/ui/templates/sidebar.html:105 -msgid "Sign out" -msgstr "登出" - -#: mailu/ui/templates/working.html:4 -msgid "We are still working on this feature!" -msgstr "该功能开发中……" - -#: mailu/ui/templates/admin/create.html:4 -msgid "Add a global administrator" -msgstr "添加全局管理员" - -#: mailu/ui/templates/admin/list.html:4 -msgid "Global administrators" -msgstr "全局管理员" - -#: mailu/ui/templates/admin/list.html:9 -msgid "Add administrator" -msgstr "添加管理员" - -#: mailu/ui/templates/admin/list.html:16 mailu/ui/templates/alias/list.html:18 -#: mailu/ui/templates/alternative/list.html:18 -#: mailu/ui/templates/domain/list.html:16 mailu/ui/templates/fetch/list.html:18 -#: mailu/ui/templates/manager/list.html:18 -#: mailu/ui/templates/relay/list.html:16 mailu/ui/templates/token/list.html:18 -#: mailu/ui/templates/user/list.html:18 -msgid "Actions" -msgstr "操作" - -#: mailu/ui/templates/admin/list.html:17 mailu/ui/templates/alias/list.html:19 -#: mailu/ui/templates/manager/list.html:19 mailu/ui/templates/user/list.html:20 -msgid "Email" -msgstr "电子邮件" - -#: mailu/ui/templates/admin/list.html:22 mailu/ui/templates/alias/list.html:29 -#: mailu/ui/templates/alternative/list.html:25 -#: mailu/ui/templates/domain/list.html:31 mailu/ui/templates/fetch/list.html:31 -#: mailu/ui/templates/manager/list.html:24 -#: mailu/ui/templates/relay/list.html:27 mailu/ui/templates/token/list.html:26 -#: mailu/ui/templates/user/list.html:31 -msgid "Delete" -msgstr "删除" - -#: mailu/ui/templates/alias/create.html:4 -msgid "Create alias" -msgstr "创建别名" - -#: mailu/ui/templates/alias/edit.html:4 -msgid "Edit alias" -msgstr "编辑别名" - -#: mailu/ui/templates/alias/list.html:4 -msgid "Alias list" -msgstr "别名列表" - -#: mailu/ui/templates/alias/list.html:12 -msgid "Add alias" -msgstr "添加别名" - -#: mailu/ui/templates/alias/list.html:22 -#: mailu/ui/templates/alternative/list.html:20 -#: mailu/ui/templates/domain/list.html:22 mailu/ui/templates/fetch/list.html:24 -#: mailu/ui/templates/relay/list.html:20 mailu/ui/templates/token/list.html:21 -#: mailu/ui/templates/user/list.html:24 -msgid "Created" -msgstr "已创建" - -#: mailu/ui/templates/alias/list.html:23 mailu/ui/templates/domain/list.html:23 -#: mailu/ui/templates/fetch/list.html:25 mailu/ui/templates/relay/list.html:21 -#: mailu/ui/templates/user/list.html:25 -msgid "Last edit" -msgstr "上次编辑" - -#: mailu/ui/templates/alias/list.html:28 mailu/ui/templates/domain/list.html:30 -#: mailu/ui/templates/fetch/list.html:30 mailu/ui/templates/relay/list.html:26 -#: mailu/ui/templates/user/list.html:30 -msgid "Edit" -msgstr "编辑" - -#: mailu/ui/templates/alternative/create.html:4 -msgid "Create alternative domain" -msgstr "创建替代域" - -#: mailu/ui/templates/alternative/list.html:4 -msgid "Alternative domain list" -msgstr "替代域名列表" - -#: mailu/ui/templates/alternative/list.html:12 -msgid "Add alternative" -msgstr "添加替代" - -#: mailu/ui/templates/alternative/list.html:19 -msgid "Name" -msgstr "名称" - -#: mailu/ui/templates/domain/create.html:4 -#: mailu/ui/templates/domain/list.html:9 -msgid "New domain" -msgstr "新域" - -#: mailu/ui/templates/domain/details.html:4 -msgid "Domain details" -msgstr "域详细信息" - -#: mailu/ui/templates/domain/details.html:15 -msgid "Regenerate keys" -msgstr "重新生成秘钥" - -#: mailu/ui/templates/domain/details.html:17 -msgid "Generate keys" -msgstr "生成秘钥" - -#: mailu/ui/templates/domain/details.html:31 -msgid "DNS MX entry" -msgstr "DNS MX条目" - -#: mailu/ui/templates/domain/details.html:35 -msgid "DNS SPF entries" -msgstr "DNS SPF 条目" - -#: mailu/ui/templates/domain/details.html:42 -msgid "DKIM public key" -msgstr "DKIM 公钥" - -#: mailu/ui/templates/domain/details.html:46 -msgid "DNS DKIM entry" -msgstr "DNS DKIM 条目" - -#: mailu/ui/templates/domain/details.html:50 -msgid "DNS DMARC entry" -msgstr "DNS DMARC 条目" - -#: mailu/ui/templates/domain/edit.html:4 -msgid "Edit domain" -msgstr "编辑域" - -#: mailu/ui/templates/domain/list.html:4 -msgid "Domain list" -msgstr "域列表" - -#: mailu/ui/templates/domain/list.html:17 -msgid "Manage" -msgstr "管理" - -#: mailu/ui/templates/domain/list.html:19 -msgid "Mailbox count" -msgstr "邮箱数量" - -#: mailu/ui/templates/domain/list.html:20 -msgid "Alias count" -msgstr "别名数量" - -#: mailu/ui/templates/domain/list.html:28 -msgid "Details" -msgstr "详细信息" - -#: mailu/ui/templates/domain/list.html:35 -msgid "Users" -msgstr "用户" - -#: mailu/ui/templates/domain/list.html:36 -msgid "Aliases" -msgstr "别名" - -#: mailu/ui/templates/domain/list.html:37 -msgid "Managers" -msgstr "管理员" - -#: mailu/ui/templates/domain/list.html:39 -msgid "Alternatives" -msgstr "备选方案" - -#: mailu/ui/templates/domain/signup.html:13 -msgid "" -"In order to register a new domain, you must first setup the\n" -" domain zone so that the domain MX points to this server" -msgstr "在注册一个新的域名前,您必须先为该域名设置 MX 记录,并使其指向本服务器" - -#: mailu/ui/templates/domain/signup.html:18 -msgid "" -"If you do not know how to setup an MX record for your DNS " -"zone,\n" -" please contact your DNS provider or administrator. Also, please wait " -"a\n" -" couple minutes after the MX is set so the local server " -"cache\n" -" expires." -msgstr "如果您不知道如何为域名设置 MX 记录,请联系你的DNS提供商或者系统管理员。在设置完成 MX 记录后,请等待本地域名服务器的缓存过期。" - - -#: mailu/ui/templates/fetch/create.html:4 -msgid "Add a fetched account" -msgstr "添加一个代收账户" - -#: mailu/ui/templates/fetch/edit.html:4 -msgid "Update a fetched account" -msgstr "更新代收账户" - -#: mailu/ui/templates/fetch/list.html:12 -msgid "Add an account" -msgstr "添加一个账户" - -#: mailu/ui/templates/fetch/list.html:19 -msgid "Endpoint" -msgstr "端点" - -#: mailu/ui/templates/fetch/list.html:21 -msgid "Keep emails" -msgstr "保留电子邮件" - -#: mailu/ui/templates/fetch/list.html:22 -msgid "Last check" -msgstr "上次检查" - -#: mailu/ui/templates/fetch/list.html:35 -msgid "yes" -msgstr "是" - -#: mailu/ui/templates/fetch/list.html:35 -msgid "no" -msgstr "否" - -#: mailu/ui/templates/manager/create.html:4 -msgid "Add a manager" -msgstr "添加一个管理员" - -#: mailu/ui/templates/manager/list.html:4 -msgid "Manager list" -msgstr "管理员列表" - -#: mailu/ui/templates/manager/list.html:12 -msgid "Add manager" -msgstr "添加管理员" - -#: mailu/ui/templates/relay/create.html:4 -msgid "New relay domain" -msgstr "新的中继域" - -#: mailu/ui/templates/relay/edit.html:4 -msgid "Edit relayd domain" -msgstr "编辑中继域" - -#: mailu/ui/templates/relay/list.html:4 -msgid "Relayed domain list" -msgstr "中继域列表" - -#: mailu/ui/templates/relay/list.html:9 -msgid "New relayed domain" -msgstr "新的中继域" - -#: mailu/ui/templates/token/create.html:4 -msgid "Create an authentication token" -msgstr "创建一个认证令牌" - -#: mailu/ui/templates/token/list.html:12 -msgid "New token" -msgstr "新令牌" - -#: mailu/ui/templates/user/create.html:4 -msgid "New user" -msgstr "新用户" - -#: mailu/ui/templates/user/create.html:15 -msgid "General" -msgstr "通用" - -#: mailu/ui/templates/user/create.html:22 -msgid "Features and quotas" -msgstr "功能和配额" - -#: mailu/ui/templates/user/edit.html:4 -msgid "Edit user" -msgstr "编辑用户" - -#: mailu/ui/templates/user/forward.html:4 -msgid "Forward emails" -msgstr "转发邮件" - -#: mailu/ui/templates/user/list.html:4 -msgid "User list" -msgstr "用户列表" - -#: mailu/ui/templates/user/list.html:12 -msgid "Add user" -msgstr "添加用户" - -#: mailu/ui/templates/user/list.html:19 mailu/ui/templates/user/settings.html:4 -msgid "User settings" -msgstr "用户设置" - -#: mailu/ui/templates/user/list.html:21 -msgid "Features" -msgstr "功能" - -#: mailu/ui/templates/user/password.html:4 -msgid "Password update" -msgstr "更新密码" - -#: mailu/ui/templates/user/reply.html:4 -msgid "Automatic reply" -msgstr "自动回复" - -#: mailu/ui/templates/user/settings.html:22 -msgid "Auto-forward" -msgstr "自动转发" - -#: mailu/ui/templates/user/signup_domain.html:8 -msgid "pick a domain for the new account" -msgstr "为新用户选择一个域名" - -#: mailu/ui/templates/user/signup_domain.html:14 -msgid "Domain" -msgstr "域名" - -#: mailu/ui/templates/user/signup_domain.html:15 -msgid "Available slots" -msgstr "可用" - -#~ msgid "Your account" -#~ msgstr "" - -#~ msgid "Spam filter threshold" -#~ msgstr "" - -#~ msgid "from" -#~ msgstr "" - -#~ msgid "General settings" -#~ msgstr "" From 303fae00fb3a5bcc125c6223a3f3caae3a334ec5 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Thu, 14 Oct 2021 23:25:42 +0200 Subject: [PATCH 30/33] cleanup modules. use dkim selector from config --- core/admin/mailu/internal/views/rspamd.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/admin/mailu/internal/views/rspamd.py b/core/admin/mailu/internal/views/rspamd.py index 61e27a59..aa969a5a 100644 --- a/core/admin/mailu/internal/views/rspamd.py +++ b/core/admin/mailu/internal/views/rspamd.py @@ -1,4 +1,4 @@ -from mailu import models, dkim +from mailu import models from mailu.internal import internal import flask @@ -22,7 +22,7 @@ def rspamd_dkim_key(domain_name): { 'domain' : domain.name, 'key' : key.decode('utf8'), - 'selector': 'dkim', + 'selector': flask.current_app.config.get('DKIM_SELECTOR', 'dkim'), } ] } From 7b0c5935a8c5d1b99ccf6927594ae0cf2b20afb1 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 15 Oct 2021 13:16:37 +0200 Subject: [PATCH 31/33] only support GET method in vault --- core/admin/mailu/internal/views/rspamd.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/admin/mailu/internal/views/rspamd.py b/core/admin/mailu/internal/views/rspamd.py index aa969a5a..8551eb8f 100644 --- a/core/admin/mailu/internal/views/rspamd.py +++ b/core/admin/mailu/internal/views/rspamd.py @@ -12,7 +12,7 @@ def vault_error(*messages, status=404): # hashicorp vault answer format: # {"request_id":"...","lease_id":"","renewable":false,"lease_duration":2764800,"data":{...see above...},"wrap_info":null,"warnings":null,"auth":null} -@internal.route("/rspamd/vault/v1/dkim/") +@internal.route("/rspamd/vault/v1/dkim/", methods=['GET']) def rspamd_dkim_key(domain_name): domain = models.Domain.query.get(domain_name) or flask.abort(vault_error('unknown domain')) key = domain.dkim_key or flask.abort(vault_error('no dkim key', status=400)) From 135c5119c568a065c74292bf6232a3970c70c788 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 15 Oct 2021 13:36:41 +0200 Subject: [PATCH 32/33] added newsfragment --- towncrier/newsfragments/2017.enhancement | 1 + 1 file changed, 1 insertion(+) create mode 100644 towncrier/newsfragments/2017.enhancement diff --git a/towncrier/newsfragments/2017.enhancement b/towncrier/newsfragments/2017.enhancement new file mode 100644 index 00000000..076914d2 --- /dev/null +++ b/towncrier/newsfragments/2017.enhancement @@ -0,0 +1 @@ +rspamd: get dkim keys via REST API instead of filesystem From 7fe15ea9cf81a1d29485c6d64e2dc68645ad6eef Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 15 Oct 2021 14:22:50 +0200 Subject: [PATCH 33/33] added dmarc record for report domain --- core/admin/mailu/models.py | 7 +++++++ core/admin/mailu/ui/templates/domain/details.html | 10 ++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/core/admin/mailu/models.py b/core/admin/mailu/models.py index 01711a60..561a4ab6 100644 --- a/core/admin/mailu/models.py +++ b/core/admin/mailu/models.py @@ -243,6 +243,13 @@ class Domain(Base): ruf = f' ruf=mailto:{ruf}@{domain};' if ruf else '' return f'_dmarc.{self.name}. 600 IN TXT "v=DMARC1; p=reject;{rua}{ruf} adkim=s; aspf=s"' + @cached_property + def dns_dmarc_report(self): + """ return DMARC report record for mailu server """ + if self.dkim_key: + domain = app.config['DOMAIN'] + return f'{self.name}._report._dmarc.{domain}. 600 IN TXT "v=DMARC1"' + @cached_property def dns_autoconfig(self): """ return list of auto configuration records (RFC6186) """ diff --git a/core/admin/mailu/ui/templates/domain/details.html b/core/admin/mailu/ui/templates/domain/details.html index b90ea3de..a30b9357 100644 --- a/core/admin/mailu/ui/templates/domain/details.html +++ b/core/admin/mailu/ui/templates/domain/details.html @@ -46,7 +46,10 @@ {% trans %}DNS DMARC entry{% endtrans %} - {{ macros.clip("dns_dmark") }}
{{ domain.dns_dmarc }}
+ + {{ macros.clip("dns_dmarc") }}
{{ domain.dns_dmarc }}
+ {{ macros.clip("dns_dmarc_report") }}
{{ domain.dns_dmarc_report }}
+ {%- endif %} {%- set tlsa_record=domain.dns_tlsa %} @@ -58,12 +61,11 @@ {%- endif %} {% trans %}DNS client auto-configuration (RFC6186) entries{% endtrans %} - - {{ macros.clip("dns_autoconfig") }}
+  {{ macros.clip("dns_autoconfig") }}
 {%- for line in domain.dns_autoconfig %}
 {{ line }}
 {%- endfor -%}
-    
+
{%- endcall %} {%- endblock %}