Compare commits

...

194 Commits

Author SHA1 Message Date
Niklas Meyer
9c814cc182 Merge pull request #5922 from mailcow/staging
2024-06
2024-06-27 11:15:53 +02:00
Niklas Meyer
cf6594220c dovecot: add Flatcurve FTS Engine as EXPERIMENTAL (#5920)
* dovecot: experimental added flatcurve backend + switch

* dovecot: bump docker image
2024-06-26 11:28:18 +02:00
Niklas Meyer
2cf952eb36 [Postfix] Upgrade to Deb12 + PF to 3.7.10 & Drop TLS 1.0/1.1 per default (#5635)
* postfix: removed TLS1.0/1.1 support (natively)

* postfix: upgrade to deb12 + pf to 3.7.9

* compose: increased postfix tag

* postfix: shortened TLS syntax with new format of 3.6+
2024-06-26 10:44:07 +02:00
DerLinkman
6fc86dd7d3 acme: corrected acme-tiny download path 2024-06-24 10:00:30 +02:00
DerLinkman
bf13af9691 increased rspamd image tag 2024-06-24 10:00:16 +02:00
milkmaker
1af9c21a50 Translations update from Weblate (#5912)
* [Web] Updated lang.ca-es.json

[Web] Updated lang.ca-es.json

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Peter <magic@kthx.at>

* [Web] Updated lang.cs-cz.json

[Web] Updated lang.cs-cz.json

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Peter <magic@kthx.at>

* [Web] Updated lang.da-dk.json

[Web] Updated lang.da-dk.json

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Peter <magic@kthx.at>

* [Web] Updated lang.es-es.json

[Web] Updated lang.es-es.json

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Peter <magic@kthx.at>

* [Web] Updated lang.fi-fi.json

[Web] Updated lang.fi-fi.json

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Peter <magic@kthx.at>

* [Web] Updated lang.fr-fr.json

[Web] Updated lang.fr-fr.json

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Peter <magic@kthx.at>

* [Web] Updated lang.hu-hu.json

[Web] Updated lang.hu-hu.json

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Peter <magic@kthx.at>

* [Web] Updated lang.ro-ro.json

[Web] Updated lang.ro-ro.json

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Peter <magic@kthx.at>

* [Web] Updated lang.it-it.json

[Web] Updated lang.it-it.json

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Peter <magic@kthx.at>

* [Web] Updated lang.lv-lv.json

[Web] Updated lang.lv-lv.json

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Peter <magic@kthx.at>

* [Web] Updated lang.ko-kr.json

[Web] Updated lang.ko-kr.json

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Peter <magic@kthx.at>

* [Web] Updated lang.nl-nl.json

[Web] Updated lang.nl-nl.json

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Peter <magic@kthx.at>

* [Web] Updated lang.pl-pl.json

[Web] Updated lang.pl-pl.json

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Peter <magic@kthx.at>

* [Web] Updated lang.ru-ru.json

[Web] Updated lang.ru-ru.json

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Peter <magic@kthx.at>

* [Web] Updated lang.sk-sk.json

[Web] Updated lang.sk-sk.json

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Peter <magic@kthx.at>

* [Web] Updated lang.sv-se.json

[Web] Updated lang.sv-se.json

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Peter <magic@kthx.at>

* [Web] Updated lang.zh-cn.json

[Web] Updated lang.zh-cn.json

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Peter <magic@kthx.at>

* [Web] Updated lang.uk-ua.json

Co-authored-by: Anonymous <noreply@weblate.org>

* [Web] Updated lang.zh-tw.json

[Web] Updated lang.zh-tw.json

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Peter <magic@kthx.at>

* [Web] Updated lang.pt-pt.json

[Web] Updated lang.pt-pt.json

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Peter <magic@kthx.at>

* [Web] Updated lang.tr-tr.json

[Web] Updated lang.tr-tr.json

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Peter <magic@kthx.at>

* [Web] Updated lang.si-si.json

[Web] Updated lang.si-si.json

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Peter <magic@kthx.at>

* [Web] Updated lang.gr-gr.json

[Web] Updated lang.gr-gr.json

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Peter <magic@kthx.at>

* [Web] Updated lang.nb-no.json

Co-authored-by: Anonymous <noreply@weblate.org>

* [Web] Updated lang.lt-lt.json

Co-authored-by: Anonymous <noreply@weblate.org>

---------

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Peter <magic@kthx.at>
2024-06-24 09:07:46 +02:00
realizelol
443941e687 [Rspamd] Delete overriding obsolete rspamd plugin (#5900)
* [Dockerfiles] rspamd: Delete COPY of metadata_exporter.lua plugin

* [Dockerfiles] rspamd: Delete metadata_exporter.lua plugin file

* Dockerfile: changed way of installing rspamd (granular version)

---------

Co-authored-by: DerLinkman <niklas.meyer@servercow.de>
2024-06-24 09:07:12 +02:00
renovate[bot]
527577b438 chore(deps): update docker/build-push-action action to v6 (#5910)
Signed-off-by: milkmaker <milkmaker@mailcow.de>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-17 17:38:21 +02:00
milkmaker
9daf2d80c0 Translations update from Weblate (#5908)
* [Web] Updated lang.fr-fr.json

Co-authored-by: Paul FERA <paulfera17@gmail.com>

* [Web] Updated lang.lv-lv.json

[Web] Updated lang.lv-lv.json

Co-authored-by: Deniss <mailcow@rigaden.me>
Co-authored-by: Edgars Andersons <Edgars+Mailcow+Weblate@gaitenis.id.lv>

---------

Co-authored-by: Paul FERA <paulfera17@gmail.com>
Co-authored-by: Deniss <mailcow@rigaden.me>
Co-authored-by: Edgars Andersons <Edgars+Mailcow+Weblate@gaitenis.id.lv>
2024-06-16 19:21:46 +02:00
Daniel
38b0641742 Remove unnecessary log lines in Postfix's log (#5817)
* Update main.cf

In order to avoid unnecessary log lines, changed:

smtpd_discard_ehlo_keywords = chunking
to this one:

# The non-logging alternative:
smtpd_discard_ehlo_keywords = chunking, silent-discard

Update main.cf to remove unnecessary log lines in Postfix log
2024-06-10 14:51:55 +02:00
Niklas Meyer
f675af5bb0 Merge pull request #5902 from mailcow/feat/nextcloud-deprecation
nextcloud: add deprecation notice once script start
2024-06-10 14:33:53 +02:00
DerLinkman
533c4e7956 nextcloud: add deprecation notice once script start 2024-06-10 14:21:13 +02:00
Niklas Meyer
1b2c2c0037 Merge pull request #5690 from mailcow:renovate/nextcloud-server-28.x
chore(deps): update dependency nextcloud/server to v28.0.6
2024-06-10 13:57:09 +02:00
Niklas Meyer
97768494e1 Merge pull request #5880 from PierrePlt:fix/blocking-last-logins
Fix blocking last logins fetching
2024-06-10 12:40:43 +02:00
Lasagne
4a052da289 Add switch to skip fetching certificates auto{config,discover} subdomains (#5838)
* Add ACME_DONT_FETCH_CERTS_FOR_HTTP_SUBDOMAINS to acme.sh

* Add ACME_DONT_FETCH_CERTS_FOR_HTTP_SUBDOMAINS to docker-compose.yml

* Add ACME_DONT_FETCH_CERTS_FOR_HTTP_SUBDOMAINS to generate_config.sh

* Add ACME_DONT_FETCH_CERTS_FOR_HTTP_SUBDOMAINS to update.sh

* AUTODISCOVER_SAN instead of long string

default on,
default is fetching certs for auto{discover,conf}

* AUTODISCOVER_SAN instead of long string

also flipped

* AUTODISCOVER_SAN instead of long string

flipped default meaning

* fix explanation for AUTODISCOVER_SAN

* AUTODISCOVER_SAN instead of long string

and flipped meaning of the bool

* fix AUTODISCOVER_SAN explanation

* Merge branch 'mailcow:staging' into staging

* update.sh: corrected syntax for mailcow.conf insertion
2024-06-10 12:33:02 +02:00
Niklas Meyer
18d7a55b15 Merge pull request #5901 from mailcow:sorbs
Remove discontinued SORBS DNSBL
2024-06-10 12:18:43 +02:00
Michael Kuron
9ca2fb7ccf Remove discontinued SORBS DNSBL 2024-06-08 12:29:08 +02:00
Niklas Meyer
b4e8355827 Merge pull request #5845 from iamspido:patch-1
remove version from docker-compose.yml
2024-06-06 15:30:15 +02:00
DerLinkman
e0bde1c459 compose: removed all versions declarations (DEPRECATED) 2024-06-06 15:29:34 +02:00
Niklas Meyer
27c007ebd3 Merge pull request #5750 from DocFraggle:staging
Fix unbound healthcheck.sh to log all messages to logfile
2024-06-06 15:27:40 +02:00
Niklas Meyer
8f3ea09732 Merge pull request #5893 from mailcow/feat/base-os
os: updated all Alpine containers to 3.20
2024-06-05 13:10:10 +02:00
DerLinkman
af626d98d3 dovecot: fixed sa-rules download 2024-06-05 13:07:12 +02:00
Niklas Meyer
34b0574e56 Merge pull request #5886 from Thomas2500:patch-1
Switch IP2Country lookup backend to shortened version
2024-06-05 12:37:31 +02:00
Niklas Meyer
49d738809b Merge pull request #5863 from mailcow:update/postscreen_access.cidr
[Postfix] update postscreen_access.cidr
2024-06-05 12:32:56 +02:00
Niklas Meyer
2fa3a22eca Merge pull request #5875 from CallMeLeon167:staging_cml
Update debug.twig to include a link to the git project URL for the mailcow version tag
2024-06-05 12:31:33 +02:00
Niklas Meyer
dc5eb6f92e Merge pull request #5883 from mailcow:renovate/alpine-3.x
chore(deps): update alpine docker tag to v3.20
2024-06-05 12:27:28 +02:00
DerLinkman
ba8902f0b1 os: updated all Alpine containers to 3.20 2024-06-05 11:52:48 +02:00
milkmaker
11e9a77840 update postscreen_access.cidr 2024-06-01 00:15:03 +00:00
Thomas Bella
64cd7e74c5 Switch IP2Country lookup backend to shortened version
Improves performance of #5880
2024-05-28 20:29:05 +02:00
renovate[bot]
cac65d081e chore(deps): update dependency nextcloud/server to v28.0.6
Signed-off-by: milkmaker <milkmaker@mailcow.de>
2024-05-28 12:54:13 +00:00
renovate[bot]
e5ada994be Update alpine Docker tag to v3.20
Signed-off-by: milkmaker <milkmaker@mailcow.de>
2024-05-22 18:17:51 +00:00
Pierre Pelletier
6ba2459645 Fixed blocking last connection fetching 2024-05-18 11:38:41 +00:00
DerLinkman
58f63aad08 [UI] Corrected Sieve Preset 1 (Fixed Regex) 2024-05-13 15:02:41 +02:00
milkmaker
8a8687a63c [Web] Updated lang.zh-cn.json (#5876)
Co-authored-by: Koala Ng <tonghoil@hotmail.com>
2024-05-10 22:38:08 +02:00
Leon Schmidt
f7f93c360d fix formatting of the mailcow version tag link 2024-05-10 19:56:31 +02:00
Leon
c160e1f68e Update debug.twig 2024-05-10 15:57:36 +02:00
Leon Schmidt
47c08ab8d2 Update debug.twig target="_blank" attribute for the mailcow version tag link 2024-05-10 15:17:49 +02:00
Leon Schmidt
cd83ffbaa2 Update debug.twig to include a link to the git project URL for the mailcow version tag 2024-05-10 15:09:27 +02:00
milkmaker
e12981a821 [Web] Updated lang.zh-cn.json (#5873)
Co-authored-by: Koala Ng <tonghoil@hotmail.com>
2024-05-07 17:44:37 +02:00
Ramis
47fd1bb894 Update lang.ru-ru.json (#5865)
Update lang

Co-authored-by: Patrick Schult <75116288+FreddleSpl0it@users.noreply.github.com>
2024-05-03 14:05:43 +02:00
milkmaker
20582b6353 [Web] Updated lang.lv-lv.json (#5862)
Co-authored-by: Edgars Andersons <Edgars+Mailcow+Weblate@gaitenis.id.lv>
2024-04-30 18:28:09 +02:00
IamSpido
c8ff5387c0 remove version from docker-compose.yml
With docker version 25.05 the version 2.1 in docker-compose.yml will be obsolete.
docker-compose.yml: `version` is obsolete
2024-04-16 14:10:44 +02:00
Mitchell van Bijleveld
7cb138d515 Improve Dutch translation (#5840) 2024-04-11 21:36:45 +02:00
milkmaker
3dd4c45fab Translations update from Weblate (#5839)
* [Web] Updated lang.hu-hu.json

Co-authored-by: David Csillag <csillag.david.istvan@gmail.com>
Co-authored-by: milkmaker <milkmaker@mailcow.de>

* [Web] Updated lang.lv-lv.json

Co-authored-by: Edgars Andersons <Edgars+Mailcow+Weblate@gaitenis.id.lv>
Co-authored-by: milkmaker <milkmaker@mailcow.de>

---------

Co-authored-by: David Csillag <csillag.david.istvan@gmail.com>
Co-authored-by: Edgars Andersons <Edgars+Mailcow+Weblate@gaitenis.id.lv>
2024-04-10 21:55:31 +02:00
polido
549539bec9 Update lang.pt-pt.json (#5832)
Co-authored-by: Patrick Schult <75116288+FreddleSpl0it@users.noreply.github.com>
2024-04-08 17:48:41 +02:00
milkmaker
e449cac464 Translations update from Weblate (#5835)
* [Web] Updated lang.fr-fr.json

Co-authored-by: Quiwy <github@quiwy.ninja>

* [Web] Updated lang.sv-se.json

Co-authored-by: André J <aj@nadox.se>

---------

Co-authored-by: Quiwy <github@quiwy.ninja>
Co-authored-by: André J <aj@nadox.se>
2024-04-08 17:47:43 +02:00
milkmaker
62e458f39b [Web] Updated lang.fr-fr.json (#5824)
Co-authored-by: Quiwy <github@quiwy.ninja>
2024-04-04 19:23:02 +02:00
FreddleSpl0it
b37caaf9e5 [Web] secure container_ctrl.php 2024-04-04 16:30:35 +02:00
FreddleSpl0it
7660ca89ae [Web] break loop if rspamd_map is valid 2024-04-04 16:29:58 +02:00
Patrick Schult
36b5cccd18 Merge pull request #5819 from mailcow/staging
2024-04
2024-04-04 08:50:58 +02:00
Patrick Schult
9decfa9c31 Merge pull request #5818 from mailcow/fix/web
[Web] fix exception handler and rspamd_maps function
2024-04-04 08:19:58 +02:00
FreddleSpl0it
3aee2b6cf5 [Web] use SEC_FETCH_DEST header instead of Referer to block api requests 2024-04-03 11:43:48 +02:00
Patrick Schult
17d797cee4 Merge pull request #5751 from mailcow/fix/rspamd-rewrite-ct
[Rspamd] milter update Content-Type and Content-Transfer-Encoding header
2024-04-03 10:49:21 +02:00
Patrick Schult
75550eeea3 Merge pull request #5812 from mailcow/limit-local-addrs
[Rspamd] Set local_addrs lo mailcow networks
2024-04-03 10:48:46 +02:00
FreddleSpl0it
0d09c86c12 [Web] fix invalid rspamd map check 2024-04-03 10:08:18 +02:00
FreddleSpl0it
2db8f482db [Web] escape html of alert messages 2024-04-03 10:07:36 +02:00
FreddleSpl0it
00d4b32a1b [Web] deny api calls from sogo 2024-04-03 10:06:43 +02:00
milkmaker
8a82bab1f3 [Web] Updated lang.tr-tr.json (#5815)
Co-authored-by: Uğurcan Albayrak <canalbayrakugur@gmail.com>
2024-04-02 18:04:30 +02:00
milkmaker
237a25e6b0 update postscreen_access.cidr (#5811) 2024-04-02 02:20:31 +02:00
milkmaker
5dc836671d [Web] Updated lang.tr-tr.json (#5813)
[Web] Updated lang.tr-tr.json

Co-authored-by: Uğurcan Albayrak <canalbayrakugur@gmail.com>
Co-authored-by: evrenkoksal <evrenkoksal@gmail.com>
2024-04-01 21:57:15 +02:00
Dmitriy Alekseev
26be1cb602 Set local_addrs in Rspamd 2024-04-01 11:28:06 +03:00
yvan-algoo
dc7a48cbf9 Update French translation (#5805)
* Fix some typo in French translation

* Fix typo error introduced in last commit

* Fixed another typo introduced in my first commit
2024-03-30 01:10:12 +01:00
milkmaker
52455be815 Translations update from Weblate (#5810)
* [Web] Updated lang.lt-lt.json

[Web] Updated lang.lt-lt.json

[Web] Updated lang.lt-lt.json

[Web] Updated lang.lt-lt.json

[Web] Updated lang.lt-lt.json

[Web] Updated lang.lt-lt.json

[Web] Added lang.lt-lt.json

Co-authored-by: Ari Archer <ari@ari.lt>
Co-authored-by: Peter <magic@kthx.at>
Co-authored-by: milkmaker <milkmaker@mailcow.de>

* [Web] Updated lang.lv-lv.json

[Web] Updated lang.lv-lv.json

[Web] Updated lang.lv-lv.json

[Web] Updated lang.lv-lv.json

Co-authored-by: Edgars Andersons <Edgars+Mailcow+Weblate@gaitenis.id.lv>
Co-authored-by: Edgars Počs <edgars.pocs@dna.lv>
Co-authored-by: milkmaker <milkmaker@mailcow.de>

* [Web] Updated lang.tr-tr.json

[Web] Updated lang.tr-tr.json

[Web] Updated lang.tr-tr.json

[Web] Updated lang.tr-tr.json

[Web] Updated lang.tr-tr.json

[Web] Updated lang.tr-tr.json

Co-authored-by: evrenkoksal <evrenkoksal@gmail.com>
Co-authored-by: milkmaker <milkmaker@mailcow.de>

* Add lt-lt in vars.inc.php

---------

Co-authored-by: Ari Archer <ari@ari.lt>
Co-authored-by: Peter <magic@kthx.at>
Co-authored-by: Edgars Andersons <Edgars+Mailcow+Weblate@gaitenis.id.lv>
Co-authored-by: Edgars Počs <edgars.pocs@dna.lv>
Co-authored-by: evrenkoksal <evrenkoksal@gmail.com>
2024-03-30 01:09:22 +01:00
Niklas Meyer
bbbdcfb625 Merge pull request #5743 from mailcow/fix-5742
Remove one GmbH in Dockerfiles
2024-03-20 09:37:45 +01:00
Niklas Meyer
b054a57e16 Merge pull request #5770 from mailcow/update/postscreen_access.cidr
[Postfix] update postscreen_access.cidr
2024-03-19 10:19:54 +01:00
aaadddfgh
fd73b3ad88 Update lang.zh-cn.json (#5789)
Change a better translation
2024-03-13 15:53:37 +01:00
milkmaker
8c0637b556 [Web] Updated lang.lv-lv.json (#5777)
Co-authored-by: Edgars Andersons <Edgars+Mailcow+Weblate@gaitenis.id.lv>
2024-03-05 17:57:55 +01:00
DerLinkman
d92ffe8fc7 helper: remove old SOGo repo to not break builds on ARM64 2024-03-01 11:41:11 +01:00
milkmaker
e0eb3a4f13 update postscreen_access.cidr 2024-03-01 00:14:54 +00:00
Niklas Meyer
1fb0060a73 Merge pull request #5765 from mailcow/feat/sogo-5.10
sogo: upgrade to 5.10.0
2024-02-27 08:22:19 +01:00
DerLinkman
d7430bf516 sogo: add new options to sogo.conf for update 5.10.0 2024-02-26 17:17:34 +01:00
DerLinkman
35f039a119 sogo: update to 5.10.0 2024-02-26 16:55:13 +01:00
milkmaker
79432a40d7 Translations update from Weblate (#5762)
* [Web] Updated lang.es-es.json

Co-authored-by: Fernando Dilland <fernandodilland@gmail.com>

* [Web] Updated lang.nb-no.json

Co-authored-by: Christer Solstrand Johannessen <csjoh@users.noreply.translate.mailcow.email>

---------

Co-authored-by: Fernando Dilland <fernandodilland@gmail.com>
Co-authored-by: Christer Solstrand Johannessen <csjoh@users.noreply.translate.mailcow.email>
2024-02-25 19:51:57 +01:00
FreddleSpl0it
98cdb95bc0 [Rspamd] milter update Content-Type and Content-Transfer-Encoding header after need_rewrite_ct 2024-02-19 11:20:19 +01:00
Hailer, Christian
02a55ce9db Fix unbound healthcheck.sh to log all messages to logfile 2024-02-19 09:26:29 +01:00
renovate[bot]
6f4720e1ea chore(deps): update thollander/actions-comment-pull-request action to v2.5.0 (#5747) 2024-02-17 11:42:30 +01:00
Peter
6a807b7799 Remove one GmbH 2024-02-15 17:43:01 +01:00
Patrick Schult
8d4ef147d2 Merge pull request #5741 from mailcow/staging
2024-02
2024-02-15 11:27:09 +01:00
milkmaker
8ed6217d1c Translations update from Weblate (#5740)
* [Web] Language file updated by 'Cleanup translation files' addon

[Web] Updated lang.it-it.json

ui: fixed broken Links to docs

ui: fix wrong docs links

Co-authored-by: DerLinkman <niklas.meyer@servercow.de>
Co-authored-by: Michele Caputo <michele@caputoweb.xyz>
Co-authored-by: milkmaker <milkmaker@mailcow.de>

* [Web] Language file updated by 'Cleanup translation files' addon

Co-authored-by: milkmaker <milkmaker@mailcow.de>

---------

Co-authored-by: DerLinkman <niklas.meyer@servercow.de>
Co-authored-by: Michele Caputo <michele@caputoweb.xyz>
2024-02-14 20:11:51 +01:00
milkmaker
7dae4a976d Translations update from Weblate (#5732)
* ui: fix wrong docs links

* ui: fixed broken Links to docs

* [Web] Updated lang.nb-no.json

[Web] Updated lang.nb-no.json

[Web] Updated lang.nb-no.json

[Web] Added lang.nb-no.json

Co-authored-by: Christer Solstrand Johannessen <csjoh@users.noreply.translate.mailcow.email>
Co-authored-by: Peter <magic@kthx.at>
Co-authored-by: milkmaker <milkmaker@mailcow.de>

* [Web] Updated lang.fr-fr.json

[Web] Updated lang.fr-fr.json

Co-authored-by: Alix ANNERAUD <alix.anneraud@outlook.fr>
Co-authored-by: William Blondel <contact@williamblondel.fr>
Co-authored-by: milkmaker <milkmaker@mailcow.de>

* [Web] Updated lang.it-it.json

Co-authored-by: Michele Caputo <michele@caputoweb.xyz>
Co-authored-by: milkmaker <milkmaker@mailcow.de>

* [Web] Updated lang.zh-tw.json

Co-authored-by: BallBill <BallBill@users.noreply.translate.mailcow.email>
Co-authored-by: milkmaker <milkmaker@mailcow.de>

* [Web] Updated lang.pt-br.json

[Web] Updated lang.pt-br.json

[Web] Updated lang.pt-br.json

[Web] Updated lang.pt-br.json

Co-authored-by: Abner Santana <abnerss@outlook.com>
Co-authored-by: milkmaker <milkmaker@mailcow.de>

* Add Norwegian in vars.inc.php

---------

Co-authored-by: DerLinkman <niklas.meyer@servercow.de>
Co-authored-by: Christer Solstrand Johannessen <csjoh@users.noreply.translate.mailcow.email>
Co-authored-by: Peter <magic@kthx.at>
Co-authored-by: Alix ANNERAUD <alix.anneraud@outlook.fr>
Co-authored-by: William Blondel <contact@williamblondel.fr>
Co-authored-by: Michele Caputo <michele@caputoweb.xyz>
Co-authored-by: BallBill <BallBill@users.noreply.translate.mailcow.email>
Co-authored-by: Abner Santana <abnerss@outlook.com>
2024-02-14 20:09:10 +01:00
FreddleSpl0it
3b83949ba3 [Netfilter] Update to 1.58 2024-02-14 13:58:07 +01:00
Patrick Schult
d8baadb991 Merge pull request #5679 from Habetdin/staging
[Netfilter] respect ban time limits
2024-02-14 11:37:24 +01:00
Patrick Schult
7d3f9fa407 Merge pull request #5727 from mailcow/fix/domain-wide-footer
[Rspamd] apply domain wide footer to alias domains
2024-02-14 09:43:04 +01:00
Patrick Schult
705d144a85 Merge pull request #5729 from mailcow/feat/readable-domainnames
[Web] display human readable domainnames instead of punycode
2024-02-14 09:36:20 +01:00
Patrick Schult
ff05cff36c Merge pull request #5730 from mailcow/fix/add-domain-gal
[Web] fix setting unchecked checkboxes on domain adding
2024-02-14 09:34:21 +01:00
Patrick Schult
861fa7b145 Merge pull request #5728 from mailcow/fix/debug-tz
[Web] fix blank /debug page with invalid timezone
2024-02-14 09:32:17 +01:00
FreddleSpl0it
d65a0bba44 [ClamAV] Update to 1.2.2 2024-02-13 09:16:38 +01:00
FreddleSpl0it
dac1bd88dc [Web] fix setting unchecked checkboxes 2024-02-09 15:17:02 +01:00
FreddleSpl0it
288dbfa37c [Web] display human readable domainnames instead of punycode 2024-02-09 15:13:45 +01:00
FreddleSpl0it
a0e55cb9b1 [Web] fix blank /debug page with invalid timezone 2024-02-09 15:08:21 +01:00
FreddleSpl0it
86ba019ca0 [Rspamd] apply domain wide footer to alias domains 2024-02-09 14:59:14 +01:00
DerLinkman
3cb9c2ece5 ui: fix wrong docs links
ui: fixed broken Links to docs
2024-02-09 08:11:20 +01:00
Habetdin
1787c53d98 [Netfilter] respect ban time limits 2024-02-09 01:57:09 +03:00
Niklas Meyer
8ae762a8c8 Merge pull request #5717 from mailcow/staging
2024-01e
2024-02-08 15:58:47 +01:00
DerLinkman
63426c3cd0 unbound: remove netcat check & package 2024-02-08 15:55:26 +01:00
DerLinkman
e184713c67 added action for support label in issues 2024-02-08 13:06:02 +01:00
Niklas Meyer
1926625297 Merge pull request #5711 from amorfo77/master
[Netfilter] set IP check more relaxed on NFTables.py
2024-02-08 12:36:03 +01:00
DerLinkman
63bb8e8cef unbound: increase check interval to 30s 2024-02-08 12:23:46 +01:00
DerLinkman
583c5b48a0 dovecot: bump to docker image 1.28.1 2024-02-07 17:29:36 +01:00
DerLinkman
d08ccbce78 dovecot: fix wrong timestamps inside logs 2024-02-07 17:28:49 +01:00
DerLinkman
5a9702771c [SOGo] Fixed SOGo crash on older kernels < 5.10.0-X 2024-02-07 17:18:20 +01:00
eb91d9905b fix typpo in chain order message 2024-02-07 15:48:49 +01:00
38cc85fa4c set strict=False 2024-02-07 15:36:04 +01:00
FreddleSpl0it
77e6ef218c [Netfilter] Update to 1.57 2024-02-05 09:54:16 +01:00
FreddleSpl0it
464b6f2e93 [Netfilter] fix redis logs 2024-02-05 09:47:19 +01:00
Niklas Meyer
20c90642f9 Merge pull request #5700 from mailcow/staging
[Netfilter] fix mailcow isolation rule for iptables
2024-02-02 17:49:49 +01:00
FreddleSpl0it
57e67ea8f7 [Netfilter] fix mailcow isolation rule for iptables 2024-02-02 17:40:44 +01:00
Niklas Meyer
c9e9628383 Merge pull request #5699 from mailcow/staging
2024-01d
2024-02-02 17:08:45 +01:00
DerLinkman
909f07939e dovecot: bump version for repl fix 2024-02-02 17:06:31 +01:00
FreddleSpl0it
a310493485 [Dovecot] fix repl_health.sh 2024-02-02 16:52:41 +01:00
Niklas Meyer
1e09df20b6 Merge pull request #5689 from mailcow/staging
2024-01c
2024-02-02 15:52:33 +01:00
Patrick Schult
087481ac12 Merge pull request #5696 from mailcow/fix/netfilter
[Netfilter] add mailcow isolation rule to MAILCOW chain
2024-02-02 14:33:01 +01:00
FreddleSpl0it
c941e802d4 [Netfilter] only perform cleanup at exit if SIGTERM was recieved 2024-02-02 12:57:21 +01:00
FreddleSpl0it
39589bd441 [Netfilter] only perform cleanup at exit if SIGTERM was recieved 2024-02-02 12:46:50 +01:00
DerLinkman
2e57325dde docker-compose.yml: Bump dovecot + netfilter version 2024-02-02 11:27:46 +01:00
FreddleSpl0it
2072301d89 [Netfilter] only perform cleanup at exit if SIGTERM was recieved 2024-02-02 11:08:44 +01:00
FreddleSpl0it
b236fd3ac6 [Netfilter] add mailcow isolation rule to MAILCOW chain
[Netfilter] add mailcow rule to docker-user chain

[Netfilter] add mailcow isolation rule to MAILCOW chain

[Netfilter] add mailcow isolation rule to MAILCOW chain

[Netfilter] set mailcow isolation rule before redis

[Netfilter] clear bans in redis after connecting

[Netfilter] simplify mailcow isolation rule for compatibility with iptables-nft

[Netfilter] stop container after mariadb, redis, dovecot, solr

[Netfilter] simplify mailcow isolation rule for compatibility with iptables-nft

[Netfilter] add exception for mailcow isolation rule for HA setups

[Netfilter] add exception for mailcow isolation rule for HA setups

[Netfilter] add DISABLE_NETFILTER_ISOLATION_RULE

[Netfilter] fix wrong var name

[Netfilter] add DISABLE_NETFILTER_ISOLATION_RULE to update and generate_config sh
2024-02-02 10:10:11 +01:00
Niklas Meyer
b968695e31 Merge pull request #5686 from mailcow/update/postscreen_access.cidr
[Postfix] update postscreen_access.cidr
2024-02-01 08:58:35 +01:00
Niklas Meyer
694f1d1623 Merge pull request #5688 from mailcow/fix/sogo-authenticated-users
sogo: fix ACL allow authenticated users + rebuild on Bookworm
2024-02-01 08:42:53 +01:00
DerLinkman
93e4d58606 sogo: fix ACL allow authenticated users + rebuild on Bookworm 2024-02-01 08:41:11 +01:00
milkmaker
cc77caad67 update postscreen_access.cidr 2024-02-01 00:13:56 +00:00
renovate[bot]
f74573f5d0 chore(deps): update peter-evans/create-pull-request action to v6 (#5683)
Signed-off-by: milkmaker <milkmaker@mailcow.de>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-31 16:14:42 +01:00
DerLinkman
deb6f0babc issue: added architecture as dropdown 2024-01-23 08:46:06 +01:00
Niklas Meyer
cb978136bd Merge pull request #5663 from mailcow/staging
2024-01b
2024-01-22 11:50:41 +01:00
Niklas Meyer
1159450cc4 Merge pull request #5662 from mailcow/fix/rollback-curl-bug
fix: rollback curl bug
2024-01-22 11:39:27 +01:00
DerLinkman
a0613e4b10 fix: rollback of Alpine 3.19 were possible 2024-01-22 11:26:26 +01:00
Niklas Meyer
68989f0a45 Merge pull request #5647 from Candinya/patch-1
fix: watchdog webhook body variables injector
2024-01-22 10:34:06 +01:00
DerLinkman
7da5e3697e compose: bump watchdog version 2024-01-22 10:32:01 +01:00
Nya Candy
6e7a0eb662 fix: watchdog webhook body variables injector 2024-01-22 10:32:01 +01:00
Niklas Meyer
b25ac855ca Merge pull request #5660 from luminem/openrc-support
Test for openrc configuration file instead of alpine
2024-01-22 10:27:29 +01:00
Niklas Meyer
3e02dcbb95 Merge pull request #5652 from KagurazakaNyaa/master
Allow user skip unbound healthcheck
2024-01-22 10:25:50 +01:00
DerLinkman
53be119e39 compose: bump unbound version 2024-01-22 10:22:24 +01:00
Luca Barbato
25bdc4c9ed Test for openrc configuration file instead of alpine
This way other distro using openrc can be supported.
2024-01-22 09:50:24 +01:00
KagurazakaNyaa
9d4055fc4d add parameter SKIP_UNBOUND_HEALTHCHECK to old installations 2024-01-19 00:07:51 +08:00
KagurazakaNyaa
d2edf359ac update config comment 2024-01-18 23:53:08 +08:00
KagurazakaNyaa
aa1d92dfbb add SKIP_UNBOUND_HEALTHCHECK to docker-compose.yml 2024-01-18 23:50:26 +08:00
KagurazakaNyaa
b89d71e6e4 change variable name 2024-01-18 23:48:59 +08:00
KagurazakaNyaa
ed493f9c3a Allow user skip unbound healthcheck 2024-01-18 23:28:03 +08:00
Niklas Meyer
76f8a5b7de Merge pull request #5650 from mailcow/staging
unbound: increased healthcheck timeout
2024-01-18 11:56:09 +01:00
DerLinkman
cb3bc207b9 unbound: increased healthcheck timeout 2024-01-18 11:55:01 +01:00
Niklas Meyer
b5db5dd0b4 Merge pull request #5642 from mailcow/staging
2024-01
2024-01-17 13:51:40 +01:00
FreddleSpl0it
90a7cff2c9 [Rspamd] check if footer.skip_replies is not 0 2024-01-17 12:05:51 +01:00
FreddleSpl0it
cc3adbe78c [Web] fix datatables ssp queries 2024-01-17 12:04:01 +01:00
Niklas Meyer
bd6a7210b7 Merge pull request #5523 from FELDSAM-INC/feldsam/datatables-ssp
Implemented Server Side processing for domains and mailboxes datatables
2024-01-17 10:23:05 +01:00
Niklas Meyer
905a202873 Merge pull request #5587 from mailcow/feat/arm64
mailcow Multiarch (x86 and ARM64) support
2024-01-17 10:18:06 +01:00
DerLinkman
accedf0280 Updated mailcow Components to be ARM64 compatible 2024-01-17 10:14:36 +01:00
FreddleSpl0it
99d9a2eacd [Web] fix mailbox and domain creation 2024-01-17 09:52:43 +01:00
Kristian Feldsam
ac4f131fa8 Domains and Mailboxes datatable - server side processing - filtering by tags
Signed-off-by: Kristian Feldsam <feldsam@gmail.com>
2024-01-16 15:03:28 +01:00
FreddleSpl0it
7f6f7e0e9f [Web] limit logo file upload 2024-01-15 16:34:47 +01:00
Niklas Meyer
43bb26f28c Merge pull request #5639 from mailcow/feat/unbound-healthcheck-rewrite
unbound: rewrote of healthcheck
2024-01-15 15:57:18 +01:00
DerLinkman
b29dc37991 unbound: rewrote healthcheck to be more detailed
unbound: added comments to rewritten healthcheck
2024-01-15 15:17:28 +01:00
DerLinkman
cf9f02adbb ui: fix alignment secondary 2024-01-10 14:43:59 +01:00
DerLinkman
b5a1a18b04 lang: fixed totp langs 2024-01-09 12:20:30 +01:00
Niklas Meyer
b4eeb0ffae Merge pull request #5522 from mailcow/renovate/krakjoe-apcu-5.x
chore(deps): update dependency krakjoe/apcu to v5.1.23
2024-01-09 12:06:12 +01:00
Niklas Meyer
48549ead7f Merge pull request #5549 from mailcow/renovate/phpredis-phpredis-6.x
chore(deps): update dependency phpredis/phpredis to v6.0.2
2024-01-09 12:04:41 +01:00
Niklas Meyer
01b0ad0fd9 Merge pull request #5550 from mailcow/renovate/tianon-gosu-1.x
chore(deps): update dependency tianon/gosu to v1.17
2024-01-09 12:04:21 +01:00
Niklas Meyer
2b21501450 Merge pull request #5581 from mailcow/renovate/composer-composer-2.x
chore(deps): update dependency composer/composer to v2.6.6
2024-01-09 12:03:08 +01:00
Niklas Meyer
b491f6af9b Merge pull request #5615 from mailcow/fix/default-values
[Web] use template for default values in mbox and domain creation
2024-01-09 12:01:24 +01:00
Niklas Meyer
942ef7c254 Merge pull request #5592 from mailcow/feat/alpine-3.19
Update Dockerfiles to Alpine 3.19
2024-01-09 11:57:34 +01:00
DerLinkman
1ee3bb42f3 compose: updated image tags 2024-01-09 11:55:32 +01:00
DerLinkman
25007b1963 dockerapi: implemented lifespan function 2024-01-09 11:50:22 +01:00
DerLinkman
f442378377 dockerfiles: updated maintainer 2024-01-09 11:18:55 +01:00
DerLinkman
333b7ebc0c Fix Alpine 3.19 dependencies 2024-01-09 11:17:52 +01:00
Peter
5896766fc3 Update to Alpine 3.19 2024-01-09 11:17:51 +01:00
Niklas Meyer
89540aec28 Merge pull request #5612 from mailcow/feat/domain-wide-footer
[Rspamd] add option to skip domain wide footer on reply e-mails
2024-01-09 11:10:35 +01:00
DerLinkman
b960143045 translation: update de-de.json 2024-01-09 11:09:35 +01:00
DerLinkman
6ab45cf668 db: bumped version to newer timestamp 2024-01-08 14:43:25 +01:00
Niklas Meyer
fd206a7ef6 Merge pull request #5621 from mailcow/align-ehlo-keywords-to-fuctions
[Postfix] Remove pipeling from ehlo keywords as we block it in data
2024-01-08 09:52:28 +01:00
Niklas Meyer
1c7347d38d Merge pull request #5616 from FELDSAM-INC/feldsam/fix-form-dark-mode
Fixed bg color of form elements in dark mode
2024-01-08 09:51:48 +01:00
Niklas Meyer
7f58c422f2 Merge pull request #5625 from mailcow/update/postscreen_access.cidr
[Postfix] update postscreen_access.cidr
2024-01-08 09:51:27 +01:00
Niklas Meyer
0a0e2b5e93 Merge pull request #5624 from mthld/patch-2
Add new SOGoMailHideInlineAttachments option to sogo.conf
2024-01-08 09:47:50 +01:00
milkmaker
de00c424f4 update postscreen_access.cidr 2024-01-01 00:15:27 +00:00
Mathilde
a249e2028d Add new SOGoMailHideInlineAttachments option to sogo.conf
SOGoMailHideInlineAttachments = YES; will allow to hide inline (body and footer) images being shown as attachments.
2023-12-30 10:16:25 +01:00
Dmitriy Alekseev
68036eeccf Update main.cf 2023-12-29 22:06:18 +02:00
Patrick Schult
cb0b0235f0 Merge pull request #5623 from mailcow/staging
🛷 🐄 Moocember 2023 Update Revision A | Postfix CVE-2023-51764 Security Update
2023-12-29 20:35:20 +01:00
FreddleSpl0it
6ff6f7a28d [Postfix] set smtpd_forbid_bare_newline = yes 2023-12-29 20:19:26 +01:00
milkmaker
0b628fb22d Translations update from Weblate (#5622)
* [Web] Updated lang.zh-tw.json

Co-authored-by: BallBill <xxx@billtang.ddns.net>

* [Web] Updated lang.pt-br.json

Co-authored-by: Abner Santana <abnerss@outlook.com>

---------

Co-authored-by: BallBill <xxx@billtang.ddns.net>
Co-authored-by: Abner Santana <abnerss@outlook.com>
2023-12-29 19:22:19 +01:00
Dmitriy Alekseev
b4bb11320f Update main.cf 2023-12-29 16:04:52 +02:00
Dmitriy Alekseev
c61938db23 [Postfix] Remove pipeling from ehlo keywords as we block it in data restrictions 2023-12-29 15:59:16 +02:00
Patrick Schult
acf9d5480c Merge pull request #5504 from FELDSAM-INC/feldsam/do-not-remove-x-mailer
[Postfix] Do not remove X-Mailer header
2023-12-27 18:40:19 +01:00
milkmaker
a1cb7fd778 [Web] Updated lang.zh-tw.json (#5617)
Co-authored-by: BallBill <xxx@billtang.ddns.net>
2023-12-27 18:03:24 +01:00
Kristian Feldsam
c24543fea0 [Web] Fixed form fields bg color in dark mode
Signed-off-by: Kristian Feldsam <feldsam@gmail.com>
2023-12-27 17:33:12 +01:00
Kristian Feldsam
100e8ab00d [Postfix] Do not remove X-Mailer header
some providers, like seznam.cz use X-Mailer in DKIM signatures

Signed-off-by: Kristian Feldsam <feldsam@gmail.com>
2023-12-27 16:32:50 +01:00
FreddleSpl0it
38497b04ac [Web] use template for default values in mbox and domain creation 2023-12-27 14:57:27 +01:00
renovate[bot]
7bd27b920a chore(deps): update dependency nextcloud/server to v28.0.1 (#5614)
Signed-off-by: milkmaker <milkmaker@mailcow.de>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-24 18:24:01 +01:00
FreddleSpl0it
efab11720d add option to skip footer on reply e-mails 2023-12-22 10:39:07 +01:00
renovate[bot]
40fdf99a55 Update dependency composer/composer to v2.6.6
Signed-off-by: milkmaker <milkmaker@mailcow.de>
2023-12-08 20:07:11 +00:00
Kristian Feldsam
efcca61f5a Mailboxes datatable - server side processing ordering
Signed-off-by: Kristian Feldsam <feldsam@gmail.com>
2023-12-04 14:52:17 +01:00
Kristian Feldsam
4dad0002cd Domains datatable - server side processing ordering
Signed-off-by: Kristian Feldsam <feldsam@gmail.com>
2023-12-04 14:15:57 +01:00
renovate[bot]
d4dd1e37ce Update dependency tianon/gosu to v1.17
Signed-off-by: milkmaker <milkmaker@mailcow.de>
2023-11-21 09:03:09 +00:00
renovate[bot]
a8dfa95126 Update dependency phpredis/phpredis to v6.0.2
Signed-off-by: milkmaker <milkmaker@mailcow.de>
2023-11-21 09:03:02 +00:00
renovate[bot]
4f109c1a94 Update dependency krakjoe/apcu to v5.1.23
Signed-off-by: milkmaker <milkmaker@mailcow.de>
2023-11-12 17:28:57 +00:00
Kristian Feldsam
28cec99699 Mailboxes datatable - server side processing
Signed-off-by: Kristian Feldsam <feldsam@gmail.com>
2023-11-12 10:35:26 +01:00
Kristian Feldsam
3e194c7906 Domains datatable - server side processing
Signed-off-by: Kristian Feldsam <feldsam@gmail.com>
2023-11-12 10:35:22 +01:00
117 changed files with 15399 additions and 1979 deletions

View File

@@ -62,6 +62,16 @@ body:
- nightly
validations:
required: true
- type: dropdown
attributes:
label: "Which architecture are you using?"
description: "#### `uname -m`"
multiple: false
options:
- x86
- ARM64 (aarch64)
validations:
required: true
- type: input
attributes:
label: "Operating System:"

View File

@@ -0,0 +1,37 @@
name: Check if labeled support, if so send message and close issue
on:
issues:
types:
- labeled
jobs:
add-comment:
if: github.event.label.name == 'support'
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- name: Add comment
run: gh issue comment "$NUMBER" --body "$BODY"
env:
GH_TOKEN: ${{ secrets.SUPPORTISSUES_ACTION_PAT }}
GH_REPO: ${{ github.repository }}
NUMBER: ${{ github.event.issue.number }}
BODY: |
**THIS IS A AUTOMATED MESSAGE!**
It seems your issue is not a bug.
Therefore we highly advise you to get support!
You can get support either by:
- ordering a paid [support contract at Servercow](https://www.servercow.de/mailcow?lang=en#support/) (Directly from the developers) or
- using the [community forum](https://community.mailcow.email) (**Based on volunteers! NO guaranteed answer**) or
- using the [Telegram support channel](https://t.me/mailcow) (**Based on volunteers! NO guaranteed answer**)
This issue will be closed. If you think your reported issue is not a support case feel free to comment above and if so the issue will reopened.
- name: Close issue
env:
GH_TOKEN: ${{ secrets.SUPPORTISSUES_ACTION_PAT }}
GH_REPO: ${{ github.repository }}
NUMBER: ${{ github.event.issue.number }}
run: gh issue close "$NUMBER" -r "not planned"

View File

@@ -10,7 +10,7 @@ jobs:
if: github.event.pull_request.base.ref != 'staging' #check if the target branch is not staging
steps:
- name: Send message
uses: thollander/actions-comment-pull-request@v2.4.3
uses: thollander/actions-comment-pull-request@v2.5.0
with:
GITHUB_TOKEN: ${{ secrets.CHECKIFPRISSTAGING_ACTION_PAT }}
message: |

View File

@@ -26,7 +26,7 @@ jobs:
password: ${{ secrets.BACKUPIMAGEBUILD_ACTION_DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
uses: docker/build-push-action@v6
with:
context: .
platforms: linux/amd64,linux/arm64

View File

@@ -22,7 +22,7 @@ jobs:
bash helper-scripts/update_postscreen_whitelist.sh
- name: Create Pull Request
uses: peter-evans/create-pull-request@v5
uses: peter-evans/create-pull-request@v6
with:
token: ${{ secrets.mailcow_action_Update_postscreen_access_cidr_pat }}
commit-message: update postscreen_access.cidr

1
.gitignore vendored
View File

@@ -13,6 +13,7 @@ data/conf/dovecot/acl_anyone
data/conf/dovecot/dovecot-master.passwd
data/conf/dovecot/dovecot-master.userdb
data/conf/dovecot/extra.conf
data/conf/dovecot/mail_replica.conf
data/conf/dovecot/global_sieve_*
data/conf/dovecot/last_login
data/conf/dovecot/lua

View File

@@ -1,7 +1,8 @@
FROM alpine:3.17
FROM alpine:3.20
LABEL maintainer "The Infrastructure Company GmbH <info@servercow.de>"
RUN apk upgrade --no-cache \
&& apk add --update --no-cache \
bash \
@@ -14,9 +15,7 @@ RUN apk upgrade --no-cache \
tini \
tzdata \
python3 \
py3-pip \
&& pip3 install --upgrade pip \
&& pip3 install acme-tiny
acme-tiny --repository=http://dl-cdn.alpinelinux.org/alpine/edge/community/
COPY acme.sh /srv/acme.sh
COPY functions.sh /srv/functions.sh

View File

@@ -33,6 +33,10 @@ if [[ "${ONLY_MAILCOW_HOSTNAME}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
ONLY_MAILCOW_HOSTNAME=y
fi
if [[ "${AUTODISCOVER_SAN}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
AUTODISCOVER_SAN=y
fi
# Request individual certificate for every domain
if [[ "${ENABLE_SSL_SNI}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
ENABLE_SSL_SNI=y
@@ -211,7 +215,11 @@ while true; do
ADDITIONAL_SAN_ARR+=($i)
fi
done
if [[ ${AUTODISCOVER_SAN} == "y" ]]; then
# Fetch certs for autoconfig and autodiscover subdomains
ADDITIONAL_WC_ARR+=('autodiscover' 'autoconfig')
fi
if [[ ${SKIP_IP_CHECK} != "y" ]]; then
# Start IP detection

View File

@@ -1,3 +1,3 @@
FROM debian:bullseye-slim
FROM debian:bookworm-slim
RUN apt update && apt install pigz

View File

@@ -1,12 +1,14 @@
FROM clamav/clamav:1.0.3_base
FROM alpine:3.20
LABEL maintainer "The Infrastructure Company GmbH <info@servercow.de>"
RUN apk upgrade --no-cache \
&& apk add --update --no-cache \
rsync \
clamav \
bind-tools \
bash
bash \
tini
# init
COPY clamd.sh /clamd.sh
@@ -14,7 +16,9 @@ RUN chmod +x /sbin/tini
# healthcheck
COPY healthcheck.sh /healthcheck.sh
COPY clamdcheck.sh /usr/local/bin
RUN chmod +x /healthcheck.sh
RUN chmod +x /usr/local/bin/clamdcheck.sh
HEALTHCHECK --start-period=6m CMD "/healthcheck.sh"
ENTRYPOINT []

View File

@@ -0,0 +1,14 @@
#!/bin/sh
set -eu
if [ "${CLAMAV_NO_CLAMD:-}" != "false" ]; then
if [ "$(echo "PING" | nc localhost 3310)" != "PONG" ]; then
echo "ERROR: Unable to contact server"
exit 1
fi
echo "Clamd is up"
fi
exit 0

View File

@@ -1,7 +1,8 @@
FROM alpine:3.17
FROM alpine:3.20
LABEL maintainer "The Infrastructure Company GmbH <info@servercow.de>"
ARG PIP_BREAK_SYSTEM_PACKAGES=1
WORKDIR /app
RUN apk add --update --no-cache python3 \
@@ -9,12 +10,13 @@ RUN apk add --update --no-cache python3 \
openssl \
tzdata \
py3-psutil \
py3-redis \
py3-async-timeout \
&& pip3 install --upgrade pip \
fastapi \
uvicorn \
aiodocker \
docker \
aioredis
docker
RUN mkdir /app/modules
COPY docker-entrypoint.sh /app/

View File

@@ -5,16 +5,63 @@ import json
import uuid
import async_timeout
import asyncio
import aioredis
import aiodocker
import docker
import logging
from logging.config import dictConfig
from fastapi import FastAPI, Response, Request
from modules.DockerApi import DockerApi
from redis import asyncio as aioredis
from contextlib import asynccontextmanager
dockerapi = None
app = FastAPI()
@asynccontextmanager
async def lifespan(app: FastAPI):
global dockerapi
# Initialize a custom logger
logger = logging.getLogger("dockerapi")
logger.setLevel(logging.INFO)
# Configure the logger to output logs to the terminal
handler = logging.StreamHandler()
handler.setLevel(logging.INFO)
formatter = logging.Formatter("%(levelname)s: %(message)s")
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.info("Init APP")
# Init redis client
if os.environ['REDIS_SLAVEOF_IP'] != "":
redis_client = redis = await aioredis.from_url(f"redis://{os.environ['REDIS_SLAVEOF_IP']}:{os.environ['REDIS_SLAVEOF_PORT']}/0")
else:
redis_client = redis = await aioredis.from_url("redis://redis-mailcow:6379/0")
# Init docker clients
sync_docker_client = docker.DockerClient(base_url='unix://var/run/docker.sock', version='auto')
async_docker_client = aiodocker.Docker(url='unix:///var/run/docker.sock')
dockerapi = DockerApi(redis_client, sync_docker_client, async_docker_client, logger)
logger.info("Subscribe to redis channel")
# Subscribe to redis channel
dockerapi.pubsub = redis.pubsub()
await dockerapi.pubsub.subscribe("MC_CHANNEL")
asyncio.create_task(handle_pubsub_messages(dockerapi.pubsub))
yield
# Close docker connections
dockerapi.sync_docker_client.close()
await dockerapi.async_docker_client.close()
# Close redis
await dockerapi.pubsub.unsubscribe("MC_CHANNEL")
await dockerapi.redis_client.close()
app = FastAPI(lifespan=lifespan)
# Define Routes
@app.get("/host/stats")
@@ -144,53 +191,7 @@ async def post_container_update_stats(container_id : str):
stats = json.loads(await dockerapi.redis_client.get(container_id + '_stats'))
return Response(content=json.dumps(stats, indent=4), media_type="application/json")
# Events
@app.on_event("startup")
async def startup_event():
global dockerapi
# Initialize a custom logger
logger = logging.getLogger("dockerapi")
logger.setLevel(logging.INFO)
# Configure the logger to output logs to the terminal
handler = logging.StreamHandler()
handler.setLevel(logging.INFO)
formatter = logging.Formatter("%(levelname)s: %(message)s")
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.info("Init APP")
# Init redis client
if os.environ['REDIS_SLAVEOF_IP'] != "":
redis_client = redis = await aioredis.from_url(f"redis://{os.environ['REDIS_SLAVEOF_IP']}:{os.environ['REDIS_SLAVEOF_PORT']}/0")
else:
redis_client = redis = await aioredis.from_url("redis://redis-mailcow:6379/0")
# Init docker clients
sync_docker_client = docker.DockerClient(base_url='unix://var/run/docker.sock', version='auto')
async_docker_client = aiodocker.Docker(url='unix:///var/run/docker.sock')
dockerapi = DockerApi(redis_client, sync_docker_client, async_docker_client, logger)
logger.info("Subscribe to redis channel")
# Subscribe to redis channel
dockerapi.pubsub = redis.pubsub()
await dockerapi.pubsub.subscribe("MC_CHANNEL")
asyncio.create_task(handle_pubsub_messages(dockerapi.pubsub))
@app.on_event("shutdown")
async def shutdown_event():
global dockerapi
# Close docker connections
dockerapi.sync_docker_client.close()
await dockerapi.async_docker_client.close()
# Close redis
await dockerapi.pubsub.unsubscribe("MC_CHANNEL")
await dockerapi.redis_client.close()
# PubSub Handler
async def handle_pubsub_messages(channel: aioredis.client.PubSub):

View File

@@ -358,8 +358,8 @@ class DockerApi:
for line in cmd_response.split("\n"):
if '$2$' in line:
hash = line.strip()
hash_out = re.search('\$2\$.+$', hash).group(0)
rspamd_passphrase_hash = re.sub('[^0-9a-zA-Z\$]+', '', hash_out.rstrip())
hash_out = re.search(r'\$2\$.+$', hash).group(0)
rspamd_passphrase_hash = re.sub(r'[^0-9a-zA-Z\$]+', '', hash_out.rstrip())
rspamd_password_filename = "/etc/rspamd/override.d/worker-controller-password.inc"
cmd = '''/bin/echo 'enable_password = "%s";' > %s && cat %s''' % (rspamd_passphrase_hash, rspamd_password_filename, rspamd_password_filename)
cmd_response = self.exec_cmd_container(container, cmd, user="_rspamd")

View File

@@ -1,119 +1,115 @@
FROM debian:bullseye-slim
FROM alpine:3.20
LABEL maintainer "The Infrastructure Company GmbH <info@servercow.de>"
ARG DEBIAN_FRONTEND=noninteractive
# renovate: datasource=github-tags depName=dovecot/core versioning=semver-coerced extractVersion=(?<version>.*)$
ARG DOVECOT=2.3.21
# renovate: datasource=github-releases depName=tianon/gosu versioning=semver-coerced extractVersion=(?<version>.*)$
# renovate: datasource=github-releases depName=tianon/gosu versioning=semver-coerced extractVersion=^(?<version>.*)$
ARG GOSU_VERSION=1.16
ENV LC_ALL C
ENV LANG C.UTF-8
ENV LC_ALL C.UTF-8
# Add groups and users before installing Dovecot to not break compatibility
RUN groupadd -g 5000 vmail \
&& groupadd -g 401 dovecot \
&& groupadd -g 402 dovenull \
&& groupadd -g 999 sogo \
&& usermod -a -G sogo nobody \
&& useradd -g vmail -u 5000 vmail -d /var/vmail \
&& useradd -c "Dovecot unprivileged user" -d /dev/null -u 401 -g dovecot -s /bin/false dovecot \
&& useradd -c "Dovecot login user" -d /dev/null -u 402 -g dovenull -s /bin/false dovenull \
&& touch /etc/default/locale \
&& apt-get update \
&& apt-get -y --no-install-recommends install \
build-essential \
apt-transport-https \
RUN addgroup -g 5000 vmail \
&& addgroup -g 401 dovecot \
&& addgroup -g 402 dovenull \
&& sed -i "s/999/99/" /etc/group \
&& addgroup -g 999 sogo \
&& addgroup nobody sogo \
&& adduser -D -u 5000 -G vmail -h /var/vmail vmail \
&& adduser -D -G dovecot -u 401 -h /dev/null -s /sbin/nologin dovecot \
&& adduser -D -G dovenull -u 402 -h /dev/null -s /sbin/nologin dovenull \
&& apk add --no-cache --update \
bash \
bind-tools \
findutils \
envsubst \
ca-certificates \
cpanminus \
curl \
dnsutils \
dirmngr \
gettext \
gnupg2 \
coreutils \
jq \
libauthen-ntlm-perl \
libcgi-pm-perl \
libcrypt-openssl-rsa-perl \
libcrypt-ssleay-perl \
libdata-uniqid-perl \
libdbd-mysql-perl \
libdbi-perl \
libdigest-hmac-perl \
libdist-checkconflicts-perl \
libencode-imaputf7-perl \
libfile-copy-recursive-perl \
libfile-tail-perl \
libhtml-parser-perl \
libio-compress-perl \
libio-socket-inet6-perl \
libio-socket-ssl-perl \
libio-tee-perl \
libipc-run-perl \
libjson-webtoken-perl \
liblockfile-simple-perl \
libmail-imapclient-perl \
libmodule-implementation-perl \
libmodule-scandeps-perl \
libnet-ssleay-perl \
libpackage-stash-perl \
libpackage-stash-xs-perl \
libpar-packer-perl \
libparse-recdescent-perl \
libproc-processtable-perl \
libreadonly-perl \
libregexp-common-perl \
libssl-dev \
libsys-meminfo-perl \
libterm-readkey-perl \
libtest-deep-perl \
libtest-fatal-perl \
libtest-mock-guard-perl \
libtest-mockobject-perl \
libtest-nowarnings-perl \
libtest-pod-perl \
libtest-requires-perl \
libtest-simple-perl \
libtest-warn-perl \
libtry-tiny-perl \
libunicode-string-perl \
liburi-perl \
libwww-perl \
lua-sql-mysql \
lua \
lua-cjson \
lua-socket \
lua-sql-mysql \
lua5.3-sql-mysql \
icu-data-full \
mariadb-connector-c \
gcompat \
mariadb-client \
perl \
perl-ntlm \
perl-cgi \
perl-crypt-openssl-rsa \
perl-utils \
perl-crypt-ssleay \
perl-data-uniqid \
perl-dbd-mysql \
perl-dbi \
perl-digest-hmac \
perl-dist-checkconflicts \
perl-encode-imaputf7 \
perl-file-copy-recursive \
perl-file-tail \
perl-io-socket-inet6 \
perl-io-gzip \
perl-io-socket-ssl \
perl-io-tee \
perl-ipc-run \
perl-json-webtoken \
perl-mail-imapclient \
perl-module-implementation \
perl-module-scandeps \
perl-net-ssleay \
perl-package-stash \
perl-package-stash-xs \
perl-par-packer \
perl-parse-recdescent \
perl-lockfile-simple \
libproc \
perl-readonly \
perl-regexp-common \
perl-sys-meminfo \
perl-term-readkey \
perl-test-deep \
perl-test-fatal \
perl-test-mockobject \
perl-test-mock-guard \
perl-test-pod \
perl-test-requires \
perl-test-simple \
perl-test-warn \
perl-try-tiny \
perl-unicode-string \
perl-proc-processtable \
perl-app-cpanminus \
procps \
python3-pip \
redis-server \
supervisor \
python3 \
py3-mysqlclient \
py3-html2text \
py3-jinja2 \
py3-redis \
redis \
syslog-ng \
syslog-ng-core \
syslog-ng-mod-redis \
syslog-ng-redis \
syslog-ng-json \
supervisor \
tzdata \
wget \
&& dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')" \
&& wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch" \
&& chmod +x /usr/local/bin/gosu \
&& gosu nobody true \
&& apt-key adv --fetch-keys https://repo.dovecot.org/DOVECOT-REPO-GPG \
&& echo "deb https://repo.dovecot.org/ce-${DOVECOT}/debian/bullseye bullseye main" > /etc/apt/sources.list.d/dovecot.list \
&& apt-get update \
&& apt-get -y --no-install-recommends install \
dovecot-lua \
dovecot-managesieved \
dovecot-sieve \
dovecot \
dovecot-dev \
dovecot-lmtpd \
dovecot-lua \
dovecot-ldap \
dovecot-mysql \
dovecot-core \
dovecot-sql \
dovecot-submissiond \
dovecot-pigeonhole-plugin \
dovecot-pop3d \
dovecot-imapd \
dovecot-solr \
&& pip3 install mysql-connector-python html2text jinja2 redis \
&& apt-get autoremove --purge -y \
&& apt-get autoclean \
&& rm -rf /var/lib/apt/lists/* \
&& rm -rf /tmp/* /var/tmp/* /root/.cache/
# imapsync dependencies
RUN cpan Crypt::OpenSSL::PKCS12
dovecot-fts-solr \
dovecot-fts-flatcurve \
&& arch=$(arch | sed s/aarch64/arm64/ | sed s/x86_64/amd64/) \
&& wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$arch" \
&& chmod +x /usr/local/bin/gosu \
&& gosu nobody true
COPY trim_logs.sh /usr/local/bin/trim_logs.sh
COPY clean_q_aged.sh /usr/local/bin/clean_q_aged.sh
@@ -133,6 +129,7 @@ COPY stop-supervisor.sh /usr/local/sbin/stop-supervisor.sh
COPY quarantine_notify.py /usr/local/bin/quarantine_notify.py
COPY quota_notify.py /usr/local/bin/quota_notify.py
COPY repl_health.sh /usr/local/bin/repl_health.sh
COPY optimize-fts.sh /usr/local/bin/optimize-fts.sh
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD exec /usr/bin/supervisord -c /etc/supervisor/supervisord.conf

View File

@@ -29,6 +29,7 @@ ${REDIS_CMDLINE} SET DOVECOT_REPL_HEALTH 1 > /dev/null
# Create missing directories
[[ ! -d /etc/dovecot/sql/ ]] && mkdir -p /etc/dovecot/sql/
[[ ! -d /etc/dovecot/lua/ ]] && mkdir -p /etc/dovecot/lua/
[[ ! -d /etc/dovecot/conf.d/ ]] && mkdir -p /etc/dovecot/conf.d/
[[ ! -d /var/vmail/_garbage ]] && mkdir -p /var/vmail/_garbage
[[ ! -d /var/vmail/sieve ]] && mkdir -p /var/vmail/sieve
[[ ! -d /etc/sogo ]] && mkdir -p /etc/sogo
@@ -109,7 +110,14 @@ EOF
echo -n ${ACL_ANYONE} > /etc/dovecot/acl_anyone
if [[ "${SKIP_SOLR}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
if [[ "${FLATCURVE_EXPERIMENTAL}" =~ ^([yY][eE][sS]|[yY]) ]]; then
echo -e "\e[33mActivating Flatcurve as FTS Backend...\e[0m"
echo -e "\e[33mDepending on your previous setup a full reindex might be needed... \e[0m"
echo -e "\e[34mVisit https://docs.mailcow.email/manual-guides/Dovecot/u_e-dovecot-fts/#fts-related-dovecot-commands to learn how to reindex\e[0m"
echo -n 'quota acl zlib mail_crypt mail_crypt_acl mail_log notify fts fts_flatcurve listescape replication' > /etc/dovecot/mail_plugins
echo -n 'quota imap_quota imap_acl acl zlib imap_zlib imap_sieve mail_crypt mail_crypt_acl notify mail_log fts fts_flatcurve listescape replication' > /etc/dovecot/mail_plugins_imap
echo -n 'quota sieve acl zlib mail_crypt mail_crypt_acl fts fts_flatcurve notify listescape replication' > /etc/dovecot/mail_plugins_lmtp
elif [[ "${SKIP_SOLR}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
echo -n 'quota acl zlib mail_crypt mail_crypt_acl mail_log notify listescape replication' > /etc/dovecot/mail_plugins
echo -n 'quota imap_quota imap_acl acl zlib imap_zlib imap_sieve mail_crypt mail_crypt_acl notify listescape replication mail_log' > /etc/dovecot/mail_plugins_imap
echo -n 'quota sieve acl zlib mail_crypt mail_crypt_acl notify listescape replication' > /etc/dovecot/mail_plugins_lmtp
@@ -239,6 +247,47 @@ function script_deinit()
end
EOF
# Temporarily set FTS depending on user choice inside mailcow.conf. Will be removed as soon as Solr is dropped
if [[ "${FLATCURVE_EXPERIMENTAL}" =~ ^([yY][eE][sS]|[yY])$ ]]; then
cat <<EOF > /etc/dovecot/conf.d/fts.conf
# Autogenerated by mailcow
plugin {
fts_autoindex = yes
fts_autoindex_exclude = \Junk
fts_autoindex_exclude2 = \Trash
fts = flatcurve
# These are not flatcurve settings, but required for Dovecot FTS. See
# Dovecot FTS Configuration link above for further information.
fts_languages = en es de
fts_tokenizer_generic = algorithm=simple
fts_tokenizers = generic email-address
# OPTIONAL: Recommended default FTS core configuration
fts_filters = normalizer-icu snowball stopwords
fts_filters_en = lowercase snowball english-possessive stopwords
}
EOF
elif [[ ! "${SKIP_SOLR}" =~ ^([yY][eE][sS]|[yY])$ ]]; then
cat <<EOF > /etc/dovecot/conf.d/fts.conf
# Autogenerated by mailcow
plugin {
fts = solr
fts_autoindex = yes
fts_autoindex_exclude = \Junk
fts_autoindex_exclude2 = \Trash
fts_solr = url=http://solr:8983/solr/dovecot-fts/
fts_tokenizers = generic email-address
fts_tokenizer_generic = algorithm=simple
fts_filters = normalizer-icu snowball stopwords
fts_filters_en = lowercase snowball english-possessive stopwords
}
EOF
fi
# Replace patterns in app-passdb.lua
sed -i "s/__DBUSER__/${DBUSER}/g" /etc/dovecot/lua/passwd-verify.lua
sed -i "s/__DBPASS__/${DBPASS}/g" /etc/dovecot/lua/passwd-verify.lua
@@ -335,6 +384,14 @@ sys.exit()
EOF
fi
# Set mail_replica for HA setups
if [[ -n ${MAILCOW_REPLICA_IP} && -n ${DOVEADM_REPLICA_PORT} ]]; then
cat <<EOF > /etc/dovecot/mail_replica.conf
# Autogenerated by mailcow
mail_replica = tcp:${MAILCOW_REPLICA_IP}:${DOVEADM_REPLICA_PORT}
EOF
fi
# 401 is user dovecot
if [[ ! -s /mail_crypt/ecprivkey.pem || ! -s /mail_crypt/ecpubkey.pem ]]; then
openssl ecparam -name prime256v1 -genkey | openssl pkey -out /mail_crypt/ecprivkey.pem
@@ -378,7 +435,8 @@ chmod +x /usr/lib/dovecot/sieve/rspamd-pipe-ham \
/usr/local/bin/maildir_gc.sh \
/usr/local/sbin/stop-supervisor.sh \
/usr/local/bin/quota_notify.py \
/usr/local/bin/repl_health.sh
/usr/local/bin/repl_health.sh \
/usr/local/bin/optimize-fts.sh
# Prepare environment file for cronjobs
printenv | sed 's/^\(.*\)$/export \1/g' > /source_env.sh
@@ -432,4 +490,8 @@ done
# May be related to something inside Docker, I seriously don't know
touch /etc/dovecot/lua/passwd-verify.lua
if [[ ! -z ${REDIS_SLAVEOF_IP} ]]; then
cp /etc/syslog-ng/syslog-ng-redis_slave.conf /etc/syslog-ng/syslog-ng.conf
fi
exec "$@"

View File

@@ -0,0 +1,7 @@
#!/bin/bash
if [[ "${SKIP_SOLR}" =~ ^([yY][eE][sS]|[yY])+$ && ! "${FLATCURVE_EXPERIMENTAL}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
exit 0
else
doveadm fts optimize -A
fi

View File

@@ -3,11 +3,10 @@
import smtplib
import os
import sys
import mysql.connector
import MySQLdb
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.utils import COMMASPACE, formatdate
import cgi
import jinja2
from jinja2 import Template
import json
@@ -50,7 +49,7 @@ try:
def query_mysql(query, headers = True, update = False):
while True:
try:
cnx = mysql.connector.connect(unix_socket = '/var/run/mysqld/mysqld.sock', user=os.environ.get('DBUSER'), passwd=os.environ.get('DBPASS'), database=os.environ.get('DBNAME'), charset="utf8mb4", collation="utf8mb4_general_ci")
cnx = MySQLdb.connect(user=os.environ.get('DBUSER'), password=os.environ.get('DBPASS'), database=os.environ.get('DBNAME'), charset="utf8mb4", collation="utf8mb4_general_ci")
except Exception as ex:
print('%s - trying again...' % (ex))
time.sleep(3)

View File

@@ -55,7 +55,7 @@ try:
msg.attach(text_part)
msg.attach(html_part)
msg['To'] = username
p = Popen(['/usr/lib/dovecot/dovecot-lda', '-d', username, '-o', '"plugin/quota=maildir:User quota:noenforcing"'], stdout=PIPE, stdin=PIPE, stderr=STDOUT)
p = Popen(['/usr/libexec/dovecot/dovecot-lda', '-d', username, '-o', '"plugin/quota=maildir:User quota:noenforcing"'], stdout=PIPE, stdin=PIPE, stderr=STDOUT)
p.communicate(input=bytes(msg.as_string(), 'utf-8'))
domain = username.split("@")[-1]

View File

@@ -11,7 +11,7 @@ fi
# Is replication active?
# grep on file is less expensive than doveconf
if ! grep -qi mail_replica /etc/dovecot/dovecot.conf; then
if [ -n ${MAILCOW_REPLICA_IP} ]; then
${REDIS_CMDLINE} SET DOVECOT_REPL_HEALTH 1 > /dev/null
exit
fi

View File

@@ -11,7 +11,7 @@ else
fi
# Deploy
curl --connect-timeout 15 --retry 10 --max-time 30 http://www.spamassassin.heinlein-support.de/$(dig txt 1.4.3.spamassassin.heinlein-support.de +short | tr -d '"' | tr -dc '0-9').tar.gz --output /tmp/sa-rules-heinlein.tar.gz
curl --connect-timeout 15 --retry 10 --max-time 30 https://www.spamassassin.heinlein-support.de/$(dig txt 1.4.3.spamassassin.heinlein-support.de +short | tr -d '"' | tr -dc '0-9').tar.gz --output /tmp/sa-rules-heinlein.tar.gz
if gzip -t /tmp/sa-rules-heinlein.tar.gz; then
tar xfvz /tmp/sa-rules-heinlein.tar.gz -C /tmp/sa-rules-heinlein
cat /tmp/sa-rules-heinlein/*cf > /etc/rspamd/custom/sa-rules

View File

@@ -13,6 +13,10 @@ autostart=true
[program:dovecot]
command=/usr/sbin/dovecot -F
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
autorestart=true
[eventlistener:processes]

View File

@@ -1,4 +1,4 @@
@version: 3.28
@version: 4.5
@include "scl.conf"
options {
chain_hostnames(off);
@@ -6,11 +6,12 @@ options {
use_dns(no);
use_fqdn(no);
owner("root"); group("adm"); perm(0640);
stats_freq(0);
stats(freq(0));
keep_timestamp(no);
bad_hostname("^gconfd$");
};
source s_src {
unix-stream("/dev/log");
source s_dgram {
unix-dgram("/dev/log");
internal();
};
destination d_stdout { pipe("/dev/stdout"); };
@@ -36,7 +37,7 @@ filter f_replica {
not match("Error: sync: Unknown user in remote" value("MESSAGE"));
};
log {
source(s_src);
source(s_dgram);
filter(f_replica);
destination(d_stdout);
filter(f_mail);

View File

@@ -1,4 +1,4 @@
@version: 3.28
@version: 4.5
@include "scl.conf"
options {
chain_hostnames(off);
@@ -6,11 +6,12 @@ options {
use_dns(no);
use_fqdn(no);
owner("root"); group("adm"); perm(0640);
stats_freq(0);
stats(freq(0));
keep_timestamp(no);
bad_hostname("^gconfd$");
};
source s_src {
unix-stream("/dev/log");
source s_dgram {
unix-dgram("/dev/log");
internal();
};
destination d_stdout { pipe("/dev/stdout"); };
@@ -36,7 +37,7 @@ filter f_replica {
not match("Error: sync: Unknown user in remote" value("MESSAGE"));
};
log {
source(s_src);
source(s_dgram);
filter(f_replica);
destination(d_stdout);
filter(f_mail);

View File

@@ -1,8 +1,9 @@
FROM alpine:3.17
FROM alpine:3.20
LABEL maintainer "The Infrastructure Company GmbH <info@servercow.de>"
WORKDIR /app
ARG PIP_BREAK_SYSTEM_PACKAGES=1
ENV XTABLES_LIBDIR /usr/lib/xtables
ENV PYTHON_IPTABLES_XTABLES_VERSION 12
ENV IPTABLES_LIBDIR /usr/lib
@@ -14,6 +15,7 @@ RUN apk add --virtual .build-deps \
openssl-dev \
&& apk add -U python3 \
iptables \
iptables-dev \
ip6tables \
xtables-addons \
nftables \

View File

@@ -21,28 +21,6 @@ from modules.IPTables import IPTables
from modules.NFTables import NFTables
# connect to redis
while True:
try:
redis_slaveof_ip = os.getenv('REDIS_SLAVEOF_IP', '')
redis_slaveof_port = os.getenv('REDIS_SLAVEOF_PORT', '')
if "".__eq__(redis_slaveof_ip):
r = redis.StrictRedis(host=os.getenv('IPV4_NETWORK', '172.22.1') + '.249', decode_responses=True, port=6379, db=0)
else:
r = redis.StrictRedis(host=redis_slaveof_ip, decode_responses=True, port=redis_slaveof_port, db=0)
r.ping()
except Exception as ex:
print('%s - trying again in 3 seconds' % (ex))
time.sleep(3)
else:
break
pubsub = r.pubsub()
# rename fail2ban to netfilter
if r.exists('F2B_LOG'):
r.rename('F2B_LOG', 'NETFILTER_LOG')
# globals
WHITELIST = []
BLACKLIST= []
@@ -50,18 +28,10 @@ bans = {}
quit_now = False
exit_code = 0
lock = Lock()
# init Logger
logger = Logger(r)
# init backend
backend = sys.argv[1]
if backend == "nftables":
logger.logInfo('Using NFTables backend')
tables = NFTables("MAILCOW", logger)
else:
logger.logInfo('Using IPTables backend')
tables = IPTables("MAILCOW", logger)
chain_name = "MAILCOW"
r = None
pubsub = None
clear_before_quit = False
def refreshF2boptions():
@@ -110,16 +80,16 @@ def refreshF2bregex():
global exit_code
if not r.get('F2B_REGEX'):
f2bregex = {}
f2bregex[1] = 'mailcow UI: Invalid password for .+ by ([0-9a-f\.:]+)'
f2bregex[2] = 'Rspamd UI: Invalid password by ([0-9a-f\.:]+)'
f2bregex[3] = 'warning: .*\[([0-9a-f\.:]+)\]: SASL .+ authentication failed: (?!.*Connection lost to authentication server).+'
f2bregex[4] = 'warning: non-SMTP command from .*\[([0-9a-f\.:]+)]:.+'
f2bregex[5] = 'NOQUEUE: reject: RCPT from \[([0-9a-f\.:]+)].+Protocol error.+'
f2bregex[6] = '-login: Disconnected.+ \(auth failed, .+\): user=.*, method=.+, rip=([0-9a-f\.:]+),'
f2bregex[7] = '-login: Aborted login.+ \(auth failed .+\): user=.+, rip=([0-9a-f\.:]+), lip.+'
f2bregex[8] = '-login: Aborted login.+ \(tried to use disallowed .+\): user=.+, rip=([0-9a-f\.:]+), lip.+'
f2bregex[9] = 'SOGo.+ Login from \'([0-9a-f\.:]+)\' for user .+ might not have worked'
f2bregex[10] = '([0-9a-f\.:]+) \"GET \/SOGo\/.* HTTP.+\" 403 .+'
f2bregex[1] = r'mailcow UI: Invalid password for .+ by ([0-9a-f\.:]+)'
f2bregex[2] = r'Rspamd UI: Invalid password by ([0-9a-f\.:]+)'
f2bregex[3] = r'warning: .*\[([0-9a-f\.:]+)\]: SASL .+ authentication failed: (?!.*Connection lost to authentication server).+'
f2bregex[4] = r'warning: non-SMTP command from .*\[([0-9a-f\.:]+)]:.+'
f2bregex[5] = r'NOQUEUE: reject: RCPT from \[([0-9a-f\.:]+)].+Protocol error.+'
f2bregex[6] = r'-login: Disconnected.+ \(auth failed, .+\): user=.*, method=.+, rip=([0-9a-f\.:]+),'
f2bregex[7] = r'-login: Aborted login.+ \(auth failed .+\): user=.+, rip=([0-9a-f\.:]+), lip.+'
f2bregex[8] = r'-login: Aborted login.+ \(tried to use disallowed .+\): user=.+, rip=([0-9a-f\.:]+), lip.+'
f2bregex[9] = r'SOGo.+ Login from \'([0-9a-f\.:]+)\' for user .+ might not have worked'
f2bregex[10] = r'([0-9a-f\.:]+) \"GET \/SOGo\/.* HTTP.+\" 403 .+'
r.set('F2B_REGEX', json.dumps(f2bregex, ensure_ascii=False))
else:
try:
@@ -144,8 +114,6 @@ def ban(address):
global lock
refreshF2boptions()
BAN_TIME = int(f2boptions['ban_time'])
BAN_TIME_INCREMENT = bool(f2boptions['ban_time_increment'])
MAX_ATTEMPTS = int(f2boptions['max_attempts'])
RETRY_WINDOW = int(f2boptions['retry_window'])
NETBAN_IPV4 = '/' + str(f2boptions['netban_ipv4'])
@@ -180,7 +148,7 @@ def ban(address):
if bans[net]['attempts'] >= MAX_ATTEMPTS:
cur_time = int(round(time.time()))
NET_BAN_TIME = BAN_TIME if not BAN_TIME_INCREMENT else BAN_TIME * 2 ** bans[net]['ban_counter']
NET_BAN_TIME = calcNetBanTime(bans[net]['ban_counter'])
logger.logCrit('Banning %s for %d minutes' % (net, NET_BAN_TIME / 60 ))
if type(ip) is ipaddress.IPv4Address and int(f2boptions['manage_external']) != 1:
with lock:
@@ -250,17 +218,21 @@ def clear():
with lock:
tables.clearIPv4Table()
tables.clearIPv6Table()
r.delete('F2B_ACTIVE_BANS')
r.delete('F2B_PERM_BANS')
pubsub.unsubscribe()
try:
if r is not None:
r.delete('F2B_ACTIVE_BANS')
r.delete('F2B_PERM_BANS')
except Exception as ex:
logger.logWarn('Error clearing redis keys F2B_ACTIVE_BANS and F2B_PERM_BANS: %s' % ex)
def watch():
logger.logInfo('Watching Redis channel F2B_CHANNEL')
pubsub.subscribe('F2B_CHANNEL')
global pubsub
global quit_now
global exit_code
logger.logInfo('Watching Redis channel F2B_CHANNEL')
pubsub.subscribe('F2B_CHANNEL')
while not quit_now:
try:
for item in pubsub.listen():
@@ -280,6 +252,7 @@ def watch():
ban(addr)
except Exception as ex:
logger.logWarn('Error reading log line from pubsub: %s' % ex)
pubsub = None
quit_now = True
exit_code = 2
@@ -302,12 +275,11 @@ def snat6(snat_target):
tables.snat6(snat_target, os.getenv('IPV6_NETWORK', 'fd4d:6169:6c63:6f77::/64'))
def autopurge():
global f2boptions
while not quit_now:
time.sleep(10)
refreshF2boptions()
BAN_TIME = int(f2boptions['ban_time'])
MAX_BAN_TIME = int(f2boptions['max_ban_time'])
BAN_TIME_INCREMENT = bool(f2boptions['ban_time_increment'])
MAX_ATTEMPTS = int(f2boptions['max_attempts'])
QUEUE_UNBAN = r.hgetall('F2B_QUEUE_UNBAN')
if QUEUE_UNBAN:
@@ -315,9 +287,9 @@ def autopurge():
unban(str(net))
for net in bans.copy():
if bans[net]['attempts'] >= MAX_ATTEMPTS:
NET_BAN_TIME = BAN_TIME if not BAN_TIME_INCREMENT else BAN_TIME * 2 ** bans[net]['ban_counter']
NET_BAN_TIME = calcNetBanTime(bans[net]['ban_counter'])
TIME_SINCE_LAST_ATTEMPT = time.time() - bans[net]['last_attempt']
if TIME_SINCE_LAST_ATTEMPT > NET_BAN_TIME or TIME_SINCE_LAST_ATTEMPT > MAX_BAN_TIME:
if TIME_SINCE_LAST_ATTEMPT > NET_BAN_TIME:
unban(net)
def mailcowChainOrder():
@@ -331,6 +303,16 @@ def mailcowChainOrder():
if quit_now: return
quit_now, exit_code = tables.checkIPv6ChainOrder()
def calcNetBanTime(ban_counter):
global f2boptions
BAN_TIME = int(f2boptions['ban_time'])
MAX_BAN_TIME = int(f2boptions['max_ban_time'])
BAN_TIME_INCREMENT = bool(f2boptions['ban_time_increment'])
NET_BAN_TIME = BAN_TIME if not BAN_TIME_INCREMENT else BAN_TIME * 2 ** ban_counter
NET_BAN_TIME = max([BAN_TIME, min([NET_BAN_TIME, MAX_BAN_TIME])])
return NET_BAN_TIME
def isIpNetwork(address):
try:
ipaddress.ip_network(address, False)
@@ -403,21 +385,76 @@ def blacklistUpdate():
permBan(net=net, unban=True)
time.sleep(60.0 - ((time.time() - start_time) % 60.0))
def quit(signum, frame):
global quit_now
quit_now = True
def sigterm_quit(signum, frame):
global clear_before_quit
clear_before_quit = True
sys.exit(exit_code)
def berfore_quit():
if clear_before_quit:
clear()
if pubsub is not None:
pubsub.unsubscribe()
if __name__ == '__main__':
refreshF2boptions()
atexit.register(berfore_quit)
signal.signal(signal.SIGTERM, sigterm_quit)
# init Logger
logger = Logger()
# init backend
backend = sys.argv[1]
if backend == "nftables":
logger.logInfo('Using NFTables backend')
tables = NFTables(chain_name, logger)
else:
logger.logInfo('Using IPTables backend')
tables = IPTables(chain_name, logger)
# In case a previous session was killed without cleanup
clear()
# Reinit MAILCOW chain
# Is called before threads start, no locking
logger.logInfo("Initializing mailcow netfilter chain")
tables.initChainIPv4()
tables.initChainIPv6()
if os.getenv("DISABLE_NETFILTER_ISOLATION_RULE").lower() in ("y", "yes"):
logger.logInfo(f"Skipping {chain_name} isolation")
else:
logger.logInfo(f"Setting {chain_name} isolation")
tables.create_mailcow_isolation_rule("br-mailcow", [3306, 6379, 8983, 12345], os.getenv("MAILCOW_REPLICA_IP"))
# connect to redis
while True:
try:
redis_slaveof_ip = os.getenv('REDIS_SLAVEOF_IP', '')
redis_slaveof_port = os.getenv('REDIS_SLAVEOF_PORT', '')
if "".__eq__(redis_slaveof_ip):
r = redis.StrictRedis(host=os.getenv('IPV4_NETWORK', '172.22.1') + '.249', decode_responses=True, port=6379, db=0)
else:
r = redis.StrictRedis(host=redis_slaveof_ip, decode_responses=True, port=redis_slaveof_port, db=0)
r.ping()
pubsub = r.pubsub()
except Exception as ex:
print('%s - trying again in 3 seconds' % (ex))
time.sleep(3)
else:
break
logger.set_redis(r)
# rename fail2ban to netfilter
if r.exists('F2B_LOG'):
r.rename('F2B_LOG', 'NETFILTER_LOG')
# clear bans in redis
r.delete('F2B_ACTIVE_BANS')
r.delete('F2B_PERM_BANS')
refreshF2boptions()
watch_thread = Thread(target=watch)
watch_thread.daemon = True
watch_thread.start()
@@ -460,9 +497,6 @@ if __name__ == '__main__':
whitelistupdate_thread.daemon = True
whitelistupdate_thread.start()
signal.signal(signal.SIGTERM, quit)
atexit.register(clear)
while not quit_now:
time.sleep(0.5)

View File

@@ -1,5 +1,6 @@
import iptc
import time
import os
class IPTables:
def __init__(self, chain_name, logger):
@@ -211,3 +212,41 @@ class IPTables:
target = rule.create_target("SNAT")
target.to_source = snat_target
return rule
def create_mailcow_isolation_rule(self, _interface:str, _dports:list, _allow:str = ""):
try:
chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), self.chain_name)
# insert mailcow isolation rule
rule = iptc.Rule()
rule.in_interface = f'!{_interface}'
rule.out_interface = _interface
rule.protocol = 'tcp'
rule.create_target("DROP")
match = rule.create_match("multiport")
match.dports = ','.join(map(str, _dports))
if rule in chain.rules:
chain.delete_rule(rule)
chain.insert_rule(rule, position=0)
# insert mailcow isolation exception rule
if _allow != "":
rule = iptc.Rule()
rule.src = _allow
rule.in_interface = f'!{_interface}'
rule.out_interface = _interface
rule.protocol = 'tcp'
rule.create_target("ACCEPT")
match = rule.create_match("multiport")
match.dports = ','.join(map(str, _dports))
if rule in chain.rules:
chain.delete_rule(rule)
chain.insert_rule(rule, position=0)
return True
except Exception as e:
self.logger.logCrit(f"Error adding {self.chain_name} isolation: {e}")
return False

View File

@@ -2,7 +2,10 @@ import time
import json
class Logger:
def __init__(self, redis):
def __init__(self):
self.r = None
def set_redis(self, redis):
self.r = redis
def log(self, priority, message):
@@ -10,8 +13,12 @@ class Logger:
tolog['time'] = int(round(time.time()))
tolog['priority'] = priority
tolog['message'] = message
self.r.lpush('NETFILTER_LOG', json.dumps(tolog, ensure_ascii=False))
print(message)
if self.r is not None:
try:
self.r.lpush('NETFILTER_LOG', json.dumps(tolog, ensure_ascii=False))
except Exception as ex:
print('Failed logging to redis: %s' % (ex))
def logWarn(self, message):
self.log('warn', message)

View File

@@ -1,5 +1,6 @@
import nftables
import ipaddress
import os
class NFTables:
def __init__(self, chain_name, logger):
@@ -40,6 +41,7 @@ class NFTables:
exit_code = 2
if chain_position > 0:
chain_position += 1
self.logger.logCrit(f'MAILCOW target is in position {chain_position} in the {filter_table} {chain} table, restarting container to fix it...')
err = True
exit_code = 2
@@ -266,6 +268,17 @@ class NFTables:
return self.nft_exec_dict(delete_command)
def delete_filter_rule(self, _family:str, _chain: str, _handle:str):
delete_command = self.get_base_dict()
_rule_opts = {'family': _family,
'table': 'filter',
'chain': _chain,
'handle': _handle }
_delete = {'delete': {'rule': _rule_opts} }
delete_command["nftables"].append(_delete)
return self.nft_exec_dict(delete_command)
def snat_rule(self, _family: str, snat_target: str, source_address: str):
chain_name = self.nft_chain_names[_family]['nat']['postrouting']
@@ -297,8 +310,8 @@ class NFTables:
rule_handle = rule["handle"]
break
dest_net = ipaddress.ip_network(source_address)
target_net = ipaddress.ip_network(snat_target)
dest_net = ipaddress.ip_network(source_address, strict=False)
target_net = ipaddress.ip_network(snat_target, strict=False)
if rule_found:
saddr_ip = rule["expr"][0]["match"]["right"]["prefix"]["addr"]
@@ -309,9 +322,9 @@ class NFTables:
target_ip = rule["expr"][3]["snat"]["addr"]
saddr_net = ipaddress.ip_network(saddr_ip + '/' + str(saddr_len))
daddr_net = ipaddress.ip_network(daddr_ip + '/' + str(daddr_len))
current_target_net = ipaddress.ip_network(target_ip)
saddr_net = ipaddress.ip_network(saddr_ip + '/' + str(saddr_len), strict=False)
daddr_net = ipaddress.ip_network(daddr_ip + '/' + str(daddr_len), strict=False)
current_target_net = ipaddress.ip_network(target_ip, strict=False)
match = all((
dest_net == saddr_net,
@@ -381,7 +394,7 @@ class NFTables:
break
return chain_handle
def get_rules_handle(self, _family: str, _table: str, chain_name: str):
def get_rules_handle(self, _family: str, _table: str, chain_name: str, _comment_filter = "mailcow"):
rule_handle = []
# Command: 'nft list chain {family} {table} {chain_name}'
_chain_opts = {'family': _family, 'table': _table, 'name': chain_name}
@@ -397,7 +410,7 @@ class NFTables:
rule = _object["rule"]
if rule["family"] == _family and rule["table"] == _table and rule["chain"] == chain_name:
if rule.get("comment") and rule["comment"] == "mailcow":
if rule.get("comment") and rule["comment"] == _comment_filter:
rule_handle.append(rule["handle"])
return rule_handle
@@ -405,7 +418,7 @@ class NFTables:
json_command = self.get_base_dict()
expr_opt = []
ipaddr_net = ipaddress.ip_network(ipaddr)
ipaddr_net = ipaddress.ip_network(ipaddr, strict=False)
right_dict = {'prefix': {'addr': str(ipaddr_net.network_address), 'len': int(ipaddr_net.prefixlen) } }
left_dict = {'payload': {'protocol': _family, 'field': 'saddr'} }
@@ -439,6 +452,8 @@ class NFTables:
continue
rule = _object["rule"]["expr"][0]["match"]
if not "payload" in rule["left"]:
continue
left_opt = rule["left"]["payload"]
if not left_opt["protocol"] == _family:
continue
@@ -454,7 +469,7 @@ class NFTables:
current_rule_net = ipaddress.ip_network(current_rule_ip)
# ip to ban
candidate_net = ipaddress.ip_network(ipaddr)
candidate_net = ipaddress.ip_network(ipaddr, strict=False)
if current_rule_net == candidate_net:
rule_handle = _object["rule"]["handle"]
@@ -493,3 +508,152 @@ class NFTables:
position+=1
return position if rule_found else False
def create_mailcow_isolation_rule(self, _interface:str, _dports:list, _allow:str = ""):
family = "ip"
table = "filter"
comment_filter_drop = "mailcow isolation"
comment_filter_allow = "mailcow isolation allow"
json_command = self.get_base_dict()
# Delete old mailcow isolation rules
handles = self.get_rules_handle(family, table, self.chain_name, comment_filter_drop)
for handle in handles:
self.delete_filter_rule(family, self.chain_name, handle)
handles = self.get_rules_handle(family, table, self.chain_name, comment_filter_allow)
for handle in handles:
self.delete_filter_rule(family, self.chain_name, handle)
# insert mailcow isolation rule
_match_dict_drop = [
{
"match": {
"op": "!=",
"left": {
"meta": {
"key": "iifname"
}
},
"right": _interface
}
},
{
"match": {
"op": "==",
"left": {
"meta": {
"key": "oifname"
}
},
"right": _interface
}
},
{
"match": {
"op": "==",
"left": {
"payload": {
"protocol": "tcp",
"field": "dport"
}
},
"right": {
"set": _dports
}
}
},
{
"counter": {
"packets": 0,
"bytes": 0
}
},
{
"drop": None
}
]
rule_drop = { "insert": { "rule": {
"family": family,
"table": table,
"chain": self.chain_name,
"comment": comment_filter_drop,
"expr": _match_dict_drop
}}}
json_command["nftables"].append(rule_drop)
# insert mailcow isolation allow rule
if _allow != "":
_match_dict_allow = [
{
"match": {
"op": "==",
"left": {
"payload": {
"protocol": "ip",
"field": "saddr"
}
},
"right": _allow
}
},
{
"match": {
"op": "!=",
"left": {
"meta": {
"key": "iifname"
}
},
"right": _interface
}
},
{
"match": {
"op": "==",
"left": {
"meta": {
"key": "oifname"
}
},
"right": _interface
}
},
{
"match": {
"op": "==",
"left": {
"payload": {
"protocol": "tcp",
"field": "dport"
}
},
"right": {
"set": _dports
}
}
},
{
"counter": {
"packets": 0,
"bytes": 0
}
},
{
"accept": None
}
]
rule_allow = { "insert": { "rule": {
"family": family,
"table": table,
"chain": self.chain_name,
"comment": comment_filter_allow,
"expr": _match_dict_allow
}}}
json_command["nftables"].append(rule_allow)
success = self.nft_exec_dict(json_command)
if success == False:
self.logger.logCrit(f"Error adding {self.chain_name} isolation")
return False
return True

View File

@@ -1,6 +1,7 @@
FROM alpine:3.17
FROM alpine:3.20
LABEL maintainer "The Infrastructure Company GmbH <info@servercow.de>"
ARG PIP_BREAK_SYSTEM_PACKAGES=1
WORKDIR /app
#RUN addgroup -S olefy && adduser -S olefy -G olefy \

View File

@@ -1,8 +1,8 @@
FROM php:8.2-fpm-alpine3.17
FROM php:8.2-fpm-alpine3.20
LABEL maintainer "The Infrastructure Company GmbH <info@servercow.de>"
# renovate: datasource=github-tags depName=krakjoe/apcu versioning=semver-coerced extractVersion=^v(?<version>.*)$
ARG APCU_PECL_VERSION=5.1.22
ARG APCU_PECL_VERSION=5.1.23
# renovate: datasource=github-tags depName=Imagick/imagick versioning=semver-coerced extractVersion=(?<version>.*)$
ARG IMAGICK_PECL_VERSION=3.7.0
# renovate: datasource=github-tags depName=php/pecl-mail-mailparse versioning=semver-coerced extractVersion=^v(?<version>.*)$
@@ -10,9 +10,9 @@ ARG MAILPARSE_PECL_VERSION=3.1.6
# renovate: datasource=github-tags depName=php-memcached-dev/php-memcached versioning=semver-coerced extractVersion=^v(?<version>.*)$
ARG MEMCACHED_PECL_VERSION=3.2.0
# renovate: datasource=github-tags depName=phpredis/phpredis versioning=semver-coerced extractVersion=(?<version>.*)$
ARG REDIS_PECL_VERSION=6.0.1
ARG REDIS_PECL_VERSION=6.0.2
# renovate: datasource=github-tags depName=composer/composer versioning=semver-coerced extractVersion=(?<version>.*)$
ARG COMPOSER_VERSION=2.6.5
ARG COMPOSER_VERSION=2.6.6
RUN apk add -U --no-cache autoconf \
aspell-dev \

View File

@@ -1,4 +1,4 @@
FROM debian:bullseye-slim
FROM debian:bookworm-slim
LABEL maintainer "The Infrastructure Company GmbH <info@servercow.de>"
ARG DEBIAN_FRONTEND=noninteractive

View File

@@ -415,12 +415,6 @@ postscreen_dnsbl_sites = wl.mailspike.net=127.0.0.[18;19;20]*-2
b.barracudacentral.org=127.0.0.2*7
bl.mailspike.net=127.0.0.2*5
bl.mailspike.net=127.0.0.[10;11;12]*4
dnsbl.sorbs.net=127.0.0.10*8
dnsbl.sorbs.net=127.0.0.5*6
dnsbl.sorbs.net=127.0.0.7*3
dnsbl.sorbs.net=127.0.0.8*2
dnsbl.sorbs.net=127.0.0.6*2
dnsbl.sorbs.net=127.0.0.9*2
EOF
fi
DNSBL_CONFIG=$(grep -v '^#' /opt/postfix/conf/dns_blocklists.cf | grep '\S')

View File

@@ -1,4 +1,4 @@
@version: 3.28
@version: 3.38
@include "scl.conf"
options {
chain_hostnames(off);

View File

@@ -1,4 +1,4 @@
@version: 3.28
@version: 3.38
@include "scl.conf"
options {
chain_hostnames(off);

View File

@@ -2,6 +2,7 @@ FROM debian:bullseye-slim
LABEL maintainer "The Infrastructure Company GmbH <info@servercow.de>"
ARG DEBIAN_FRONTEND=noninteractive
ARG RSPAMD_VER=rspamd_3.7.5-2~8c86c1676
ARG CODENAME=bullseye
ENV LC_ALL C
@@ -12,11 +13,14 @@ RUN apt-get update && apt-get install -y \
apt-transport-https \
dnsutils \
netcat \
&& apt-key adv --fetch-keys https://rspamd.com/apt-stable/gpg.key \
&& echo "deb [arch=amd64] https://rspamd.com/apt-stable/ $CODENAME main" > /etc/apt/sources.list.d/rspamd.list \
&& apt-get update \
&& apt-get --no-install-recommends -y install rspamd redis-tools procps nano \
&& rm -rf /var/lib/apt/lists/* \
wget \
redis-tools \
procps \
nano \
&& arch=$(arch | sed s/aarch64/arm64/ | sed s/x86_64/amd64/) \
&& wget -P /tmp https://rspamd.com/apt-stable/pool/main/r/rspamd/${RSPAMD_VER}~${CODENAME}_${arch}.deb\
&& apt install -y /tmp/${RSPAMD_VER}~${CODENAME}_${arch}.deb \
&& rm -rf /var/lib/apt/lists/* /tmp/*\
&& apt-get autoremove --purge \
&& apt-get clean \
&& mkdir -p /run/rspamd \
@@ -25,7 +29,6 @@ RUN apt-get update && apt-get install -y \
&& sed -i 's/#analysis_keyword_table > 0/analysis_cat_table.macro_exist == "M"/g' /usr/share/rspamd/lualib/lua_scanners/oletools.lua
COPY settings.conf /etc/rspamd/settings.conf
COPY metadata_exporter.lua /usr/share/rspamd/plugins/metadata_exporter.lua
COPY set_worker_password.sh /set_worker_password.sh
COPY docker-entrypoint.sh /docker-entrypoint.sh

View File

@@ -1,632 +0,0 @@
--[[
Copyright (c) 2016, Andrew Lewis <nerf@judo.za.org>
Copyright (c) 2016, Vsevolod Stakhov <vsevolod@highsecure.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
]]--
if confighelp then
return
end
-- A plugin that pushes metadata (or whole messages) to external services
local redis_params
local lua_util = require "lua_util"
local rspamd_http = require "rspamd_http"
local rspamd_util = require "rspamd_util"
local rspamd_logger = require "rspamd_logger"
local ucl = require "ucl"
local E = {}
local N = 'metadata_exporter'
local settings = {
pusher_enabled = {},
pusher_format = {},
pusher_select = {},
mime_type = 'text/plain',
defer = false,
mail_from = '',
mail_to = 'postmaster@localhost',
helo = 'rspamd',
email_template = [[From: "Rspamd" <$mail_from>
To: $mail_to
Subject: Spam alert
Date: $date
MIME-Version: 1.0
Message-ID: <$our_message_id>
Content-type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
Authenticated username: $user
IP: $ip
Queue ID: $qid
SMTP FROM: $from
SMTP RCPT: $rcpt
MIME From: $header_from
MIME To: $header_to
MIME Date: $header_date
Subject: $header_subject
Message-ID: $message_id
Action: $action
Score: $score
Symbols: $symbols]],
}
local function get_general_metadata(task, flatten, no_content)
local r = {}
local ip = task:get_from_ip()
if ip and ip:is_valid() then
r.ip = tostring(ip)
else
r.ip = 'unknown'
end
r.user = task:get_user() or 'unknown'
r.qid = task:get_queue_id() or 'unknown'
r.subject = task:get_subject() or 'unknown'
r.action = task:get_metric_action('default')
local s = task:get_metric_score('default')[1]
r.score = flatten and string.format('%.2f', s) or s
local fuzzy = task:get_mempool():get_variable("fuzzy_hashes", "fstrings")
if fuzzy and #fuzzy > 0 then
local fz = {}
for _,h in ipairs(fuzzy) do
table.insert(fz, h)
end
if not flatten then
r.fuzzy = fz
else
r.fuzzy = table.concat(fz, ', ')
end
else
r.fuzzy = 'unknown'
end
local rcpt = task:get_recipients('smtp')
if rcpt then
local l = {}
for _, a in ipairs(rcpt) do
table.insert(l, a['addr'])
end
if not flatten then
r.rcpt = l
else
r.rcpt = table.concat(l, ', ')
end
else
r.rcpt = 'unknown'
end
local from = task:get_from('smtp')
if ((from or E)[1] or E).addr then
r.from = from[1].addr
else
r.from = 'unknown'
end
local syminf = task:get_symbols_all()
if flatten then
local l = {}
for _, sym in ipairs(syminf) do
local txt
if sym.options then
local topt = table.concat(sym.options, ', ')
txt = sym.name .. '(' .. string.format('%.2f', sym.score) .. ')' .. ' [' .. topt .. ']'
else
txt = sym.name .. '(' .. string.format('%.2f', sym.score) .. ')'
end
table.insert(l, txt)
end
r.symbols = table.concat(l, '\n\t')
else
r.symbols = syminf
end
local function process_header(name)
local hdr = task:get_header_full(name)
if hdr then
local l = {}
for _, h in ipairs(hdr) do
table.insert(l, h.decoded)
end
if not flatten then
return l
else
return table.concat(l, '\n')
end
else
return 'unknown'
end
end
if not no_content then
r.header_from = process_header('from')
r.header_to = process_header('to')
r.header_subject = process_header('subject')
r.header_date = process_header('date')
r.message_id = task:get_message_id()
end
return r
end
local formatters = {
default = function(task)
return task:get_content(), {}
end,
email_alert = function(task, rule, extra)
local meta = get_general_metadata(task, true)
local display_emails = {}
local mail_targets = {}
meta.mail_from = rule.mail_from or settings.mail_from
local mail_rcpt = rule.mail_to or settings.mail_to
if type(mail_rcpt) ~= 'table' then
table.insert(display_emails, string.format('<%s>', mail_rcpt))
table.insert(mail_targets, mail_rcpt)
else
for _, e in ipairs(mail_rcpt) do
table.insert(display_emails, string.format('<%s>', e))
table.insert(mail_targets, mail_rcpt)
end
end
if rule.email_alert_sender then
local x = task:get_from('smtp')
if x and string.len(x[1].addr) > 0 then
table.insert(mail_targets, x)
table.insert(display_emails, string.format('<%s>', x[1].addr))
end
end
if rule.email_alert_user then
local x = task:get_user()
if x then
table.insert(mail_targets, x)
table.insert(display_emails, string.format('<%s>', x))
end
end
if rule.email_alert_recipients then
local x = task:get_recipients('smtp')
if x then
for _, e in ipairs(x) do
if string.len(e.addr) > 0 then
table.insert(mail_targets, e.addr)
table.insert(display_emails, string.format('<%s>', e.addr))
end
end
end
end
meta.mail_to = table.concat(display_emails, ', ')
meta.our_message_id = rspamd_util.random_hex(12) .. '@rspamd'
meta.date = rspamd_util.time_to_string(rspamd_util.get_time())
return lua_util.template(rule.email_template or settings.email_template, meta), { mail_targets = mail_targets}
end,
json = function(task)
return ucl.to_format(get_general_metadata(task), 'json-compact')
end
}
local function is_spam(action)
return (action == 'reject' or action == 'add header' or action == 'rewrite subject')
end
local selectors = {
default = function(task)
return true
end,
is_spam = function(task)
local action = task:get_metric_action('default')
return is_spam(action)
end,
is_spam_authed = function(task)
if not task:get_user() then
return false
end
local action = task:get_metric_action('default')
return is_spam(action)
end,
is_reject = function(task)
local action = task:get_metric_action('default')
return (action == 'reject')
end,
is_reject_authed = function(task)
if not task:get_user() then
return false
end
local action = task:get_metric_action('default')
return (action == 'reject')
end,
}
local function maybe_defer(task, rule)
if rule.defer then
rspamd_logger.warnx(task, 'deferring message')
task:set_pre_result('soft reject', 'deferred', N)
end
end
local pushers = {
redis_pubsub = function(task, formatted, rule)
local _,ret,upstream
local function redis_pub_cb(err)
if err then
rspamd_logger.errx(task, 'got error %s when publishing on server %s',
err, upstream:get_addr())
return maybe_defer(task, rule)
end
return true
end
ret,_,upstream = rspamd_redis_make_request(task,
redis_params, -- connect params
nil, -- hash key
true, -- is write
redis_pub_cb, --callback
'PUBLISH', -- command
{rule.channel, formatted} -- arguments
)
if not ret then
rspamd_logger.errx(task, 'error connecting to redis')
maybe_defer(task, rule)
end
end,
http = function(task, formatted, rule)
local function http_callback(err, code)
if err then
rspamd_logger.errx(task, 'got error %s in http callback', err)
return maybe_defer(task, rule)
end
if code ~= 200 then
rspamd_logger.errx(task, 'got unexpected http status: %s', code)
return maybe_defer(task, rule)
end
return true
end
local hdrs = {}
if rule.meta_headers then
local gm = get_general_metadata(task, false, true)
local pfx = rule.meta_header_prefix or 'X-Rspamd-'
for k, v in pairs(gm) do
if type(v) == 'table' then
hdrs[pfx .. k] = ucl.to_format(v, 'json-compact')
else
hdrs[pfx .. k] = v
end
end
end
rspamd_http.request({
task=task,
url=rule.url,
body=formatted,
callback=http_callback,
mime_type=rule.mime_type or settings.mime_type,
headers=hdrs,
})
end,
send_mail = function(task, formatted, rule, extra)
local lua_smtp = require "lua_smtp"
local function sendmail_cb(ret, err)
if not ret then
rspamd_logger.errx(task, 'SMTP export error: %s', err)
maybe_defer(task, rule)
end
end
lua_smtp.sendmail({
task = task,
host = rule.smtp,
port = rule.smtp_port or settings.smtp_port or 25,
from = rule.mail_from or settings.mail_from,
recipients = extra.mail_targets or rule.mail_to or settings.mail_to,
helo = rule.helo or settings.helo,
timeout = rule.timeout or settings.timeout,
}, formatted, sendmail_cb)
end,
}
local opts = rspamd_config:get_all_opt(N)
if not opts then return end
local process_settings = {
select = function(val)
selectors.custom = assert(load(val))()
end,
format = function(val)
formatters.custom = assert(load(val))()
end,
push = function(val)
pushers.custom = assert(load(val))()
end,
custom_push = function(val)
if type(val) == 'table' then
for k, v in pairs(val) do
pushers[k] = assert(load(v))()
end
end
end,
custom_select = function(val)
if type(val) == 'table' then
for k, v in pairs(val) do
selectors[k] = assert(load(v))()
end
end
end,
custom_format = function(val)
if type(val) == 'table' then
for k, v in pairs(val) do
formatters[k] = assert(load(v))()
end
end
end,
pusher_enabled = function(val)
if type(val) == 'string' then
if pushers[val] then
settings.pusher_enabled[val] = true
else
rspamd_logger.errx(rspamd_config, 'Pusher type: %s is invalid', val)
end
elseif type(val) == 'table' then
for _, v in ipairs(val) do
if pushers[v] then
settings.pusher_enabled[v] = true
else
rspamd_logger.errx(rspamd_config, 'Pusher type: %s is invalid', val)
end
end
end
end,
}
for k, v in pairs(opts) do
local f = process_settings[k]
if f then
f(opts[k])
else
settings[k] = v
end
end
if type(settings.rules) ~= 'table' then
-- Legacy config
settings.rules = {}
if not next(settings.pusher_enabled) then
if pushers.custom then
rspamd_logger.infox(rspamd_config, 'Custom pusher implicitly enabled')
settings.pusher_enabled.custom = true
else
-- Check legacy options
if settings.url then
rspamd_logger.warnx(rspamd_config, 'HTTP pusher implicitly enabled')
settings.pusher_enabled.http = true
end
if settings.channel then
rspamd_logger.warnx(rspamd_config, 'Redis Pubsub pusher implicitly enabled')
settings.pusher_enabled.redis_pubsub = true
end
if settings.smtp and settings.mail_to then
rspamd_logger.warnx(rspamd_config, 'SMTP pusher implicitly enabled')
settings.pusher_enabled.send_mail = true
end
end
end
if not next(settings.pusher_enabled) then
rspamd_logger.errx(rspamd_config, 'No push backend enabled')
return
end
if settings.formatter then
settings.format = formatters[settings.formatter]
if not settings.format then
rspamd_logger.errx(rspamd_config, 'No such formatter: %s', settings.formatter)
return
end
end
if settings.selector then
settings.select = selectors[settings.selector]
if not settings.select then
rspamd_logger.errx(rspamd_config, 'No such selector: %s', settings.selector)
return
end
end
for k in pairs(settings.pusher_enabled) do
local formatter = settings.pusher_format[k]
local selector = settings.pusher_select[k]
if not formatter then
settings.pusher_format[k] = settings.formatter or 'default'
rspamd_logger.infox(rspamd_config, 'Using default formatter for %s pusher', k)
else
if not formatters[formatter] then
rspamd_logger.errx(rspamd_config, 'No such formatter: %s - disabling %s', formatter, k)
settings.pusher_enabled.k = nil
end
end
if not selector then
settings.pusher_select[k] = settings.selector or 'default'
rspamd_logger.infox(rspamd_config, 'Using default selector for %s pusher', k)
else
if not selectors[selector] then
rspamd_logger.errx(rspamd_config, 'No such selector: %s - disabling %s', selector, k)
settings.pusher_enabled.k = nil
end
end
end
if settings.pusher_enabled.redis_pubsub then
redis_params = rspamd_parse_redis_server(N)
if not redis_params then
rspamd_logger.errx(rspamd_config, 'No redis servers are specified')
settings.pusher_enabled.redis_pubsub = nil
else
local r = {}
r.backend = 'redis_pubsub'
r.channel = settings.channel
r.defer = settings.defer
r.selector = settings.pusher_select.redis_pubsub
r.formatter = settings.pusher_format.redis_pubsub
settings.rules[r.backend:upper()] = r
end
end
if settings.pusher_enabled.http then
if not settings.url then
rspamd_logger.errx(rspamd_config, 'No URL is specified')
settings.pusher_enabled.http = nil
else
local r = {}
r.backend = 'http'
r.url = settings.url
r.mime_type = settings.mime_type
r.defer = settings.defer
r.selector = settings.pusher_select.http
r.formatter = settings.pusher_format.http
settings.rules[r.backend:upper()] = r
end
end
if settings.pusher_enabled.send_mail then
if not (settings.mail_to and settings.smtp) then
rspamd_logger.errx(rspamd_config, 'No mail_to and/or smtp setting is specified')
settings.pusher_enabled.send_mail = nil
else
local r = {}
r.backend = 'send_mail'
r.mail_to = settings.mail_to
r.mail_from = settings.mail_from
r.helo = settings.hello
r.smtp = settings.smtp
r.smtp_port = settings.smtp_port
r.email_template = settings.email_template
r.defer = settings.defer
r.selector = settings.pusher_select.send_mail
r.formatter = settings.pusher_format.send_mail
settings.rules[r.backend:upper()] = r
end
end
if not next(settings.pusher_enabled) then
rspamd_logger.errx(rspamd_config, 'No push backend enabled')
return
end
elseif not next(settings.rules) then
lua_util.debugm(N, rspamd_config, 'No rules enabled')
return
end
if not settings.rules or not next(settings.rules) then
rspamd_logger.errx(rspamd_config, 'No rules enabled')
return
end
local backend_required_elements = {
http = {
'url',
},
smtp = {
'mail_to',
'smtp',
},
redis_pubsub = {
'channel',
},
}
local check_element = {
selector = function(k, v)
if not selectors[v] then
rspamd_logger.errx(rspamd_config, 'Rule %s has invalid selector %s', k, v)
return false
else
return true
end
end,
formatter = function(k, v)
if not formatters[v] then
rspamd_logger.errx(rspamd_config, 'Rule %s has invalid formatter %s', k, v)
return false
else
return true
end
end,
}
local backend_check = {
default = function(k, rule)
local reqset = backend_required_elements[rule.backend]
if reqset then
for _, e in ipairs(reqset) do
if not rule[e] then
rspamd_logger.errx(rspamd_config, 'Rule %s misses required setting %s', k, e)
settings.rules[k] = nil
end
end
end
for sett, v in pairs(rule) do
local f = check_element[sett]
if f then
if not f(sett, v) then
settings.rules[k] = nil
end
end
end
end,
}
backend_check.redis_pubsub = function(k, rule)
if not redis_params then
redis_params = rspamd_parse_redis_server(N)
end
if not redis_params then
rspamd_logger.errx(rspamd_config, 'No redis servers are specified')
settings.rules[k] = nil
else
backend_check.default(k, rule)
end
end
setmetatable(backend_check, {
__index = function()
return backend_check.default
end,
})
for k, v in pairs(settings.rules) do
if type(v) == 'table' then
local backend = v.backend
if not backend then
rspamd_logger.errx(rspamd_config, 'Rule %s has no backend', k)
settings.rules[k] = nil
elseif not pushers[backend] then
rspamd_logger.errx(rspamd_config, 'Rule %s has invalid backend %s', k, backend)
settings.rules[k] = nil
else
local f = backend_check[backend]
f(k, v)
end
else
rspamd_logger.errx(rspamd_config, 'Rule %s has bad type: %s', k, type(v))
settings.rules[k] = nil
end
end
local function gen_exporter(rule)
return function (task)
if task:has_flag('skip') then return end
local selector = rule.selector or 'default'
local selected = selectors[selector](task)
if selected then
lua_util.debugm(N, task, 'Message selected for processing')
local formatter = rule.formatter or 'default'
local formatted, extra = formatters[formatter](task, rule)
if formatted then
pushers[rule.backend](task, formatted, rule, extra)
else
lua_util.debugm(N, task, 'Formatter [%s] returned non-truthy value [%s]', formatter, formatted)
end
else
lua_util.debugm(N, task, 'Selector [%s] returned non-truthy value [%s]', selector, selected)
end
end
end
if not next(settings.rules) then
rspamd_logger.errx(rspamd_config, 'No rules enabled')
lua_util.disable_module(N, "config")
end
for k, r in pairs(settings.rules) do
rspamd_config:register_symbol({
name = 'EXPORT_METADATA_' .. k,
type = 'idempotent',
callback = gen_exporter(r),
priority = 10,
flags = 'empty,explicit_disable,ignore_passthrough',
})
end

View File

@@ -2,9 +2,10 @@ FROM debian:bullseye-slim
LABEL maintainer "The Infrastructure Company GmbH <info@servercow.de>"
ARG DEBIAN_FRONTEND=noninteractive
ARG SOGO_DEBIAN_REPOSITORY=http://packages.sogo.nu/nightly/5/debian/
ARG DEBIAN_VERSION=bullseye
ARG SOGO_DEBIAN_REPOSITORY=http://www.axis.cz/linux/debian
# renovate: datasource=github-releases depName=tianon/gosu versioning=semver-coerced extractVersion=^(?<version>.*)$
ARG GOSU_VERSION=1.16
ARG GOSU_VERSION=1.17
ENV LC_ALL C
# Prerequisites
@@ -21,7 +22,7 @@ RUN echo "Building from repository $SOGO_DEBIAN_REPOSITORY" \
syslog-ng-core \
syslog-ng-mod-redis \
dirmngr \
netcat \
netcat-traditional \
psmisc \
wget \
patch \
@@ -32,7 +33,7 @@ RUN echo "Building from repository $SOGO_DEBIAN_REPOSITORY" \
&& mkdir /usr/share/doc/sogo \
&& touch /usr/share/doc/sogo/empty.sh \
&& apt-key adv --keyserver keys.openpgp.org --recv-key 74FFC6D72B925A34B5D356BDF8A27B36A6E2EAE9 \
&& echo "deb ${SOGO_DEBIAN_REPOSITORY} bullseye bullseye" > /etc/apt/sources.list.d/sogo.list \
&& echo "deb [trusted=yes] ${SOGO_DEBIAN_REPOSITORY} ${DEBIAN_VERSION} sogo-v5" > /etc/apt/sources.list.d/sogo.list \
&& apt-get update && apt-get install -y --no-install-recommends \
sogo \
sogo-activesync \

View File

@@ -150,6 +150,8 @@ cat <<EOF > /var/lib/sogo/GNUstep/Defaults/sogod.plist
<string>YES</string>
<key>SOGoEncryptionKey</key>
<string>${RAND_PASS}</string>
<key>OCSAdminURL</key>
<string>mysql://${DBUSER}:${DBPASS}@%2Fvar%2Frun%2Fmysqld%2Fmysqld.sock/${DBNAME}/sogo_admin</string>
<key>OCSCacheFolderURL</key>
<string>mysql://${DBUSER}:${DBPASS}@%2Fvar%2Frun%2Fmysqld%2Fmysqld.sock/${DBNAME}/sogo_cache_folder</string>
<key>OCSEMailAlarmsFolderURL</key>

View File

@@ -3,7 +3,7 @@ FROM solr:7.7-slim
USER root
# renovate: datasource=github-releases depName=tianon/gosu versioning=semver-coerced extractVersion=(?<version>.*)$
ARG GOSU_VERSION=1.16
ARG GOSU_VERSION=1.17
COPY solr.sh /
COPY solr-config-7.7.0.xml /

View File

@@ -1,7 +1,15 @@
#!/bin/bash
if [[ "${SKIP_SOLR}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
if [[ "${FLATCURVE_EXPERIMENTAL}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
echo "FLATCURVE_EXPERIMENTAL=y, skipping Solr but enabling Flatcurve as FTS for Dovecot!"
echo "Solr will be removed in the future!"
sleep 365d
exit 0
elif [[ "${SKIP_SOLR}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
echo "SKIP_SOLR=y, skipping Solr..."
echo "HINT: You could try the newer FTS Backend Flatcurve, which is currently in experimental state..."
echo "Simply set FLATCURVE_EXPERIMENTAL=y inside your mailcow.conf and restart the stack afterwards!"
echo "Solr will be removed in the future!"
sleep 365d
exit 0
fi
@@ -57,5 +65,11 @@ if [[ "${1}" == "--bootstrap" ]]; then
exit 0
fi
echo "Starting up Solr..."
echo -e "\e[31mSolr is deprecated! You can try the new FTS System now by enabling FLATCURVE_EXPERIMENTAL=y inside mailcow.conf and restarting the stack\e[0m"
echo -e "\e[31mSolr will be removed completely soon!\e[0m"
sleep 15
exec gosu solr solr-foreground

View File

@@ -1,9 +1,10 @@
FROM alpine:3.17
FROM alpine:3.20
LABEL maintainer "The Infrastructure Company GmbH <info@servercow.de>"
RUN apk add --update --no-cache \
curl \
bind-tools \
unbound \
bash \
openssl \
@@ -18,10 +19,10 @@ EXPOSE 53/udp 53/tcp
COPY docker-entrypoint.sh /docker-entrypoint.sh
# healthcheck (nslookup)
# healthcheck (dig, ping)
COPY healthcheck.sh /healthcheck.sh
RUN chmod +x /healthcheck.sh
HEALTHCHECK --interval=30s --timeout=10s CMD [ "/healthcheck.sh" ]
HEALTHCHECK --interval=30s --timeout=30s CMD [ "/healthcheck.sh" ]
ENTRYPOINT ["/docker-entrypoint.sh"]

View File

@@ -1,12 +1,76 @@
#!/bin/bash
nslookup mailcow.email 127.0.0.1 1> /dev/null
# Skip Unbound (DNS Resolver) Healthchecks (NOT Recommended!)
if [[ "${SKIP_UNBOUND_HEALTHCHECK}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
SKIP_UNBOUND_HEALTHCHECK=y
fi
if [ $? == 0 ]; then
echo "DNS resolution is working!"
# Reset logfile
echo "$(date +"%Y-%m-%d %H:%M:%S"): Starting health check - logs can be found in /var/log/healthcheck.log"
echo "$(date +"%Y-%m-%d %H:%M:%S"): Starting health check" > /var/log/healthcheck.log
# Declare log function for logfile inside container
function log_to_file() {
echo "$(date +"%Y-%m-%d %H:%M:%S"): $1" >> /var/log/healthcheck.log
}
# General Ping function to check general pingability
function check_ping() {
declare -a ipstoping=("1.1.1.1" "8.8.8.8" "9.9.9.9")
for ip in "${ipstoping[@]}" ; do
ping -q -c 3 -w 5 "$ip"
if [ $? -ne 0 ]; then
log_to_file "Healthcheck: Couldn't ping $ip for 5 seconds... Gave up!"
log_to_file "Please check your internet connection or firewall rules to fix this error, because a simple ping test should always go through from the unbound container!"
return 1
fi
done
log_to_file "Healthcheck: Ping Checks WORKING properly!"
return 0
}
# General DNS Resolve Check against Unbound Resolver himself
function check_dns() {
declare -a domains=("mailcow.email" "github.com" "hub.docker.com")
for domain in "${domains[@]}" ; do
for ((i=1; i<=3; i++)); do
dig +short +timeout=2 +tries=1 "$domain" @127.0.0.1 > /dev/null
if [ $? -ne 0 ]; then
log_to_file "Healthcheck: DNS Resolution Failed on $i attempt! Trying again..."
if [ $i -eq 3 ]; then
log_to_file "Healthcheck: DNS Resolution not possible after $i attempts... Gave up!"
log_to_file "Maybe check your outbound firewall, as it needs to resolve DNS over TCP AND UDP!"
return 1
fi
fi
done
done
log_to_file "Healthcheck: DNS Resolver WORKING properly!"
return 0
}
if [[ ${SKIP_UNBOUND_HEALTHCHECK} == "y" ]]; then
log_to_file "Healthcheck: ALL CHECKS WERE SKIPPED! Unbound is healthy!"
exit 0
else
echo "DNS resolution is not working correctly..."
echo "Maybe check your outbound firewall, as it needs to resolve DNS over TCP AND UDP!"
fi
# run checks, if check is not returning 0 (return value if check is ok), healthcheck will exit with 1 (marked in docker as unhealthy)
check_ping
if [ $? -ne 0 ]; then
exit 1
fi
check_dns
if [ $? -ne 0 ]; then
exit 1
fi
log_to_file "Healthcheck: ALL CHECKS WERE SUCCESSFUL! Unbound is healthy!"
exit 0

View File

@@ -1,5 +1,5 @@
FROM alpine:3.17
LABEL maintainer "André Peters <andre.peters@servercow.de>"
FROM alpine:3.20
LABEL maintainer "The Infrastructure Company GmbH <info@servercow.de>"
# Installation
RUN apk add --update \

View File

@@ -170,7 +170,7 @@ function notify_error() {
fi
# Replace subject and body placeholders
WEBHOOK_BODY=$(echo ${WATCHDOG_NOTIFY_WEBHOOK_BODY} | sed "s|\$SUBJECT\|\${SUBJECT}|$SUBJECT|g" | sed "s|\$BODY\|\${BODY}|$BODY|")
WEBHOOK_BODY=$(echo ${WATCHDOG_NOTIFY_WEBHOOK_BODY} | sed "s/\$SUBJECT\|\${SUBJECT}/$SUBJECT/g" | sed "s/\$BODY\|\${BODY}/$BODY/g")
# POST to webhook
curl -X POST -H "Content-Type: application/json" ${CURL_VERBOSE} -d "${WEBHOOK_BODY}" ${WATCHDOG_NOTIFY_WEBHOOK}
@@ -716,8 +716,8 @@ rspamd_checks() {
From: watchdog@localhost
Empty
' | usr/bin/curl --max-time 10 -s --data-binary @- --unix-socket /var/lib/rspamd/rspamd.sock http://rspamd/scan | jq -rc .default.required_score)
if [[ ${SCORE} != "9999" ]]; then
' | usr/bin/curl --max-time 10 -s --data-binary @- --unix-socket /var/lib/rspamd/rspamd.sock http://rspamd/scan | jq -rc .default.required_score | sed 's/\..*//' )
if [[ ${SCORE} -ne 9999 ]]; then
echo "Rspamd settings check failed, score returned: ${SCORE}" 2>> /tmp/rspamd-mailcow 1>&2
err_count=$(( ${err_count} + 1))
else

View File

@@ -10,6 +10,7 @@
auth_mechanisms = plain login
#mail_debug = yes
#auth_debug = yes
#log_debug = category=fts-flatcurve # Activate Logging for Flatcurve FTS Searchings
log_path = syslog
disable_plaintext_auth = yes
# Uncomment on NFS share
@@ -194,9 +195,6 @@ plugin {
acl_shared_dict = file:/var/vmail/shared-mailboxes.db
acl = vfile
acl_user = %u
fts = solr
fts_autoindex = yes
fts_solr = url=http://solr:8983/solr/dovecot-fts/
quota = dict:Userquota::proxy::sqlquota
quota_rule2 = Trash:storage=+100%%
sieve = /var/vmail/sieve/%u.sieve
@@ -247,6 +245,9 @@ plugin {
mail_log_events = delete undelete expunge copy mailbox_delete mailbox_rename
mail_log_fields = uid box msgid size
mail_log_cached_only = yes
# Try set mail_replica
!include_try /etc/dovecot/mail_replica.conf
}
service quota-warning {
executable = script /usr/local/bin/quota_notify.py
@@ -302,6 +303,7 @@ replication_dsync_parameters = -d -l 30 -U -n INBOX
!include_try /etc/dovecot/extra.conf
!include_try /etc/dovecot/sogo-sso.conf
!include_try /etc/dovecot/shared_namespace.conf
!include_try /etc/dovecot/conf.d/fts.conf
# </Includes>
default_client_limit = 10400
default_vsz_limit = 1024 M

View File

@@ -1,6 +1,6 @@
if /^\s*Received:.*Authenticated sender.*\(Postcow\)/
#/^Received: from .*? \([\w-.]* \[.*?\]\)\s+\(Authenticated sender: (.+)\)\s+by.+\(Postcow\) with (E?SMTPS?A?) id ([A-F0-9]+).+;.*?/
/^Received: from .*? \([\w-.]* \[.*?\]\)(.*|\n.*)\(Authenticated sender: (.+)\)\s+by.+\(Postcow\) with (.*)/
/^Received: from .*? \([\w\-.]* \[.*?\]\)(.*|\n.*)\(Authenticated sender: (.+)\)\s+by.+\(Postcow\) with (.*)/
REPLACE Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with $3
endif
if /^\s*Received: from.* \(.*dovecot-mailcow.*mailcow-network.*\).*\(Postcow\)/
@@ -12,7 +12,8 @@ if /^\s*Received: from.* \(.*rspamd-mailcow.*mailcow-network.*\).*\(Postcow\)/
REPLACE Received: from rspamd (rspamd $3) by $4 (Postcow) with $5
endif
/^\s*X-Enigmail/ IGNORE
/^\s*X-Mailer/ IGNORE
# Not removing Mailer by default, might be signed
#/^\s*X-Mailer/ IGNORE
/^\s*X-Originating-IP/ IGNORE
/^\s*X-Forward/ IGNORE
# Not removing UA by default, might be signed

View File

@@ -11,6 +11,7 @@ smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtpd_relay_restrictions = permit_mynetworks,
permit_sasl_authenticated,
defer_unauth_destination
smtpd_forbid_bare_newline = yes
# alias maps are auto-generated in postfix.sh on startup
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
@@ -84,6 +85,7 @@ smtp_tls_security_level = dane
smtpd_data_restrictions = reject_unauth_pipelining, permit
smtpd_delay_reject = yes
smtpd_error_sleep_time = 10s
smtpd_forbid_bare_newline = yes
smtpd_hard_error_limit = ${stress?1}${stress:5}
smtpd_helo_required = yes
smtpd_proxy_timeout = 600s
@@ -112,14 +114,14 @@ smtpd_tls_loglevel = 1
# Mandatory protocols and ciphers are used when a connections is enforced to use TLS
# Does _not_ apply to enforced incoming TLS settings per mailbox
smtp_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
lmtp_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtp_tls_mandatory_protocols = >=TLSv1.2
lmtp_tls_mandatory_protocols = >=TLSv1.2
smtpd_tls_mandatory_protocols = >=TLSv1.2
smtpd_tls_mandatory_ciphers = high
smtp_tls_protocols = !SSLv2, !SSLv3
lmtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtpd_tls_protocols = !SSLv2, !SSLv3
smtp_tls_protocols = >=TLSv1.2
lmtp_tls_protocols = >=TLSv1.2
smtpd_tls_protocols = >=TLSv1.2
smtpd_tls_security_level = may
tls_preempt_cipherlist = yes
@@ -160,12 +162,13 @@ transport_maps = pcre:/opt/postfix/conf/custom_transport.pcre,
proxy:mysql:/opt/postfix/conf/sql/mysql_relay_ne.cf,
proxy:mysql:/opt/postfix/conf/sql/mysql_transport_maps.cf
smtp_sasl_auth_soft_bounce = no
postscreen_discard_ehlo_keywords = silent-discard, dsn
compatibility_level = 2
postscreen_discard_ehlo_keywords = silent-discard, dsn, chunking
smtpd_discard_ehlo_keywords = chunking, silent-discard
compatibility_level = 3.7
smtputf8_enable = no
# Define protocols for SMTPS and submission service
submission_smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtps_smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
submission_smtpd_tls_mandatory_protocols = >=TLSv1.2
smtps_smtpd_tls_mandatory_protocols = >=TLSv1.2
parent_domain_matches_subdomains = debug_peer_list,fast_flush_domains,mynetworks,qmqpd_authorized_clients
# DO NOT EDIT ANYTHING BELOW #

View File

@@ -1,9 +1,10 @@
# Whitelist generated by Postwhite v3.4 on Fri Dec 1 00:15:18 UTC 2023
# Whitelist generated by Postwhite v3.4 on Sat Jun 1 00:15:02 UTC 2024
# https://github.com/stevejenkins/postwhite/
# 2038 total rules
# 2000 total rules
2a00:1450:4000::/36 permit
2a01:111:f400::/48 permit
2a01:111:f403:8000::/50 permit
2a01:111:f403:8000::/51 permit
2a01:111:f403::/49 permit
2a01:111:f403:c000::/51 permit
2a01:111:f403:f000::/52 permit
@@ -12,14 +13,15 @@
2.207.151.53 permit
3.70.123.177 permit
3.93.157.0/24 permit
3.94.40.108 permit
3.129.120.190 permit
3.137.78.75 permit
3.210.190.0/24 permit
8.20.114.31 permit
8.25.194.0/23 permit
8.25.196.0/23 permit
8.39.54.0/23 permit
8.40.222.0/23 permit
10.162.0.0/16 permit
12.130.86.238 permit
13.70.32.43 permit
13.72.50.45 permit
@@ -31,21 +33,25 @@
13.110.216.0/22 permit
13.110.224.0/20 permit
13.111.0.0/16 permit
13.111.191.0/24 permit
15.200.21.50 permit
15.200.44.248 permit
15.200.201.185 permit
17.41.0.0/16 permit
17.57.155.0/24 permit
17.57.156.0/24 permit
17.58.0.0/16 permit
17.142.0.0/15 permit
18.156.89.250 permit
18.157.243.190 permit
18.194.95.56 permit
18.198.96.88 permit
18.208.124.128/25 permit
18.216.232.154 permit
18.234.1.244 permit
18.236.40.242 permit
18.236.56.161 permit
20.51.6.32/30 permit
20.51.98.61 permit
20.52.52.2 permit
20.52.128.133 permit
20.59.80.4/30 permit
@@ -63,10 +69,9 @@
20.107.239.64/30 permit
20.112.250.133 permit
20.118.139.208/30 permit
20.185.213.160/27 permit
20.185.213.224/27 permit
20.141.10.196 permit
20.185.213.0/24 permit
20.185.214.0/27 permit
20.185.214.2 permit
20.185.214.32/27 permit
20.185.214.64/27 permit
20.231.239.246 permit
@@ -90,23 +95,22 @@
27.123.204.172 permit
27.123.204.188/30 permit
27.123.204.192 permit
27.123.206.0/24 permit
27.123.206.50/31 permit
27.123.206.56/29 permit
27.123.206.76/30 permit
27.123.206.80/28 permit
31.25.48.222 permit
34.195.217.107 permit
34.202.239.6 permit
34.212.163.75 permit
34.215.104.144 permit
34.218.116.3 permit
34.225.212.172 permit
34.247.168.44 permit
35.161.32.253 permit
35.167.93.243 permit
35.176.132.251 permit
35.190.247.0/24 permit
35.191.0.0/16 permit
35.242.169.159 permit
37.218.248.47 permit
37.218.249.47 permit
37.218.251.62 permit
@@ -116,13 +120,11 @@
40.92.0.0/16 permit
40.107.0.0/16 permit
40.112.65.63 permit
40.117.80.0/24 permit
43.228.184.0/22 permit
44.206.138.57 permit
44.209.42.157 permit
44.236.56.93 permit
44.238.220.251 permit
46.19.168.0/23 permit
46.19.170.16 permit
46.226.48.0/21 permit
46.228.36.37 permit
46.228.36.38/31 permit
@@ -162,7 +164,6 @@
46.228.38.144/29 permit
46.228.38.152/31 permit
46.228.38.154 permit
46.228.39.0/24 permit
46.228.39.64/27 permit
46.228.39.96/30 permit
46.228.39.100/30 permit
@@ -183,22 +184,23 @@
50.18.125.237 permit
50.18.126.162 permit
50.31.32.0/19 permit
50.56.130.220/30 permit
51.137.58.21 permit
51.140.75.55 permit
51.144.100.179 permit
52.1.14.157 permit
52.5.230.59 permit
52.27.5.72 permit
52.27.28.47 permit
52.28.63.81 permit
52.36.138.31 permit
52.37.142.146 permit
52.50.24.208 permit
52.58.216.183 permit
52.59.143.3 permit
52.60.41.5 permit
52.60.115.116 permit
52.61.91.9 permit
52.71.0.205 permit
52.82.172.0/22 permit
52.94.124.0/28 permit
52.95.48.152/29 permit
52.95.49.88/29 permit
@@ -214,7 +216,6 @@
52.100.0.0/14 permit
52.103.0.0/17 permit
52.119.213.144/28 permit
52.160.39.140 permit
52.165.175.144 permit
52.185.106.240/28 permit
52.200.59.0/24 permit
@@ -226,37 +227,33 @@
52.222.75.85 permit
52.222.89.228 permit
52.234.172.96/28 permit
52.235.253.128 permit
52.236.28.240/28 permit
52.244.206.214 permit
52.247.53.144 permit
52.250.107.196 permit
52.250.126.174 permit
54.90.148.255 permit
54.165.19.38 permit
54.172.97.247 permit
54.174.52.0/24 permit
54.174.53.128/30 permit
54.174.57.0/24 permit
54.174.59.0/24 permit
54.174.60.0/23 permit
54.174.63.0/24 permit
54.186.193.102 permit
54.191.223.56 permit
54.194.61.95 permit
54.195.113.45 permit
54.213.20.246 permit
54.214.39.184 permit
54.216.77.168 permit
54.221.227.204 permit
54.240.0.0/18 permit
54.240.64.0/19 permit
54.240.96.0/19 permit
54.241.16.209 permit
54.244.54.130 permit
54.244.242.0/24 permit
54.246.232.180 permit
54.255.61.23 permit
62.13.128.0/24 permit
62.13.128.150 permit
62.13.128.196 permit
62.13.129.128/25 permit
62.13.136.0/22 permit
62.13.140.0/22 permit
@@ -264,14 +261,13 @@
62.13.148.0/23 permit
62.13.150.0/23 permit
62.13.152.0/23 permit
62.13.159.196 permit
62.17.146.128/26 permit
62.179.121.0/24 permit
62.201.172.0/27 permit
62.201.172.32/27 permit
62.253.227.114 permit
63.32.13.159 permit
63.80.14.0/23 permit
63.111.28.137 permit
63.128.21.0/24 permit
63.143.57.128/25 permit
63.143.59.128/25 permit
@@ -284,24 +280,9 @@
64.79.155.193 permit
64.79.155.205 permit
64.79.155.206 permit
64.89.44.85 permit
64.89.45.80 permit
64.89.45.194 permit
64.89.45.196 permit
64.127.115.252 permit
64.132.88.0/23 permit
64.132.92.0/24 permit
64.147.123.17 permit
64.147.123.18 permit
64.147.123.19 permit
64.147.123.20 permit
64.147.123.21 permit
64.147.123.24 permit
64.147.123.25 permit
64.147.123.26 permit
64.147.123.27 permit
64.147.123.28 permit
64.147.123.29 permit
64.147.123.128/27 permit
64.207.219.7 permit
64.207.219.8 permit
@@ -359,23 +340,8 @@
65.154.166.0/24 permit
65.212.180.36 permit
66.102.0.0/20 permit
66.111.4.25 permit
66.111.4.26 permit
66.111.4.27 permit
66.111.4.28 permit
66.111.4.29 permit
66.111.4.221 permit
66.111.4.222 permit
66.111.4.224 permit
66.111.4.225 permit
66.111.4.229 permit
66.111.4.230 permit
66.119.150.192/26 permit
66.135.202.0/27 permit
66.135.215.0/24 permit
66.135.222.1 permit
66.162.193.226/31 permit
66.163.184.0/21 permit
66.163.184.0/24 permit
66.163.185.0/24 permit
66.163.186.0/24 permit
@@ -388,7 +354,6 @@
66.196.80.112/28 permit
66.196.80.144/29 permit
66.196.80.193 permit
66.196.81.0/24 permit
66.196.81.104/29 permit
66.196.81.112/29 permit
66.196.81.120 permit
@@ -403,7 +368,6 @@
66.196.81.228/30 permit
66.196.81.232/31 permit
66.196.81.234 permit
66.211.168.230/31 permit
66.211.170.88/29 permit
66.211.184.0/23 permit
66.218.74.64/30 permit
@@ -432,12 +396,10 @@
66.249.80.0/20 permit
67.23.31.6 permit
67.72.99.26 permit
67.195.22.0/24 permit
67.195.22.113 permit
67.195.22.116/30 permit
67.195.23.144/30 permit
67.195.23.148 permit
67.195.60.0/24 permit
67.195.60.45 permit
67.195.60.46/31 permit
67.195.60.48/31 permit
@@ -445,7 +407,6 @@
67.195.60.146 permit
67.195.60.155 permit
67.195.60.156 permit
67.195.87.0/24 permit
67.195.87.64 permit
67.195.87.81 permit
67.195.87.82/31 permit
@@ -470,7 +431,6 @@
67.228.37.4/30 permit
67.231.145.42 permit
67.231.153.30 permit
68.142.230.0/24 permit
68.142.230.64/31 permit
68.142.230.69 permit
68.142.230.70/31 permit
@@ -498,7 +458,6 @@
70.37.151.128/25 permit
70.42.149.0/24 permit
70.42.149.35 permit
72.3.237.64/28 permit
72.14.192.0/18 permit
72.21.192.0/19 permit
72.21.217.142 permit
@@ -529,7 +488,6 @@
72.30.237.180/30 permit
72.30.237.184/31 permit
72.30.237.204/30 permit
72.30.238.0/23 permit
72.30.238.116/30 permit
72.30.238.120/31 permit
72.30.238.128 permit
@@ -560,12 +518,7 @@
72.30.239.228/31 permit
72.30.239.244/30 permit
72.30.239.248/31 permit
72.34.168.76 permit
72.34.168.80 permit
72.34.168.85 permit
72.34.168.86 permit
72.52.72.32/28 permit
74.6.128.0/21 permit
74.6.128.0/24 permit
74.6.129.0/24 permit
74.6.130.0/24 permit
@@ -592,13 +545,14 @@
74.112.67.243 permit
74.125.0.0/16 permit
74.202.227.40 permit
74.208.4.192/26 permit
74.208.5.64/26 permit
74.208.122.0/26 permit
74.208.4.200 permit
74.208.4.201 permit
74.208.4.220 permit
74.208.4.221 permit
74.209.250.0/24 permit
75.2.70.75 permit
76.223.128.0/19 permit
76.223.176.0/20 permit
77.238.176.0/22 permit
77.238.176.0/24 permit
77.238.177.0/24 permit
77.238.178.0/24 permit
@@ -621,19 +575,25 @@
77.238.189.148/30 permit
81.7.169.128/25 permit
81.223.46.0/27 permit
82.165.159.0/24 permit
82.165.159.0/26 permit
82.165.229.31 permit
82.165.229.130 permit
82.165.230.21 permit
82.165.230.22 permit
82.165.159.2 permit
82.165.159.3 permit
82.165.159.4 permit
82.165.159.12 permit
82.165.159.13 permit
82.165.159.14 permit
82.165.159.34 permit
82.165.159.35 permit
82.165.159.40 permit
82.165.159.41 permit
82.165.159.42 permit
82.165.159.45 permit
82.165.159.130 permit
82.165.159.131 permit
84.116.6.0/23 permit
84.116.36.0/24 permit
84.116.50.0/23 permit
85.158.136.0/21 permit
86.61.88.25 permit
87.198.219.130 permit
87.198.219.153 permit
87.238.80.0/21 permit
87.248.103.12 permit
87.248.103.21 permit
@@ -673,6 +633,7 @@
87.253.232.0/21 permit
89.22.108.0/24 permit
91.211.240.0/22 permit
94.169.2.0/23 permit
94.245.112.0/27 permit
94.245.112.10/31 permit
95.131.104.0/21 permit
@@ -686,7 +647,6 @@
98.136.44.181 permit
98.136.44.182/31 permit
98.136.44.184 permit
98.136.164.0/24 permit
98.136.164.36/31 permit
98.136.164.64/29 permit
98.136.164.72/30 permit
@@ -694,7 +654,6 @@
98.136.164.78 permit
98.136.172.32/30 permit
98.136.172.36/31 permit
98.136.185.0/24 permit
98.136.185.29 permit
98.136.185.42/31 permit
98.136.185.46 permit
@@ -729,7 +688,6 @@
98.136.215.184 permit
98.136.215.208/30 permit
98.136.215.212/31 permit
98.136.217.0/24 permit
98.136.217.1 permit
98.136.217.2 permit
98.136.217.3 permit
@@ -739,14 +697,12 @@
98.136.217.12/30 permit
98.136.217.16/30 permit
98.136.217.20/30 permit
98.136.218.0/24 permit
98.136.218.39 permit
98.136.218.40/29 permit
98.136.218.48/28 permit
98.136.218.67 permit
98.136.218.68/30 permit
98.136.218.72/30 permit
98.137.12.0/24 permit
98.137.12.48/30 permit
98.137.12.52/31 permit
98.137.12.54 permit
@@ -784,7 +740,6 @@
98.137.13.132 permit
98.137.13.137 permit
98.137.13.138 permit
98.137.64.0/21 permit
98.137.64.0/24 permit
98.137.65.0/24 permit
98.137.66.0/24 permit
@@ -808,7 +763,6 @@
98.138.83.176/31 permit
98.138.83.179 permit
98.138.83.180/31 permit
98.138.84.0/22 permit
98.138.84.37 permit
98.138.84.38/31 permit
98.138.84.40/29 permit
@@ -849,7 +803,6 @@
98.138.87.148/31 permit
98.138.87.192/30 permit
98.138.87.196/31 permit
98.138.88.0/22 permit
98.138.88.105 permit
98.138.88.106 permit
98.138.88.128/30 permit
@@ -889,7 +842,6 @@
98.138.91.2/31 permit
98.138.91.4/31 permit
98.138.91.6 permit
98.138.100.0/23 permit
98.138.100.220/30 permit
98.138.100.224/30 permit
98.138.100.228/31 permit
@@ -899,7 +851,6 @@
98.138.104.100 permit
98.138.104.112/30 permit
98.138.104.116 permit
98.138.120.0/24 permit
98.138.120.36/30 permit
98.138.120.48/28 permit
98.138.197.46/31 permit
@@ -992,12 +943,10 @@
98.138.213.238/31 permit
98.138.213.240/31 permit
98.138.213.242 permit
98.138.215.0/24 permit
98.138.215.12/30 permit
98.138.215.16/28 permit
98.138.217.216/30 permit
98.138.217.220/31 permit
98.138.226.0/24 permit
98.138.226.30/31 permit
98.138.226.56/29 permit
98.138.226.64/30 permit
@@ -1023,21 +972,18 @@
98.138.227.108/31 permit
98.138.227.128/30 permit
98.138.227.132/31 permit
98.138.229.0/24 permit
98.138.229.24/29 permit
98.138.229.32/31 permit
98.138.229.122/31 permit
98.138.229.138/31 permit
98.138.229.154/31 permit
98.138.229.170/31 permit
98.139.164.0/24 permit
98.139.164.96/30 permit
98.139.164.100/30 permit
98.139.164.104/29 permit
98.139.164.112/30 permit
98.139.172.112/30 permit
98.139.172.116/31 permit
98.139.175.0/24 permit
98.139.175.65 permit
98.139.175.66/31 permit
98.139.175.68/30 permit
@@ -1062,10 +1008,8 @@
98.139.210.196/31 permit
98.139.210.202/31 permit
98.139.210.204/30 permit
98.139.211.0/24 permit
98.139.211.160/30 permit
98.139.211.192/28 permit
98.139.212.0/23 permit
98.139.212.160/28 permit
98.139.212.176/29 permit
98.139.212.184/30 permit
@@ -1080,7 +1024,6 @@
98.139.214.155 permit
98.139.214.156/30 permit
98.139.214.221 permit
98.139.215.0/24 permit
98.139.215.228/31 permit
98.139.215.230 permit
98.139.215.248/30 permit
@@ -1139,14 +1082,12 @@
98.139.220.243 permit
98.139.220.245 permit
98.139.220.253 permit
98.139.221.0/24 permit
98.139.221.43 permit
98.139.221.60/30 permit
98.139.221.156/30 permit
98.139.221.232/30 permit
98.139.221.236/31 permit
98.139.221.250 permit
98.139.244.0/24 permit
98.139.244.47 permit
98.139.244.49 permit
98.139.244.50/31 permit
@@ -1186,6 +1127,7 @@
98.139.245.208/30 permit
98.139.245.212/31 permit
99.78.197.208/28 permit
99.83.190.102 permit
103.2.140.0/22 permit
103.9.96.0/22 permit
103.28.42.0/24 permit
@@ -1226,7 +1168,6 @@
106.10.146.52/31 permit
106.10.146.224/30 permit
106.10.146.228/31 permit
106.10.148.0/24 permit
106.10.148.48/30 permit
106.10.148.52/31 permit
106.10.148.68/30 permit
@@ -1239,7 +1180,6 @@
106.10.149.30 permit
106.10.149.160/30 permit
106.10.149.164/31 permit
106.10.150.0/23 permit
106.10.150.23 permit
106.10.150.24/30 permit
106.10.150.28/31 permit
@@ -1278,7 +1218,6 @@
106.10.151.250/31 permit
106.10.151.252/31 permit
106.10.151.254 permit
106.10.167.0/24 permit
106.10.167.72 permit
106.10.167.128/27 permit
106.10.167.160/28 permit
@@ -1300,7 +1239,6 @@
106.10.174.120/30 permit
106.10.174.154/31 permit
106.10.174.156/30 permit
106.10.176.0/24 permit
106.10.176.32/29 permit
106.10.176.48 permit
106.10.176.112 permit
@@ -1319,7 +1257,6 @@
106.10.196.43 permit
106.10.196.44/30 permit
106.10.196.48 permit
106.10.240.0/22 permit
106.10.240.0/24 permit
106.10.241.0/24 permit
106.10.242.0/24 permit
@@ -1327,6 +1264,7 @@
106.10.244.0/24 permit
106.39.212.64/29 permit
106.50.16.0/28 permit
107.20.210.250 permit
108.174.0.0/24 permit
108.174.0.215 permit
108.174.3.0/24 permit
@@ -1337,6 +1275,7 @@
108.175.30.45 permit
108.177.8.0/21 permit
108.177.96.0/19 permit
108.179.144.0/20 permit
109.237.142.0/24 permit
111.221.23.128/25 permit
111.221.26.0/27 permit
@@ -1345,7 +1284,6 @@
111.221.112.0/21 permit
112.19.199.64/29 permit
112.19.242.64/29 permit
116.214.12.0/24 permit
116.214.12.47 permit
116.214.12.48/31 permit
116.214.12.56/31 permit
@@ -1364,7 +1302,6 @@
121.244.91.48 permit
122.15.156.182 permit
123.126.78.64/29 permit
124.108.96.0/24 permit
124.108.96.24/31 permit
124.108.96.28/31 permit
124.108.96.70/31 permit
@@ -1426,6 +1363,7 @@
135.84.216.0/22 permit
136.143.160.0/24 permit
136.143.161.0/24 permit
136.143.178.49 permit
136.143.182.0/23 permit
136.143.184.0/24 permit
136.143.188.0/24 permit
@@ -1447,6 +1385,12 @@
139.180.17.0/24 permit
141.148.159.229 permit
141.193.32.0/23 permit
141.193.184.32/27 permit
141.193.184.64/26 permit
141.193.184.128/25 permit
141.193.185.32/27 permit
141.193.185.64/26 permit
141.193.185.128/25 permit
143.55.224.0/21 permit
143.55.232.0/22 permit
143.55.236.0/22 permit
@@ -1460,6 +1404,7 @@
144.178.38.0/24 permit
145.253.228.160/29 permit
145.253.239.128/29 permit
146.20.14.104/30 permit
146.20.112.0/26 permit
146.20.113.0/24 permit
146.20.191.0/24 permit
@@ -1474,6 +1419,7 @@
148.105.0.0/16 permit
148.105.8.0/21 permit
149.72.0.0/16 permit
149.72.223.204 permit
149.72.248.236 permit
149.97.173.180 permit
150.230.98.160 permit
@@ -1531,9 +1477,11 @@
161.71.64.0/20 permit
162.247.216.0/22 permit
163.47.180.0/22 permit
163.47.180.0/23 permit
163.114.130.16 permit
163.114.132.120 permit
163.114.134.16 permit
163.114.135.16 permit
164.177.132.168/30 permit
165.173.128.0/24 permit
166.78.68.0/22 permit
166.78.68.221 permit
@@ -1554,8 +1502,6 @@
167.89.75.164 permit
167.89.101.2 permit
167.89.101.192/28 permit
167.216.129.210 permit
167.216.131.180 permit
167.220.67.232/29 permit
168.138.5.36 permit
168.138.73.51 permit
@@ -1567,6 +1513,7 @@
169.148.131.0/24 permit
169.148.142.10 permit
169.148.144.0/25 permit
169.148.144.10 permit
170.10.68.0/22 permit
170.10.128.0/24 permit
170.10.129.0/24 permit
@@ -1604,14 +1551,14 @@
182.50.76.0/22 permit
182.50.78.64/28 permit
183.240.219.64/29 permit
185.4.120.0/23 permit
185.4.122.0/24 permit
185.4.120.0/22 permit
185.12.80.0/22 permit
185.58.84.93 permit
185.80.93.204 permit
185.80.93.227 permit
185.80.95.31 permit
185.90.20.0/22 permit
185.138.56.128/25 permit
185.189.236.0/22 permit
185.211.120.0/22 permit
185.250.236.0/22 permit
@@ -1628,7 +1575,6 @@
188.125.68.184 permit
188.125.68.186 permit
188.125.68.192 permit
188.125.69.0/24 permit
188.125.69.105 permit
188.125.69.110 permit
188.125.69.112 permit
@@ -1671,9 +1617,6 @@
192.0.64.0/18 permit
192.18.139.154 permit
192.30.252.0/22 permit
192.64.236.0/24 permit
192.64.237.0/24 permit
192.64.238.0/24 permit
192.161.144.0/20 permit
192.162.87.0/24 permit
192.237.158.0/23 permit
@@ -1689,7 +1632,6 @@
193.122.128.100 permit
193.123.56.63 permit
194.19.134.0/25 permit
194.64.234.128/27 permit
194.64.234.129 permit
194.106.220.0/23 permit
194.113.24.0/22 permit
@@ -1715,6 +1657,9 @@
198.61.254.231 permit
198.178.234.57 permit
198.244.48.0/20 permit
198.244.59.30 permit
198.244.59.33 permit
198.244.59.35 permit
198.244.60.0/22 permit
198.245.80.0/20 permit
198.245.81.0/24 permit
@@ -1726,6 +1671,9 @@
199.34.22.36 permit
199.59.148.0/22 permit
199.67.80.2 permit
199.67.80.20 permit
199.67.82.2 permit
199.67.82.20 permit
199.67.84.0/24 permit
199.67.86.0/24 permit
199.67.88.0/24 permit
@@ -1753,7 +1701,6 @@
203.188.194.251 permit
203.188.195.240/30 permit
203.188.195.244/31 permit
203.188.197.0/24 permit
203.188.197.193 permit
203.188.197.194/31 permit
203.188.197.196/30 permit
@@ -1763,7 +1710,6 @@
203.188.197.216/29 permit
203.188.197.232/29 permit
203.188.197.240/29 permit
203.188.200.0/24 permit
203.188.200.56/31 permit
203.188.200.58 permit
203.188.200.60/30 permit
@@ -1779,11 +1725,9 @@
203.209.230.76/31 permit
204.11.168.0/21 permit
204.13.11.48/29 permit
204.13.11.48/30 permit
204.14.232.0/21 permit
204.14.232.64/28 permit
204.14.234.64/28 permit
204.29.186.0/23 permit
204.75.142.0/24 permit
204.79.197.212 permit
204.92.114.187 permit
@@ -1832,6 +1776,7 @@
207.67.98.192/27 permit
207.68.176.0/26 permit
207.68.176.96/27 permit
207.97.204.96/29 permit
207.126.144.0/20 permit
207.171.160.0/19 permit
207.211.30.64/26 permit
@@ -1845,11 +1790,7 @@
208.43.21.28/30 permit
208.43.21.64/29 permit
208.43.21.72/30 permit
208.46.212.80 permit
208.46.212.208/31 permit
208.46.212.210 permit
208.64.132.0/22 permit
208.71.40.0/24 permit
208.71.40.63 permit
208.71.40.64/31 permit
208.71.40.174/31 permit
@@ -1868,18 +1809,15 @@
208.71.41.172/31 permit
208.71.41.188/30 permit
208.71.41.192/31 permit
208.71.42.0/24 permit
208.71.42.190/31 permit
208.71.42.192/28 permit
208.71.42.208/30 permit
208.71.42.212/31 permit
208.71.42.214 permit
208.72.249.240/29 permit
208.74.204.0/22 permit
208.74.204.5 permit
208.74.204.9 permit
208.75.120.0/22 permit
208.75.121.246 permit
208.75.122.246 permit
208.82.237.96/29 permit
208.82.237.104/31 permit
208.82.238.96/29 permit
@@ -1898,10 +1836,8 @@
209.67.98.46 permit
209.67.98.59 permit
209.85.128.0/17 permit
212.82.96.0/24 permit
212.82.96.32/27 permit
212.82.96.64/29 permit
212.82.98.0/24 permit
212.82.98.32/29 permit
212.82.98.64/27 permit
212.82.98.96/30 permit
@@ -1938,12 +1874,41 @@
212.82.111.228/31 permit
212.82.111.230 permit
212.123.28.40 permit
212.227.15.0/24 permit
212.227.15.0/25 permit
212.227.17.0/27 permit
212.227.126.128/25 permit
212.227.15.3 permit
212.227.15.4 permit
212.227.15.5 permit
212.227.15.6 permit
212.227.15.14 permit
212.227.15.15 permit
212.227.15.18 permit
212.227.15.19 permit
212.227.15.25 permit
212.227.15.26 permit
212.227.15.29 permit
212.227.15.44 permit
212.227.15.45 permit
212.227.15.46 permit
212.227.15.47 permit
212.227.15.50 permit
212.227.15.52 permit
212.227.15.53 permit
212.227.15.54 permit
212.227.15.55 permit
212.227.17.11 permit
212.227.17.12 permit
212.227.17.18 permit
212.227.17.19 permit
212.227.17.20 permit
212.227.17.21 permit
212.227.17.22 permit
212.227.17.26 permit
212.227.17.28 permit
212.227.17.29 permit
212.227.126.224 permit
212.227.126.225 permit
212.227.126.226 permit
212.227.126.227 permit
213.46.255.0/24 permit
213.165.64.0/23 permit
213.199.128.139 permit
213.199.128.145 permit
213.199.138.181 permit
@@ -1954,7 +1919,6 @@
216.17.150.251 permit
216.22.15.224/27 permit
216.24.224.0/20 permit
216.39.60.0/23 permit
216.39.60.154/31 permit
216.39.60.156/30 permit
216.39.60.160/30 permit
@@ -1972,14 +1936,12 @@
216.39.61.170 permit
216.39.61.175 permit
216.39.61.238/31 permit
216.39.62.0/24 permit
216.39.62.32/28 permit
216.39.62.48/29 permit
216.39.62.56/30 permit
216.39.62.60/31 permit
216.39.62.136/29 permit
216.39.62.144/31 permit
216.46.168.0/24 permit
216.58.192.0/19 permit
216.66.217.240/29 permit
216.71.138.33 permit
@@ -1992,12 +1954,8 @@
216.98.158.0/24 permit
216.99.5.67 permit
216.99.5.68 permit
216.109.114.0/24 permit
216.109.114.32/27 permit
216.109.114.64/29 permit
216.113.160.0/24 permit
216.113.172.0/25 permit
216.113.175.0/24 permit
216.128.126.97 permit
216.136.162.65 permit
216.136.162.120/29 permit
@@ -2007,10 +1965,10 @@
216.203.30.55 permit
216.203.33.178/31 permit
216.205.24.0/24 permit
216.221.160.0/19 permit
216.239.32.0/19 permit
217.72.192.64/26 permit
217.72.192.248/29 permit
217.72.207.0/27 permit
217.72.192.77 permit
217.72.192.78 permit
217.77.141.52 permit
217.77.141.59 permit
217.175.194.0/24 permit
@@ -2028,6 +1986,8 @@
2603:1030:20e:3::23c permit
2603:1030:b:3::152 permit
2603:1030:c02:8::14 permit
2607:13c0:0001:0000:0000:0000:0000:7000/116 permit
2607:13c0:0002:0000:0000:0000:0000:1000/116 permit
2607:f8b0:4000::/36 permit
2620:109:c003:104::/64 permit
2620:109:c003:104::215 permit
@@ -2036,6 +1996,8 @@
2620:109:c00d:104::/64 permit
2620:10d:c090:400::8:1 permit
2620:10d:c091:400::8:1 permit
2620:10d:c09b:400::8:1 permit
2620:10d:c09c:400::8:1 permit
2620:119:50c0:207::/64 permit
2620:119:50c0:207::215 permit
2800:3f0:4000::/36 permit

View File

@@ -49,27 +49,49 @@ $from = $headers['From'];
$empty_footer = json_encode(array(
'html' => '',
'plain' => '',
'skip_replies' => 0,
'vars' => array()
));
error_log("FOOTER: checking for domain " . $domain . ", user " . $username . " and address " . $from . PHP_EOL);
try {
$stmt = $pdo->prepare("SELECT `plain`, `html`, `mbox_exclude` FROM `domain_wide_footer`
// try get $target_domain if $domain is an alias_domain
$stmt = $pdo->prepare("SELECT `target_domain` FROM `alias_domain`
WHERE `alias_domain` = :alias_domain");
$stmt->execute(array(
':alias_domain' => $domain
));
$alias_domain = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$alias_domain) {
$target_domain = $domain;
} else {
$target_domain = $alias_domain['target_domain'];
}
// get footer associated with the domain
$stmt = $pdo->prepare("SELECT `plain`, `html`, `mbox_exclude`, `alias_domain_exclude`, `skip_replies` FROM `domain_wide_footer`
WHERE `domain` = :domain");
$stmt->execute(array(
':domain' => $domain
':domain' => $target_domain
));
$footer = $stmt->fetch(PDO::FETCH_ASSOC);
// check if the sender is excluded
if (in_array($from, json_decode($footer['mbox_exclude']))){
$footer = false;
}
if (in_array($domain, json_decode($footer['alias_domain_exclude']))){
$footer = false;
}
if (empty($footer)){
echo $empty_footer;
exit;
}
error_log("FOOTER: " . json_encode($footer) . PHP_EOL);
// footer will be applied
// get custom mailbox attributes to insert into the footer
$stmt = $pdo->prepare("SELECT `custom_attributes` FROM `mailbox` WHERE `username` = :username");
$stmt->execute(array(
':username' => $username

View File

@@ -6,3 +6,4 @@ disable_monitoring = true;
# In case a task times out (like DNS lookup), soft reject the message
# instead of silently accepting the message without further processing.
soft_reject_on_timeout = true;
local_addrs = /etc/rspamd/custom/mailcow_networks.map;

View File

@@ -1,20 +1,4 @@
rbls {
sorbs {
symbol = "RBL_SORBS";
rbl = "dnsbl.sorbs.net";
returncodes {
# http:// www.sorbs.net/general/using.shtml
RBL_SORBS_HTTP = "127.0.0.2";
RBL_SORBS_SOCKS = "127.0.0.3";
RBL_SORBS_MISC = "127.0.0.4";
RBL_SORBS_SMTP = "127.0.0.5";
RBL_SORBS_RECENT = "127.0.0.6";
RBL_SORBS_WEB = "127.0.0.7";
RBL_SORBS_DUL = "127.0.0.10";
RBL_SORBS_BLOCK = "127.0.0.8";
RBL_SORBS_ZOMBIE = "127.0.0.9";
}
}
interserver_ip {
symbol = "RBL_INTERSERVER_IP";
rbl = "rbl.interserver.net";

View File

@@ -5,46 +5,6 @@ symbols = {
"RBL_UCEPROTECT_LEVEL2" {
score = 1.5;
}
"RBL_SORBS" {
score = 0.0;
description = "Unrecognised result from SORBS RBL";
}
"RBL_SORBS_HTTP" {
score = 2.5;
description = "List of Open HTTP Proxy Servers.";
}
"RBL_SORBS_SOCKS" {
score = 2.5;
description = "List of Open SOCKS Proxy Servers.";
}
"RBL_SORBS_MISC" {
score = 1.0;
description = "List of open Proxy Servers not listed in the SOCKS or HTTP lists.";
}
"RBL_SORBS_SMTP" {
score = 4.0;
description = "List of Open SMTP relay servers.";
}
"RBL_SORBS_RECENT" {
score = 2.0;
description = "List of hosts that have been noted as sending spam/UCE/UBE to the admins of SORBS within the last 28 days (includes new.spam.dnsbl.sorbs.net).";
}
"RBL_SORBS_WEB" {
score = 2.0;
description = "List of web (WWW) servers which have spammer abusable vulnerabilities (e.g. FormMail scripts)";
}
"RBL_SORBS_DUL" {
score = 2.0;
description = "Dynamic IP Address ranges (NOT a Dial Up list!)";
}
"RBL_SORBS_BLOCK" {
score = 0.5;
description = "List of hosts demanding that they never be tested by SORBS.";
}
"RBL_SORBS_ZOMBIE" {
score = 2.0;
description = "List of networks hijacked from their original owners, some of which have already used for spamming.";
}
"RECEIVED_SPAMHAUS_XBL" {
weight = 0.0;
description = "Received address is listed in ZEN XBL";

View File

@@ -567,6 +567,14 @@ rspamd_config:register_symbol({
if footer and type(footer) == "table" and (footer.html and footer.html ~= "" or footer.plain and footer.plain ~= "") then
rspamd_logger.infox(rspamd_config, "found domain wide footer for user %s: html=%s, plain=%s, vars=%s", uname, footer.html, footer.plain, footer.vars)
if footer.skip_replies ~= 0 then
in_reply_to = task:get_header_raw('in-reply-to')
if in_reply_to then
rspamd_logger.infox(rspamd_config, "mail is a reply - skip footer")
return
end
end
local envfrom_mime = task:get_from(2)
local from_name = ""
if envfrom_mime and envfrom_mime[1].name then
@@ -613,10 +621,24 @@ rspamd_config:register_symbol({
local nct = string.format('%s: %s/%s; charset=utf-8',
'Content-Type', rewrite.new_ct.type, rewrite.new_ct.subtype)
out[#out + 1] = nct
-- update Content-Type header
task:set_milter_reply({
remove_headers = {['Content-Type'] = 0},
})
task:set_milter_reply({
add_headers = {['Content-Type'] = string.format('%s/%s; charset=utf-8', rewrite.new_ct.type, rewrite.new_ct.subtype)}
})
return
elseif name:lower() == 'content-transfer-encoding' then
out[#out + 1] = string.format('%s: %s',
'Content-Transfer-Encoding', 'quoted-printable')
-- update Content-Transfer-Encoding header
task:set_milter_reply({
remove_headers = {['Content-Transfer-Encoding'] = 0},
})
task:set_milter_reply({
add_headers = {['Content-Transfer-Encoding'] = 'quoted-printable'}
})
seen_cte = true
return
end

View File

@@ -12,9 +12,13 @@
SOGoJunkFolderName= "Junk";
SOGoMailDomain = "sogo.local";
SOGoEnableEMailAlarms = YES;
SOGoMailHideInlineAttachments = YES;
SOGoFoldersSendEMailNotifications = YES;
SOGoForwardEnabled = YES;
// Option to set Users as admin to globally manage calendar permissions etc. Disabled by default
// SOGoSuperUsernames = ("moo@example.com");
SOGoUIAdditionalJSFiles = (
js/theme.js,
js/custom-sogo.js
@@ -37,6 +41,7 @@
SOGoLanguage = English;
SOGoMailAuxiliaryUserAccountsEnabled = YES;
// SOGoCreateIdentitiesDisabled = NO;
SOGoMailCustomFromEnabled = YES;
SOGoMailingMechanism = smtp;
SOGoSMTPAuthenticationType = plain;

View File

@@ -228,8 +228,8 @@ legend {
margin-top: 20px;
}
.slave-info {
padding: 15px 0px 15px 15px;
font-weight: bold;
color: orange;
}
.alert-hr {
margin:3px 0px;

View File

@@ -175,6 +175,9 @@ pre {
background-color: #282828;
border: 1px solid #555;
}
.form-control {
background-color: transparent;
}
input.form-control, textarea.form-control {
color: #e2e2e2 !important;
background-color: #424242 !important;

View File

@@ -39,9 +39,13 @@ foreach ($containers as $container => $container_info) {
$StartedAt['month'],
$StartedAt['day'],
$StartedAt['year']));
$user_tz = new DateTimeZone(getenv('TZ'));
$date->setTimezone($user_tz);
$started = $date->format('r');
try {
$user_tz = new DateTimeZone(getenv('TZ'));
$date->setTimezone($user_tz);
$started = $date->format('r');
} catch(Exception $e) {
$started = '?';
}
}
else {
$started = '?';

View File

@@ -59,7 +59,8 @@ if (isset($_SESSION['mailcow_cc_role'])) {
'domain_details' => $result,
'domain_footer' => $domain_footer,
'mailboxes' => mailbox('get', 'mailboxes', $_GET["domain"]),
'aliases' => mailbox('get', 'aliases', $_GET["domain"], 'address')
'aliases' => mailbox('get', 'aliases', $_GET["domain"], 'address'),
'alias_domains' => mailbox('get', 'alias_domains', $_GET["domain"])
];
}
}

View File

@@ -1,4 +1,11 @@
<?php
// Block requests by checking the 'Sec-Fetch-Dest' header.
if (isset($_SERVER['HTTP_SEC_FETCH_DEST']) && $_SERVER['HTTP_SEC_FETCH_DEST'] !== 'empty') {
header('HTTP/1.1 403 Forbidden');
exit;
}
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/prerequisites.inc.php';
if (!isset($_SESSION['mailcow_cc_role']) || $_SESSION['mailcow_cc_role'] != 'admin') {
exit();

View File

@@ -12,7 +12,8 @@ $alertbox_log_parser = alertbox_log_parser($_SESSION);
$alerts = [];
if (is_array($alertbox_log_parser)) {
foreach ($alertbox_log_parser as $log) {
$message = strtr($log['msg'], ["\n" => '', "\r" => '', "\t" => '<br>']);
$message = htmlspecialchars($log['msg'], ENT_QUOTES);
$message = strtr($message, ["\n" => '', "\r" => '', "\t" => '<br>']);
$alerts[trim($log['type'], '"')][] = trim($message, '"');
}
$alert = array_filter(array_unique($alerts));

View File

@@ -2,6 +2,7 @@
function customize($_action, $_item, $_data = null) {
global $redis;
global $lang;
global $LOGO_LIMITS;
switch ($_action) {
case 'add':
@@ -35,6 +36,23 @@ function customize($_action, $_item, $_data = null) {
);
return false;
}
if ($_data[$_item]['size'] > $LOGO_LIMITS['max_size']) {
$_SESSION['return'][] = array(
'type' => 'danger',
'log' => array(__FUNCTION__, $_action, $_item, $_data),
'msg' => 'img_size_exceeded'
);
return false;
}
list($width, $height) = getimagesize($_data[$_item]['tmp_name']);
if ($width > $LOGO_LIMITS['max_width'] || $height > $LOGO_LIMITS['max_height']) {
$_SESSION['return'][] = array(
'type' => 'danger',
'log' => array(__FUNCTION__, $_action, $_item, $_data),
'msg' => 'img_dimensions_exceeded'
);
return false;
}
$image = new Imagick($_data[$_item]['tmp_name']);
if ($image->valid() !== true) {
$_SESSION['return'][] = array(

View File

@@ -284,17 +284,17 @@ function last_login($action, $username, $sasl_limit_days = 7, $ui_offset = 1) {
}
if (!$sasl[$k]['location']) {
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL,"https://dfdata.bella.network/lookup/" . $sasl[$k]['real_rip']);
curl_setopt($curl, CURLOPT_URL,"https://dfdata.bella.network/country/" . $sasl[$k]['real_rip']);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_USERAGENT, 'Moocow');
curl_setopt($curl, CURLOPT_TIMEOUT, 5);
$ip_data = curl_exec($curl);
if (!curl_errno($curl)) {
$ip_data_array = json_decode($ip_data, true);
if ($ip_data_array !== false and !empty($ip_data_array['location']['shortcountry'])) {
$sasl[$k]['location'] = $ip_data_array['location']['shortcountry'];
if ($ip_data_array !== false and !empty($ip_data_array['shortcountry'])) {
$sasl[$k]['location'] = $ip_data_array['shortcountry'];
try {
$redis->hSet('IP_SHORTCOUNTRY', $sasl[$k]['real_rip'], $ip_data_array['location']['shortcountry']);
$redis->hSet('IP_SHORTCOUNTRY', $sasl[$k]['real_rip'], $ip_data_array['shortcountry']);
}
catch (RedisException $e) {
$_SESSION['return'][] = array(

View File

@@ -478,16 +478,24 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
);
return false;
}
$DOMAIN_DEFAULT_ATTRIBUTES = null;
if ($_data['template']){
$DOMAIN_DEFAULT_ATTRIBUTES = mailbox('get', 'domain_templates', $_data['template'])['attributes'];
}
if (empty($DOMAIN_DEFAULT_ATTRIBUTES)) {
$DOMAIN_DEFAULT_ATTRIBUTES = mailbox('get', 'domain_templates')[0]['attributes'];
}
$domain = idn_to_ascii(strtolower(trim($_data['domain'])), 0, INTL_IDNA_VARIANT_UTS46);
$description = $_data['description'];
if (empty($description)) $description = $domain;
$tags = (array)$_data['tags'];
$aliases = (int)$_data['aliases'];
$mailboxes = (int)$_data['mailboxes'];
$defquota = (int)$_data['defquota'];
$maxquota = (int)$_data['maxquota'];
$tags = (isset($_data['tags'])) ? (array)$_data['tags'] : $DOMAIN_DEFAULT_ATTRIBUTES['tags'];
$aliases = (isset($_data['aliases'])) ? (int)$_data['aliases'] : $DOMAIN_DEFAULT_ATTRIBUTES['max_num_aliases_for_domain'];
$mailboxes = (isset($_data['mailboxes'])) ? (int)$_data['mailboxes'] : $DOMAIN_DEFAULT_ATTRIBUTES['max_num_mboxes_for_domain'];
$defquota = (isset($_data['defquota'])) ? (int)$_data['defquota'] : $DOMAIN_DEFAULT_ATTRIBUTES['def_quota_for_mbox'] / 1024 ** 2;
$maxquota = (isset($_data['maxquota'])) ? (int)$_data['maxquota'] : $DOMAIN_DEFAULT_ATTRIBUTES['max_quota_for_mbox'] / 1024 ** 2;
$restart_sogo = (int)$_data['restart_sogo'];
$quota = (int)$_data['quota'];
$quota = (isset($_data['quota'])) ? (int)$_data['quota'] : $DOMAIN_DEFAULT_ATTRIBUTES['max_quota_for_domain'] / 1024 ** 2;
if ($defquota > $maxquota) {
$_SESSION['return'][] = array(
'type' => 'danger',
@@ -520,11 +528,11 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
);
return false;
}
$active = intval($_data['active']);
$relay_all_recipients = intval($_data['relay_all_recipients']);
$relay_unknown_only = intval($_data['relay_unknown_only']);
$backupmx = intval($_data['backupmx']);
$gal = intval($_data['gal']);
$active = (isset($_data['active'])) ? intval($_data['active']) : $DOMAIN_DEFAULT_ATTRIBUTES['active'];
$relay_all_recipients = (isset($_data['relay_all_recipients'])) ? intval($_data['relay_all_recipients']) : $DOMAIN_DEFAULT_ATTRIBUTES['relay_all_recipients'];
$relay_unknown_only = (isset($_data['relay_unknown_only'])) ? intval($_data['relay_unknown_only']) : $DOMAIN_DEFAULT_ATTRIBUTES['relay_unknown_only'];
$backupmx = (isset($_data['backupmx'])) ? intval($_data['backupmx']) : $DOMAIN_DEFAULT_ATTRIBUTES['backupmx'];
$gal = (isset($_data['gal'])) ? intval($_data['gal']) : $DOMAIN_DEFAULT_ATTRIBUTES['gal'];
if ($relay_all_recipients == 1) {
$backupmx = '1';
}
@@ -625,9 +633,13 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
);
return false;
}
if (!empty(intval($_data['rl_value']))) {
$_data['rl_value'] = (isset($_data['rl_value'])) ? intval($_data['rl_value']) : $DOMAIN_DEFAULT_ATTRIBUTES['rl_value'];
$_data['rl_frame'] = (isset($_data['rl_frame'])) ? $_data['rl_frame'] : $DOMAIN_DEFAULT_ATTRIBUTES['rl_frame'];
if (!empty($_data['rl_value']) && !empty($_data['rl_frame'])){
ratelimit('edit', 'domain', array('rl_value' => $_data['rl_value'], 'rl_frame' => $_data['rl_frame'], 'object' => $domain));
}
$_data['key_size'] = (isset($_data['key_size'])) ? intval($_data['key_size']) : $DOMAIN_DEFAULT_ATTRIBUTES['key_size'];
$_data['dkim_selector'] = (isset($_data['dkim_selector'])) ? $_data['dkim_selector'] : $DOMAIN_DEFAULT_ATTRIBUTES['dkim_selector'];
if (!empty($_data['key_size']) && !empty($_data['dkim_selector'])) {
if (!empty($redis->hGet('DKIM_SELECTORS', $domain))) {
$_SESSION['return'][] = array(
@@ -1006,11 +1018,23 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
);
return false;
}
if (empty($name)) {
$name = $local_part;
}
$template_attr = null;
if ($_data['template']){
$template_attr = mailbox('get', 'mailbox_templates', $_data['template'])['attributes'];
}
if (empty($template_attr)) {
$template_attr = mailbox('get', 'mailbox_templates')[0]['attributes'];
}
$MAILBOX_DEFAULT_ATTRIBUTES = array_merge($MAILBOX_DEFAULT_ATTRIBUTES, $template_attr);
$password = $_data['password'];
$password2 = $_data['password2'];
$name = ltrim(rtrim($_data['name'], '>'), '<');
$tags = $_data['tags'];
$quota_m = intval($_data['quota']);
$tags = (isset($_data['tags'])) ? $_data['tags'] : $MAILBOX_DEFAULT_ATTRIBUTES['tags'];
$quota_m = (isset($_data['quota'])) ? intval($_data['quota']) : intval($MAILBOX_DEFAULT_ATTRIBUTES['quota']) / 1024 ** 2;
if ((!isset($_SESSION['acl']['unlimited_quota']) || $_SESSION['acl']['unlimited_quota'] != "1") && $quota_m === 0) {
$_SESSION['return'][] = array(
'type' => 'danger',
@@ -1019,9 +1043,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
);
return false;
}
if (empty($name)) {
$name = $local_part;
}
if (isset($_data['protocol_access'])) {
$_data['protocol_access'] = (array)$_data['protocol_access'];
$_data['imap_access'] = (in_array('imap', $_data['protocol_access'])) ? 1 : 0;
@@ -1029,7 +1051,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
$_data['smtp_access'] = (in_array('smtp', $_data['protocol_access'])) ? 1 : 0;
$_data['sieve_access'] = (in_array('sieve', $_data['protocol_access'])) ? 1 : 0;
}
$active = intval($_data['active']);
$active = (isset($_data['active'])) ? intval($_data['active']) : intval($MAILBOX_DEFAULT_ATTRIBUTES['active']);
$force_pw_update = (isset($_data['force_pw_update'])) ? intval($_data['force_pw_update']) : intval($MAILBOX_DEFAULT_ATTRIBUTES['force_pw_update']);
$tls_enforce_in = (isset($_data['tls_enforce_in'])) ? intval($_data['tls_enforce_in']) : intval($MAILBOX_DEFAULT_ATTRIBUTES['tls_enforce_in']);
$tls_enforce_out = (isset($_data['tls_enforce_out'])) ? intval($_data['tls_enforce_out']) : intval($MAILBOX_DEFAULT_ATTRIBUTES['tls_enforce_out']);
@@ -1227,12 +1249,29 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
$_data['quarantine_notification'] = (in_array('quarantine_notification', $_data['acl'])) ? 1 : 0;
$_data['quarantine_category'] = (in_array('quarantine_category', $_data['acl'])) ? 1 : 0;
$_data['app_passwds'] = (in_array('app_passwds', $_data['acl'])) ? 1 : 0;
} else {
$_data['spam_alias'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['acl_spam_alias']);
$_data['tls_policy'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['acl_tls_policy']);
$_data['spam_score'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['acl_spam_score']);
$_data['spam_policy'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['acl_spam_policy']);
$_data['delimiter_action'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['acl_delimiter_action']);
$_data['syncjobs'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['acl_syncjobs']);
$_data['eas_reset'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['acl_eas_reset']);
$_data['sogo_profile_reset'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['acl_sogo_profile_reset']);
$_data['pushover'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['acl_pushover']);
$_data['quarantine'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['acl_quarantine']);
$_data['quarantine_attachments'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['acl_quarantine_attachments']);
$_data['quarantine_notification'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['acl_quarantine_notification']);
$_data['quarantine_category'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['acl_quarantine_category']);
$_data['app_passwds'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['acl_app_passwds']);
}
try {
$stmt = $pdo->prepare("INSERT INTO `user_acl`
(`username`, `spam_alias`, `tls_policy`, `spam_score`, `spam_policy`, `delimiter_action`, `syncjobs`, `eas_reset`, `sogo_profile_reset`,
`pushover`, `quarantine`, `quarantine_attachments`, `quarantine_notification`, `quarantine_category`, `app_passwds`)
`pushover`, `quarantine`, `quarantine_attachments`, `quarantine_notification`, `quarantine_category`, `app_passwds`)
VALUES (:username, :spam_alias, :tls_policy, :spam_score, :spam_policy, :delimiter_action, :syncjobs, :eas_reset, :sogo_profile_reset,
:pushover, :quarantine, :quarantine_attachments, :quarantine_notification, :quarantine_category, :app_passwds) ");
:pushover, :quarantine, :quarantine_attachments, :quarantine_notification, :quarantine_category, :app_passwds) ");
$stmt->execute(array(
':username' => $username,
':spam_alias' => $_data['spam_alias'],
@@ -1251,31 +1290,17 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
':app_passwds' => $_data['app_passwds']
));
}
else {
$stmt = $pdo->prepare("INSERT INTO `user_acl`
(`username`, `spam_alias`, `tls_policy`, `spam_score`, `spam_policy`, `delimiter_action`, `syncjobs`, `eas_reset`, `sogo_profile_reset`,
`pushover`, `quarantine`, `quarantine_attachments`, `quarantine_notification`, `quarantine_category`, `app_passwds`)
VALUES (:username, :spam_alias, :tls_policy, :spam_score, :spam_policy, :delimiter_action, :syncjobs, :eas_reset, :sogo_profile_reset,
:pushover, :quarantine, :quarantine_attachments, :quarantine_notification, :quarantine_category, :app_passwds) ");
$stmt->execute(array(
':username' => $username,
':spam_alias' => 0,
':tls_policy' => 0,
':spam_score' => 0,
':spam_policy' => 0,
':delimiter_action' => 0,
':syncjobs' => 0,
':eas_reset' => 0,
':sogo_profile_reset' => 0,
':pushover' => 0,
':quarantine' => 0,
':quarantine_attachments' => 0,
':quarantine_notification' => 0,
':quarantine_category' => 0,
':app_passwds' => 0
));
catch (PDOException $e) {
$_SESSION['return'][] = array(
'type' => 'danger',
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
'msg' => $e->getMessage()
);
return false;
}
$_data['rl_frame'] = (isset($_data['rl_frame'])) ? $_data['rl_frame'] : $MAILBOX_DEFAULT_ATTRIBUTES['rl_frame'];
$_data['rl_value'] = (isset($_data['rl_value'])) ? $_data['rl_value'] : $MAILBOX_DEFAULT_ATTRIBUTES['rl_value'];
if (isset($_data['rl_frame']) && isset($_data['rl_value'])){
ratelimit('edit', 'mailbox', array(
'object' => $username,
@@ -1524,17 +1549,17 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
$attr["tls_enforce_out"] = isset($_data['tls_enforce_out']) ? intval($_data['tls_enforce_out']) : intval($MAILBOX_DEFAULT_ATTRIBUTES['tls_enforce_out']);
if (isset($_data['protocol_access'])) {
$_data['protocol_access'] = (array)$_data['protocol_access'];
$attr['imap_access'] = (in_array('imap', $_data['protocol_access'])) ? 1 : intval($MAILBOX_DEFAULT_ATTRIBUTES['imap_access']);
$attr['pop3_access'] = (in_array('pop3', $_data['protocol_access'])) ? 1 : intval($MAILBOX_DEFAULT_ATTRIBUTES['pop3_access']);
$attr['smtp_access'] = (in_array('smtp', $_data['protocol_access'])) ? 1 : intval($MAILBOX_DEFAULT_ATTRIBUTES['smtp_access']);
$attr['sieve_access'] = (in_array('sieve', $_data['protocol_access'])) ? 1 : intval($MAILBOX_DEFAULT_ATTRIBUTES['sieve_access']);
$attr['imap_access'] = (in_array('imap', $_data['protocol_access'])) ? 1 : 0;
$attr['pop3_access'] = (in_array('pop3', $_data['protocol_access'])) ? 1 : 0;
$attr['smtp_access'] = (in_array('smtp', $_data['protocol_access'])) ? 1 : 0;
$attr['sieve_access'] = (in_array('sieve', $_data['protocol_access'])) ? 1 : 0;
}
else {
$attr['imap_access'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['imap_access']);
$attr['pop3_access'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['pop3_access']);
$attr['smtp_access'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['smtp_access']);
$attr['sieve_access'] = intval($MAILBOX_DEFAULT_ATTRIBUTES['sieve_access']);
}
}
if (isset($_data['acl'])) {
$_data['acl'] = (array)$_data['acl'];
$attr['acl_spam_alias'] = (in_array('spam_alias', $_data['acl'])) ? 1 : 0;
@@ -3411,31 +3436,56 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
$footers = array();
$footers['html'] = isset($_data['html']) ? $_data['html'] : '';
$footers['plain'] = isset($_data['plain']) ? $_data['plain'] : '';
$footers['skip_replies'] = isset($_data['skip_replies']) ? (int)$_data['skip_replies'] : 0;
$footers['mbox_exclude'] = array();
if (isset($_data["mbox_exclude"])){
if (!is_array($_data["mbox_exclude"])) {
$_data["mbox_exclude"] = array($_data["mbox_exclude"]);
$footers['alias_domain_exclude'] = array();
if (isset($_data["exclude"])){
if (!is_array($_data["exclude"])) {
$_data["exclude"] = array($_data["exclude"]);
}
foreach ($_data["mbox_exclude"] as $mailbox) {
if (!filter_var($mailbox, FILTER_VALIDATE_EMAIL)) {
foreach ($_data["exclude"] as $exclude) {
if (filter_var($exclude, FILTER_VALIDATE_EMAIL)) {
$stmt = $pdo->prepare("SELECT `address` FROM `alias` WHERE `address` = :address
UNION
SELECT `username` FROM `mailbox` WHERE `username` = :username");
$stmt->execute(array(
':address' => $exclude,
':username' => $exclude,
));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if(!$row){
$_SESSION['return'][] = array(
'type' => 'danger',
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
'msg' => array('username_invalid', $exclude)
);
continue;
}
array_push($footers['mbox_exclude'], $exclude);
}
elseif (is_valid_domain_name($exclude)) {
$stmt = $pdo->prepare("SELECT `alias_domain` FROM `alias_domain` WHERE `alias_domain` = :alias_domain");
$stmt->execute(array(
':alias_domain' => $exclude,
));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if(!$row){
$_SESSION['return'][] = array(
'type' => 'danger',
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
'msg' => array('username_invalid', $exclude)
);
continue;
}
array_push($footers['alias_domain_exclude'], $exclude);
}
else {
$_SESSION['return'][] = array(
'type' => 'danger',
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
'msg' => array('username_invalid', $mailbox)
'msg' => array('username_invalid', $exclude)
);
continue;
}
$is_now = mailbox('get', 'mailbox_details', $mailbox);
if(empty($is_now)){
$_SESSION['return'][] = array(
'type' => 'danger',
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
'msg' => array('username_invalid', $mailbox)
);
continue;
}
array_push($footers['mbox_exclude'], $mailbox);
}
}
foreach ($domains as $domain) {
@@ -3460,12 +3510,14 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
try {
$stmt = $pdo->prepare("DELETE FROM `domain_wide_footer` WHERE `domain`= :domain");
$stmt->execute(array(':domain' => $domain));
$stmt = $pdo->prepare("INSERT INTO `domain_wide_footer` (`domain`, `html`, `plain`, `mbox_exclude`) VALUES (:domain, :html, :plain, :mbox_exclude)");
$stmt = $pdo->prepare("INSERT INTO `domain_wide_footer` (`domain`, `html`, `plain`, `mbox_exclude`, `alias_domain_exclude`, `skip_replies`) VALUES (:domain, :html, :plain, :mbox_exclude, :alias_domain_exclude, :skip_replies)");
$stmt->execute(array(
':domain' => $domain,
':html' => $footers['html'],
':plain' => $footers['plain'],
':mbox_exclude' => json_encode($footers['mbox_exclude']),
':alias_domain_exclude' => json_encode($footers['alias_domain_exclude']),
':skip_replies' => $footers['skip_replies'],
));
}
catch (PDOException $e) {
@@ -4289,6 +4341,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
$domaindata['mboxes_in_domain'] = $MailboxDataDomain['count'];
$domaindata['mboxes_left'] = $row['mailboxes'] - $MailboxDataDomain['count'];
$domaindata['domain_name'] = $row['domain'];
$domaindata['domain_h_name'] = idn_to_utf8($row['domain']);
$domaindata['description'] = $row['description'];
$domaindata['max_num_aliases_for_domain'] = $row['aliases'];
$domaindata['max_num_mboxes_for_domain'] = $row['mailboxes'];
@@ -4435,7 +4488,6 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
$mailboxdata['active'] = $row['active'];
$mailboxdata['active_int'] = $row['active'];
$mailboxdata['domain'] = $row['domain'];
$mailboxdata['relayhost'] = $row['relayhost'];
$mailboxdata['name'] = $row['name'];
$mailboxdata['local_part'] = $row['local_part'];
$mailboxdata['quota'] = $row['quota'];
@@ -4622,7 +4674,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
}
try {
$stmt = $pdo->prepare("SELECT `html`, `plain`, `mbox_exclude` FROM `domain_wide_footer`
$stmt = $pdo->prepare("SELECT `html`, `plain`, `mbox_exclude`, `alias_domain_exclude`, `skip_replies` FROM `domain_wide_footer`
WHERE `domain` = :domain");
$stmt->execute(array(
':domain' => $domain

View File

@@ -143,17 +143,26 @@ function rspamd_maps($_action, $_data = null) {
return false;
}
$maps = (array)$_data['map'];
$valid_maps = array();
foreach ($maps as $map) {
$is_valid = false;
foreach ($RSPAMD_MAPS as $rspamd_map_type) {
if (!in_array($map, $rspamd_map_type)) {
$_SESSION['return'][] = array(
'type' => 'danger',
'log' => array(__FUNCTION__, $_action, '-'),
'msg' => array('global_map_invalid', $map)
);
continue;
if (in_array($map, $rspamd_map_type)) {
$is_valid = true;
break;
}
}
if ($is_valid) {
array_push($valid_maps, $map);
} else {
$_SESSION['return'][] = array(
'type' => 'danger',
'log' => array(__FUNCTION__, $_action, '-'),
'msg' => array('global_map_invalid', $map)
);
}
}
foreach ($valid_maps as $map) {
try {
if (file_exists('/rspamd_custom_maps/' . $map)) {
$map_content = trim($_data['rspamd_map_data']);

View File

@@ -49,7 +49,6 @@ $globalVariables = [
'app_links' => customize('get', 'app_links'),
'is_root_uri' => (parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) == '/'),
'uri' => $_SERVER['REQUEST_URI'],
'last_login' => last_login('get', $_SESSION['mailcow_cc_username'], 7, 0)['ui']['time']
];
foreach ($globalVariables as $globalVariableName => $globalVariableValue) {

View File

@@ -3,7 +3,7 @@ function init_db_schema() {
try {
global $pdo;
$db_version = "21112023_1644";
$db_version = "26022024_1433";
$stmt = $pdo->query("SHOW TABLES LIKE 'versions'");
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
@@ -273,6 +273,8 @@ function init_db_schema() {
"html" => "LONGTEXT",
"plain" => "LONGTEXT",
"mbox_exclude" => "JSON NOT NULL DEFAULT ('[]')",
"alias_domain_exclude" => "JSON NOT NULL DEFAULT ('[]')",
"skip_replies" => "TINYINT(1) NOT NULL DEFAULT '0'"
),
"keys" => array(
"primary" => array(
@@ -977,6 +979,18 @@ function init_db_schema() {
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"sogo_admin" => array(
"cols" => array(
"c_key" => "VARCHAR(255) NOT NULL DEFAULT ''",
"c_content" => "mediumtext NOT NULL",
),
"keys" => array(
"primary" => array(
"" => array("c_key")
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
"pushover" => array(
"cols" => array(
"username" => "VARCHAR(255) NOT NULL",

View File

@@ -0,0 +1,622 @@
<?php
/*
* Helper functions for building a DataTables server-side processing SQL query
*
* The static functions in this class are just helper functions to help build
* the SQL used in the DataTables demo server-side processing scripts. These
* functions obviously do not represent all that can be done with server-side
* processing, they are intentionally simple to show how it works. More complex
* server-side processing operations will likely require a custom script.
*
* See https://datatables.net/usage/server-side for full details on the server-
* side processing requirements of DataTables.
*
* @license MIT - https://datatables.net/license_mit
*/
class SSP {
/**
* Create the data output array for the DataTables rows
*
* @param array $columns Column information array
* @param array $data Data from the SQL get
* @return array Formatted data in a row based format
*/
static function data_output ( $columns, $data )
{
$out = array();
for ( $i=0, $ien=count($data) ; $i<$ien ; $i++ ) {
$row = array();
for ( $j=0, $jen=count($columns) ; $j<$jen ; $j++ ) {
$column = $columns[$j];
// Is there a formatter?
if ( isset( $column['formatter'] ) ) {
if(empty($column['db'])){
$row[ $column['dt'] ] = $column['formatter']( $data[$i] );
}
else{
$row[ $column['dt'] ] = $column['formatter']( $data[$i][ $column['db'] ], $data[$i] );
}
}
else {
if(!empty($column['db']) && (!isset($column['dummy']) || $column['dummy'] !== true)){
$row[ $column['dt'] ] = $data[$i][ $columns[$j]['db'] ];
}
else{
$row[ $column['dt'] ] = "";
}
}
}
$out[] = $row;
}
return $out;
}
/**
* Database connection
*
* Obtain an PHP PDO connection from a connection details array
*
* @param array $conn SQL connection details. The array should have
* the following properties
* * host - host name
* * db - database name
* * user - user name
* * pass - user password
* * Optional: `'charset' => 'utf8'` - you might need this depending on your PHP / MySQL config
* @return resource PDO connection
*/
static function db ( $conn )
{
if ( is_array( $conn ) ) {
return self::sql_connect( $conn );
}
return $conn;
}
/**
* Paging
*
* Construct the LIMIT clause for server-side processing SQL query
*
* @param array $request Data sent to server by DataTables
* @param array $columns Column information array
* @return string SQL limit clause
*/
static function limit ( $request, $columns )
{
$limit = '';
if ( isset($request['start']) && $request['length'] != -1 ) {
$limit = "LIMIT ".intval($request['start']).", ".intval($request['length']);
}
return $limit;
}
/**
* Ordering
*
* Construct the ORDER BY clause for server-side processing SQL query
*
* @param array $request Data sent to server by DataTables
* @param array $columns Column information array
* @return string SQL order by clause
*/
static function order ( $tableAS, $request, $columns )
{
$select = '';
$order = '';
if ( isset($request['order']) && count($request['order']) ) {
$selects = [];
$orderBy = [];
$dtColumns = self::pluck( $columns, 'dt' );
for ( $i=0, $ien=count($request['order']) ; $i<$ien ; $i++ ) {
// Convert the column index into the column data property
$columnIdx = intval($request['order'][$i]['column']);
$requestColumn = $request['columns'][$columnIdx];
$columnIdx = array_search( $columnIdx, $dtColumns );
$column = $columns[ $columnIdx ];
if ( $requestColumn['orderable'] == 'true' ) {
$dir = $request['order'][$i]['dir'] === 'asc' ?
'ASC' :
'DESC';
if(isset($column['order_subquery'])) {
$selects[] = '('.$column['order_subquery'].') AS `'.$column['db'].'_count`';
$orderBy[] = '`'.$column['db'].'_count` '.$dir;
} else {
$orderBy[] = '`'.$tableAS.'`.`'.$column['db'].'` '.$dir;
}
}
}
if ( count( $selects ) ) {
$select = ', '.implode(', ', $selects);
}
if ( count( $orderBy ) ) {
$order = 'ORDER BY '.implode(', ', $orderBy);
}
}
return [$select, $order];
}
/**
* Searching / Filtering
*
* Construct the WHERE clause for server-side processing SQL query.
*
* NOTE this does not match the built-in DataTables filtering which does it
* word by word on any field. It's possible to do here performance on large
* databases would be very poor
*
* @param array $request Data sent to server by DataTables
* @param array $columns Column information array
* @param array $bindings Array of values for PDO bindings, used in the
* sql_exec() function
* @return string SQL where clause
*/
static function filter ( $tablesAS, $request, $columns, &$bindings )
{
$globalSearch = array();
$columnSearch = array();
$joins = array();
$dtColumns = self::pluck( $columns, 'dt' );
if ( isset($request['search']) && $request['search']['value'] != '' ) {
$str = $request['search']['value'];
for ( $i=0, $ien=count($request['columns']) ; $i<$ien ; $i++ ) {
$requestColumn = $request['columns'][$i];
$columnIdx = array_search( $i, $dtColumns );
$column = $columns[ $columnIdx ];
if ( $requestColumn['searchable'] == 'true' ) {
if(!empty($column['db'])){
$binding = self::bind( $bindings, '%'.$str.'%', PDO::PARAM_STR );
if(isset($column['search']['join'])) {
$joins[] = $column['search']['join'];
$globalSearch[] = $column['search']['where_column'].' LIKE '.$binding;
} else {
$globalSearch[] = "`".$tablesAS."`.`".$column['db']."` LIKE ".$binding;
}
}
}
}
}
// Individual column filtering
if ( isset( $request['columns'] ) ) {
for ( $i=0, $ien=count($request['columns']) ; $i<$ien ; $i++ ) {
$requestColumn = $request['columns'][$i];
$columnIdx = array_search( $requestColumn['data'], $dtColumns );
$column = $columns[ $columnIdx ];
$str = $requestColumn['search']['value'];
if ( $requestColumn['searchable'] == 'true' &&
$str != '' ) {
if(!empty($column['db'])){
$binding = self::bind( $bindings, '%'.$str.'%', PDO::PARAM_STR );
$columnSearch[] = "`".$tablesAS."`.`".$column['db']."` LIKE ".$binding;
}
}
}
}
// Combine the filters into a single string
$where = '';
if ( count( $globalSearch ) ) {
$where = '('.implode(' OR ', $globalSearch).')';
}
if ( count( $columnSearch ) ) {
$where = $where === '' ?
implode(' AND ', $columnSearch) :
$where .' AND '. implode(' AND ', $columnSearch);
}
$join = '';
if( count($joins) ) {
$join = implode(' ', $joins);
}
if ( $where !== '' ) {
$where = 'WHERE '.$where;
}
return [$join, $where];
}
/**
* Perform the SQL queries needed for an server-side processing requested,
* utilising the helper functions of this class, limit(), order() and
* filter() among others. The returned array is ready to be encoded as JSON
* in response to an SSP request, or can be modified if needed before
* sending back to the client.
*
* @param array $request Data sent to server by DataTables
* @param array|PDO $conn PDO connection resource or connection parameters array
* @param string $table SQL table to query
* @param string $primaryKey Primary key of the table
* @param array $columns Column information array
* @return array Server-side processing response array
*/
static function simple ( $request, $conn, $table, $primaryKey, $columns )
{
$bindings = array();
$db = self::db( $conn );
// Allow for a JSON string to be passed in
if (isset($request['json'])) {
$request = json_decode($request['json'], true);
}
// table AS
$tablesAS = null;
if(is_array($table)) {
$tablesAS = $table[1];
$table = $table[0];
}
// Build the SQL query string from the request
list($select, $order) = self::order( $tablesAS, $request, $columns );
$limit = self::limit( $request, $columns );
list($join, $where) = self::filter( $tablesAS, $request, $columns, $bindings );
// Main query to actually get the data
$data = self::sql_exec( $db, $bindings,
"SELECT `$tablesAS`.`".implode("`, `$tablesAS`.`", self::pluck($columns, 'db'))."`
$select
FROM `$table` AS `$tablesAS`
$join
$where
GROUP BY `{$tablesAS}`.`{$primaryKey}`
$order
$limit"
);
// Data set length after filtering
$resFilterLength = self::sql_exec( $db, $bindings,
"SELECT COUNT(DISTINCT `{$tablesAS}`.`{$primaryKey}`)
FROM `$table` AS `$tablesAS`
$join
$where"
);
$recordsFiltered = $resFilterLength[0][0];
// Total data set length
$resTotalLength = self::sql_exec( $db,
"SELECT COUNT(`{$tablesAS}`.`{$primaryKey}`)
FROM `$table` AS `$tablesAS`"
);
$recordsTotal = $resTotalLength[0][0];
/*
* Output
*/
return array(
"draw" => isset ( $request['draw'] ) ?
intval( $request['draw'] ) :
0,
"recordsTotal" => intval( $recordsTotal ),
"recordsFiltered" => intval( $recordsFiltered ),
"data" => self::data_output( $columns, $data )
);
}
/**
* The difference between this method and the `simple` one, is that you can
* apply additional `where` conditions to the SQL queries. These can be in
* one of two forms:
*
* * 'Result condition' - This is applied to the result set, but not the
* overall paging information query - i.e. it will not effect the number
* of records that a user sees they can have access to. This should be
* used when you want apply a filtering condition that the user has sent.
* * 'All condition' - This is applied to all queries that are made and
* reduces the number of records that the user can access. This should be
* used in conditions where you don't want the user to ever have access to
* particular records (for example, restricting by a login id).
*
* In both cases the extra condition can be added as a simple string, or if
* you are using external values, as an assoc. array with `condition` and
* `bindings` parameters. The `condition` is a string with the SQL WHERE
* condition and `bindings` is an assoc. array of the binding names and
* values.
*
* @param array $request Data sent to server by DataTables
* @param array|PDO $conn PDO connection resource or connection parameters array
* @param string|array $table SQL table to query, if array second key is AS
* @param string $primaryKey Primary key of the table
* @param array $columns Column information array
* @param string $join JOIN sql string
* @param string|array $whereResult WHERE condition to apply to the result set
* @return array Server-side processing response array
*/
static function complex (
$request,
$conn,
$table,
$primaryKey,
$columns,
$join=null,
$whereResult=null
) {
$bindings = array();
$db = self::db( $conn );
// table AS
$tablesAS = null;
if(is_array($table)) {
$tablesAS = $table[1];
$table = $table[0];
}
// Build the SQL query string from the request
list($select, $order) = self::order( $tablesAS, $request, $columns );
$limit = self::limit( $request, $columns );
list($join_filter, $where) = self::filter( $tablesAS, $request, $columns, $bindings );
// whereResult can be a simple string, or an assoc. array with a
// condition and bindings
if ( $whereResult ) {
$str = $whereResult;
if ( is_array($whereResult) ) {
$str = $whereResult['condition'];
if ( isset($whereResult['bindings']) ) {
self::add_bindings($bindings, $whereResult);
}
}
$where = $where ?
$where .' AND '.$str :
'WHERE '.$str;
}
// Main query to actually get the data
$data = self::sql_exec( $db, $bindings,
"SELECT `$tablesAS`.`".implode("`, `$tablesAS`.`", self::pluck($columns, 'db'))."`
$select
FROM `$table` AS `$tablesAS`
$join
$join_filter
$where
GROUP BY `{$tablesAS}`.`{$primaryKey}`
$order
$limit"
);
// Data set length after filtering
$resFilterLength = self::sql_exec( $db, $bindings,
"SELECT COUNT(DISTINCT `{$tablesAS}`.`{$primaryKey}`)
FROM `$table` AS `$tablesAS`
$join
$join_filter
$where"
);
$recordsFiltered = (isset($resFilterLength[0])) ? $resFilterLength[0][0] : 0;
// Total data set length
$resTotalLength = self::sql_exec( $db, $bindings,
"SELECT COUNT(`{$tablesAS}`.`{$primaryKey}`)
FROM `$table` AS `$tablesAS`
$join
$join_filter
$where"
);
$recordsTotal = (isset($resTotalLength[0])) ? $resTotalLength[0][0] : 0;
/*
* Output
*/
return array(
"draw" => isset ( $request['draw'] ) ?
intval( $request['draw'] ) :
0,
"recordsTotal" => intval( $recordsTotal ),
"recordsFiltered" => intval( $recordsFiltered ),
"data" => self::data_output( $columns, $data )
);
}
/**
* Connect to the database
*
* @param array $sql_details SQL server connection details array, with the
* properties:
* * host - host name
* * db - database name
* * user - user name
* * pass - user password
* @return resource Database connection handle
*/
static function sql_connect ( $sql_details )
{
try {
$db = @new PDO(
"mysql:host={$sql_details['host']};dbname={$sql_details['db']}",
$sql_details['user'],
$sql_details['pass'],
array( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION )
);
}
catch (PDOException $e) {
self::fatal(
"An error occurred while connecting to the database. ".
"The error reported by the server was: ".$e->getMessage()
);
}
return $db;
}
/**
* Execute an SQL query on the database
*
* @param resource $db Database handler
* @param array $bindings Array of PDO binding values from bind() to be
* used for safely escaping strings. Note that this can be given as the
* SQL query string if no bindings are required.
* @param string $sql SQL query to execute.
* @return array Result from the query (all rows)
*/
static function sql_exec ( $db, $bindings, $sql=null )
{
// Argument shifting
if ( $sql === null ) {
$sql = $bindings;
}
$stmt = $db->prepare( $sql );
// Bind parameters
if ( is_array( $bindings ) ) {
for ( $i=0, $ien=count($bindings) ; $i<$ien ; $i++ ) {
$binding = $bindings[$i];
$stmt->bindValue( $binding['key'], $binding['val'], $binding['type'] );
}
}
// Execute
try {
$stmt->execute();
}
catch (PDOException $e) {
self::fatal( "An SQL error occurred: ".$e->getMessage() );
}
// Return all
return $stmt->fetchAll( PDO::FETCH_BOTH );
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Internal methods
*/
/**
* Throw a fatal error.
*
* This writes out an error message in a JSON string which DataTables will
* see and show to the user in the browser.
*
* @param string $msg Message to send to the client
*/
static function fatal ( $msg )
{
echo json_encode( array(
"error" => $msg
) );
exit(0);
}
/**
* Create a PDO binding key which can be used for escaping variables safely
* when executing a query with sql_exec()
*
* @param array &$a Array of bindings
* @param * $val Value to bind
* @param int $type PDO field type
* @return string Bound key to be used in the SQL where this parameter
* would be used.
*/
static function bind ( &$a, $val, $type )
{
$key = ':binding_'.count( $a );
$a[] = array(
'key' => $key,
'val' => $val,
'type' => $type
);
return $key;
}
static function add_bindings(&$bindings, $vals)
{
foreach($vals['bindings'] as $key => $value) {
$bindings[] = array(
'key' => $key,
'val' => $value,
'type' => PDO::PARAM_STR
);
}
}
/**
* Pull a particular property from each assoc. array in a numeric array,
* returning and array of the property values from each item.
*
* @param array $a Array to get data from
* @param string $prop Property to read
* @return array Array of property values
*/
static function pluck ( $a, $prop )
{
$out = array();
for ( $i=0, $len=count($a) ; $i<$len ; $i++ ) {
if ( empty($a[$i][$prop]) && $a[$i][$prop] !== 0 ) {
continue;
}
if ( $prop == 'db' && isset($a[$i]['dummy']) && $a[$i]['dummy'] === true ) {
continue;
}
//removing the $out array index confuses the filter method in doing proper binding,
//adding it ensures that the array data are mapped correctly
$out[$i] = $a[$i][$prop];
}
return $out;
}
/**
* Return a string from an array or a string
*
* @param array|string $a Array to join
* @param string $join Glue for the concatenation
* @return string Joined string
*/
static function _flatten ( $a, $join = ' AND ' )
{
if ( ! $a ) {
return '';
}
else if ( $a && is_array($a) ) {
return implode( $join, $a );
}
return $a;
}
}

View File

@@ -1,7 +1,7 @@
headline: lang.sieve_preset_1
content: |
require ["reject","body","regex"];
if anyof (body :raw :regex ["filename=.*\.doc","filename=.*\.exe","filename=.*\.moo"]) {
if anyof (body :raw :regex ["filename=\".*\\.(doc|exe|moo)\""]) {
reject text:
doc, exe and moo are dangerous file extensions.
Why would you do that? I am a sad cow.

View File

@@ -95,6 +95,8 @@ $AVAILABLE_LANGUAGES = array(
'it-it' => 'Italiano (Italian)',
'ko-kr' => '한국어 (Korean)',
'lv-lv' => 'latviešu (Latvian)',
'lt-lt' => 'Lietuvių (Lithuanian)',
'nb-no' => 'Norsk (Norwegian)',
'nl-nl' => 'Nederlands (Dutch)',
'pl-pl' => 'Język Polski (Polish)',
'pt-br' => 'Português brasileiro (Brazilian Portuguese)',
@@ -126,6 +128,15 @@ $MAILCOW_APPS = array(
)
);
// Logo max file size in bytes
$LOGO_LIMITS['max_size'] = 15 * 1024 * 1024; // 15MB
// Logo max width in pixels
$LOGO_LIMITS['max_width'] = 1920;
// Logo max height in pixels
$LOGO_LIMITS['max_height'] = 1920;
// Rows until pagination begins
$PAGINATION_SIZE = 25;

View File

@@ -435,7 +435,7 @@ jQuery(function($){
var table = $('#domain_table').DataTable({
responsive: true,
processing: true,
serverSide: false,
serverSide: true,
stateSave: true,
pageLength: pagination_size,
dom: "<'row'<'col-sm-12 col-md-6'f><'col-sm-12 col-md-6'l>>" +
@@ -447,10 +447,14 @@ jQuery(function($){
},
ajax: {
type: "GET",
url: "/api/v1/get/domain/all",
url: "/api/v1/get/domain/datatables",
dataSrc: function(json){
$.each(json, function(i, item) {
$.each(json.data, function(i, item) {
item.domain_name = escapeHtml(item.domain_name);
item.domain_h_name = escapeHtml(item.domain_h_name);
if (item.domain_name != item.domain_h_name){
item.domain_h_name = item.domain_h_name + '<small class="d-block">' + item.domain_name + '</small>';
}
item.aliases = item.aliases_in_domain + " / " + item.max_num_aliases_for_domain;
item.mailboxes = item.mboxes_in_domain + " / " + item.max_num_mboxes_for_domain;
@@ -489,16 +493,16 @@ jQuery(function($){
if (item.backupmx == 1) {
if (item.relay_unknown_only == 1) {
item.domain_name = '<div class="badge fs-6 bg-info">Relay Non-Local</div> ' + item.domain_name;
item.domain_h_name = '<div class="badge fs-7 bg-info">Relay Non-Local</div> ' + item.domain_h_name;
} else if (item.relay_all_recipients == 1) {
item.domain_name = '<div class="badge fs-6 bg-info">Relay All</div> ' + item.domain_name;
item.domain_h_name = '<div class="badge fs-7 bg-info">Relay All</div> ' + item.domain_h_name;
} else {
item.domain_name = '<div class="badge fs-6 bg-info">Relay</div> ' + item.domain_name;
item.domain_h_name = '<div class="badge fs-7 bg-info">Relay</div> ' + item.domain_h_name;
}
}
});
return json;
return json.data;
}
},
columns: [
@@ -521,24 +525,27 @@ jQuery(function($){
},
{
title: lang.domain,
data: 'domain_name',
data: 'domain_h_name',
responsivePriority: 3,
defaultContent: ''
},
{
title: lang.aliases,
data: 'aliases',
searchable: false,
defaultContent: ''
},
{
title: lang.mailboxes,
data: 'mailboxes',
searchable: false,
responsivePriority: 4,
defaultContent: ''
},
{
title: lang.domain_quota,
data: 'quota',
searchable: false,
defaultContent: '',
render: function (data, type) {
data = data.split("/");
@@ -548,6 +555,7 @@ jQuery(function($){
{
title: lang.stats,
data: 'stats',
searchable: false,
defaultContent: '',
render: function (data, type) {
data = data.split("/");
@@ -557,53 +565,67 @@ jQuery(function($){
{
title: lang.mailbox_defquota,
data: 'def_quota_for_mbox',
searchable: false,
defaultContent: ''
},
{
title: lang.mailbox_quota,
data: 'max_quota_for_mbox',
searchable: false,
defaultContent: ''
},
{
title: 'RL',
data: 'rl',
searchable: false,
orderable: false,
defaultContent: ''
},
{
title: lang.backup_mx,
data: 'backupmx',
searchable: false,
defaultContent: '',
redner: function (data, type){
return 1==value ? '<i class="bi bi-check-lg"></i>' : 0==value && '<i class="bi bi-x-lg"></i>';
render: function (data, type){
return 1==data ? '<i class="bi bi-check-lg"></i>' : 0==data && '<i class="bi bi-x-lg"></i>';
}
},
{
title: lang.domain_admins,
data: 'domain_admins',
searchable: false,
orderable: false,
defaultContent: '',
className: 'none'
},
{
title: lang.created_on,
data: 'created',
searchable: false,
orderable: false,
defaultContent: '',
className: 'none'
},
{
title: lang.last_modified,
data: 'modified',
searchable: false,
orderable: false,
defaultContent: '',
className: 'none'
},
{
title: 'Tags',
data: 'tags',
searchable: true,
orderable: false,
defaultContent: '',
className: 'none'
},
{
title: lang.active,
data: 'active',
searchable: false,
defaultContent: '',
responsivePriority: 6,
render: function (data, type) {
@@ -613,6 +635,8 @@ jQuery(function($){
{
title: lang.action,
data: 'action',
searchable: false,
orderable: false,
className: 'dt-sm-head-hidden dt-data-w100 dtr-col-md dt-text-right',
responsivePriority: 5,
defaultContent: ''
@@ -844,7 +868,7 @@ jQuery(function($){
var table = $('#mailbox_table').DataTable({
responsive: true,
processing: true,
serverSide: false,
serverSide: true,
stateSave: true,
pageLength: pagination_size,
dom: "<'row'<'col-sm-12 col-md-6'f><'col-sm-12 col-md-6'l>>" +
@@ -853,13 +877,12 @@ jQuery(function($){
language: lang_datatables,
initComplete: function(settings, json){
hideTableExpandCollapseBtn('#tab-mailboxes', '#mailbox_table');
filterByDomain(json, 8, table);
},
ajax: {
type: "GET",
url: "/api/v1/get/mailbox/reduced",
url: "/api/v1/get/mailbox/datatables",
dataSrc: function(json){
$.each(json, function (i, item) {
$.each(json.data, function (i, item) {
item.quota = {
sortBy: item.quota_used,
value: item.quota
@@ -945,7 +968,7 @@ jQuery(function($){
}
});
return json;
return json.data;
}
},
columns: [
@@ -975,13 +998,14 @@ jQuery(function($){
{
title: lang.domain_quota,
data: 'quota.value',
searchable: false,
responsivePriority: 8,
defaultContent: '',
orderData: 23
defaultContent: ''
},
{
title: lang.last_mail_login,
data: 'last_mail_login',
searchable: false,
defaultContent: '',
responsivePriority: 7,
render: function (data, type) {
@@ -994,15 +1018,16 @@ jQuery(function($){
{
title: lang.last_pw_change,
data: 'last_pw_change',
searchable: false,
defaultContent: ''
},
{
title: lang.in_use,
data: 'in_use.value',
searchable: false,
defaultContent: '',
responsivePriority: 9,
className: 'dt-data-w100',
orderData: 24
className: 'dt-data-w100'
},
{
title: lang.fname,
@@ -1067,6 +1092,7 @@ jQuery(function($){
{
title: lang.msg_num,
data: 'messages',
searchable: false,
defaultContent: '',
responsivePriority: 5
},
@@ -1085,12 +1111,14 @@ jQuery(function($){
{
title: 'Tags',
data: 'tags',
searchable: true,
defaultContent: '',
className: 'none'
},
{
title: lang.active,
data: 'active',
searchable: false,
defaultContent: '',
responsivePriority: 4,
render: function (data, type) {
@@ -1100,22 +1128,12 @@ jQuery(function($){
{
title: lang.action,
data: 'action',
searchable: false,
orderable: false,
className: 'dt-sm-head-hidden dt-data-w100 dtr-col-md dt-text-right',
responsivePriority: 6,
defaultContent: ''
},
{
title: "",
data: 'quota.sortBy',
defaultContent: '',
className: "d-none"
},
{
title: "",
data: 'in_use.sortBy',
defaultContent: '',
className: "d-none"
},
}
]
});

View File

@@ -676,5 +676,5 @@ jQuery(function($){
onVisible("[id^=wl_policy_mailbox_table]", () => draw_wl_policy_mailbox_table());
onVisible("[id^=sync_job_table]", () => draw_sync_job_table());
onVisible("[id^=app_passwd_table]", () => draw_app_passwd_table());
last_logins('get');
onVisible("[id^=recent-logins]", () => last_logins('get'));
});

View File

@@ -15,7 +15,7 @@ function api_log($_data) {
continue;
}
$value = json_decode($value, true);
$value = json_decode($value, true);
if ($value) {
if (is_array($value)) unset($value["csrf_token"]);
foreach ($value as $key => &$val) {
@@ -23,7 +23,7 @@ function api_log($_data) {
$val = '*';
}
}
$value = json_encode($value);
$value = json_encode($value);
}
$data_var[] = $data . "='" . $value . "'";
}
@@ -44,7 +44,13 @@ function api_log($_data) {
'msg' => 'Redis: '.$e
);
return false;
}
}
}
// Block requests not intended for direct API use by checking the 'Sec-Fetch-Dest' header.
if (isset($_SERVER['HTTP_SEC_FETCH_DEST']) && $_SERVER['HTTP_SEC_FETCH_DEST'] !== 'empty') {
header('HTTP/1.1 403 Forbidden');
exit;
}
if (isset($_GET['query'])) {
@@ -178,12 +184,12 @@ if (isset($_GET['query'])) {
// parse post data
$post = trim(file_get_contents('php://input'));
if ($post) $post = json_decode($post);
// process registration data from authenticator
try {
// decode base64 strings
$clientDataJSON = base64_decode($post->clientDataJSON);
$attestationObject = base64_decode($post->attestationObject);
$attestationObject = base64_decode($post->attestationObject);
// processCreate($clientDataJSON, $attestationObject, $challenge, $requireUserVerification=false, $requireUserPresent=true, $failIfRootMismatch=true)
$data = $WebAuthn->processCreate($clientDataJSON, $attestationObject, $_SESSION['challenge'], false, true);
@@ -250,7 +256,7 @@ if (isset($_GET['query'])) {
default:
process_add_return(mailbox('add', 'domain', $attr));
break;
}
}
break;
case "resource":
process_add_return(mailbox('add', 'resource', $attr));
@@ -470,7 +476,7 @@ if (isset($_GET['query'])) {
// false, if only internal is allowed
// null, if internal and cross-platform is allowed
$createArgs = $WebAuthn->getCreateArgs($_SESSION["mailcow_cc_username"], $_SESSION["mailcow_cc_username"], $_SESSION["mailcow_cc_username"], 30, false, $GLOBALS['WEBAUTHN_UV_FLAG_REGISTER'], null, $excludeCredentialIds);
print(json_encode($createArgs));
$_SESSION['challenge'] = $WebAuthn->getChallenge();
return;
@@ -533,9 +539,50 @@ if (isset($_GET['query'])) {
case "domain":
switch ($object) {
case "datatables":
$table = ['domain', 'd'];
$primaryKey = 'domain';
$columns = [
['db' => 'domain', 'dt' => 2],
['db' => 'aliases', 'dt' => 3, 'order_subquery' => "SELECT COUNT(*) FROM `alias` WHERE (`domain`= `d`.`domain` OR `domain` IN (SELECT `alias_domain` FROM `alias_domain` WHERE `target_domain` = `d`.`domain`)) AND `address` NOT IN (SELECT `username` FROM `mailbox`)"],
['db' => 'mailboxes', 'dt' => 4, 'order_subquery' => "SELECT COUNT(*) FROM `mailbox` WHERE `mailbox`.`domain` = `d`.`domain` AND (`mailbox`.`kind` = '' OR `mailbox`.`kind` = NULL)"],
['db' => 'quota', 'dt' => 5, 'order_subquery' => "SELECT COALESCE(SUM(`mailbox`.`quota`), 0) FROM `mailbox` WHERE `mailbox`.`domain` = `d`.`domain` AND (`mailbox`.`kind` = '' OR `mailbox`.`kind` = NULL)"],
['db' => 'stats', 'dt' => 6, 'dummy' => true, 'order_subquery' => "SELECT SUM(bytes) FROM `quota2` WHERE `quota2`.`username` IN (SELECT `username` FROM `mailbox` WHERE `domain` = `d`.`domain`)"],
['db' => 'defquota', 'dt' => 7],
['db' => 'maxquota', 'dt' => 8],
['db' => 'backupmx', 'dt' => 10],
['db' => 'tags', 'dt' => 14, 'dummy' => true, 'search' => ['join' => 'LEFT JOIN `tags_domain` AS `td` ON `td`.`domain` = `d`.`domain`', 'where_column' => '`td`.`tag_name`']],
['db' => 'active', 'dt' => 15],
];
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/lib/ssp.class.php';
global $pdo;
if($_SESSION['mailcow_cc_role'] === 'admin') {
$data = SSP::simple($_GET, $pdo, $table, $primaryKey, $columns);
} elseif ($_SESSION['mailcow_cc_role'] === 'domainadmin') {
$data = SSP::complex($_GET, $pdo, $table, $primaryKey, $columns,
'INNER JOIN domain_admins as da ON da.domain = d.domain',
[
'condition' => 'da.active = 1 and da.username = :username',
'bindings' => ['username' => $_SESSION['mailcow_cc_username']]
]);
}
if (!empty($data['data'])) {
$domainsData = [];
foreach ($data['data'] as $domain) {
if ($details = mailbox('get', 'domain_details', $domain[2])) {
$domainsData[] = $details;
}
}
$data['data'] = $domainsData;
}
process_get_return($data);
break;
case "all":
$tags = null;
if (isset($_GET['tags']) && $_GET['tags'] != '')
if (isset($_GET['tags']) && $_GET['tags'] != '')
$tags = explode(',', $_GET['tags']);
$domains = mailbox('get', 'domains', null, $tags);
@@ -1021,10 +1068,49 @@ if (isset($_GET['query'])) {
break;
case "mailbox":
switch ($object) {
case "datatables":
$table = ['mailbox', 'm'];
$primaryKey = 'username';
$columns = [
['db' => 'username', 'dt' => 2],
['db' => 'quota', 'dt' => 3],
['db' => 'last_mail_login', 'dt' => 4, 'dummy' => true, 'order_subquery' => "SELECT MAX(`datetime`) FROM `sasl_log` WHERE `service` != 'SSO' AND `username` = `m`.`username`"],
['db' => 'last_pw_change', 'dt' => 5, 'dummy' => true, 'order_subquery' => "JSON_EXTRACT(attributes, '$.passwd_update')"],
['db' => 'in_use', 'dt' => 6, 'dummy' => true, 'order_subquery' => "(SELECT SUM(bytes) FROM `quota2` WHERE `quota2`.`username` = `m`.`username`) / `m`.`quota`"],
['db' => 'messages', 'dt' => 17, 'dummy' => true, 'order_subquery' => "SELECT SUM(messages) FROM `quota2` WHERE `quota2`.`username` = `m`.`username`"],
['db' => 'tags', 'dt' => 20, 'dummy' => true, 'search' => ['join' => 'LEFT JOIN `tags_mailbox` AS `tm` ON `tm`.`username` = `m`.`username`', 'where_column' => '`tm`.`tag_name`']],
['db' => 'active', 'dt' => 21]
];
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/lib/ssp.class.php';
global $pdo;
if($_SESSION['mailcow_cc_role'] === 'admin') {
$data = SSP::complex($_GET, $pdo, $table, $primaryKey, $columns, null, "(`m`.`kind` = '' OR `m`.`kind` = NULL)");
} elseif ($_SESSION['mailcow_cc_role'] === 'domainadmin') {
$data = SSP::complex($_GET, $pdo, $table, $primaryKey, $columns,
'INNER JOIN domain_admins as da ON da.domain = m.domain',
[
'condition' => "(`m`.`kind` = '' OR `m`.`kind` = NULL) AND `da`.`active` = 1 AND `da`.`username` = :username",
'bindings' => ['username' => $_SESSION['mailcow_cc_username']]
]);
}
if (!empty($data['data'])) {
$mailboxData = [];
foreach ($data['data'] as $mailbox) {
if ($details = mailbox('get', 'mailbox_details', $mailbox[2])) {
$mailboxData[] = $details;
}
}
$data['data'] = $mailboxData;
}
process_get_return($data);
break;
case "all":
case "reduced":
$tags = null;
if (isset($_GET['tags']) && $_GET['tags'] != '')
if (isset($_GET['tags']) && $_GET['tags'] != '')
$tags = explode(',', $_GET['tags']);
if (empty($extra)) $domains = mailbox('get', 'domains');
@@ -1058,7 +1144,7 @@ if (isset($_GET['query'])) {
break;
default:
$tags = null;
if (isset($_GET['tags']) && $_GET['tags'] != '')
if (isset($_GET['tags']) && $_GET['tags'] != '')
$tags = explode(',', $_GET['tags']);
if ($tags === null) {
@@ -1068,7 +1154,7 @@ if (isset($_GET['query'])) {
$mailboxes = mailbox('get', 'mailboxes', $object, $tags);
if (is_array($mailboxes)) {
foreach ($mailboxes as $mailbox) {
if ($details = mailbox('get', 'mailbox_details', $mailbox))
if ($details = mailbox('get', 'mailbox_details', $mailbox))
$data[] = $details;
}
}
@@ -1571,15 +1657,15 @@ if (isset($_GET['query'])) {
'solr_size' => $solr_size,
'solr_documents' => $solr_documents
));
break;
break;
case "host":
if (!$extra){
$stats = docker("host_stats");
echo json_encode($stats);
}
}
else if ($extra == "ip") {
// get public ips
$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POST, 0);
@@ -2003,7 +2089,7 @@ if (isset($_GET['query'])) {
exit();
}
}
if ($_SESSION['mailcow_cc_api'] === true) {
if (array_key_exists('mailcow_cc_api', $_SESSION) && $_SESSION['mailcow_cc_api'] === true) {
if (isset($_SESSION['mailcow_cc_api']) && $_SESSION['mailcow_cc_api'] === true) {
unset($_SESSION['return']);
}

View File

@@ -19,7 +19,16 @@
"spam_alias": "Àlies temporals",
"spam_score": "Puntuació de correu brossa",
"tls_policy": "Política TLS",
"unlimited_quota": "Quota ilimitada per bústies de correo"
"unlimited_quota": "Quota ilimitada per bústies de correo",
"delimiter_action": "",
"ratelimit": "",
"smtp_ip_access": "",
"sogo_access": "",
"domain_relayhost": "",
"extend_sender_acl": "",
"mailbox_relayhost": "",
"pushover": "",
"spam_policy": ""
},
"add": {
"activate_filter_warn": "All other filters will be deactivated, when active is checked.",
@@ -73,7 +82,33 @@
"validate": "Validar",
"validation_success": "Validated successfully",
"app_name": "Nom de l'aplicació",
"app_password": "Afegir contrasenya a l'aplicació"
"app_password": "Afegir contrasenya a l'aplicació",
"dry": "",
"inactive": "",
"disable_login": "",
"goto_ham": "",
"goto_spam": "",
"mailbox_quota_def": "",
"private_comment": "",
"public_comment": "",
"relay_unknown_only": "",
"relayhost_wrapped_tls_info": "",
"subscribeall": "",
"tags": "",
"timeout1": "",
"timeout2": "",
"relay_transport_info": "",
"domain_matches_hostname": "",
"gal": "",
"gal_info": "",
"generate": "",
"nexthop": "",
"app_passwd_protocols": "",
"bcc_dest_format": "",
"comment_info": "",
"custom_params": "",
"custom_params_hint": "",
"destination": ""
},
"admin": {
"access": "Accés",
@@ -156,7 +191,167 @@
"ui_texts": "Etiquetes i textos de la UI",
"unchanged_if_empty": "Si no hi ha canvis, deixa'l en blanc",
"upload": "Pujar",
"username": "Nom d'usuari"
"username": "Nom d'usuari",
"lookup_mx": "",
"logo_dark_label": "",
"optional": "",
"copy_to_clipboard": "",
"f2b_manage_external": "",
"f2b_manage_external_info": "",
"license_info": "",
"message": "",
"message_size": "",
"nexthop": "",
"no": "",
"no_active_bans": "",
"oauth2_apps": "",
"oauth2_client_secret": "",
"oauth2_info": "",
"password_policy_chars": "",
"password_policy_numbers": "",
"password_policy_special_chars": "",
"priority": "",
"quarantine_bcc": "",
"quarantine_max_size": "",
"quarantine_notification_html": "",
"quarantine_redirect": "",
"quarantine_release_format_att": "",
"quarantine_retention_size": "",
"quota_notification_html": "",
"quota_notification_subject": "",
"quota_notifications": "",
"relay_rcpt": "",
"relay_run": "",
"routing": "",
"rspamd_global_filters_regex": "",
"title": "",
"transport_maps": "",
"transport_test_rcpt_info": "",
"transports_hint": "",
"ui_header_announcement_active": "",
"validate_license_now": "",
"verify": "",
"yes": "",
"password_length": "",
"password_policy": "",
"logo_normal_label": "",
"f2b_max_ban_time": "",
"f2b_ban_time_increment": "",
"add_relayhost_hint": "",
"add_transport": "",
"add_transports_hint": "",
"admins": "",
"quarantine_exclude_domains": "",
"quarantine_max_age": "",
"quarantine_release_format_raw": "",
"quota_notification_sender": "",
"quota_notifications_info": "",
"quota_notifications_vars": "",
"r_active": "",
"r_inactive": "",
"rate_name": "",
"regex_maps": "",
"ui_header_announcement": "",
"cors_settings": "",
"allowed_methods": "",
"allowed_origins": "",
"oauth2_renew_secret": "",
"oauth2_revoke_tokens": "",
"send": "",
"success": "",
"sys_mails": "",
"text": "",
"time": "",
"unban_pending": "",
"ip_check": "",
"quarantine_notification_sender": "",
"dkim_domains_wo_keys": "",
"dkim_to": "",
"duplicate": "",
"excludes": "",
"f2b_blacklist": "",
"f2b_filter": "",
"guid": "",
"oauth2_add_client": "",
"rsetting_content": "",
"queue_unban": "",
"ip_check_disabled": "",
"ip_check_opt_in": "",
"options": "",
"relayhosts": "",
"reset_limit": "",
"rsetting_add_rule": "",
"rspamd_com_settings": "",
"ui_footer": "",
"dkim_from": "",
"admins_ldap": "",
"advanced_settings": "",
"api_info": "",
"api_read_only": "",
"api_read_write": "",
"api_skip_ip_check": "",
"arrival_time": "",
"authed_user": "",
"ays": "",
"activate_send": "",
"active_rspamd_settings_map": "",
"add_admin": "",
"add_settings_rule": "",
"oauth2_redirect_uri": "",
"domain_admin": "",
"password_policy_length": "",
"password_policy_lowerupper": "",
"quarantine_release_format": "",
"rsetting_none": "",
"rsettings_insert_preset": "",
"transport_dest_format": "",
"ban_list_info": "",
"convert_html_to_text": "",
"credentials_transport_warning": "",
"customer_id": "",
"destination": "",
"dkim_domains_selector": "",
"dkim_from_title": "",
"dkim_overwrite_key": "",
"dkim_to_title": "",
"domain_s": "",
"f2b_list_info": "",
"f2b_regex_info": "",
"from": "",
"generate": "",
"guid_and_license": "",
"hash_remove_info": "",
"html": "",
"include_exclude": "",
"include_exclude_info": "",
"includes": "",
"is_mx_based": "",
"last_applied": "",
"login_time": "",
"oauth2_client_id": "",
"quarantine_max_score": "",
"quarantine_notification_subject": "",
"rsetting_no_selection": "",
"rsettings_preset_1": "",
"rsettings_preset_2": "",
"rsettings_preset_3": "",
"rsettings_preset_4": "",
"rspamd_global_filters": "",
"rspamd_global_filters_agree": "",
"rspamd_global_filters_info": "",
"rspamd_settings_map": "",
"sal_level": "",
"service": "",
"service_id": "",
"ui_header_announcement_content": "",
"ui_header_announcement_help": "",
"ui_header_announcement_select": "",
"ui_header_announcement_type": "",
"ui_header_announcement_type_danger": "",
"ui_header_announcement_type_info": "",
"ui_header_announcement_type_warning": "",
"duplicate_dkim": "",
"r_info": ""
},
"danger": {
"access_denied": "Accés denegat o dades incorrectes",
@@ -207,7 +402,87 @@
"target_domain_invalid": "El domini \"goto\" no és vàlid",
"targetd_not_found": "No s'ha trobat el domini destí",
"username_invalid": "El nom d'usuari no es pot fer servir",
"validity_missing": "Si et plau posa un període de validesa"
"validity_missing": "Si et plau posa un període de validesa",
"webauthn_authenticator_failed": "",
"webauthn_publickey_failed": "",
"value_missing": "",
"unknown": "",
"app_name_empty": "",
"app_passwd_id_invalid": "",
"bcc_empty": "",
"invalid_bcc_map_type": "",
"invalid_filter_type": "",
"invalid_host": "",
"bcc_exists": "",
"bcc_must_be_email": "",
"comment_too_long": "",
"cors_invalid_method": "",
"cors_invalid_origin": "",
"defquota_empty": "",
"extended_sender_acl_denied": "",
"extra_acl_invalid": "",
"extra_acl_invalid_domain": "",
"fido2_verification_failed": "",
"file_open_error": "",
"filter_type": "",
"from_invalid": "",
"global_filter_write_error": "",
"global_map_invalid": "",
"global_map_write_error": "",
"ham_learn_error": "",
"invalid_nexthop": "",
"invalid_recipient_map_new": "",
"invalid_destination": "",
"tfa_token_invalid": "",
"tls_policy_map_dest_invalid": "",
"rl_timeframe": "",
"img_dimensions_exceeded": "",
"img_size_exceeded": "",
"invalid_nexthop_authenticated": "",
"invalid_recipient_map_old": "",
"private_key_error": "",
"pushover_credentials_missing": "",
"pushover_key": "",
"pushover_token": "",
"recipient_map_entry_exists": "",
"redis_error": "",
"relayhost_invalid": "",
"reset_f2b_regex": "",
"rspamd_ui_pw_length": "",
"script_empty": "",
"set_acl_failed": "",
"targetd_relay_domain": "",
"template_exists": "",
"template_id_invalid": "",
"template_name_invalid": "",
"temp_error": "",
"text_empty": "",
"tls_policy_map_entry_exists": "",
"tls_policy_map_parameter_invalid": "",
"totp_verification_failed": "",
"transport_dest_exists": "",
"webauthn_verification_failed": "",
"webauthn_username_failed": "",
"unknown_tfa_method": "",
"unlimited_quota_acl": "",
"yotp_verification_failed": "",
"no_user_defined": "",
"demo_mode_enabled": "",
"dkim_domain_or_sel_exists": "",
"domain_cannot_match_hostname": "",
"ip_list_empty": "",
"settings_map_invalid": "",
"sieve_error": "",
"spam_learn_error": "",
"subject_empty": "",
"mailbox_defquota_exceeds_mailbox_maxquota": "",
"malformed_username": "",
"map_content_empty": "",
"mysql_error": "",
"network_host_invalid": "",
"next_hop_interferes": "",
"next_hop_interferes_any": "",
"nginx_reload_failed": ""
},
"diagnostics": {
"cname_from_a": "Valor derivat de registre A/AAAA. Això és compatible sempre que el registre assenyali el recurs correcte.",
@@ -217,7 +492,8 @@
"dns_records_name": "Nom",
"dns_records_status": "Valor actual",
"dns_records_type": "Tipus",
"optional": "Aquest registre és opcional."
"optional": "Aquest registre és opcional.",
"dns_records_docs": ""
},
"edit": {
"active": "Actiu",
@@ -273,7 +549,82 @@
"title": "Editar l'objecte",
"unchanged_if_empty": "Si no hay cambios dejalo en blanco",
"username": "Usuari",
"validate_save": "Validar i desar"
"validate_save": "Validar i desar",
"lookup_mx": "",
"acl": "",
"admin": "",
"allow_from_smtp": "",
"footer_exclude": "",
"domain_footer_skip_replies": "",
"domain_footer_plain": "",
"gal_info": "",
"grant_types": "",
"pushover": "",
"scope": "",
"custom_attributes": "",
"disable_login": "",
"none_inherit": "",
"pushover_info": "",
"domain_footer": "",
"domain_footer_html": "",
"domain_footer_info_vars": {
"from_name": "",
"from_addr": "",
"from_domain": "",
"auth_user": "",
"from_user": "",
"custom": ""
},
"gal": "",
"mbox_rl_info": "",
"nexthop": "",
"private_comment": "",
"public_comment": "",
"pushover_evaluate_x_prio": "",
"pushover_only_x_prio": "",
"pushover_sender_array": "",
"pushover_sender_regex": "",
"sogo_visible": "",
"allow_from_smtp_info": "",
"allowed_protocols": "",
"app_name": "",
"app_passwd": "",
"bcc_dest_format": "",
"client_id": "",
"client_secret": "",
"comment_info": "",
"created_on": "",
"delete_ays": "",
"domain_footer_info": "",
"inactive": "",
"extended_sender_acl": "",
"extended_sender_acl_info": "",
"last_modified": "",
"mailbox_quota_def": "",
"mailbox_relayhost_info": "",
"pushover_text": "",
"pushover_title": "",
"sender_acl_disabled": "",
"sender_acl_info": "",
"sogo_access_info": "",
"sogo_visible_info": "",
"timeout1": "",
"timeout2": "",
"generate": "",
"app_passwd_protocols": "",
"ratelimit": "",
"relayhost": "",
"pushover_sound": "",
"pushover_vars": "",
"pushover_verify": "",
"quota_warning_bcc": "",
"quota_warning_bcc_info": "",
"relay_transport_info": "",
"relay_unknown_only": "",
"spam_filter": "",
"advanced_settings": "",
"redirect_uri": "",
"sogo_access": ""
},
"footer": {
"cancel": "Cancel·lar",
@@ -282,7 +633,13 @@
"delete_these_items": "Si et plau confirma els canvis al objecte amb id:",
"loading": "Si et plau espera ...",
"restart_container_info": "<b>Important:</b> Un reinici pot trigar una estona, si et plau espera a que acabi.",
"restart_now": "Reiniciar ara"
"restart_now": "Reiniciar ara",
"hibp_check": "",
"hibp_nok": "",
"hibp_ok": "",
"nothing_selected": "",
"restart_container": "",
"restarting_container": ""
},
"header": {
"administration": "Administració",
@@ -291,16 +648,24 @@
"mailcow_config": "Configuració",
"quarantine": "Quarantena",
"restart_sogo": "Reiniciar SOGo",
"user_settings": "Preferències d'usuari"
"user_settings": "Preferències d'usuari",
"restart_netfilter": "",
"apps": "",
"mailcow_system": ""
},
"info": {
"no_action": "No hi ha cap acció aplicable"
"no_action": "No hi ha cap acció aplicable",
"awaiting_tfa_confirmation": "",
"session_expires": ""
},
"login": {
"delayed": "Pots iniciar de sessió passats %s segons.",
"login": "Inici de sessió",
"password": "Contrasenya",
"username": "Nom d'usuari"
"username": "Nom d'usuari",
"fido2_webauthn": "",
"mobileconfig_info": "",
"other_logins": ""
},
"mailbox": {
"action": "Acció",
@@ -385,7 +750,97 @@
"tls_enforce_out": "Forçar TLS al enviar",
"toggle_all": "Tots",
"username": "Nom d'usuari",
"waiting": "Esperant"
"waiting": "Esperant",
"booking_0_short": "",
"booking_null": "",
"booking_custom": "",
"sieve_preset_8": "",
"sieve_preset_header": "",
"sogo_visible": "",
"stats": "",
"tls_policy_maps_long": "",
"quarantine_notification": "",
"recipient_map_old_info": "",
"table_size_show_n": "",
"tls_map_dest": "",
"tls_map_dest_info": "",
"sieve_preset_2": "",
"add_tls_policy_map": "",
"sieve_preset_3": "",
"syncjob_EXIT_OVERQUOTA": "",
"syncjob_EXIT_CONNECTION_FAILURE_HOST1": "",
"syncjob_EXIT_AUTHENTICATION_FAILURE_USER1": "",
"table_size": "",
"tls_map_parameters": "",
"disable_x": "",
"domain_templates": "",
"last_pw_change": "",
"no": "",
"public_comment": "",
"q_add_header": "",
"q_reject": "",
"recipient": "",
"relay_unknown": "",
"sieve_preset_1": "",
"sieve_preset_7": "",
"tls_map_parameters_info": "",
"tls_map_policy": "",
"tls_policy_maps": "",
"dkim_domains_selector": "",
"templates": "",
"never": "",
"add_template": "",
"all_domains": "",
"allowed_protocols": "",
"bcc_map": "",
"booking_custom_short": "",
"booking_ltnull": "",
"booking_lt0_short": "",
"catch_all": "",
"created_on": "",
"daily": "",
"disable_login": "",
"domain_quota_total": "",
"enable_x": "",
"gal": "",
"goto_ham": "",
"goto_spam": "",
"hourly": "",
"insert_preset": "",
"last_mail_login": "",
"last_modified": "",
"mailbox": "",
"mailbox_defaults": "",
"mailbox_defaults_info": "",
"mailbox_defquota": "",
"mailbox_templates": "",
"open_logs": "",
"private_comment": "",
"q_all": "",
"quarantine_category": "",
"recipient_map_new_info": "",
"sender": "",
"sieve_preset_4": "",
"sieve_preset_5": "",
"syncjob_last_run_result": "",
"syncjob_EXIT_CONNECTION_FAILURE": "",
"syncjob_EXIT_TLS_FAILURE": "",
"syncjob_EXIT_AUTHENTICATION_FAILURE": "",
"template": "",
"tls_policy_maps_enforced_tls": "",
"tls_policy_maps_info": "",
"weekly": "",
"yes": "",
"sogo_visible_n": "",
"add_alias_expand": "",
"alias_domain_alias_hint": "",
"alias_domain_backupmx": "",
"allow_from_smtp": "",
"allow_from_smtp_info": "",
"sogo_visible_y": "",
"syncjob_check_log": "",
"syncjob_EX_OK": "",
"sieve_preset_6": ""
},
"quarantine": {
"action": "Acció",
@@ -408,15 +863,59 @@
"subj": "Assumpte",
"text_from_html_content": "Contingut (a partir del HTML)",
"text_plain_content": "Contingut (text/plain)",
"toggle_all": "Marcar tots"
"toggle_all": "Marcar tots",
"deliver_inbox": "",
"spam_score": "",
"table_size": "",
"type": "",
"learn_spam_delete": "",
"confirm": "",
"confirm_delete": "",
"danger": "",
"disabled_by_config": "",
"spam": "",
"download_eml": "",
"high_danger": "",
"info": "",
"junk_folder": "",
"low_danger": "",
"medium_danger": "",
"neutral_danger": "",
"notified": "",
"qhandler_success": "",
"qinfo": "",
"quick_delete_link": "",
"quick_info_link": "",
"quick_release_link": "",
"rspamd_result": "",
"sender_header": "",
"settings_info": "",
"table_size_show_n": "",
"refresh": "",
"rejected": "",
"rewrite_subject": ""
},
"queue": {
"queue_manager": "Queue Manager"
"queue_manager": "Queue Manager",
"delete": "",
"flush": "",
"info": "",
"legend": "",
"ays": "",
"hold_mail": "",
"hold_mail_legend": "",
"unhold_mail": "",
"unhold_mail_legend": "",
"deliver_mail": "",
"deliver_mail_legend": "",
"show_message": "",
"unban": ""
},
"start": {
"help": "Mostrar/Ocultar panell d'ajuda",
"mailcow_apps_detail": "Tria una aplicació (de moment només SOGo) per a accedir als teus correus, calendari, contactes i més.",
"mailcow_panel_detail": "Els <b>administradors del domini</b> poden crear, modificar o esborrar bústies i àlies, configurar i obtenir informació detallada sobre els seus dominis<br>\r\n\tEls <b>usuaris d'e-mail</b> poden crear àlies temporals (spam àlies), canviar la seva contrasenya i la configuració del seu filtre anti-spam."
"mailcow_panel_detail": "Els <b>administradors del domini</b> poden crear, modificar o esborrar bústies i àlies, configurar i obtenir informació detallada sobre els seus dominis<br>\r\n\tEls <b>usuaris d'e-mail</b> poden crear àlies temporals (spam àlies), canviar la seva contrasenya i la configuració del seu filtre anti-spam.",
"imap_smtp_server_auth_info": ""
},
"success": {
"admin_modified": "Els canvis fets a l'administrador s'han desat",
@@ -453,7 +952,56 @@
"resource_modified": "S'han desat els canvis fets al recurs %s",
"resource_removed": "S'ha esborrat el recurs %s",
"ui_texts": "S'han desat els canvis als noms de App",
"upload_success": "El fitxer s'ha pujat"
"upload_success": "El fitxer s'ha pujat",
"template_removed": "",
"tls_policy_map_entry_deleted": "",
"app_passwd_added": "",
"bcc_saved": "",
"hash_deleted": "",
"ip_check_opt_in_modified": "",
"item_released": "",
"learned_ham": "",
"license_modified": "",
"logged_in_as": "",
"pushover_settings_edited": "",
"qlearn_spam": "",
"queue_command_success": "",
"recipient_map_entry_deleted": "",
"recipient_map_entry_saved": "",
"settings_map_removed": "",
"verified_fido2_login": "",
"global_filter_written": "",
"bcc_deleted": "",
"cors_headers_edited": "",
"db_init_complete": "",
"delete_filter": "",
"delete_filters": "",
"deleted_syncjob": "",
"deleted_syncjobs": "",
"domain_add_dkim_available": "",
"dkim_duplicated": "",
"sogo_profile_reset": "",
"template_modified": "",
"tls_policy_map_entry_saved": "",
"verified_webauthn_login": "",
"template_added": "",
"acl_saved": "",
"admin_added": "",
"admin_api_modified": "",
"admin_removed": "",
"app_passwd_removed": "",
"bcc_edited": "",
"domain_footer_modified": "",
"dovecot_restart_success": "",
"f2b_banlist_refreshed": "",
"rl_saved": "",
"rspamd_ui_pw_set": "",
"saved_settings": "",
"settings_map_added": "",
"verified_totp_login": "",
"verified_yotp_login": "",
"nginx_reloaded": "",
"password_policy_saved": ""
},
"tfa": {
"api_register": "%s fa servir la Yubico Cloud API. Obté una API key per la teva clau <a href=\"https://upgrade.yubico.com/getapikey/\" target=\"_blank\">aquí</a>",
@@ -473,7 +1021,15 @@
"webauthn": "Autenticació WebAuthn",
"waiting_usb_auth": "<i>Esperant el dispositiu USB...</i><br><br>Apreta el botó del teu dispositiu USB WebAuthn ara.",
"waiting_usb_register": "<i>Esperant el dispositiu USB...</i><br><br>Posa el teu password i confirma el registre del teu WebAuthn apretant el botó del teu dispositiiu USB WebAuthn.",
"yubi_otp": "Autenticació OTP de Yubico"
"yubi_otp": "Autenticació OTP de Yubico",
"reload_retry": "",
"authenticators": "",
"error_code": "",
"start_webauthn_validation": "",
"tfa_token_invalid": "",
"init_webauthn": "",
"u2f_deprecated": "",
"u2f_deprecated_important": ""
},
"user": {
"action": "Acció",
@@ -556,6 +1112,198 @@
"username": "Usuari",
"waiting": "Esperant",
"week": "Setmana",
"weeks": "Setmanes"
"weeks": "Setmanes",
"last_mail_login": "",
"last_pw_change": "",
"last_ui_login": "",
"login_history": "",
"open_logs": "",
"password": "",
"pushover_info": "",
"pushover_sender_array": "",
"app_hint": "",
"allowed_protocols": "",
"apple_connection_profile": "",
"apple_connection_profile_complete": "",
"apple_connection_profile_with_app_password": "",
"delete_ays": "",
"pushover_sound": "",
"years": "",
"daily": "",
"attribute": "",
"hourly": "",
"mailbox": "",
"mailbox_general": "",
"mailbox_settings": "",
"pushover_evaluate_x_prio": "",
"pushover_only_x_prio": "",
"q_add_header": "",
"quarantine_notification": "",
"sogo_profile_reset": "",
"app_passwds": "",
"created_on": "",
"change_password_hint_app_passwords": "",
"clear_recent_successful_connections": "",
"create_app_passwd": "",
"month": "",
"months": "",
"open_webmail_sso": "",
"password_repeat": "",
"pushover_text": "",
"quarantine_notification_info": "",
"recent_successful_connections": "",
"save": "",
"sender_acl_disabled": "",
"sogo_profile_reset_now": "",
"verify": "",
"syncjob_last_run_result": "",
"syncjob_EX_OK": "",
"syncjob_EXIT_CONNECTION_FAILURE": "",
"syncjob_check_log": "",
"title": "",
"apple_connection_profile_mailonly": "",
"expire_in": "",
"fido2_webauthn": "",
"pushover_sender_regex": "",
"pushover_title": "",
"pushover_vars": "",
"pushover_verify": "",
"q_all": "",
"quarantine_category": "",
"quarantine_category_info": "",
"sogo_profile_reset_help": "",
"spam_score_reset": "",
"syncjob_EXIT_TLS_FAILURE": "",
"syncjob_EXIT_AUTHENTICATION_FAILURE": "",
"syncjob_EXIT_OVERQUOTA": "",
"syncjob_EXIT_CONNECTION_FAILURE_HOST1": "",
"syncjob_EXIT_AUTHENTICATION_FAILURE_USER1": "",
"value": "",
"with_app_password": "",
"year": "",
"from": "",
"text": "",
"q_reject": "",
"generate": "",
"advanced_settings": "",
"app_name": "",
"direct_protocol_access": "",
"email": "",
"email_and_dav": "",
"empty": "",
"never": "",
"no_last_login": "",
"weekly": ""
},
"datatables": {
"decimal": "",
"infoPostFix": "",
"collapse_all": "",
"emptyTable": "",
"expand_all": "",
"info": "",
"infoEmpty": "",
"infoFiltered": "",
"lengthMenu": "",
"loadingRecords": "",
"processing": "",
"search": "",
"zeroRecords": "",
"paginate": {
"first": "",
"last": "",
"next": "",
"previous": ""
},
"aria": {
"sortAscending": "",
"sortDescending": ""
},
"thousands": ""
},
"debug": {
"history_all_servers": "",
"architecture": "",
"containers_info": "",
"container_running": "",
"docs": "",
"login_time": "",
"logs": "",
"error_show_ip": "",
"external_logs": "",
"in_memory_logs": "",
"jvm_memory_solr": "",
"last_modified": "",
"log_info": "",
"memory": "",
"online_users": "",
"restart_container": "",
"show_ip": "",
"size": "",
"solr_status": "",
"started_at": "",
"started_on": "",
"static_logs": "",
"success": "",
"system_containers": "",
"timezone": "",
"uptime": "",
"update_available": "",
"no_update_available": "",
"chart_this_server": "",
"container_disabled": "",
"container_stopped": "",
"cores": "",
"current_time": "",
"disk_usage": "",
"solr_dead": "",
"update_failed": "",
"username": "",
"wip": "",
"service": ""
},
"warning": {
"domain_added_sogo_failed": "",
"dovecot_restart_failed": "",
"fuzzy_learn_error": "",
"hash_not_found": "",
"no_active_admin": "",
"quota_exceeded_scope": "",
"cannot_delete_self": "",
"session_token": "",
"session_ua": "",
"ip_invalid": "",
"is_not_primary_alias": ""
},
"ratelimit": {
"hour": "",
"day": "",
"disabled": "",
"second": "",
"minute": ""
},
"oauth2": {
"permit": "",
"profile": "",
"scope_ask_permission": "",
"authorize_app": "",
"deny": "",
"profile_desc": "",
"access_denied": ""
},
"fido2": {
"confirm": "",
"fido2_auth": "",
"fido2_success": "",
"fido2_validation_failed": "",
"fn": "",
"known_ids": "",
"register_status": "",
"rename": "",
"set_fido2": "",
"set_fido2_touchid": "",
"set_fn": "",
"start_fido2_validation": "",
"none": ""
}
}

View File

@@ -346,7 +346,12 @@
"f2b_ban_time_increment": "Délka banu je prodlužována s každým dalším banem",
"f2b_max_ban_time": "Maximální délka banu (s)",
"cors_settings": "Nastavení CORS",
"queue_unban": "zrušit ban"
"queue_unban": "zrušit ban",
"copy_to_clipboard": "",
"f2b_manage_external": "",
"f2b_manage_external_info": "",
"allowed_methods": "",
"allowed_origins": ""
},
"danger": {
"access_denied": "Přístup odepřen nebo jsou neplatná data ve formuláři",
@@ -475,7 +480,9 @@
"webauthn_publickey_failed": "Pro vybraný ověřovací prostředek nebyl uložen žádný veřejný klíč",
"webauthn_username_failed": "Zvolený ověřovací prostředek patří k jinému účtu",
"extended_sender_acl_denied": "chybějící ACL pro nastavení externích adres odesílatele",
"demo_mode_enabled": "Demo režim je zapnutý"
"demo_mode_enabled": "Demo režim je zapnutý",
"img_dimensions_exceeded": "",
"img_size_exceeded": ""
},
"datatables": {
"emptyTable": "Tabulka neobsahuje žádná data",
@@ -500,7 +507,8 @@
"decimal": ",",
"thousands": " ",
"collapse_all": "Sbalit vše",
"expand_all": "Rozbalit vše"
"expand_all": "Rozbalit vše",
"infoPostFix": ""
},
"debug": {
"chart_this_server": "Graf (tento server)",
@@ -540,14 +548,15 @@
"update_failed": "Nepodařilo se zkontrolovat aktualizace",
"wip": "Nedokončená vývojová verze",
"memory": "Paměť",
"container_disabled": "Kontejner je zastaven nebo zakázán"
"container_disabled": "Kontejner je zastaven nebo zakázán",
"cores": ""
},
"diagnostics": {
"cname_from_a": "Hodnota odvozena z A/AAAA záznamu. Lze použít, pokud záznam ukazuje na správný zdroj.",
"dns_records": "DNS záznamy",
"dns_records_24hours": "Upozornění: Změnám v systému DNS může trvat až 24 hodin, než se zde správně zobrazí jejich aktuální stav. Můžete zde snadno zjistit, jak nastavit DNS záznamy a zda jsou všechny záznamy správně uloženy.",
"dns_records_data": "Správný záznam",
"dns_records_docs": "Přečtěte si prosím <a target=\"_blank\" href=\"https://docs.mailcow.email/prerequisite/prerequisite-dns/\">dokumentaci</a>.",
"dns_records_docs": "Přečtěte si prosím <a target=\"_blank\" href=\"https://docs.mailcow.email/getstarted/prerequisite-dns\">dokumentaci</a>.",
"dns_records_name": "Název",
"dns_records_status": "Současný stav",
"dns_records_type": "Typ",
@@ -672,12 +681,17 @@
"auth_user": "{= auth_user =} - Ověřené uživatelské jméno zadané MTA",
"from_user": "{= from_user =} - uživatelská část odesílatele, např. pro \"moo@mailcow.tld\" vrátí \"moo\"",
"from_domain": "{= from_domain =} - Doména odesílatele",
"from_addr": "{= from_addr =} - E-mailová adresa odesílatele"
"from_addr": "{= from_addr =} - E-mailová adresa odesílatele",
"custom": ""
},
"domain_footer": "Patička pro celou doménu",
"domain_footer_html": "HTML text",
"domain_footer_plain": "Prostý text",
"pushover_sound": "Zvukové upozornění"
"pushover_sound": "Zvukové upozornění",
"footer_exclude": "",
"custom_attributes": "",
"domain_footer_skip_replies": "",
"pushover": ""
},
"fido2": {
"confirm": "Potvrdit",
@@ -985,7 +999,8 @@
"hold_mail_legend": "Podrží vybrané e-maily. (Zabrání dalším pokusům o doručení)",
"show_message": "Zobrazit zprávu",
"unhold_mail": "Uvolnit",
"unhold_mail_legend": "Uvolnit vybrané e-maily k doručení. (Pouze v případě předchozího podržení)"
"unhold_mail_legend": "Uvolnit vybrané e-maily k doručení. (Pouze v případě předchozího podržení)",
"unban": ""
},
"ratelimit": {
"disabled": "Vypnuto",
@@ -1081,7 +1096,10 @@
"verified_webauthn_login": "WebAuthn přihlášení ověřeno",
"verified_yotp_login": "Yubico OTP přihlášení ověřeno",
"cors_headers_edited": "Nastavení CORS byla uložena",
"domain_footer_modified": "Změny patičky domény %s byly uloženy"
"domain_footer_modified": "Změny patičky domény %s byly uloženy",
"f2b_banlist_refreshed": "",
"domain_add_dkim_available": "",
"ip_check_opt_in_modified": ""
},
"tfa": {
"api_register": "%s používá Yubico Cloud API. Prosím získejte API klíč pro své Yubico <a href=\"https://upgrade.yubico.com/getapikey/\" target=\"_blank\">ZDE</a>",
@@ -1106,7 +1124,10 @@
"webauthn": "WebAuthn ověření",
"waiting_usb_auth": "<i>Čeká se na USB zařízení...</i><br><br>Prosím stiskněte tlačítko na svém WebAuthn USB zařízení.",
"waiting_usb_register": "<i>Čeká se na USB zařízení...</i><br><br>Prosím zadejte své heslo výše a potvrďte WebAuthn registraci stiskem tlačítka na svém WebAuthn USB zařízení.",
"yubi_otp": "Yubico OTP ověření"
"yubi_otp": "Yubico OTP ověření",
"authenticators": "",
"u2f_deprecated": "",
"u2f_deprecated_important": ""
},
"user": {
"action": "Akce",
@@ -1268,7 +1289,9 @@
"with_app_password": "s heslem aplikace",
"year": "rok",
"years": "let",
"pushover_sound": "Zvukové upozornění"
"pushover_sound": "Zvukové upozornění",
"attribute": "",
"value": ""
},
"warning": {
"cannot_delete_self": "Nelze smazat právě přihlášeného uživatele",

View File

@@ -107,7 +107,8 @@
"validation_success": "Valideret med succes",
"bcc_dest_format": "BCC-destination skal være en enkelt gyldig e-mail-adresse.<br>Hvis du har brug for at sende en kopi til flere adresser, kan du oprette et alias og bruge det her.",
"app_passwd_protocols": "Tilladte protokoller for app adgangskode",
"tags": "Tag's"
"tags": "Tag's",
"dry": ""
},
"admin": {
"access": "Adgang",
@@ -317,7 +318,40 @@
"yes": "&#10003;",
"ip_check_opt_in": "Opt-In for brug af tredjepartstjeneste <strong>ipv4.mailcow.email</strong> og <strong>ipv6.mailcow.email</strong> til at finde eksterne IP-adresser.",
"queue_unban": "unban",
"admins": "Administratorer"
"admins": "Administratorer",
"copy_to_clipboard": "",
"f2b_ban_time_increment": "",
"f2b_manage_external": "",
"f2b_manage_external_info": "",
"logo_normal_label": "",
"logo_dark_label": "",
"f2b_max_ban_time": "",
"cors_settings": "",
"allowed_origins": "",
"allowed_methods": "",
"options": "",
"password_length": "",
"password_policy": "",
"password_policy_chars": "",
"password_policy_length": "",
"ip_check": "",
"login_time": "",
"oauth2_apps": "",
"oauth2_add_client": "",
"password_policy_lowerupper": "",
"password_policy_numbers": "",
"password_policy_special_chars": "",
"relay_rcpt": "",
"service": "",
"transport_test_rcpt_info": "",
"ip_check_disabled": "",
"rsettings_preset_4": "",
"convert_html_to_text": "",
"success": "",
"is_mx_based": "",
"admins_ldap": "",
"api_read_only": "",
"api_read_write": ""
},
"danger": {
"access_denied": "Adgang nægtet eller ugyldig formular data",
@@ -435,7 +469,20 @@
"validity_missing": "Tildel venligst en gyldighedsperiode",
"value_missing": "Angiv alle værdier",
"yotp_verification_failed": "Yubico OTP verifikationen mislykkedes: %s",
"webauthn_publickey_failed": "Der er ikke gemt nogen offentlig nøgle for den valgte autentifikator"
"webauthn_publickey_failed": "Der er ikke gemt nogen offentlig nøgle for den valgte autentifikator",
"cors_invalid_method": "",
"cors_invalid_origin": "",
"img_dimensions_exceeded": "",
"img_size_exceeded": "",
"webauthn_authenticator_failed": "",
"webauthn_username_failed": "",
"nginx_reload_failed": "",
"template_exists": "",
"extended_sender_acl_denied": "",
"extra_acl_invalid_domain": "",
"template_id_invalid": "",
"template_name_invalid": "",
"demo_mode_enabled": ""
},
"debug": {
"chart_this_server": "Diagram (denne server)",
@@ -453,13 +500,36 @@
"started_on": "Startede den",
"static_logs": "Statiske logfiler",
"system_containers": "System og Beholdere",
"error_show_ip": "Kunne ikke finde de offentlige IP-adresser"
"error_show_ip": "Kunne ikke finde de offentlige IP-adresser",
"update_available": "",
"username": "",
"timezone": "",
"started_at": "",
"success": "",
"uptime": "",
"architecture": "",
"container_running": "",
"cores": "",
"current_time": "",
"docs": "",
"last_modified": "",
"login_time": "",
"memory": "",
"show_ip": "",
"size": "",
"no_update_available": "",
"update_failed": "",
"wip": "",
"online_users": "",
"service": "",
"container_disabled": "",
"container_stopped": ""
},
"diagnostics": {
"cname_from_a": "Værdi afledt af A / AAAA-post. Dette understøttes, så længe posten peger på den korrekte ressource.",
"dns_records": "DNS-poster",
"dns_records_24hours": "Bemærk, at ændringer, der foretages i DNS, kan tage op til 24 timer for at få deres aktuelle status korrekt reflekteret på denne side. Det er beregnet som en måde for dig let at se, hvordan du konfigurerer dine DNS-poster og kontrollere, om alle dine poster er korrekt gemt i DNS.",
"dns_records_docs": "Se også <a target=\"_blank\" href=\"https://docs.mailcow.email/prerequisite/prerequisite-dns/\">dokumentationen</a>.",
"dns_records_docs": "Se også <a target=\"_blank\" href=\"https://docs.mailcow.email/getstarted/prerequisite-dns\">dokumentationen</a>.",
"dns_records_data": "Korrekte data",
"dns_records_name": "Navn",
"dns_records_status": "Nuværende tilstand",
@@ -568,7 +638,34 @@
"admin": "Rediger administrator",
"lookup_mx": "Destination er et regulært udtryk, der matcher MX-navnet (<code>.*google\\.dk</code> for at dirigere al e-mail, der er målrettet til en MX, der ender på google.dk, over dette hop)",
"mailbox_relayhost_info": "Anvendt på postkassen og kun direkte aliasser, og overskriver et domæne relæ-host.",
"quota_warning_bcc": "Kvoteadvarsel BCC"
"quota_warning_bcc": "Kvoteadvarsel BCC",
"footer_exclude": "",
"custom_attributes": "",
"last_modified": "",
"app_passwd_protocols": "",
"created_on": "",
"domain_footer_info_vars": {
"custom": "",
"auth_user": "",
"from_user": "",
"from_name": "",
"from_addr": "",
"from_domain": ""
},
"domain_footer_skip_replies": "",
"spam_filter": "",
"domain_footer": "",
"domain_footer_html": "",
"domain_footer_info": "",
"domain_footer_plain": "",
"sogo_access_info": "",
"acl": "",
"none_inherit": "",
"pushover": "",
"pushover_sound": "",
"quota_warning_bcc_info": "",
"ratelimit": "",
"sogo_access": ""
},
"footer": {
"cancel": "Afbestille",
@@ -581,7 +678,9 @@
"restart_container": "Genstart beholderen",
"restart_container_info": "<b>Vigtig:</b> Det kan tage et stykke tid at gennemføre en yndefuld genstart. Vent til den er færdig.",
"restart_now": "Genstart nu",
"restarting_container": "Genstart af beholder, det kan tage et stykke tid"
"restarting_container": "Genstart af beholder, det kan tage et stykke tid",
"hibp_check": "",
"nothing_selected": ""
},
"header": {
"administration": "Konfiguration og detailer",
@@ -592,7 +691,8 @@
"quarantine": "Karantæne",
"restart_netfilter": "Genstart netfilter",
"restart_sogo": "Genstart SOGo",
"user_settings": "Brugerindstillinger"
"user_settings": "Brugerindstillinger",
"mailcow_system": ""
},
"info": {
"awaiting_tfa_confirmation": "Venter på TFA-bekræftelse",
@@ -757,7 +857,31 @@
"yes": "&#10003;",
"goto_ham": "Lær som <b>ønsket</b>",
"catch_all": "Fang-alt",
"open_logs": "Åben logfiler"
"open_logs": "Åben logfiler",
"syncjob_EXIT_AUTHENTICATION_FAILURE": "",
"syncjob_EXIT_OVERQUOTA": "",
"syncjob_EXIT_CONNECTION_FAILURE_HOST1": "",
"syncjob_EXIT_AUTHENTICATION_FAILURE_USER1": "",
"all_domains": "",
"domain_templates": "",
"last_modified": "",
"last_pw_change": "",
"mailbox_templates": "",
"template": "",
"relay_unknown": "",
"add_alias_expand": "",
"add_template": "",
"created_on": "",
"goto_spam": "",
"recipient": "",
"relay_all": "",
"sender": "",
"syncjob_check_log": "",
"syncjob_last_run_result": "",
"syncjob_EX_OK": "",
"syncjob_EXIT_CONNECTION_FAILURE": "",
"syncjob_EXIT_TLS_FAILURE": "",
"templates": ""
},
"oauth2": {
"access_denied": "Log ind som mailboks ejer for at give adgang via OAuth2.",
@@ -818,10 +942,24 @@
"table_size_show_n": "Vis %s genstande",
"text_from_html_content": "Indhold (konverterede html)",
"text_plain_content": "Indhold (text/plain)",
"toggle_all": "Skift alt"
"toggle_all": "Skift alt",
"settings_info": ""
},
"queue": {
"queue_manager": "Køadministrator"
"queue_manager": "Køadministrator",
"deliver_mail": "",
"delete": "",
"flush": "",
"info": "",
"legend": "",
"ays": "",
"deliver_mail_legend": "",
"hold_mail": "",
"hold_mail_legend": "",
"show_message": "",
"unban": "",
"unhold_mail": "",
"unhold_mail_legend": ""
},
"start": {
"help": "Vis / skjul hjælpepanel",
@@ -903,7 +1041,17 @@
"verified_totp_login": "Bekræftet TOTP-login",
"verified_webauthn_login": "Bekræftet WebAuthn-login",
"verified_fido2_login": "Bekræftet FIDO2-login",
"verified_yotp_login": "Bekræftet Yubico OTP-login"
"verified_yotp_login": "Bekræftet Yubico OTP-login",
"template_removed": "",
"domain_footer_modified": "",
"cors_headers_edited": "",
"domain_add_dkim_available": "",
"f2b_banlist_refreshed": "",
"ip_check_opt_in_modified": "",
"nginx_reloaded": "",
"password_policy_saved": "",
"template_added": "",
"template_modified": ""
},
"tfa": {
"api_register": "%s bruger Yubico Cloud API. Få en API-nøgle til din nøgle <a href=\"https://upgrade.yubico.com/getapikey/\" target=\"_blank\">here</a>",
@@ -928,7 +1076,10 @@
"webauthn": "WebAuthn godkendelse",
"waiting_usb_auth": "<i>Venter på USB-enhed...</i><br><br>Tryk let på knappen på din USB-enhed nu.",
"waiting_usb_register": "<i>Venter på USB-enhed...</i><br><br>Indtast din adgangskode ovenfor, og bekræft din registrering ved at trykke på knappen på din USB-enhed.",
"yubi_otp": "Yubico OTP godkendelse"
"yubi_otp": "Yubico OTP godkendelse",
"authenticators": "",
"u2f_deprecated": "",
"u2f_deprecated_important": ""
},
"fido2": {
"set_fn": "Set venneligt navn",
@@ -942,7 +1093,8 @@
"start_fido2_validation": "Start FIDO2 validering",
"fido2_auth": "Login med FIDO2",
"fido2_success": "Enheden blev registreret",
"fido2_validation_failed": "Validering mislykkedes"
"fido2_validation_failed": "Validering mislykkedes",
"set_fido2_touchid": ""
},
"user": {
"action": "Handling",
@@ -1071,7 +1223,42 @@
"waiting": "Venter",
"week": "uge",
"weekly": "Ugeligt",
"weeks": "uger"
"weeks": "uger",
"empty": "",
"allowed_protocols": "",
"login_history": "",
"mailbox": "",
"mailbox_general": "",
"syncjob_EXIT_TLS_FAILURE": "",
"syncjob_EXIT_AUTHENTICATION_FAILURE": "",
"syncjob_EXIT_OVERQUOTA": "",
"syncjob_EXIT_CONNECTION_FAILURE_HOST1": "",
"syncjob_EXIT_AUTHENTICATION_FAILURE_USER1": "",
"syncjob_check_log": "",
"syncjob_last_run_result": "",
"syncjob_EX_OK": "",
"apple_connection_profile_with_app_password": "",
"attribute": "",
"change_password_hint_app_passwords": "",
"clear_recent_successful_connections": "",
"created_on": "",
"direct_protocol_access": "",
"fido2_webauthn": "",
"from": "",
"last_pw_change": "",
"last_ui_login": "",
"month": "",
"months": "",
"open_logs": "",
"open_webmail_sso": "",
"pushover_sound": "",
"recent_successful_connections": "",
"syncjob_EXIT_CONNECTION_FAILURE": "",
"value": "",
"with_app_password": "",
"year": "",
"years": "",
"mailbox_settings": ""
},
"warning": {
"cannot_delete_self": "Kan ikke slette en bruger som er logget ind.",
@@ -1083,12 +1270,40 @@
"no_active_admin": "Kan ikke deaktivere den sidste administrator",
"quota_exceeded_scope": "Domænekvote overskredet: Kun ubegrænsede postkasser kan oprettes i dette domæneomfang.",
"session_token": "Form nøgle ugyldig: Nøgle passer ikke",
"session_ua": "Form nøgle ugyldig: Bruger-Agent gyldighedskontrols fejl"
"session_ua": "Form nøgle ugyldig: Bruger-Agent gyldighedskontrols fejl",
"is_not_primary_alias": ""
},
"datatables": {
"lengthMenu": "Vis _MENU_ poster",
"paginate": {
"first": "Først"
}
"first": "Først",
"last": "",
"next": "",
"previous": ""
},
"decimal": "",
"infoPostFix": "",
"loadingRecords": "",
"processing": "",
"search": "",
"zeroRecords": "",
"thousands": "",
"emptyTable": "",
"expand_all": "",
"info": "",
"infoEmpty": "",
"infoFiltered": "",
"aria": {
"sortAscending": "",
"sortDescending": ""
},
"collapse_all": ""
},
"ratelimit": {
"day": "",
"hour": "",
"disabled": "",
"second": "",
"minute": ""
}
}

View File

@@ -394,7 +394,9 @@
"goto_invalid": "Ziel-Adresse %s ist ungültig",
"ham_learn_error": "Ham Lernfehler: %s",
"imagick_exception": "Fataler Bildverarbeitungsfehler",
"img_dimensions_exceeded": "Grafik überschreitet die maximale Bildgröße",
"img_invalid": "Grafik konnte nicht validiert werden",
"img_size_exceeded": "Grafik überschreitet die maximale Dateigröße",
"img_tmp_missing": "Grafik konnte nicht validiert werden: Erstellung temporärer Datei fehlgeschlagen.",
"invalid_bcc_map_type": "Ungültiger BCC-Map-Typ",
"invalid_destination": "Ziel-Format \"%s\" ist ungültig",
@@ -554,7 +556,7 @@
"dns_records": "DNS-Einträge",
"dns_records_24hours": "Bitte beachten Sie, dass es bis zu 24 Stunden dauern kann, bis Änderungen an Ihren DNS-Einträgen als aktueller Status auf dieser Seite dargestellt werden. Diese Seite ist nur als Hilfsmittel gedacht, um die korrekten Werte für DNS-Einträge anzuzeigen und zu überprüfen, ob die Daten im DNS hinterlegt sind.",
"dns_records_data": "Korrekte Daten",
"dns_records_docs": "Die <a target=\"_blank\" href=\"https://docs.mailcow.email/prerequisite/prerequisite-dns/\">Online-Dokumentation</a> enthält weitere Informationen zur DNS-Konfiguration.",
"dns_records_docs": "Die <a target=\"_blank\" href=\"https://docs.mailcow.email/de/getstarted/prerequisite-dns\">Online-Dokumentation</a> enthält weitere Informationen zur DNS-Konfiguration.",
"dns_records_name": "Name",
"dns_records_status": "Aktueller Status",
"dns_records_type": "Typ",
@@ -588,10 +590,19 @@
"disable_login": "Login verbieten (Mails werden weiterhin angenommen)",
"domain": "Domain bearbeiten",
"domain_admin": "Domain-Administrator bearbeiten",
"domain_footer": "Domain wide footer",
"domain_footer_html": "HTML footer",
"domain_footer_info": "Domain wide footer werden allen ausgehenden E-Mails hinzugefügt, die einer Adresse innerhalb dieser Domain gehört.<br>Die folgenden Variablen können für den Footer benutzt werden:",
"domain_footer_plain": "PLAIN footer",
"domain_footer": "Domänenweite Fußzeile",
"domain_footer_html": "Fußzeile im HTML Format",
"domain_footer_info": "Domänenweite Footer (Domain wide footer) werden allen ausgehenden E-Mails hinzugefügt, die einer Adresse innerhalb dieser Domain gehört.<br>Die folgenden Variablen können für die Fußzeile benutzt werden:",
"domain_footer_info_vars": {
"auth_user": "{= auth_user =} - Angemeldeter Benutzername vom MTA",
"from_user": "{= from_user =} - Absender Teil der E-Mail z.B. für \"moo@mailcow.tld\" wird \"moo\" zurückgeben.",
"from_name": "{= from_name =} - Namen des Absenders z.B. für \"Mailcow &lt;moo@mailcow.tld&gt;\", wird \"Mailcow\" zurückgegeben.",
"from_addr": "{= from_addr =} - Adresse des Absenders.",
"from_domain": "{= from_domain =} - Domain des Absenders",
"custom": "{= foo =} - Wenn die Mailbox das benutzerdefinierte Attribut \"foo\" mit dem Wert \"bar\" hat, wird \"bar\" zurückgegeben."
},
"domain_footer_plain": "Fußzeile im PLAIN Format",
"domain_footer_skip_replies": "Ignoriere Footer bei Antwort E-Mails",
"domain_quota": "Domain Speicherplatz gesamt (MiB)",
"domains": "Domains",
"dont_check_sender_acl": "Absender für Domain %s u. Alias-Domain nicht prüfen",
@@ -602,6 +613,7 @@
"extended_sender_acl_info": "Der DKIM-Domainkey der externen Absenderdomain sollte in diesen Server importiert werden, falls vorhanden.<br>\r\n Wird SPF verwendet, muss diesem Server der Versand gestattet werden.<br>\r\n Wird eine Domain oder Alias-Domain zu diesem Server hinzugefügt, die sich mit der externen Absenderadresse überschneidet, wird der externe Absender hier entfernt.<br>\r\n Ein Eintrag @domain.tld erlaubt den Versand als *@domain.tld",
"force_pw_update": "Erzwinge Passwortänderung bei nächstem Login",
"force_pw_update_info": "Dem Benutzer wird lediglich der Zugang zur %s ermöglicht, App Passwörter funktionieren weiterhin.",
"footer_exclude": "von Fußzeile ausschließen",
"full_name": "Voller Name",
"gal": "Globales Adressbuch",
"gal_info": "Das globale Adressbuch enthält alle Objekte einer Domain und kann durch keinen Benutzer geändert werden. Die Verfügbarkeitsinformation in SOGo ist nur bei eingeschaltetem globalen Adressbuch ersichtlich <b>Zum Anwenden einer Änderung muss SOGo neugestartet werden.</b>",
@@ -620,7 +632,6 @@
"max_quota": "Max. Größe per Mailbox (MiB)",
"maxage": "Maximales Alter in Tagen einer Nachricht, die kopiert werden soll<br><small>(0 = alle Nachrichten kopieren)</small>",
"maxbytespersecond": "Max. Übertragungsrate in Bytes/s (0 für unlimitiert)",
"mbox_exclude": "Mailboxen ausschließen",
"mbox_rl_info": "Dieses Limit wird auf den SASL Loginnamen angewendet und betrifft daher alle Absenderadressen, die der eingeloggte Benutzer verwendet. Bei Mailbox Ratelimit überwiegt ein Domain-weites Ratelimit.",
"mins_interval": "Intervall (min)",
"multiple_bookings": "Mehrfaches Buchen",
@@ -680,11 +691,7 @@
"unchanged_if_empty": "Unverändert, wenn leer",
"username": "Benutzername",
"validate_save": "Validieren und speichern",
"pushover_sound": "Ton",
"domain_footer_info_vars": {
"auth_user": "{= auth_user =} - Angemeldeter Benutzername vom MTA",
"from_user": "{= from_user =} - Von Teil des Benutzers z.B. \"moo@mailcow.tld\" wird \"moo\" zurückgeben."
}
"pushover_sound": "Ton"
},
"fido2": {
"confirm": "Bestätigen",
@@ -1088,6 +1095,7 @@
"verified_yotp_login": "Yubico-OTP-Anmeldung verifiziert"
},
"tfa": {
"authenticators": "Authentikatoren",
"api_register": "%s verwendet die Yubico-Cloud-API. Ein API-Key für den Yubico-Stick kann <a href=\"https://upgrade.yubico.com/getapikey/\" target=\"_blank\">hier</a> bezogen werden.",
"confirm": "Bestätigen",
"confirm_totp_token": "Bitte bestätigen Sie die Änderung durch Eingabe eines generierten Tokens",

View File

@@ -394,7 +394,9 @@
"goto_invalid": "Goto address %s is invalid",
"ham_learn_error": "Ham learn error: %s",
"imagick_exception": "Error: Imagick exception while reading image",
"img_dimensions_exceeded": "Image exceeds the maximum image size",
"img_invalid": "Cannot validate image file",
"img_size_exceeded": "Image exceeds the maximum file size",
"img_tmp_missing": "Cannot validate image file: Temporary file not found",
"invalid_bcc_map_type": "Invalid BCC map type",
"invalid_destination": "Destination format \"%s\" is invalid",
@@ -554,7 +556,7 @@
"dns_records": "DNS Records",
"dns_records_24hours": "Please note that changes made to DNS may take up to 24 hours to correctly have their current state reflected on this page. It is intended as a way for you to easily see how to configure your DNS records and to check whether all your records are correctly stored in DNS.",
"dns_records_data": "Correct Data",
"dns_records_docs": "Please also consult <a target=\"_blank\" href=\"https://docs.mailcow.email/prerequisite/prerequisite-dns/\">the documentation</a>.",
"dns_records_docs": "Please also consult <a target=\"_blank\" href=\"https://docs.mailcow.email/getstarted/prerequisite-dns\">the documentation</a>.",
"dns_records_name": "Name",
"dns_records_status": "Current State",
"dns_records_type": "Type",
@@ -600,6 +602,7 @@
"custom": "{= foo =} - If mailbox has the custom attribute \"foo\" with value \"bar\" it returns \"bar\""
},
"domain_footer_plain": "PLAIN footer",
"domain_footer_skip_replies": "Ignore footer on reply e-mails",
"domain_quota": "Domain quota",
"domains": "Domains",
"dont_check_sender_acl": "Disable sender check for domain %s (+ alias domains)",
@@ -610,6 +613,7 @@
"extended_sender_acl_info": "A DKIM domain key should be imported, if available.<br>\r\n Remember to add this server to the corresponding SPF TXT record.<br>\r\n Whenever a domain or alias domain is added to this server, that overlaps with an external address, the external address is removed.<br>\r\n Use @domain.tld to allow to send as *@domain.tld.",
"force_pw_update": "Force password update at next login",
"force_pw_update_info": "This user will only be able to login to %s. App passwords remain useable.",
"footer_exclude": "Exclude from footer",
"full_name": "Full name",
"gal": "Global Address List",
"gal_info": "The GAL contains all objects of a domain and cannot be edited by any user. Free/busy information in SOGo is missing, if disabled! <b>Restart SOGo to apply changes.</b>",
@@ -628,7 +632,6 @@
"max_quota": "Max. quota per mailbox (MiB)",
"maxage": "Maximum age of messages in days that will be polled from remote<br><small>(0 = ignore age)</small>",
"maxbytespersecond": "Max. bytes per second <br><small>(0 = unlimited)</small>",
"mbox_exclude": "Exclude mailboxes",
"mbox_rl_info": "This rate limit is applied on the SASL login name, it matches any \"from\" address used by the logged-in user. A mailbox rate limit overrides a domain-wide rate limit.",
"mins_interval": "Interval (min)",
"multiple_bookings": "Multiple bookings",
@@ -1099,6 +1102,7 @@
"verified_yotp_login": "Verified Yubico OTP login"
},
"tfa": {
"authenticators": "Authenticators",
"api_register": "%s uses the Yubico Cloud API. Please get an API key for your key <a href=\"https://upgrade.yubico.com/getapikey/\" target=\"_blank\">here</a>",
"confirm": "Confirm",
"confirm_totp_token": "Please confirm your changes by entering the generated token",

View File

@@ -22,7 +22,13 @@
"app_passwds": "Gestionar las contraseñas de aplicaciones",
"domain_desc": "Cambiar descripción del dominio",
"protocol_access": "Cambiar protocolo de acceso",
"quarantine_category": "Cambiar categoría de las notificaciones de cuarentena"
"quarantine_category": "Cambiar categoría de las notificaciones de cuarentena",
"domain_relayhost": "Cambiar relayhost por un dominio",
"extend_sender_acl": "Permitir extender la ACL del remitente por direcciones externas",
"smtp_ip_access": "",
"sogo_access": "",
"mailbox_relayhost": "",
"pushover": ""
},
"add": {
"activate_filter_warn": "Todos los demás filtros se desactivarán cuando este filtro se active.",
@@ -93,7 +99,16 @@
"app_password": "Añadir contraseña para la app",
"public_comment": "Comentarios públicos",
"disable_login": "Desactivar login (el correo entrante seguirá activo)",
"comment_info": "Los comentarios privados no son visibles al usuario, mientras que los comentarios públicos aparecerán sobre la información general del usuario"
"comment_info": "Los comentarios privados no son visibles al usuario, mientras que los comentarios públicos aparecerán sobre la información general del usuario",
"dry": "",
"private_comment": "",
"relay_transport_info": "",
"domain_matches_hostname": "",
"relay_unknown_only": "",
"relayhost_wrapped_tls_info": "",
"app_passwd_protocols": "",
"bcc_dest_format": "",
"tags": ""
},
"admin": {
"access": "Acceso",
@@ -246,7 +261,97 @@
"unban_pending": "Desbloqueo pendiente",
"unchanged_if_empty": "Si no hay cambios déjalo en blanco",
"upload": "Cargar",
"username": "Nombre de usuario"
"username": "Nombre de usuario",
"lookup_mx": "",
"license_info": "",
"message": "",
"oauth2_apps": "",
"transport_dest_format": "",
"ui_footer": "",
"copy_to_clipboard": "",
"f2b_manage_external": "",
"f2b_manage_external_info": "",
"no": "",
"quarantine_max_score": "",
"queue_unban": "",
"rate_name": "",
"regex_maps": "",
"relay_rcpt": "",
"rsetting_no_selection": "",
"rsettings_preset_3": "",
"rsettings_preset_4": "",
"title": "",
"transport_test_rcpt_info": "",
"oauth2_add_client": "",
"oauth2_revoke_tokens": "",
"options": "",
"ui_header_announcement": "",
"logo_normal_label": "",
"logo_dark_label": "",
"quarantine_redirect": "",
"time": "",
"ui_header_announcement_active": "",
"ui_header_announcement_type_info": "",
"ui_header_announcement_type_warning": "",
"validate_license_now": "",
"reset_limit": "",
"success": "",
"allowed_methods": "",
"allowed_origins": "",
"cors_settings": "",
"login_time": "",
"yes": "",
"f2b_filter": "",
"html": "",
"oauth2_redirect_uri": "",
"oauth2_renew_secret": "",
"admins": "",
"admins_ldap": "",
"guid": "",
"guid_and_license": "",
"hash_remove_info": "",
"is_mx_based": "",
"last_applied": "",
"ip_check": "",
"ip_check_disabled": "",
"ip_check_opt_in": "",
"rspamd_global_filters_regex": "",
"sal_level": "",
"service": "",
"service_id": "",
"oauth2_info": "",
"optional": "",
"password_length": "",
"password_policy": "",
"password_policy_chars": "",
"password_policy_length": "",
"password_policy_lowerupper": "",
"password_policy_numbers": "",
"priority": "",
"quarantine_bcc": "",
"rspamd_global_filters": "",
"rspamd_global_filters_agree": "",
"rspamd_global_filters_info": "",
"ui_header_announcement_content": "",
"ui_header_announcement_help": "",
"ui_header_announcement_select": "",
"ui_header_announcement_type": "",
"ui_header_announcement_type_danger": "",
"verify": "",
"customer_id": "",
"dkim_overwrite_key": "",
"domain_admin": "",
"domain_s": "",
"f2b_regex_info": "",
"advanced_settings": "",
"api_info": "",
"api_read_only": "",
"api_read_write": "",
"api_skip_ip_check": "",
"authed_user": "",
"ays": "",
"convert_html_to_text": "",
"password_policy_special_chars": ""
},
"danger": {
"access_denied": "Acceso denegado o datos del formulario inválidos",
@@ -334,7 +439,50 @@
"username_invalid": "Nombre de usuario no se puede utilizar",
"validity_missing": "Por favor asigna un periodo de validez",
"value_missing": "Por favor proporcione todos los valores",
"yotp_verification_failed": "Verificación Yubico OTP fallida: %s"
"yotp_verification_failed": "Verificación Yubico OTP fallida: %s",
"invalid_mime_type": "",
"description_invalid": "",
"dkim_domain_or_sel_exists": "",
"extended_sender_acl_denied": "",
"extra_acl_invalid": "",
"last_key": "",
"webauthn_authenticator_failed": "",
"webauthn_publickey_failed": "",
"webauthn_username_failed": "",
"app_name_empty": "",
"app_passwd_id_invalid": "",
"comment_too_long": "",
"cors_invalid_method": "",
"cors_invalid_origin": "",
"demo_mode_enabled": "",
"global_filter_write_error": "",
"pushover_credentials_missing": "",
"pushover_key": "",
"pushover_token": "",
"img_dimensions_exceeded": "",
"img_size_exceeded": "",
"maxquota_empty": "",
"nginx_reload_failed": "",
"targetd_relay_domain": "",
"template_exists": "",
"template_id_invalid": "",
"temp_error": "",
"tfa_token_invalid": "",
"tls_policy_map_dest_invalid": "",
"extra_acl_invalid_domain": "",
"fido2_verification_failed": "",
"template_name_invalid": "",
"resource_invalid": "",
"file_open_error": "",
"img_tmp_missing": "",
"invalid_filter_type": "",
"global_map_invalid": "",
"global_map_write_error": "",
"ham_learn_error": "",
"img_invalid": "",
"imagick_exception": "",
"max_alias_exceeded": "",
"reset_f2b_regex": ""
},
"debug": {
"containers_info": "Información de los contenedores",
@@ -352,7 +500,30 @@
"solr_status": "Solr status",
"uptime": "Uptime",
"static_logs": "Logs estáticos",
"system_containers": "Sistema y Contenedores"
"system_containers": "Sistema y Contenedores",
"container_disabled": "",
"architecture": "",
"update_failed": "",
"wip": "",
"chart_this_server": "",
"container_running": "",
"container_stopped": "",
"cores": "",
"current_time": "",
"error_show_ip": "",
"history_all_servers": "",
"jvm_memory_solr": "",
"memory": "",
"online_users": "",
"service": "",
"show_ip": "",
"started_on": "",
"success": "",
"timezone": "",
"update_available": "",
"no_update_available": "",
"username": "",
"login_time": ""
},
"diagnostics": {
"cname_from_a": "Valor derivado del registro A / AAAA. Esto es permitido siempre que el registro apunte al recurso correcto.",
@@ -362,7 +533,8 @@
"dns_records_name": "Nombre",
"dns_records_status": "Información actual",
"dns_records_type": "Tipo",
"optional": "Este récord es opcional."
"optional": "Este récord es opcional.",
"dns_records_docs": ""
},
"edit": {
"active": "Activo",
@@ -430,13 +602,85 @@
"title": "Editar objeto",
"unchanged_if_empty": "Si no hay cambios dejalo en blanco",
"username": "Nombre de usuario",
"validate_save": "Validar y guardar"
"validate_save": "Validar y guardar",
"lookup_mx": "",
"footer_exclude": "",
"custom_attributes": "",
"domain_footer_info_vars": {
"from_user": "",
"from_name": "",
"from_domain": "",
"custom": "",
"auth_user": "",
"from_addr": ""
},
"domain_footer_plain": "",
"domain_footer_skip_replies": "",
"sender_acl_info": "",
"domain_footer": "",
"domain_footer_html": "",
"spam_score": "",
"domain_footer_info": "",
"acl": "",
"relay_transport_info": "",
"sender_acl_disabled": "",
"sogo_access": "",
"sogo_access_info": "",
"sogo_visible": "",
"sogo_visible_info": "",
"spam_alias": "",
"spam_filter": "",
"spam_policy": "",
"generate": "",
"private_comment": "",
"public_comment": "",
"pushover": "",
"pushover_evaluate_x_prio": "",
"pushover_text": "",
"admin": "",
"advanced_settings": "",
"allow_from_smtp": "",
"allow_from_smtp_info": "",
"allowed_protocols": "",
"app_passwd": "",
"app_passwd_protocols": "",
"comment_info": "",
"created_on": "",
"delete_ays": "",
"extended_sender_acl": "",
"extended_sender_acl_info": "",
"mbox_rl_info": "",
"none_inherit": "",
"pushover_only_x_prio": "",
"pushover_sender_array": "",
"pushover_title": "",
"pushover_sound": "",
"pushover_vars": "",
"mailbox_relayhost_info": "",
"pushover_verify": "",
"quota_warning_bcc": "",
"quota_warning_bcc_info": "",
"ratelimit": "",
"relay_unknown_only": "",
"pushover_info": "",
"pushover_sender_regex": "",
"app_name": "",
"disable_login": ""
},
"footer": {
"hibp_nok": "¡Se encontró coincidencia - esta es una contraseña <b>no segura</b>, selecciona otra!",
"hibp_ok": "No se encontraron coincidencias",
"loading": "Espera por favor...",
"restart_now": "Reiniciar ahora"
"restart_now": "Reiniciar ahora",
"cancel": "",
"confirm_delete": "",
"delete_now": "",
"hibp_check": "",
"nothing_selected": "",
"delete_these_items": "",
"restart_container": "",
"restarting_container": "",
"restart_container_info": ""
},
"header": {
"administration": "Administración",
@@ -445,17 +689,24 @@
"mailcow_config": "Configuración",
"quarantine": "Cuarentena",
"restart_sogo": "Reiniciar SOGo",
"user_settings": "Configuraciones de usuario"
"user_settings": "Configuraciones de usuario",
"apps": "",
"mailcow_system": "",
"restart_netfilter": ""
},
"info": {
"awaiting_tfa_confirmation": "En espera de confirmación de TFA",
"no_action": "No hay acción aplicable"
"no_action": "No hay acción aplicable",
"session_expires": ""
},
"login": {
"delayed": "El inicio de sesión ha sido retrasado %s segundos.",
"login": "Inicio de sesión",
"password": "Contraseña",
"username": "Nombre de usuario"
"username": "Nombre de usuario",
"fido2_webauthn": "",
"mobileconfig_info": "",
"other_logins": ""
},
"mailbox": {
"action": "Acción",
@@ -567,7 +818,70 @@
"toggle_all": "Selecionar todo",
"username": "Nombre de usuario",
"waiting": "Esperando",
"weekly": "Cada semana"
"weekly": "Cada semana",
"disable_login": "",
"templates": "",
"public_comment": "",
"q_add_header": "",
"q_reject": "",
"table_size": "",
"domain_templates": "",
"catch_all": "",
"created_on": "",
"goto_ham": "",
"add_alias_expand": "",
"add_template": "",
"alias_domain_alias_hint": "",
"alias_domain_backupmx": "",
"all_domains": "",
"allow_from_smtp": "",
"allow_from_smtp_info": "",
"allowed_protocols": "",
"goto_spam": "",
"insert_preset": "",
"last_mail_login": "",
"last_pw_change": "",
"last_run_reset": "",
"mailbox": "",
"mailbox_defaults": "",
"no": "",
"open_logs": "",
"owner": "",
"private_comment": "",
"q_all": "",
"quarantine_category": "",
"recipient": "",
"relay_unknown": "",
"sender": "",
"sieve_preset_1": "",
"sieve_preset_5": "",
"syncjob_EXIT_TLS_FAILURE": "",
"syncjob_EXIT_AUTHENTICATION_FAILURE": "",
"syncjob_EXIT_CONNECTION_FAILURE_HOST1": "",
"syncjob_EXIT_AUTHENTICATION_FAILURE_USER1": "",
"template": "",
"tls_policy_maps_enforced_tls": "",
"yes": "",
"table_size_show_n": "",
"mailbox_defaults_info": "",
"sieve_preset_header": "",
"mailbox_templates": "",
"sieve_preset_2": "",
"sieve_preset_3": "",
"sieve_preset_8": "",
"sogo_visible": "",
"sogo_visible_n": "",
"sogo_visible_y": "",
"spam_aliases": "",
"stats": "",
"syncjob_check_log": "",
"syncjob_last_run_result": "",
"syncjob_EX_OK": "",
"syncjob_EXIT_CONNECTION_FAILURE": "",
"syncjob_EXIT_OVERQUOTA": "",
"sieve_preset_4": "",
"sieve_preset_6": "",
"sieve_preset_7": ""
},
"oauth2": {
"access_denied": "Inicie sesión como propietario del buzón para otorgar acceso a través de OAuth2.",
@@ -609,10 +923,43 @@
"subj": "Asunto",
"text_from_html_content": "Contenido (html convertido)",
"text_plain_content": "Contenido (text/plain)",
"toggle_all": "Seleccionar todos"
"toggle_all": "Seleccionar todos",
"spam": "",
"confirm": "",
"download_eml": "",
"info": "",
"deliver_inbox": "",
"junk_folder": "",
"notified": "",
"qinfo": "",
"quick_delete_link": "",
"quick_info_link": "",
"quick_release_link": "",
"refresh": "",
"rejected": "",
"rewrite_subject": "",
"rspamd_result": "",
"sender_header": "",
"settings_info": "",
"table_size": "",
"table_size_show_n": "",
"type": ""
},
"queue": {
"queue_manager": "Administrador de cola"
"queue_manager": "Administrador de cola",
"legend": "",
"ays": "",
"deliver_mail": "",
"unhold_mail": "",
"unhold_mail_legend": "",
"delete": "",
"flush": "",
"info": "",
"deliver_mail_legend": "",
"hold_mail": "",
"hold_mail_legend": "",
"show_message": "",
"unban": ""
},
"start": {
"help": "Mostrar/Ocultar panel de ayuda",
@@ -668,7 +1015,43 @@
"tls_policy_map_entry_saved": "Regla de póliza de TLS \"%s\" ha sido guardada",
"verified_totp_login": "Inicio de sesión TOTP verificado",
"verified_webauthn_login": "Inicio de sesión WebAuthn verificado",
"verified_yotp_login": "Inicio de sesión Yubico OTP verificado"
"verified_yotp_login": "Inicio de sesión Yubico OTP verificado",
"sogo_profile_reset": "",
"template_added": "",
"template_removed": "",
"ui_texts": "",
"upload_success": "",
"verified_fido2_login": "",
"admin_added": "",
"admin_api_modified": "",
"admin_removed": "",
"app_links": "",
"app_passwd_added": "",
"app_passwd_removed": "",
"cors_headers_edited": "",
"domain_add_dkim_available": "",
"dkim_duplicated": "",
"domain_footer_modified": "",
"dovecot_restart_success": "",
"eas_reset": "",
"f2b_banlist_refreshed": "",
"f2b_modified": "",
"global_filter_written": "",
"hash_deleted": "",
"ip_check_opt_in_modified": "",
"item_deleted": "",
"item_released": "",
"items_deleted": "",
"items_released": "",
"learned_ham": "",
"license_modified": "",
"nginx_reloaded": "",
"object_modified": "",
"password_policy_saved": "",
"pushover_settings_edited": "",
"reset_main_logo": "",
"resource_removed": "",
"template_modified": ""
},
"tfa": {
"api_register": "%s utiliza la API de la nube de Yubico. Por favor, obtén una clave API para tu llave <a href=\"https://upgrade.yubico.com/getapikey/\" target=\"_blank\">aquí</a>.",
@@ -688,7 +1071,15 @@
"webauthn": "Autenticación WebAuthn",
"waiting_usb_auth": "<i>Esperando al dispositivo USB...</i><br><br>Toque el botón en su dispositivo USB WebAuthn ahora.",
"waiting_usb_register": "<i>Esperando al dispositivo USB....</i><br><br>Ingrese su contraseña arriba y confirme su registro WebAuthn tocando el botón en su dispositivo USB WebAuthn.",
"yubi_otp": "Yubico OTP"
"yubi_otp": "Yubico OTP",
"authenticators": "",
"u2f_deprecated": "",
"u2f_deprecated_important": "",
"error_code": "",
"init_webauthn": "",
"reload_retry": "",
"start_webauthn_validation": "",
"tfa_token_invalid": ""
},
"user": {
"action": "Acción",
@@ -769,11 +1160,150 @@
"waiting": "Esperando",
"week": "Semana",
"weekly": "Cada semana",
"weeks": "Semanas"
"weeks": "Semanas",
"fido2_webauthn": "",
"last_pw_change": "",
"save": "",
"pushover_info": "",
"client_configuration": "",
"created_on": "",
"q_add_header": "",
"active_sieve": "",
"apple_connection_profile_mailonly": "",
"attribute": "",
"email": "",
"expire_in": "",
"last_ui_login": "",
"loading": "",
"mailbox_general": "",
"mailbox_settings": "",
"messages": "",
"month": "",
"months": "",
"no_active_filter": "",
"password_repeat": "",
"pushover_evaluate_x_prio": "",
"pushover_only_x_prio": "",
"pushover_sender_array": "",
"pushover_sender_regex": "",
"pushover_text": "",
"pushover_title": "",
"pushover_sound": "",
"pushover_vars": "",
"q_reject": "",
"quarantine_category": "",
"recent_successful_connections": "",
"sogo_profile_reset_help": "",
"sogo_profile_reset_now": "",
"spam_score_reset": "",
"spamfilter_table_domain_policy": "",
"syncjob_last_run_result": "",
"syncjob_EX_OK": "",
"syncjob_EXIT_CONNECTION_FAILURE": "",
"syncjob_EXIT_TLS_FAILURE": "",
"syncjob_EXIT_AUTHENTICATION_FAILURE": "",
"syncjob_EXIT_OVERQUOTA": "",
"syncjob_EXIT_CONNECTION_FAILURE_HOST1": "",
"syncjob_EXIT_AUTHENTICATION_FAILURE_USER1": "",
"last_mail_login": "",
"pushover_verify": "",
"q_all": "",
"quarantine_category_info": "",
"create_app_passwd": "",
"no_last_login": "",
"sender_acl_disabled": "",
"show_sieve_filters": "",
"email_and_dav": "",
"empty": "",
"syncjob_check_log": "",
"login_history": "",
"mailbox": "",
"text": "",
"apple_connection_profile_with_app_password": "",
"change_password_hint_app_passwords": "",
"clear_recent_successful_connections": "",
"delete_ays": "",
"direct_protocol_access": "",
"force_pw_update": "",
"from": "",
"generate": "",
"in_use": "",
"open_logs": "",
"open_webmail_sso": "",
"title": "",
"value": "",
"verify": "",
"with_app_password": "",
"year": "",
"years": "",
"advanced_settings": "",
"app_hint": "",
"allowed_protocols": "",
"app_name": "",
"app_passwds": "",
"apple_connection_profile": "",
"apple_connection_profile_complete": "",
"password": ""
},
"warning": {
"domain_added_sogo_failed": "Se agregó el dominio pero no se pudo reiniciar SOGo, revisa los logs del servidor.",
"fuzzy_learn_error": "Error aprendiendo hash: %s",
"ip_invalid": "IP inválida omitida: %s"
"ip_invalid": "IP inválida omitida: %s",
"session_token": "",
"session_ua": "",
"cannot_delete_self": "",
"dovecot_restart_failed": "",
"hash_not_found": "",
"is_not_primary_alias": "",
"no_active_admin": "",
"quota_exceeded_scope": ""
},
"datatables": {
"decimal": "",
"infoPostFix": "",
"paginate": {
"last": "",
"first": "",
"next": "",
"previous": ""
},
"collapse_all": "",
"emptyTable": "",
"expand_all": "",
"info": "",
"infoEmpty": "",
"infoFiltered": "",
"thousands": "",
"lengthMenu": "",
"loadingRecords": "",
"processing": "",
"search": "",
"zeroRecords": "",
"aria": {
"sortAscending": "",
"sortDescending": ""
}
},
"fido2": {
"set_fn": "",
"start_fido2_validation": "",
"confirm": "",
"fido2_auth": "",
"fido2_success": "",
"fido2_validation_failed": "",
"fn": "",
"known_ids": "",
"none": "",
"register_status": "",
"rename": "",
"set_fido2": "",
"set_fido2_touchid": ""
},
"ratelimit": {
"disabled": "",
"second": "",
"minute": "",
"hour": "",
"day": ""
}
}

View File

@@ -20,7 +20,15 @@
"spam_score": "Roskapostitulos",
"syncjobs": "Synkronoi työt",
"tls_policy": "TLS-käytäntö",
"unlimited_quota": "Rajoittamaton kiintiö sähkö postilaatikoille"
"unlimited_quota": "Rajoittamaton kiintiö sähkö postilaatikoille",
"app_passwds": "",
"domain_desc": "",
"domain_relayhost": "",
"mailbox_relayhost": "",
"protocol_access": "",
"pushover": "",
"quarantine_category": "",
"smtp_ip_access": ""
},
"add": {
"activate_filter_warn": "Kaikki muut suodattimet deaktivoidaan, kun aktiivinen on valittu.",
@@ -90,7 +98,17 @@
"timeout2": "Aikakatkaisu yhteyden muodostamiseen paikalliseen isäntään",
"username": "Käyttäjätunnus",
"validate": "Vahvista",
"validation_success": "Vahvistettu onnistuneesti"
"validation_success": "Vahvistettu onnistuneesti",
"dry": "",
"tags": "",
"inactive": "",
"relay_transport_info": "",
"app_name": "",
"app_password": "",
"app_passwd_protocols": "",
"bcc_dest_format": "",
"disable_login": "",
"relay_unknown_only": ""
},
"admin": {
"access": "Hallinta",
@@ -267,7 +285,73 @@
"upload": "Lataa",
"username": "Käyttäjätunnus",
"validate_license_now": "Vahvista GUID-tunnus lisenssi palvelinta vastaan",
"yes": "&#10003;"
"yes": "&#10003;",
"logo_normal_label": "",
"logo_dark_label": "",
"copy_to_clipboard": "",
"f2b_ban_time_increment": "",
"f2b_manage_external": "",
"f2b_manage_external_info": "",
"f2b_max_ban_time": "",
"allowed_methods": "",
"allowed_origins": "",
"cors_settings": "",
"ip_check": "",
"rspamd_global_filters": "",
"service": "",
"password_policy_lowerupper": "",
"password_policy_numbers": "",
"quarantine_max_score": "",
"quarantine_redirect": "",
"domain_admin": "",
"f2b_filter": "",
"f2b_regex_info": "",
"html": "",
"oauth2_apps": "",
"oauth2_add_client": "",
"optional": "",
"options": "",
"password_length": "",
"password_policy_chars": "",
"rspamd_global_filters_agree": "",
"rspamd_global_filters_info": "",
"sal_level": "",
"success": "",
"title": "",
"transport_test_rcpt_info": "",
"ui_header_announcement": "",
"ui_header_announcement_active": "",
"ui_header_announcement_content": "",
"password_policy": "",
"password_policy_length": "",
"queue_unban": "",
"relay_rcpt": "",
"rsettings_preset_3": "",
"rsettings_preset_4": "",
"ui_header_announcement_help": "",
"ui_header_announcement_select": "",
"ui_header_announcement_type": "",
"ui_header_announcement_type_danger": "",
"ui_header_announcement_type_info": "",
"ui_header_announcement_type_warning": "",
"verify": "",
"ip_check_disabled": "",
"ip_check_opt_in": "",
"is_mx_based": "",
"login_time": "",
"rspamd_global_filters_regex": "",
"password_policy_special_chars": "",
"quarantine_bcc": "",
"regex_maps": "",
"dkim_overwrite_key": "",
"admins": "",
"admins_ldap": "",
"advanced_settings": "",
"api_read_only": "",
"api_read_write": "",
"api_skip_ip_check": "",
"ays": "",
"convert_html_to_text": ""
},
"danger": {
"access_denied": "Käyttö estetty tai lomake tiedot eivät kelpaa",
@@ -369,7 +453,36 @@
"username_invalid": "Käyttäjätunnusta %s ei voi käyttää",
"validity_missing": "Anna voimassaolo aika",
"value_missing": "Anna kaikki arvot",
"yotp_verification_failed": "Yubico OTP todentaminen epäonnistui: %s"
"yotp_verification_failed": "Yubico OTP todentaminen epäonnistui: %s",
"webauthn_authenticator_failed": "",
"webauthn_publickey_failed": "",
"cors_invalid_origin": "",
"file_open_error": "",
"global_filter_write_error": "",
"global_map_invalid": "",
"global_map_write_error": "",
"ham_learn_error": "",
"invalid_filter_type": "",
"cors_invalid_method": "",
"pushover_key": "",
"img_dimensions_exceeded": "",
"img_size_exceeded": "",
"nginx_reload_failed": "",
"pushover_credentials_missing": "",
"pushover_token": "",
"template_exists": "",
"template_id_invalid": "",
"template_name_invalid": "",
"tls_policy_map_dest_invalid": "",
"webauthn_username_failed": "",
"app_name_empty": "",
"app_passwd_id_invalid": "",
"demo_mode_enabled": "",
"dkim_domain_or_sel_exists": "",
"extended_sender_acl_denied": "",
"fido2_verification_failed": "",
"reset_f2b_regex": "",
"tfa_token_invalid": ""
},
"debug": {
"containers_info": "Säilön tiedot",
@@ -389,7 +502,28 @@
"uptime": "Päällä",
"started_on": "Aloitettiin",
"static_logs": "Staattiset lokit",
"system_containers": "Systeemi & Säiliöt"
"system_containers": "Systeemi & Säiliöt",
"memory": "",
"architecture": "",
"online_users": "",
"error_show_ip": "",
"success": "",
"wip": "",
"container_disabled": "",
"history_all_servers": "",
"service": "",
"timezone": "",
"update_available": "",
"no_update_available": "",
"update_failed": "",
"username": "",
"chart_this_server": "",
"container_running": "",
"container_stopped": "",
"cores": "",
"login_time": "",
"current_time": "",
"show_ip": ""
},
"diagnostics": {
"cname_from_a": "Arvo johdettu A / AAAA-tietueesta. Tätä tuetaan niin kauan kuin tietue osoittaa oikealle resurssille.",
@@ -399,7 +533,8 @@
"dns_records_name": "Nimi",
"dns_records_status": "Nykyinen tila",
"dns_records_type": "Tyyppi",
"optional": "Tämä tietue on valinnainen."
"optional": "Tämä tietue on valinnainen.",
"dns_records_docs": ""
},
"edit": {
"active": "Aktiivinen",
@@ -480,7 +615,57 @@
"title": "Muokkaa objektia",
"unchanged_if_empty": "Jos muuttumaton jätä tyhjäksi",
"username": "Käyttäjätunnus",
"validate_save": "Vahvista ja tallenna"
"validate_save": "Vahvista ja tallenna",
"lookup_mx": "",
"footer_exclude": "",
"custom_attributes": "",
"domain_footer_info_vars": {
"from_addr": "",
"from_domain": "",
"auth_user": "",
"from_user": "",
"from_name": "",
"custom": ""
},
"allow_from_smtp_info": "",
"allowed_protocols": "",
"app_name": "",
"app_passwd": "",
"app_passwd_protocols": "",
"created_on": "",
"sogo_access": "",
"sogo_access_info": "",
"domain_footer_skip_replies": "",
"domain_footer_plain": "",
"domain_footer": "",
"domain_footer_html": "",
"ratelimit": "",
"acl": "",
"advanced_settings": "",
"allow_from_smtp": "",
"domain_footer_info": "",
"none_inherit": "",
"pushover_only_x_prio": "",
"pushover_sender_regex": "",
"pushover_verify": "",
"quota_warning_bcc_info": "",
"relay_transport_info": "",
"relay_unknown_only": "",
"spam_filter": "",
"pushover_text": "",
"admin": "",
"generate": "",
"delete_ays": "",
"disable_login": "",
"pushover": "",
"pushover_info": "",
"pushover_sender_array": "",
"pushover_title": "",
"pushover_sound": "",
"mailbox_relayhost_info": "",
"pushover_vars": "",
"pushover_evaluate_x_prio": "",
"quota_warning_bcc": ""
},
"footer": {
"cancel": "Peruuta",
@@ -493,7 +678,9 @@
"restart_container": "Uudelleen käynnistä moottori",
"restart_container_info": "<b>Tärkeää:</b> Uudelleenkäynnistys voi kestää jonkin aikaa, odota, kunnes se päättyy.",
"restart_now": "Käynnistä uudelleen nyt",
"restarting_container": "Uudelleen käynnistä container, tämä saattaa kestää jonkin aikaa..."
"restarting_container": "Uudelleen käynnistä container, tämä saattaa kestää jonkin aikaa...",
"hibp_check": "",
"nothing_selected": ""
},
"header": {
"administration": "Kokoonpanon & tiedot",
@@ -504,7 +691,8 @@
"quarantine": "Karanteeni",
"restart_netfilter": "Uudelleen käynnistä netfilter",
"restart_sogo": "Uudelleen käynnistä SOGo",
"user_settings": "Käyttäjän asetukset"
"user_settings": "Käyttäjän asetukset",
"mailcow_system": ""
},
"info": {
"awaiting_tfa_confirmation": "Odotetaan TFA-vahvistusta",
@@ -515,7 +703,10 @@
"delayed": "Kirjautuminen viivästyi %s sekunttia.",
"login": "Kirjaudu",
"password": "Salasana",
"username": "Käyttäjätunnus"
"username": "Käyttäjätunnus",
"fido2_webauthn": "",
"mobileconfig_info": "",
"other_logins": ""
},
"mailbox": {
"action": "Toiminnot",
@@ -639,7 +830,58 @@
"username": "Käyttäjätunnus",
"waiting": "Odotetaan..",
"weekly": "Viikoittain",
"yes": "&#10003;"
"yes": "&#10003;",
"templates": "",
"catch_all": "",
"created_on": "",
"disable_login": "",
"domain_templates": "",
"goto_ham": "",
"goto_spam": "",
"template": "",
"sieve_preset_8": "",
"allow_from_smtp_info": "",
"sieve_preset_header": "",
"sender": "",
"sieve_preset_6": "",
"sieve_preset_7": "",
"insert_preset": "",
"last_mail_login": "",
"add_template": "",
"alias_domain_alias_hint": "",
"all_domains": "",
"allow_from_smtp": "",
"allowed_protocols": "",
"q_reject": "",
"quarantine_category": "",
"recipient": "",
"relay_unknown": "",
"stats": "",
"syncjob_check_log": "",
"syncjob_last_run_result": "",
"syncjob_EX_OK": "",
"syncjob_EXIT_CONNECTION_FAILURE": "",
"syncjob_EXIT_TLS_FAILURE": "",
"syncjob_EXIT_AUTHENTICATION_FAILURE": "",
"syncjob_EXIT_OVERQUOTA": "",
"syncjob_EXIT_CONNECTION_FAILURE_HOST1": "",
"syncjob_EXIT_AUTHENTICATION_FAILURE_USER1": "",
"table_size": "",
"table_size_show_n": "",
"tls_policy_maps_enforced_tls": "",
"last_pw_change": "",
"open_logs": "",
"q_add_header": "",
"q_all": "",
"mailbox_defaults": "",
"mailbox_defaults_info": "",
"mailbox_templates": "",
"sieve_preset_1": "",
"sieve_preset_2": "",
"sieve_preset_3": "",
"sieve_preset_4": "",
"sieve_preset_5": "",
"add_alias_expand": ""
},
"oauth2": {
"access_denied": "Kirjaudu sisään postilaatikon omistajana myöntääksesi käyttöoikeuden OAuth2: n kautta.",
@@ -683,10 +925,41 @@
"subj": "Aihe",
"text_from_html_content": "Sisältö (muunnettu html)",
"text_plain_content": "Sisältö (teksti / tavallinen)",
"toggle_all": "Valitse kaikki"
"toggle_all": "Valitse kaikki",
"spam": "",
"deliver_inbox": "",
"info": "",
"type": "",
"quick_info_link": "",
"table_size": "",
"table_size_show_n": "",
"confirm": "",
"qinfo": "",
"sender_header": "",
"settings_info": "",
"rewrite_subject": "",
"junk_folder": "",
"notified": "",
"quick_release_link": "",
"rejected": "",
"quick_delete_link": "",
"refresh": ""
},
"queue": {
"queue_manager": "Jonon hallinta"
"queue_manager": "Jonon hallinta",
"deliver_mail": "",
"deliver_mail_legend": "",
"delete": "",
"flush": "",
"info": "",
"legend": "",
"ays": "",
"hold_mail": "",
"hold_mail_legend": "",
"show_message": "",
"unban": "",
"unhold_mail": "",
"unhold_mail_legend": ""
},
"start": {
"help": "Näytä/Piilota help paneeli",
@@ -761,7 +1034,24 @@
"upload_success": "Tiedosto ladattu onnistuneesti",
"verified_totp_login": "Vahvistettu TOTP-kirjautuminen",
"verified_webauthn_login": "Vahvistettu WebAuthn kirjautuminen",
"verified_yotp_login": "Vahvistettu Yubico OTP kirjautuminen"
"verified_yotp_login": "Vahvistettu Yubico OTP kirjautuminen",
"app_passwd_added": "",
"global_filter_written": "",
"template_added": "",
"template_modified": "",
"app_passwd_removed": "",
"cors_headers_edited": "",
"domain_add_dkim_available": "",
"domain_footer_modified": "",
"dovecot_restart_success": "",
"f2b_banlist_refreshed": "",
"ip_check_opt_in_modified": "",
"learned_ham": "",
"nginx_reloaded": "",
"password_policy_saved": "",
"pushover_settings_edited": "",
"template_removed": "",
"verified_fido2_login": ""
},
"tfa": {
"api_register": "%s käyttää Yubico Cloud API. Saat avaimesi API-avaimen <a href=\"https://upgrade.yubico.com/getapikey/\" target=\"_blank\">täältä</a>",
@@ -785,7 +1075,11 @@
"webauthn": "WebAuthn todennus",
"waiting_usb_auth": "<i>Odotetaan USB-laitetta...</i><br><br>Napauta painiketta WebAuthn USB-laitteessa nyt",
"waiting_usb_register": "<i>Odotetaan USB-laitetta...</i><br><br>Anna salasanasi yltä ja vahvista WebAuthn-rekisteröinti napauttamalla painiketta WebAuthn USB-laitteessa.",
"yubi_otp": "Yubico OTP-todennus"
"yubi_otp": "Yubico OTP-todennus",
"authenticators": "",
"tfa_token_invalid": "",
"u2f_deprecated": "",
"u2f_deprecated_important": ""
},
"user": {
"action": "Toiminnot",
@@ -880,7 +1174,76 @@
"waiting": "Odottaa",
"week": "Viikko",
"weekly": "Viikoittain",
"weeks": "Viikkoa"
"weeks": "Viikkoa",
"attribute": "",
"last_ui_login": "",
"allowed_protocols": "",
"delete_ays": "",
"email_and_dav": "",
"empty": "",
"fido2_webauthn": "",
"text": "",
"generate": "",
"last_mail_login": "",
"last_pw_change": "",
"login_history": "",
"mailbox_general": "",
"mailbox_settings": "",
"month": "",
"months": "",
"no_last_login": "",
"open_logs": "",
"open_webmail_sso": "",
"password": "",
"password_repeat": "",
"pushover_evaluate_x_prio": "",
"pushover_info": "",
"pushover_sender_array": "",
"recent_successful_connections": "",
"value": "",
"mailbox": "",
"syncjob_EXIT_CONNECTION_FAILURE": "",
"syncjob_EXIT_TLS_FAILURE": "",
"syncjob_EXIT_AUTHENTICATION_FAILURE": "",
"syncjob_EXIT_OVERQUOTA": "",
"syncjob_EXIT_CONNECTION_FAILURE_HOST1": "",
"syncjob_last_run_result": "",
"syncjob_EX_OK": "",
"syncjob_EXIT_AUTHENTICATION_FAILURE_USER1": "",
"title": "",
"verify": "",
"with_app_password": "",
"year": "",
"years": "",
"advanced_settings": "",
"app_hint": "",
"app_name": "",
"app_passwds": "",
"apple_connection_profile": "",
"apple_connection_profile_mailonly": "",
"apple_connection_profile_with_app_password": "",
"change_password_hint_app_passwords": "",
"clear_recent_successful_connections": "",
"create_app_passwd": "",
"created_on": "",
"direct_protocol_access": "",
"email": "",
"apple_connection_profile_complete": "",
"pushover_sender_regex": "",
"pushover_text": "",
"pushover_title": "",
"pushover_sound": "",
"pushover_vars": "",
"pushover_verify": "",
"q_add_header": "",
"q_all": "",
"q_reject": "",
"quarantine_category": "",
"quarantine_category_info": "",
"pushover_only_x_prio": "",
"from": "",
"save": "",
"syncjob_check_log": ""
},
"warning": {
"cannot_delete_self": "Kirjautuneen käyttäjän poistaminen ei onnistu",
@@ -890,7 +1253,10 @@
"ip_invalid": "Ohitettu virheellinen IP-osoite: %s",
"no_active_admin": "Viimeistä aktiivista järjestelmänvalvojaa ei voi poistaa käytöstä",
"session_token": "Lomakkeen tunnus sanoma ei kelpaa: tunnus sanoman risti riita",
"session_ua": "Lomakkeen tunnus sanoma ei kelpaa: käyttäjä agentin tarkistus virhe"
"session_ua": "Lomakkeen tunnus sanoma ei kelpaa: käyttäjä agentin tarkistus virhe",
"is_not_primary_alias": "",
"quota_exceeded_scope": "",
"dovecot_restart_failed": ""
},
"datatables": {
"emptyTable": "Tietoja ei ole saatavilla taulukossa",
@@ -901,7 +1267,43 @@
"search": "Etsi:",
"paginate": {
"first": "Ensimmäinen",
"last": "Edellinen"
"last": "Edellinen",
"next": "",
"previous": ""
},
"infoPostFix": "",
"decimal": "",
"collapse_all": "",
"info": "",
"infoEmpty": "",
"infoFiltered": "",
"thousands": "",
"zeroRecords": "",
"aria": {
"sortAscending": "",
"sortDescending": ""
}
},
"fido2": {
"confirm": "",
"fido2_auth": "",
"fido2_validation_failed": "",
"fn": "",
"known_ids": "",
"register_status": "",
"rename": "",
"set_fido2": "",
"fido2_success": "",
"none": "",
"set_fido2_touchid": "",
"set_fn": "",
"start_fido2_validation": ""
},
"ratelimit": {
"disabled": "",
"second": "",
"minute": "",
"hour": "",
"day": ""
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -107,7 +107,8 @@
"validation_success": "Convalidato con successo",
"bcc_dest_format": "Il destinatario in copia nascosta deve essere un singolo indirizzo email.<br>Se si vuole spedire una copia del messaggio a più destinatari, bisogna creare un alias ed utilizzarlo per questa opzione.",
"app_passwd_protocols": "Protocolli consentiti per la password dell'app",
"tags": "Tag"
"tags": "Tag",
"dry": "Simula sincronizzazione"
},
"admin": {
"access": "Accedi",
@@ -339,7 +340,18 @@
"oauth2_add_client": "Aggiungere il client OAuth2",
"rsettings_preset_4": "Disattivare Rspamd per un dominio",
"options": "Opzioni",
"cors_settings": "Impostazioni CORS"
"cors_settings": "Impostazioni CORS",
"copy_to_clipboard": "Testo copiato negli appunti!",
"logo_normal_label": "",
"logo_dark_label": "",
"f2b_manage_external": "",
"f2b_manage_external_info": "",
"allowed_methods": "",
"allowed_origins": "",
"ip_check": "",
"ip_check_disabled": "",
"ip_check_opt_in": "",
"queue_unban": ""
},
"danger": {
"access_denied": "Accesso negato o form di login non corretto",
@@ -462,7 +474,15 @@
"demo_mode_enabled": "La modalità demo è abilitata",
"template_name_invalid": "Nome template non valido",
"template_exists": "Il template %s esiste già",
"template_id_invalid": "Il template con ID %s non è valido"
"template_id_invalid": "Il template con ID %s non è valido",
"img_dimensions_exceeded": "L'immagine supera la dimensione massima consentita",
"img_size_exceeded": "L'immagine supera la dimensione massima del file",
"webauthn_authenticator_failed": "",
"webauthn_username_failed": "",
"cors_invalid_method": "",
"cors_invalid_origin": "",
"webauthn_publickey_failed": "",
"extended_sender_acl_denied": ""
},
"debug": {
"chart_this_server": "Grafico (questo server)",
@@ -499,14 +519,18 @@
"memory": "Memoria",
"timezone": "Fuso orario",
"no_update_available": "Il sistema è aggiornato all'ultima versione",
"update_failed": "Impossibile verificare la presenza di un aggiornamento"
"update_failed": "Impossibile verificare la presenza di un aggiornamento",
"architecture": "",
"show_ip": "",
"wip": "",
"error_show_ip": ""
},
"diagnostics": {
"cname_from_a": "Valore letto dal record A/AAAA. Questo è supportato finché il record punta alla risorsa corretta.",
"dns_records": "Record DNS",
"dns_records_24hours": "Tieni presente che le modifiche apportate ai record DNS potrebbero richiedere fino a 24 ore per poter essere visualizzate correttamente in questa pagina. Tutto ciò è da intendersi come un modo per voi di vedere come configurare i record DNS e per controllare se tutti i record DNS sono stati inseriti correttamente.",
"dns_records_data": "Dati corretti",
"dns_records_docs": "Si prega di consultare anche <a target=\"_blank\" href=\"https://docs.mailcow.email/prerequisite/prerequisite-dns/\">la documentazione</a>.",
"dns_records_docs": "Si prega di consultare anche <a target=\"_blank\" href=\"https://docs.mailcow.email/getstarted/prerequisite-dns\">la documentazione</a>.",
"dns_records_name": "Nome",
"dns_records_status": "Stato attuale",
"dns_records_type": "Tipo",
@@ -626,7 +650,22 @@
"acl": "ACL (autorizzazione)",
"app_passwd_protocols": "Protocolli consentiti per la password dell'app",
"last_modified": "Ultima modifica",
"pushover_sound": "Suono"
"pushover_sound": "Suono",
"custom_attributes": "Attributi personalizzati",
"domain_footer_skip_replies": "Ignora il piè di pagina nelle e-mail di risposta",
"footer_exclude": "",
"domain_footer_info_vars": {
"custom": "",
"auth_user": "",
"from_user": "",
"from_name": "",
"from_addr": "",
"from_domain": ""
},
"domain_footer": "",
"domain_footer_html": "",
"domain_footer_plain": "",
"domain_footer_info": ""
},
"fido2": {
"confirm": "Conferma",
@@ -933,7 +972,9 @@
"show_message": "Mostra messaggio",
"unhold_mail": "Sblocca",
"hold_mail_legend": "Blocca le mail selezionate. (Previene ulteriori tentativi di consegna)",
"legend": "Funzioni delle azioni della coda di posta:"
"legend": "Funzioni delle azioni della coda di posta:",
"unban": "",
"unhold_mail_legend": ""
},
"start": {
"help": "Mostra/Nascondi pannello di aiuto",
@@ -1021,7 +1062,11 @@
"domain_add_dkim_available": "Esisteva già una chiave DKIM",
"template_added": "Aggiunto template %s",
"template_modified": "Le modifiche al template %s sono state salvate",
"template_removed": "Il template con ID %s è stato cancellato"
"template_removed": "Il template con ID %s è stato cancellato",
"f2b_banlist_refreshed": "L'ID della lista blocchi è stato aggiornato con successo.",
"domain_footer_modified": "",
"ip_check_opt_in_modified": "",
"cors_headers_edited": ""
},
"tfa": {
"api_register": "%s usa le API Yubico Cloud. Richiedi una chiave API <a href=\"https://upgrade.yubico.com/getapikey/\" target=\"_blank\">qui</a>",
@@ -1048,7 +1093,8 @@
"yubi_otp": "Autenticazione Yubico OTP",
"tfa_token_invalid": "Token TFA non valido",
"u2f_deprecated": "Sembra che la tua chiave sia stata registrata utilizzando il metodo U2F deprecato. Disattiveremo Two-Factor-Authenticaiton per te e cancelleremo la tua chiave.",
"u2f_deprecated_important": "Registra la tua chiave nel pannello di amministrazione con il nuovo metodo WebAuthn."
"u2f_deprecated_important": "Registra la tua chiave nel pannello di amministrazione con il nuovo metodo WebAuthn.",
"authenticators": "Autenticatori"
},
"user": {
"action": "Azione",
@@ -1210,7 +1256,9 @@
"syncjob_EXIT_AUTHENTICATION_FAILURE_USER1": "Nome utente o password errati",
"with_app_password": "con password dell'app",
"direct_protocol_access": "Questo utente della mailbox ha <b>accesso diretto ed esterno</b> ai seguenti protocolli e applicazioni. Questa impostazione è controllata dal tuo amministratore. Le password delle applicazioni possono essere create per garantire l'accesso ai singoli protocolli e applicazioni.<br>Il pulsante \"Accedi alla webmail\" fornisce un singolo accesso a SOGo ed è sempre disponibile.",
"pushover_sound": "Suono"
"pushover_sound": "Suono",
"attribute": "Attributo",
"value": "Valore"
},
"warning": {
"cannot_delete_self": "Cannot delete logged in user",
@@ -1254,6 +1302,8 @@
"aria": {
"sortAscending": ": attivare l'ordinamento crescente delle colonne",
"sortDescending": ": attivare l'ordinamento decrescente delle colonne"
}
},
"decimal": "",
"infoPostFix": ""
}
}

View File

@@ -25,7 +25,10 @@
"syncjobs": "동기화 작업",
"tls_policy": "TLS 정책",
"unlimited_quota": "메일에 무제한 할당",
"domain_desc": "도메인 설명 변경"
"domain_desc": "도메인 설명 변경",
"domain_relayhost": "",
"mailbox_relayhost": "",
"quarantine_category": ""
},
"add": {
"activate_filter_warn": "활성화가 체크되어 있으면 모든 다른 필터들은 비활성화됩니다.",
@@ -101,7 +104,11 @@
"timeout2": "로컬 호스트 연결 시간 초과",
"username": "사용자명",
"validate": "확인하기",
"validation_success": "성공적으로 확인됨"
"validation_success": "성공적으로 확인됨",
"dry": "",
"tags": "",
"app_passwd_protocols": "",
"bcc_dest_format": ""
},
"admin": {
"access": "접근",
@@ -301,7 +308,50 @@
"username": "사용자 이름",
"validate_license_now": "라이선스 서버와 GUID 확인",
"verify": "확인",
"yes": "&#10003;"
"yes": "&#10003;",
"is_mx_based": "",
"optional": "",
"oauth2_apps": "",
"logo_normal_label": "",
"logo_dark_label": "",
"f2b_manage_external": "",
"copy_to_clipboard": "",
"domain_admin": "",
"f2b_ban_time_increment": "",
"f2b_manage_external_info": "",
"f2b_max_ban_time": "",
"login_time": "",
"oauth2_add_client": "",
"allowed_methods": "",
"allowed_origins": "",
"cors_settings": "",
"dkim_overwrite_key": "",
"f2b_filter": "",
"f2b_regex_info": "",
"html": "",
"options": "",
"password_length": "",
"password_policy": "",
"ip_check": "",
"ip_check_disabled": "",
"ip_check_opt_in": "",
"queue_unban": "",
"service": "",
"transport_test_rcpt_info": "",
"password_policy_chars": "",
"password_policy_length": "",
"password_policy_lowerupper": "",
"password_policy_numbers": "",
"password_policy_special_chars": "",
"quarantine_max_score": "",
"relay_rcpt": "",
"rsettings_preset_4": "",
"success": "",
"admins": "",
"admins_ldap": "",
"api_read_only": "",
"api_read_write": "",
"convert_html_to_text": ""
},
"danger": {
"access_denied": "접근이 거부되거나 잘못된 데이터 양식",
@@ -415,7 +465,24 @@
"username_invalid": "%s는 사용지 이름으로 사용할 수 없습니다.",
"validity_missing": "유효 기간을 지정해주세요.",
"value_missing": "모든 값을 입력해주세요.",
"yotp_verification_failed": "Yubico OTP 검증 실패: %s"
"yotp_verification_failed": "Yubico OTP 검증 실패: %s",
"cors_invalid_method": "",
"cors_invalid_origin": "",
"img_dimensions_exceeded": "",
"img_size_exceeded": "",
"webauthn_authenticator_failed": "",
"webauthn_publickey_failed": "",
"webauthn_username_failed": "",
"fido2_verification_failed": "",
"nginx_reload_failed": "",
"template_exists": "",
"template_id_invalid": "",
"template_name_invalid": "",
"demo_mode_enabled": "",
"dkim_domain_or_sel_exists": "",
"reset_f2b_regex": "",
"tfa_token_invalid": "",
"extended_sender_acl_denied": ""
},
"debug": {
"chart_this_server": "Chart (this server)",
@@ -437,7 +504,26 @@
"uptime": "Uptime",
"started_on": "Started on",
"static_logs": "Static logs",
"system_containers": "System & Containers"
"system_containers": "System & Containers",
"container_running": "",
"architecture": "",
"container_disabled": "",
"cores": "",
"current_time": "",
"error_show_ip": "",
"memory": "",
"online_users": "",
"service": "",
"show_ip": "",
"success": "",
"timezone": "",
"update_available": "",
"no_update_available": "",
"update_failed": "",
"username": "",
"wip": "",
"login_time": "",
"container_stopped": ""
},
"diagnostics": {
"cname_from_a": "Value derived from A/AAAA record. This is supported as long as the record points to the correct resource.",
@@ -447,7 +533,8 @@
"dns_records_name": "Name",
"dns_records_status": "Current State",
"dns_records_type": "Type",
"optional": "This record is optional."
"optional": "This record is optional.",
"dns_records_docs": ""
},
"edit": {
"active": "Active",
@@ -545,7 +632,40 @@
"title": "Edit object",
"unchanged_if_empty": "If unchanged leave blank",
"username": "Username",
"validate_save": "Validate and save"
"validate_save": "Validate and save",
"lookup_mx": "",
"footer_exclude": "",
"domain_footer_skip_replies": "",
"custom_attributes": "",
"domain_footer_info_vars": {
"from_addr": "",
"auth_user": "",
"from_user": "",
"from_name": "",
"from_domain": "",
"custom": ""
},
"domain_footer": "",
"domain_footer_html": "",
"domain_footer_info": "",
"acl": "",
"admin": "",
"allow_from_smtp": "",
"allow_from_smtp_info": "",
"allowed_protocols": "",
"app_passwd_protocols": "",
"domain_footer_plain": "",
"created_on": "",
"sogo_access": "",
"sogo_access_info": "",
"spam_filter": "",
"mailbox_relayhost_info": "",
"none_inherit": "",
"pushover": "",
"pushover_sound": "",
"quota_warning_bcc": "",
"quota_warning_bcc_info": "",
"ratelimit": ""
},
"footer": {
"cancel": "Cancel",
@@ -558,7 +678,9 @@
"restart_container": "Restart container",
"restart_container_info": "<b>Important:</b> A graceful restart may take a while to complete, please wait for it to finish.",
"restart_now": "Restart now",
"restarting_container": "Restarting container, this may take a while"
"restarting_container": "Restarting container, this may take a while",
"nothing_selected": "",
"hibp_check": ""
},
"header": {
"administration": "Configuration & Details",
@@ -569,7 +691,8 @@
"quarantine": "Quarantine",
"restart_netfilter": "Restart netfilter",
"restart_sogo": "Restart SOGo",
"user_settings": "User Settings"
"user_settings": "User Settings",
"mailcow_system": ""
},
"info": {
"awaiting_tfa_confirmation": "Awaiting TFA confirmation",
@@ -581,7 +704,9 @@
"login": "Login",
"mobileconfig_info": "Please login as mailbox user to download the requested Apple connection profile.",
"password": "Password",
"username": "Username"
"username": "Username",
"fido2_webauthn": "",
"other_logins": ""
},
"mailbox": {
"action": "조치",
@@ -722,7 +847,41 @@
"username": "Username",
"waiting": "Waiting",
"weekly": "Weekly",
"yes": "&#10003;"
"yes": "&#10003;",
"domain_templates": "",
"syncjob_check_log": "",
"syncjob_last_run_result": "",
"syncjob_EX_OK": "",
"syncjob_EXIT_CONNECTION_FAILURE": "",
"allow_from_smtp_info": "",
"catch_all": "",
"goto_spam": "",
"last_pw_change": "",
"mailbox_defaults": "",
"mailbox_templates": "",
"open_logs": "",
"sender": "",
"syncjob_EXIT_TLS_FAILURE": "",
"syncjob_EXIT_AUTHENTICATION_FAILURE": "",
"syncjob_EXIT_OVERQUOTA": "",
"syncjob_EXIT_CONNECTION_FAILURE_HOST1": "",
"syncjob_EXIT_AUTHENTICATION_FAILURE_USER1": "",
"templates": "",
"template": "",
"q_reject": "",
"q_all": "",
"quarantine_category": "",
"recipient": "",
"add_alias_expand": "",
"add_template": "",
"all_domains": "",
"allow_from_smtp": "",
"created_on": "",
"goto_ham": "",
"mailbox_defaults_info": "",
"q_add_header": "",
"allowed_protocols": "",
"relay_unknown": ""
},
"oauth2": {
"access_denied": "Please login as mailbox owner to grant access via OAuth2.",
@@ -774,10 +933,33 @@
"table_size_show_n": "%s개 항목 보기",
"text_from_html_content": "내용 (converted html)",
"text_plain_content": "내용 (text/plain)",
"toggle_all": "선택 반전"
"toggle_all": "선택 반전",
"rejected": "",
"quick_info_link": "",
"rewrite_subject": "",
"confirm": "",
"deliver_inbox": "",
"info": "",
"junk_folder": "",
"settings_info": "",
"type": "",
"spam": ""
},
"queue": {
"queue_manager": "대기열 관리자"
"queue_manager": "대기열 관리자",
"deliver_mail": "",
"deliver_mail_legend": "",
"hold_mail": "",
"hold_mail_legend": "",
"show_message": "",
"unhold_mail": "",
"unhold_mail_legend": "",
"unban": "",
"delete": "",
"flush": "",
"info": "",
"legend": "",
"ays": ""
},
"start": {
"help": "Show/Hide help panel",
@@ -858,7 +1040,18 @@
"upload_success": "File uploaded successfully",
"verified_totp_login": "Verified TOTP login",
"verified_webauthn_login": "Verified WebAuthn login",
"verified_yotp_login": "Verified Yubico OTP login"
"verified_yotp_login": "Verified Yubico OTP login",
"f2b_banlist_refreshed": "",
"ip_check_opt_in_modified": "",
"domain_footer_modified": "",
"domain_add_dkim_available": "",
"template_added": "",
"template_modified": "",
"cors_headers_edited": "",
"template_removed": "",
"nginx_reloaded": "",
"password_policy_saved": "",
"verified_fido2_login": ""
},
"tfa": {
"api_register": "%s uses the Yubico Cloud API. Please get an API key for your key <a href=\"https://upgrade.yubico.com/getapikey/\" target=\"_blank\">here</a>",
@@ -882,7 +1075,11 @@
"webauthn": "WebAuthn authentication",
"waiting_usb_auth": "<i>Waiting for USB device...</i><br><br>Please tap the button on your WebAuthn USB device now.",
"waiting_usb_register": "<i>Waiting for USB device...</i><br><br>Please enter your password above and confirm your WebAuthn registration by tapping the button on your WebAuthn USB device.",
"yubi_otp": "Yubico OTP authentication"
"yubi_otp": "Yubico OTP authentication",
"authenticators": "",
"tfa_token_invalid": "",
"u2f_deprecated": "",
"u2f_deprecated_important": ""
},
"user": {
"action": "조치",
@@ -1006,7 +1203,47 @@
"waiting": "대기중",
"week": "주",
"weekly": "매주",
"weeks": "주"
"weeks": "주",
"mailbox": "",
"q_all": "",
"q_reject": "",
"recent_successful_connections": "",
"open_logs": "",
"syncjob_check_log": "",
"syncjob_EXIT_CONNECTION_FAILURE": "",
"syncjob_EXIT_TLS_FAILURE": "",
"syncjob_EXIT_AUTHENTICATION_FAILURE": "",
"syncjob_EXIT_CONNECTION_FAILURE_HOST1": "",
"open_webmail_sso": "",
"value": "",
"q_add_header": "",
"syncjob_EXIT_OVERQUOTA": "",
"apple_connection_profile_with_app_password": "",
"attribute": "",
"change_password_hint_app_passwords": "",
"clear_recent_successful_connections": "",
"created_on": "",
"direct_protocol_access": "",
"fido2_webauthn": "",
"last_pw_change": "",
"last_ui_login": "",
"login_history": "",
"mailbox_general": "",
"mailbox_settings": "",
"month": "",
"pushover_sound": "",
"quarantine_category": "",
"quarantine_category_info": "",
"syncjob_EX_OK": "",
"syncjob_EXIT_AUTHENTICATION_FAILURE_USER1": "",
"with_app_password": "",
"years": "",
"syncjob_last_run_result": "",
"empty": "",
"allowed_protocols": "",
"from": "",
"months": "",
"year": ""
},
"warning": {
"cannot_delete_self": "Cannot delete logged in user",
@@ -1018,6 +1255,55 @@
"no_active_admin": "Cannot deactivate last active admin",
"quota_exceeded_scope": "Domain quota exceeded: Only unlimited mailboxes can be created in this domain scope.",
"session_token": "Form token invalid: Token mismatch",
"session_ua": "Form token invalid: User-Agent validation error"
"session_ua": "Form token invalid: User-Agent validation error",
"is_not_primary_alias": ""
},
"datatables": {
"infoPostFix": "",
"decimal": "",
"collapse_all": "",
"emptyTable": "",
"loadingRecords": "",
"processing": "",
"zeroRecords": "",
"info": "",
"infoEmpty": "",
"infoFiltered": "",
"thousands": "",
"search": "",
"aria": {
"sortAscending": "",
"sortDescending": ""
},
"expand_all": "",
"lengthMenu": "",
"paginate": {
"first": "",
"last": "",
"next": "",
"previous": ""
}
},
"fido2": {
"fido2_validation_failed": "",
"fn": "",
"known_ids": "",
"none": "",
"register_status": "",
"rename": "",
"set_fido2": "",
"set_fido2_touchid": "",
"set_fn": "",
"start_fido2_validation": "",
"confirm": "",
"fido2_auth": "",
"fido2_success": ""
},
"ratelimit": {
"disabled": "",
"second": "",
"minute": "",
"hour": "",
"day": ""
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -26,7 +26,9 @@
"syncjobs": "Sync jobs",
"tls_policy": "Versleutelingsbeleid",
"unlimited_quota": "Onbeperkte quota voor mailboxen",
"domain_desc": "Wijzig domeinbeschrijving"
"domain_desc": "Wijzig domeinbeschrijving",
"domain_relayhost": "",
"mailbox_relayhost": ""
},
"add": {
"activate_filter_warn": "Alle andere filters worden gedeactiveerd zolang deze geactiveerd is.",
@@ -104,7 +106,9 @@
"validate": "Verifieer",
"validation_success": "Succesvol geverifieerd",
"tags": "Tags",
"bcc_dest_format": "BCC-bestemming moet één geldig e-mailadres zijn.<br>Als u een kopie naar meerdere adressen wilt sturen, maak dan een alias aan en gebruik die hier."
"bcc_dest_format": "BCC-bestemming moet één geldig e-mailadres zijn.<br>Als u een kopie naar meerdere adressen wilt sturen, maak dan een alias aan en gebruik die hier.",
"dry": "",
"app_passwd_protocols": ""
},
"admin": {
"access": "Toegang",
@@ -185,7 +189,7 @@
"filter_table": "Filtertabel",
"forwarding_hosts": "Forwarding hosts",
"forwarding_hosts_add_hint": "Het is mogelijk om IPv4- of IPv6-adressen, netwerken in CIDR-notatie, hostnames (worden omgezet naar IP-adressen) of domeinnamen (worden tevens omgezet naar IP-adressen of, bij gebrek daaraan, MX-records) op te geven.",
"forwarding_hosts_hint": "Inkomende berichten worden onvoorwaardelijk geaccepteerd vanaf iedere host hieronder vermeld. Deze hosts worden hierdoor niet gecontroleerd op DNSBLs, en zullen de greylisting omzeilen. Spam wordt daarentegen zoals gebruikelijk in de spamfolder geplaatst. Dit wordt vaak gebruikt om mailservers te specificeren die forwarden naar deze Mailcow-server.",
"forwarding_hosts_hint": "Inkomende berichten worden onvoorwaardelijk geaccepteerd vanaf iedere host hieronder vermeld. Deze hosts worden hierdoor niet gecontroleerd op DNSBLs, en zullen de greylisting omzeilen. Spam wordt daarentegen zoals gebruikelijk in de spamfolder geplaatst. Dit wordt vaak gebruikt om mailservers te specificeren die alles doorsturen naar deze Mailcow-server.",
"from": "Afzender",
"generate": "genereer",
"guid": "Identificatienummer - GUID",
@@ -295,7 +299,7 @@
"to_top": "Naar boven",
"transport_dest_format": "Voorbeeld: example.org, .example.org, *, mailbox@example.org (meerdere waarden zijn kommagescheiden)",
"transport_maps": "Transport-maps",
"transports_hint": "→ Een transport-map wordt boven een afzendergebonden transport-map verkozen.<br>→ Het uitgaande versleutelingsbeleid van individuele gebruikers wordt genegeerd en kan uitsluitend worden gehandhaafd doormiddel van globaal versleutelingsbeleid.<br>→ De transportservice is altijd \"smtp:\" en zal daarom met TLS proberen te verbinden. Wrapped TLS (SMTPS) wordt niet ondersteund.<br>→ Adressen overeenkomend met \"/localhost$/\" zullen altijd via \"local:\" getransporteerd worden, hierdoor zullen \"*\"-bestemmingen niet van toepassing zijn op deze adressen.<br>→ Om de aanmeldingsgegevens van een (voorbeeld) nexthop \"[host]:25\" te bepalen, zoekt Postfix <b>altijd</b> naar \"nexthop\" voodat er wordt gekeken naar \"[nexthop]:25\". Dit maakt het onmogelijk om \"nexthop\" en \"[nexthop]:25\" tegelijkertijd te gebruiken.",
"transports_hint": "→ Een transport-map wordt boven een afzendergebonden transport-map verkozen.<br>→ Het uitgaande versleutelingsbeleid van individuele gebruikers wordt genegeerd en kan uitsluitend worden gehandhaafd door middel van globaal versleutelingsbeleid.<br>→ De transportservice is altijd \"smtp:\" en zal daarom met TLS proberen te verbinden. Wrapped TLS (SMTPS) wordt niet ondersteund.<br>→ Adressen overeenkomend met \"/localhost$/\" zullen altijd via \"local:\" getransporteerd worden, hierdoor zullen \"*\"-bestemmingen niet van toepassing zijn op deze adressen.<br>→ Om de aanmeldingsgegevens van een (voorbeeld) nexthop \"[host]:25\" te bepalen, zoekt Postfix <b>altijd</b> naar \"nexthop\" voodat er wordt gekeken naar \"[nexthop]:25\". Dit maakt het onmogelijk om \"nexthop\" en \"[nexthop]:25\" tegelijkertijd te gebruiken.",
"ui_footer": "Footer (HTML toegestaan)",
"ui_header_announcement": "Aankondigingen",
"ui_header_announcement_active": "Activeer aankondiging",
@@ -337,7 +341,17 @@
"admins_ldap": "LDAP administrators",
"api_read_only": "Alleen-lezen toegang",
"api_read_write": "Lees en schrijf toegang",
"login_time": "Login tijd"
"login_time": "Login tijd",
"allowed_methods": "",
"copy_to_clipboard": "",
"f2b_manage_external": "",
"f2b_manage_external_info": "",
"allowed_origins": "",
"ip_check_opt_in": "",
"queue_unban": "",
"transport_test_rcpt_info": "",
"yes": "",
"no": ""
},
"danger": {
"access_denied": "Toegang geweigerd of ongeldige gegevens",
@@ -463,7 +477,12 @@
"demo_mode_enabled": "Demo modus is ingeschakeld",
"template_exists": "Sjabloon %s bestaat al",
"template_id_invalid": "Sjabloon ID %s ongeldig",
"template_name_invalid": "Sjabloon naam ongeldig"
"template_name_invalid": "Sjabloon naam ongeldig",
"webauthn_username_failed": "",
"cors_invalid_origin": "",
"img_dimensions_exceeded": "",
"img_size_exceeded": "",
"extended_sender_acl_denied": ""
},
"debug": {
"chart_this_server": "Grafiek (deze server)",
@@ -473,7 +492,7 @@
"history_all_servers": "Geschiedenis (alle servers)",
"in_memory_logs": "Geheugenlogs",
"jvm_memory_solr": "JVM-geheugengebruik",
"log_info": "<p>Mailcows <b>geheugenlogs</b> worden elke minuut afgesneden naar maximaal %d regels (LOG_LINES) om de stabiliteit te garanderen.<br>Geheugenlogs zijn niet bedoeld om bewaard te blijven. Alle applicaties die geheugenlogs schrijven worden ook naar het Docker-proces gelogd.<br>De geheugenlogs kunnen gebruikt worden voor het oplossen van problemen met bepaalde containers.</p><p><b>Externe logs</b> worden verzameld doormiddel van de API van deze applicaties.</p><p><b>Statische logs</b> zijn activiteitenlogs die niet naar het Docker-proces worden gelogd, maar wel bewaard moeten blijven (uitgezonderd API-logs).</p>",
"log_info": "<p>Mailcows <b>geheugenlogs</b> worden elke minuut afgesneden naar maximaal %d regels (LOG_LINES) om de stabiliteit te garanderen.<br>Geheugenlogs zijn niet bedoeld om bewaard te blijven. Alle applicaties die geheugenlogs schrijven worden ook naar het Docker-proces gelogd.<br>De geheugenlogs kunnen gebruikt worden voor het oplossen van problemen met bepaalde containers.</p><p><b>Externe logs</b> worden verzameld door middel van de API van deze applicaties.</p><p><b>Statische logs</b> zijn activiteitenlogs die niet naar het Docker-proces worden gelogd, maar wel bewaard moeten blijven (uitgezonderd API-logs).</p>",
"logs": "Logs",
"restart_container": "Herstart",
"solr_dead": "Solr is uitgeschakeld, uitgevallen of nog bezig met opstarten.",
@@ -510,7 +529,7 @@
"cname_from_a": "Waarde afgeleid van een A- of AAAA-vermelding.",
"dns_records": "DNS-configuratie",
"dns_records_24hours": "Houd er rekening mee dat wijzigingen aan DNS tot wel 24 uur in beslag kunnen nemen voordat ze op deze pagina worden weergegeven. Deze informatie is bedoeld om gemakkelijk te bekijken of de DNS-configuratie aan de eisen voldoet.",
"dns_records_docs": "Raadpleeg ook <a target=\"_blank\" href=\"https://docs.mailcow.email/prerequisite/prerequisite-dns/\">de documentatie</a>.",
"dns_records_docs": "Raadpleeg ook <a target=\"_blank\" href=\"https://docs.mailcow.email/getstarted/prerequisite-dns\">de documentatie</a>.",
"dns_records_data": "Correcte gegevens",
"dns_records_name": "Naam",
"dns_records_status": "Huidige staat",
@@ -627,7 +646,26 @@
"acl": "ACL (Toestemming)",
"domain_footer": "Domeinbreede footer",
"domain_footer_html": "HTML footer",
"mailbox_relayhost_info": "Wordt alleen toegepast op de mailbox en directe aliassen, maar heft een domein relayhost op."
"mailbox_relayhost_info": "Wordt alleen toegepast op de mailbox en directe aliassen, maar heft een domein relayhost op.",
"lookup_mx": "",
"footer_exclude": "",
"domain_footer_skip_replies": "",
"custom_attributes": "",
"quota_warning_bcc": "",
"domain_footer_info_vars": {
"auth_user": "",
"from_user": "",
"from_name": "",
"from_addr": "",
"from_domain": "",
"custom": ""
},
"pushover": "",
"domain_footer_plain": "",
"none_inherit": "",
"quota_warning_bcc_info": "",
"sogo_access": "",
"sogo_access_info": ""
},
"footer": {
"cancel": "Annuleren",
@@ -640,7 +678,9 @@
"restart_container": "Herstart container",
"restart_container_info": "<b>Belangrijk:</b> Een herstart kan enige tijd in beslag nemen, wacht aub totdat dit proces voltooid is.<br>Deze pagina zal zichzelf verversen zodra het proces voltooid is.",
"restart_now": "Nu herstarten",
"restarting_container": "Container wordt herstart, even geduld aub..."
"restarting_container": "Container wordt herstart, even geduld aub...",
"hibp_check": "",
"nothing_selected": ""
},
"header": {
"administration": "Configuratie & details",
@@ -651,7 +691,8 @@
"quarantine": "Quarantaine",
"restart_netfilter": "Herstart netfilter",
"restart_sogo": "Herstart SOGo",
"user_settings": "Gebruikersinstellingen"
"user_settings": "Gebruikersinstellingen",
"mailcow_system": ""
},
"info": {
"awaiting_tfa_confirmation": "In afwachting van tweefactorauthenticatie...",
@@ -684,7 +725,7 @@
"add_tls_policy_map": "Voeg versleutelingsbeleid toe",
"address_rewriting": "Adresomleidingen",
"alias": "Alias",
"alias_domain_alias_hint": "Aliassen worden <b>niet</b> automatisch toegepast op domeinaliassen. Aliasadres <code>alias@domein</code> dekt het adres <code>alias@alias-domein</code> <b>niet</b> (waarbij \"alias-domein\" een aliasdomein is voor \"domein\").<br>Gebruik een filter om mail te forwarden naar een externe mailbox (zie het tabje \"Filters\" of gebruik SOGo -> Doorsturen).",
"alias_domain_alias_hint": "Aliassen worden <b>niet</b> automatisch toegepast op domeinaliassen. Aliasadres <code>alias@domein</code> dekt het adres <code>alias@alias-domein</code> <b>niet</b> (waarbij \"alias-domein\" een aliasdomein is voor \"domein\").<br>Gebruik een filter om mail door te sturen naar een externe mailbox (zie het tabje \"Filters\" of gebruik SOGo -> Doorsturen).",
"alias_domain_backupmx": "Aliasdomein inactief voor geforward domein",
"aliases": "Aliassen",
"allow_from_smtp": "Sta enkel de volgende IP-adressen toe voor <b>SMTP</b>",
@@ -694,7 +735,7 @@
"bcc": "BCC",
"bcc_destination": "BCC-bestemming",
"bcc_destinations": "BCC-bestemmingen",
"bcc_info": "BCC-maps worden gebruikt om kopieën van alle berichten naar een ander adres te forwarden.<br>Wees er van bewust dat er geen melding wordt gedaan van een mislukte aflevering.",
"bcc_info": "BCC-maps worden gebruikt om kopieën van alle berichten naar een ander adres door te sturen.<br>Wees er van bewust dat er geen melding wordt gedaan van een mislukte aflevering.",
"bcc_local_dest": "Lokale bestemming",
"bcc_map": "BCC-map",
"bcc_map_type": "BCC-type",
@@ -812,7 +853,35 @@
"toggle_all": "Selecteer alles",
"username": "Gebruikersnaam",
"waiting": "Wachten",
"weekly": "Wekelijks"
"weekly": "Wekelijks",
"add_alias_expand": "",
"all_domains": "",
"goto_spam": "",
"sender": "",
"catch_all": "",
"add_template": "",
"created_on": "",
"domain_templates": "",
"domain_quota_total": "",
"goto_ham": "",
"last_pw_change": "",
"mailbox_templates": "",
"no": "",
"open_logs": "",
"recipient": "",
"relay_unknown": "",
"syncjob_check_log": "",
"syncjob_last_run_result": "",
"syncjob_EX_OK": "",
"syncjob_EXIT_CONNECTION_FAILURE": "",
"syncjob_EXIT_TLS_FAILURE": "",
"syncjob_EXIT_AUTHENTICATION_FAILURE": "",
"syncjob_EXIT_OVERQUOTA": "",
"syncjob_EXIT_CONNECTION_FAILURE_HOST1": "",
"syncjob_EXIT_AUTHENTICATION_FAILURE_USER1": "",
"templates": "",
"template": "",
"yes": ""
},
"oauth2": {
"access_denied": "Log in als een mailboxgebruiker om toegang via OAuth te verlenen",
@@ -877,7 +946,20 @@
"toggle_all": "Selecteer alles"
},
"queue": {
"queue_manager": "Queue manager"
"queue_manager": "Queue manager",
"delete": "",
"flush": "",
"info": "",
"legend": "",
"ays": "",
"deliver_mail": "",
"deliver_mail_legend": "",
"hold_mail": "",
"hold_mail_legend": "",
"show_message": "",
"unban": "",
"unhold_mail": "",
"unhold_mail_legend": ""
},
"start": {
"help": "Toon/verberg hulppaneel",
@@ -960,7 +1042,16 @@
"verified_totp_login": "TOTP succesvol geverifieerd",
"verified_webauthn_login": "WebAuthn succesvol geverifieerd",
"verified_fido2_login": "FIDO2 succesvol geverifieerd",
"verified_yotp_login": "Yubico OTP succesvol geverifieerd"
"verified_yotp_login": "Yubico OTP succesvol geverifieerd",
"f2b_banlist_refreshed": "",
"ip_check_opt_in_modified": "",
"password_policy_saved": "",
"template_added": "",
"cors_headers_edited": "",
"domain_add_dkim_available": "",
"domain_footer_modified": "",
"template_modified": "",
"template_removed": ""
},
"tfa": {
"api_register": "%s maakt gebruik van de Yubico Cloud API. Om dit te benutten is er een API-key van Yubico vereist, deze kan <a href=\"https://upgrade.yubico.com/getapikey/\" target=\"_blank\">hier</a> opgevraagd worden",
@@ -985,7 +1076,10 @@
"webauthn": "WebAuthn",
"waiting_usb_auth": "<i>In afwachting van USB-apparaat...</i><br><br>Druk nu op de knop van je WebAuthn-apparaat.",
"waiting_usb_register": "<i>In afwachting van USB-apparaat...</i><br><br>Voer je wachtwoord hierboven in en bevestig de registratie van het WebAuthn-apparaat door op de knop van het apparaat te drukken.",
"yubi_otp": "Yubico OTP"
"yubi_otp": "Yubico OTP",
"authenticators": "",
"u2f_deprecated": "",
"u2f_deprecated_important": ""
},
"fido2": {
"set_fn": "Stel naam in",
@@ -999,7 +1093,8 @@
"start_fido2_validation": "Start FIDO2-validatie",
"fido2_auth": "Aanmelden met FIDO2",
"fido2_success": "Apparaat succesvol geregistreerd",
"fido2_validation_failed": "Validatie mislukt"
"fido2_validation_failed": "Validatie mislukt",
"set_fido2_touchid": ""
},
"user": {
"action": "Handeling",
@@ -1129,7 +1224,41 @@
"waiting": "Wachten",
"week": "week",
"weekly": "Wekelijks",
"weeks": "weken"
"weeks": "weken",
"attribute": "",
"years": "",
"value": "",
"fido2_webauthn": "",
"recent_successful_connections": "",
"syncjob_check_log": "",
"allowed_protocols": "",
"apple_connection_profile_with_app_password": "",
"direct_protocol_access": "",
"last_pw_change": "",
"last_ui_login": "",
"login_history": "",
"mailbox": "",
"mailbox_general": "",
"mailbox_settings": "",
"month": "",
"months": "",
"open_logs": "",
"open_webmail_sso": "",
"syncjob_last_run_result": "",
"syncjob_EX_OK": "",
"syncjob_EXIT_CONNECTION_FAILURE": "",
"syncjob_EXIT_TLS_FAILURE": "",
"syncjob_EXIT_AUTHENTICATION_FAILURE": "",
"syncjob_EXIT_OVERQUOTA": "",
"syncjob_EXIT_CONNECTION_FAILURE_HOST1": "",
"syncjob_EXIT_AUTHENTICATION_FAILURE_USER1": "",
"year": "",
"with_app_password": "",
"from": "",
"change_password_hint_app_passwords": "",
"clear_recent_successful_connections": "",
"created_on": "",
"empty": ""
},
"warning": {
"cannot_delete_self": "Gebruikers kunnen niet worden verwijderd wanneer deze zijn aangemeld",
@@ -1141,7 +1270,8 @@
"no_active_admin": "Het is niet mogelijk om de laatste actieve administrator te verwijderen",
"quota_exceeded_scope": "Domeinquota overschreden: Voor dit domein kunnen uitsluitend onbeperkte mailboxen aangemaakt worden.",
"session_token": "Token ongeldig: komt niet overeen",
"session_ua": "Token ongeldig: gebruikersagentvalidatie mislukt"
"session_ua": "Token ongeldig: gebruikersagentvalidatie mislukt",
"is_not_primary_alias": ""
},
"datatables": {
"emptyTable": "Geen data beschikbaar in tabel",
@@ -1165,6 +1295,15 @@
"loadingRecords": "Laden...",
"processing": "Wachten alstublieft..",
"search": "Zoeken:",
"zeroRecords": "Geen overeenkomsten gevonden"
"zeroRecords": "Geen overeenkomsten gevonden",
"infoPostFix": "",
"infoFiltered": ""
},
"ratelimit": {
"disabled": "",
"second": "",
"minute": "",
"hour": "",
"day": ""
}
}

View File

@@ -2,7 +2,33 @@
"acl": {
"sogo_profile_reset": "Usuń profil SOGo (webmail)",
"syncjobs": "Polecenie synchronizacji",
"alias_domains": "Dodaj aliasy domen"
"alias_domains": "Dodaj aliasy domen",
"quarantine_notification": "",
"ratelimit": "",
"recipient_maps": "",
"smtp_ip_access": "",
"sogo_access": "",
"spam_alias": "",
"spam_policy": "",
"spam_score": "",
"tls_policy": "",
"unlimited_quota": "",
"app_passwds": "",
"bcc_maps": "",
"delimiter_action": "",
"domain_desc": "",
"domain_relayhost": "",
"eas_reset": "",
"extend_sender_acl": "",
"filters": "",
"login_as": "",
"mailbox_relayhost": "",
"prohibited": "",
"protocol_access": "",
"quarantine": "",
"quarantine_attachments": "",
"quarantine_category": "",
"pushover": ""
},
"add": {
"active": "Aktywny",
@@ -43,7 +69,46 @@
"target_address": "Adresy Idź do:",
"target_address_info": "<small> Pełny/e adres/y email (oddzielone przecinkami).</small>",
"target_domain": "Domena docelowa:",
"username": "Nazwa użytkownika"
"username": "Nazwa użytkownika",
"dry": "",
"add_domain_only": "",
"automap": "",
"bcc_dest_format": "",
"comment_info": "",
"custom_params": "",
"custom_params_hint": "",
"delete2": "",
"disable_login": "",
"domain_matches_hostname": "",
"destination": "",
"sieve_desc": "",
"sieve_type": "",
"skipcrossduplicates": "",
"subscribeall": "",
"tags": "",
"timeout1": "",
"gal": "",
"gal_info": "",
"goto_ham": "",
"goto_null": "",
"goto_spam": "",
"inactive": "",
"mailbox_quota_def": "",
"private_comment": "",
"public_comment": "",
"relay_transport_info": "",
"timeout2": "",
"validate": "",
"relay_unknown_only": "",
"relayhost_wrapped_tls_info": "",
"validation_success": "",
"activate_filter_warn": "",
"add_domain_restart": "",
"app_name": "",
"generate": "",
"nexthop": "",
"app_password": "",
"app_passwd_protocols": ""
},
"admin": {
"access": "Dostęp",
@@ -99,7 +164,194 @@
"spamfilter": "Filtr spamu",
"time": "Czas",
"unchanged_if_empty": "W przypadku braku zmian, nie wypełniaj",
"username": "Nazwa użytkownika"
"username": "Nazwa użytkownika",
"oauth2_redirect_uri": "",
"oauth2_renew_secret": "",
"oauth2_revoke_tokens": "",
"rspamd_global_filters_regex": "",
"ui_header_announcement_type_warning": "",
"logo_normal_label": "",
"logo_dark_label": "",
"rate_name": "",
"ui_texts": "",
"unban_pending": "",
"f2b_ban_time_increment": "",
"f2b_max_ban_time": "",
"relayhosts_hint": "",
"copy_to_clipboard": "",
"f2b_manage_external": "",
"f2b_manage_external_info": "",
"in_use_by": "",
"include_exclude": "",
"include_exclude_info": "",
"includes": "",
"is_mx_based": "",
"nexthop": "",
"no": "",
"no_active_bans": "",
"no_new_rows": "",
"oauth2_apps": "",
"oauth2_add_client": "",
"oauth2_client_id": "",
"oauth2_client_secret": "",
"oauth2_info": "",
"optional": "",
"options": "",
"password_length": "",
"password_policy": "",
"password_policy_chars": "",
"password_policy_length": "",
"quarantine_notification_html": "",
"quarantine_notification_subject": "",
"quarantine_redirect": "",
"quarantine_release_format": "",
"quarantine_release_format_att": "",
"quarantine_release_format_raw": "",
"quarantine_retention_size": "",
"quota_notification_html": "",
"quota_notification_sender": "",
"quota_notification_subject": "",
"quota_notifications": "",
"quota_notifications_info": "",
"quota_notifications_vars": "",
"queue_unban": "",
"recipients": "",
"regen_api_key": "",
"relay_rcpt": "",
"relay_run": "",
"relayhosts": "",
"remove_row": "",
"reset_default": "",
"reset_limit": "",
"rsetting_add_rule": "",
"rsetting_content": "",
"rsetting_desc": "",
"rsetting_no_selection": "",
"rsetting_none": "",
"rsettings_insert_preset": "",
"rsettings_preset_1": "",
"rsettings_preset_2": "",
"rsettings_preset_3": "",
"rsettings_preset_4": "",
"rspamd_com_settings": "",
"rspamd_global_filters": "",
"rspamd_global_filters_agree": "",
"rspamd_global_filters_info": "",
"rspamd_settings_map": "",
"sal_level": "",
"send": "",
"sender": "",
"service": "",
"service_id": "",
"subject": "",
"success": "",
"sys_mails": "",
"text": "",
"title": "",
"ui_header_announcement_type": "",
"ui_header_announcement_type_danger": "",
"ui_header_announcement_type_info": "",
"validate_license_now": "",
"verify": "",
"yes": "",
"allowed_methods": "",
"allowed_origins": "",
"cors_settings": "",
"customize": "",
"credentials_transport_warning": "",
"destination": "",
"dkim_domains_selector": "",
"hash_remove_info": "",
"html": "",
"message_size": "",
"dkim_domains_wo_keys": "",
"dkim_from_title": "",
"dkim_overwrite_key": "",
"excludes": "",
"f2b_blacklist": "",
"f2b_filter": "",
"f2b_list_info": "",
"f2b_netban_ipv4": "",
"f2b_netban_ipv6": "",
"f2b_regex_info": "",
"from": "",
"generate": "",
"guid": "",
"guid_and_license": "",
"help_text": "",
"dkim_to": "",
"dkim_to_title": "",
"domain_admin": "",
"domain_s": "",
"duplicate": "",
"duplicate_dkim": "",
"ip_check": "",
"ip_check_disabled": "",
"ip_check_opt_in": "",
"last_applied": "",
"merged_vars_hint": "",
"license_info": "",
"link": "",
"login_time": "",
"logo_info": "",
"main_name": "",
"password_policy_lowerupper": "",
"password_policy_numbers": "",
"password_policy_special_chars": "",
"quarantine_bcc": "",
"quarantine_exclude_domains": "",
"quarantine_max_age": "",
"quarantine_max_score": "",
"quarantine_max_size": "",
"quarantine_notification_sender": "",
"title_name": "",
"to_top": "",
"transport_dest_format": "",
"transport_maps": "",
"transport_test_rcpt_info": "",
"transports_hint": "",
"ui_header_announcement": "",
"ui_header_announcement_active": "",
"ui_header_announcement_content": "",
"ui_header_announcement_help": "",
"ui_header_announcement_select": "",
"upload": "",
"regex_maps": "",
"relay_from": "",
"dkim_from": "",
"activate_api": "",
"activate_send": "",
"active_rspamd_settings_map": "",
"add_admin": "",
"add_relayhost": "",
"add_relayhost_hint": "",
"add_row": "",
"add_settings_rule": "",
"add_transport": "",
"add_transports_hint": "",
"customer_id": "",
"additional_rows": "",
"admins": "",
"admins_ldap": "",
"advanced_settings": "",
"api_allow_from": "",
"api_info": "",
"api_key": "",
"api_read_only": "",
"api_read_write": "",
"api_skip_ip_check": "",
"app_links": "",
"app_name": "",
"apps_name": "",
"arrival_time": "",
"authed_user": "",
"ays": "",
"ban_list_info": "",
"change_logo": "",
"convert_html_to_text": "",
"routing": "",
"ui_footer": "",
"lookup_mx": ""
},
"danger": {
"access_denied": "Odmowa dostępu lub nieprawidłowe dane w formularzu",
@@ -145,7 +397,92 @@
"target_domain_invalid": "Domena Idź do jest nieprawidłowa",
"targetd_not_found": "Nie znaleziono domeny docelowej",
"username_invalid": "Nie można użyć nazwy użytkownika",
"validity_missing": "Proszę wyznaczyć termin ważności"
"validity_missing": "Proszę wyznaczyć termin ważności",
"webauthn_authenticator_failed": "",
"app_name_empty": "",
"app_passwd_id_invalid": "",
"bcc_empty": "",
"bcc_exists": "",
"bcc_must_be_email": "",
"cors_invalid_method": "",
"cors_invalid_origin": "",
"mysql_error": "",
"img_dimensions_exceeded": "",
"img_size_exceeded": "",
"invalid_filter_type": "",
"invalid_host": "",
"invalid_mime_type": "",
"invalid_nexthop": "",
"invalid_nexthop_authenticated": "",
"invalid_recipient_map_new": "",
"invalid_recipient_map_old": "",
"mailbox_defquota_exceeds_mailbox_maxquota": "",
"map_content_empty": "",
"network_host_invalid": "",
"next_hop_interferes": "",
"next_hop_interferes_any": "",
"nginx_reload_failed": "",
"no_user_defined": "",
"tls_policy_map_entry_exists": "",
"tls_policy_map_parameter_invalid": "",
"totp_verification_failed": "",
"transport_dest_exists": "",
"webauthn_verification_failed": "",
"webauthn_publickey_failed": "",
"webauthn_username_failed": "",
"unknown": "",
"value_missing": "",
"yotp_verification_failed": "",
"unknown_tfa_method": "",
"unlimited_quota_acl": "",
"comment_too_long": "",
"defquota_empty": "",
"demo_mode_enabled": "",
"dkim_domain_or_sel_exists": "",
"domain_cannot_match_hostname": "",
"extended_sender_acl_denied": "",
"from_invalid": "",
"global_filter_write_error": "",
"global_map_invalid": "",
"global_map_write_error": "",
"ham_learn_error": "",
"imagick_exception": "",
"img_invalid": "",
"img_tmp_missing": "",
"invalid_bcc_map_type": "",
"invalid_destination": "",
"private_key_error": "",
"pushover_credentials_missing": "",
"pushover_key": "",
"pushover_token": "",
"recipient_map_entry_exists": "",
"redis_error": "",
"relayhost_invalid": "",
"release_send_failed": "",
"reset_f2b_regex": "",
"rl_timeframe": "",
"rspamd_ui_pw_length": "",
"set_acl_failed": "",
"settings_map_invalid": "",
"sieve_error": "",
"spam_learn_error": "",
"subject_empty": "",
"template_exists": "",
"template_id_invalid": "",
"template_name_invalid": "",
"text_empty": "",
"tls_policy_map_dest_invalid": "",
"malformed_username": "",
"extra_acl_invalid": "",
"targetd_relay_domain": "",
"temp_error": "",
"tfa_token_invalid": "",
"script_empty": "",
"ip_list_empty": "",
"extra_acl_invalid_domain": "",
"fido2_verification_failed": "",
"file_open_error": "",
"filter_type": ""
},
"edit": {
"active": "Aktywny",
@@ -190,7 +527,93 @@
"target_domain": "Domena docelowa",
"title": "Edytuj obiekt",
"unchanged_if_empty": "Jeżli bez zmian, nie wypełniaj",
"username": "Nazwa użytkownika"
"username": "Nazwa użytkownika",
"comment_info": "",
"created_on": "",
"footer_exclude": "",
"domain_footer_skip_replies": "",
"relay_transport_info": "",
"relay_unknown_only": "",
"scope": "",
"sender_acl_disabled": "",
"sender_acl_info": "",
"sieve_type": "",
"skipcrossduplicates": "",
"sogo_access": "",
"sogo_access_info": "",
"timeout2": "",
"validate_save": "",
"custom_attributes": "",
"domain_footer_info_vars": {
"from_user": "",
"from_addr": "",
"custom": "",
"auth_user": "",
"from_name": "",
"from_domain": ""
},
"domain_footer_plain": "",
"relayhost": "",
"timeout1": "",
"acl": "",
"admin": "",
"advanced_settings": "",
"allow_from_smtp": "",
"bcc_dest_format": "",
"client_id": "",
"client_secret": "",
"domain_footer": "",
"domain_footer_html": "",
"domain_footer_info": "",
"pushover_sender_array": "",
"pushover_sender_regex": "",
"pushover_text": "",
"pushover_title": "",
"ratelimit": "",
"redirect_uri": "",
"sogo_visible": "",
"sogo_visible_info": "",
"spam_alias": "",
"spam_filter": "",
"spam_policy": "",
"spam_score": "",
"sieve_desc": "",
"gal_info": "",
"grant_types": "",
"last_modified": "",
"delete2": "",
"delete_ays": "",
"disable_login": "",
"extended_sender_acl": "",
"extended_sender_acl_info": "",
"force_pw_update": "",
"force_pw_update_info": "",
"mailbox_quota_def": "",
"mailbox_relayhost_info": "",
"mbox_rl_info": "",
"none_inherit": "",
"nexthop": "",
"private_comment": "",
"public_comment": "",
"pushover": "",
"pushover_evaluate_x_prio": "",
"pushover_info": "",
"pushover_only_x_prio": "",
"maxbytespersecond": "",
"allow_from_smtp_info": "",
"allowed_protocols": "",
"app_name": "",
"app_passwd": "",
"app_passwd_protocols": "",
"automap": "",
"gal": "",
"generate": "",
"pushover_sound": "",
"pushover_vars": "",
"pushover_verify": "",
"quota_warning_bcc": "",
"quota_warning_bcc_info": "",
"lookup_mx": ""
},
"footer": {
"cancel": "Anuluj",
@@ -198,7 +621,14 @@
"delete_now": "Usuń teraz",
"delete_these_items": "Czy jesteś pewien, że chcesz usunąć następujące elementy?",
"loading": "Proszę czekać...",
"restart_now": "Uruchom ponownie teraz"
"restart_now": "Uruchom ponownie teraz",
"hibp_check": "",
"hibp_nok": "",
"restart_container_info": "",
"restarting_container": "",
"hibp_ok": "",
"nothing_selected": "",
"restart_container": ""
},
"header": {
"administration": "Administrowanie",
@@ -206,16 +636,25 @@
"mailcow_config": "Konfiguracja",
"quarantine": "Kwarantanna",
"restart_sogo": "Uruchom ponownie SOGo",
"user_settings": "Ustawienia użytkownika"
"user_settings": "Ustawienia użytkownika",
"apps": "",
"debug": "",
"mailcow_system": "",
"restart_netfilter": ""
},
"info": {
"no_action": "Żadne działanie nie ma zastosowania"
"no_action": "Żadne działanie nie ma zastosowania",
"awaiting_tfa_confirmation": "",
"session_expires": ""
},
"login": {
"delayed": "Logowanie zostało opóźnione o %s sekund.",
"login": "Zaloguj się",
"password": "Hasło",
"username": "Nazwa użytkownika"
"username": "Nazwa użytkownika",
"mobileconfig_info": "",
"fido2_webauthn": "",
"other_logins": ""
},
"mailbox": {
"action": "Działanie",
@@ -275,7 +714,122 @@
"tls_enforce_out": "Uruchom TLS wychodzące",
"toggle_all": "Zaznacz wszystkie",
"username": "Nazwa użytkownika",
"weekly": "Co tydzień"
"weekly": "Co tydzień",
"syncjob_EX_OK": "",
"syncjob_EXIT_CONNECTION_FAILURE": "",
"add_alias_expand": "",
"add_bcc_entry": "",
"add_filter": "",
"add_recipient_map_entry": "",
"allow_from_smtp": "",
"bcc_info": "",
"bcc_local_dest": "",
"bcc_map": "",
"bcc_map_type": "",
"bcc_maps": "",
"bcc_rcpt_map": "",
"bcc_sender_map": "",
"bcc_to_rcpt": "",
"bcc_to_sender": "",
"bcc_type": "",
"booking_null": "",
"booking_0_short": "",
"booking_custom": "",
"booking_custom_short": "",
"booking_ltnull": "",
"booking_lt0_short": "",
"catch_all": "",
"created_on": "",
"goto_spam": "",
"insert_preset": "",
"last_mail_login": "",
"last_modified": "",
"last_pw_change": "",
"last_run_reset": "",
"mailbox": "",
"mailbox_defaults": "",
"mailbox_defaults_info": "",
"mailbox_defquota": "",
"mailbox_templates": "",
"no": "",
"q_add_header": "",
"q_all": "",
"q_reject": "",
"quarantine_category": "",
"recipient": "",
"recipient_map": "",
"recipient_map_info": "",
"recipient_map_old": "",
"recipient_map_old_info": "",
"recipient_maps": "",
"relay_unknown": "",
"sogo_visible_y": "",
"stats": "",
"status": "",
"syncjob_check_log": "",
"syncjob_last_run_result": "",
"syncjob_EXIT_TLS_FAILURE": "",
"tls_policy_maps_info": "",
"tls_policy_maps_long": "",
"waiting": "",
"yes": "",
"sieve_preset_8": "",
"add_template": "",
"add_tls_policy_map": "",
"address_rewriting": "",
"allow_from_smtp_info": "",
"table_size": "",
"alias_domain_alias_hint": "",
"disable_login": "",
"disable_x": "",
"dkim_domains_selector": "",
"domain_templates": "",
"sieve_preset_3": "",
"sieve_preset_5": "",
"allowed_protocols": "",
"bcc": "",
"bcc_destination": "",
"bcc_destinations": "",
"enable_x": "",
"filters": "",
"force_pw_update": "",
"gal": "",
"goto_ham": "",
"open_logs": "",
"owner": "",
"private_comment": "",
"public_comment": "",
"recipient_map_new": "",
"recipient_map_new_info": "",
"running": "",
"sender": "",
"set_postfilter": "",
"set_prefilter": "",
"sieve_info": "",
"sieve_preset_1": "",
"sieve_preset_2": "",
"sieve_preset_6": "",
"sieve_preset_7": "",
"sieve_preset_header": "",
"sogo_visible": "",
"sogo_visible_n": "",
"syncjob_EXIT_AUTHENTICATION_FAILURE": "",
"syncjob_EXIT_OVERQUOTA": "",
"syncjob_EXIT_CONNECTION_FAILURE_HOST1": "",
"syncjob_EXIT_AUTHENTICATION_FAILURE_USER1": "",
"table_size_show_n": "",
"templates": "",
"template": "",
"tls_map_parameters_info": "",
"tls_map_policy": "",
"tls_policy_maps": "",
"tls_policy_maps_enforced_tls": "",
"sieve_preset_4": "",
"alias_domain_backupmx": "",
"all_domains": "",
"tls_map_dest": "",
"tls_map_dest_info": "",
"tls_map_parameters": ""
},
"quarantine": {
"action": "Działanie",
@@ -283,10 +837,68 @@
"quarantine": "Kwarantanna",
"quick_actions": "Szybkie działania",
"remove": "Usuń",
"toggle_all": "Zaznacz wszystkie"
"toggle_all": "Zaznacz wszystkie",
"deliver_inbox": "",
"disabled_by_config": "",
"download_eml": "",
"high_danger": "",
"neutral_danger": "",
"info": "",
"junk_folder": "",
"learn_spam_delete": "",
"low_danger": "",
"medium_danger": "",
"notified": "",
"rcpt": "",
"atts": "",
"check_hash": "",
"confirm": "",
"confirm_delete": "",
"danger": "",
"qhandler_success": "",
"qid": "",
"qinfo": "",
"quick_delete_link": "",
"quick_info_link": "",
"quick_release_link": "",
"received": "",
"recipients": "",
"refresh": "",
"rejected": "",
"release": "",
"release_body": "",
"rspamd_result": "",
"sender": "",
"sender_header": "",
"show_item": "",
"spam": "",
"spam_score": "",
"subj": "",
"table_size": "",
"table_size_show_n": "",
"text_from_html_content": "",
"text_plain_content": "",
"type": "",
"settings_info": "",
"release_subject": "",
"rewrite_subject": "",
"qitem": ""
},
"queue": {
"queue_manager": "Queue Manager"
"queue_manager": "Queue Manager",
"hold_mail_legend": "",
"delete": "",
"flush": "",
"info": "",
"legend": "",
"ays": "",
"deliver_mail": "",
"deliver_mail_legend": "",
"hold_mail": "",
"show_message": "",
"unban": "",
"unhold_mail": "",
"unhold_mail_legend": ""
},
"start": {
"help": "Pokaż/Ukryj panel pomocy",
@@ -322,7 +934,63 @@
"object_modified": "Zapisano zmiany w obiekcie %s",
"resource_added": "Dodano śródło %s",
"resource_modified": "Zapisano zmiany w skrzynce %s",
"resource_removed": "Usunięto zasób %s"
"resource_removed": "Usunięto zasób %s",
"hash_deleted": "",
"template_removed": "",
"tls_policy_map_entry_saved": "",
"ui_texts": "",
"upload_success": "",
"verified_fido2_login": "",
"verified_webauthn_login": "",
"verified_totp_login": "",
"verified_yotp_login": "",
"tls_policy_map_entry_deleted": "",
"acl_saved": "",
"admin_added": "",
"admin_api_modified": "",
"admin_removed": "",
"app_links": "",
"app_passwd_added": "",
"app_passwd_removed": "",
"bcc_deleted": "",
"bcc_edited": "",
"bcc_saved": "",
"cors_headers_edited": "",
"db_init_complete": "",
"delete_filter": "",
"delete_filters": "",
"deleted_syncjob": "",
"deleted_syncjobs": "",
"domain_add_dkim_available": "",
"dkim_duplicated": "",
"domain_footer_modified": "",
"f2b_banlist_refreshed": "",
"ip_check_opt_in_modified": "",
"item_released": "",
"items_released": "",
"learned_ham": "",
"license_modified": "",
"nginx_reloaded": "",
"password_policy_saved": "",
"pushover_settings_edited": "",
"qlearn_spam": "",
"queue_command_success": "",
"recipient_map_entry_deleted": "",
"recipient_map_entry_saved": "",
"relayhost_added": "",
"relayhost_removed": "",
"reset_main_logo": "",
"rl_saved": "",
"rspamd_ui_pw_set": "",
"saved_settings": "",
"settings_map_added": "",
"settings_map_removed": "",
"sogo_profile_reset": "",
"template_added": "",
"template_modified": "",
"dovecot_restart_success": "",
"global_filter_written": "",
"logged_in_as": ""
},
"tfa": {
"api_register": "%s używa Yubico Cloud API. Proszę pobrać klucz API dla Twojego klucza <a href=\"https://upgrade.yubico.com/getapikey/\" target=\"_blank\">here</a>",
@@ -342,7 +1010,15 @@
"webauthn": "Uwierzytelnianie WebAuthn",
"waiting_usb_auth": "<i>Czekam na urządzenie USB...</i><br><br>Wciśnij teraz przycisk na urządzeniu WebAuthn USB.",
"waiting_usb_register": "<i> Czekam na urządzenie USB...</i><br><br>Wprowadź swoje hasło powyżej i potwierdź rejestrację WebAuthn przez naciśnięcie przycisku na urządzeniu WebAuthn USB.",
"yubi_otp": "Uwierzytelnianie Yubico OTP"
"yubi_otp": "Uwierzytelnianie Yubico OTP",
"authenticators": "",
"init_webauthn": "",
"reload_retry": "",
"start_webauthn_validation": "",
"tfa_token_invalid": "",
"u2f_deprecated": "",
"u2f_deprecated_important": "",
"error_code": ""
},
"user": {
"action": "Działanie",
@@ -429,6 +1105,205 @@
"username": "Nazwa użytkownika",
"week": "Tydzień",
"weekly": "Co tydzień",
"weeks": "Tygodnie"
"weeks": "Tygodnie",
"last_ui_login": "",
"loading": "",
"spam_score_reset": "",
"status": "",
"change_password_hint_app_passwords": "",
"verify": "",
"email": "",
"login_history": "",
"mailbox": "",
"mailbox_general": "",
"mailbox_settings": "",
"month": "",
"months": "",
"app_name": "",
"apple_connection_profile": "",
"from": "",
"generate": "",
"pushover_sound": "",
"value": "",
"quarantine_category_info": "",
"running": "",
"pushover_sender_regex": "",
"pushover_text": "",
"pushover_title": "",
"pushover_vars": "",
"pushover_verify": "",
"title": "",
"advanced_settings": "",
"app_hint": "",
"allowed_protocols": "",
"apple_connection_profile_complete": "",
"apple_connection_profile_mailonly": "",
"apple_connection_profile_with_app_password": "",
"attribute": "",
"clear_recent_successful_connections": "",
"created_on": "",
"direct_protocol_access": "",
"email_and_dav": "",
"fido2_webauthn": "",
"last_mail_login": "",
"last_pw_change": "",
"no_last_login": "",
"open_logs": "",
"open_webmail_sso": "",
"password": "",
"password_repeat": "",
"pushover_evaluate_x_prio": "",
"pushover_info": "",
"pushover_only_x_prio": "",
"pushover_sender_array": "",
"q_add_header": "",
"q_all": "",
"q_reject": "",
"quarantine_category": "",
"quarantine_notification_info": "",
"recent_successful_connections": "",
"syncjob_check_log": "",
"syncjob_last_run_result": "",
"syncjob_EX_OK": "",
"syncjob_EXIT_CONNECTION_FAILURE": "",
"syncjob_EXIT_TLS_FAILURE": "",
"syncjob_EXIT_AUTHENTICATION_FAILURE": "",
"syncjob_EXIT_AUTHENTICATION_FAILURE_USER1": "",
"waiting": "",
"with_app_password": "",
"year": "",
"years": "",
"empty": "",
"save": "",
"sender_acl_disabled": "",
"syncjob_EXIT_OVERQUOTA": "",
"syncjob_EXIT_CONNECTION_FAILURE_HOST1": "",
"expire_in": "",
"app_passwds": "",
"text": "",
"create_app_passwd": "",
"delete_ays": ""
},
"debug": {
"size": "",
"started_at": "",
"started_on": "",
"static_logs": "",
"show_ip": "",
"solr_dead": "",
"solr_status": "",
"no_update_available": "",
"update_failed": "",
"architecture": "",
"chart_this_server": "",
"container_disabled": "",
"log_info": "",
"online_users": "",
"restart_container": "",
"success": "",
"system_containers": "",
"timezone": "",
"uptime": "",
"update_available": "",
"username": "",
"wip": "",
"containers_info": "",
"container_running": "",
"in_memory_logs": "",
"jvm_memory_solr": "",
"last_modified": "",
"logs": "",
"memory": "",
"service": "",
"container_stopped": "",
"cores": "",
"current_time": "",
"disk_usage": "",
"docs": "",
"error_show_ip": "",
"external_logs": "",
"history_all_servers": "",
"login_time": ""
},
"oauth2": {
"deny": "",
"access_denied": "",
"authorize_app": "",
"permit": "",
"profile_desc": "",
"scope_ask_permission": "",
"profile": ""
},
"fido2": {
"confirm": "",
"fido2_auth": "",
"fido2_success": "",
"fido2_validation_failed": "",
"fn": "",
"known_ids": "",
"none": "",
"register_status": "",
"set_fido2": "",
"set_fido2_touchid": "",
"set_fn": "",
"start_fido2_validation": "",
"rename": ""
},
"warning": {
"quota_exceeded_scope": "",
"session_token": "",
"session_ua": "",
"no_active_admin": "",
"cannot_delete_self": "",
"domain_added_sogo_failed": "",
"dovecot_restart_failed": "",
"fuzzy_learn_error": "",
"hash_not_found": "",
"ip_invalid": "",
"is_not_primary_alias": ""
},
"datatables": {
"paginate": {
"next": "",
"first": "",
"last": "",
"previous": ""
},
"collapse_all": "",
"emptyTable": "",
"infoEmpty": "",
"infoFiltered": "",
"thousands": "",
"lengthMenu": "",
"loadingRecords": "",
"processing": "",
"search": "",
"zeroRecords": "",
"aria": {
"sortAscending": "",
"sortDescending": ""
},
"expand_all": "",
"info": "",
"decimal": "",
"infoPostFix": ""
},
"diagnostics": {
"dns_records_24hours": "",
"dns_records_data": "",
"dns_records_status": "",
"dns_records_type": "",
"optional": "",
"dns_records_docs": "",
"dns_records": "",
"cname_from_a": "",
"dns_records_name": ""
},
"ratelimit": {
"disabled": "",
"second": "",
"minute": "",
"hour": "",
"day": ""
}
}

View File

@@ -1,6 +1,6 @@
{
"acl": {
"alias_domains": "Adicionar domínios alternativos",
"alias_domains": "Adicionar domínios alias",
"app_passwds": "Gerenciar senhas de aplicativos",
"bcc_maps": "Mapas BCC",
"delimiter_action": "Ação delimitadora",
@@ -9,8 +9,8 @@
"eas_reset": "Redefinir dispositivos EAS",
"extend_sender_acl": "Permitir estender a ACL do remetente por endereços externos",
"filters": "Filtros",
"login_as": "Faça login como usuário da caixa de correio",
"mailbox_relayhost": "Alterar relayhost para uma caixa de correio",
"login_as": "Faça login como usuário da mailbox",
"mailbox_relayhost": "Alterar relayhost para uma mailbox",
"prohibited": "Proibido pela ACL",
"protocol_access": "Alterar o acesso ao protocolo",
"pushover": "Pushover",
@@ -28,7 +28,7 @@
"spam_score": "Pontuação de spam",
"syncjobs": "Trabalhos de sincronização",
"tls_policy": "Política de TLS",
"unlimited_quota": "Cota ilimitada para caixas de correio"
"unlimited_quota": "Cota ilimitada para mailboxes"
},
"add": {
"activate_filter_warn": "Todos os outros filtros serão desativados quando a opção ativa estiver marcada.",
@@ -70,11 +70,11 @@
"hostname": "Anfitrião",
"inactive": "Inativo",
"kind": "Gentil",
"mailbox_quota_def": "Cota de caixa de correio padrão",
"mailbox_quota_m": "Cota máxima por caixa de correio (MiB)",
"mailbox_quota_def": "Cota de caixa de mailbox",
"mailbox_quota_m": "Cota máxima por mailbox (MiB)",
"mailbox_username": "Nome de usuário (parte esquerda de um endereço de e-mail)",
"max_aliases": "Máximo de aliases possíveis",
"max_mailboxes": "Número máximo de caixas de correio possíveis",
"max_mailboxes": "Número máximo de mailboxes possíveis",
"mins_interval": "Intervalo de votação (minutos)",
"multiple_bookings": "Várias reservas",
"nexthop": "Próximo salto",
@@ -86,10 +86,10 @@
"public_comment": "Comentário público",
"quota_mb": "Cota (MiB)",
"relay_all": "Retransmita todos os destinatários",
"relay_all_info": "↪ Se você optar por <b>não</b> retransmitir todos os destinatários, precisará adicionar uma caixa de correio (“cega”) para cada destinatário que deve ser retransmitido.",
"relay_all_info": "↪ Se você optar por <b>não</b> retransmitir todos os destinatários, precisará adicionar uma mailbox (“cega”) para cada destinatário que deve ser retransmitido.",
"relay_domain": "Retransmitir este domínio",
"relay_transport_info": "<div class=\"badge fs-6 bg-info\">Informações</div> Você pode definir mapas de transporte para um destino personalizado para esse domínio. Se não for definido, uma pesquisa MX será feita.",
"relay_unknown_only": "Retransmita somente caixas de correio não existentes. As caixas de correio existentes serão entregues localmente.",
"relay_unknown_only": "Retransmita somente mailboxes não existentes. As mailboxes existentes serão entregues localmente.",
"relayhost_wrapped_tls_info": "Por favor, <b>não</b> use portas com cobertura TLS (usadas principalmente na porta 465). <br>\r\nUse qualquer porta não encapsulada e emita STARTTLS. Uma política de TLS para impor o TLS pode ser criada em “mapas de políticas de TLS”.",
"select": "Selecione...",
"select_domain": "Selecione primeiro um domínio",
@@ -212,7 +212,7 @@
"in_use_by": "Em uso por",
"inactive": "Inativo",
"include_exclude": "Incluir/Excluir",
"include_exclude_info": "Por padrão - sem seleção - <b>todas as caixas de correio são endereçadas</b>",
"include_exclude_info": "Por padrão - sem seleção - <b>todas as mailboxes são endereçadas</b>",
"includes": "Inclua esses destinatários",
"ip_check": "Verificação de IP",
"ip_check_disabled": "A verificação de IP está desativada. Você pode ativá-lo em <br><strong>Sistema > Configuração > Opções > Personalizar</strong>",
@@ -268,13 +268,13 @@
"quarantine_release_format": "Formato dos itens lançados",
"quarantine_release_format_att": "Como anexo",
"quarantine_release_format_raw": "Original não modificado",
"quarantine_retention_size": "<b>Retenções por caixa de correio: <small>0</small> indica inativo.</b> <br>",
"quarantine_retention_size": "Retenções por mailbox: <br><small>0 indica <b>inativo</b>.</small>",
"quota_notification_html": "Modelo de e-mail de notificação: <br><small>deixe em branco para restaurar o modelo padrão.</small>",
"quota_notification_sender": "Remetente do e-mail de notificação",
"quota_notification_subject": "Assunto do e-mail de notificação",
"quota_notifications": "Notificações de cotas",
"quota_notifications_info": "As notificações de cota são enviadas aos usuários uma vez ao ultrapassar 80% e uma vez ao ultrapassar 95% de uso.",
"quota_notifications_vars": "{{percent}} é igual à cota atual do usuário <br>{{username}} é o nome da caixa de correio",
"quota_notifications_vars": "{{percent}} é igual à cota atual do usuário <br>{{username}} é o nome da mailbox",
"queue_unban": "não banido",
"r_active": "Restrições ativas",
"r_inactive": "Restrições inativas",
@@ -302,7 +302,7 @@
"rsettings_insert_preset": "Inserir exemplo de predefinição “%s”",
"rsettings_preset_1": "Desative tudo, exceto o DKIM e o limite de taxa para usuários autenticados",
"rsettings_preset_2": "Postmasters querem spam",
"rsettings_preset_3": "Permitir somente remetentes específicos para uma caixa de correio (ou seja, uso somente como caixa de correio interna)",
"rsettings_preset_3": "Permitir somente remetentes específicos para uma mailbox (ou seja, uso somente como mailbox interna)",
"rsettings_preset_4": "Desativar Rspamd para um domínio",
"rspamd_com_settings": "Um nome de configuração será gerado automaticamente, veja os exemplos de predefinições abaixo. Para obter mais detalhes, consulte a documentação <a href=\"https://rspamd.com/doc/configuration/settings.html#settings-structure\" target=\"_blank\">do Rspamd</a>",
"rspamd_global_filters": "Mapas de filtro globais",
@@ -369,7 +369,7 @@
"comment_too_long": "Comentário muito longo, máximo de 160 caracteres permitidos",
"cors_invalid_method": "Método de permissão inválido especificado",
"cors_invalid_origin": "Origem de permissão inválida especificada",
"defquota_empty": "A cota padrão por caixa de correio não deve ser 0.",
"defquota_empty": "A cota padrão por mailbox não deve ser 0.",
"demo_mode_enabled": "O modo de demonstração está ativado",
"description_invalid": "A descrição do recurso para %s é inválida",
"dkim_domain_or_sel_exists": "Existe uma chave DKIM para “%s” e não será substituída",
@@ -407,22 +407,22 @@
"invalid_recipient_map_old": "Destinatário original inválido especificado: %s",
"ip_list_empty": "A lista de IPs permitidos não pode estar vazia",
"is_alias": "%s já é conhecido como endereço de alias",
"is_alias_or_mailbox": "%s já é conhecido como alias, caixa de correio ou endereço de alias expandido a partir de um domínio de alias.",
"is_alias_or_mailbox": "%s já é conhecido como alias, mailbox ou alias de endereço expandido a partir de um domínio de alias.",
"is_spam_alias": "%s já é conhecido como endereço de alias temporário (endereço de alias de spam)",
"last_key": "A última chave não pode ser excluída. Em vez disso, desative o TFA.",
"login_failed": "Falha no login",
"mailbox_defquota_exceeds_mailbox_maxquota": "A cota padrão excede o limite máximo da cota",
"mailbox_invalid": "O nome da caixa de correio é inválido",
"mailbox_invalid": "O nome da mailbox é inválido",
"mailbox_quota_exceeded": "A cota excede o limite do domínio (máx. %d MiB)",
"mailbox_quota_exceeds_domain_quota": "A cota máxima excede o limite da cota do domínio",
"mailbox_quota_left_exceeded": "Não há espaço restante (espaço restante: %d MiB)",
"mailboxes_in_use": "O máximo de caixas de correio deve ser maior ou igual a %d",
"mailboxes_in_use": "O máximo de mailboxes deve ser maior ou igual a %d",
"malformed_username": "Nome de usuário malformado",
"map_content_empty": "O conteúdo do mapa não pode estar vazio",
"max_alias_exceeded": "Número máximo de aliases excedido",
"max_mailbox_exceeded": "Número máximo de caixas de correio excedido (%d de %d)",
"max_quota_in_use": "A cota da caixa de correio deve ser maior ou igual a %d MiB",
"maxquota_empty": "A cota máxima por caixa de correio não deve ser 0.",
"max_mailbox_exceeded": "Número máximo de mailboxes excedido (%d de %d)",
"max_quota_in_use": "A cota da mailbox deve ser maior ou igual a %d MiB",
"maxquota_empty": "A cota máxima por mailbox não deve ser 0.",
"mysql_error": "Erro do MySQL: %s",
"network_host_invalid": "Rede ou host inválidos: %s",
"next_hop_interferes": "%s interfere com o nexthop %s",
@@ -480,7 +480,9 @@
"username_invalid": "O nome de usuário %s não pode ser usado",
"validity_missing": "Por favor, atribua um período de validade",
"value_missing": "Forneça todos os valores",
"yotp_verification_failed": "Falha na verificação do Yubico OTP: %s"
"yotp_verification_failed": "Falha na verificação do Yubico OTP: %s",
"img_dimensions_exceeded": "A imagem excede o tamanho máximo",
"img_size_exceeded": "A imagem excede o tamanho máximo"
},
"datatables": {
"collapse_all": "Recolher tudo",
@@ -554,7 +556,7 @@
"dns_records": "Registros DNS",
"dns_records_24hours": "Observe que as alterações feitas no DNS podem levar até 24 horas para que seu estado atual seja refletido corretamente nesta página. O objetivo é uma forma de você ver facilmente como configurar seus registros DNS e verificar se todos os seus registros estão armazenados corretamente no DNS.",
"dns_records_data": "Dados corretos",
"dns_records_docs": "Consulte também <a target=\"_blank\" href=\"https://docs.mailcow.email/prerequisite/prerequisite-dns/\">a documentação</a>.",
"dns_records_docs": "Consulte também <a target=\"_blank\" href=\"https://docs.mailcow.email/getstarted/prerequisite-dns\">a documentação</a>.",
"dns_records_name": "Nome",
"dns_records_status": "Estado atual",
"dns_records_type": "Tipo",
@@ -609,6 +611,7 @@
"extended_sender_acl_info": "Uma chave de domínio DKIM deve ser importada, se disponível. <br>\r\n Lembre-se de adicionar esse servidor ao registro TXT SPF correspondente. <br>\r\n Sempre que um domínio ou domínio de alias é adicionado a esse servidor, que se sobrepõe a um endereço externo, o endereço externo é removido. <br>\r\n Use @domain .tld para permitir o envio como * @domain .tld.",
"force_pw_update": "Forçar a atualização da senha no próximo login",
"force_pw_update_info": "Esse usuário só poderá fazer login em %s. As senhas do aplicativo permanecem utilizáveis.",
"footer_exclude": "Excluir do rodapé",
"full_name": "Nome completo",
"gal": "Lista de endereços global",
"gal_info": "A GAL contém todos os objetos de um domínio e não pode ser editada por nenhum usuário. Faltam informações de disponibilidade no SoGo, se desativadas! <b>Reinicie o SoGo para aplicar as alterações.</b>",
@@ -619,15 +622,15 @@
"kind": "Gentil",
"last_modified": "Última modificação",
"lookup_mx": "Destination é uma expressão regular que corresponde ao nome MX (<code>.*\\ .google\\ .com</code> para rotear todos os e-mails direcionados a um MX que termina em google.com nesse salto)",
"mailbox": "Editar caixa de correio",
"mailbox_quota_def": "Cota de caixa de correio padrão",
"mailbox": "Editar mailbox",
"mailbox_quota_def": "Cota mailbox padrão",
"mailbox_relayhost_info": "Aplicado somente à caixa de correio e aos aliases diretos, substitui um host de retransmissão de domínio.",
"max_aliases": "Máximo de aliases",
"max_mailboxes": "Número máximo de caixas de correio possíveis",
"max_quota": "Cota máxima por caixa de correio (MiB)",
"max_mailboxes": "Número máximo de mailboxes possíveis",
"max_quota": "Cota máxima por mailbox (MiB)",
"maxage": "Duração máxima das mensagens em dias que serão pesquisadas remotamente <br><small>(0 = ignorar a idade</small>)",
"maxbytespersecond": "Máximo de bytes por segundo <br><small>(0 = ilimitado</small>)",
"mbox_rl_info": "Esse limite de taxa é aplicado ao nome de login do SASL e corresponde a qualquer endereço “de” usado pelo usuário conectado. Um limite de taxa de caixa de correio substitui um limite de taxa em todo o domínio.",
"mbox_rl_info": "Esse limite de taxa é aplicado ao nome de login do SASL e corresponde a qualquer endereço “de” usado pelo usuário conectado. Um limite de taxa de mailbox substitui um limite de taxa em todo o domínio.",
"mins_interval": "Intervalo (min)",
"multiple_bookings": "Várias reservas",
"none_inherit": "Nenhum/Herdar",
@@ -654,10 +657,10 @@
"ratelimit": "Limite de taxa",
"redirect_uri": "URL de redirecionamento/retorno de chamada",
"relay_all": "Retransmita todos os destinatários",
"relay_all_info": "↪ Se você optar por <b>não</b> retransmitir todos os destinatários, precisará adicionar uma caixa de correio (“cega”) para cada destinatário que deve ser retransmitido.",
"relay_all_info": "↪ Se você optar por <b>não</b> retransmitir todos os destinatários, precisará adicionar uma mailbox (“cega”) para cada destinatário que deve ser retransmitido.",
"relay_domain": "Retransmitir este domínio",
"relay_transport_info": "<div class=\"badge fs-6 bg-info\">Informações</div> Você pode definir mapas de transporte para um destino personalizado para esse domínio. Se não for definido, uma pesquisa MX será feita.",
"relay_unknown_only": "Retransmita somente caixas de correio não existentes. As caixas de correio existentes serão entregues localmente.",
"relay_unknown_only": "Retransmita somente mailboxes não existentes. As caixas de mailboxes serão entregues localmente.",
"relayhost": "Transportes dependentes do remetente",
"remove": "Remover",
"resource": "Recurso",
@@ -665,14 +668,14 @@
"scope": "Escopo",
"sender_acl": "Permitir enviar como",
"sender_acl_disabled": "<span class=\"badge fs-6 bg-danger\">A verificação do remetente está desativada</span>",
"sender_acl_info": "Se o usuário A da caixa de correio tiver permissão para enviar como usuário B da caixa de correio, o endereço do remetente não será exibido automaticamente como campo “de” selecionável no SoGo. <br>\r\n O usuário B da caixa de correio precisa criar uma delegação no SoGo para permitir que o usuário A da caixa de correio selecione seu endereço como remetente. Para delegar uma caixa de correio no SoGo, use o menu (três pontos) à direita do nome da sua caixa de correio no canto superior esquerdo enquanto estiver na visualização de e-mail. Esse comportamento não se aplica a endereços de alias.",
"sender_acl_info": "Se o usuário A da mailbox tiver permissão para enviar como usuário B da mailbox, o endereço do remetente não será exibido automaticamente como campo “de” selecionável no SoGo. <br>\n O usuário B da mailbox precisa criar uma delegação no SoGo para permitir que o usuário A da mailbox selecione seu endereço como remetente. Para delegar uma mailbox no SoGo, use o menu (três pontos) à direita do nome da sua caixa de correio no canto superior esquerdo enquanto estiver na visualização de e-mail. Esse comportamento não se aplica a endereços de alias.",
"sieve_desc": "Breve descrição",
"sieve_type": "Tipo de filtro",
"skipcrossduplicates": "Ignore mensagens duplicadas entre pastas (primeiro a chegar, primeiro a ser servido)",
"sogo_access": "Conceder acesso de login direto ao SoGo",
"sogo_access_info": "O login único de dentro da interface do usuário de e-mail continua funcionando. Essa configuração não afeta o acesso a todos os outros serviços nem exclui ou altera o perfil SoGo existente de um usuário.",
"sogo_visible": "O alias é visível no SoGo",
"sogo_visible_info": "Essa opção afeta somente objetos, que podem ser exibidos no SoGo (endereços de alias compartilhados ou não compartilhados apontando para pelo menos uma caixa de correio local). Se estiver oculto, um alias não aparecerá como remetente selecionável no SoGo.",
"sogo_visible_info": "Essa opção afeta somente objetos, que podem ser exibidos no SoGo (endereços de alias compartilhados ou não compartilhados apontando para pelo menos uma mailbox local). Se estiver oculto, um alias não aparecerá como remetente selecionável no SoGo.",
"spam_alias": "Crie ou altere endereços de alias com limite de tempo",
"spam_filter": "Filtro de spam",
"spam_policy": "Adicionar ou remover itens da lista branca/negra",
@@ -688,7 +691,7 @@
"username": "Nome de usuário",
"validate_save": "Valide e salve",
"custom_attributes": "Atributos personalizados",
"mbox_exclude": "Excluir caixas de email"
"domain_footer_skip_replies": "Ignore o rodapé nos e-mails de resposta"
},
"fido2": {
"confirm": "Confirme",
@@ -724,7 +727,7 @@
"administration": "Configuração e detalhes",
"apps": "Aplicativos",
"debug": "Informações",
"email": "Correio eletrônico",
"email": "E-mail",
"mailcow_system": "Sistema",
"mailcow_config": "Configuração",
"quarantine": "Quarentena",
@@ -741,7 +744,7 @@
"delayed": "O login foi atrasado em %s segundos.",
"fido2_webauthn": "Login do FIDO2/WebAuthn",
"login": "Login",
"mobileconfig_info": "Faça login como usuário da caixa de correio para baixar o perfil de conexão Apple solicitado.",
"mobileconfig_info": "Faça login como usuário da mailbox para baixar o perfil de conexão Apple solicitado.",
"other_logins": "Login com chave",
"password": "Senha",
"username": "Nome de usuário"
@@ -758,16 +761,16 @@
"add_domain_alias": "Adicionar alias de domínio",
"add_domain_record_first": "Por favor, adicione um domínio primeiro",
"add_filter": "Adicionar filtro",
"add_mailbox": "Adicionar caixa de correio",
"add_mailbox": "Adicionar mailbox",
"add_recipient_map_entry": "Adicionar mapa do destinatário",
"add_resource": "Adicionar recurso",
"add_template": "Adicionar modelo",
"add_tls_policy_map": "Adicionar mapa de política TLS",
"address_rewriting": "Reescrita de endereço",
"alias": "Pseudônimo",
"alias_domain_alias_hint": "Os aliases <b>não</b> são aplicados automaticamente aos aliases de domínio. Um endereço de alias <code>my-alias @domain</code> <b>não</b> cobre o endereço <code>my-alias @alias -domain (onde “alias-domain” é um domínio</code> de alias imaginário para “domain”). <br>Use um filtro de peneira para redirecionar e-mails para uma caixa de correio externa (consulte a guia “Filtros” ou use SoGo -> Forwarder). Use “Expandir alias em domínios de alias” para adicionar automaticamente os aliases ausentes.",
"alias": "Alias",
"alias_domain_alias_hint": "Os aliases <b>não</b> são aplicados automaticamente aos aliases de domínio. Um endereço de alias <code>my-alias@domain</code> <b>não</b> cobre o endereço <code>my-alias@alias -domain</code> (onde “alias-domain” é um domínio de alias imaginário para “domain”). <br>Use um filtro para redirecionar e-mails para uma mailbox externa (consulte a guia “Filtros” ou use SoGo -> Forwarder). Use “Expandir alias em domínios de alias” para adicionar automaticamente os aliases ausentes.",
"alias_domain_backupmx": "Domínio de alias inativo para domínio de retransmissão",
"aliases": "Pseudônimos",
"aliases": "Aliases",
"all_domains": "Todos os domínios",
"allow_from_smtp": "<b>Permita que esses IPs usem apenas SMTP</b>",
"allow_from_smtp_info": "Deixe em branco para permitir todos os remetentes. Endereços e <br>redes IPv4/IPv6.",
@@ -829,16 +832,16 @@
"last_pw_change": "Última alteração de senha",
"last_run": "Última corrida",
"last_run_reset": "Programe a seguir",
"mailbox": "Caixa de correio",
"mailbox": "Mailbox",
"mailbox_defaults": "Configurações padrão",
"mailbox_defaults_info": "Defina as configurações padrão para novas caixas de correio.",
"mailbox_defquota": "Tamanho padrão da caixa de correio",
"mailbox_templates": "Modelos de caixa de correio",
"mailbox_quota": "Tamanho máximo de uma caixa de correio",
"mailboxes": "Caixas de correio",
"mailbox_defaults_info": "Defina as configurações padrão para novas mailboxes.",
"mailbox_defquota": "Tamanho padrão da mailbox",
"mailbox_templates": "Modelos de mailbox",
"mailbox_quota": "Tamanho máximo de uma mailbox",
"mailboxes": "Mailboxes",
"max_aliases": "Máximo de aliases",
"max_mailboxes": "Número máximo de caixas de correio possíveis",
"max_quota": "Cota máxima por caixa de correio",
"max_mailboxes": "Número máximo de mailboxes possíveis",
"max_quota": "Cota máxima por mailbox",
"mins_interval": "Intervalo (min)",
"msg_num": "Mensagem #",
"multiple_bookings": "Várias reservas",
@@ -865,7 +868,7 @@
"recipient_map_old_info": "O destino original do mapa de um destinatário deve ser um endereço de e-mail válido ou um nome de domínio.",
"recipient_maps": "Mapas de destinatários",
"relay_all": "Retransmita todos os destinatários",
"relay_unknown": "Retransmitir caixas de correio desconhecidas",
"relay_unknown": "Retransmitir mailboxes desconhecidas",
"remove": "Remover",
"resources": "Recursos",
"running": "Executando",
@@ -895,7 +898,7 @@
"syncjob_EXIT_CONNECTION_FAILURE": "Problema de conexão",
"syncjob_EXIT_TLS_FAILURE": "Problema com conexão criptografada",
"syncjob_EXIT_AUTHENTICATION_FAILURE": "Problema de autenticação",
"syncjob_EXIT_OVERQUOTA": "A caixa de correio de destino está acima da cota",
"syncjob_EXIT_OVERQUOTA": "A mailbox de destino está acima da cota",
"syncjob_EXIT_CONNECTION_FAILURE_HOST1": "Não é possível se conectar ao servidor remoto",
"syncjob_EXIT_AUTHENTICATION_FAILURE_USER1": "Nome de usuário ou senha incorretos",
"table_size": "Tamanho da mesa",
@@ -922,7 +925,7 @@
"yes": "✓"
},
"oauth2": {
"access_denied": "Faça login como proprietário da caixa de correio para conceder acesso via OAuth2.",
"access_denied": "Faça login como proprietário da mailbox para conceder acesso via OAuth2.",
"authorize_app": "Autorizar aplicativo",
"deny": "Negar",
"permit": "Autorizar aplicativo",
@@ -938,7 +941,7 @@
"confirm_delete": "Confirme a exclusão desse elemento.",
"danger": "Perigo",
"deliver_inbox": "Entregar na caixa de entrada",
"disabled_by_config": "A configuração atual do sistema desativa a funcionalidade de quarentena. Defina “retenções por caixa de correio” e um “tamanho máximo” para os elementos de quarentena.",
"disabled_by_config": "A configuração atual do sistema desativa a funcionalidade de quarentena. Defina “retenções por mailbox” e um “tamanho máximo” para os elementos de quarentena.",
"download_eml": "Baixar (.eml)",
"empty": "Sem resultados",
"high_danger": "Alto",
@@ -951,7 +954,7 @@
"notified": "Notificado",
"qhandler_success": "Solicitação enviada com sucesso para o sistema. Agora você pode fechar a janela.",
"qid": "Respand AID",
"qinfo": "O sistema de quarentena salvará as mensagens rejeitadas no banco de dados (o remetente <em>não</em> terá a impressão de uma mensagem entregue), bem como as mensagens, que são entregues como cópia na pasta Lixo eletrônico de uma caixa de correio.\r\n <br>“Aprenda como spam e exclua” aprenderá uma mensagem como spam por meio do teorema bayesiano e também calculará hashes difusos para negar mensagens semelhantes no futuro.\r\n <br>Esteja ciente de que aprender várias mensagens pode ser demorado, dependendo do seu sistema. <br>Os elementos da lista negra são excluídos da quarentena.",
"qinfo": "O sistema de quarentena salvará as mensagens rejeitadas no banco de dados (o remetente <em>não</em> terá a impressão de uma mensagem entregue), bem como as mensagens, que são entregues como cópia na pasta Lixo eletrônico de uma mailbox.\n <br>“Aprenda como spam e exclua” aprenderá uma mensagem como spam por meio do Teorema de Bayes e também calculará hashes difusos para negar mensagens semelhantes no futuro.\n <br>Esteja ciente de que aprender várias mensagens pode ser demorado, dependendo do seu sistema. <br>Os elementos da lista negra são excluídos da quarentena.",
"qitem": "Item de quarentena",
"quarantine": "Quarentena",
"quick_actions": "Ações",
@@ -1010,7 +1013,7 @@
"help": "Mostrar/ocultar painel de ajuda",
"imap_smtp_server_auth_info": "Use seu endereço de e-mail completo e o mecanismo de autenticação PLAIN. <br>\r\nSeus dados de login serão criptografados pela criptografia obrigatória do lado do servidor.",
"mailcow_apps_detail": "Use um aplicativo mailcow para acessar seus e-mails, calendário, contatos e muito mais.",
"mailcow_panel_detail": "<b>Os administradores de domínio</b> criam, modificam ou excluem caixas de correio e aliases, alteram domínios e leem mais informações sobre seus domínios atribuídos. <br>\r\n<b>Os usuários de caixas de correio</b> podem criar aliases com limite de tempo (aliases de spam), alterar suas configurações de senha e filtro de spam."
"mailcow_panel_detail": "<b>Os administradores de domínio</b> criam, modificam ou excluem mailboxes e aliases, alteram domínios e leem mais informações sobre seus domínios atribuídos. <br>\n<b>Os usuários de mailbox </b> podem criar aliases com limite de tempo (aliases de spam), alterar suas configurações de senha e filtro de spam."
},
"success": {
"acl_saved": "ACL para o objeto %s salvo",
@@ -1062,9 +1065,9 @@
"learned_ham": "Identificação %s como ham aprendida com sucesso",
"license_modified": "As alterações na licença foram salvas",
"logged_in_as": "Conectado como %s",
"mailbox_added": "A caixa de correio %s foi adicionada",
"mailbox_modified": "As alterações na caixa de correio %s foram salvas",
"mailbox_removed": "A caixa de correio %s foi removida",
"mailbox_added": "A mailbox %s foi adicionada",
"mailbox_modified": "As alterações na mailbox %s foram salvas",
"mailbox_removed": "A mailbox %s foi removida",
"nginx_reloaded": "O Nginx foi recarregado",
"object_modified": "As alterações no objeto %s foram salvas",
"password_policy_saved": "A política de senha foi salva com sucesso",
@@ -1077,7 +1080,7 @@
"relayhost_removed": "A entrada de mapa %s foi removida",
"reset_main_logo": "Redefinir para o logotipo padrão",
"resource_added": "O recurso %s foi adicionado",
"resource_modified": "As alterações na caixa de correio %s foram salvas",
"resource_modified": "As alterações na mailbox %s foram salvas",
"resource_removed": "O recurso %s foi removido",
"rl_saved": "Limite de taxa para o objeto %s salvo",
"rspamd_ui_pw_set": "Senha do Rspamd UI definida com sucesso",
@@ -1123,14 +1126,15 @@
"webauthn": "Autenticação WebAuthn",
"waiting_usb_auth": "<i>Aguardando o dispositivo USB...</i> <br><br>Toque no botão no seu dispositivo USB agora.",
"waiting_usb_register": "<i>Aguardando o dispositivo USB...</i> <br><br>Digite sua senha acima e confirme seu registro tocando no botão no seu dispositivo USB.",
"yubi_otp": "Autenticação Yubico OTP"
"yubi_otp": "Autenticação Yubico OTP",
"authenticators": "Autenticadores"
},
"user": {
"action": "Ação",
"active": "Ativo",
"active_sieve": "Filtro ativo",
"advanced_settings": "Configurações avançadas",
"alias": "Pseudônimo",
"alias": "Alias",
"alias_create_random": "Gere um alias aleatório",
"alias_extend_all": "Estenda os aliases em 1 hora",
"alias_full_date": "D.M.Y., H: S T",
@@ -1147,7 +1151,7 @@
"apple_connection_profile": "Perfil de conexão da Apple",
"apple_connection_profile_complete": "Esse perfil de conexão inclui parâmetros IMAP e SMTP, bem como caminhos CalDAV (calendários) e CardDAV (contatos) para um dispositivo Apple.",
"apple_connection_profile_mailonly": "Esse perfil de conexão inclui parâmetros de configuração IMAP e SMTP para um dispositivo Apple.",
"apple_connection_profile_with_app_password": "Uma nova senha de aplicativo é gerada e adicionada ao perfil para que nenhuma senha precise ser inserida ao configurar seu dispositivo. Não compartilhe o arquivo, pois ele concede acesso total à sua caixa de correio.",
"apple_connection_profile_with_app_password": "Uma nova senha de aplicativo é gerada e adicionada ao perfil para que nenhuma senha precise ser inserida ao configurar seu dispositivo. Não compartilhe o arquivo, pois ele concede acesso total à sua mailbox.",
"change_password": "Alterar senha",
"change_password_hint_app_passwords": "Sua conta tem %d senhas de aplicativos que não serão alteradas. Para gerenciá-las, acesse a guia Senhas do aplicativo.",
"clear_recent_successful_connections": "Conexões bem-sucedidas e claras",
@@ -1160,7 +1164,7 @@
"delete_ays": "Confirme o processo de exclusão.",
"direct_aliases": "Endereços de alias diretos",
"direct_aliases_desc": "Os endereços de alias diretos são afetados pelo filtro de spam e pelas configurações da política TLS.",
"direct_protocol_access": "Esse usuário da caixa de correio tem <b>acesso externo direto</b> aos seguintes protocolos e aplicativos. Essa configuração é controlada pelo administrador. As senhas de aplicativos podem ser criadas para conceder acesso a protocolos e aplicativos individuais. <br>O botão “Login no webmail” fornece login único no SoGo e está sempre disponível.",
"direct_protocol_access": "Esse usuário da mailbox tem <b>acesso externo direto</b> aos seguintes protocolos e aplicativos. Essa configuração é controlada pelo administrador. As senhas de aplicativos podem ser criadas para conceder acesso a protocolos e aplicativos individuais. <br>O botão “Login no webmail” fornece login único no SoGo e está sempre disponível.",
"eas_reset": "Redefinir o cache do dispositivo ActiveSync",
"eas_reset_help": "Em muitos casos, uma redefinição do cache do dispositivo ajudará a recuperar um perfil quebrado do ActiveSync. <br><b>Atenção:</b> Todos os elementos serão baixados novamente!",
"eas_reset_now": "Reinicie agora",
@@ -1187,7 +1191,7 @@
"last_ui_login": "Último login na interface do usuário",
"loading": "Carregando...",
"login_history": "Histórico de login",
"mailbox": "Caixa de correio",
"mailbox": "Mailbox",
"mailbox_details": "Detalhes",
"mailbox_general": "Geral",
"mailbox_settings": "Configurações",
@@ -1239,7 +1243,7 @@
"spamfilter": "Filtro de spam",
"spamfilter_behavior": "Avaliação",
"spamfilter_bl": "Lista negra",
"spamfilter_bl_desc": "Endereços de e-mail na lista negra para <b>sempre</b> serem classificados como spam e rejeitados. E-mails rejeitados <b>não</b> serão copiados para a quarentena. Podem ser usados curingas. Um filtro só é aplicado a aliases diretos (aliases com uma única caixa de correio de destino), excluindo aliases abrangentes e a própria caixa de correio.",
"spamfilter_bl_desc": "Endereços de e-mail na lista negra para <b>sempre</b> serem classificados como spam e rejeitados. E-mails rejeitados <b>não</b> serão copiados para a quarentena. Podem ser usados curingas. Um filtro só é aplicado a aliases diretos (aliases com uma única caixa de correio de destino), excluindo aliases abrangentes e a própria mailbox.",
"spamfilter_default_score": "Valores padrão",
"spamfilter_green": "Verde: esta mensagem não é spam",
"spamfilter_hint": "O primeiro valor descreve a “pontuação baixa de spam”, o segundo representa a “alta pontuação de spam”.",
@@ -1251,7 +1255,7 @@
"spamfilter_table_remove": "remover",
"spamfilter_table_rule": "Regra",
"spamfilter_wl": "Lista branca",
"spamfilter_wl_desc": "Os endereços de e-mail incluídos na lista branca são programados para <b>nunca</b> serem classificados como spam. Podem ser usados curingas. Um filtro só é aplicado a aliases diretos (aliases com uma única caixa de correio de destino), excluindo aliases abrangentes e a própria caixa de correio.",
"spamfilter_wl_desc": "Os endereços de e-mail incluídos na lista branca são programados para <b>nunca</b> serem classificados como spam. Podem ser usados curingas. Um filtro só é aplicado a aliases diretos (aliases com uma única mailbox de destino), excluindo aliases abrangentes e a própria mailbox.",
"spamfilter_yellow": "Amarelo: esta mensagem pode ser spam, será marcada como spam e movida para sua pasta de lixo eletrônico",
"status": "Status",
"sync_jobs": "Trabalhos de sincronização",
@@ -1261,7 +1265,7 @@
"syncjob_EXIT_CONNECTION_FAILURE": "Problema de conexão",
"syncjob_EXIT_TLS_FAILURE": "Problema com conexão criptografada",
"syncjob_EXIT_AUTHENTICATION_FAILURE": "Problema de autenticação",
"syncjob_EXIT_OVERQUOTA": "A caixa de correio de destino está acima da cota",
"syncjob_EXIT_OVERQUOTA": "A mailbox de destino está acima da cota",
"syncjob_EXIT_CONNECTION_FAILURE_HOST1": "Não é possível se conectar ao servidor remoto",
"syncjob_EXIT_AUTHENTICATION_FAILURE_USER1": "Nome de usuário ou senha incorretos",
"tag_handling": "Definir o tratamento para e-mails marcados",
@@ -1275,7 +1279,7 @@
"tls_enforce_in": "Imponha a entrada de TLS",
"tls_enforce_out": "Imponha a saída TLS",
"tls_policy": "Política de criptografia",
"tls_policy_warning": "<strong>Aviso:</strong> Se você decidir impor a transferência de e-mail criptografada, poderá perder e-mails. <br>As mensagens que não satisfizerem a política serão devolvidas com uma falha grave pelo sistema de correio. <br>Essa opção se aplica ao seu endereço de e-mail principal (nome de login), a todos os endereços derivados de domínios de alias, bem como aos endereços de alias <b>com apenas essa única caixa de correio</b> como destino.",
"tls_policy_warning": "<strong>Aviso:</strong> Se você decidir impor a transferência de e-mail criptografada, poderá perder e-mails. <br>As mensagens que não satisfizerem a política serão devolvidas com uma falha grave pelo sistema de correio. <br>Essa opção se aplica ao seu endereço de e-mail principal (nome de login), a todos os endereços derivados de domínios de alias, bem como aos endereços de alias <b>com apenas essa única mailbox </b> como destino.",
"user_settings": "Configurações do usuário",
"username": "Nome de usuário",
"verify": "Verificar",
@@ -1298,7 +1302,7 @@
"ip_invalid": "IP inválido ignorado: %s",
"is_not_primary_alias": "Alias não primário ignorado %s",
"no_active_admin": "Não é possível desativar o último administrador ativo",
"quota_exceeded_scope": "Cota de domínio excedida: somente caixas de correio ilimitadas podem ser criadas nesse escopo de domínio.",
"quota_exceeded_scope": "Cota de domínio excedida: somente mailboxes ilimitadas podem ser criadas nesse escopo de domínio.",
"session_token": "Token de formulário inválido: incompatibilidade de token",
"session_ua": "Token de formulário inválido: erro de validação do agente de usuário"
}

File diff suppressed because it is too large Load Diff

View File

@@ -107,7 +107,8 @@
"username": "Nume de utilizator",
"validate": "Validează",
"validation_success": "Validat cu succes",
"tags": "Etichete"
"tags": "Etichete",
"dry": ""
},
"admin": {
"access": "Acces",
@@ -343,7 +344,14 @@
"ip_check_disabled": "Verificarea IP este dezactivată. Puteţi activa la<br> <strong>Sistem > Configuraţie > Opţiuni > Personalizează</strong>",
"ip_check_opt_in": "Alegeţi să folosiţi servicile <strong>ipv4.mailcow.email</strong> şi <strong>ipv6.mailcow.email</strong> să rezolvaţi addrese IP externale.",
"options": "Opţiuni",
"queue_unban": "retractează interzicere"
"queue_unban": "retractează interzicere",
"logo_normal_label": "",
"logo_dark_label": "",
"allowed_methods": "",
"copy_to_clipboard": "",
"f2b_manage_external": "",
"f2b_manage_external_info": "",
"allowed_origins": ""
},
"danger": {
"access_denied": "Accesul a fost respins sau datele formularului sunt invalide",
@@ -471,7 +479,10 @@
"extended_sender_acl_denied": "lipseşte ACL pentru setarea adrese externe",
"template_exists": "Şablon %s deja există",
"template_id_invalid": "Şablon ID %s este invalid",
"template_name_invalid": "Nume de şablon este invalid"
"template_name_invalid": "Nume de şablon este invalid",
"cors_invalid_origin": "",
"img_dimensions_exceeded": "",
"img_size_exceeded": ""
},
"debug": {
"chart_this_server": "Grafic (acest server)",
@@ -498,13 +509,27 @@
"success": "Succes",
"system_containers": "Sistem și Containere",
"uptime": "Timp de funcționare",
"username": "Utilizator"
"username": "Utilizator",
"architecture": "",
"container_running": "",
"show_ip": "",
"wip": "",
"error_show_ip": "",
"memory": "",
"timezone": "",
"update_available": "",
"no_update_available": "",
"update_failed": "",
"container_disabled": "",
"container_stopped": "",
"cores": "",
"current_time": ""
},
"diagnostics": {
"cname_from_a": "Valoare derivată din înregistrarea A/AAAA. Acest lucru este acceptat atâta timp cât înregistrarea indică resursele corecte.",
"dns_records": "Înregistrări DNS",
"dns_records_24hours": "Rețineți că modificările aduse DNS-ului pot dura până la 24 de ore pentru a reflecta corect starea lor curentă pe această pagină. Acest mecanism este conceput ca o modalitate să vezi ușor cum să îți configurezi înregistrările DNS și să verifici dacă toate înregistrările sunt stocate corect în DNS.",
"dns_records_docs": "Vă rugăm să consultați și <a target=\"_blank\" href=\"https://docs.mailcow.email/prerequisite/prerequisite-dns/\">documentația</a>.",
"dns_records_docs": "Vă rugăm să consultați și <a target=\"_blank\" href=\"https://docs.mailcow.email/getstarted/prerequisite-dns\">documentația</a>.",
"dns_records_data": "Date corecte",
"dns_records_name": "Nume",
"dns_records_status": "Stare curentă",
@@ -624,7 +649,23 @@
"title": "Editează obiectul",
"unchanged_if_empty": "Dacă rămâne neschimbat se lasă necompletat",
"username": "Nume de utilizator",
"validate_save": "Validează și salvează"
"validate_save": "Validează și salvează",
"footer_exclude": "",
"domain_footer_skip_replies": "",
"custom_attributes": "",
"domain_footer_info_vars": {
"custom": "",
"auth_user": "",
"from_user": "",
"from_name": "",
"from_addr": "",
"from_domain": ""
},
"domain_footer": "",
"domain_footer_html": "",
"domain_footer_info": "",
"domain_footer_plain": "",
"pushover_sound": ""
},
"fido2": {
"set_fn": "Setați un nume prietenos",
@@ -665,7 +706,8 @@
"quarantine": "Carantină",
"restart_netfilter": "Repornire netfilter",
"restart_sogo": "Repornire SOGo",
"user_settings": "Setări utilizator"
"user_settings": "Setări utilizator",
"mailcow_system": ""
},
"info": {
"awaiting_tfa_confirmation": "În așteptarea confirmării TFA",
@@ -848,7 +890,13 @@
"username": "Nume de utilizator",
"waiting": "Aşteptare",
"weekly": "Săptămânal",
"yes": "&#10003;"
"yes": "&#10003;",
"mailbox_templates": "",
"template": "",
"templates": "",
"add_template": "",
"domain_templates": "",
"relay_unknown": ""
},
"oauth2": {
"access_denied": "Conectează-te ca proprietar al cutiei poștale pentru a acorda acces prin OAuth2.",
@@ -913,7 +961,20 @@
"toggle_all": "Comută toate"
},
"queue": {
"queue_manager": "Manager de coadă"
"queue_manager": "Manager de coadă",
"deliver_mail_legend": "",
"hold_mail": "",
"hold_mail_legend": "",
"show_message": "",
"unban": "",
"unhold_mail": "",
"unhold_mail_legend": "",
"delete": "",
"flush": "",
"ays": "",
"deliver_mail": "",
"info": "",
"legend": ""
},
"ratelimit": {
"disabled": "Dezactivat",
@@ -1005,7 +1066,14 @@
"verified_webauthn_login": "Autentificarea WebAuthn verificată",
"verified_fido2_login": "Conectare FIDO2 verificată",
"verified_yotp_login": "Autentificarea Yubico OTP verificată",
"domain_add_dkim_available": "O cheie DKIM deja a existat"
"domain_add_dkim_available": "O cheie DKIM deja a existat",
"domain_footer_modified": "",
"f2b_banlist_refreshed": "",
"ip_check_opt_in_modified": "",
"cors_headers_edited": "",
"template_added": "",
"template_modified": "",
"template_removed": ""
},
"tfa": {
"api_register": "%s utilizează API-ul Yubico Cloud. Obțineți o cheie API pentru cheia dvs. de <a href=\"https://upgrade.yubico.com/getapikey/\" target=\"_blank\">aici</a>",
@@ -1030,7 +1098,10 @@
"webauthn": "Autentificare WebAuthn",
"waiting_usb_auth": "<i>În așteptarea dispozitivului USB...</i><br><br>Apasă acum butonul de pe dispozitivul tău USB WebAuthn.",
"waiting_usb_register": "<i>În așteptarea dispozitivului USB...</i><br><br>Introdu parola ta mai sus și confirmă înregistrarea ta WebAuthn atingând butonul de pe dispozitivul tău USB WebAuthn.",
"yubi_otp": "Autentificare Yubico OTP"
"yubi_otp": "Autentificare Yubico OTP",
"authenticators": "",
"u2f_deprecated_important": "",
"u2f_deprecated": ""
},
"user": {
"action": "Acțiune",
@@ -1191,7 +1262,10 @@
"weeks": "săptămâni",
"with_app_password": "cu parola aplicație",
"year": "an",
"years": "ani"
"years": "ani",
"attribute": "",
"pushover_sound": "",
"value": ""
},
"warning": {
"cannot_delete_self": "Nu se poate șterge utilizatorul conectat",
@@ -1208,6 +1282,28 @@
},
"datatables": {
"expand_all": "Expandează tot",
"decimal": ","
"decimal": ",",
"infoPostFix": "",
"emptyTable": "",
"thousands": "",
"info": "",
"infoEmpty": "",
"infoFiltered": "",
"lengthMenu": "",
"loadingRecords": "",
"processing": "",
"search": "",
"zeroRecords": "",
"paginate": {
"first": "",
"last": "",
"next": "",
"previous": ""
},
"aria": {
"sortAscending": "",
"sortDescending": ""
},
"collapse_all": ""
}
}

View File

@@ -348,7 +348,10 @@
"ip_check_opt_in": "Согласие на использование сторонних служб <strong>ipv4.mailcow.email</strong> и <strong>ipv6.mailcow.email</strong> для разрешения внешних IP-адресов.",
"f2b_manage_external": "Внешнее управление Fail2Ban",
"f2b_manage_external_info": "Fail2ban по-прежнему будет вести банлист, но не будет активно устанавливать правила для блокировки трафика. Используйте сгенерированный ниже банлист для внешнего блокирования трафика.",
"copy_to_clipboard": "Текст скопирован в буфер обмена!"
"copy_to_clipboard": "Текст скопирован в буфер обмена!",
"logo_normal_label": "",
"logo_dark_label": "",
"options": ""
},
"danger": {
"access_denied": "Доступ запрещён, или указаны неверные данные",
@@ -470,7 +473,16 @@
"yotp_verification_failed": "Ошибка валидации Yubico OTP: %s",
"cors_invalid_method": "Указан недопустимый метод разрешения",
"demo_mode_enabled": "Демонстрационный режим включен",
"cors_invalid_origin": "Указан неверный Allow-Origin"
"cors_invalid_origin": "Указан неверный Allow-Origin",
"webauthn_authenticator_failed": "",
"img_dimensions_exceeded": "",
"img_size_exceeded": "",
"webauthn_publickey_failed": "",
"webauthn_username_failed": "",
"extended_sender_acl_denied": "",
"template_exists": "",
"template_id_invalid": "",
"template_name_invalid": ""
},
"debug": {
"chart_this_server": "Диаграмма (текущий сервер)",
@@ -497,14 +509,28 @@
"success": "Успех",
"system_containers": "Система и контейнеры",
"uptime": "Время работы",
"username": "Имя пользователя"
"username": "Имя пользователя",
"wip": "",
"architecture": "",
"container_running": "",
"container_disabled": "",
"container_stopped": "",
"cores": "",
"current_time": "",
"error_show_ip": "",
"memory": "",
"show_ip": "",
"timezone": "",
"update_available": "",
"no_update_available": "",
"update_failed": ""
},
"diagnostics": {
"cname_from_a": "Значение, полученное из записи A/AAAA. Это поддерживается до тех пор, пока запись указывает на правильный ресурс.",
"dns_records": "Записи DNS",
"dns_records_24hours": "Обратите внимание, что для внесения изменений в DNS может потребоваться до 24 часов, чтобы правильно отобразить их текущее состояние на этой странице. Эта страница предназначен для того, чтобы вы могли легко увидеть, как настроить записи DNS и проверить, все ли записи правильно занесены в DNS.",
"dns_records_data": "Значение",
"dns_records_docs": "Пожалуйста, ознакомьтесь с <a target=\"_blank\" href=\"https://docs.mailcow.email/prerequisite/prerequisite-dns/\">документацией</a>.",
"dns_records_docs": "Пожалуйста, ознакомьтесь с <a target=\"_blank\" href=\"https://docs.mailcow.email/getstarted/prerequisite-dns\">документацией</a>.",
"dns_records_name": "Название",
"dns_records_status": "Статус",
"dns_records_type": "Тип",
@@ -546,6 +572,7 @@
"extended_sender_acl_info": "Для внешних доменов должен быть импортирован или сгенерирован доменный ключ DKIM с соответствующей записью TXT в домене, если внешний домен использует DMARC.<br>\r\n Не забудьте добавить этот сервер к соответствующей записи SPF TXT внешнего домена.<br>\r\n Добавление домена из списка внешних адресов в mailcow автоматически удалит соответствующие записи из внешних адресов пользователей.<br>\r\n Чтобы разрешить пользователю отправку от имени *@domain.tld, укажите @domain.tld.",
"force_pw_update": "Требовать смены пароля при следующем входе в систему",
"force_pw_update_info": "Пользователь должен будет войти в %s и сменить свой пароль. mailcow OAuth2, SOGo, EAS, IMAP/POP3 и SMTP будут не доступны до смены пароля.",
"footer_exclude": "Исключить из нижнего колонтитула",
"full_name": "Полное имя",
"gal": "GAL - Глобальная адресная книга",
"gal_info": "GAL содержит все объекты домена и не подлежит редактированию. Информация о занятости в SOGo будет отсутствовать для домена, если данная функция будет отключена! <b>Требуется перезапустить SOGo, чтобы применить изменения.</b>",
@@ -635,8 +662,10 @@
"domain_footer": "Нижний колонтитул домена",
"domain_footer_html": "HTML нижний колонтитул",
"domain_footer_plain": "ПРОСТОЙ нижний колонтитул",
"mbox_exclude": "Исключить почтовые ящики",
"custom_attributes": "Пользовательские атрибуты"
"custom_attributes": "Пользовательские атрибуты",
"domain_footer_skip_replies": "",
"pushover_sound": "",
"sogo_access": ""
},
"fido2": {
"confirm": "Подтвердить",
@@ -677,7 +706,8 @@
"quarantine": "Карантин",
"restart_netfilter": "Перезапустить netfilter",
"restart_sogo": "Перезапустить SOGo",
"user_settings": "Настройки пользователя"
"user_settings": "Настройки пользователя",
"mailcow_system": ""
},
"info": {
"awaiting_tfa_confirmation": "В ожидании подтверждения TFA",
@@ -860,7 +890,13 @@
"username": "Имя пользователя",
"waiting": "В ожидании",
"weekly": "Раз в неделю",
"yes": "&#10003;"
"yes": "&#10003;",
"domain_templates": "",
"add_template": "",
"mailbox_templates": "",
"relay_unknown": "",
"templates": "",
"template": ""
},
"oauth2": {
"access_denied": "Пожалуйста, войдите в систему как владелец почтового аккаунта, чтобы получить доступ через OAuth2.",
@@ -925,7 +961,20 @@
"type": "Тип"
},
"queue": {
"queue_manager": "Очередь на отправку"
"queue_manager": "Очередь на отправку",
"delete": "",
"info": "",
"unhold_mail_legend": "",
"flush": "",
"legend": "",
"ays": "",
"deliver_mail": "",
"deliver_mail_legend": "",
"hold_mail": "",
"hold_mail_legend": "",
"show_message": "",
"unban": "",
"unhold_mail": ""
},
"ratelimit": {
"disabled": "Отключен",
@@ -1019,7 +1068,12 @@
"verified_yotp_login": "Авторизация Yubico OTP пройдена",
"cors_headers_edited": "Настройки CORS сохранены",
"domain_footer_modified": "Изменения в нижнем колонтитуле домена %s сохранены",
"f2b_banlist_refreshed": "Идентификатор банлиста был успешно обновлен."
"f2b_banlist_refreshed": "Идентификатор банлиста был успешно обновлен.",
"domain_add_dkim_available": "",
"ip_check_opt_in_modified": "",
"template_added": "",
"template_modified": "",
"template_removed": ""
},
"tfa": {
"api_register": "%s использует Yubico Cloud API. Пожалуйста, получите ключ API для вашего ключа <a href=\"https://upgrade.yubico.com/getapikey/\" target=\"_blank\">здесь</a>",
@@ -1045,7 +1099,9 @@
"waiting_usb_auth": "<i>Ожидание устройства USB...</i><br><br>Пожалуйста, нажмите кнопку на USB устройстве сейчас.",
"waiting_usb_register": "<i>Ожидание устройства USB...</i><br><br>Пожалуйста, введите пароль выше и подтвердите регистрацию, нажав кнопку на USB устройстве.",
"yubi_otp": "Yubico OTP аутентификация",
"u2f_deprecated": "Похоже, что ваш ключ был зарегистрирован с использованием устаревшего метода U2F. Мы деактивируем для вас двухфакторную аутентификацию и удалим ваш ключ."
"u2f_deprecated": "Похоже, что ваш ключ был зарегистрирован с использованием устаревшего метода U2F. Мы деактивируем для вас двухфакторную аутентификацию и удалим ваш ключ.",
"authenticators": "",
"u2f_deprecated_important": ""
},
"user": {
"action": "Действия",
@@ -1208,7 +1264,8 @@
"with_app_password": "с паролем приложения",
"change_password_hint_app_passwords": "В вашей учетной записи есть {{number_of_app_passwords}} паролей приложений, которые не будут изменены. Чтобы управлять ими, перейдите на вкладку \"Пароли приложений\".",
"attribute": "Атрибут",
"value": "Значение"
"value": "Значение",
"pushover_sound": ""
},
"warning": {
"cannot_delete_self": "Вы не можете удалить сами себя",
@@ -1224,6 +1281,29 @@
"session_ua": "Неверный токен формы: ошибка проверки User-Agent"
},
"datatables": {
"infoPostFix": ""
"collapse_all": "Свернуть все",
"expand_all": "Развернуть все",
"infoPostFix": "",
"decimal": "",
"thousands": "",
"lengthMenu": "",
"loadingRecords": "",
"processing": "",
"search": "",
"zeroRecords": "",
"paginate": {
"last": "",
"first": "",
"next": "",
"previous": ""
},
"aria": {
"sortAscending": "",
"sortDescending": ""
},
"emptyTable": "",
"info": "",
"infoEmpty": "",
"infoFiltered": ""
}
}

View File

@@ -107,7 +107,8 @@
"post_domain_add": "SOGo container \"sogo-mailcow\" mora biti ponovno zagnan po dodajanju nove domene!<br><br>Dodatno se mora preveriti DNS konfiguracija domene. Ko je DNS konfiguracija domene odobrena, ponovno zaženite \"acme-mailcow\" za samodejno generiranje certifikatov za novo domeno (autoconfig.&lt;domain&gt;, autodiscover.&lt;domain&gt;).<br>Ta korak je opcijski in se ponovno poskuša vsakih 24 ur.",
"relay_transport_info": "<div class=\"badge fs-6 bg-info\">Info</div> Definirate lahko preslikave transportov za cilj po meri za to domeno. Če ni nastavljena, se ustvari MX poizvedba.",
"syncjob_hint": "Pozor! Gesla se morajo shraniti v plain-text!",
"timeout2": "Časovna omejitev za povezavo do lokalnega gostitelja"
"timeout2": "Časovna omejitev za povezavo do lokalnega gostitelja",
"dry": ""
},
"admin": {
"access": "Dostop",
@@ -347,7 +348,10 @@
"logo_dark_label": "Za temni način",
"cors_settings": "Nastavitve CORS",
"allowed_methods": "Dovoljene metode za upravljanje dostopa",
"allowed_origins": "Upravljanje-dostopa-Dovoljeni-Viri"
"allowed_origins": "Upravljanje-dostopa-Dovoljeni-Viri",
"copy_to_clipboard": "",
"f2b_manage_external": "",
"f2b_manage_external_info": ""
},
"danger": {
"alias_goto_identical": "Alias in goto naslov morata biti identična",
@@ -476,7 +480,9 @@
"temp_error": "Začasna napaka",
"cors_invalid_method": "Navedena neveljavna Allow metoda",
"cors_invalid_origin": "Naveden neveljaven Allow-Origin",
"invalid_recipient_map_new": "Naveden neveljaven nov prejemnik: %s"
"invalid_recipient_map_new": "Naveden neveljaven nov prejemnik: %s",
"img_dimensions_exceeded": "",
"img_size_exceeded": ""
},
"debug": {
"containers_info": "Informacije o vsebniku (containerju)",
@@ -511,7 +517,13 @@
"no_update_available": "Sistem je na najnovejši verziji",
"update_failed": "Ni mogoče preveriti za posodobitve",
"username": "Uporabniško ime",
"wip": "Trenutno v delu"
"wip": "Trenutno v delu",
"log_info": "",
"login_time": "",
"logs": "",
"memory": "",
"online_users": "",
"restart_container": ""
},
"datatables": {
"infoFiltered": "(filtrirano od _MAX_ skupaj zapisov)",
@@ -536,14 +548,15 @@
"aria": {
"sortAscending": ": aktivirajte za razvrstitev stolpca naraščajoče",
"sortDescending": ": aktivirajte za razvrstitev stolpca padajoče"
}
},
"infoPostFix": ""
},
"diagnostics": {
"cname_from_a": "Vrednost pridobljena iz A/AAAA zapisa. To je podprto, če zapis kaže na pravilen resurs.",
"dns_records": "DNS zapisi",
"dns_records_24hours": "Prosim upoštevajte, da lahko traja do 24 ur da se spremembe v DNS pravilno prikažejo na tej strani. Namen je da lahko enostavno vidite, kako konfigurirati svoje DNS zapise in preverite ali so vaši zapisi pravilno shranjeni v DNS.",
"dns_records_data": "Pravilni podatki",
"dns_records_docs": "Prosim preverite tudi <a target=\"_blank\" href=\"https://docs.mailcow.email/prerequisite/prerequisite-dns/\">dokumentacijo</a>.",
"dns_records_docs": "Prosim preverite tudi <a target=\"_blank\" href=\"https://docs.mailcow.email/getstarted/prerequisite-dns\">dokumentacijo</a>.",
"dns_records_name": "Ime",
"dns_records_status": "Trenutno stanje",
"dns_records_type": "Vrsta",
@@ -551,6 +564,746 @@
},
"edit": {
"acl": "ACL (Dovoljenje)",
"active": "Aktivno"
"active": "Aktivno",
"maxbytespersecond": "",
"footer_exclude": "",
"gal_info": "",
"inactive": "",
"kind": "",
"last_modified": "",
"lookup_mx": "",
"mailbox": "",
"mailbox_quota_def": "",
"mailbox_relayhost_info": "",
"maxage": "",
"mins_interval": "",
"domain_quota": "",
"spam_alias": "",
"gal": "",
"domain_footer_skip_replies": "",
"domains": "",
"dont_check_sender_acl": "",
"full_name": "",
"edit_alias_domain": "",
"encryption": "",
"exclude": "",
"extended_sender_acl": "",
"pushover_evaluate_x_prio": "",
"pushover_info": "",
"pushover": "",
"pushover_only_x_prio": "",
"pushover_sender_array": "",
"spam_filter": "",
"skipcrossduplicates": "",
"sogo_access": "",
"sogo_access_info": "",
"sogo_visible": "",
"sogo_visible_info": "",
"spam_policy": "",
"spam_score": "",
"subfolder2": "",
"syncjob": "",
"target_address": "",
"title": "",
"username": "",
"app_name": "",
"custom_attributes": "",
"delete2": "",
"delete2duplicates": "",
"generate": "",
"grant_types": "",
"redirect_uri": "",
"domain_footer_plain": "",
"extended_sender_acl_info": "",
"force_pw_update": "",
"force_pw_update_info": "",
"mbox_rl_info": "",
"multiple_bookings": "",
"none_inherit": "",
"nexthop": "",
"password": "",
"domain_footer": "",
"domain_footer_html": "",
"pushover_sender_regex": "",
"alias": "",
"max_aliases": "",
"max_mailboxes": "",
"max_quota": "",
"admin": "",
"advanced_settings": "",
"allow_from_smtp": "",
"allow_from_smtp_info": "",
"allowed_protocols": "",
"app_passwd": "",
"app_passwd_protocols": "",
"automap": "",
"backup_mx_options": "",
"bcc_dest_format": "",
"client_id": "",
"client_secret": "",
"comment_info": "",
"created_on": "",
"delete1": "",
"delete_ays": "",
"description": "",
"disable_login": "",
"domain": "",
"domain_admin": "",
"domain_footer_info": "",
"domain_footer_info_vars": {
"auth_user": "",
"from_user": "",
"from_name": "",
"from_addr": "",
"from_domain": "",
"custom": ""
},
"password_repeat": "",
"previous": "",
"private_comment": "",
"public_comment": "",
"pushover_text": "",
"pushover_title": "",
"pushover_sound": "",
"pushover_vars": "",
"pushover_verify": "",
"quota_mb": "",
"quota_warning_bcc": "",
"quota_warning_bcc_info": "",
"ratelimit": "",
"relay_all": "",
"relay_all_info": "",
"relay_domain": "",
"relay_transport_info": "",
"relay_unknown_only": "",
"relayhost": "",
"remove": "",
"hostname": "",
"resource": "",
"save": "",
"scope": "",
"sender_acl": "",
"sender_acl_disabled": "",
"sender_acl_info": "",
"sieve_desc": "",
"sieve_type": "",
"target_domain": "",
"timeout1": "",
"timeout2": "",
"unchanged_if_empty": "",
"validate_save": ""
},
"mailbox": {
"add_resource": "",
"domain_templates": "",
"activate": "",
"public_comment": "",
"set_prefilter": "",
"sieve_preset_5": "",
"active": "",
"add": "",
"add_alias": "",
"add_alias_expand": "",
"add_bcc_entry": "",
"bcc_destinations": "",
"bcc_local_dest": "",
"mailbox_defaults_info": "",
"mailbox_defquota": "",
"mailbox_templates": "",
"multiple_bookings": "",
"private_comment": "",
"q_add_header": "",
"q_all": "",
"q_reject": "",
"quarantine_category": "",
"quarantine_notification": "",
"quick_actions": "",
"recipient": "",
"recipient_map": "",
"recipient_map_info": "",
"recipient_map_new": "",
"recipient_map_new_info": "",
"recipient_map_old": "",
"recipient_map_old_info": "",
"recipient_maps": "",
"relay_unknown": "",
"running": "",
"sender": "",
"set_postfilter": "",
"sieve_preset_1": "",
"sieve_preset_2": "",
"sieve_info": "",
"sieve_preset_3": "",
"sieve_preset_4": "",
"sieve_preset_6": "",
"sieve_preset_7": "",
"sieve_preset_8": "",
"sogo_visible": "",
"status": "",
"target_address": "",
"target_domain": "",
"template": "",
"templates": "",
"tls_enforce_in": "",
"tls_enforce_out": "",
"tls_map_dest_info": "",
"tls_map_parameters": "",
"tls_map_policy": "",
"tls_policy_maps": "",
"tls_policy_maps_enforced_tls": "",
"tls_policy_maps_long": "",
"backup_mx": "",
"force_pw_update": "",
"gal": "",
"last_run": "",
"last_run_reset": "",
"filter_table": "",
"filters": "",
"fname": "",
"remove": "",
"tls_map_dest": "",
"add_mailbox": "",
"domain_admins": "",
"domain_aliases": "",
"edit": "",
"empty": "",
"enable_x": "",
"excludes": "",
"catch_all": "",
"no_record_single": "",
"relay_all": "",
"action": "",
"add_domain": "",
"add_domain_alias": "",
"add_domain_record_first": "",
"add_filter": "",
"add_recipient_map_entry": "",
"add_template": "",
"add_tls_policy_map": "",
"address_rewriting": "",
"alias": "",
"alias_domain_alias_hint": "",
"alias_domain_backupmx": "",
"aliases": "",
"all_domains": "",
"allow_from_smtp": "",
"allow_from_smtp_info": "",
"allowed_protocols": "",
"bcc": "",
"bcc_destination": "",
"bcc_info": "",
"bcc_map": "",
"bcc_map_type": "",
"bcc_maps": "",
"bcc_rcpt_map": "",
"bcc_sender_map": "",
"bcc_to_rcpt": "",
"bcc_to_sender": "",
"bcc_type": "",
"booking_null": "",
"booking_0_short": "",
"booking_custom": "",
"booking_custom_short": "",
"booking_ltnull": "",
"booking_lt0_short": "",
"created_on": "",
"daily": "",
"deactivate": "",
"description": "",
"disable_login": "",
"disable_x": "",
"dkim_domains_selector": "",
"dkim_key_length": "",
"domain": "",
"domain_quota": "",
"domain_quota_total": "",
"domains": "",
"goto_ham": "",
"goto_spam": "",
"hourly": "",
"in_use": "",
"inactive": "",
"insert_preset": "",
"kind": "",
"last_mail_login": "",
"last_modified": "",
"last_pw_change": "",
"mailbox": "",
"mailbox_defaults": "",
"mailbox_quota": "",
"mailboxes": "",
"max_aliases": "",
"max_mailboxes": "",
"max_quota": "",
"mins_interval": "",
"msg_num": "",
"never": "",
"no": "",
"no_record": "",
"open_logs": "",
"owner": "",
"resources": "",
"sieve_preset_header": "",
"sogo_visible_n": "",
"sogo_visible_y": "",
"spam_aliases": "",
"stats": "",
"sync_jobs": "",
"syncjob_check_log": "",
"syncjob_last_run_result": "",
"syncjob_EX_OK": "",
"syncjob_EXIT_CONNECTION_FAILURE": "",
"syncjob_EXIT_TLS_FAILURE": "",
"syncjob_EXIT_AUTHENTICATION_FAILURE": "",
"syncjob_EXIT_OVERQUOTA": "",
"syncjob_EXIT_CONNECTION_FAILURE_HOST1": "",
"syncjob_EXIT_AUTHENTICATION_FAILURE_USER1": "",
"table_size": "",
"table_size_show_n": "",
"tls_map_parameters_info": "",
"tls_policy_maps_info": "",
"toggle_all": "",
"username": "",
"waiting": "",
"weekly": "",
"yes": ""
},
"user": {
"login_history": "",
"advanced_settings": "",
"alias": "",
"alias_create_random": "",
"alias_extend_all": "",
"alias_full_date": "",
"alias_remove_all": "",
"action": "",
"active": "",
"active_sieve": "",
"alias_select_validity": "",
"alias_time_left": "",
"alias_valid_until": "",
"delete_ays": "",
"direct_aliases": "",
"email_and_dav": "",
"spamfilter_table_rule": "",
"spamfilter_wl": "",
"verify": "",
"waiting": "",
"week": "",
"weekly": "",
"month": "",
"months": "",
"sogo_profile_reset_now": "",
"spam_aliases": "",
"spam_score_reset": "",
"spamfilter": "",
"value": "",
"eas_reset_now": "",
"remove": "",
"text": "",
"no_active_filter": "",
"no_last_login": "",
"spamfilter_bl_desc": "",
"spamfilter_default_score": "",
"day": "",
"never": "",
"pushover_verify": "",
"tag_handling": "",
"edit": "",
"last_ui_login": "",
"title": "",
"tls_enforce_in": "",
"tls_enforce_out": "",
"tls_policy": "",
"tls_policy_warning": "",
"aliases_also_send_as": "",
"aliases_send_as_all": "",
"app_hint": "",
"allowed_protocols": "",
"app_name": "",
"app_passwds": "",
"apple_connection_profile": "",
"apple_connection_profile_complete": "",
"apple_connection_profile_mailonly": "",
"apple_connection_profile_with_app_password": "",
"attribute": "",
"change_password": "",
"change_password_hint_app_passwords": "",
"clear_recent_successful_connections": "",
"client_configuration": "",
"create_app_passwd": "",
"create_syncjob": "",
"created_on": "",
"daily": "",
"direct_aliases_desc": "",
"direct_protocol_access": "",
"eas_reset": "",
"eas_reset_help": "",
"email": "",
"empty": "",
"encryption": "",
"excludes": "",
"expire_in": "",
"fido2_webauthn": "",
"force_pw_update": "",
"from": "",
"generate": "",
"hour": "",
"hourly": "",
"hours": "",
"in_use": "",
"interval": "",
"is_catch_all": "",
"last_mail_login": "",
"last_pw_change": "",
"last_run": "",
"loading": "",
"mailbox": "",
"mailbox_details": "",
"mailbox_general": "",
"mailbox_settings": "",
"messages": "",
"new_password": "",
"new_password_repeat": "",
"no_record": "",
"open_logs": "",
"open_webmail_sso": "",
"password": "",
"password_now": "",
"password_repeat": "",
"pushover_evaluate_x_prio": "",
"pushover_info": "",
"pushover_only_x_prio": "",
"pushover_sender_array": "",
"pushover_sender_regex": "",
"pushover_text": "",
"pushover_title": "",
"pushover_sound": "",
"pushover_vars": "",
"q_add_header": "",
"q_all": "",
"q_reject": "",
"quarantine_category": "",
"quarantine_category_info": "",
"quarantine_notification": "",
"quarantine_notification_info": "",
"recent_successful_connections": "",
"running": "",
"save": "",
"save_changes": "",
"sender_acl_disabled": "",
"shared_aliases": "",
"shared_aliases_desc": "",
"show_sieve_filters": "",
"sogo_profile_reset": "",
"sogo_profile_reset_help": "",
"spamfilter_behavior": "",
"spamfilter_bl": "",
"spamfilter_green": "",
"spamfilter_hint": "",
"spamfilter_red": "",
"spamfilter_table_action": "",
"spamfilter_table_add": "",
"spamfilter_table_domain_policy": "",
"spamfilter_table_empty": "",
"spamfilter_table_remove": "",
"spamfilter_wl_desc": "",
"spamfilter_yellow": "",
"status": "",
"sync_jobs": "",
"syncjob_check_log": "",
"syncjob_last_run_result": "",
"syncjob_EX_OK": "",
"syncjob_EXIT_CONNECTION_FAILURE": "",
"syncjob_EXIT_TLS_FAILURE": "",
"syncjob_EXIT_AUTHENTICATION_FAILURE": "",
"syncjob_EXIT_OVERQUOTA": "",
"syncjob_EXIT_CONNECTION_FAILURE_HOST1": "",
"syncjob_EXIT_AUTHENTICATION_FAILURE_USER1": "",
"tag_help_example": "",
"tag_help_explain": "",
"tag_in_none": "",
"tag_in_subfolder": "",
"tag_in_subject": "",
"user_settings": "",
"username": "",
"weeks": "",
"with_app_password": "",
"year": "",
"years": ""
},
"fido2": {
"set_fn": "",
"rename": "",
"set_fido2": "",
"set_fido2_touchid": "",
"start_fido2_validation": "",
"confirm": "",
"fido2_auth": "",
"fido2_success": "",
"fido2_validation_failed": "",
"fn": "",
"known_ids": "",
"none": "",
"register_status": ""
},
"footer": {
"cancel": "",
"confirm_delete": "",
"delete_now": "",
"delete_these_items": "",
"hibp_check": "",
"hibp_nok": "",
"hibp_ok": "",
"loading": "",
"nothing_selected": "",
"restart_container": "",
"restart_container_info": "",
"restart_now": "",
"restarting_container": ""
},
"quarantine": {
"qid": "",
"quarantine": "",
"quick_actions": "",
"quick_delete_link": "",
"neutral_danger": "",
"qitem": "",
"download_eml": "",
"action": "",
"atts": "",
"check_hash": "",
"confirm": "",
"confirm_delete": "",
"danger": "",
"deliver_inbox": "",
"disabled_by_config": "",
"empty": "",
"high_danger": "",
"info": "",
"junk_folder": "",
"learn_spam_delete": "",
"low_danger": "",
"medium_danger": "",
"notified": "",
"qhandler_success": "",
"qinfo": "",
"quick_info_link": "",
"quick_release_link": "",
"rcpt": "",
"received": "",
"recipients": "",
"refresh": "",
"rejected": "",
"release": "",
"release_body": "",
"release_subject": "",
"remove": "",
"rewrite_subject": "",
"rspamd_result": "",
"sender": "",
"sender_header": "",
"settings_info": "",
"show_item": "",
"spam": "",
"spam_score": "",
"subj": "",
"table_size": "",
"table_size_show_n": "",
"text_from_html_content": "",
"text_plain_content": "",
"toggle_all": "",
"type": ""
},
"ratelimit": {
"minute": "",
"hour": "",
"day": "",
"disabled": "",
"second": ""
},
"start": {
"help": "",
"imap_smtp_server_auth_info": "",
"mailcow_panel_detail": "",
"mailcow_apps_detail": ""
},
"queue": {
"unhold_mail": "",
"unhold_mail_legend": "",
"delete": "",
"flush": "",
"info": "",
"legend": "",
"deliver_mail": "",
"ays": "",
"deliver_mail_legend": "",
"hold_mail": "",
"hold_mail_legend": "",
"queue_manager": "",
"show_message": "",
"unban": ""
},
"success": {
"acl_saved": "",
"admin_added": "",
"cors_headers_edited": "",
"db_init_complete": "",
"delete_filter": "",
"delete_filters": "",
"deleted_syncjob": "",
"deleted_syncjobs": "",
"dkim_added": "",
"domain_add_dkim_available": "",
"dkim_duplicated": "",
"dkim_removed": "",
"domain_added": "",
"domain_admin_removed": "",
"domain_footer_modified": "",
"domain_modified": "",
"domain_removed": "",
"dovecot_restart_success": "",
"f2b_banlist_refreshed": "",
"domain_admin_added": "",
"domain_admin_modified": "",
"f2b_modified": "",
"forwarding_host_added": "",
"resource_modified": "",
"resource_removed": "",
"rl_saved": "",
"reset_main_logo": "",
"resource_added": "",
"rspamd_ui_pw_set": "",
"saved_settings": "",
"settings_map_added": "",
"settings_map_removed": "",
"sogo_profile_reset": "",
"template_added": "",
"template_modified": "",
"template_removed": "",
"tls_policy_map_entry_deleted": "",
"eas_reset": "",
"mailbox_added": "",
"items_deleted": "",
"items_released": "",
"learned_ham": "",
"license_modified": "",
"logged_in_as": "",
"password_policy_saved": "",
"hash_deleted": "",
"app_links": "",
"admin_api_modified": "",
"admin_modified": "",
"admin_removed": "",
"alias_added": "",
"alias_domain_removed": "",
"alias_modified": "",
"alias_removed": "",
"aliasd_added": "",
"aliasd_modified": "",
"app_passwd_added": "",
"app_passwd_removed": "",
"bcc_deleted": "",
"bcc_edited": "",
"bcc_saved": "",
"forwarding_host_removed": "",
"global_filter_written": "",
"ip_check_opt_in_modified": "",
"item_deleted": "",
"item_released": "",
"mailbox_modified": "",
"mailbox_removed": "",
"nginx_reloaded": "",
"object_modified": "",
"pushover_settings_edited": "",
"qlearn_spam": "",
"queue_command_success": "",
"recipient_map_entry_deleted": "",
"recipient_map_entry_saved": "",
"relayhost_added": "",
"relayhost_removed": "",
"tls_policy_map_entry_saved": "",
"ui_texts": "",
"upload_success": "",
"verified_fido2_login": "",
"verified_totp_login": "",
"verified_webauthn_login": "",
"verified_yotp_login": ""
},
"tfa": {
"webauthn": "",
"waiting_usb_register": "",
"authenticators": "",
"api_register": "",
"confirm_totp_token": "",
"none": "",
"select": "",
"yubi_otp": "",
"waiting_usb_auth": "",
"delete_tfa": "",
"disable_tfa": "",
"enter_qr_code": "",
"error_code": "",
"init_webauthn": "",
"key_id": "",
"confirm": "",
"key_id_totp": "",
"reload_retry": "",
"scan_qr_code": "",
"set_tfa": "",
"start_webauthn_validation": "",
"tfa": "",
"tfa_token_invalid": "",
"totp": "",
"u2f_deprecated": "",
"u2f_deprecated_important": ""
},
"header": {
"debug": "",
"administration": "",
"apps": "",
"email": "",
"mailcow_system": "",
"mailcow_config": "",
"quarantine": "",
"restart_netfilter": "",
"restart_sogo": "",
"user_settings": ""
},
"warning": {
"domain_added_sogo_failed": "",
"dovecot_restart_failed": "",
"fuzzy_learn_error": "",
"hash_not_found": "",
"ip_invalid": "",
"no_active_admin": "",
"quota_exceeded_scope": "",
"session_token": "",
"session_ua": "",
"cannot_delete_self": "",
"is_not_primary_alias": ""
},
"info": {
"awaiting_tfa_confirmation": "",
"no_action": "",
"session_expires": ""
},
"login": {
"delayed": "",
"fido2_webauthn": "",
"login": "",
"mobileconfig_info": "",
"other_logins": "",
"password": "",
"username": ""
},
"oauth2": {
"access_denied": "",
"authorize_app": "",
"deny": "",
"permit": "",
"profile": "",
"profile_desc": "",
"scope_ask_permission": ""
}
}

View File

@@ -342,7 +342,16 @@
"username": "Prihlasovacie meno",
"validate_license_now": "Validovať GUID cez licenčný server",
"verify": "Kontrola",
"yes": "&#10003;"
"yes": "&#10003;",
"queue_unban": "",
"allowed_origins": "",
"cors_settings": "",
"f2b_ban_time_increment": "",
"f2b_max_ban_time": "",
"copy_to_clipboard": "",
"f2b_manage_external": "",
"f2b_manage_external_info": "",
"allowed_methods": ""
},
"danger": {
"access_denied": "Prístup zamietnutý alebo nesprávne dáta formulára",
@@ -464,7 +473,16 @@
"username_invalid": "Používateľské meno %s nemôže byť použité",
"validity_missing": "Zadajte periódu platnosti",
"value_missing": "Prosím poskytnite všetky hodnoty",
"yotp_verification_failed": "Overenie cez OTP Yubico zlyhalo: %s"
"yotp_verification_failed": "Overenie cez OTP Yubico zlyhalo: %s",
"webauthn_publickey_failed": "",
"webauthn_username_failed": "",
"webauthn_authenticator_failed": "",
"cors_invalid_method": "",
"cors_invalid_origin": "",
"demo_mode_enabled": "",
"img_dimensions_exceeded": "",
"img_size_exceeded": "",
"extended_sender_acl_denied": ""
},
"datatables": {
"info": "Záznamy _START_ až _END_ z celkom _TOTAL_",
@@ -489,7 +507,8 @@
"decimal": ",",
"thousands": " ",
"collapse_all": "Zbaliť všetko",
"expand_all": "Rozbaliť všetko"
"expand_all": "Rozbaliť všetko",
"infoPostFix": ""
},
"debug": {
"chart_this_server": "Graf (tento server)",
@@ -516,14 +535,28 @@
"success": "Úspech",
"system_containers": "Systém & Kontajnery",
"uptime": "Doba behu",
"username": "Používateľské meno"
"username": "Používateľské meno",
"architecture": "",
"error_show_ip": "",
"update_failed": "",
"show_ip": "",
"timezone": "",
"update_available": "",
"no_update_available": "",
"wip": "",
"current_time": "",
"memory": "",
"container_running": "",
"container_disabled": "",
"container_stopped": "",
"cores": ""
},
"diagnostics": {
"cname_from_a": "Hodnota odvodená od A/AAAA záznamu. Toto je podporené len v prípade ak záznam poukazuje na správny zdroj.",
"dns_records": "DNS záznamy",
"dns_records_24hours": "Berte prosím do úvahy, že zmeny v DNS môžu trvať až 24 hodín, aby sa zmeny prejavili na tejto stránke. Pre jednoduchosť DNS konfigurácie môžete použiť údaje uvedené nižšie, prípadne skontrolovať tak správnosť záznamov v DNS.",
"dns_records_data": "Správne dáta",
"dns_records_docs": "Pozrite si prosím <a target=\"_blank\" href=\"https://docs.mailcow.email/prerequisite/prerequisite-dns/\">dokumentáciu</a>.",
"dns_records_docs": "Pozrite si prosím <a target=\"_blank\" href=\"https://docs.mailcow.email/getstarted/prerequisite-dns\">dokumentáciu</a>.",
"dns_records_name": "Meno",
"dns_records_status": "Súčasný stav",
"dns_records_type": "Typ",
@@ -648,12 +681,17 @@
"from_domain": "{= from_domain =} - Doména odosielateľa",
"auth_user": "{= auth_user =} - Prihlasovacie meno odosielateľa",
"from_user": "{= from_user =} - Používateľská časť e-mailovej adresy odosielateľa, napr. pre \"moo@mailcow.tld\" vráti \"moo\"",
"from_name": "{= from_name =} - Meno odosielateľa, napr. pre \"Mailcow &lt;moo@mailcow.tld&gt;\" vráti \"Mailcow\""
"from_name": "{= from_name =} - Meno odosielateľa, napr. pre \"Mailcow &lt;moo@mailcow.tld&gt;\" vráti \"Mailcow\"",
"custom": ""
},
"domain_footer": "Pätička pre celú doménu",
"domain_footer_html": "HTML text",
"domain_footer_info": "Pätička pre celú doménu sa pridáva do všetkých odchádzajúcich e-mailov spojených s adresou v rámci tejto domény. <br> Pre pätičku je možné použiť nasledujúce premenné:",
"domain_footer_plain": "Obyčajný text"
"domain_footer_plain": "Obyčajný text",
"footer_exclude": "",
"domain_footer_skip_replies": "",
"custom_attributes": "",
"pushover_sound": ""
},
"fido2": {
"confirm": "Potvrdiť",
@@ -883,7 +921,8 @@
"username": "Používateľské meno",
"waiting": "Čakanie",
"weekly": "Týždenný",
"yes": "&#10003;"
"yes": "&#10003;",
"relay_unknown": ""
},
"oauth2": {
"access_denied": "Prosím prihláste sa ako používateľ mailovej schránky, aby ste mohli získať prístup cez OAuth2.",
@@ -960,7 +999,8 @@
"unhold_mail": "Uvoľniť",
"unhold_mail_legend": "Uvoľniť vybrané e-maily na doručenie. (Len v prípade predchádzajúceho podržania)",
"hold_mail": "Podržať",
"hold_mail_legend": "Podržať vybrané e-maily. (Zabráni ďalším pokusom o doručenie)"
"hold_mail_legend": "Podržať vybrané e-maily. (Zabráni ďalším pokusom o doručenie)",
"unban": ""
},
"ratelimit": {
"disabled": "Vypnuté",
@@ -1055,7 +1095,11 @@
"verified_totp_login": "Overené TOTP prihlásenie",
"verified_webauthn_login": "Overené WebAuthn prihlásenie",
"verified_yotp_login": "Overené Yubico OTP prihlásenie",
"domain_footer_modified": "Zmeny v pätičke domény %s boli uložené"
"domain_footer_modified": "Zmeny v pätičke domény %s boli uložené",
"cors_headers_edited": "",
"f2b_banlist_refreshed": "",
"ip_check_opt_in_modified": "",
"domain_add_dkim_available": ""
},
"tfa": {
"api_register": "%s využíva Yubico Cloud API. Prosím, zaobstarajte si API kľúč pre váš kľúč <a href=\"https://upgrade.yubico.com/getapikey/\" target=\"_blank\">tu</a>",
@@ -1082,7 +1126,8 @@
"waiting_usb_register": "<i>Čakanie na USB zariadenie...</i><br><br>Prosím zadajte vaše heslo a potvrďte registráciu stlačením tlačidla na vašom USB zariadení.",
"yubi_otp": "Yubico OTP autentifikácia",
"u2f_deprecated_important": "Zaregistrujte si svoj Kľúč v paneli správcu pomocou novej metódy WebAuthn.",
"u2f_deprecated": "Zdá sa, že váš kľúč bol zaregistrovaný pomocou zastaranej metódy U2F. Deaktivujeme vám dvojfaktorovú autentifikáciu a odstránime váš Kľúč."
"u2f_deprecated": "Zdá sa, že váš kľúč bol zaregistrovaný pomocou zastaranej metódy U2F. Deaktivujeme vám dvojfaktorovú autentifikáciu a odstránime váš Kľúč.",
"authenticators": ""
},
"user": {
"action": "Akcia",
@@ -1243,7 +1288,10 @@
"weeks": "týždne",
"with_app_password": "s heslom aplikácie",
"year": "rok",
"years": "rokov"
"years": "rokov",
"value": "",
"attribute": "",
"pushover_sound": ""
},
"warning": {
"cannot_delete_self": "Nemožno vymazať prihláseného používateľa",

View File

@@ -60,7 +60,7 @@
"exclude": "Exkludera objekt (regex-filter)",
"full_name": "Fullständiga namn",
"gal": "Global adressbok",
"gal_info": "Den global adressboken innehåller alla objekt i en domän och kan inte redigeras av någon användare. Informationen om tillgänglighet i SOGo är endast synlig när den globala adressboken är påslagen. <b>Starta om SOGo för att tillämpa ändringar.</b>",
"gal_info": "Den global adressboken innehåller alla objekt i en domän och kan inte redigeras av någon användare. Informationen om tillgänglighet i SOGo är endast synlig när den globala adressboken är påslagen. <b>Starta om SOGo för att tillämpa ändringar.</b>",
"generate": "generera",
"goto_ham": "Markera detta som en <span class=\"text-success\"><b>felaktig spam-registrering</b>, detta kommer förhindra liknande fel i framtiden</span>",
"goto_null": "Kasta e-postmeddelanande omedelbart",
@@ -106,7 +106,9 @@
"validate": "Validera",
"validation_success": "Korrekt validerad",
"app_passwd_protocols": "Tillåtna protokoll för applösenord",
"bcc_dest_format": "BCC-destinationen måste vara en enda giltig e-postadress.<br>Om du behöver skicka en kopia till flera adresser skapar du ett alias och använder det här."
"bcc_dest_format": "BCC-destinationen måste vara en enda giltig e-postadress.<br>Om du behöver skicka en kopia till flera adresser skapar du ett alias och använder det här.",
"dry": "",
"tags": ""
},
"admin": {
"access": "Åtkomst",
@@ -325,7 +327,31 @@
"username": "Användarnamn",
"validate_license_now": "Validera installations-ID mot licensservern",
"verify": "Verifiera",
"yes": "&#10003;"
"yes": "&#10003;",
"allowed_origins": "",
"allowed_methods": "",
"logo_dark_label": "",
"cors_settings": "",
"logo_normal_label": "",
"ip_check": "",
"f2b_ban_time_increment": "",
"copy_to_clipboard": "",
"f2b_manage_external": "",
"f2b_manage_external_info": "",
"f2b_max_ban_time": "",
"ip_check_disabled": "",
"login_time": "",
"oauth2_apps": "",
"oauth2_add_client": "",
"options": "",
"api_read_only": "",
"ip_check_opt_in": "",
"is_mx_based": "",
"queue_unban": "",
"rsettings_preset_4": "",
"service": "",
"success": "",
"api_read_write": ""
},
"danger": {
"access_denied": "Nekad åtkomst, eller ofullständig/ogiltig data",
@@ -444,7 +470,19 @@
"username_invalid": "Användarnamnet %s kan inte användas",
"validity_missing": "Ange en giltighetsperiod",
"value_missing": "Ange alla värden",
"yotp_verification_failed": "Yubico OTP-verifiering misslyckades: %s"
"yotp_verification_failed": "Yubico OTP-verifiering misslyckades: %s",
"webauthn_authenticator_failed": "",
"cors_invalid_method": "",
"cors_invalid_origin": "",
"img_dimensions_exceeded": "",
"img_size_exceeded": "",
"webauthn_publickey_failed": "",
"webauthn_username_failed": "",
"demo_mode_enabled": "",
"extended_sender_acl_denied": "",
"template_exists": "",
"template_id_invalid": "",
"template_name_invalid": ""
},
"debug": {
"chart_this_server": "Tabell (denna server)",
@@ -467,13 +505,31 @@
"uptime": "Upptid",
"started_on": "Startades",
"static_logs": "Statiska loggar",
"system_containers": "System & behållare"
"system_containers": "System & behållare",
"success": "",
"architecture": "",
"login_time": "",
"update_available": "",
"container_running": "",
"container_disabled": "",
"container_stopped": "",
"cores": "",
"current_time": "",
"error_show_ip": "",
"memory": "",
"service": "",
"show_ip": "",
"timezone": "",
"update_failed": "",
"username": "",
"wip": "",
"no_update_available": ""
},
"diagnostics": {
"cname_from_a": "Värde härstammar från A/AAAA-uppslaget. Detta stöds så länge som uppslaget pekar mot rätt resurs.",
"dns_records": "DNS-uppslag",
"dns_records_24hours": "Observera att ändringar gjorda i DNS kan ta upp till 24 timmar innan det visas korrekt på denna sida. Syftet med sidan är att enkelt se hur DNS-uppslagen är konfigurerade. Det är lätt att kontrollera att DNS-uppslagen är korrekt uppsatta.",
"dns_records_docs": "Se även <a target=\"_blank\" href=\"https://docs.mailcow.email/prerequisite/prerequisite-dns/\">dokumentationen</a>.",
"dns_records_docs": "Se även <a target=\"_blank\" href=\"https://docs.mailcow.email/getstarted/prerequisite-dns\">dokumentationen</a>.",
"dns_records_data": "Korrektdata",
"dns_records_name": "Namn",
"dns_records_status": "Nuvarande status",
@@ -585,7 +641,31 @@
"title": "Ändra objekt",
"unchanged_if_empty": "Lämna blakt, om oförändrat",
"username": "Användarnamn",
"validate_save": "Validera och spara"
"validate_save": "Validera och spara",
"footer_exclude": "",
"mailbox_relayhost_info": "",
"domain_footer_skip_replies": "",
"pushover_sound": "",
"custom_attributes": "",
"sogo_access": "",
"domain_footer": "",
"domain_footer_html": "",
"domain_footer_info_vars": {
"auth_user": "",
"from_user": "",
"from_name": "",
"from_addr": "",
"from_domain": "",
"custom": ""
},
"app_passwd_protocols": "",
"domain_footer_info": "",
"domain_footer_plain": "",
"none_inherit": "",
"sogo_access_info": "",
"pushover": "",
"acl": "",
"lookup_mx": ""
},
"footer": {
"cancel": "Avbryt",
@@ -598,7 +678,9 @@
"restart_container": "Starta om kontainer",
"restart_container_info": "<b>Viktigt:</b> En fullständig omstart kan ta ett tag att slutföra, vänta tills att det är klart.",
"restart_now": "Starta om nu",
"restarting_container": "Startar om kontainern, det kan ta en stund"
"restarting_container": "Startar om kontainern, det kan ta en stund",
"hibp_check": "",
"nothing_selected": ""
},
"header": {
"administration": "Konfiguration & detaljer",
@@ -609,7 +691,8 @@
"quarantine": "Karantän",
"restart_netfilter": "Starta om netfilter",
"restart_sogo": "Starta om SOGo",
"user_settings": "Användarinställningar"
"user_settings": "Användarinställningar",
"mailcow_system": ""
},
"info": {
"awaiting_tfa_confirmation": "Inväntar en TFA-bekräftelse",
@@ -775,7 +858,30 @@
"username": "Användarnamn",
"waiting": "Väntar",
"weekly": "Varje vecka",
"yes": "&#10003;"
"yes": "&#10003;",
"goto_ham": "",
"goto_spam": "",
"templates": "",
"template": "",
"add_template": "",
"catch_all": "",
"all_domains": "",
"domain_templates": "",
"last_pw_change": "",
"mailbox_templates": "",
"open_logs": "",
"recipient": "",
"relay_unknown": "",
"sender": "",
"syncjob_check_log": "",
"syncjob_last_run_result": "",
"syncjob_EX_OK": "",
"syncjob_EXIT_CONNECTION_FAILURE": "",
"syncjob_EXIT_TLS_FAILURE": "",
"syncjob_EXIT_AUTHENTICATION_FAILURE": "",
"syncjob_EXIT_OVERQUOTA": "",
"syncjob_EXIT_CONNECTION_FAILURE_HOST1": "",
"syncjob_EXIT_AUTHENTICATION_FAILURE_USER1": ""
},
"oauth2": {
"access_denied": "Logga in som ägare av en postlåda för att tilldela åtkomst via OAuth2.",
@@ -840,7 +946,20 @@
"toggle_all": "Markera alla"
},
"queue": {
"queue_manager": "Kö-hanteraring"
"queue_manager": "Kö-hanteraring",
"unban": "",
"ays": "",
"deliver_mail": "",
"deliver_mail_legend": "",
"hold_mail": "",
"hold_mail_legend": "",
"delete": "",
"flush": "",
"info": "",
"legend": "",
"show_message": "",
"unhold_mail": "",
"unhold_mail_legend": ""
},
"start": {
"help": "Visa/dölj hjälppanel",
@@ -924,7 +1043,15 @@
"verified_totp_login": "Verifierad TOTP inloggning",
"verified_webauthn_login": "Verifierad WebAuthn inloggning",
"verified_fido2_login": "Verifierad FIDO2 inloggning",
"verified_yotp_login": "Verifierad Yubico OTP inloggning"
"verified_yotp_login": "Verifierad Yubico OTP inloggning",
"domain_footer_modified": "",
"template_added": "",
"template_modified": "",
"cors_headers_edited": "",
"domain_add_dkim_available": "",
"f2b_banlist_refreshed": "",
"ip_check_opt_in_modified": "",
"template_removed": ""
},
"tfa": {
"api_register": "%s använder Yubico Moln-API. Vänligen skaffa en API-nyckel för din nyckel <a href=\"https://upgrade.yubico.com/getapikey/\" target=\"_blank\">här</a>",
@@ -949,7 +1076,10 @@
"webauthn": "WebAuthn-autentisering",
"waiting_usb_auth": "<i>Väntar på USB-enhet...</i><br><br>Tryck på knappen på USB-enheten nu.",
"waiting_usb_register": "<i>Väntar på USB-enhet...</i><br><br>Vänligen fyll i det övre lösenordsfältet först och tryck sedan på knappen på USB-enheten.",
"yubi_otp": "Yubico OTP-autentisering"
"yubi_otp": "Yubico OTP-autentisering",
"authenticators": "",
"u2f_deprecated": "",
"u2f_deprecated_important": ""
},
"fido2": {
"set_fn": "Ange ett eget namn",
@@ -963,7 +1093,8 @@
"start_fido2_validation": "Starta FIDO2 verifiering",
"fido2_auth": "Loggain med FIDO2",
"fido2_success": "Enheten har registrerats",
"fido2_validation_failed": "Verifiering misslyckades"
"fido2_validation_failed": "Verifiering misslyckades",
"set_fido2_touchid": ""
},
"user": {
"action": "Åtgärd",
@@ -1097,7 +1228,37 @@
"weekly": "Varje vecka",
"weeks": "veckor",
"year": "år",
"years": "år"
"years": "år",
"empty": "",
"pushover_sound": "",
"fido2_webauthn": "",
"recent_successful_connections": "",
"value": "",
"with_app_password": "",
"attribute": "",
"from": "",
"allowed_protocols": "",
"apple_connection_profile_with_app_password": "",
"change_password_hint_app_passwords": "",
"clear_recent_successful_connections": "",
"direct_protocol_access": "",
"last_pw_change": "",
"last_ui_login": "",
"login_history": "",
"mailbox": "",
"mailbox_general": "",
"mailbox_settings": "",
"open_logs": "",
"open_webmail_sso": "",
"syncjob_check_log": "",
"syncjob_last_run_result": "",
"syncjob_EX_OK": "",
"syncjob_EXIT_CONNECTION_FAILURE": "",
"syncjob_EXIT_TLS_FAILURE": "",
"syncjob_EXIT_AUTHENTICATION_FAILURE": "",
"syncjob_EXIT_OVERQUOTA": "",
"syncjob_EXIT_CONNECTION_FAILURE_HOST1": "",
"syncjob_EXIT_AUTHENTICATION_FAILURE_USER1": ""
},
"warning": {
"cannot_delete_self": "Inloggade användare kan inte tas bort",
@@ -1111,5 +1272,38 @@
"quota_exceeded_scope": "Domänkvoten fylld: Endast postlådor med obegränsade kvoter kan skapas på den här domänen.",
"session_token": "Formulär-nyckeln är ogiltig: Nyckeln matchar inte",
"session_ua": "Formulär-nyckeln är ogiltig: User-Agenten kunde inte valideras"
},
"datatables": {
"info": "",
"expand_all": "",
"emptyTable": "",
"infoFiltered": "",
"infoEmpty": "",
"lengthMenu": "",
"loadingRecords": "",
"processing": "",
"search": "",
"zeroRecords": "",
"paginate": {
"first": "",
"last": "",
"next": "",
"previous": ""
},
"aria": {
"sortAscending": "",
"sortDescending": ""
},
"collapse_all": "",
"thousands": "",
"decimal": "",
"infoPostFix": ""
},
"ratelimit": {
"day": "",
"disabled": "",
"second": "",
"minute": "",
"hour": ""
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -349,7 +349,9 @@
"queue_unban": "розблокувати",
"f2b_manage_external": "Керування Fail2Ban ззовні",
"f2b_manage_external_info": "Fail2ban буде підтримувати список заборонених, але не буде активно встановлювати правила для блокування трафіку. Використовуйте згенерований список заборон нижче для зовнішнього блокування трафіку.",
"copy_to_clipboard": "Текст скопійовано в буфер обміну!"
"copy_to_clipboard": "Текст скопійовано в буфер обміну!",
"logo_normal_label": "",
"logo_dark_label": ""
},
"danger": {
"alias_domain_invalid": "Неприпустимий псевдонім домену: %s",
@@ -478,7 +480,9 @@
"extended_sender_acl_denied": "відсутній ACL для встановлення зовнішніх адрес відправників",
"template_exists": "Шаблон %s вже існує",
"template_id_invalid": "Ідентифікатор шаблону %s недійсний",
"template_name_invalid": "Ім'я шаблону невірне"
"template_name_invalid": "Ім'я шаблону невірне",
"img_dimensions_exceeded": "",
"img_size_exceeded": ""
},
"debug": {
"chart_this_server": "Діаграма (цей сервер)",
@@ -525,7 +529,7 @@
"cname_from_a": "Значення, отримане із запису A/AAAA. Це підтримується, поки запис вказує на правильний ресурс.",
"dns_records": "Записи DNS",
"dns_records_data": "Значення",
"dns_records_docs": "Також перегляньте <a target=\"_blank\" href=\"https://docs.mailcow.email/prerequisite/prerequisite-dns/\">документацію</a>.",
"dns_records_docs": "Також перегляньте <a target=\"_blank\" href=\"https://docs.mailcow.email/getstarted/prerequisite-dns\">документацію</a>.",
"dns_records_name": "Назва",
"dns_records_status": "Статус",
"optional": "Цей запис необов'язковий.",
@@ -561,6 +565,7 @@
"extended_sender_acl": "Зовнішні адреси пошти",
"force_pw_update": "Вимагати зміну пароля при наступному вході до системи",
"force_pw_update_info": "Цей користувач зможе увійти лише в %s. Паролі додатків залишаються придатними для використання.",
"footer_exclude": "Виключити з нижнього колонтитула",
"full_name": "Повне ім'я",
"gal": "GAL - Глобальна адресна книга",
"generate": "згенерувати",
@@ -660,7 +665,7 @@
"domain_footer_html": "Нижній колонтитул HTML",
"domain_footer_plain": "ЗВИЧАЙНИЙ нижній колонтитул",
"custom_attributes": "Користувацькі атрибути",
"mbox_exclude": "Виключити поштові скриньки"
"domain_footer_skip_replies": ""
},
"fido2": {
"confirm": "Підтвердити",
@@ -1067,7 +1072,8 @@
"cors_headers_edited": "Налаштування CORS збережено",
"ip_check_opt_in_modified": "Перевірка IP-адреси успішно збережено",
"template_removed": "Шаблону із ID %s видалено",
"f2b_banlist_refreshed": "Ідентифікатор списку заборонених успішно оновлено."
"f2b_banlist_refreshed": "Ідентифікатор списку заборонених успішно оновлено.",
"domain_footer_modified": ""
},
"tfa": {
"confirm": "Підтвердьте",
@@ -1094,7 +1100,8 @@
"set_tfa": "Встановити метод двофакторної перевірки",
"u2f_deprecated": "Схоже, ваш ключ був зареєстрований за допомогою застарілого методу U2F. Ми дезактивуємо двофакторну автентифікацію для вас і видалимо ваш ключ.",
"waiting_usb_auth": "<i>Очікування пристрою USB...</i><br><br>Будь ласка, натисніть зараз кнопку на USB пристрої.",
"waiting_usb_register": "<i>Очікування USB-пристрою...</i><br><br>Будь ласка, введіть пароль вище та підтвердіть реєстрацію, натиснувши кнопку на USB пристрої."
"waiting_usb_register": "<i>Очікування USB-пристрою...</i><br><br>Будь ласка, введіть пароль вище та підтвердіть реєстрацію, натиснувши кнопку на USB пристрої.",
"authenticators": ""
},
"user": {
"action": "Дії",

View File

@@ -107,7 +107,8 @@
"timeout2": "本地主机连接超时时间",
"username": "用户名",
"validate": "验证",
"validation_success": "验证成功"
"validation_success": "验证成功",
"dry": ""
},
"admin": {
"access": "权限管理",
@@ -336,7 +337,21 @@
"validate_license_now": "通过证书服务器验证 GUID",
"verify": "验证",
"yes": "&#10003;",
"options": "选项"
"options": "选项",
"f2b_max_ban_time": "最长封禁时间(秒)",
"copy_to_clipboard": "复制到粘贴板",
"allowed_methods": "",
"allowed_origins": "",
"logo_dark_label": "",
"logo_normal_label": "",
"cors_settings": "",
"f2b_ban_time_increment": "",
"f2b_manage_external": "",
"f2b_manage_external_info": "",
"ip_check": "",
"ip_check_disabled": "",
"ip_check_opt_in": "",
"queue_unban": ""
},
"danger": {
"access_denied": "访问被拒绝或者表单数据无效",
@@ -356,7 +371,7 @@
"description_invalid": "%s 的资源描述无效",
"dkim_domain_or_sel_exists": "\"%s\"的 DKIM 密钥已存在,因此不会被覆盖",
"dkim_domain_or_sel_invalid": "DKIM 域名或选择器无效: %s",
"domain_cannot_match_hostname": "域名与主机名称不匹配",
"domain_cannot_match_hostname": "域名不应与主机名相同",
"domain_exists": "域名 %s 已存在",
"domain_invalid": "域名地址为空或无效",
"domain_not_empty": "不能删除非空域名 %s",
@@ -456,7 +471,18 @@
"validity_missing": "请设置有效期",
"value_missing": "请填入所有值",
"yotp_verification_failed": "Yubico OTP 认证失败: %s",
"template_exists": "模板 %s 已存在"
"template_exists": "模板 %s 已存在",
"template_name_invalid": "模板名称无效",
"webauthn_authenticator_failed": "",
"webauthn_username_failed": "",
"cors_invalid_method": "",
"cors_invalid_origin": "",
"img_dimensions_exceeded": "",
"img_size_exceeded": "",
"webauthn_publickey_failed": "",
"demo_mode_enabled": "",
"extended_sender_acl_denied": "",
"template_id_invalid": ""
},
"debug": {
"chart_this_server": "图表 (此服务器)",
@@ -487,14 +513,24 @@
"container_disabled": "容器已被停止或禁用",
"container_running": "运行中",
"cores": "核心数",
"memory": "内存"
"memory": "内存",
"error_show_ip": "无法解析公网IP地址",
"show_ip": "显示公网IP",
"update_available": "有可用更新",
"update_failed": "无法检查更新",
"container_stopped": "",
"architecture": "",
"no_update_available": "",
"wip": "",
"current_time": "",
"timezone": ""
},
"diagnostics": {
"cname_from_a": "来自 A/AAAA 记录的值。但只要记录指向正确的资源即可。",
"dns_records": "DNS 记录",
"dns_records_24hours": "请注意 DNS 记录的更改可能需要24小时才可以使此页面的当前状态显示正确。此页面为你提供了一个可以便捷查询如何配置 DNS 记录以及检查你的 DNS 记录是否正确的方式。",
"dns_records_data": "正确数据",
"dns_records_docs": "请同时也参考这个<a target=\"_blank\" href=\"https://docs.mailcow.email/prerequisite/prerequisite-dns/\">文档</a>.",
"dns_records_docs": "请同时也参考这个<a target=\"_blank\" href=\"https://docs.mailcow.email/getstarted/prerequisite-dns\">文档</a>.",
"dns_records_name": "名称",
"dns_records_status": "当前状态",
"dns_records_type": "类型",
@@ -611,7 +647,25 @@
"title": "编辑对象",
"unchanged_if_empty": "如果不更改则留空",
"username": "用户名",
"validate_save": "验证并保存"
"validate_save": "验证并保存",
"footer_exclude": "",
"created_on": "",
"domain_footer_skip_replies": "",
"last_modified": "",
"custom_attributes": "",
"domain_footer": "",
"domain_footer_html": "",
"domain_footer_info": "",
"domain_footer_info_vars": {
"auth_user": "",
"from_user": "",
"from_name": "",
"from_addr": "",
"from_domain": "",
"custom": ""
},
"domain_footer_plain": "",
"pushover_sound": ""
},
"fido2": {
"confirm": "确认",
@@ -652,7 +706,8 @@
"quarantine": "隔离",
"restart_netfilter": "重启 netfilter",
"restart_sogo": "重启 SOGo",
"user_settings": "用户设置"
"user_settings": "用户设置",
"mailcow_system": ""
},
"info": {
"awaiting_tfa_confirmation": "等待 TFA 确认",
@@ -831,7 +886,17 @@
"mailbox_templates": "邮箱模板",
"gal": "全局地址列表",
"max_aliases": "最大别名数",
"max_mailboxes": "最大可能的邮箱数"
"max_mailboxes": "最大可能的邮箱数",
"goto_ham": "",
"goto_spam": "",
"templates": "",
"template": "",
"force_pw_update": "",
"last_modified": "",
"add_template": "",
"created_on": "",
"max_quota": "",
"relay_unknown": ""
},
"oauth2": {
"access_denied": "请作为邮箱所有者登录以使用 OAuth2 授权",
@@ -897,13 +962,25 @@
},
"queue": {
"queue_manager": "队列管理器",
"delete": "全部删除"
"delete": "全部删除",
"show_message": "",
"unban": "",
"unhold_mail": "",
"unhold_mail_legend": "",
"flush": "",
"info": "",
"legend": "",
"ays": "",
"deliver_mail": "",
"deliver_mail_legend": "",
"hold_mail": "",
"hold_mail_legend": ""
},
"ratelimit": {
"disabled": "禁用",
"second": "msgs / 秒",
"minute": "msgs / 分钟",
"hour": "msgs / 小",
"hour": "msgs / 小",
"day": "msgs / 天"
},
"start": {
@@ -989,7 +1066,14 @@
"verified_fido2_login": "FIDO2 登录验证成功",
"verified_totp_login": "TOTP 登录验证成功",
"verified_webauthn_login": "WebAuthn 登录验证成功",
"verified_yotp_login": "Yubico OTP 登录验证成功"
"verified_yotp_login": "Yubico OTP 登录验证成功",
"cors_headers_edited": "",
"domain_footer_modified": "",
"f2b_banlist_refreshed": "",
"ip_check_opt_in_modified": "",
"template_added": "",
"template_modified": "",
"template_removed": ""
},
"tfa": {
"api_register": "%s 使用了 Yubico Cloud API请<a href=\"https://upgrade.yubico.com/getapikey/\" target=\"_blank\">在此</a>为你的密钥获取 API 密钥",
@@ -1016,7 +1100,8 @@
"webauthn": "WebAuthn 认证",
"waiting_usb_auth": "<i>等待 USB 设备中...</i><br><br>现在请触碰你的 WebAuthn USB 设备上的按钮。",
"waiting_usb_register": "<i>等待 USB 设备中...</i><br><br>请在上方输入你的密码并请触碰你的 WebAuthn USB 设备上的按钮以确认注册该 WebAuthn 设备。",
"yubi_otp": "Yubico OTP 认证"
"yubi_otp": "Yubico OTP 认证",
"authenticators": ""
},
"user": {
"action": "操作",
@@ -1177,7 +1262,10 @@
"weeks": "周",
"with_app_password": "包含应用密码",
"year": "年",
"years": "年"
"years": "年",
"pushover_sound": "",
"attribute": "",
"value": ""
},
"warning": {
"cannot_delete_self": "不能删除已登录的用户",
@@ -1202,7 +1290,20 @@
"paginate": {
"first": "第一页",
"last": "最后一页",
"previous": "上一页"
}
"previous": "上一页",
"next": "下一页"
},
"decimal": "",
"infoPostFix": "",
"infoFiltered": "",
"thousands": "",
"lengthMenu": "",
"loadingRecords": "",
"zeroRecords": "",
"aria": {
"sortAscending": "",
"sortDescending": ""
},
"emptyTable": ""
}
}

Some files were not shown because too many files have changed in this diff Show More