Merge branch 'master' into patch-1

master
Dario Ernst 5 years ago committed by GitHub
commit 4d475f4e69
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -67,6 +67,7 @@ DEFAULT_CONFIG = {
'HOST_REDIS': 'redis', 'HOST_REDIS': 'redis',
'HOST_FRONT': 'front', 'HOST_FRONT': 'front',
'SUBNET': '192.168.203.0/24', 'SUBNET': '192.168.203.0/24',
'SUBNET6': None,
'POD_ADDRESS_RANGE': None 'POD_ADDRESS_RANGE': None
} }

@ -1,23 +1,7 @@
from mailu.limiter import RateLimitExceeded
from mailu import utils
from flask import current_app as app
import socket
import flask import flask
internal = flask.Blueprint('internal', __name__, template_folder='templates') internal = flask.Blueprint('internal', __name__, template_folder='templates')
@internal.app_errorhandler(RateLimitExceeded)
def rate_limit_handler(e):
response = flask.Response()
response.headers['Auth-Status'] = 'Authentication rate limit from one source exceeded'
response.headers['Auth-Error-Code'] = '451 4.3.2'
if int(flask.request.headers['Auth-Login-Attempt']) < 10:
response.headers['Auth-Wait'] = '3'
return response
from mailu.internal.views import * from mailu.internal.views import *

@ -5,21 +5,31 @@ from flask import current_app as app
import flask import flask
import flask_login import flask_login
import base64 import base64
import ipaddress
@internal.route("/auth/email") @internal.route("/auth/email")
def nginx_authentication(): def nginx_authentication():
""" Main authentication endpoint for Nginx email server """ Main authentication endpoint for Nginx email server
""" """
utils.limiter.check(flask.request.headers["Client-Ip"]) limiter = utils.limiter.get_limiter(app.config["AUTH_RATELIMIT"], "auth-ip")
client_ip = flask.request.headers["Client-Ip"]
if not limiter.test(client_ip):
response = flask.Response()
response.headers['Auth-Status'] = 'Authentication rate limit from one source exceeded'
response.headers['Auth-Error-Code'] = '451 4.3.2'
if int(flask.request.headers['Auth-Login-Attempt']) < 10:
response.headers['Auth-Wait'] = '3'
return response
headers = nginx.handle_authentication(flask.request.headers) headers = nginx.handle_authentication(flask.request.headers)
response = flask.Response() response = flask.Response()
for key, value in headers.items(): for key, value in headers.items():
response.headers[key] = str(value) response.headers[key] = str(value)
if ("Auth-Status" not in headers) or (headers["Auth-Status"]!="OK"): if ("Auth-Status" not in headers) or (headers["Auth-Status"] != "OK"):
utils.limiter.hit(flask.request.headers["Client-Ip"]) limit_subnet = str(app.config["AUTH_RATELIMIT_SUBNET"]) != 'False'
subnet = ipaddress.ip_network(app.config["SUBNET"])
if limit_subnet or ipaddress.ip_address(client_ip) not in subnet:
limiter.hit(flask.request.headers["Client-Ip"])
return response return response

@ -11,6 +11,8 @@ def dovecot_passdb_dict(user_email):
user = models.User.query.get(user_email) or flask.abort(404) user = models.User.query.get(user_email) or flask.abort(404)
allow_nets = [] allow_nets = []
allow_nets.append(app.config["SUBNET"]) allow_nets.append(app.config["SUBNET"])
if app.config["SUBNET6"]:
allow_nets.append(app.config["SUBNET6"])
if app.config["POD_ADDRESS_RANGE"]: if app.config["POD_ADDRESS_RANGE"]:
allow_nets.append(app.config["POD_ADDRESS_RANGE"]) allow_nets.append(app.config["POD_ADDRESS_RANGE"])
return flask.jsonify({ return flask.jsonify({

@ -3,6 +3,7 @@ from mailu.internal import internal
import flask import flask
import re import re
import srslib
@internal.route("/postfix/domain/<domain_name>") @internal.route("/postfix/domain/<domain_name>")
@ -36,7 +37,43 @@ def postfix_transport(email):
return flask.abort(404) return flask.abort(404)
localpart, domain_name = models.Email.resolve_domain(email) localpart, domain_name = models.Email.resolve_domain(email)
relay = models.Relay.query.get(domain_name) or flask.abort(404) relay = models.Relay.query.get(domain_name) or flask.abort(404)
return flask.jsonify("smtp:[{}]".format(relay.smtp)) ret = "smtp:[{0}]".format(relay.smtp)
if ":" in relay.smtp:
split = relay.smtp.split(':')
ret = "smtp:[{0}]:{1}".format(split[0], split[1])
return flask.jsonify(ret)
@internal.route("/postfix/recipient/map/<path:recipient>")
def postfix_recipient_map(recipient):
""" Rewrite the envelope recipient if it is a valid SRS address.
This is meant for bounces to go back to the original sender.
"""
srs = srslib.SRS(flask.current_app.config["SECRET_KEY"])
if srslib.SRS.is_srs_address(recipient):
try:
return flask.jsonify(srs.reverse(recipient))
except srslib.Error as error:
return flask.abort(404)
return flask.abort(404)
@internal.route("/postfix/sender/map/<path:sender>")
def postfix_sender_map(sender):
""" Rewrite the envelope sender in case the mail was not emitted by us.
This is for bounces to come back the reverse path properly.
"""
srs = srslib.SRS(flask.current_app.config["SECRET_KEY"])
domain = flask.current_app.config["DOMAIN"]
try:
localpart, domain_name = models.Email.resolve_domain(sender)
except Exception as error:
return flask.abort(404)
if models.Domain.query.get(domain_name):
return flask.abort(404)
return flask.jsonify(srs.forward(sender, domain))
@internal.route("/postfix/sender/login/<path:sender>") @internal.route("/postfix/sender/login/<path:sender>")

@ -1,36 +1,34 @@
import limits import limits
import limits.storage import limits.storage
import limits.strategies import limits.strategies
import ipaddress
class RateLimitExceeded(Exception):
pass
class Limiter: class LimitWrapper(object):
""" Wraps a limit by providing the storage, item and identifiers
"""
def __init__(self): def __init__(self, limiter, limit, *identifiers):
self.storage = None self.limiter = limiter
self.limiter = None self.limit = limit
self.rate = None self.base_identifiers = identifiers
self.subnet = None
self.rate_limit_subnet = True def test(self, *args):
return self.limiter.test(self.limit, *(self.base_identifiers + args))
def hit(self, *args):
return self.limiter.hit(self.limit, *(self.base_identifiers + args))
def get_window_stats(self, *args):
return self.limiter.get_window_stats(self.limit, *(self.base_identifiers + args))
class LimitWraperFactory(object):
""" Global limiter, to be used as a factory
"""
def init_app(self, app): def init_app(self, app):
self.storage = limits.storage.storage_from_string(app.config["RATELIMIT_STORAGE_URL"]) self.storage = limits.storage.storage_from_string(app.config["RATELIMIT_STORAGE_URL"])
self.limiter = limits.strategies.MovingWindowRateLimiter(self.storage) self.limiter = limits.strategies.MovingWindowRateLimiter(self.storage)
self.rate = limits.parse(app.config["AUTH_RATELIMIT"])
self.rate_limit_subnet = str(app.config["AUTH_RATELIMIT_SUBNET"])!='False'
self.subnet = ipaddress.ip_network(app.config["SUBNET"])
def check(self,clientip): def get_limiter(self, limit, *args):
# disable limits for internal requests (e.g. from webmail)? return LimitWrapper(self.limiter, limits.parse(limit), *args)
if self.rate_limit_subnet==False and ipaddress.ip_address(clientip) in self.subnet:
return
if not self.limiter.test(self.rate,"client-ip",clientip):
raise RateLimitExceeded()
def hit(self,clientip):
# disable limits for internal requests (e.g. from webmail)?
if self.rate_limit_subnet==False and ipaddress.ip_address(clientip) in self.subnet:
return
self.limiter.hit(self.rate,"client-ip",clientip)

@ -177,7 +177,7 @@ def config_update(verbose=False, delete_objects=False):
"""sync configuration with data from YAML-formatted stdin""" """sync configuration with data from YAML-formatted stdin"""
import yaml import yaml
import sys import sys
new_config = yaml.load(sys.stdin) new_config = yaml.safe_load(sys.stdin)
# print new_config # print new_config
domains = new_config.get('domains', []) domains = new_config.get('domains', [])
tracked_domains = set() tracked_domains = set()

@ -8,13 +8,16 @@ msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2018-04-22 12:10+0200\n" "POT-Creation-Date: 2018-04-22 12:10+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: 2020-03-11 23:03+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: Jaume Barber <jaumebarber@gmail.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: Catalan <https://translate.tedomum.net/projects/mailu/admin/"
"ca/>\n"
"Language: ca\n" "Language: ca\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 3.11.2\n"
"Generated-By: Babel 2.5.3\n" "Generated-By: Babel 2.5.3\n"
#: mailu/ui/forms.py:32 #: mailu/ui/forms.py:32
@ -22,45 +25,46 @@ msgid "Invalid email address."
msgstr "" msgstr ""
#: mailu/ui/forms.py:36 #: mailu/ui/forms.py:36
#, fuzzy
msgid "Confirm" msgid "Confirm"
msgstr "" msgstr "Confirmeu"
#: mailu/ui/forms.py:40 mailu/ui/forms.py:77 #: mailu/ui/forms.py:40 mailu/ui/forms.py:77
msgid "E-mail" msgid "E-mail"
msgstr "" msgstr "Correu"
#: mailu/ui/forms.py:41 mailu/ui/forms.py:78 mailu/ui/forms.py:90 #: 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/forms.py:109 mailu/ui/forms.py:162
#: mailu/ui/templates/client.html:32 mailu/ui/templates/client.html:59 #: mailu/ui/templates/client.html:32 mailu/ui/templates/client.html:59
msgid "Password" msgid "Password"
msgstr "" msgstr "Contrasenya"
#: mailu/ui/forms.py:42 mailu/ui/templates/login.html:4 #: mailu/ui/forms.py:42 mailu/ui/templates/login.html:4
#: mailu/ui/templates/sidebar.html:111 #: mailu/ui/templates/sidebar.html:111
msgid "Sign in" msgid "Sign in"
msgstr "" msgstr "Entreu"
#: mailu/ui/forms.py:46 mailu/ui/forms.py:56 #: mailu/ui/forms.py:46 mailu/ui/forms.py:56
#: mailu/ui/templates/domain/details.html:27 #: mailu/ui/templates/domain/details.html:27
#: mailu/ui/templates/domain/list.html:18 mailu/ui/templates/relay/list.html:17 #: mailu/ui/templates/domain/list.html:18 mailu/ui/templates/relay/list.html:17
msgid "Domain name" msgid "Domain name"
msgstr "" msgstr "Nom de domini"
#: mailu/ui/forms.py:47 #: mailu/ui/forms.py:47
msgid "Maximum user count" msgid "Maximum user count"
msgstr "" msgstr "Nombre màxim d'usuaris"
#: mailu/ui/forms.py:48 #: mailu/ui/forms.py:48
msgid "Maximum alias count" msgid "Maximum alias count"
msgstr "" msgstr "Nombre màxim d'àlies"
#: mailu/ui/forms.py:49 #: mailu/ui/forms.py:49
msgid "Maximum user quota" msgid "Maximum user quota"
msgstr "" msgstr "Espai màxim per usuari"
#: mailu/ui/forms.py:50 #: mailu/ui/forms.py:50
msgid "Enable sign-up" msgid "Enable sign-up"
msgstr "" msgstr "Activeu el registre"
#: mailu/ui/forms.py:51 mailu/ui/forms.py:72 mailu/ui/forms.py:83 #: 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/forms.py:128 mailu/ui/forms.py:140
@ -68,308 +72,308 @@ msgstr ""
#: mailu/ui/templates/relay/list.html:19 mailu/ui/templates/token/list.html:19 #: mailu/ui/templates/relay/list.html:19 mailu/ui/templates/token/list.html:19
#: mailu/ui/templates/user/list.html:23 #: mailu/ui/templates/user/list.html:23
msgid "Comment" msgid "Comment"
msgstr "" msgstr "Comentari"
#: mailu/ui/forms.py:52 mailu/ui/forms.py:61 mailu/ui/forms.py:66 #: 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 #: mailu/ui/forms.py:73 mailu/ui/forms.py:132 mailu/ui/forms.py:141
msgid "Create" msgid "Create"
msgstr "" msgstr "Creeu"
#: mailu/ui/forms.py:57 #: mailu/ui/forms.py:57
msgid "Initial admin" msgid "Initial admin"
msgstr "" msgstr "Admin inicial"
#: mailu/ui/forms.py:58 #: mailu/ui/forms.py:58
msgid "Admin password" msgid "Admin password"
msgstr "" msgstr "Contrasenya d'admin"
#: mailu/ui/forms.py:59 mailu/ui/forms.py:79 mailu/ui/forms.py:91 #: mailu/ui/forms.py:59 mailu/ui/forms.py:79 mailu/ui/forms.py:91
msgid "Confirm password" msgid "Confirm password"
msgstr "" msgstr "Confirmeu la contrasenya"
#: mailu/ui/forms.py:65 #: mailu/ui/forms.py:65
msgid "Alternative name" msgid "Alternative name"
msgstr "" msgstr "Nom alternatiu"
#: mailu/ui/forms.py:70 #: mailu/ui/forms.py:70
msgid "Relayed domain name" msgid "Relayed domain name"
msgstr "" msgstr "Nom de domini traspassat (relayed)"
#: mailu/ui/forms.py:71 mailu/ui/templates/relay/list.html:18 #: mailu/ui/forms.py:71 mailu/ui/templates/relay/list.html:18
msgid "Remote host" msgid "Remote host"
msgstr "" msgstr "Amfitrió remot"
#: mailu/ui/forms.py:80 mailu/ui/templates/user/list.html:22 #: mailu/ui/forms.py:80 mailu/ui/templates/user/list.html:22
#: mailu/ui/templates/user/signup_domain.html:16 #: mailu/ui/templates/user/signup_domain.html:16
msgid "Quota" msgid "Quota"
msgstr "" msgstr "Espai"
#: mailu/ui/forms.py:81 #: mailu/ui/forms.py:81
msgid "Allow IMAP access" msgid "Allow IMAP access"
msgstr "" msgstr "Permeteu accés IMAP"
#: mailu/ui/forms.py:82 #: mailu/ui/forms.py:82
msgid "Allow POP3 access" msgid "Allow POP3 access"
msgstr "" msgstr "Permeteu accés POP3"
#: mailu/ui/forms.py:84 #: mailu/ui/forms.py:84
msgid "Enabled" msgid "Enabled"
msgstr "" msgstr "Activat"
#: mailu/ui/forms.py:85 #: mailu/ui/forms.py:85
msgid "Save" msgid "Save"
msgstr "" msgstr "Desa"
#: mailu/ui/forms.py:89 #: mailu/ui/forms.py:89
msgid "Email address" msgid "Email address"
msgstr "" msgstr "Adreça email"
#: mailu/ui/forms.py:93 mailu/ui/templates/sidebar.html:117 #: mailu/ui/forms.py:93 mailu/ui/templates/sidebar.html:117
#: mailu/ui/templates/user/signup.html:4 #: mailu/ui/templates/user/signup.html:4
#: mailu/ui/templates/user/signup_domain.html:4 #: mailu/ui/templates/user/signup_domain.html:4
msgid "Sign up" msgid "Sign up"
msgstr "" msgstr "Registreu-vos"
#: mailu/ui/forms.py:97 #: mailu/ui/forms.py:97
msgid "Displayed name" msgid "Displayed name"
msgstr "" msgstr "Nom per mostrar"
#: mailu/ui/forms.py:98 #: mailu/ui/forms.py:98
msgid "Enable spam filter" msgid "Enable spam filter"
msgstr "" msgstr "Activeu filtre d'spam"
#: mailu/ui/forms.py:99 #: mailu/ui/forms.py:99
msgid "Spam filter tolerance" msgid "Spam filter tolerance"
msgstr "" msgstr "Tolerància del filtre spam"
#: mailu/ui/forms.py:100 #: mailu/ui/forms.py:100
msgid "Enable forwarding" msgid "Enable forwarding"
msgstr "" msgstr "Activeu el reenviament"
#: mailu/ui/forms.py:101 #: mailu/ui/forms.py:101
msgid "Keep a copy of the emails" msgid "Keep a copy of the emails"
msgstr "" msgstr "Mantigueu una còpia dels correus"
#: mailu/ui/forms.py:103 mailu/ui/forms.py:139 #: mailu/ui/forms.py:103 mailu/ui/forms.py:139
#: mailu/ui/templates/alias/list.html:20 #: mailu/ui/templates/alias/list.html:20
msgid "Destination" msgid "Destination"
msgstr "" msgstr "Destinació"
#: mailu/ui/forms.py:105 #: mailu/ui/forms.py:105
msgid "Save settings" msgid "Save settings"
msgstr "" msgstr "Desa ajustos"
#: mailu/ui/forms.py:110 #: mailu/ui/forms.py:110
msgid "Password check" msgid "Password check"
msgstr "" msgstr "Comproveu la contrasenya"
#: mailu/ui/forms.py:111 mailu/ui/templates/sidebar.html:16 #: mailu/ui/forms.py:111 mailu/ui/templates/sidebar.html:16
msgid "Update password" msgid "Update password"
msgstr "" msgstr "Canvieu la contrasenya"
#: mailu/ui/forms.py:115 #: mailu/ui/forms.py:115
msgid "Enable automatic reply" msgid "Enable automatic reply"
msgstr "" msgstr "Activeu la resposta automàtica"
#: mailu/ui/forms.py:116 #: mailu/ui/forms.py:116
msgid "Reply subject" msgid "Reply subject"
msgstr "" msgstr "Tema de la resposta"
#: mailu/ui/forms.py:117 #: mailu/ui/forms.py:117
msgid "Reply body" msgid "Reply body"
msgstr "" msgstr "Missatge de resposta"
#: mailu/ui/forms.py:119 #: mailu/ui/forms.py:119
msgid "End of vacation" msgid "End of vacation"
msgstr "" msgstr "Tornada de vacances"
#: mailu/ui/forms.py:120 #: mailu/ui/forms.py:120
msgid "Update" msgid "Update"
msgstr "" msgstr "Actualitzeu"
#: mailu/ui/forms.py:125 #: mailu/ui/forms.py:125
msgid "Your token (write it down, as it will never be displayed again)" msgid "Your token (write it down, as it will never be displayed again)"
msgstr "" msgstr "Token personal (apunteu-lo perquè no es mostrarà de nou)"
#: mailu/ui/forms.py:130 mailu/ui/templates/token/list.html:20 #: mailu/ui/forms.py:130 mailu/ui/templates/token/list.html:20
msgid "Authorized IP" msgid "Authorized IP"
msgstr "" msgstr "IP autoritzada"
#: mailu/ui/forms.py:136 #: mailu/ui/forms.py:136
msgid "Alias" msgid "Alias"
msgstr "" msgstr "Àlies"
#: mailu/ui/forms.py:138 #: mailu/ui/forms.py:138
msgid "Use SQL LIKE Syntax (e.g. for catch-all aliases)" msgid "Use SQL LIKE Syntax (e.g. for catch-all aliases)"
msgstr "" msgstr "Feu servir sintaxi tipus SQL (ex. per a agafar tots els àlies)"
#: mailu/ui/forms.py:145 #: mailu/ui/forms.py:145
msgid "Admin email" msgid "Admin email"
msgstr "" msgstr "Adreça d'admin"
#: mailu/ui/forms.py:146 mailu/ui/forms.py:151 mailu/ui/forms.py:164 #: mailu/ui/forms.py:146 mailu/ui/forms.py:151 mailu/ui/forms.py:164
msgid "Submit" msgid "Submit"
msgstr "" msgstr "Envia"
#: mailu/ui/forms.py:150 #: mailu/ui/forms.py:150
msgid "Manager email" msgid "Manager email"
msgstr "" msgstr "Adreça de gestor"
#: mailu/ui/forms.py:155 #: mailu/ui/forms.py:155
msgid "Protocol" msgid "Protocol"
msgstr "" msgstr "Protocol"
#: mailu/ui/forms.py:158 #: mailu/ui/forms.py:158
msgid "Hostname or IP" msgid "Hostname or IP"
msgstr "" msgstr "Nom d'amfitrio o IP"
#: mailu/ui/forms.py:159 mailu/ui/templates/client.html:20 #: mailu/ui/forms.py:159 mailu/ui/templates/client.html:20
#: mailu/ui/templates/client.html:47 #: mailu/ui/templates/client.html:47
msgid "TCP port" msgid "TCP port"
msgstr "" msgstr "Port TCP"
#: mailu/ui/forms.py:160 #: mailu/ui/forms.py:160
msgid "Enable TLS" msgid "Enable TLS"
msgstr "" msgstr "Activeu TLS"
#: mailu/ui/forms.py:161 mailu/ui/templates/client.html:28 #: mailu/ui/forms.py:161 mailu/ui/templates/client.html:28
#: mailu/ui/templates/client.html:55 mailu/ui/templates/fetch/list.html:20 #: mailu/ui/templates/client.html:55 mailu/ui/templates/fetch/list.html:20
msgid "Username" msgid "Username"
msgstr "" msgstr "Nom d'usuari"
#: mailu/ui/forms.py:163 #: mailu/ui/forms.py:163
msgid "Keep emails on the server" msgid "Keep emails on the server"
msgstr "" msgstr "Mantén els correus al servidor"
#: mailu/ui/forms.py:168 #: mailu/ui/forms.py:168
msgid "Announcement subject" msgid "Announcement subject"
msgstr "" msgstr "Tema de l'avís"
#: mailu/ui/forms.py:170 #: mailu/ui/forms.py:170
msgid "Announcement body" msgid "Announcement body"
msgstr "" msgstr "Missatge de l'avís"
#: mailu/ui/forms.py:172 #: mailu/ui/forms.py:172
msgid "Send" msgid "Send"
msgstr "" msgstr "Envia"
#: mailu/ui/templates/announcement.html:4 #: mailu/ui/templates/announcement.html:4
msgid "Public announcement" msgid "Public announcement"
msgstr "" msgstr "Avís públic"
#: mailu/ui/templates/client.html:4 mailu/ui/templates/sidebar.html:82 #: mailu/ui/templates/client.html:4 mailu/ui/templates/sidebar.html:82
msgid "Client setup" msgid "Client setup"
msgstr "" msgstr "Ajustos del client"
#: mailu/ui/templates/client.html:16 mailu/ui/templates/client.html:43 #: mailu/ui/templates/client.html:16 mailu/ui/templates/client.html:43
msgid "Mail protocol" msgid "Mail protocol"
msgstr "" msgstr "Protocol de correu"
#: mailu/ui/templates/client.html:24 mailu/ui/templates/client.html:51 #: mailu/ui/templates/client.html:24 mailu/ui/templates/client.html:51
msgid "Server name" msgid "Server name"
msgstr "" msgstr "Nom de servidor"
#: mailu/ui/templates/confirm.html:4 #: mailu/ui/templates/confirm.html:4
msgid "Confirm action" msgid "Confirm action"
msgstr "" msgstr "Confirmeu acció"
#: mailu/ui/templates/confirm.html:13 #: mailu/ui/templates/confirm.html:13
#, python-format #, python-format
msgid "You are about to %(action)s. Please confirm your action." msgid "You are about to %(action)s. Please confirm your action."
msgstr "" msgstr "Esteu a punt de %(action)s. Per favor, confirmeu l'acció."
#: mailu/ui/templates/docker-error.html:4 #: mailu/ui/templates/docker-error.html:4
msgid "Docker error" msgid "Docker error"
msgstr "" msgstr "Error de Docker"
#: mailu/ui/templates/docker-error.html:12 #: mailu/ui/templates/docker-error.html:12
msgid "An error occurred while talking to the Docker server." msgid "An error occurred while talking to the Docker server."
msgstr "" msgstr "Hi ha hagut un error de comunicació amb el servidor Docker."
#: mailu/ui/templates/login.html:8 #: mailu/ui/templates/login.html:8
msgid "to access the administration tools" msgid "to access the administration tools"
msgstr "" msgstr "per accedir a les eines d'administració"
#: mailu/ui/templates/sidebar.html:11 mailu/ui/templates/user/list.html:34 #: mailu/ui/templates/sidebar.html:11 mailu/ui/templates/user/list.html:34
msgid "Settings" msgid "Settings"
msgstr "" msgstr "Ajustos"
#: mailu/ui/templates/sidebar.html:21 mailu/ui/templates/user/list.html:35 #: mailu/ui/templates/sidebar.html:21 mailu/ui/templates/user/list.html:35
msgid "Auto-reply" msgid "Auto-reply"
msgstr "" msgstr "Resposta automàtica"
#: mailu/ui/templates/fetch/list.html:4 mailu/ui/templates/sidebar.html:26 #: mailu/ui/templates/fetch/list.html:4 mailu/ui/templates/sidebar.html:26
#: mailu/ui/templates/user/list.html:36 #: mailu/ui/templates/user/list.html:36
msgid "Fetched accounts" msgid "Fetched accounts"
msgstr "" msgstr "Comptes trobats"
#: mailu/ui/templates/sidebar.html:31 mailu/ui/templates/token/list.html:4 #: mailu/ui/templates/sidebar.html:31 mailu/ui/templates/token/list.html:4
msgid "Authentication tokens" msgid "Authentication tokens"
msgstr "" msgstr "Tokens d'autenticació"
#: mailu/ui/templates/sidebar.html:35 #: mailu/ui/templates/sidebar.html:35
msgid "Administration" msgid "Administration"
msgstr "" msgstr "Administració"
#: mailu/ui/templates/sidebar.html:44 #: mailu/ui/templates/sidebar.html:44
msgid "Announcement" msgid "Announcement"
msgstr "" msgstr "Avís"
#: mailu/ui/templates/sidebar.html:49 #: mailu/ui/templates/sidebar.html:49
msgid "Administrators" msgid "Administrators"
msgstr "" msgstr "Administradors"
#: mailu/ui/templates/sidebar.html:54 #: mailu/ui/templates/sidebar.html:54
msgid "Relayed domains" msgid "Relayed domains"
msgstr "" msgstr "Dominis tramesos"
#: mailu/ui/templates/sidebar.html:59 mailu/ui/templates/user/settings.html:15 #: mailu/ui/templates/sidebar.html:59 mailu/ui/templates/user/settings.html:15
msgid "Antispam" msgid "Antispam"
msgstr "" msgstr "Antispam"
#: mailu/ui/templates/sidebar.html:66 #: mailu/ui/templates/sidebar.html:66
msgid "Mail domains" msgid "Mail domains"
msgstr "" msgstr "Dominis de correu"
#: mailu/ui/templates/sidebar.html:72 #: mailu/ui/templates/sidebar.html:72
msgid "Go to" msgid "Go to"
msgstr "" msgstr "Aneu a"
#: mailu/ui/templates/sidebar.html:76 #: mailu/ui/templates/sidebar.html:76
msgid "Webmail" msgid "Webmail"
msgstr "" msgstr "Correu web"
#: mailu/ui/templates/sidebar.html:87 #: mailu/ui/templates/sidebar.html:87
msgid "Website" msgid "Website"
msgstr "" msgstr "Lloc web"
#: mailu/ui/templates/sidebar.html:92 #: mailu/ui/templates/sidebar.html:92
msgid "Help" msgid "Help"
msgstr "" msgstr "Ajuda"
#: mailu/ui/templates/domain/signup.html:4 mailu/ui/templates/sidebar.html:98 #: mailu/ui/templates/domain/signup.html:4 mailu/ui/templates/sidebar.html:98
msgid "Register a domain" msgid "Register a domain"
msgstr "" msgstr "Registreu un domini"
#: mailu/ui/templates/sidebar.html:105 #: mailu/ui/templates/sidebar.html:105
msgid "Sign out" msgid "Sign out"
msgstr "" msgstr "Eixiu"
#: mailu/ui/templates/working.html:4 #: mailu/ui/templates/working.html:4
msgid "We are still working on this feature!" msgid "We are still working on this feature!"
msgstr "" msgstr "Encara estem treballant en aquesta funcionalitat!"
#: mailu/ui/templates/admin/create.html:4 #: mailu/ui/templates/admin/create.html:4
msgid "Add a global administrator" msgid "Add a global administrator"
msgstr "" msgstr "Afegiu un admin global"
#: mailu/ui/templates/admin/list.html:4 #: mailu/ui/templates/admin/list.html:4
msgid "Global administrators" msgid "Global administrators"
msgstr "" msgstr "Administradors globals"
#: mailu/ui/templates/admin/list.html:9 #: mailu/ui/templates/admin/list.html:9
msgid "Add administrator" msgid "Add administrator"
msgstr "" msgstr "Afegiu un administrador"
#: mailu/ui/templates/admin/list.html:16 mailu/ui/templates/alias/list.html:18 #: mailu/ui/templates/admin/list.html:16 mailu/ui/templates/alias/list.html:18
#: mailu/ui/templates/alternative/list.html:18 #: mailu/ui/templates/alternative/list.html:18
@ -378,12 +382,12 @@ msgstr ""
#: mailu/ui/templates/relay/list.html:16 mailu/ui/templates/token/list.html:18 #: mailu/ui/templates/relay/list.html:16 mailu/ui/templates/token/list.html:18
#: mailu/ui/templates/user/list.html:18 #: mailu/ui/templates/user/list.html:18
msgid "Actions" msgid "Actions"
msgstr "" msgstr "Accions"
#: mailu/ui/templates/admin/list.html:17 mailu/ui/templates/alias/list.html:19 #: 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 #: mailu/ui/templates/manager/list.html:19 mailu/ui/templates/user/list.html:20
msgid "Email" msgid "Email"
msgstr "" msgstr "Correu"
#: mailu/ui/templates/admin/list.html:22 mailu/ui/templates/alias/list.html:29 #: mailu/ui/templates/admin/list.html:22 mailu/ui/templates/alias/list.html:29
#: mailu/ui/templates/alternative/list.html:25 #: mailu/ui/templates/alternative/list.html:25
@ -392,23 +396,23 @@ msgstr ""
#: mailu/ui/templates/relay/list.html:27 mailu/ui/templates/token/list.html:26 #: mailu/ui/templates/relay/list.html:27 mailu/ui/templates/token/list.html:26
#: mailu/ui/templates/user/list.html:31 #: mailu/ui/templates/user/list.html:31
msgid "Delete" msgid "Delete"
msgstr "" msgstr "Esborra"
#: mailu/ui/templates/alias/create.html:4 #: mailu/ui/templates/alias/create.html:4
msgid "Create alias" msgid "Create alias"
msgstr "" msgstr "Creeu àlies"
#: mailu/ui/templates/alias/edit.html:4 #: mailu/ui/templates/alias/edit.html:4
msgid "Edit alias" msgid "Edit alias"
msgstr "" msgstr "Editeu àlies"
#: mailu/ui/templates/alias/list.html:4 #: mailu/ui/templates/alias/list.html:4
msgid "Alias list" msgid "Alias list"
msgstr "" msgstr "Llista d'àlies"
#: mailu/ui/templates/alias/list.html:12 #: mailu/ui/templates/alias/list.html:12
msgid "Add alias" msgid "Add alias"
msgstr "" msgstr "Afegiu àlies"
#: mailu/ui/templates/alias/list.html:22 #: mailu/ui/templates/alias/list.html:22
#: mailu/ui/templates/alternative/list.html:20 #: mailu/ui/templates/alternative/list.html:20
@ -416,118 +420,121 @@ msgstr ""
#: mailu/ui/templates/relay/list.html:20 mailu/ui/templates/token/list.html:21 #: mailu/ui/templates/relay/list.html:20 mailu/ui/templates/token/list.html:21
#: mailu/ui/templates/user/list.html:24 #: mailu/ui/templates/user/list.html:24
msgid "Created" msgid "Created"
msgstr "" msgstr "Creat"
#: mailu/ui/templates/alias/list.html:23 mailu/ui/templates/domain/list.html:23 #: 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/fetch/list.html:25 mailu/ui/templates/relay/list.html:21
#: mailu/ui/templates/user/list.html:25 #: mailu/ui/templates/user/list.html:25
msgid "Last edit" msgid "Last edit"
msgstr "" msgstr "Última edició"
#: mailu/ui/templates/alias/list.html:28 mailu/ui/templates/domain/list.html:30 #: 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/fetch/list.html:30 mailu/ui/templates/relay/list.html:26
#: mailu/ui/templates/user/list.html:30 #: mailu/ui/templates/user/list.html:30
msgid "Edit" msgid "Edit"
msgstr "" msgstr "Edita"
#: mailu/ui/templates/alternative/create.html:4 #: mailu/ui/templates/alternative/create.html:4
msgid "Create alternative domain" msgid "Create alternative domain"
msgstr "" msgstr "Creeu domini alternatiu"
#: mailu/ui/templates/alternative/list.html:4 #: mailu/ui/templates/alternative/list.html:4
msgid "Alternative domain list" msgid "Alternative domain list"
msgstr "" msgstr "Llista de dominis alternatius"
#: mailu/ui/templates/alternative/list.html:12 #: mailu/ui/templates/alternative/list.html:12
msgid "Add alternative" msgid "Add alternative"
msgstr "" msgstr "Afegiu alternativa"
#: mailu/ui/templates/alternative/list.html:19 #: mailu/ui/templates/alternative/list.html:19
msgid "Name" msgid "Name"
msgstr "" msgstr "Nom"
#: mailu/ui/templates/domain/create.html:4 #: mailu/ui/templates/domain/create.html:4
#: mailu/ui/templates/domain/list.html:9 #: mailu/ui/templates/domain/list.html:9
msgid "New domain" msgid "New domain"
msgstr "" msgstr "Nou domini"
#: mailu/ui/templates/domain/details.html:4 #: mailu/ui/templates/domain/details.html:4
msgid "Domain details" msgid "Domain details"
msgstr "" msgstr "Detalls del domini"
#: mailu/ui/templates/domain/details.html:15 #: mailu/ui/templates/domain/details.html:15
msgid "Regenerate keys" msgid "Regenerate keys"
msgstr "" msgstr "Regenereu les claus"
#: mailu/ui/templates/domain/details.html:17 #: mailu/ui/templates/domain/details.html:17
msgid "Generate keys" msgid "Generate keys"
msgstr "" msgstr "Genereu claus"
#: mailu/ui/templates/domain/details.html:31 #: mailu/ui/templates/domain/details.html:31
msgid "DNS MX entry" msgid "DNS MX entry"
msgstr "" msgstr "Entrada DNS MX"
#: mailu/ui/templates/domain/details.html:35 #: mailu/ui/templates/domain/details.html:35
msgid "DNS SPF entries" msgid "DNS SPF entries"
msgstr "" msgstr "Entrada DNS SPF"
#: mailu/ui/templates/domain/details.html:42 #: mailu/ui/templates/domain/details.html:42
msgid "DKIM public key" msgid "DKIM public key"
msgstr "" msgstr "Clau pública DKIM"
#: mailu/ui/templates/domain/details.html:46 #: mailu/ui/templates/domain/details.html:46
msgid "DNS DKIM entry" msgid "DNS DKIM entry"
msgstr "" msgstr "Entrada DNS DKIM"
#: mailu/ui/templates/domain/details.html:50 #: mailu/ui/templates/domain/details.html:50
msgid "DNS DMARC entry" msgid "DNS DMARC entry"
msgstr "" msgstr "Entrada DNS DMARC"
#: mailu/ui/templates/domain/edit.html:4 #: mailu/ui/templates/domain/edit.html:4
msgid "Edit domain" msgid "Edit domain"
msgstr "" msgstr "Edita domini"
#: mailu/ui/templates/domain/list.html:4 #: mailu/ui/templates/domain/list.html:4
msgid "Domain list" msgid "Domain list"
msgstr "" msgstr "Llista de dominis"
#: mailu/ui/templates/domain/list.html:17 #: mailu/ui/templates/domain/list.html:17
msgid "Manage" msgid "Manage"
msgstr "" msgstr "Gestioneu"
#: mailu/ui/templates/domain/list.html:19 #: mailu/ui/templates/domain/list.html:19
msgid "Mailbox count" msgid "Mailbox count"
msgstr "" msgstr "Nombre de bústies"
#: mailu/ui/templates/domain/list.html:20 #: mailu/ui/templates/domain/list.html:20
msgid "Alias count" msgid "Alias count"
msgstr "" msgstr "Nombre d'àlies"
#: mailu/ui/templates/domain/list.html:28 #: mailu/ui/templates/domain/list.html:28
msgid "Details" msgid "Details"
msgstr "" msgstr "Detalls"
#: mailu/ui/templates/domain/list.html:35 #: mailu/ui/templates/domain/list.html:35
msgid "Users" msgid "Users"
msgstr "" msgstr "Usuaris"
#: mailu/ui/templates/domain/list.html:36 #: mailu/ui/templates/domain/list.html:36
msgid "Aliases" msgid "Aliases"
msgstr "" msgstr "Àlies"
#: mailu/ui/templates/domain/list.html:37 #: mailu/ui/templates/domain/list.html:37
msgid "Managers" msgid "Managers"
msgstr "" msgstr "Gestors"
#: mailu/ui/templates/domain/list.html:39 #: mailu/ui/templates/domain/list.html:39
msgid "Alternatives" msgid "Alternatives"
msgstr "" msgstr "Alternatives"
#: mailu/ui/templates/domain/signup.html:13 #: mailu/ui/templates/domain/signup.html:13
msgid "" msgid ""
"In order to register a new domain, you must first setup the\n" "In order to register a new domain, you must first setup the\n"
" domain zone so that the domain <code>MX</code> points to this server" " domain zone so that the domain <code>MX</code> points to this server"
msgstr "" msgstr ""
"Per a registrar un nou domini, heu de configurar la \n"
" zona de dominis per tal que el domini <code>MX</code> apunte a aquest "
"servidor"
#: mailu/ui/templates/domain/signup.html:18 #: mailu/ui/templates/domain/signup.html:18
msgid "" msgid ""
@ -539,131 +546,136 @@ msgid ""
"cache\n" "cache\n"
" expires." " expires."
msgstr "" msgstr ""
"Si no sabeu configurar un registre <code>MX</code> a la zona DNS,\n"
"contacteu el vostre proveïdor o administrador de DNS. Per favor, espereu \n"
"uns quants minuts despres d'ajustar el registre <code>MX</code> perquè la "
"caixet \n"
"del servidor local expire."
#: mailu/ui/templates/fetch/create.html:4 #: mailu/ui/templates/fetch/create.html:4
msgid "Add a fetched account" msgid "Add a fetched account"
msgstr "" msgstr "Afegiu un compte (fetched)"
#: mailu/ui/templates/fetch/edit.html:4 #: mailu/ui/templates/fetch/edit.html:4
msgid "Update a fetched account" msgid "Update a fetched account"
msgstr "" msgstr "Actualitzeu un compte (fetched)"
#: mailu/ui/templates/fetch/list.html:12 #: mailu/ui/templates/fetch/list.html:12
msgid "Add an account" msgid "Add an account"
msgstr "" msgstr "Afegiu un compte"
#: mailu/ui/templates/fetch/list.html:19 #: mailu/ui/templates/fetch/list.html:19
msgid "Endpoint" msgid "Endpoint"
msgstr "" msgstr "Endpoint"
#: mailu/ui/templates/fetch/list.html:21 #: mailu/ui/templates/fetch/list.html:21
msgid "Keep emails" msgid "Keep emails"
msgstr "" msgstr "Mantingueu els correus"
#: mailu/ui/templates/fetch/list.html:22 #: mailu/ui/templates/fetch/list.html:22
msgid "Last check" msgid "Last check"
msgstr "" msgstr "Última comprovació"
#: mailu/ui/templates/fetch/list.html:35 #: mailu/ui/templates/fetch/list.html:35
msgid "yes" msgid "yes"
msgstr "" msgstr ""
#: mailu/ui/templates/fetch/list.html:35 #: mailu/ui/templates/fetch/list.html:35
msgid "no" msgid "no"
msgstr "" msgstr "no"
#: mailu/ui/templates/manager/create.html:4 #: mailu/ui/templates/manager/create.html:4
msgid "Add a manager" msgid "Add a manager"
msgstr "" msgstr "Afegiu un gestor"
#: mailu/ui/templates/manager/list.html:4 #: mailu/ui/templates/manager/list.html:4
msgid "Manager list" msgid "Manager list"
msgstr "" msgstr "Llista de gestors"
#: mailu/ui/templates/manager/list.html:12 #: mailu/ui/templates/manager/list.html:12
msgid "Add manager" msgid "Add manager"
msgstr "" msgstr "Afegiu un gestor"
#: mailu/ui/templates/relay/create.html:4 #: mailu/ui/templates/relay/create.html:4
msgid "New relay domain" msgid "New relay domain"
msgstr "" msgstr "Nou domini traspassat (relayed)"
#: mailu/ui/templates/relay/edit.html:4 #: mailu/ui/templates/relay/edit.html:4
msgid "Edit relayd domain" msgid "Edit relayd domain"
msgstr "" msgstr "Editeu domini traspassat (relayed)"
#: mailu/ui/templates/relay/list.html:4 #: mailu/ui/templates/relay/list.html:4
msgid "Relayed domain list" msgid "Relayed domain list"
msgstr "" msgstr "Llista de dominis traspassats (relayed)"
#: mailu/ui/templates/relay/list.html:9 #: mailu/ui/templates/relay/list.html:9
msgid "New relayed domain" msgid "New relayed domain"
msgstr "" msgstr "Nou domini traspassat (relayed)"
#: mailu/ui/templates/token/create.html:4 #: mailu/ui/templates/token/create.html:4
msgid "Create an authentication token" msgid "Create an authentication token"
msgstr "" msgstr "Creeu un token d'autenticació"
#: mailu/ui/templates/token/list.html:12 #: mailu/ui/templates/token/list.html:12
msgid "New token" msgid "New token"
msgstr "" msgstr "Nou token"
#: mailu/ui/templates/user/create.html:4 #: mailu/ui/templates/user/create.html:4
msgid "New user" msgid "New user"
msgstr "" msgstr "Nou usuari"
#: mailu/ui/templates/user/create.html:15 #: mailu/ui/templates/user/create.html:15
msgid "General" msgid "General"
msgstr "" msgstr "General"
#: mailu/ui/templates/user/create.html:22 #: mailu/ui/templates/user/create.html:22
msgid "Features and quotas" msgid "Features and quotas"
msgstr "" msgstr "Funcions i espai"
#: mailu/ui/templates/user/edit.html:4 #: mailu/ui/templates/user/edit.html:4
msgid "Edit user" msgid "Edit user"
msgstr "" msgstr "Edita usuari"
#: mailu/ui/templates/user/forward.html:4 #: mailu/ui/templates/user/forward.html:4
msgid "Forward emails" msgid "Forward emails"
msgstr "" msgstr "Reenvia correus"
#: mailu/ui/templates/user/list.html:4 #: mailu/ui/templates/user/list.html:4
msgid "User list" msgid "User list"
msgstr "" msgstr "Llista d'usuaris"
#: mailu/ui/templates/user/list.html:12 #: mailu/ui/templates/user/list.html:12
msgid "Add user" msgid "Add user"
msgstr "" msgstr "Afegiu usuari"
#: mailu/ui/templates/user/list.html:19 mailu/ui/templates/user/settings.html:4 #: mailu/ui/templates/user/list.html:19 mailu/ui/templates/user/settings.html:4
msgid "User settings" msgid "User settings"
msgstr "" msgstr "Ajustos d'usuari"
#: mailu/ui/templates/user/list.html:21 #: mailu/ui/templates/user/list.html:21
msgid "Features" msgid "Features"
msgstr "" msgstr "Funcions"
#: mailu/ui/templates/user/password.html:4 #: mailu/ui/templates/user/password.html:4
msgid "Password update" msgid "Password update"
msgstr "" msgstr "Canvieu la contrasenya"
#: mailu/ui/templates/user/reply.html:4 #: mailu/ui/templates/user/reply.html:4
msgid "Automatic reply" msgid "Automatic reply"
msgstr "" msgstr "Resposta automàtica"
#: mailu/ui/templates/user/settings.html:22 #: mailu/ui/templates/user/settings.html:22
msgid "Auto-forward" msgid "Auto-forward"
msgstr "" msgstr "Auto-reenviament"
#: mailu/ui/templates/user/signup_domain.html:8 #: mailu/ui/templates/user/signup_domain.html:8
msgid "pick a domain for the new account" msgid "pick a domain for the new account"
msgstr "" msgstr "tria un domini per al compte nou"
#: mailu/ui/templates/user/signup_domain.html:14 #: mailu/ui/templates/user/signup_domain.html:14
msgid "Domain" msgid "Domain"
msgstr "" msgstr "Domini"
#: mailu/ui/templates/user/signup_domain.html:15 #: mailu/ui/templates/user/signup_domain.html:15
msgid "Available slots" msgid "Available slots"
msgstr "" msgstr "Ranures lliures"

@ -8,14 +8,16 @@ msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2018-04-22 12:10+0200\n" "POT-Creation-Date: 2018-04-22 12:10+0200\n"
"PO-Revision-Date: 2016-10-02 15:02+0200\n" "PO-Revision-Date: 2020-03-11 23:03+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: Jae Beojkkoch <jae@jae.moe>\n"
"Language-Team: English <https://translate.tedomum.net/projects/mailu/admin/"
"en/>\n"
"Language: en\n" "Language: en\n"
"Language-Team: en <LL@li.org>\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 3.11.2\n"
"Generated-By: Babel 2.5.3\n" "Generated-By: Babel 2.5.3\n"
#: mailu/ui/forms.py:32 #: mailu/ui/forms.py:32
@ -24,7 +26,7 @@ msgstr ""
#: mailu/ui/forms.py:36 #: mailu/ui/forms.py:36
msgid "Confirm" msgid "Confirm"
msgstr "" msgstr "Confirm"
#: mailu/ui/forms.py:40 mailu/ui/forms.py:77 #: mailu/ui/forms.py:40 mailu/ui/forms.py:77
msgid "E-mail" msgid "E-mail"
@ -684,4 +686,3 @@ msgstr ""
#~ msgid "General settings" #~ msgid "General settings"
#~ msgstr "" #~ msgstr ""

@ -1,11 +1,16 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Mailu\n"
"PO-Revision-Date: 2020-03-11 23:03+0000\n"
"Last-Translator: Jaume Barber <jaumebarber@gmail.com>\n"
"Language-Team: Spanish <https://translate.tedomum.net/projects/mailu/admin/"
"es/>\n"
"Language: es\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Generator: POEditor.com\n" "Plural-Forms: nplurals=2; plural=n != 1;\n"
"Project-Id-Version: Mailu\n" "X-Generator: Weblate 3.11.2\n"
"Language: es\n"
#: mailu/ui/forms.py:32 #: mailu/ui/forms.py:32
msgid "Invalid email address." msgid "Invalid email address."
@ -17,7 +22,7 @@ msgstr "Confirmar"
#: mailu/ui/forms.py:40 mailu/ui/forms.py:77 #: mailu/ui/forms.py:40 mailu/ui/forms.py:77
msgid "E-mail" msgid "E-mail"
msgstr "Dirección de Correo" msgstr "Dirección de correo"
#: mailu/ui/forms.py:41 mailu/ui/forms.py:78 mailu/ui/forms.py:90 #: 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/forms.py:109 mailu/ui/forms.py:162
@ -34,7 +39,7 @@ msgstr "Entrar"
#: mailu/ui/templates/domain/details.html:27 #: mailu/ui/templates/domain/details.html:27
#: mailu/ui/templates/domain/list.html:18 mailu/ui/templates/relay/list.html:17 #: mailu/ui/templates/domain/list.html:18 mailu/ui/templates/relay/list.html:17
msgid "Domain name" msgid "Domain name"
msgstr "Nmbre de dominio" msgstr "Nombre de dominio"
#: mailu/ui/forms.py:47 #: mailu/ui/forms.py:47
msgid "Maximum user count" msgid "Maximum user count"
@ -42,7 +47,7 @@ msgstr "Máximo número de usuarios"
#: mailu/ui/forms.py:48 #: mailu/ui/forms.py:48
msgid "Maximum alias count" msgid "Maximum alias count"
msgstr "Máximo número de aliases" msgstr "Máximo número de alias"
#: mailu/ui/forms.py:51 mailu/ui/forms.py:72 mailu/ui/forms.py:83 #: 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/forms.py:128 mailu/ui/forms.py:140
@ -64,7 +69,7 @@ msgstr "Confirmar contraseña"
#: mailu/ui/forms.py:80 mailu/ui/templates/user/list.html:22 #: mailu/ui/forms.py:80 mailu/ui/templates/user/list.html:22
#: mailu/ui/templates/user/signup_domain.html:16 #: mailu/ui/templates/user/signup_domain.html:16
msgid "Quota" msgid "Quota"
msgstr "Cuota" msgstr "Espacio"
#: mailu/ui/forms.py:81 #: mailu/ui/forms.py:81
msgid "Allow IMAP access" msgid "Allow IMAP access"
@ -137,7 +142,7 @@ msgstr "Usar sintaxis SQL (p.ej. para abarcar todos los alias)"
#: mailu/ui/forms.py:145 #: mailu/ui/forms.py:145
msgid "Admin email" msgid "Admin email"
msgstr "Correo-e del administrador" msgstr "Correo del administrador"
#: mailu/ui/forms.py:146 mailu/ui/forms.py:151 mailu/ui/forms.py:164 #: mailu/ui/forms.py:146 mailu/ui/forms.py:151 mailu/ui/forms.py:164
msgid "Submit" msgid "Submit"
@ -145,7 +150,7 @@ msgstr "Enviar"
#: mailu/ui/forms.py:150 #: mailu/ui/forms.py:150
msgid "Manager email" msgid "Manager email"
msgstr "Gestor de correo" msgstr "Correo del gestor"
#: mailu/ui/forms.py:155 #: mailu/ui/forms.py:155
msgid "Protocol" msgid "Protocol"
@ -175,7 +180,7 @@ msgstr "Confirmar acción"
#: mailu/ui/templates/confirm.html:13 #: mailu/ui/templates/confirm.html:13
msgid "You are about to %(action)s. Please confirm your action." msgid "You are about to %(action)s. Please confirm your action."
msgstr "Está a punto de %(action)s. Por favor, confirme su acción. " msgstr "Está a punto de %(action)s. Por favor, confirme su acción."
#: mailu/ui/templates/docker-error.html:4 #: mailu/ui/templates/docker-error.html:4
msgid "Docker error" msgid "Docker error"
@ -264,7 +269,7 @@ msgstr "Ayuda"
#: mailu/ui/templates/working.html:4 #: mailu/ui/templates/working.html:4
msgid "We are still working on this feature!" msgid "We are still working on this feature!"
msgstr "Aún trabajamos en esta característica!" msgstr "Aún estamos trabajando en esta funcionalidad!"
#: mailu/ui/templates/admin/create.html:4 #: mailu/ui/templates/admin/create.html:4
msgid "Add a global administrator" msgid "Add a global administrator"
@ -276,7 +281,7 @@ msgstr "Administradores globales"
#: mailu/ui/templates/admin/list.html:9 #: mailu/ui/templates/admin/list.html:9
msgid "Add administrator" msgid "Add administrator"
msgstr "Añadr administrador" msgstr "Añadir administrador"
#: mailu/ui/templates/admin/list.html:16 mailu/ui/templates/alias/list.html:18 #: mailu/ui/templates/admin/list.html:16 mailu/ui/templates/alias/list.html:18
#: mailu/ui/templates/alternative/list.html:18 #: mailu/ui/templates/alternative/list.html:18
@ -424,7 +429,7 @@ msgstr "Punto final"
#: mailu/ui/templates/fetch/list.html:22 #: mailu/ui/templates/fetch/list.html:22
msgid "Last check" msgid "Last check"
msgstr "Último checkeo" msgstr "Última comprobación"
#: mailu/ui/templates/manager/create.html:4 #: mailu/ui/templates/manager/create.html:4
msgid "Add a manager" msgid "Add a manager"
@ -516,7 +521,7 @@ msgstr "Mantener los correos"
#: mailu/ui/templates/fetch/list.html:35 #: mailu/ui/templates/fetch/list.html:35
msgid "yes" msgid "yes"
msgstr "si" msgstr "sí"
#: mailu/ui/templates/fetch/list.html:35 #: mailu/ui/templates/fetch/list.html:35
msgid "no" msgid "no"
@ -529,7 +534,7 @@ msgstr "Nombre alternativo"
#. I assume relayed domain means the server is a relay server (hoy receive it from another machine), and relay domain means hoy silla send it todo another machine. Is it right, or opossite? #. I assume relayed domain means the server is a relay server (hoy receive it from another machine), and relay domain means hoy silla send it todo another machine. Is it right, or opossite?
#: mailu/ui/forms.py:70 #: mailu/ui/forms.py:70
msgid "Relayed domain name" msgid "Relayed domain name"
msgstr "Nombre de.dominio a recepcionar" msgstr "Nombre de dominio a recepcionar"
#: mailu/ui/forms.py:71 mailu/ui/templates/relay/list.html:18 #: mailu/ui/forms.py:71 mailu/ui/templates/relay/list.html:18
msgid "Remote host" msgid "Remote host"
@ -577,7 +582,7 @@ msgstr "Nuevo dominio externo (relayed)"
#: mailu/ui/forms.py:125 #: mailu/ui/forms.py:125
msgid "Your token (write it down, as it will never be displayed again)" msgid "Your token (write it down, as it will never be displayed again)"
msgstr "Sus llaves (token) (anótelas, ya que no se mostrarán nunca más)." msgstr "Su token (anótelo, ya que no se mostrará nunca más)"
#: mailu/ui/forms.py:130 mailu/ui/templates/token/list.html:20 #: mailu/ui/forms.py:130 mailu/ui/templates/token/list.html:20
msgid "Authorized IP" msgid "Authorized IP"
@ -585,7 +590,7 @@ msgstr "IP autorizada"
#: mailu/ui/templates/sidebar.html:31 mailu/ui/templates/token/list.html:4 #: mailu/ui/templates/sidebar.html:31 mailu/ui/templates/token/list.html:4
msgid "Authentication tokens" msgid "Authentication tokens"
msgstr "Tokens (llaves) autorizados" msgstr "Tokens de autenticación"
#: mailu/ui/templates/sidebar.html:72 #: mailu/ui/templates/sidebar.html:72
msgid "Go to" msgid "Go to"
@ -593,15 +598,15 @@ msgstr "Ir a"
#: mailu/ui/templates/sidebar.html:76 #: mailu/ui/templates/sidebar.html:76
msgid "Webmail" msgid "Webmail"
msgstr "Webmail" msgstr "Correo web"
#: mailu/ui/templates/sidebar.html:87 #: mailu/ui/templates/sidebar.html:87
msgid "Website" msgid "Website"
msgstr "Web" msgstr "Correo web"
#: mailu/ui/templates/token/create.html:4 #: mailu/ui/templates/token/create.html:4
msgid "Create an authentication token" msgid "Create an authentication token"
msgstr "Crear un token (llave) de autenticación." msgstr "Crear un token de autenticación"
#: mailu/ui/templates/token/list.html:12 #: mailu/ui/templates/token/list.html:12
msgid "New token" msgid "New token"
@ -700,4 +705,3 @@ msgstr "Dominio"
#: mailu/ui/templates/user/signup_domain.html:15 #: mailu/ui/templates/user/signup_domain.html:15
msgid "Available slots" msgid "Available slots"
msgstr "Slots disponibles" msgstr "Slots disponibles"

@ -1,8 +1,8 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Mailu\n" "Project-Id-Version: Mailu\n"
"PO-Revision-Date: 2019-07-22 06:23+0000\n" "PO-Revision-Date: 2020-03-11 23:03+0000\n"
"Last-Translator: kaiyou <pierre@jaury.eu>\n" "Last-Translator: Jaume Barber <jaumebarber@gmail.com>\n"
"Language-Team: Italian <https://translate.tedomum.net/projects/mailu/admin/" "Language-Team: Italian <https://translate.tedomum.net/projects/mailu/admin/"
"it/>\n" "it/>\n"
"Language: it\n" "Language: it\n"
@ -10,7 +10,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n" "Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 3.3\n" "X-Generator: Weblate 3.11.2\n"
#: mailu/ui/forms.py:32 #: mailu/ui/forms.py:32
msgid "Invalid email address." msgid "Invalid email address."
@ -43,11 +43,11 @@ msgstr "Nome dominio"
#: mailu/ui/forms.py:47 #: mailu/ui/forms.py:47
msgid "Maximum user count" msgid "Maximum user count"
msgstr "" msgstr "Numero massimo utenti"
#: mailu/ui/forms.py:48 #: mailu/ui/forms.py:48
msgid "Maximum alias count" msgid "Maximum alias count"
msgstr "" msgstr "Numero massimo alias"
#: mailu/ui/forms.py:51 mailu/ui/forms.py:72 mailu/ui/forms.py:83 #: 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/forms.py:128 mailu/ui/forms.py:140
@ -55,7 +55,7 @@ msgstr ""
#: mailu/ui/templates/relay/list.html:19 mailu/ui/templates/token/list.html:19 #: mailu/ui/templates/relay/list.html:19 mailu/ui/templates/token/list.html:19
#: mailu/ui/templates/user/list.html:23 #: mailu/ui/templates/user/list.html:23
msgid "Comment" msgid "Comment"
msgstr "" msgstr "Commento"
#: mailu/ui/forms.py:52 mailu/ui/forms.py:61 mailu/ui/forms.py:66 #: 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 #: mailu/ui/forms.py:73 mailu/ui/forms.py:132 mailu/ui/forms.py:141
@ -101,7 +101,7 @@ msgstr "Salva impostazioni"
#: mailu/ui/forms.py:110 #: mailu/ui/forms.py:110
msgid "Password check" msgid "Password check"
msgstr "" msgstr "Verifica la password"
#: mailu/ui/forms.py:111 mailu/ui/templates/sidebar.html:16 #: mailu/ui/forms.py:111 mailu/ui/templates/sidebar.html:16
msgid "Update password" msgid "Update password"
@ -172,7 +172,7 @@ msgstr "Abilita TLS"
#: mailu/ui/forms.py:161 mailu/ui/templates/client.html:28 #: mailu/ui/forms.py:161 mailu/ui/templates/client.html:28
#: mailu/ui/templates/client.html:55 mailu/ui/templates/fetch/list.html:20 #: mailu/ui/templates/client.html:55 mailu/ui/templates/fetch/list.html:20
msgid "Username" msgid "Username"
msgstr "Username" msgstr "Nome utente"
#: mailu/ui/templates/confirm.html:4 #: mailu/ui/templates/confirm.html:4
msgid "Confirm action" msgid "Confirm action"
@ -188,7 +188,7 @@ msgstr "Errore Docker"
#: mailu/ui/templates/docker-error.html:12 #: mailu/ui/templates/docker-error.html:12
msgid "An error occurred while talking to the Docker server." msgid "An error occurred while talking to the Docker server."
msgstr "" msgstr "C'è stato un errore nel tentativo di connessione con il Docker server."
#: mailu/admin/templates/login.html:6 #: mailu/admin/templates/login.html:6
msgid "Your account" msgid "Your account"
@ -196,15 +196,15 @@ msgstr "Il tuo account"
#: mailu/ui/templates/login.html:8 #: mailu/ui/templates/login.html:8
msgid "to access the administration tools" msgid "to access the administration tools"
msgstr "" msgstr "per accedere le impostazioni d'admin"
#: mailu/ui/templates/services.html:4 mailu/ui/templates/sidebar.html:39 #: mailu/ui/templates/services.html:4 mailu/ui/templates/sidebar.html:39
msgid "Services status" msgid "Services status"
msgstr "" msgstr "Status dei servizi"
#: mailu/ui/templates/services.html:10 #: mailu/ui/templates/services.html:10
msgid "Service" msgid "Service"
msgstr "" msgstr "Servizio"
#: mailu/ui/templates/fetch/list.html:23 mailu/ui/templates/services.html:11 #: mailu/ui/templates/fetch/list.html:23 mailu/ui/templates/services.html:11
msgid "Status" msgid "Status"
@ -245,7 +245,7 @@ msgstr "Auto-risponditore"
#: mailu/ui/templates/fetch/list.html:4 mailu/ui/templates/sidebar.html:26 #: mailu/ui/templates/fetch/list.html:4 mailu/ui/templates/sidebar.html:26
#: mailu/ui/templates/user/list.html:36 #: mailu/ui/templates/user/list.html:36
msgid "Fetched accounts" msgid "Fetched accounts"
msgstr "" msgstr "Conti ricuperati"
#: mailu/ui/templates/sidebar.html:105 #: mailu/ui/templates/sidebar.html:105
msgid "Sign out" msgid "Sign out"
@ -357,23 +357,23 @@ msgstr "Rigenera chiavi"
#: mailu/ui/templates/domain/details.html:31 #: mailu/ui/templates/domain/details.html:31
msgid "DNS MX entry" msgid "DNS MX entry"
msgstr "" msgstr "Entrate DNS MX"
#: mailu/ui/templates/domain/details.html:35 #: mailu/ui/templates/domain/details.html:35
msgid "DNS SPF entries" msgid "DNS SPF entries"
msgstr "" msgstr "Entrate DNS SPF"
#: mailu/ui/templates/domain/details.html:42 #: mailu/ui/templates/domain/details.html:42
msgid "DKIM public key" msgid "DKIM public key"
msgstr "" msgstr "Chiave pubblica DKIM"
#: mailu/ui/templates/domain/details.html:46 #: mailu/ui/templates/domain/details.html:46
msgid "DNS DKIM entry" msgid "DNS DKIM entry"
msgstr "" msgstr "Entrata DNS DKIM"
#: mailu/ui/templates/domain/details.html:50 #: mailu/ui/templates/domain/details.html:50
msgid "DNS DMARC entry" msgid "DNS DMARC entry"
msgstr "" msgstr "Entrata DNS DMARC"
#: mailu/ui/templates/domain/edit.html:4 #: mailu/ui/templates/domain/edit.html:4
msgid "Edit domain" msgid "Edit domain"
@ -413,11 +413,11 @@ msgstr "Manager"
#: mailu/ui/templates/fetch/create.html:4 #: mailu/ui/templates/fetch/create.html:4
msgid "Add a fetched account" msgid "Add a fetched account"
msgstr "" msgstr "Aggiungere un conto ricuperato"
#: mailu/ui/templates/fetch/edit.html:4 #: mailu/ui/templates/fetch/edit.html:4
msgid "Update a fetched account" msgid "Update a fetched account"
msgstr "" msgstr "Aggiornare un conto ricuperato"
#: mailu/ui/templates/fetch/list.html:12 #: mailu/ui/templates/fetch/list.html:12
msgid "Add an account" msgid "Add an account"
@ -425,7 +425,7 @@ msgstr "Aggiungi un account"
#: mailu/ui/templates/fetch/list.html:19 #: mailu/ui/templates/fetch/list.html:19
msgid "Endpoint" msgid "Endpoint"
msgstr "" msgstr "Endpoint"
#: mailu/ui/templates/fetch/list.html:22 #: mailu/ui/templates/fetch/list.html:22
msgid "Last check" msgid "Last check"
@ -437,7 +437,7 @@ msgstr "Aggiungi un manager"
#: mailu/ui/templates/manager/list.html:4 #: mailu/ui/templates/manager/list.html:4
msgid "Manager list" msgid "Manager list"
msgstr "" msgstr "Elenco di Manager"
#: mailu/ui/templates/manager/list.html:12 #: mailu/ui/templates/manager/list.html:12
msgid "Add manager" msgid "Add manager"
@ -445,7 +445,7 @@ msgstr "Aggiungi manager"
#: mailu/ui/forms.py:168 #: mailu/ui/forms.py:168
msgid "Announcement subject" msgid "Announcement subject"
msgstr "" msgstr "Oggetto dell'avviso"
#: mailu/ui/forms.py:170 #: mailu/ui/forms.py:170
msgid "Announcement body" msgid "Announcement body"
@ -505,7 +505,7 @@ msgstr "Risposta automatica"
#: mailu/ui/forms.py:49 #: mailu/ui/forms.py:49
msgid "Maximum user quota" msgid "Maximum user quota"
msgstr "" msgstr "Spazio massimo per utente"
#: mailu/ui/forms.py:101 #: mailu/ui/forms.py:101
msgid "Keep a copy of the emails" msgid "Keep a copy of the emails"
@ -533,7 +533,7 @@ msgstr "Nome alternativo"
#: mailu/ui/forms.py:70 #: mailu/ui/forms.py:70
msgid "Relayed domain name" msgid "Relayed domain name"
msgstr "" msgstr "Nome di dominio affidato"
#: mailu/ui/forms.py:71 mailu/ui/templates/relay/list.html:18 #: mailu/ui/forms.py:71 mailu/ui/templates/relay/list.html:18
msgid "Remote host" msgid "Remote host"
@ -541,15 +541,15 @@ msgstr "Host remoto"
#: mailu/ui/templates/sidebar.html:54 #: mailu/ui/templates/sidebar.html:54
msgid "Relayed domains" msgid "Relayed domains"
msgstr "" msgstr "Domini affidati"
#: mailu/ui/templates/alternative/create.html:4 #: mailu/ui/templates/alternative/create.html:4
msgid "Create alternative domain" msgid "Create alternative domain"
msgstr "" msgstr "Creare un dominio alternativo"
#: mailu/ui/templates/alternative/list.html:4 #: mailu/ui/templates/alternative/list.html:4
msgid "Alternative domain list" msgid "Alternative domain list"
msgstr "" msgstr "Elenco di domini alternativi"
#: mailu/ui/templates/alternative/list.html:12 #: mailu/ui/templates/alternative/list.html:12
msgid "Add alternative" msgid "Add alternative"
@ -565,23 +565,23 @@ msgstr "Alternative"
#: mailu/ui/templates/relay/create.html:4 #: mailu/ui/templates/relay/create.html:4
msgid "New relay domain" msgid "New relay domain"
msgstr "" msgstr "Nuovo dominio affidato"
#: mailu/ui/templates/relay/edit.html:4 #: mailu/ui/templates/relay/edit.html:4
msgid "Edit relayd domain" msgid "Edit relayd domain"
msgstr "" msgstr "Editare dominio affidato"
#: mailu/ui/templates/relay/list.html:4 #: mailu/ui/templates/relay/list.html:4
msgid "Relayed domain list" msgid "Relayed domain list"
msgstr "" msgstr "Elenco di domini affidati"
#: mailu/ui/templates/relay/list.html:9 #: mailu/ui/templates/relay/list.html:9
msgid "New relayed domain" msgid "New relayed domain"
msgstr "" msgstr "Nuovo dominio affidato"
#: mailu/ui/forms.py:125 #: mailu/ui/forms.py:125
msgid "Your token (write it down, as it will never be displayed again)" msgid "Your token (write it down, as it will never be displayed again)"
msgstr "" msgstr "Il suo token (dovrà annotarlo, dato che non verrà più mostrato)"
#: mailu/ui/forms.py:130 mailu/ui/templates/token/list.html:20 #: mailu/ui/forms.py:130 mailu/ui/templates/token/list.html:20
msgid "Authorized IP" msgid "Authorized IP"
@ -633,58 +633,61 @@ msgstr "Tolleranza filtro spam"
#: mailu/ui/forms.py:50 #: mailu/ui/forms.py:50
msgid "Enable sign-up" msgid "Enable sign-up"
msgstr "" msgstr "Avviare l'iscrizione"
#: mailu/ui/forms.py:57 #: mailu/ui/forms.py:57
msgid "Initial admin" msgid "Initial admin"
msgstr "" msgstr "Admin iniziale"
#: mailu/ui/forms.py:58 #: mailu/ui/forms.py:58
msgid "Admin password" msgid "Admin password"
msgstr "" msgstr "Admin password"
#: mailu/ui/forms.py:84 #: mailu/ui/forms.py:84
msgid "Enabled" msgid "Enabled"
msgstr "" msgstr "Attivo"
#: mailu/ui/forms.py:89 #: mailu/ui/forms.py:89
msgid "Email address" msgid "Email address"
msgstr "" msgstr "Indirizzo email"
#: mailu/ui/forms.py:93 mailu/ui/templates/sidebar.html:117 #: mailu/ui/forms.py:93 mailu/ui/templates/sidebar.html:117
#: mailu/ui/templates/user/signup.html:4 #: mailu/ui/templates/user/signup.html:4
#: mailu/ui/templates/user/signup_domain.html:4 #: mailu/ui/templates/user/signup_domain.html:4
msgid "Sign up" msgid "Sign up"
msgstr "" msgstr "Iscriversi"
#: mailu/ui/forms.py:119 #: mailu/ui/forms.py:119
msgid "End of vacation" msgid "End of vacation"
msgstr "" msgstr "Rientro delle vacanze"
#: mailu/ui/templates/client.html:4 mailu/ui/templates/sidebar.html:82 #: mailu/ui/templates/client.html:4 mailu/ui/templates/sidebar.html:82
msgid "Client setup" msgid "Client setup"
msgstr "" msgstr "Impostazioni del cliente"
#: mailu/ui/templates/client.html:16 mailu/ui/templates/client.html:43 #: mailu/ui/templates/client.html:16 mailu/ui/templates/client.html:43
msgid "Mail protocol" msgid "Mail protocol"
msgstr "" msgstr "Protocolo mail"
#: mailu/ui/templates/client.html:24 mailu/ui/templates/client.html:51 #: mailu/ui/templates/client.html:24 mailu/ui/templates/client.html:51
msgid "Server name" msgid "Server name"
msgstr "" msgstr "Nome del server"
#: mailu/ui/templates/domain/signup.html:4 mailu/ui/templates/sidebar.html:98 #: mailu/ui/templates/domain/signup.html:4 mailu/ui/templates/sidebar.html:98
msgid "Register a domain" msgid "Register a domain"
msgstr "" msgstr "Registrare un dominio"
#: mailu/ui/templates/domain/details.html:17 #: mailu/ui/templates/domain/details.html:17
msgid "Generate keys" msgid "Generate keys"
msgstr "" msgstr "Generare chiavi"
#: mailu/ui/templates/domain/signup.html:13 #: mailu/ui/templates/domain/signup.html:13
msgid "In order to register a new domain, you must first setup the\n" msgid "In order to register a new domain, you must first setup the\n"
" domain zone so that the domain <code>MX</code> points to this server" " domain zone so that the domain <code>MX</code> points to this server"
msgstr "" msgstr ""
"Per registrare un nuovo dominio, dovrà aggiustare prima la \n"
"domain zone affinché il vostro dominio <code>MX</code> punti contro il "
"server"
#: mailu/ui/templates/domain/signup.html:18 #: mailu/ui/templates/domain/signup.html:18
msgid "If you do not know how to setup an <code>MX</code> record for your DNS zone,\n" msgid "If you do not know how to setup an <code>MX</code> record for your DNS zone,\n"
@ -692,15 +695,22 @@ msgid "If you do not know how to setup an <code>MX</code> record for your DNS zo
" couple minutes after the <code>MX</code> is set so the local server cache\n" " couple minutes after the <code>MX</code> is set so the local server cache\n"
" expires." " expires."
msgstr "" msgstr ""
"Se non sa come aggiungere un registro <code>MX</code> alla vostra zona DNS, "
"\n"
"dovrà contattare il suo provider o amministratore DNS. Prego, attenda "
"qualche\n"
"minuto tra l'impostazione del registro <code>MX</code> finché la cache "
"locale \n"
"del server scaderà."
#: mailu/ui/templates/user/signup_domain.html:8 #: mailu/ui/templates/user/signup_domain.html:8
msgid "pick a domain for the new account" msgid "pick a domain for the new account"
msgstr "" msgstr "scelga un dominio per il nuovo conto"
#: mailu/ui/templates/user/signup_domain.html:14 #: mailu/ui/templates/user/signup_domain.html:14
msgid "Domain" msgid "Domain"
msgstr "" msgstr "Dominio"
#: mailu/ui/templates/user/signup_domain.html:15 #: mailu/ui/templates/user/signup_domain.html:15
msgid "Available slots" msgid "Available slots"
msgstr "" msgstr "Slot disponibili"

@ -1,11 +1,17 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Mailu\n"
"PO-Revision-Date: 2020-02-17 20:23+0000\n"
"Last-Translator: NeroPcStation <dareknowacki2001@gmail.com>\n"
"Language-Team: Polish <https://translate.tedomum.net/projects/mailu/admin/pl/"
">\n"
"Language: pl\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Generator: POEditor.com\n" "Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
"Project-Id-Version: Mailu\n" "|| n%100>=20) ? 1 : 2;\n"
"Language: pl\n" "X-Generator: Weblate 3.3\n"
#: mailu/ui/forms.py:32 #: mailu/ui/forms.py:32
msgid "Invalid email address." msgid "Invalid email address."
@ -65,7 +71,7 @@ msgstr "Potwierdź hasło"
#: mailu/ui/forms.py:80 mailu/ui/templates/user/list.html:22 #: mailu/ui/forms.py:80 mailu/ui/templates/user/list.html:22
#: mailu/ui/templates/user/signup_domain.html:16 #: mailu/ui/templates/user/signup_domain.html:16
msgid "Quota" msgid "Quota"
msgstr "" msgstr "Maksymalna przestrzeń na dysku"
#: mailu/ui/forms.py:81 #: mailu/ui/forms.py:81
msgid "Allow IMAP access" msgid "Allow IMAP access"
@ -101,7 +107,7 @@ msgstr ""
#: mailu/ui/forms.py:111 mailu/ui/templates/sidebar.html:16 #: mailu/ui/forms.py:111 mailu/ui/templates/sidebar.html:16
msgid "Update password" msgid "Update password"
msgstr "Zmień hasło" msgstr "Zaktualizuj hasło"
#: mailu/ui/forms.py:100 #: mailu/ui/forms.py:100
msgid "Enable forwarding" msgid "Enable forwarding"
@ -146,7 +152,7 @@ msgstr "Prześlij"
#: mailu/ui/forms.py:150 #: mailu/ui/forms.py:150
msgid "Manager email" msgid "Manager email"
msgstr "" msgstr "E-mail menedżera"
#: mailu/ui/forms.py:155 #: mailu/ui/forms.py:155
msgid "Protocol" msgid "Protocol"
@ -192,7 +198,7 @@ msgstr "Twoje konto"
#: mailu/ui/templates/login.html:8 #: mailu/ui/templates/login.html:8
msgid "to access the administration tools" msgid "to access the administration tools"
msgstr "" msgstr "aby uzyskać dostęp do narzędzi administracyjnych"
#: mailu/ui/templates/services.html:4 mailu/ui/templates/sidebar.html:39 #: mailu/ui/templates/services.html:4 mailu/ui/templates/sidebar.html:39
msgid "Services status" msgid "Services status"
@ -212,7 +218,7 @@ msgstr "PID"
#: mailu/ui/templates/services.html:13 #: mailu/ui/templates/services.html:13
msgid "Image" msgid "Image"
msgstr "" msgstr "Obraz"
#: mailu/ui/templates/services.html:14 #: mailu/ui/templates/services.html:14
msgid "Started" msgid "Started"
@ -265,7 +271,7 @@ msgstr "Pomoc"
#: mailu/ui/templates/working.html:4 #: mailu/ui/templates/working.html:4
msgid "We are still working on this feature!" msgid "We are still working on this feature!"
msgstr "" msgstr "Nadal pracujemy nad tą funkcją!"
#: mailu/ui/templates/admin/create.html:4 #: mailu/ui/templates/admin/create.html:4
msgid "Add a global administrator" msgid "Add a global administrator"
@ -405,7 +411,7 @@ msgstr "Aliasy"
#: mailu/ui/templates/domain/list.html:37 #: mailu/ui/templates/domain/list.html:37
msgid "Managers" msgid "Managers"
msgstr "" msgstr "Menedżerowie"
#: mailu/ui/templates/fetch/create.html:4 #: mailu/ui/templates/fetch/create.html:4
msgid "Add a fetched account" msgid "Add a fetched account"
@ -425,19 +431,19 @@ msgstr ""
#: mailu/ui/templates/fetch/list.html:22 #: mailu/ui/templates/fetch/list.html:22
msgid "Last check" msgid "Last check"
msgstr "" msgstr "Ostatnie sprawdzenie"
#: mailu/ui/templates/manager/create.html:4 #: mailu/ui/templates/manager/create.html:4
msgid "Add a manager" msgid "Add a manager"
msgstr "" msgstr "Dodaj menedżera"
#: mailu/ui/templates/manager/list.html:4 #: mailu/ui/templates/manager/list.html:4
msgid "Manager list" msgid "Manager list"
msgstr "" msgstr "Lista menedżerów"
#: mailu/ui/templates/manager/list.html:12 #: mailu/ui/templates/manager/list.html:12
msgid "Add manager" msgid "Add manager"
msgstr "" msgstr "Dodaj menedżera"
#: mailu/ui/forms.py:168 #: mailu/ui/forms.py:168
msgid "Announcement subject" msgid "Announcement subject"
@ -489,7 +495,7 @@ msgstr "Ustawienia użytkownika"
#: mailu/ui/templates/user/list.html:21 #: mailu/ui/templates/user/list.html:21
msgid "Features" msgid "Features"
msgstr "" msgstr "Funkcje"
#: mailu/ui/templates/user/password.html:4 #: mailu/ui/templates/user/password.html:4
msgid "Password update" msgid "Password update"
@ -501,7 +507,7 @@ msgstr "Automatyczna odpowiedź"
#: mailu/ui/forms.py:49 #: mailu/ui/forms.py:49
msgid "Maximum user quota" msgid "Maximum user quota"
msgstr "" msgstr "Maksymalny przydział użytkownika"
#: mailu/ui/forms.py:101 #: mailu/ui/forms.py:101
msgid "Keep a copy of the emails" msgid "Keep a copy of the emails"
@ -525,7 +531,7 @@ msgstr "Nie"
#: mailu/ui/forms.py:65 #: mailu/ui/forms.py:65
msgid "Alternative name" msgid "Alternative name"
msgstr "" msgstr "Alternatywna nazwa"
#: mailu/ui/forms.py:70 #: mailu/ui/forms.py:70
msgid "Relayed domain name" msgid "Relayed domain name"
@ -533,7 +539,7 @@ msgstr ""
#: mailu/ui/forms.py:71 mailu/ui/templates/relay/list.html:18 #: mailu/ui/forms.py:71 mailu/ui/templates/relay/list.html:18
msgid "Remote host" msgid "Remote host"
msgstr "" msgstr "Zdalny host"
#: mailu/ui/templates/sidebar.html:54 #: mailu/ui/templates/sidebar.html:54
msgid "Relayed domains" msgid "Relayed domains"
@ -541,19 +547,19 @@ msgstr ""
#: mailu/ui/templates/alternative/create.html:4 #: mailu/ui/templates/alternative/create.html:4
msgid "Create alternative domain" msgid "Create alternative domain"
msgstr "" msgstr "Utwórz alternatywną domenę"
#: mailu/ui/templates/alternative/list.html:4 #: mailu/ui/templates/alternative/list.html:4
msgid "Alternative domain list" msgid "Alternative domain list"
msgstr "" msgstr "Alternatywna lista domen"
#: mailu/ui/templates/alternative/list.html:12 #: mailu/ui/templates/alternative/list.html:12
msgid "Add alternative" msgid "Add alternative"
msgstr "" msgstr "Dodaj alternatywę"
#: mailu/ui/templates/alternative/list.html:19 #: mailu/ui/templates/alternative/list.html:19
msgid "Name" msgid "Name"
msgstr "" msgstr "Nazwa"
#: mailu/ui/templates/domain/list.html:39 #: mailu/ui/templates/domain/list.html:39
msgid "Alternatives" msgid "Alternatives"
@ -577,19 +583,19 @@ msgstr ""
#: mailu/ui/forms.py:125 #: mailu/ui/forms.py:125
msgid "Your token (write it down, as it will never be displayed again)" msgid "Your token (write it down, as it will never be displayed again)"
msgstr "" msgstr "Twój token (zapisz go, ponieważ nigdy więcej nie będzie wyświetlany)"
#: mailu/ui/forms.py:130 mailu/ui/templates/token/list.html:20 #: mailu/ui/forms.py:130 mailu/ui/templates/token/list.html:20
msgid "Authorized IP" msgid "Authorized IP"
msgstr "" msgstr "Autoryzowany adres IP"
#: mailu/ui/templates/sidebar.html:31 mailu/ui/templates/token/list.html:4 #: mailu/ui/templates/sidebar.html:31 mailu/ui/templates/token/list.html:4
msgid "Authentication tokens" msgid "Authentication tokens"
msgstr "" msgstr "Tokeny uwierzytelnienia"
#: mailu/ui/templates/sidebar.html:72 #: mailu/ui/templates/sidebar.html:72
msgid "Go to" msgid "Go to"
msgstr "" msgstr "Przejdź do"
#: mailu/ui/templates/sidebar.html:76 #: mailu/ui/templates/sidebar.html:76
msgid "Webmail" msgid "Webmail"
@ -601,7 +607,7 @@ msgstr "Strona internetowa"
#: mailu/ui/templates/token/create.html:4 #: mailu/ui/templates/token/create.html:4
msgid "Create an authentication token" msgid "Create an authentication token"
msgstr "" msgstr "Utwórz token uwierzytelniający"
#: mailu/ui/templates/token/list.html:12 #: mailu/ui/templates/token/list.html:12
msgid "New token" msgid "New token"
@ -625,7 +631,7 @@ msgstr "Filtr antyspamowy"
#: mailu/ui/forms.py:99 #: mailu/ui/forms.py:99
msgid "Spam filter tolerance" msgid "Spam filter tolerance"
msgstr "" msgstr "Tolerancja filtra spamu"
#: mailu/ui/forms.py:50 #: mailu/ui/forms.py:50
msgid "Enable sign-up" msgid "Enable sign-up"
@ -633,7 +639,7 @@ msgstr "Włącz rejestrację"
#: mailu/ui/forms.py:57 #: mailu/ui/forms.py:57
msgid "Initial admin" msgid "Initial admin"
msgstr "" msgstr "Początkowy administrator"
#: mailu/ui/forms.py:58 #: mailu/ui/forms.py:58
msgid "Admin password" msgid "Admin password"
@ -641,11 +647,11 @@ msgstr "hasło administratora"
#: mailu/ui/forms.py:84 #: mailu/ui/forms.py:84
msgid "Enabled" msgid "Enabled"
msgstr "" msgstr "Włączone"
#: mailu/ui/forms.py:89 #: mailu/ui/forms.py:89
msgid "Email address" msgid "Email address"
msgstr "" msgstr "Adres e-mail"
#: mailu/ui/forms.py:93 mailu/ui/templates/sidebar.html:117 #: mailu/ui/forms.py:93 mailu/ui/templates/sidebar.html:117
#: mailu/ui/templates/user/signup.html:4 #: mailu/ui/templates/user/signup.html:4
@ -655,11 +661,11 @@ msgstr ""
#: mailu/ui/forms.py:119 #: mailu/ui/forms.py:119
msgid "End of vacation" msgid "End of vacation"
msgstr "" msgstr "Koniec wakacji"
#: mailu/ui/templates/client.html:4 mailu/ui/templates/sidebar.html:82 #: mailu/ui/templates/client.html:4 mailu/ui/templates/sidebar.html:82
msgid "Client setup" msgid "Client setup"
msgstr "" msgstr "Konfiguracja klienta"
#: mailu/ui/templates/client.html:16 mailu/ui/templates/client.html:43 #: mailu/ui/templates/client.html:16 mailu/ui/templates/client.html:43
msgid "Mail protocol" msgid "Mail protocol"
@ -681,6 +687,8 @@ msgstr "Wygeneruj klucze"
msgid "In order to register a new domain, you must first setup the\n" msgid "In order to register a new domain, you must first setup the\n"
" domain zone so that the domain <code>MX</code> points to this server" " domain zone so that the domain <code>MX</code> points to this server"
msgstr "" msgstr ""
"Aby zarejestrować nową domenę, musisz najpierw skonfigurować strefę domeny, "
"aby domena <code> MX </code> wskazywała na ten serwer"
#: mailu/ui/templates/domain/signup.html:18 #: mailu/ui/templates/domain/signup.html:18
msgid "If you do not know how to setup an <code>MX</code> record for your DNS zone,\n" msgid "If you do not know how to setup an <code>MX</code> record for your DNS zone,\n"
@ -688,10 +696,15 @@ msgid "If you do not know how to setup an <code>MX</code> record for your DNS zo
" couple minutes after the <code>MX</code> is set so the local server cache\n" " couple minutes after the <code>MX</code> is set so the local server cache\n"
" expires." " expires."
msgstr "" msgstr ""
"Jeśli nie wiesz, jak skonfigurować rekord <code> MX </code> dla swojej "
"strefy DNS,\n"
"skontaktuj się z dostawcą DNS lub administratorem. Proszę również poczekać\n"
"kilka minut po ustawieniu <code> MX </code> , żeby pamięć podręczna serwera "
"lokalnego wygasła."
#: mailu/ui/templates/user/signup_domain.html:8 #: mailu/ui/templates/user/signup_domain.html:8
msgid "pick a domain for the new account" msgid "pick a domain for the new account"
msgstr "" msgstr "wybierz domenę dla nowego konta"
#: mailu/ui/templates/user/signup_domain.html:14 #: mailu/ui/templates/user/signup_domain.html:14
msgid "Domain" msgid "Domain"
@ -699,5 +712,4 @@ msgstr "Domena"
#: mailu/ui/templates/user/signup_domain.html:15 #: mailu/ui/templates/user/signup_domain.html:15
msgid "Available slots" msgid "Available slots"
msgstr "" msgstr "Dostępne miejsca"

@ -20,7 +20,7 @@ def handle_needs_login():
) )
# Rate limiter # Rate limiter
limiter = limiter.Limiter() limiter = limiter.LimitWraperFactory()
# Application translation # Application translation
babel = flask_babel.Babel() babel = flask_babel.Babel()

@ -41,9 +41,10 @@ redis==3.2.1
six==1.12.0 six==1.12.0
socrate==0.1.1 socrate==0.1.1
SQLAlchemy==1.3.3 SQLAlchemy==1.3.3
srslib==0.1.4
tabulate==0.8.3 tabulate==0.8.3
tenacity==5.0.4 tenacity==5.0.4
validators==0.12.5 validators==0.12.6
visitor==0.1.3 visitor==0.1.3
Werkzeug==0.15.3 Werkzeug==0.15.3
WTForms==2.2.1 WTForms==2.2.1

@ -22,3 +22,4 @@ tenacity
mysqlclient mysqlclient
psycopg2 psycopg2
idna idna
srslib

@ -1,4 +1,15 @@
ARG DISTRO=alpine:3.10 ARG DISTRO=alpine:3.10
FROM $DISTRO as builder
WORKDIR /tmp
RUN apk add git build-base automake autoconf libtool dovecot-dev xapian-core-dev icu-dev
RUN git clone https://github.com/grosjo/fts-xapian.git \
&& cd fts-xapian \
&& git checkout 1.2.7 \
&& autoreconf -vi \
&& PANDOC=false ./configure --with-dovecot=/usr/lib/dovecot \
&& make \
&& make install
FROM $DISTRO FROM $DISTRO
# python3 shared with most images # python3 shared with most images
RUN apk add --no-cache \ RUN apk add --no-cache \
@ -13,9 +24,11 @@ RUN pip3 install "podop>0.2.5"
# Image specific layers under this line # Image specific layers under this line
RUN apk add --no-cache \ RUN apk add --no-cache \
dovecot dovecot-lmtpd dovecot-pop3d dovecot-submissiond dovecot-pigeonhole-plugin rspamd-client \ dovecot dovecot-lmtpd dovecot-pop3d dovecot-submissiond dovecot-pigeonhole-plugin rspamd-client xapian-core \
&& mkdir /var/lib/dovecot && mkdir /var/lib/dovecot
COPY --from=builder /usr/lib/dovecot/lib21_fts_xapian_plugin.* /usr/lib/dovecot/
COPY conf /conf COPY conf /conf
COPY start.py /start.py COPY start.py /start.py

@ -21,7 +21,8 @@ mail_access_groups = mail
maildir_stat_dirs = yes maildir_stat_dirs = yes
mailbox_list_index = yes mailbox_list_index = yes
mail_vsize_bg_after_count = 100 mail_vsize_bg_after_count = 100
mail_plugins = $mail_plugins quota quota_clone zlib mail_plugins = $mail_plugins quota quota_clone zlib fts fts_xapian
default_vsz_limit = 2GB
namespace inbox { namespace inbox {
inbox = yes inbox = yes
@ -38,6 +39,12 @@ plugin {
quota_vsizes = yes quota_vsizes = yes
quota_clone_dict = proxy:/tmp/podop.socket:quota quota_clone_dict = proxy:/tmp/podop.socket:quota
fts = xapian
fts_xapian = partial=2 full=30
fts_autoindex = yes
fts_enforced = yes
fts_autoindex_exclude = \Trash
{% if COMPRESSION in [ 'gz', 'bz2' ] %} {% if COMPRESSION in [ 'gz', 'bz2' ] %}
zlib_save = {{ COMPRESSION }} zlib_save = {{ COMPRESSION }}
{% endif %} {% endif %}

@ -218,8 +218,9 @@ mail {
listen 25; listen 25;
listen [::]:25; listen [::]:25;
{% if TLS and not TLS_ERROR %} {% if TLS and not TLS_ERROR %}
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4"; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA;
ssl_prefer_server_ciphers on;
starttls on; starttls on;
{% endif %} {% endif %}
protocol smtp; protocol smtp;

@ -1,8 +1,8 @@
ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384';
ssl_prefer_server_ciphers on;
ssl_session_timeout 10m;
ssl_session_tickets off;
ssl_certificate {{ TLS[0] }}; ssl_certificate {{ TLS[0] }};
ssl_certificate_key {{ TLS[1] }}; ssl_certificate_key {{ TLS[1] }};
ssl_session_timeout 1d;
ssl_session_tickets off;
ssl_dhparam /conf/dhparam.pem; ssl_dhparam /conf/dhparam.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;

@ -75,6 +75,12 @@ relay_domains = ${podop}transport
transport_maps = ${podop}transport transport_maps = ${podop}transport
virtual_transport = lmtp:inet:{{ LMTP_ADDRESS }} virtual_transport = lmtp:inet:{{ LMTP_ADDRESS }}
# Sender and recipient canonical maps, mostly for SRS
sender_canonical_maps = ${podop}sendermap
sender_canonical_classes = envelope_sender
recipient_canonical_maps = ${podop}recipientmap
recipient_canonical_classes= envelope_recipient,header_recipient
# In order to prevent Postfix from running DNS query, enforce the use of the # In order to prevent Postfix from running DNS query, enforce the use of the
# native DNS stack, that will check /etc/hosts properly. # native DNS stack, that will check /etc/hosts properly.
lmtp_host_lookup = native lmtp_host_lookup = native
@ -120,4 +126,3 @@ milter_default_action = tempfail
############### ###############
# Extra Settings # Extra Settings
############### ###############

@ -21,10 +21,16 @@ def start_podop():
("alias", "url", url + "alias/§"), ("alias", "url", url + "alias/§"),
("domain", "url", url + "domain/§"), ("domain", "url", url + "domain/§"),
("mailbox", "url", url + "mailbox/§"), ("mailbox", "url", url + "mailbox/§"),
("recipientmap", "url", url + "recipient/map/§"),
("sendermap", "url", url + "sender/map/§"),
("senderaccess", "url", url + "sender/access/§"), ("senderaccess", "url", url + "sender/access/§"),
("senderlogin", "url", url + "sender/login/§") ("senderlogin", "url", url + "sender/login/§")
]) ])
def is_valid_postconf_line(line):
return not line.startswith("#") \
and not line == ''
# Actual startup script # Actual startup script
os.environ["FRONT_ADDRESS"] = system.get_host_address_from_environment("FRONT", "front") os.environ["FRONT_ADDRESS"] = system.get_host_address_from_environment("FRONT", "front")
os.environ["ADMIN_ADDRESS"] = system.get_host_address_from_environment("ADMIN", "admin") os.environ["ADMIN_ADDRESS"] = system.get_host_address_from_environment("ADMIN", "admin")
@ -36,11 +42,13 @@ for postfix_file in glob.glob("/conf/*.cf"):
if os.path.exists("/overrides/postfix.cf"): if os.path.exists("/overrides/postfix.cf"):
for line in open("/overrides/postfix.cf").read().strip().split("\n"): for line in open("/overrides/postfix.cf").read().strip().split("\n"):
os.system('postconf -e "{}"'.format(line)) if is_valid_postconf_line(line):
os.system('postconf -e "{}"'.format(line))
if os.path.exists("/overrides/postfix.master"): if os.path.exists("/overrides/postfix.master"):
for line in open("/overrides/postfix.master").read().strip().split("\n"): for line in open("/overrides/postfix.master").read().strip().split("\n"):
os.system('postconf -Me "{}"'.format(line)) if is_valid_postconf_line(line):
os.system('postconf -Me "{}"'.format(line))
for map_file in glob.glob("/overrides/*.map"): for map_file in glob.glob("/overrides/*.map"):
destination = os.path.join("/etc/postfix", os.path.basename(map_file)) destination = os.path.join("/etc/postfix", os.path.basename(map_file))

@ -38,7 +38,7 @@ POSTMASTER=admin
TLS_FLAVOR=cert TLS_FLAVOR=cert
# Authentication rate limit (per source IP address) # Authentication rate limit (per source IP address)
AUTH_RATELIMIT=10/minute;1000/hour AUTH_RATELIMIT=10/minute
# Opt-out of statistics, replace with "True" to opt out # Opt-out of statistics, replace with "True" to opt out
DISABLE_STATISTICS=False DISABLE_STATISTICS=False
@ -68,6 +68,10 @@ ANTIVIRUS=none
# Max attachment size will be 33% smaller # Max attachment size will be 33% smaller
MESSAGE_SIZE_LIMIT=50000000 MESSAGE_SIZE_LIMIT=50000000
# Message rate limit for outgoing messages
# This limit is per user
MESSAGE_RATELIMIT=100/day
# Networks granted relay permissions # Networks granted relay permissions
# Use this with care, all hosts in this networks will be able to send mail without authentication! # Use this with care, all hosts in this networks will be able to send mail without authentication!
RELAYNETS= RELAYNETS=

@ -46,7 +46,6 @@ rules does also apply to auth requests coming from ``SUBNET``, especially for th
If you disable this, ensure that the rate limit on the webmail is enforced in a different If you disable this, ensure that the rate limit on the webmail is enforced in a different
way (e.g. roundcube plug-in), otherwise an attacker can simply bypass the limit using webmail. way (e.g. roundcube plug-in), otherwise an attacker can simply bypass the limit using webmail.
The ``TLS_FLAVOR`` sets how Mailu handles TLS connections. Setting this value to The ``TLS_FLAVOR`` sets how Mailu handles TLS connections. Setting this value to
``notls`` will cause Mailu not to server any web content! More on :ref:`tls_flavor`. ``notls`` will cause Mailu not to server any web content! More on :ref:`tls_flavor`.
@ -57,6 +56,10 @@ The ``MESSAGE_SIZE_LIMIT`` is the maximum size of a single email. It should not
be too low to avoid dropping legitimate emails and should not be too high to be too low to avoid dropping legitimate emails and should not be too high to
avoid filling the disks with large junk emails. avoid filling the disks with large junk emails.
The ``MESSAGE_RATELIMIT`` is the limit of messages a single user can send. This is
meant to fight outbound spam in case of compromised or malicious account on the
server.
The ``RELAYNETS`` are network addresses for which mail is relayed for free with The ``RELAYNETS`` are network addresses for which mail is relayed for free with
no authentication required. This should be used with great care. If you want other no authentication required. This should be used with great care. If you want other
Docker services' outbound mail to be relayed, you can set this to ``172.16.0.0/12`` Docker services' outbound mail to be relayed, you can set this to ``172.16.0.0/12``

@ -456,7 +456,7 @@ follow these steps:
logging: logging:
driver: journald driver: journald
2. Add the /etc/fail2ban/jail.d/bad-auth.conf 2. Add the /etc/fail2ban/filter.d/bad-auth.conf
.. code-block:: bash .. code-block:: bash

@ -67,7 +67,6 @@ spec:
role: mail role: mail
tier: backend tier: backend
ports: ports:
ports:
- name: imap-auth - name: imap-auth
port: 2102 port: 2102
protocol: TCP protocol: TCP

@ -8,6 +8,7 @@ import subprocess
import re import re
import requests import requests
import sys import sys
import traceback
FETCHMAIL = """ FETCHMAIL = """
@ -45,47 +46,50 @@ def fetchmail(fetchmailrc):
def run(debug): def run(debug):
fetches = requests.get("http://admin/internal/fetch").json() try:
smtphost, smtpport = extract_host_port(os.environ.get("HOST_SMTP", "smtp"), None) fetches = requests.get("http://admin/internal/fetch").json()
if smtpport is None: smtphost, smtpport = extract_host_port(os.environ.get("HOST_SMTP", "smtp"), None)
smtphostport = smtphost if smtpport is None:
else: smtphostport = smtphost
smtphostport = "%s/%d" % (smtphost, smtpport) else:
for fetch in fetches: smtphostport = "%s/%d" % (smtphost, smtpport)
fetchmailrc = "" for fetch in fetches:
options = "options antispam 501, 504, 550, 553, 554" fetchmailrc = ""
options += " sslmode wrapped" if fetch["tls"] else "" options = "options antispam 501, 504, 550, 553, 554"
options += " keep" if fetch["keep"] else " fetchall" options += " sslmode wrapped" if fetch["tls"] else ""
fetchmailrc += RC_LINE.format( options += " keep" if fetch["keep"] else " fetchall"
user_email=escape_rc_string(fetch["user_email"]), fetchmailrc += RC_LINE.format(
protocol=fetch["protocol"], user_email=escape_rc_string(fetch["user_email"]),
host=escape_rc_string(fetch["host"]), protocol=fetch["protocol"],
port=fetch["port"], host=escape_rc_string(fetch["host"]),
smtphost=smtphostport, port=fetch["port"],
username=escape_rc_string(fetch["username"]), smtphost=smtphostport,
password=escape_rc_string(fetch["password"]), username=escape_rc_string(fetch["username"]),
options=options password=escape_rc_string(fetch["password"]),
) options=options
if debug:
print(fetchmailrc)
try:
print(fetchmail(fetchmailrc))
error_message = ""
except subprocess.CalledProcessError as error:
error_message = error.output.decode("utf8")
# No mail is not an error
if not error_message.startswith("fetchmail: No mail"):
print(error_message)
user_info = "for %s at %s" % (fetch["user_email"], fetch["host"])
# Number of messages seen is not a error as well
if ("messages" in error_message and
"(seen " in error_message and
user_info in error_message):
print(error_message)
finally:
requests.post("http://admin/internal/fetch/{}".format(fetch["id"]),
json=error_message.split("\n")[0]
) )
if debug:
print(fetchmailrc)
try:
print(fetchmail(fetchmailrc))
error_message = ""
except subprocess.CalledProcessError as error:
error_message = error.output.decode("utf8")
# No mail is not an error
if not error_message.startswith("fetchmail: No mail"):
print(error_message)
user_info = "for %s at %s" % (fetch["user_email"], fetch["host"])
# Number of messages seen is not a error as well
if ("messages" in error_message and
"(seen " in error_message and
user_info in error_message):
print(error_message)
finally:
requests.post("http://admin/internal/fetch/{}".format(fetch["id"]),
json=error_message.split("\n")[0]
)
except Exception:
traceback.print_exc()
if __name__ == "__main__": if __name__ == "__main__":

@ -30,8 +30,8 @@ POSTMASTER={{ postmaster }}
TLS_FLAVOR={{ tls_flavor }} TLS_FLAVOR={{ tls_flavor }}
# Authentication rate limit (per source IP address) # Authentication rate limit (per source IP address)
{% if auth_ratelimit_pm > '0' and auth_ratelimit_ph > '0' %} {% if auth_ratelimit_pm > '0' %}
AUTH_RATELIMIT={{ auth_ratelimit_pm }}/minute;{{ auth_ratelimit_ph }}/hour AUTH_RATELIMIT={{ auth_ratelimit_pm }}/minute
{% endif %} {% endif %}
# Opt-out of statistics, replace with "True" to opt out # Opt-out of statistics, replace with "True" to opt out

@ -47,11 +47,10 @@ Or in plain english: if receivers start to classify your mail as spam, this post
<div class="form-group"> <div class="form-group">
<label>Authentication rate limit (per source IP address)</label> <label>Authentication rate limit (per source IP address)</label>
<!-- Validates number input only --> <!-- Validates number input only -->
<p><input class="form-control" style="width: 7%; display: inline;" type="number" name="auth_ratelimit_pm" <p><input class="form-control" style="width: 7%; display: inline;" type="number" name="auth_ratelimit_pm"
value="10" required >/minute; value="10" required > / minute
<input class="form-control" style="width: 7%; display: inline;;" type="number" name="auth_ratelimit_ph" </p>
value="1000" required >/hour</p>
</div> </div>
<div class="form-check form-check-inline"> <div class="form-check form-check-inline">

@ -0,0 +1 @@
Ignore newlines and comment-lines in postfix overrides - this means you can now make your override configfiles much more readable.

@ -0,0 +1 @@
The roundcube container does support mysql now (no setup integration yet)

@ -0,0 +1 @@
Allow users to use server-sided full-text-search again by adding the dovecot fts-xapian plugin

@ -0,0 +1 @@
Relay a domain to a nonstandard SMTP port by adding ":<port_num>" to the remote hostname or IP address.

@ -0,0 +1 @@
Add support for backward-forwarding using SRS

@ -16,13 +16,13 @@ RUN apt-get update && apt-get install -y \
# Shared layer between nginx, dovecot, postfix, postgresql, rspamd, unbound, rainloop, roundcube # Shared layer between nginx, dovecot, postfix, postgresql, rspamd, unbound, rainloop, roundcube
RUN pip3 install socrate RUN pip3 install socrate
ENV ROUNDCUBE_URL https://github.com/roundcube/roundcubemail/releases/download/1.4.2/roundcubemail-1.4.2-complete.tar.gz ENV ROUNDCUBE_URL https://github.com/roundcube/roundcubemail/releases/download/1.4.3/roundcubemail-1.4.3-complete.tar.gz
RUN apt-get update && apt-get install -y \ RUN apt-get update && apt-get install -y \
zlib1g-dev libzip4 libzip-dev \ zlib1g-dev libzip4 libzip-dev libpq-dev \
python3-jinja2 \ python3-jinja2 \
gpg \ gpg \
&& docker-php-ext-install zip \ && docker-php-ext-install zip pdo_mysql pdo_pgsql \
&& echo date.timezone=UTC > /usr/local/etc/php/conf.d/timezone.ini \ && echo date.timezone=UTC > /usr/local/etc/php/conf.d/timezone.ini \
&& rm -rf /var/www/html/ \ && rm -rf /var/www/html/ \
&& cd /var/www \ && cd /var/www \

@ -3,7 +3,7 @@
$config = array(); $config = array();
// Generals // Generals
$config['db_dsnw'] = 'sqlite:////data/roundcube.db'; $config['db_dsnw'] = getenv('DB_DSNW');;
$config['temp_dir'] = '/tmp/'; $config['temp_dir'] = '/tmp/';
$config['des_key'] = getenv('SECRET_KEY'); $config['des_key'] = getenv('SECRET_KEY');
$config['cipher_method'] = 'AES-256-CBC'; $config['cipher_method'] = 'AES-256-CBC';

@ -4,16 +4,61 @@ import os
import logging as log import logging as log
import sys import sys
from socrate import conf from socrate import conf
import subprocess
log.basicConfig(stream=sys.stderr, level=os.environ.get("LOG_LEVEL", "WARNING")) log.basicConfig(stream=sys.stderr, level=os.environ.get("LOG_LEVEL", "WARNING"))
os.environ["MAX_FILESIZE"] = str(int(int(os.environ.get("MESSAGE_SIZE_LIMIT"))*0.66/1048576)) os.environ["MAX_FILESIZE"] = str(int(int(os.environ.get("MESSAGE_SIZE_LIMIT"))*0.66/1048576))
db_flavor=os.environ.get("ROUNDCUBE_DB_FLAVOR",os.environ.get("DB_FLAVOR","sqlite"))
if db_flavor=="sqlite":
os.environ["DB_DSNW"]="sqlite:////data/roundcube.db"
elif db_flavor=="mysql":
os.environ["DB_DSNW"]="mysql://%s:%s@%s/%s" % (
os.environ.get("ROUNDCUBE_DB_USER","roundcube"),
os.environ.get("ROUNDCUBE_DB_PW"),
os.environ.get("ROUNDCUBE_DB_HOST",os.environ.get("DB_HOST","database")),
os.environ.get("ROUNDCUBE_DB_NAME","roundcube")
)
elif db_flavor=="postgresql":
os.environ["DB_DSNW"]="pgsql://%s:%s@%s/%s" % (
os.environ.get("ROUNDCUBE_DB_USER","roundcube"),
os.environ.get("ROUNDCUBE_DB_PW"),
os.environ.get("ROUNDCUBE_DB_HOST",os.environ.get("DB_HOST","database")),
os.environ.get("ROUNDCUBE_DB_NAME","roundcube")
)
else:
print("Unknown ROUNDCUBE_DB_FLAVOR: %s",db_flavor)
exit(1)
conf.jinja("/php.ini", os.environ, "/usr/local/etc/php/conf.d/roundcube.ini") conf.jinja("/php.ini", os.environ, "/usr/local/etc/php/conf.d/roundcube.ini")
# Fix some permissions # Fix some permissions
os.system("mkdir -p /data/gpg") os.system("mkdir -p /data/gpg /var/www/html/logs")
os.system("chown -R www-data:www-data /data") os.system("touch /var/www/html/logs/errors")
os.system("chown -R www-data:www-data /data /var/www/html/logs")
try:
print("Initializing database")
result=subprocess.check_output(["/var/www/html/bin/initdb.sh","--dir","/var/www/html/SQL"],stderr=subprocess.STDOUT)
print(result.decode())
except subprocess.CalledProcessError as e:
if "already exists" in e.stdout.decode():
print("Already initialzed")
else:
print(e.stdout.decode())
quit(1)
try:
print("Upgrading database")
subprocess.check_call(["/var/www/html/bin/update.sh","--version=?","-y"],stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
quit(1)
# Tail roundcube logs
subprocess.Popen(["tail","-f","-n","0","/var/www/html/logs/errors"])
# Run apache # Run apache
os.execv("/usr/local/bin/apache2-foreground", ["apache2-foreground"]) os.execv("/usr/local/bin/apache2-foreground", ["apache2-foreground"])

Loading…
Cancel
Save