mirror of
https://github.com/mailcow/mailcow-dockerized.git
synced 2026-06-14 18:40:23 +00:00
Compare commits
85 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2024cda560 | |||
| 03aaf4ad76 | |||
| 550b88861f | |||
| 02ae5fa007 | |||
| d81f105ed7 | |||
| d3ed225675 | |||
| 9ffc83f0f6 | |||
| 981c7d5974 | |||
| 5da089ccd7 | |||
| 91e00f7d97 | |||
| 3a675fb541 | |||
| 9a5d8d2d22 | |||
| de812221ef | |||
| f68a28fa2b | |||
| 7b7798e8c4 | |||
| b3ac94115e | |||
| b1a172cad9 | |||
| f2e21c68d0 | |||
| 8b784c0eb1 | |||
| bc59f32b96 | |||
| a4fa8a4fae | |||
| f730192c98 | |||
| f994501296 | |||
| 9c3e73606c | |||
| 5619e16b70 | |||
| d2e3867893 | |||
| 979f5475c3 | |||
| 5a10f2dd7c | |||
| a80b5b7dd0 | |||
| 392967d664 | |||
| 3b3c2b7141 | |||
| f55c3c0887 | |||
| f423ad77f3 | |||
| 8ba1e1ba9e | |||
| 55576084fc | |||
| 03311b06c9 | |||
| b5c3d01834 | |||
| f398ecbe39 | |||
| 8f1ae0f099 | |||
| c8bee57732 | |||
| 85641794c3 | |||
| 849decaa59 | |||
| 6e88550f92 | |||
| 7c52483887 | |||
| 0aa520c030 | |||
| 548999f163 | |||
| 63df547306 | |||
| 547d2ca308 | |||
| 46b995f9e3 | |||
| 1fdf704cb4 | |||
| 5ec9c4c750 | |||
| afed94cc0e | |||
| 6f48c5ace0 | |||
| 9a7e1c2b5a | |||
| 2ef7539d55 | |||
| 4e52542e33 | |||
| a1895ad924 | |||
| d5a2c96887 | |||
| 3f30fe3113 | |||
| d89f24a1a3 | |||
| 413354ff29 | |||
| a28ba5bebb | |||
| b93375b671 | |||
| b568a33581 | |||
| b05ef8edac | |||
| 015f9b663f | |||
| b6167257c9 | |||
| 687fe044b2 | |||
| cfa47eb873 | |||
| 7079000ee0 | |||
| f60c4f39ee | |||
| 473713219f | |||
| 03ed81dc3f | |||
| 53543ccf26 | |||
| 3b183933e3 | |||
| 6c6fde8e2e | |||
| 61e23b6b81 | |||
| 6c649debc9 | |||
| 87b0683f77 | |||
| 59c1e7a18a | |||
| 4f9dad5dd3 | |||
| adc6a0054c | |||
| 8a70cdb48b | |||
| bb4bc11383 | |||
| 2c0d379dc5 |
@@ -12,7 +12,7 @@
|
|||||||
"baseBranches": ["staging"],
|
"baseBranches": ["staging"],
|
||||||
"enabledManagers": ["github-actions", "regex", "docker-compose"],
|
"enabledManagers": ["github-actions", "regex", "docker-compose"],
|
||||||
"ignorePaths": [
|
"ignorePaths": [
|
||||||
"data\/web\/inc\/lib\/vendor\/matthiasmullie\/minify\/**"
|
"data\/web\/inc\/lib\/vendor\/**"
|
||||||
],
|
],
|
||||||
"regexManagers": [
|
"regexManagers": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ jobs:
|
|||||||
if: github.event.pull_request.base.ref != 'staging' #check if the target branch is not staging
|
if: github.event.pull_request.base.ref != 'staging' #check if the target branch is not staging
|
||||||
steps:
|
steps:
|
||||||
- name: Send message
|
- name: Send message
|
||||||
uses: thollander/actions-comment-pull-request@v2.4.2
|
uses: thollander/actions-comment-pull-request@v2.4.3
|
||||||
with:
|
with:
|
||||||
GITHUB_TOKEN: ${{ secrets.CHECKIFPRISSTAGING_ACTION_PAT }}
|
GITHUB_TOKEN: ${{ secrets.CHECKIFPRISSTAGING_ACTION_PAT }}
|
||||||
message: |
|
message: |
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
[](https://translate.mailcow.email/engage/mailcow-dockerized/)
|
[](https://translate.mailcow.email/engage/mailcow-dockerized/)
|
||||||
[](https://twitter.com/mailcow_email)
|
[](https://twitter.com/mailcow_email)
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
## Want to support mailcow?
|
## Want to support mailcow?
|
||||||
|
|
||||||
@@ -25,7 +27,9 @@ Please see [the official documentation](https://docs.mailcow.email/) for install
|
|||||||
|
|
||||||
[Telegram mailcow Off-Topic channel](https://t.me/mailcowOfftopic)
|
[Telegram mailcow Off-Topic channel](https://t.me/mailcowOfftopic)
|
||||||
|
|
||||||
[Official Twitter Account](https://twitter.com/mailcow_email)
|
[Official 𝕏 (Twitter) Account](https://twitter.com/mailcow_email)
|
||||||
|
|
||||||
|
[Official Mastodon Account](https://mailcow.social/@doncow)
|
||||||
|
|
||||||
Telegram desktop clients are available for [multiple platforms](https://desktop.telegram.org). You can search the groups history for keywords.
|
Telegram desktop clients are available for [multiple platforms](https://desktop.telegram.org). You can search the groups history for keywords.
|
||||||
|
|
||||||
@@ -38,4 +42,4 @@ mailcow is a registered word mark of The Infrastructure Company GmbH, Parkstr. 4
|
|||||||
|
|
||||||
The project is managed and maintained by The Infrastructure Company GmbH.
|
The project is managed and maintained by The Infrastructure Company GmbH.
|
||||||
|
|
||||||
Originated from @andryyy (André)
|
Originated from @andryyy (André)
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ FROM debian:bullseye-slim
|
|||||||
LABEL maintainer "The Infrastructure Company GmbH <info@servercow.de>"
|
LABEL maintainer "The Infrastructure Company GmbH <info@servercow.de>"
|
||||||
|
|
||||||
ARG DEBIAN_FRONTEND=noninteractive
|
ARG DEBIAN_FRONTEND=noninteractive
|
||||||
# renovate: datasource=github-tags depName=dovecot/core versioning=semver-coerced extractVersion=^v(?<version>.*)$
|
# renovate: datasource=github-tags depName=dovecot/core versioning=semver-coerced extractVersion=(?<version>.*)$
|
||||||
ARG DOVECOT=2.3.21
|
ARG DOVECOT=2.3.21
|
||||||
# renovate: datasource=github-releases depName=tianon/gosu versioning=semver-coerced extractVersion=^v(?<version>.*)$
|
# renovate: datasource=github-releases depName=tianon/gosu versioning=semver-coerced extractVersion=(?<version>.*)$
|
||||||
ARG GOSU_VERSION=1.16
|
ARG GOSU_VERSION=1.16
|
||||||
ENV LC_ALL C
|
ENV LC_ALL C
|
||||||
|
|
||||||
|
|||||||
@@ -75,7 +75,8 @@ my $sth = $dbh->prepare("SELECT id,
|
|||||||
custom_params,
|
custom_params,
|
||||||
subscribeall,
|
subscribeall,
|
||||||
timeout1,
|
timeout1,
|
||||||
timeout2
|
timeout2,
|
||||||
|
dry
|
||||||
FROM imapsync
|
FROM imapsync
|
||||||
WHERE active = 1
|
WHERE active = 1
|
||||||
AND is_running = 0
|
AND is_running = 0
|
||||||
@@ -111,13 +112,16 @@ while ($row = $sth->fetchrow_arrayref()) {
|
|||||||
$subscribeall = @$row[18];
|
$subscribeall = @$row[18];
|
||||||
$timeout1 = @$row[19];
|
$timeout1 = @$row[19];
|
||||||
$timeout2 = @$row[20];
|
$timeout2 = @$row[20];
|
||||||
|
$dry = @$row[21];
|
||||||
|
|
||||||
if ($enc1 eq "TLS") { $enc1 = "--tls1"; } elsif ($enc1 eq "SSL") { $enc1 = "--ssl1"; } else { undef $enc1; }
|
if ($enc1 eq "TLS") { $enc1 = "--tls1"; } elsif ($enc1 eq "SSL") { $enc1 = "--ssl1"; } else { undef $enc1; }
|
||||||
|
|
||||||
my $template = $run_dir . '/imapsync.XXXXXXX';
|
my $template = $run_dir . '/imapsync.XXXXXXX';
|
||||||
my $passfile1 = File::Temp->new(TEMPLATE => $template);
|
my $passfile1 = File::Temp->new(TEMPLATE => $template);
|
||||||
my $passfile2 = File::Temp->new(TEMPLATE => $template);
|
my $passfile2 = File::Temp->new(TEMPLATE => $template);
|
||||||
|
|
||||||
|
binmode( $passfile1, ":utf8" );
|
||||||
|
|
||||||
print $passfile1 "$password1\n";
|
print $passfile1 "$password1\n";
|
||||||
print $passfile2 trim($master_pass) . "\n";
|
print $passfile2 trim($master_pass) . "\n";
|
||||||
|
|
||||||
@@ -148,6 +152,7 @@ while ($row = $sth->fetchrow_arrayref()) {
|
|||||||
"--host2", "localhost",
|
"--host2", "localhost",
|
||||||
"--user2", $user2 . '*' . trim($master_user),
|
"--user2", $user2 . '*' . trim($master_user),
|
||||||
"--passfile2", $passfile2->filename,
|
"--passfile2", $passfile2->filename,
|
||||||
|
($dry eq "1" ? ('--dry') : ()),
|
||||||
'--no-modulesversion',
|
'--no-modulesversion',
|
||||||
'--noreleasecheck'];
|
'--noreleasecheck'];
|
||||||
|
|
||||||
|
|||||||
@@ -3,15 +3,15 @@ LABEL maintainer "The Infrastructure Company GmbH <info@servercow.de>"
|
|||||||
|
|
||||||
# renovate: datasource=github-tags depName=krakjoe/apcu versioning=semver-coerced extractVersion=^v(?<version>.*)$
|
# 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.22
|
||||||
# renovate: datasource=github-tags depName=Imagick/imagick versioning=semver-coerced extractVersion=^v(?<version>.*)$
|
# renovate: datasource=github-tags depName=Imagick/imagick versioning=semver-coerced extractVersion=(?<version>.*)$
|
||||||
ARG IMAGICK_PECL_VERSION=3.7.0
|
ARG IMAGICK_PECL_VERSION=3.7.0
|
||||||
# renovate: datasource=github-tags depName=php/pecl-mail-mailparse versioning=semver-coerced extractVersion=^v(?<version>.*)$
|
# renovate: datasource=github-tags depName=php/pecl-mail-mailparse versioning=semver-coerced extractVersion=^v(?<version>.*)$
|
||||||
ARG MAILPARSE_PECL_VERSION=3.1.6
|
ARG MAILPARSE_PECL_VERSION=3.1.6
|
||||||
# renovate: datasource=github-tags depName=php-memcached-dev/php-memcached versioning=semver-coerced extractVersion=^v(?<version>.*)$
|
# renovate: datasource=github-tags depName=php-memcached-dev/php-memcached versioning=semver-coerced extractVersion=^v(?<version>.*)$
|
||||||
ARG MEMCACHED_PECL_VERSION=3.2.0
|
ARG MEMCACHED_PECL_VERSION=3.2.0
|
||||||
# renovate: datasource=github-tags depName=phpredis/phpredis versioning=semver-coerced extractVersion=^v(?<version>.*)$
|
# 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.1
|
||||||
# renovate: datasource=github-tags depName=composer/composer versioning=semver-coerced extractVersion=^v(?<version>.*)$
|
# renovate: datasource=github-tags depName=composer/composer versioning=semver-coerced extractVersion=(?<version>.*)$
|
||||||
ARG COMPOSER_VERSION=2.6.5
|
ARG COMPOSER_VERSION=2.6.5
|
||||||
|
|
||||||
RUN apk add -U --no-cache autoconf \
|
RUN apk add -U --no-cache autoconf \
|
||||||
|
|||||||
@@ -79,6 +79,9 @@ EOF
|
|||||||
redis-cli -h redis-mailcow SLAVEOF NO ONE
|
redis-cli -h redis-mailcow SLAVEOF NO ONE
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Provide additional lua modules
|
||||||
|
ln -s /usr/lib/$(uname -m)-linux-gnu/liblua5.1-cjson.so.0.0.0 /usr/lib/rspamd/cjson.so
|
||||||
|
|
||||||
chown -R _rspamd:_rspamd /var/lib/rspamd \
|
chown -R _rspamd:_rspamd /var/lib/rspamd \
|
||||||
/etc/rspamd/local.d \
|
/etc/rspamd/local.d \
|
||||||
/etc/rspamd/override.d \
|
/etc/rspamd/override.d \
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ LABEL maintainer "The Infrastructure Company GmbH <info@servercow.de>"
|
|||||||
|
|
||||||
ARG DEBIAN_FRONTEND=noninteractive
|
ARG DEBIAN_FRONTEND=noninteractive
|
||||||
ARG SOGO_DEBIAN_REPOSITORY=http://packages.sogo.nu/nightly/5/debian/
|
ARG SOGO_DEBIAN_REPOSITORY=http://packages.sogo.nu/nightly/5/debian/
|
||||||
# renovate: datasource=github-releases depName=tianon/gosu versioning=semver-coerced extractVersion=^v(?<version>.*)$
|
# renovate: datasource=github-releases depName=tianon/gosu versioning=semver-coerced extractVersion=^(?<version>.*)$
|
||||||
ARG GOSU_VERSION=1.16
|
ARG GOSU_VERSION=1.16
|
||||||
ENV LC_ALL C
|
ENV LC_ALL C
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ FROM solr:7.7-slim
|
|||||||
|
|
||||||
USER root
|
USER root
|
||||||
|
|
||||||
# renovate: datasource=github-releases depName=tianon/gosu versioning=semver-coerced extractVersion=^v(?<version>.*)$
|
# renovate: datasource=github-releases depName=tianon/gosu versioning=semver-coerced extractVersion=(?<version>.*)$
|
||||||
ARG GOSU_VERSION=1.16
|
ARG GOSU_VERSION=1.16
|
||||||
|
|
||||||
COPY solr.sh /
|
COPY solr.sh /
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ server {
|
|||||||
deny all;
|
deny all;
|
||||||
}
|
}
|
||||||
|
|
||||||
location ~ ^\/(?:index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+)\.php(?:$|\/) {
|
location ~ ^\/(?:index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|ocs-provider\/.+)\.php(?:$|\/) {
|
||||||
fastcgi_split_path_info ^(.+?\.php)(\/.*|)$;
|
fastcgi_split_path_info ^(.+?\.php)(\/.*|)$;
|
||||||
set $path_info $fastcgi_path_info;
|
set $path_info $fastcgi_path_info;
|
||||||
try_files $fastcgi_script_name =404;
|
try_files $fastcgi_script_name =404;
|
||||||
@@ -105,7 +105,7 @@ server {
|
|||||||
fastcgi_read_timeout 1200;
|
fastcgi_read_timeout 1200;
|
||||||
}
|
}
|
||||||
|
|
||||||
location ~ ^\/(?:updater|oc[ms]-provider)(?:$|\/) {
|
location ~ ^\/(?:updater|ocs-provider)(?:$|\/) {
|
||||||
try_files $uri/ =404;
|
try_files $uri/ =404;
|
||||||
index index.php;
|
index index.php;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Whitelist generated by Postwhite v3.4 on Sun Oct 1 00:14:59 UTC 2023
|
# Whitelist generated by Postwhite v3.4 on Fri Dec 1 00:15:18 UTC 2023
|
||||||
# https://github.com/stevejenkins/postwhite/
|
# https://github.com/stevejenkins/postwhite/
|
||||||
# 2019 total rules
|
# 2038 total rules
|
||||||
2a00:1450:4000::/36 permit
|
2a00:1450:4000::/36 permit
|
||||||
2a01:111:f400::/48 permit
|
2a01:111:f400::/48 permit
|
||||||
2a01:111:f403:8000::/50 permit
|
2a01:111:f403:8000::/50 permit
|
||||||
@@ -10,10 +10,10 @@
|
|||||||
2a02:a60:0:5::/64 permit
|
2a02:a60:0:5::/64 permit
|
||||||
2c0f:fb50:4000::/36 permit
|
2c0f:fb50:4000::/36 permit
|
||||||
2.207.151.53 permit
|
2.207.151.53 permit
|
||||||
3.14.230.16 permit
|
|
||||||
3.70.123.177 permit
|
3.70.123.177 permit
|
||||||
3.93.157.0/24 permit
|
3.93.157.0/24 permit
|
||||||
3.129.120.190 permit
|
3.129.120.190 permit
|
||||||
|
3.137.78.75 permit
|
||||||
3.210.190.0/24 permit
|
3.210.190.0/24 permit
|
||||||
8.20.114.31 permit
|
8.20.114.31 permit
|
||||||
8.25.194.0/23 permit
|
8.25.194.0/23 permit
|
||||||
@@ -183,8 +183,6 @@
|
|||||||
50.18.125.237 permit
|
50.18.125.237 permit
|
||||||
50.18.126.162 permit
|
50.18.126.162 permit
|
||||||
50.31.32.0/19 permit
|
50.31.32.0/19 permit
|
||||||
50.31.156.96/27 permit
|
|
||||||
50.31.205.0/24 permit
|
|
||||||
51.137.58.21 permit
|
51.137.58.21 permit
|
||||||
51.140.75.55 permit
|
51.140.75.55 permit
|
||||||
51.144.100.179 permit
|
51.144.100.179 permit
|
||||||
@@ -211,6 +209,7 @@
|
|||||||
52.96.222.194 permit
|
52.96.222.194 permit
|
||||||
52.96.222.226 permit
|
52.96.222.226 permit
|
||||||
52.96.223.2 permit
|
52.96.223.2 permit
|
||||||
|
52.96.228.130 permit
|
||||||
52.96.229.242 permit
|
52.96.229.242 permit
|
||||||
52.100.0.0/14 permit
|
52.100.0.0/14 permit
|
||||||
52.103.0.0/17 permit
|
52.103.0.0/17 permit
|
||||||
@@ -303,22 +302,31 @@
|
|||||||
64.147.123.27 permit
|
64.147.123.27 permit
|
||||||
64.147.123.28 permit
|
64.147.123.28 permit
|
||||||
64.147.123.29 permit
|
64.147.123.29 permit
|
||||||
|
64.147.123.128/27 permit
|
||||||
64.207.219.7 permit
|
64.207.219.7 permit
|
||||||
64.207.219.8 permit
|
64.207.219.8 permit
|
||||||
64.207.219.9 permit
|
64.207.219.9 permit
|
||||||
|
64.207.219.10 permit
|
||||||
|
64.207.219.11 permit
|
||||||
|
64.207.219.12 permit
|
||||||
64.207.219.13 permit
|
64.207.219.13 permit
|
||||||
64.207.219.14 permit
|
64.207.219.14 permit
|
||||||
64.207.219.15 permit
|
64.207.219.15 permit
|
||||||
64.207.219.71 permit
|
64.207.219.71 permit
|
||||||
64.207.219.72 permit
|
64.207.219.72 permit
|
||||||
64.207.219.73 permit
|
64.207.219.73 permit
|
||||||
|
64.207.219.74 permit
|
||||||
64.207.219.75 permit
|
64.207.219.75 permit
|
||||||
|
64.207.219.76 permit
|
||||||
64.207.219.77 permit
|
64.207.219.77 permit
|
||||||
64.207.219.78 permit
|
64.207.219.78 permit
|
||||||
64.207.219.79 permit
|
64.207.219.79 permit
|
||||||
64.207.219.135 permit
|
64.207.219.135 permit
|
||||||
64.207.219.136 permit
|
64.207.219.136 permit
|
||||||
64.207.219.137 permit
|
64.207.219.137 permit
|
||||||
|
64.207.219.138 permit
|
||||||
|
64.207.219.139 permit
|
||||||
|
64.207.219.140 permit
|
||||||
64.207.219.141 permit
|
64.207.219.141 permit
|
||||||
64.207.219.142 permit
|
64.207.219.142 permit
|
||||||
64.207.219.143 permit
|
64.207.219.143 permit
|
||||||
@@ -396,7 +404,6 @@
|
|||||||
66.196.81.232/31 permit
|
66.196.81.232/31 permit
|
||||||
66.196.81.234 permit
|
66.196.81.234 permit
|
||||||
66.211.168.230/31 permit
|
66.211.168.230/31 permit
|
||||||
66.211.170.86/31 permit
|
|
||||||
66.211.170.88/29 permit
|
66.211.170.88/29 permit
|
||||||
66.211.184.0/23 permit
|
66.211.184.0/23 permit
|
||||||
66.218.74.64/30 permit
|
66.218.74.64/30 permit
|
||||||
@@ -620,7 +627,9 @@
|
|||||||
82.165.229.130 permit
|
82.165.229.130 permit
|
||||||
82.165.230.21 permit
|
82.165.230.21 permit
|
||||||
82.165.230.22 permit
|
82.165.230.22 permit
|
||||||
|
84.116.6.0/23 permit
|
||||||
84.116.36.0/24 permit
|
84.116.36.0/24 permit
|
||||||
|
84.116.50.0/23 permit
|
||||||
85.158.136.0/21 permit
|
85.158.136.0/21 permit
|
||||||
86.61.88.25 permit
|
86.61.88.25 permit
|
||||||
87.198.219.130 permit
|
87.198.219.130 permit
|
||||||
@@ -1192,7 +1201,6 @@
|
|||||||
104.130.96.0/28 permit
|
104.130.96.0/28 permit
|
||||||
104.130.122.0/23 permit
|
104.130.122.0/23 permit
|
||||||
104.214.25.77 permit
|
104.214.25.77 permit
|
||||||
104.245.209.192/26 permit
|
|
||||||
106.10.144.64/27 permit
|
106.10.144.64/27 permit
|
||||||
106.10.144.100/31 permit
|
106.10.144.100/31 permit
|
||||||
106.10.144.103 permit
|
106.10.144.103 permit
|
||||||
@@ -1369,6 +1377,8 @@
|
|||||||
128.245.0.0/20 permit
|
128.245.0.0/20 permit
|
||||||
128.245.64.0/20 permit
|
128.245.64.0/20 permit
|
||||||
128.245.176.0/20 permit
|
128.245.176.0/20 permit
|
||||||
|
128.245.240.0/24 permit
|
||||||
|
128.245.241.0/24 permit
|
||||||
128.245.242.0/24 permit
|
128.245.242.0/24 permit
|
||||||
128.245.242.16 permit
|
128.245.242.16 permit
|
||||||
128.245.242.17 permit
|
128.245.242.17 permit
|
||||||
@@ -1378,6 +1388,7 @@
|
|||||||
128.245.245.0/24 permit
|
128.245.245.0/24 permit
|
||||||
128.245.246.0/24 permit
|
128.245.246.0/24 permit
|
||||||
128.245.247.0/24 permit
|
128.245.247.0/24 permit
|
||||||
|
128.245.248.0/21 permit
|
||||||
129.41.77.70 permit
|
129.41.77.70 permit
|
||||||
129.41.169.249 permit
|
129.41.169.249 permit
|
||||||
129.80.5.164 permit
|
129.80.5.164 permit
|
||||||
@@ -1418,6 +1429,7 @@
|
|||||||
136.143.182.0/23 permit
|
136.143.182.0/23 permit
|
||||||
136.143.184.0/24 permit
|
136.143.184.0/24 permit
|
||||||
136.143.188.0/24 permit
|
136.143.188.0/24 permit
|
||||||
|
136.143.190.0/23 permit
|
||||||
136.147.128.0/20 permit
|
136.147.128.0/20 permit
|
||||||
136.147.135.0/24 permit
|
136.147.135.0/24 permit
|
||||||
136.147.176.0/20 permit
|
136.147.176.0/20 permit
|
||||||
@@ -1454,7 +1466,6 @@
|
|||||||
146.20.215.0/24 permit
|
146.20.215.0/24 permit
|
||||||
146.20.215.182 permit
|
146.20.215.182 permit
|
||||||
146.88.28.0/24 permit
|
146.88.28.0/24 permit
|
||||||
147.160.158.0/24 permit
|
|
||||||
147.243.1.47 permit
|
147.243.1.47 permit
|
||||||
147.243.1.48 permit
|
147.243.1.48 permit
|
||||||
147.243.1.153 permit
|
147.243.1.153 permit
|
||||||
@@ -1492,6 +1503,8 @@
|
|||||||
158.101.211.207 permit
|
158.101.211.207 permit
|
||||||
158.120.80.0/21 permit
|
158.120.80.0/21 permit
|
||||||
158.247.16.0/20 permit
|
158.247.16.0/20 permit
|
||||||
|
159.92.154.0/24 permit
|
||||||
|
159.92.155.0/24 permit
|
||||||
159.92.157.0/24 permit
|
159.92.157.0/24 permit
|
||||||
159.92.157.16 permit
|
159.92.157.16 permit
|
||||||
159.92.157.17 permit
|
159.92.157.17 permit
|
||||||
@@ -1501,6 +1514,9 @@
|
|||||||
159.92.160.0/24 permit
|
159.92.160.0/24 permit
|
||||||
159.92.161.0/24 permit
|
159.92.161.0/24 permit
|
||||||
159.92.162.0/24 permit
|
159.92.162.0/24 permit
|
||||||
|
159.92.163.0/24 permit
|
||||||
|
159.92.164.0/22 permit
|
||||||
|
159.92.168.0/21 permit
|
||||||
159.112.240.0/20 permit
|
159.112.240.0/20 permit
|
||||||
159.112.242.162 permit
|
159.112.242.162 permit
|
||||||
159.135.132.128/25 permit
|
159.135.132.128/25 permit
|
||||||
@@ -1549,6 +1565,8 @@
|
|||||||
168.245.127.231 permit
|
168.245.127.231 permit
|
||||||
169.148.129.0/24 permit
|
169.148.129.0/24 permit
|
||||||
169.148.131.0/24 permit
|
169.148.131.0/24 permit
|
||||||
|
169.148.142.10 permit
|
||||||
|
169.148.144.0/25 permit
|
||||||
170.10.68.0/22 permit
|
170.10.68.0/22 permit
|
||||||
170.10.128.0/24 permit
|
170.10.128.0/24 permit
|
||||||
170.10.129.0/24 permit
|
170.10.129.0/24 permit
|
||||||
@@ -1700,13 +1718,14 @@
|
|||||||
198.244.60.0/22 permit
|
198.244.60.0/22 permit
|
||||||
198.245.80.0/20 permit
|
198.245.80.0/20 permit
|
||||||
198.245.81.0/24 permit
|
198.245.81.0/24 permit
|
||||||
199.15.176.173 permit
|
|
||||||
199.15.213.187 permit
|
199.15.213.187 permit
|
||||||
199.15.226.37 permit
|
199.15.226.37 permit
|
||||||
199.16.156.0/22 permit
|
199.16.156.0/22 permit
|
||||||
199.33.145.1 permit
|
199.33.145.1 permit
|
||||||
199.33.145.32 permit
|
199.33.145.32 permit
|
||||||
|
199.34.22.36 permit
|
||||||
199.59.148.0/22 permit
|
199.59.148.0/22 permit
|
||||||
|
199.67.80.2 permit
|
||||||
199.67.84.0/24 permit
|
199.67.84.0/24 permit
|
||||||
199.67.86.0/24 permit
|
199.67.86.0/24 permit
|
||||||
199.67.88.0/24 permit
|
199.67.88.0/24 permit
|
||||||
|
|||||||
@@ -0,0 +1,91 @@
|
|||||||
|
<?php
|
||||||
|
// File size is limited by Nginx site to 10M
|
||||||
|
// To speed things up, we do not include prerequisites
|
||||||
|
header('Content-Type: text/plain');
|
||||||
|
require_once "vars.inc.php";
|
||||||
|
// Do not show errors, we log to using error_log
|
||||||
|
ini_set('error_reporting', 0);
|
||||||
|
// Init database
|
||||||
|
//$dsn = $database_type . ':host=' . $database_host . ';dbname=' . $database_name;
|
||||||
|
$dsn = $database_type . ":unix_socket=" . $database_sock . ";dbname=" . $database_name;
|
||||||
|
$opt = [
|
||||||
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||||
|
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||||
|
PDO::ATTR_EMULATE_PREPARES => false,
|
||||||
|
];
|
||||||
|
try {
|
||||||
|
$pdo = new PDO($dsn, $database_user, $database_pass, $opt);
|
||||||
|
}
|
||||||
|
catch (PDOException $e) {
|
||||||
|
error_log("FOOTER: " . $e . PHP_EOL);
|
||||||
|
http_response_code(501);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!function_exists('getallheaders')) {
|
||||||
|
function getallheaders() {
|
||||||
|
if (!is_array($_SERVER)) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
$headers = array();
|
||||||
|
foreach ($_SERVER as $name => $value) {
|
||||||
|
if (substr($name, 0, 5) == 'HTTP_') {
|
||||||
|
$headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $headers;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read headers
|
||||||
|
$headers = getallheaders();
|
||||||
|
// Get Domain
|
||||||
|
$domain = $headers['Domain'];
|
||||||
|
// Get Username
|
||||||
|
$username = $headers['Username'];
|
||||||
|
// Get From
|
||||||
|
$from = $headers['From'];
|
||||||
|
// define empty footer
|
||||||
|
$empty_footer = json_encode(array(
|
||||||
|
'html' => '',
|
||||||
|
'plain' => '',
|
||||||
|
'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`
|
||||||
|
WHERE `domain` = :domain");
|
||||||
|
$stmt->execute(array(
|
||||||
|
':domain' => $domain
|
||||||
|
));
|
||||||
|
$footer = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
if (in_array($from, json_decode($footer['mbox_exclude']))){
|
||||||
|
$footer = false;
|
||||||
|
}
|
||||||
|
if (empty($footer)){
|
||||||
|
echo $empty_footer;
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
error_log("FOOTER: " . json_encode($footer) . PHP_EOL);
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare("SELECT `custom_attributes` FROM `mailbox` WHERE `username` = :username");
|
||||||
|
$stmt->execute(array(
|
||||||
|
':username' => $username
|
||||||
|
));
|
||||||
|
$custom_attributes = $stmt->fetch(PDO::FETCH_ASSOC)['custom_attributes'];
|
||||||
|
if (empty($custom_attributes)){
|
||||||
|
$custom_attributes = (object)array();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception $e) {
|
||||||
|
error_log("FOOTER: " . $e->getMessage() . PHP_EOL);
|
||||||
|
http_response_code(502);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// return footer
|
||||||
|
$footer["vars"] = $custom_attributes;
|
||||||
|
echo json_encode($footer);
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
# Uncomment below to apply the ratelimits globally. Use Ratelimits inside mailcow UI to overwrite them for a specific domain/mailbox.
|
||||||
|
# rates {
|
||||||
|
# # Format: "1 / 1h" or "20 / 1m" etc.
|
||||||
|
# to = "100 / 1s";
|
||||||
|
# to_ip = "100 / 1s";
|
||||||
|
# to_ip_from = "100 / 1s";
|
||||||
|
# bounce_to = "100 / 1h";
|
||||||
|
# bounce_to_ip = "7 / 1m";
|
||||||
|
# }
|
||||||
@@ -527,20 +527,21 @@ rspamd_config:register_symbol({
|
|||||||
name = 'MOO_FOOTER',
|
name = 'MOO_FOOTER',
|
||||||
type = 'prefilter',
|
type = 'prefilter',
|
||||||
callback = function(task)
|
callback = function(task)
|
||||||
|
local cjson = require "cjson"
|
||||||
local lua_mime = require "lua_mime"
|
local lua_mime = require "lua_mime"
|
||||||
local lua_util = require "lua_util"
|
local lua_util = require "lua_util"
|
||||||
local rspamd_logger = require "rspamd_logger"
|
local rspamd_logger = require "rspamd_logger"
|
||||||
local rspamd_redis = require "rspamd_redis"
|
local rspamd_http = require "rspamd_http"
|
||||||
local ucl = require "ucl"
|
|
||||||
local redis_params = rspamd_parse_redis_server('footer')
|
|
||||||
local envfrom = task:get_from(1)
|
local envfrom = task:get_from(1)
|
||||||
local uname = task:get_user()
|
local uname = task:get_user()
|
||||||
if not envfrom or not uname then
|
if not envfrom or not uname then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
local uname = uname:lower()
|
local uname = uname:lower()
|
||||||
local env_from_domain = envfrom[1].domain:lower() -- get smtp from domain in lower case
|
local env_from_domain = envfrom[1].domain:lower()
|
||||||
|
local env_from_addr = envfrom[1].addr:lower()
|
||||||
|
|
||||||
|
-- determine newline type
|
||||||
local function newline(task)
|
local function newline(task)
|
||||||
local t = task:get_newlines_type()
|
local t = task:get_newlines_type()
|
||||||
|
|
||||||
@@ -552,20 +553,19 @@ rspamd_config:register_symbol({
|
|||||||
|
|
||||||
return '\r\n'
|
return '\r\n'
|
||||||
end
|
end
|
||||||
local function redis_cb_footer(err, data)
|
-- retrieve footer
|
||||||
|
local function footer_cb(err_message, code, data, headers)
|
||||||
if err or type(data) ~= 'string' then
|
if err or type(data) ~= 'string' then
|
||||||
rspamd_logger.infox(rspamd_config, "domain wide footer request for user %s returned invalid or empty data (\"%s\") or error (\"%s\")", uname, data, err)
|
rspamd_logger.infox(rspamd_config, "domain wide footer request for user %s returned invalid or empty data (\"%s\") or error (\"%s\")", uname, data, err)
|
||||||
else
|
else
|
||||||
|
|
||||||
-- parse json string
|
-- parse json string
|
||||||
local parser = ucl.parser()
|
local footer = cjson.decode(data)
|
||||||
local res,err = parser:parse_string(data)
|
if not footer then
|
||||||
if not res then
|
|
||||||
rspamd_logger.infox(rspamd_config, "parsing domain wide footer for user %s returned invalid or empty data (\"%s\") or error (\"%s\")", uname, data, err)
|
rspamd_logger.infox(rspamd_config, "parsing domain wide footer for user %s returned invalid or empty data (\"%s\") or error (\"%s\")", uname, data, err)
|
||||||
else
|
else
|
||||||
local footer = parser:get_object()
|
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 and type(footer) == "table" and (footer.html or footer.plain) then
|
|
||||||
rspamd_logger.infox(rspamd_config, "found domain wide footer for user %s: html=%s, plain=%s", uname, footer.html, footer.plain)
|
|
||||||
|
|
||||||
local envfrom_mime = task:get_from(2)
|
local envfrom_mime = task:get_from(2)
|
||||||
local from_name = ""
|
local from_name = ""
|
||||||
@@ -575,6 +575,7 @@ rspamd_config:register_symbol({
|
|||||||
from_name = envfrom[1].name
|
from_name = envfrom[1].name
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- default replacements
|
||||||
local replacements = {
|
local replacements = {
|
||||||
auth_user = uname,
|
auth_user = uname,
|
||||||
from_user = envfrom[1].user,
|
from_user = envfrom[1].user,
|
||||||
@@ -582,10 +583,20 @@ rspamd_config:register_symbol({
|
|||||||
from_addr = envfrom[1].addr,
|
from_addr = envfrom[1].addr,
|
||||||
from_domain = envfrom[1].domain:lower()
|
from_domain = envfrom[1].domain:lower()
|
||||||
}
|
}
|
||||||
if footer.html then
|
-- add custom mailbox attributes
|
||||||
|
if footer.vars and type(footer.vars) == "string" then
|
||||||
|
local footer_vars = cjson.decode(footer.vars)
|
||||||
|
|
||||||
|
if type(footer_vars) == "table" then
|
||||||
|
for key, value in pairs(footer_vars) do
|
||||||
|
replacements[key] = value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if footer.html and footer.html ~= "" then
|
||||||
footer.html = lua_util.jinja_template(footer.html, replacements, true)
|
footer.html = lua_util.jinja_template(footer.html, replacements, true)
|
||||||
end
|
end
|
||||||
if footer.plain then
|
if footer.plain and footer.plain ~= "" then
|
||||||
footer.plain = lua_util.jinja_template(footer.plain, replacements, true)
|
footer.plain = lua_util.jinja_template(footer.plain, replacements, true)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -631,15 +642,19 @@ rspamd_config:register_symbol({
|
|||||||
end
|
end
|
||||||
local out_parts = {}
|
local out_parts = {}
|
||||||
for _,o in ipairs(out) do
|
for _,o in ipairs(out) do
|
||||||
if type(o) ~= 'table' then
|
if type(o) ~= 'table' then
|
||||||
out_parts[#out_parts + 1] = o
|
out_parts[#out_parts + 1] = o
|
||||||
out_parts[#out_parts + 1] = newline_s
|
out_parts[#out_parts + 1] = newline_s
|
||||||
else
|
else
|
||||||
out_parts[#out_parts + 1] = o[1]
|
local removePrefix = "--\x0D\x0AContent-Type"
|
||||||
if o[2] then
|
if string.lower(string.sub(tostring(o[1]), 1, string.len(removePrefix))) == string.lower(removePrefix) then
|
||||||
out_parts[#out_parts + 1] = newline_s
|
o[1] = string.sub(tostring(o[1]), string.len("--\x0D\x0A") + 1)
|
||||||
end
|
end
|
||||||
end
|
out_parts[#out_parts + 1] = o[1]
|
||||||
|
if o[2] then
|
||||||
|
out_parts[#out_parts + 1] = newline_s
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
task:set_message(out_parts)
|
task:set_message(out_parts)
|
||||||
else
|
else
|
||||||
@@ -649,17 +664,14 @@ rspamd_config:register_symbol({
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local redis_ret_footer = rspamd_redis_make_request(task,
|
-- fetch footer
|
||||||
redis_params, -- connect params
|
rspamd_http.request({
|
||||||
env_from_domain, -- hash key
|
task=task,
|
||||||
false, -- is write
|
url='http://nginx:8081/footer.php',
|
||||||
redis_cb_footer, --callback
|
body='',
|
||||||
'HGET', -- command
|
callback=footer_cb,
|
||||||
{"DOMAIN_WIDE_FOOTER", env_from_domain} -- arguments
|
headers={Domain=env_from_domain,Username=uname,From=env_from_addr},
|
||||||
)
|
})
|
||||||
if not redis_ret_footer then
|
|
||||||
rspamd_logger.infox(rspamd_config, "cannot make request to load footer for domain")
|
|
||||||
end
|
|
||||||
|
|
||||||
return true
|
return true
|
||||||
end,
|
end,
|
||||||
|
|||||||
@@ -1,11 +1,3 @@
|
|||||||
rates {
|
|
||||||
# Format: "1 / 1h" or "20 / 1m" etc. - global ratelimits are disabled by default
|
|
||||||
to = "100 / 1s";
|
|
||||||
to_ip = "100 / 1s";
|
|
||||||
to_ip_from = "100 / 1s";
|
|
||||||
bounce_to = "100 / 1h";
|
|
||||||
bounce_to_ip = "7 / 1m";
|
|
||||||
}
|
|
||||||
whitelisted_rcpts = "postmaster,mailer-daemon";
|
whitelisted_rcpts = "postmaster,mailer-daemon";
|
||||||
max_rcpt = 25;
|
max_rcpt = 25;
|
||||||
custom_keywords = "/etc/rspamd/lua/ratelimit.lua";
|
custom_keywords = "/etc/rspamd/lua/ratelimit.lua";
|
||||||
|
|||||||
@@ -3137,6 +3137,86 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
type: object
|
type: object
|
||||||
summary: Update domain
|
summary: Update domain
|
||||||
|
/api/v1/edit/domain/footer:
|
||||||
|
post:
|
||||||
|
responses:
|
||||||
|
"401":
|
||||||
|
$ref: "#/components/responses/Unauthorized"
|
||||||
|
"200":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
examples:
|
||||||
|
response:
|
||||||
|
value:
|
||||||
|
- log:
|
||||||
|
- mailbox
|
||||||
|
- edit
|
||||||
|
- domain_wide_footer
|
||||||
|
- domains:
|
||||||
|
- mailcow.tld
|
||||||
|
html: "<br>foo {= foo =}"
|
||||||
|
plain: "<foo {= foo =}"
|
||||||
|
mbox_exclude:
|
||||||
|
- moo@mailcow.tld
|
||||||
|
- null
|
||||||
|
msg:
|
||||||
|
- domain_footer_modified
|
||||||
|
- mailcow.tld
|
||||||
|
type: success
|
||||||
|
schema:
|
||||||
|
properties:
|
||||||
|
log:
|
||||||
|
description: contains request object
|
||||||
|
items: {}
|
||||||
|
type: array
|
||||||
|
msg:
|
||||||
|
items: {}
|
||||||
|
type: array
|
||||||
|
type:
|
||||||
|
enum:
|
||||||
|
- success
|
||||||
|
- danger
|
||||||
|
- error
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
description: OK
|
||||||
|
headers: {}
|
||||||
|
tags:
|
||||||
|
- Domains
|
||||||
|
description: >-
|
||||||
|
You can update the footer of one or more domains per request.
|
||||||
|
operationId: Update domain wide footer
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
example:
|
||||||
|
attr:
|
||||||
|
html: "<br>foo {= foo =}"
|
||||||
|
plain: "foo {= foo =}"
|
||||||
|
mbox_exclude:
|
||||||
|
- moo@mailcow.tld
|
||||||
|
items: mailcow.tld
|
||||||
|
properties:
|
||||||
|
attr:
|
||||||
|
properties:
|
||||||
|
html:
|
||||||
|
description: Footer text in HTML format
|
||||||
|
type: string
|
||||||
|
plain:
|
||||||
|
description: Footer text in PLAIN text format
|
||||||
|
type: string
|
||||||
|
mbox_exclude:
|
||||||
|
description: Array of mailboxes to exclude from domain wide footer
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
items:
|
||||||
|
description: contains a list of domain names where you want to update the footer
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
summary: Update domain wide footer
|
||||||
/api/v1/edit/fail2ban:
|
/api/v1/edit/fail2ban:
|
||||||
post:
|
post:
|
||||||
responses:
|
responses:
|
||||||
@@ -3336,6 +3416,86 @@ paths:
|
|||||||
type: object
|
type: object
|
||||||
type: object
|
type: object
|
||||||
summary: Update mailbox
|
summary: Update mailbox
|
||||||
|
/api/v1/edit/mailbox/custom-attribute:
|
||||||
|
post:
|
||||||
|
responses:
|
||||||
|
"401":
|
||||||
|
$ref: "#/components/responses/Unauthorized"
|
||||||
|
"200":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
examples:
|
||||||
|
response:
|
||||||
|
value:
|
||||||
|
- log:
|
||||||
|
- mailbox
|
||||||
|
- edit
|
||||||
|
- mailbox_custom_attribute
|
||||||
|
- mailboxes:
|
||||||
|
- moo@mailcow.tld
|
||||||
|
attribute:
|
||||||
|
- role
|
||||||
|
- foo
|
||||||
|
value:
|
||||||
|
- cow
|
||||||
|
- bar
|
||||||
|
- null
|
||||||
|
msg:
|
||||||
|
- mailbox_modified
|
||||||
|
- moo@mailcow.tld
|
||||||
|
type: success
|
||||||
|
schema:
|
||||||
|
properties:
|
||||||
|
log:
|
||||||
|
description: contains request object
|
||||||
|
items: {}
|
||||||
|
type: array
|
||||||
|
msg:
|
||||||
|
items: {}
|
||||||
|
type: array
|
||||||
|
type:
|
||||||
|
enum:
|
||||||
|
- success
|
||||||
|
- danger
|
||||||
|
- error
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
description: OK
|
||||||
|
headers: {}
|
||||||
|
tags:
|
||||||
|
- Mailboxes
|
||||||
|
description: >-
|
||||||
|
You can update custom attributes of one or more mailboxes per request.
|
||||||
|
operationId: Update mailbox custom attributes
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
example:
|
||||||
|
attr:
|
||||||
|
attribute:
|
||||||
|
- role
|
||||||
|
- foo
|
||||||
|
value:
|
||||||
|
- cow
|
||||||
|
- bar
|
||||||
|
items:
|
||||||
|
- moo@mailcow.tld
|
||||||
|
properties:
|
||||||
|
attr:
|
||||||
|
properties:
|
||||||
|
attribute:
|
||||||
|
description: Array of attribute keys
|
||||||
|
type: object
|
||||||
|
value:
|
||||||
|
description: Array of attribute values
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
items:
|
||||||
|
description: contains list of mailboxes you want update
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
summary: Update mailbox custom attributes
|
||||||
/api/v1/edit/mailq:
|
/api/v1/edit/mailq:
|
||||||
post:
|
post:
|
||||||
responses:
|
responses:
|
||||||
@@ -5581,6 +5741,7 @@ paths:
|
|||||||
sogo_access: "1"
|
sogo_access: "1"
|
||||||
tls_enforce_in: "0"
|
tls_enforce_in: "0"
|
||||||
tls_enforce_out: "0"
|
tls_enforce_out: "0"
|
||||||
|
custom_attributes: {}
|
||||||
domain: domain3.tld
|
domain: domain3.tld
|
||||||
is_relayed: 0
|
is_relayed: 0
|
||||||
local_part: info
|
local_part: info
|
||||||
@@ -5646,6 +5807,40 @@ paths:
|
|||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
summary: Edit Cross-Origin Resource Sharing (CORS) settings
|
summary: Edit Cross-Origin Resource Sharing (CORS) settings
|
||||||
|
"/api/v1/get/spam-score/{mailbox}":
|
||||||
|
get:
|
||||||
|
parameters:
|
||||||
|
- description: name of mailbox or empty for current user - admin user will retrieve the global spam filter score
|
||||||
|
in: path
|
||||||
|
name: mailbox
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- description: e.g. api-key-string
|
||||||
|
example: api-key-string
|
||||||
|
in: header
|
||||||
|
name: X-API-Key
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"401":
|
||||||
|
$ref: "#/components/responses/Unauthorized"
|
||||||
|
"200":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
examples:
|
||||||
|
response:
|
||||||
|
value:
|
||||||
|
spam_score: "8,15"
|
||||||
|
description: OK
|
||||||
|
headers: {}
|
||||||
|
tags:
|
||||||
|
- Mailboxes
|
||||||
|
description: >-
|
||||||
|
Using this endpoint you can get the global spam filter score or the spam filter score of a certain mailbox.
|
||||||
|
operationId: Get mailbox or global spam filter score
|
||||||
|
summary: Get mailbox or global spam filter score
|
||||||
|
|
||||||
tags:
|
tags:
|
||||||
- name: Domains
|
- name: Domains
|
||||||
|
|||||||
@@ -58,6 +58,8 @@ if (isset($_SESSION['mailcow_cc_role'])) {
|
|||||||
'dkim' => dkim('details', $domain),
|
'dkim' => dkim('details', $domain),
|
||||||
'domain_details' => $result,
|
'domain_details' => $result,
|
||||||
'domain_footer' => $domain_footer,
|
'domain_footer' => $domain_footer,
|
||||||
|
'mailboxes' => mailbox('get', 'mailboxes', $_GET["domain"]),
|
||||||
|
'aliases' => mailbox('get', 'aliases', $_GET["domain"], 'address')
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -218,6 +220,7 @@ $js_minifier->add('/web/js/site/pwgen.js');
|
|||||||
$template_data['result'] = $result;
|
$template_data['result'] = $result;
|
||||||
$template_data['return_to'] = $_SESSION['return_to'];
|
$template_data['return_to'] = $_SESSION['return_to'];
|
||||||
$template_data['lang_user'] = json_encode($lang['user']);
|
$template_data['lang_user'] = json_encode($lang['user']);
|
||||||
|
$template_data['lang_admin'] = json_encode($lang['admin']);
|
||||||
$template_data['lang_datatables'] = json_encode($lang['datatables']);
|
$template_data['lang_datatables'] = json_encode($lang['datatables']);
|
||||||
|
|
||||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/footer.inc.php';
|
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/footer.inc.php';
|
||||||
|
|||||||
@@ -325,6 +325,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
|||||||
$timeout2 = intval($_data['timeout2']);
|
$timeout2 = intval($_data['timeout2']);
|
||||||
$skipcrossduplicates = intval($_data['skipcrossduplicates']);
|
$skipcrossduplicates = intval($_data['skipcrossduplicates']);
|
||||||
$automap = intval($_data['automap']);
|
$automap = intval($_data['automap']);
|
||||||
|
$dry = intval($_data['dry']);
|
||||||
$port1 = $_data['port1'];
|
$port1 = $_data['port1'];
|
||||||
$host1 = strtolower($_data['host1']);
|
$host1 = strtolower($_data['host1']);
|
||||||
$password1 = $_data['password1'];
|
$password1 = $_data['password1'];
|
||||||
@@ -435,8 +436,8 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
|||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$stmt = $pdo->prepare("INSERT INTO `imapsync` (`user2`, `exclude`, `delete1`, `delete2`, `timeout1`, `timeout2`, `automap`, `skipcrossduplicates`, `maxbytespersecond`, `subscribeall`, `maxage`, `subfolder2`, `host1`, `authmech1`, `user1`, `password1`, `mins_interval`, `port1`, `enc1`, `delete2duplicates`, `custom_params`, `active`)
|
$stmt = $pdo->prepare("INSERT INTO `imapsync` (`user2`, `exclude`, `delete1`, `delete2`, `timeout1`, `timeout2`, `automap`, `skipcrossduplicates`, `maxbytespersecond`, `subscribeall`, `dry`, `maxage`, `subfolder2`, `host1`, `authmech1`, `user1`, `password1`, `mins_interval`, `port1`, `enc1`, `delete2duplicates`, `custom_params`, `active`)
|
||||||
VALUES (:user2, :exclude, :delete1, :delete2, :timeout1, :timeout2, :automap, :skipcrossduplicates, :maxbytespersecond, :subscribeall, :maxage, :subfolder2, :host1, :authmech1, :user1, :password1, :mins_interval, :port1, :enc1, :delete2duplicates, :custom_params, :active)");
|
VALUES (:user2, :exclude, :delete1, :delete2, :timeout1, :timeout2, :automap, :skipcrossduplicates, :maxbytespersecond, :subscribeall, :dry, :maxage, :subfolder2, :host1, :authmech1, :user1, :password1, :mins_interval, :port1, :enc1, :delete2duplicates, :custom_params, :active)");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':user2' => $username,
|
':user2' => $username,
|
||||||
':custom_params' => $custom_params,
|
':custom_params' => $custom_params,
|
||||||
@@ -450,6 +451,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
|||||||
':skipcrossduplicates' => $skipcrossduplicates,
|
':skipcrossduplicates' => $skipcrossduplicates,
|
||||||
':maxbytespersecond' => $maxbytespersecond,
|
':maxbytespersecond' => $maxbytespersecond,
|
||||||
':subscribeall' => $subscribeall,
|
':subscribeall' => $subscribeall,
|
||||||
|
':dry' => $dry,
|
||||||
':subfolder2' => $subfolder2,
|
':subfolder2' => $subfolder2,
|
||||||
':host1' => $host1,
|
':host1' => $host1,
|
||||||
':authmech1' => 'PLAIN',
|
':authmech1' => 'PLAIN',
|
||||||
@@ -2031,6 +2033,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
|||||||
$success = (isset($_data['success'])) ? NULL : $is_now['success'];
|
$success = (isset($_data['success'])) ? NULL : $is_now['success'];
|
||||||
$delete2duplicates = (isset($_data['delete2duplicates'])) ? intval($_data['delete2duplicates']) : $is_now['delete2duplicates'];
|
$delete2duplicates = (isset($_data['delete2duplicates'])) ? intval($_data['delete2duplicates']) : $is_now['delete2duplicates'];
|
||||||
$subscribeall = (isset($_data['subscribeall'])) ? intval($_data['subscribeall']) : $is_now['subscribeall'];
|
$subscribeall = (isset($_data['subscribeall'])) ? intval($_data['subscribeall']) : $is_now['subscribeall'];
|
||||||
|
$dry = (isset($_data['dry'])) ? intval($_data['dry']) : $is_now['dry'];
|
||||||
$delete1 = (isset($_data['delete1'])) ? intval($_data['delete1']) : $is_now['delete1'];
|
$delete1 = (isset($_data['delete1'])) ? intval($_data['delete1']) : $is_now['delete1'];
|
||||||
$delete2 = (isset($_data['delete2'])) ? intval($_data['delete2']) : $is_now['delete2'];
|
$delete2 = (isset($_data['delete2'])) ? intval($_data['delete2']) : $is_now['delete2'];
|
||||||
$automap = (isset($_data['automap'])) ? intval($_data['automap']) : $is_now['automap'];
|
$automap = (isset($_data['automap'])) ? intval($_data['automap']) : $is_now['automap'];
|
||||||
@@ -2164,6 +2167,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
|||||||
`timeout1` = :timeout1,
|
`timeout1` = :timeout1,
|
||||||
`timeout2` = :timeout2,
|
`timeout2` = :timeout2,
|
||||||
`subscribeall` = :subscribeall,
|
`subscribeall` = :subscribeall,
|
||||||
|
`dry` = :dry,
|
||||||
`active` = :active
|
`active` = :active
|
||||||
WHERE `id` = :id");
|
WHERE `id` = :id");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
@@ -2189,6 +2193,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
|||||||
':timeout1' => $timeout1,
|
':timeout1' => $timeout1,
|
||||||
':timeout2' => $timeout2,
|
':timeout2' => $timeout2,
|
||||||
':subscribeall' => $subscribeall,
|
':subscribeall' => $subscribeall,
|
||||||
|
':dry' => $dry,
|
||||||
':active' => $active,
|
':active' => $active,
|
||||||
));
|
));
|
||||||
$_SESSION['return'][] = array(
|
$_SESSION['return'][] = array(
|
||||||
@@ -3259,6 +3264,62 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
|||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
case 'mailbox_custom_attribute':
|
||||||
|
$_data['attribute'] = isset($_data['attribute']) ? $_data['attribute'] : array();
|
||||||
|
$_data['attribute'] = is_array($_data['attribute']) ? $_data['attribute'] : array($_data['attribute']);
|
||||||
|
$_data['attribute'] = array_map(function($value) { return str_replace(' ', '', $value); }, $_data['attribute']);
|
||||||
|
$_data['value'] = isset($_data['value']) ? $_data['value'] : array();
|
||||||
|
$_data['value'] = is_array($_data['value']) ? $_data['value'] : array($_data['value']);
|
||||||
|
$attributes = (object)array_combine($_data['attribute'], $_data['value']);
|
||||||
|
$mailboxes = is_array($_data['mailboxes']) ? $_data['mailboxes'] : array($_data['mailboxes']);
|
||||||
|
|
||||||
|
foreach ($mailboxes as $mailbox) {
|
||||||
|
if (!filter_var($mailbox, FILTER_VALIDATE_EMAIL)) {
|
||||||
|
$_SESSION['return'][] = array(
|
||||||
|
'type' => 'danger',
|
||||||
|
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||||
|
'msg' => array('username_invalid', $mailbox)
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$is_now = mailbox('get', 'mailbox_details', $mailbox);
|
||||||
|
if(!empty($is_now)){
|
||||||
|
if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $is_now['domain'])) {
|
||||||
|
$_SESSION['return'][] = array(
|
||||||
|
'type' => 'danger',
|
||||||
|
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||||
|
'msg' => 'access_denied'
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$_SESSION['return'][] = array(
|
||||||
|
'type' => 'danger',
|
||||||
|
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||||
|
'msg' => 'access_denied'
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare("UPDATE `mailbox`
|
||||||
|
SET `custom_attributes` = :custom_attributes
|
||||||
|
WHERE username = :username");
|
||||||
|
$stmt->execute(array(
|
||||||
|
":username" => $mailbox,
|
||||||
|
":custom_attributes" => json_encode($attributes)
|
||||||
|
));
|
||||||
|
|
||||||
|
$_SESSION['return'][] = array(
|
||||||
|
'type' => 'success',
|
||||||
|
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||||
|
'msg' => array('mailbox_modified', $mailbox)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
case 'resource':
|
case 'resource':
|
||||||
if (!is_array($_data['name'])) {
|
if (!is_array($_data['name'])) {
|
||||||
$names = array();
|
$names = array();
|
||||||
@@ -3338,44 +3399,89 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'domain_wide_footer':
|
case 'domain_wide_footer':
|
||||||
$domain = idn_to_ascii(strtolower(trim($_data['domain'])), 0, INTL_IDNA_VARIANT_UTS46);
|
if (!is_array($_data['domains'])) {
|
||||||
if (!is_valid_domain_name($domain)) {
|
$domains = array();
|
||||||
$_SESSION['return'][] = array(
|
$domains[] = $_data['domains'];
|
||||||
'type' => 'danger',
|
|
||||||
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
|
||||||
'msg' => 'domain_invalid'
|
|
||||||
);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
|
else {
|
||||||
$_SESSION['return'][] = array(
|
$domains = $_data['domains'];
|
||||||
'type' => 'danger',
|
|
||||||
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
|
||||||
'msg' => 'access_denied'
|
|
||||||
);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$footers = array();
|
$footers = array();
|
||||||
$footers['html'] = isset($_data['footer_html']) ? $_data['footer_html'] : '';
|
$footers['html'] = isset($_data['html']) ? $_data['html'] : '';
|
||||||
$footers['plain'] = isset($_data['footer_plain']) ? $_data['footer_plain'] : '';
|
$footers['plain'] = isset($_data['plain']) ? $_data['plain'] : '';
|
||||||
try {
|
$footers['mbox_exclude'] = array();
|
||||||
$redis->hSet('DOMAIN_WIDE_FOOTER', $domain, json_encode($footers));
|
if (isset($_data["mbox_exclude"])){
|
||||||
|
if (!is_array($_data["mbox_exclude"])) {
|
||||||
|
$_data["mbox_exclude"] = array($_data["mbox_exclude"]);
|
||||||
|
}
|
||||||
|
foreach ($_data["mbox_exclude"] as $mailbox) {
|
||||||
|
if (!filter_var($mailbox, FILTER_VALIDATE_EMAIL)) {
|
||||||
|
$_SESSION['return'][] = array(
|
||||||
|
'type' => 'danger',
|
||||||
|
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||||
|
'msg' => array('username_invalid', $mailbox)
|
||||||
|
);
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (RedisException $e) {
|
foreach ($domains as $domain) {
|
||||||
|
$domain = idn_to_ascii(strtolower(trim($domain)), 0, INTL_IDNA_VARIANT_UTS46);
|
||||||
|
if (!is_valid_domain_name($domain)) {
|
||||||
|
$_SESSION['return'][] = array(
|
||||||
|
'type' => 'danger',
|
||||||
|
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||||
|
'msg' => 'domain_invalid'
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
|
||||||
|
$_SESSION['return'][] = array(
|
||||||
|
'type' => 'danger',
|
||||||
|
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||||
|
'msg' => 'access_denied'
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
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->execute(array(
|
||||||
|
':domain' => $domain,
|
||||||
|
':html' => $footers['html'],
|
||||||
|
':plain' => $footers['plain'],
|
||||||
|
':mbox_exclude' => json_encode($footers['mbox_exclude']),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
catch (PDOException $e) {
|
||||||
|
$_SESSION['return'][] = array(
|
||||||
|
'type' => 'danger',
|
||||||
|
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||||
|
'msg' => $e->getMessage()
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$_SESSION['return'][] = array(
|
$_SESSION['return'][] = array(
|
||||||
'type' => 'danger',
|
'type' => 'success',
|
||||||
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||||
'msg' => array('redis_error', $e)
|
'msg' => array('domain_footer_modified', htmlspecialchars($domain))
|
||||||
);
|
);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
$_SESSION['return'][] = array(
|
|
||||||
'type' => 'success',
|
|
||||||
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
|
||||||
'msg' => array('domain_footer_modified', htmlspecialchars($domain))
|
|
||||||
);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -3929,13 +4035,17 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
|||||||
if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
|
if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$stmt = $pdo->prepare("SELECT `id` FROM `alias` WHERE `address` != `goto` AND `domain` = :domain");
|
$stmt = $pdo->prepare("SELECT `id`, `address` FROM `alias` WHERE `address` != `goto` AND `domain` = :domain");
|
||||||
$stmt->execute(array(
|
$stmt->execute(array(
|
||||||
':domain' => $_data,
|
':domain' => $_data,
|
||||||
));
|
));
|
||||||
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
while($row = array_shift($rows)) {
|
while($row = array_shift($rows)) {
|
||||||
$aliases[] = $row['id'];
|
if ($_extra == "address"){
|
||||||
|
$aliases[] = $row['address'];
|
||||||
|
} else {
|
||||||
|
$aliases[] = $row['id'];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return $aliases;
|
return $aliases;
|
||||||
break;
|
break;
|
||||||
@@ -4287,6 +4397,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
|||||||
`mailbox`.`modified`,
|
`mailbox`.`modified`,
|
||||||
`quota2`.`bytes`,
|
`quota2`.`bytes`,
|
||||||
`attributes`,
|
`attributes`,
|
||||||
|
`custom_attributes`,
|
||||||
`quota2`.`messages`
|
`quota2`.`messages`
|
||||||
FROM `mailbox`, `quota2`, `domain`
|
FROM `mailbox`, `quota2`, `domain`
|
||||||
WHERE (`mailbox`.`kind` = '' OR `mailbox`.`kind` = NULL)
|
WHERE (`mailbox`.`kind` = '' OR `mailbox`.`kind` = NULL)
|
||||||
@@ -4307,6 +4418,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
|||||||
`mailbox`.`modified`,
|
`mailbox`.`modified`,
|
||||||
`quota2replica`.`bytes`,
|
`quota2replica`.`bytes`,
|
||||||
`attributes`,
|
`attributes`,
|
||||||
|
`custom_attributes`,
|
||||||
`quota2replica`.`messages`
|
`quota2replica`.`messages`
|
||||||
FROM `mailbox`, `quota2replica`, `domain`
|
FROM `mailbox`, `quota2replica`, `domain`
|
||||||
WHERE (`mailbox`.`kind` = '' OR `mailbox`.`kind` = NULL)
|
WHERE (`mailbox`.`kind` = '' OR `mailbox`.`kind` = NULL)
|
||||||
@@ -4329,6 +4441,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
|||||||
$mailboxdata['quota'] = $row['quota'];
|
$mailboxdata['quota'] = $row['quota'];
|
||||||
$mailboxdata['messages'] = $row['messages'];
|
$mailboxdata['messages'] = $row['messages'];
|
||||||
$mailboxdata['attributes'] = json_decode($row['attributes'], true);
|
$mailboxdata['attributes'] = json_decode($row['attributes'], true);
|
||||||
|
$mailboxdata['custom_attributes'] = json_decode($row['custom_attributes'], true);
|
||||||
$mailboxdata['quota_used'] = intval($row['bytes']);
|
$mailboxdata['quota_used'] = intval($row['bytes']);
|
||||||
$mailboxdata['percent_in_use'] = ($row['quota'] == 0) ? '- ' : round((intval($row['bytes']) / intval($row['quota'])) * 100);
|
$mailboxdata['percent_in_use'] = ($row['quota'] == 0) ? '- ' : round((intval($row['bytes']) / intval($row['quota'])) * 100);
|
||||||
$mailboxdata['created'] = $row['created'];
|
$mailboxdata['created'] = $row['created'];
|
||||||
@@ -4509,19 +4622,23 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$footers = $redis->hGet('DOMAIN_WIDE_FOOTER', $domain);
|
$stmt = $pdo->prepare("SELECT `html`, `plain`, `mbox_exclude` FROM `domain_wide_footer`
|
||||||
$footers = json_decode($footers, true);
|
WHERE `domain` = :domain");
|
||||||
|
$stmt->execute(array(
|
||||||
|
':domain' => $domain
|
||||||
|
));
|
||||||
|
$footer = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
}
|
}
|
||||||
catch (RedisException $e) {
|
catch (PDOException $e) {
|
||||||
$_SESSION['return'][] = array(
|
$_SESSION['return'][] = array(
|
||||||
'type' => 'danger',
|
'type' => 'danger',
|
||||||
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||||
'msg' => array('redis_error', $e)
|
'msg' => $e->getMessage()
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $footers;
|
return $footer;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ function init_db_schema() {
|
|||||||
try {
|
try {
|
||||||
global $pdo;
|
global $pdo;
|
||||||
|
|
||||||
$db_version = "14022023_1000";
|
$db_version = "21112023_1644";
|
||||||
|
|
||||||
$stmt = $pdo->query("SHOW TABLES LIKE 'versions'");
|
$stmt = $pdo->query("SHOW TABLES LIKE 'versions'");
|
||||||
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||||
@@ -267,6 +267,20 @@ function init_db_schema() {
|
|||||||
),
|
),
|
||||||
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
),
|
),
|
||||||
|
"domain_wide_footer" => array(
|
||||||
|
"cols" => array(
|
||||||
|
"domain" => "VARCHAR(255) NOT NULL",
|
||||||
|
"html" => "LONGTEXT",
|
||||||
|
"plain" => "LONGTEXT",
|
||||||
|
"mbox_exclude" => "JSON NOT NULL DEFAULT ('[]')",
|
||||||
|
),
|
||||||
|
"keys" => array(
|
||||||
|
"primary" => array(
|
||||||
|
"" => array("domain")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||||
|
),
|
||||||
"tags_domain" => array(
|
"tags_domain" => array(
|
||||||
"cols" => array(
|
"cols" => array(
|
||||||
"tag_name" => "VARCHAR(255) NOT NULL",
|
"tag_name" => "VARCHAR(255) NOT NULL",
|
||||||
@@ -344,6 +358,7 @@ function init_db_schema() {
|
|||||||
"local_part" => "VARCHAR(255) NOT NULL",
|
"local_part" => "VARCHAR(255) NOT NULL",
|
||||||
"domain" => "VARCHAR(255) NOT NULL",
|
"domain" => "VARCHAR(255) NOT NULL",
|
||||||
"attributes" => "JSON",
|
"attributes" => "JSON",
|
||||||
|
"custom_attributes" => "JSON NOT NULL DEFAULT ('{}')",
|
||||||
"kind" => "VARCHAR(100) NOT NULL DEFAULT ''",
|
"kind" => "VARCHAR(100) NOT NULL DEFAULT ''",
|
||||||
"multiple_bookings" => "INT NOT NULL DEFAULT -1",
|
"multiple_bookings" => "INT NOT NULL DEFAULT -1",
|
||||||
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
|
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
|
||||||
@@ -704,6 +719,7 @@ function init_db_schema() {
|
|||||||
"timeout1" => "SMALLINT NOT NULL DEFAULT '600'",
|
"timeout1" => "SMALLINT NOT NULL DEFAULT '600'",
|
||||||
"timeout2" => "SMALLINT NOT NULL DEFAULT '600'",
|
"timeout2" => "SMALLINT NOT NULL DEFAULT '600'",
|
||||||
"subscribeall" => "TINYINT(1) NOT NULL DEFAULT '1'",
|
"subscribeall" => "TINYINT(1) NOT NULL DEFAULT '1'",
|
||||||
|
"dry" => "TINYINT(1) NOT NULL DEFAULT '0'",
|
||||||
"is_running" => "TINYINT(1) NOT NULL DEFAULT '0'",
|
"is_running" => "TINYINT(1) NOT NULL DEFAULT '0'",
|
||||||
"returned_text" => "LONGTEXT",
|
"returned_text" => "LONGTEXT",
|
||||||
"last_run" => "TIMESTAMP NULL DEFAULT NULL",
|
"last_run" => "TIMESTAMP NULL DEFAULT NULL",
|
||||||
|
|||||||
+4
-4
@@ -19,10 +19,10 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Cache dependencies
|
- name: Cache dependencies
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: ~/.composer/cache/files
|
path: ~/.composer/cache/files
|
||||||
key: dependencies-php-${{ matrix.php }}-composer-${{ hashFiles('composer.json') }}
|
key: dependencies-php-${{ matrix.php }}-composer-${{ hashFiles('composer.json') }}
|
||||||
@@ -52,10 +52,10 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Cache dependencies
|
- name: Cache dependencies
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: ~/.composer/cache/files
|
path: ~/.composer/cache/files
|
||||||
key: dependencies-php-${{ matrix.php }}-composer-${{ hashFiles('composer.json') }}
|
key: dependencies-php-${{ matrix.php }}-composer-${{ hashFiles('composer.json') }}
|
||||||
|
|||||||
Vendored
+3
-3
@@ -12,7 +12,7 @@ jobs:
|
|||||||
dependency-version: [prefer-lowest, prefer-stable]
|
dependency-version: [prefer-lowest, prefer-stable]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v1
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup PHP
|
- name: Setup PHP
|
||||||
uses: shivammathur/setup-php@v2
|
uses: shivammathur/setup-php@v2
|
||||||
@@ -31,7 +31,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v1
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: composer update --no-progress --ignore-platform-reqs
|
run: composer update --no-progress --ignore-platform-reqs
|
||||||
@@ -43,7 +43,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v1
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup PHP
|
- name: Setup PHP
|
||||||
uses: shivammathur/setup-php@v2
|
uses: shivammathur/setup-php@v2
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ jobs:
|
|||||||
php-version: ['5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0']
|
php-version: ['5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0']
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: shivammathur/setup-php@v2
|
- uses: shivammathur/setup-php@v2
|
||||||
with:
|
with:
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v1
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup PHP
|
- name: Setup PHP
|
||||||
uses: shivammathur/setup-php@v2
|
uses: shivammathur/setup-php@v2
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: "Checkout code"
|
- name: "Checkout code"
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: "Install PHP with extensions"
|
- name: "Install PHP with extensions"
|
||||||
uses: shivammathur/setup-php@v2
|
uses: shivammathur/setup-php@v2
|
||||||
@@ -86,7 +86,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: "Checkout code"
|
- name: "Checkout code"
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: "Install PHP with extensions"
|
- name: "Install PHP with extensions"
|
||||||
uses: shivammathur/setup-php@v2
|
uses: shivammathur/setup-php@v2
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: "Checkout code"
|
- name: "Checkout code"
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: "Set-up PHP"
|
- name: "Set-up PHP"
|
||||||
uses: shivammathur/setup-php@v2
|
uses: shivammathur/setup-php@v2
|
||||||
@@ -33,7 +33,7 @@ jobs:
|
|||||||
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
|
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
|
||||||
|
|
||||||
- name: Cache dependencies
|
- name: Cache dependencies
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: ${{ steps.composercache.outputs.dir }}
|
path: ${{ steps.composercache.outputs.dir }}
|
||||||
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
|
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
|
||||||
@@ -54,7 +54,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: "Checkout code"
|
- name: "Checkout code"
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: "Run DOCtor-RST"
|
- name: "Run DOCtor-RST"
|
||||||
uses: docker://oskarstark/doctor-rst
|
uses: docker://oskarstark/doctor-rst
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
headline: lang.sieve_preset_8
|
||||||
|
content: |
|
||||||
|
require "fileinto";
|
||||||
|
require "mailbox";
|
||||||
|
require "variables";
|
||||||
|
require "subaddress";
|
||||||
|
require "envelope";
|
||||||
|
require "duplicate";
|
||||||
|
require "imap4flags";
|
||||||
|
if header :matches "To" "*mail@domain.tld*" {
|
||||||
|
redirect "anothermail@anotherdomain.tld";
|
||||||
|
setflag "\\seen"; /* Mark mail as read */
|
||||||
|
fileInto "INBOX/SubFolder"; /* Move mail on subfolder after */
|
||||||
|
} else {
|
||||||
|
# The rest goes into INBOX
|
||||||
|
# default is "implicit keep", we do it explicitly here
|
||||||
|
keep;
|
||||||
|
}
|
||||||
+91
-88
@@ -97,6 +97,7 @@ $AVAILABLE_LANGUAGES = array(
|
|||||||
'lv-lv' => 'latviešu (Latvian)',
|
'lv-lv' => 'latviešu (Latvian)',
|
||||||
'nl-nl' => 'Nederlands (Dutch)',
|
'nl-nl' => 'Nederlands (Dutch)',
|
||||||
'pl-pl' => 'Język Polski (Polish)',
|
'pl-pl' => 'Język Polski (Polish)',
|
||||||
|
'pt-br' => 'Português brasileiro (Brazilian Portuguese)',
|
||||||
'pt-pt' => 'Português (Portuguese)',
|
'pt-pt' => 'Português (Portuguese)',
|
||||||
'ro-ro' => 'Română (Romanian)',
|
'ro-ro' => 'Română (Romanian)',
|
||||||
'ru-ru' => 'Pусский (Russian)',
|
'ru-ru' => 'Pусский (Russian)',
|
||||||
@@ -235,118 +236,120 @@ $RSPAMD_MAPS = array(
|
|||||||
|
|
||||||
$IMAPSYNC_OPTIONS = array(
|
$IMAPSYNC_OPTIONS = array(
|
||||||
'whitelist' => array(
|
'whitelist' => array(
|
||||||
|
'abort',
|
||||||
|
'authmd51',
|
||||||
|
'authmd52',
|
||||||
'authmech1',
|
'authmech1',
|
||||||
'authmech2',
|
'authmech2',
|
||||||
'authuser1',
|
'authuser1',
|
||||||
'authuser2',
|
'authuser2',
|
||||||
'debugcontent',
|
|
||||||
'disarmreadreceipts',
|
|
||||||
'logdir',
|
|
||||||
'debugcrossduplicates',
|
|
||||||
'maxsize',
|
|
||||||
'minsize',
|
|
||||||
'minage',
|
|
||||||
'search',
|
|
||||||
'noabletosearch',
|
|
||||||
'pidfile',
|
|
||||||
'pidfilelocking',
|
|
||||||
'search1',
|
|
||||||
'search2',
|
|
||||||
'sslargs1',
|
|
||||||
'sslargs2',
|
|
||||||
'syncduplicates',
|
|
||||||
'usecache',
|
|
||||||
'synclabels',
|
|
||||||
'truncmess',
|
|
||||||
'domino2',
|
|
||||||
'expunge1',
|
|
||||||
'filterbuggyflags',
|
|
||||||
'justconnect',
|
|
||||||
'justfolders',
|
|
||||||
'maxlinelength',
|
|
||||||
'useheader',
|
|
||||||
'noabletosearch1',
|
|
||||||
'nolog',
|
|
||||||
'prefix1',
|
|
||||||
'prefix2',
|
|
||||||
'sep1',
|
|
||||||
'sep2',
|
|
||||||
'nofoldersizesatend',
|
|
||||||
'justfoldersizes',
|
|
||||||
'proxyauth1',
|
|
||||||
'skipemptyfolders',
|
|
||||||
'include',
|
|
||||||
'subfolder1',
|
|
||||||
'subscribed',
|
|
||||||
'subscribe',
|
|
||||||
'debug',
|
'debug',
|
||||||
|
'debugcontent',
|
||||||
|
'debugcrossduplicates',
|
||||||
|
'debugflags',
|
||||||
|
'debugfolders',
|
||||||
|
'debugimap',
|
||||||
|
'debugimap1',
|
||||||
'debugimap2',
|
'debugimap2',
|
||||||
|
'debugmemory',
|
||||||
|
'debugssl',
|
||||||
|
'delete1emptyfolders',
|
||||||
|
'delete2folders',
|
||||||
|
'disarmreadreceipts',
|
||||||
|
'domain1',
|
||||||
|
'domain2',
|
||||||
'domino1',
|
'domino1',
|
||||||
|
'domino2',
|
||||||
|
'dry',
|
||||||
|
'errorsmax',
|
||||||
'exchange1',
|
'exchange1',
|
||||||
'exchange2',
|
'exchange2',
|
||||||
|
'exitwhenover',
|
||||||
|
'expunge1',
|
||||||
|
'f1f2',
|
||||||
|
'filterbuggyflags',
|
||||||
|
'folder',
|
||||||
|
'folderfirst',
|
||||||
|
'folderlast',
|
||||||
|
'folderrec',
|
||||||
|
'gmail1',
|
||||||
|
'gmail2',
|
||||||
|
'idatefromheader',
|
||||||
|
'include',
|
||||||
|
'inet4',
|
||||||
|
'inet6',
|
||||||
|
'justconnect',
|
||||||
|
'justfolders',
|
||||||
|
'justfoldersizes',
|
||||||
'justlogin',
|
'justlogin',
|
||||||
'keepalive1',
|
'keepalive1',
|
||||||
'keepalive2',
|
'keepalive2',
|
||||||
|
'log',
|
||||||
|
'logdir',
|
||||||
|
'logfile',
|
||||||
|
'maxbytesafter',
|
||||||
|
'maxlinelength',
|
||||||
|
'maxmessagespersecond',
|
||||||
|
'maxsize',
|
||||||
|
'maxsleep',
|
||||||
|
'minage',
|
||||||
|
'minsize',
|
||||||
|
'noabletosearch',
|
||||||
|
'noabletosearch1',
|
||||||
'noabletosearch2',
|
'noabletosearch2',
|
||||||
|
'noexpunge1',
|
||||||
'noexpunge2',
|
'noexpunge2',
|
||||||
|
'nofoldersizesatend',
|
||||||
|
'noid',
|
||||||
|
'nolog',
|
||||||
|
'nomixfolders',
|
||||||
'noresyncflags',
|
'noresyncflags',
|
||||||
'nossl1',
|
'nossl1',
|
||||||
'nouidexpunge2',
|
'nossl2',
|
||||||
'syncinternaldates',
|
|
||||||
'idatefromheader',
|
|
||||||
'useuid',
|
|
||||||
'debugflags',
|
|
||||||
'debugimap',
|
|
||||||
'delete1emptyfolders',
|
|
||||||
'delete2folders',
|
|
||||||
'gmail2',
|
|
||||||
'office1',
|
|
||||||
'testslive6',
|
|
||||||
'debugimap1',
|
|
||||||
'errorsmax',
|
|
||||||
'tests',
|
|
||||||
'gmail1',
|
|
||||||
'maxmessagespersecond',
|
|
||||||
'maxbytesafter',
|
|
||||||
'maxsleep',
|
|
||||||
'abort',
|
|
||||||
'resyncflags',
|
|
||||||
'resynclabels',
|
|
||||||
'syncacls',
|
|
||||||
'nosyncacls',
|
'nosyncacls',
|
||||||
|
'notls1',
|
||||||
|
'notls2',
|
||||||
|
'nouidexpunge2',
|
||||||
'nousecache',
|
'nousecache',
|
||||||
'office2',
|
|
||||||
'testslive',
|
|
||||||
'debugmemory',
|
|
||||||
'exitwhenover',
|
|
||||||
'noid',
|
|
||||||
'noexpunge1',
|
|
||||||
'authmd51',
|
|
||||||
'logfile',
|
|
||||||
'proxyauth2',
|
|
||||||
'domain1',
|
|
||||||
'domain2',
|
|
||||||
'oauthaccesstoken1',
|
'oauthaccesstoken1',
|
||||||
'oauthaccesstoken2',
|
'oauthaccesstoken2',
|
||||||
'oauthdirect1',
|
'oauthdirect1',
|
||||||
'oauthdirect2',
|
'oauthdirect2',
|
||||||
'folder',
|
'office1',
|
||||||
'folderrec',
|
'office2',
|
||||||
'folderfirst',
|
'pidfile',
|
||||||
'folderlast',
|
'pidfilelocking',
|
||||||
'nomixfolders',
|
'prefix1',
|
||||||
'authmd52',
|
'prefix2',
|
||||||
'debugfolders',
|
'proxyauth1',
|
||||||
'nossl2',
|
'proxyauth2',
|
||||||
|
'resyncflags',
|
||||||
|
'resynclabels',
|
||||||
|
'search',
|
||||||
|
'search1',
|
||||||
|
'search2',
|
||||||
|
'sep1',
|
||||||
|
'sep2',
|
||||||
|
'showpasswords',
|
||||||
|
'skipemptyfolders',
|
||||||
'ssl2',
|
'ssl2',
|
||||||
|
'sslargs1',
|
||||||
|
'sslargs2',
|
||||||
|
'subfolder1',
|
||||||
|
'subscribe',
|
||||||
|
'subscribed',
|
||||||
|
'syncacls',
|
||||||
|
'syncduplicates',
|
||||||
|
'syncinternaldates',
|
||||||
|
'synclabels',
|
||||||
|
'tests',
|
||||||
|
'testslive',
|
||||||
|
'testslive6',
|
||||||
'tls2',
|
'tls2',
|
||||||
'notls2',
|
'truncmess',
|
||||||
'debugssl',
|
'usecache',
|
||||||
'notls1',
|
'useheader',
|
||||||
'inet4',
|
'useuid'
|
||||||
'inet6',
|
|
||||||
'log',
|
|
||||||
'showpasswords'
|
|
||||||
),
|
),
|
||||||
'blacklist' => array(
|
'blacklist' => array(
|
||||||
'skipmess',
|
'skipmess',
|
||||||
|
|||||||
@@ -1684,7 +1684,7 @@ function showVersionModal(title, version){
|
|||||||
function parseGithubMarkdownLinks(inputText) {
|
function parseGithubMarkdownLinks(inputText) {
|
||||||
var replacedText, replacePattern1;
|
var replacedText, replacePattern1;
|
||||||
|
|
||||||
replacePattern1 = /(\b(https?):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim;
|
replacePattern1 = /(\b(https?):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])(?![^<]*>)/gim;
|
||||||
replacedText = inputText.replace(replacePattern1, (matched, index, original, input_string) => {
|
replacedText = inputText.replace(replacePattern1, (matched, index, original, input_string) => {
|
||||||
if (matched.includes('github.com')){
|
if (matched.includes('github.com')){
|
||||||
// return short link if it's github link
|
// return short link if it's github link
|
||||||
|
|||||||
@@ -199,6 +199,23 @@ jQuery(function($){
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function add_table_row(table_id, type) {
|
||||||
|
var row = $('<tr />');
|
||||||
|
if (type == "mbox_attr") {
|
||||||
|
cols = '<td><input class="input-sm input-xs-lg form-control" data-id="mbox_attr" type="text" name="attribute" required></td>';
|
||||||
|
cols += '<td><input class="input-sm input-xs-lg form-control" data-id="mbox_attr" type="text" name="value" required></td>';
|
||||||
|
cols += '<td><a href="#" role="button" class="btn btn-sm btn-xs-lg btn-secondary h-100 w-100" type="button">' + lang_admin.remove_row + '</a></td>';
|
||||||
|
}
|
||||||
|
row.append(cols);
|
||||||
|
table_id.append(row);
|
||||||
|
}
|
||||||
|
$('#mbox_attr_table').on('click', 'tr a', function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
$(this).parents('tr').remove();
|
||||||
|
});
|
||||||
|
$('#add_mbox_attr_row').click(function() {
|
||||||
|
add_table_row($('#mbox_attr_table'), "mbox_attr");
|
||||||
|
});
|
||||||
|
|
||||||
// detect element visibility changes
|
// detect element visibility changes
|
||||||
function onVisible(element, callback) {
|
function onVisible(element, callback) {
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ jQuery(function($){
|
|||||||
if (value.score > 0) highlightClass = 'negative';
|
if (value.score > 0) highlightClass = 'negative';
|
||||||
else if (value.score < 0) highlightClass = 'positive';
|
else if (value.score < 0) highlightClass = 'positive';
|
||||||
else highlightClass = 'neutral';
|
else highlightClass = 'neutral';
|
||||||
$('#qid_detail_symbols').append('<span data-bs-toggle="tooltip" class="rspamd-symbol ' + highlightClass + '" title="' + (value.options ? value.options.join(', ') : '') + '">' + value.name + ' (<span class="score">' + value.score + '</span>)</span>');
|
$('#qid_detail_symbols').append('<span data-bs-toggle="tooltip" class="rspamd-symbol ' + highlightClass + '" title="' + (value.options ? escapeHtml(value.options.join(', ')) : '') + '">' + value.name + ' (<span class="score">' + value.score + '</span>)</span>');
|
||||||
});
|
});
|
||||||
$('[data-bs-toggle="tooltip"]').tooltip();
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
||||||
}
|
}
|
||||||
@@ -295,3 +295,7 @@ jQuery(function($){
|
|||||||
$(".table_collapse_option").hide();
|
$(".table_collapse_option").hide();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+12
-2
@@ -1591,6 +1591,12 @@ if (isset($_GET['query'])) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "spam-score":
|
||||||
|
$score = mailbox('get', 'spam_score', $object);
|
||||||
|
if ($score)
|
||||||
|
$score = array("score" => preg_replace("/\s+/", "", $score));
|
||||||
|
process_get_return($score);
|
||||||
|
break;
|
||||||
break;
|
break;
|
||||||
// return no route found if no case is matched
|
// return no route found if no case is matched
|
||||||
default:
|
default:
|
||||||
@@ -1867,8 +1873,6 @@ if (isset($_GET['query'])) {
|
|||||||
case "quota_notification_bcc":
|
case "quota_notification_bcc":
|
||||||
process_edit_return(quota_notification_bcc('edit', $attr));
|
process_edit_return(quota_notification_bcc('edit', $attr));
|
||||||
break;
|
break;
|
||||||
case "domain-wide-footer":
|
|
||||||
process_edit_return(mailbox('edit', 'domain_wide_footer', $attr));
|
|
||||||
break;
|
break;
|
||||||
case "mailq":
|
case "mailq":
|
||||||
process_edit_return(mailq('edit', array_merge(array('qid' => $items), $attr)));
|
process_edit_return(mailq('edit', array_merge(array('qid' => $items), $attr)));
|
||||||
@@ -1881,6 +1885,9 @@ if (isset($_GET['query'])) {
|
|||||||
case "template":
|
case "template":
|
||||||
process_edit_return(mailbox('edit', 'mailbox_templates', array_merge(array('ids' => $items), $attr)));
|
process_edit_return(mailbox('edit', 'mailbox_templates', array_merge(array('ids' => $items), $attr)));
|
||||||
break;
|
break;
|
||||||
|
case "custom-attribute":
|
||||||
|
process_edit_return(mailbox('edit', 'mailbox_custom_attribute', array_merge(array('mailboxes' => $items), $attr)));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
process_edit_return(mailbox('edit', 'mailbox', array_merge(array('username' => $items), $attr)));
|
process_edit_return(mailbox('edit', 'mailbox', array_merge(array('username' => $items), $attr)));
|
||||||
break;
|
break;
|
||||||
@@ -1900,6 +1907,9 @@ if (isset($_GET['query'])) {
|
|||||||
case "template":
|
case "template":
|
||||||
process_edit_return(mailbox('edit', 'domain_templates', array_merge(array('ids' => $items), $attr)));
|
process_edit_return(mailbox('edit', 'domain_templates', array_merge(array('ids' => $items), $attr)));
|
||||||
break;
|
break;
|
||||||
|
case "footer":
|
||||||
|
process_edit_return(mailbox('edit', 'domain_wide_footer', array_merge(array('domains' => $items), $attr)));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
process_edit_return(mailbox('edit', 'domain', array_merge(array('domain' => $items), $attr)));
|
process_edit_return(mailbox('edit', 'domain', array_merge(array('domain' => $items), $attr)));
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -147,6 +147,8 @@
|
|||||||
"ays": "Opravdu chcete pokračovat?",
|
"ays": "Opravdu chcete pokračovat?",
|
||||||
"ban_list_info": "Seznam blokovaných IP adres je zobrazen níže: <b>síť (zbývající čas blokování) - [akce]</b>.<br />IP adresy zařazené pro odblokování budou z aktivního seznamu odebrány během několika sekund.<br />Červeně označené položky jsou pernamentní bloky z blacklistu.",
|
"ban_list_info": "Seznam blokovaných IP adres je zobrazen níže: <b>síť (zbývající čas blokování) - [akce]</b>.<br />IP adresy zařazené pro odblokování budou z aktivního seznamu odebrány během několika sekund.<br />Červeně označené položky jsou pernamentní bloky z blacklistu.",
|
||||||
"change_logo": "Změnit logo",
|
"change_logo": "Změnit logo",
|
||||||
|
"logo_normal_label": "Normální",
|
||||||
|
"logo_dark_label": "Inverzní pro tmavý režim",
|
||||||
"configuration": "Nastavení",
|
"configuration": "Nastavení",
|
||||||
"convert_html_to_text": "Převést HTML do prostého textu",
|
"convert_html_to_text": "Převést HTML do prostého textu",
|
||||||
"credentials_transport_warning": "<b>Upozornění</b>: Přidání položky do transportní mapy aktualizuje také přihlašovací údaje všech záznamů s odpovídajícím skokem.",
|
"credentials_transport_warning": "<b>Upozornění</b>: Přidání položky do transportní mapy aktualizuje také přihlašovací údaje všech záznamů s odpovídajícím skokem.",
|
||||||
@@ -206,6 +208,9 @@
|
|||||||
"include_exclude": "Zahrnout/Vyloučit",
|
"include_exclude": "Zahrnout/Vyloučit",
|
||||||
"include_exclude_info": "Ve výchozím nastavení (bez výběru), jsou adresovány <b>všechny mailové schránky</b>",
|
"include_exclude_info": "Ve výchozím nastavení (bez výběru), jsou adresovány <b>všechny mailové schránky</b>",
|
||||||
"includes": "Zahrnout tyto přijemce",
|
"includes": "Zahrnout tyto přijemce",
|
||||||
|
"ip_check": "Kontrola IP",
|
||||||
|
"ip_check_disabled": "Kontrola IP je zakázána. Můžete ji povolit v nabídce<br> <strong>Systém > Nastavení > Možnosti > Přizpůsobení</strong>",
|
||||||
|
"ip_check_opt_in": "Přihlásit se k používání služby třetí strany <strong>ipv4.mailcow.email</strong> a <strong>ipv6.mailcow.email</strong> pro zjištění externích IP adres.",
|
||||||
"is_mx_based": "Na základě MX",
|
"is_mx_based": "Na základě MX",
|
||||||
"last_applied": "Naposledy použité",
|
"last_applied": "Naposledy použité",
|
||||||
"license_info": "Licence není povinná, pomůžete však dalšímu vývoji.<br><a href=\"https://www.servercow.de/mailcow?lang=en#sal\" target=\"_blank\" alt=\"SAL order\">Registrujte si své GUID</a>, nebo si <a href=\"https://www.servercow.de/mailcow?lang=en#support\" target=\"_blank\" alt=\"Support order\">zaplaťte podporu pro svou instalaci mailcow.</a>",
|
"license_info": "Licence není povinná, pomůžete však dalšímu vývoji.<br><a href=\"https://www.servercow.de/mailcow?lang=en#sal\" target=\"_blank\" alt=\"SAL order\">Registrujte si své GUID</a>, nebo si <a href=\"https://www.servercow.de/mailcow?lang=en#support\" target=\"_blank\" alt=\"Support order\">zaplaťte podporu pro svou instalaci mailcow.</a>",
|
||||||
@@ -232,6 +237,7 @@
|
|||||||
"oauth2_renew_secret": "Vytvořit nový tajný klíč",
|
"oauth2_renew_secret": "Vytvořit nový tajný klíč",
|
||||||
"oauth2_revoke_tokens": "Odvolat všechny klientské tokeny",
|
"oauth2_revoke_tokens": "Odvolat všechny klientské tokeny",
|
||||||
"optional": "volitelné",
|
"optional": "volitelné",
|
||||||
|
"options": "Možnosti",
|
||||||
"password": "Heslo",
|
"password": "Heslo",
|
||||||
"password_length": "Délka hesla",
|
"password_length": "Délka hesla",
|
||||||
"password_policy": "Politika hesel",
|
"password_policy": "Politika hesel",
|
||||||
@@ -337,9 +343,7 @@
|
|||||||
"verify": "Ověřit",
|
"verify": "Ověřit",
|
||||||
"yes": "✓",
|
"yes": "✓",
|
||||||
"f2b_ban_time_increment": "Délka banu je prodlužována s každým dalším banem",
|
"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)",
|
"f2b_max_ban_time": "Maximální délka banu (s)"
|
||||||
"ip_check": "Kontrola IP",
|
|
||||||
"ip_check_disabled": "Kontrola IP je vypnuta. Můžete ji zapnout v <br> <strong>System > Nastavení > Options > Přizpůsobení</strong>"
|
|
||||||
},
|
},
|
||||||
"danger": {
|
"danger": {
|
||||||
"access_denied": "Přístup odepřen nebo jsou neplatná data ve formuláři",
|
"access_denied": "Přístup odepřen nebo jsou neplatná data ve formuláři",
|
||||||
@@ -443,6 +447,9 @@
|
|||||||
"target_domain_invalid": "Cílová doména %s je neplatná",
|
"target_domain_invalid": "Cílová doména %s je neplatná",
|
||||||
"targetd_not_found": "Cílová doména %s nenalezena",
|
"targetd_not_found": "Cílová doména %s nenalezena",
|
||||||
"targetd_relay_domain": "Cílová doména %s je předávaná",
|
"targetd_relay_domain": "Cílová doména %s je předávaná",
|
||||||
|
"template_exists": "Šablona %s již existuje",
|
||||||
|
"template_id_invalid": "Šablona ID %s je neplatná",
|
||||||
|
"template_name_invalid": "Název šablony je neplatný",
|
||||||
"temp_error": "Dočasná chyba",
|
"temp_error": "Dočasná chyba",
|
||||||
"text_empty": "Text nesmí být prázdný",
|
"text_empty": "Text nesmí být prázdný",
|
||||||
"tfa_token_invalid": "Neplatný TFA token",
|
"tfa_token_invalid": "Neplatný TFA token",
|
||||||
@@ -461,27 +468,27 @@
|
|||||||
"yotp_verification_failed": "Yubico OTP ověření selhalo: %s"
|
"yotp_verification_failed": "Yubico OTP ověření selhalo: %s"
|
||||||
},
|
},
|
||||||
"datatables": {
|
"datatables": {
|
||||||
"emptyTable": "Tabulka neobsahuje žádná data",
|
"emptyTable": "Tabulka neobsahuje žádná data",
|
||||||
"info": "Zobrazuji _START_ až _END_ z celkem _TOTAL_ záznamů",
|
"info": "Zobrazuji _START_ až _END_ z celkem _TOTAL_ záznamů",
|
||||||
"infoEmpty": "Zobrazuji 0 až 0 z 0 záznamů",
|
"infoEmpty": "Zobrazuji 0 až 0 z 0 záznamů",
|
||||||
"infoFiltered": "(filtrováno z celkem _MAX_ záznamů)",
|
"infoFiltered": "(filtrováno z celkem _MAX_ záznamů)",
|
||||||
"loadingRecords": "Načítám...",
|
"loadingRecords": "Načítám...",
|
||||||
"zeroRecords": "Žádné záznamy nebyly nalezeny",
|
"zeroRecords": "Žádné záznamy nebyly nalezeny",
|
||||||
"paginate": {
|
"paginate": {
|
||||||
"first": "První",
|
"first": "První",
|
||||||
"last": "Poslední",
|
"last": "Poslední",
|
||||||
"next": "Další",
|
"next": "Další",
|
||||||
"previous": "Předchozí"
|
"previous": "Předchozí"
|
||||||
},
|
},
|
||||||
"aria": {
|
"aria": {
|
||||||
"sortAscending": ": aktivujte pro seřazení vzestupně",
|
"sortAscending": ": aktivujte pro seřazení vzestupně",
|
||||||
"sortDescending": ": aktivujte pro seřazení sestupně"
|
"sortDescending": ": aktivujte pro seřazení sestupně"
|
||||||
},
|
},
|
||||||
"lengthMenu": "Zobrazit _MENU_ výsledků",
|
"lengthMenu": "Zobrazit _MENU_ výsledků",
|
||||||
"processing": "Zpracovávání...",
|
"processing": "Zpracovávání...",
|
||||||
"search": "Vyhledávání:",
|
"search": "Vyhledávání:",
|
||||||
"decimal": ",",
|
"decimal": ",",
|
||||||
"thousands": " "
|
"thousands": " "
|
||||||
},
|
},
|
||||||
"debug": {
|
"debug": {
|
||||||
"chart_this_server": "Graf (tento server)",
|
"chart_this_server": "Graf (tento server)",
|
||||||
@@ -670,6 +677,7 @@
|
|||||||
"apps": "Aplikace",
|
"apps": "Aplikace",
|
||||||
"debug": "Systémové informace",
|
"debug": "Systémové informace",
|
||||||
"email": "E-Mail",
|
"email": "E-Mail",
|
||||||
|
"mailcow_system": "Systém",
|
||||||
"mailcow_config": "Nastavení",
|
"mailcow_config": "Nastavení",
|
||||||
"quarantine": "Karanténa",
|
"quarantine": "Karanténa",
|
||||||
"restart_netfilter": "Restartovat netfilter",
|
"restart_netfilter": "Restartovat netfilter",
|
||||||
@@ -705,6 +713,7 @@
|
|||||||
"add_mailbox": "Přidat mailovou schránku",
|
"add_mailbox": "Přidat mailovou schránku",
|
||||||
"add_recipient_map_entry": "Přidat mapu příjemce",
|
"add_recipient_map_entry": "Přidat mapu příjemce",
|
||||||
"add_resource": "Přidat zdroj",
|
"add_resource": "Přidat zdroj",
|
||||||
|
"add_template": "Přidat šablonu",
|
||||||
"add_tls_policy_map": "Přidat mapu TLS pravidel",
|
"add_tls_policy_map": "Přidat mapu TLS pravidel",
|
||||||
"address_rewriting": "Přepisování adres",
|
"address_rewriting": "Přepisování adres",
|
||||||
"alias": "Alias",
|
"alias": "Alias",
|
||||||
@@ -747,6 +756,7 @@
|
|||||||
"domain": "Doména",
|
"domain": "Doména",
|
||||||
"domain_admins": "Správci domén",
|
"domain_admins": "Správci domén",
|
||||||
"domain_aliases": "Doménové aliasy",
|
"domain_aliases": "Doménové aliasy",
|
||||||
|
"domain_templates": "Šablony domén",
|
||||||
"domain_quota": "Kvóta",
|
"domain_quota": "Kvóta",
|
||||||
"domain_quota_total": "Celková kvóta domény",
|
"domain_quota_total": "Celková kvóta domény",
|
||||||
"domains": "Domény",
|
"domains": "Domény",
|
||||||
@@ -775,6 +785,7 @@
|
|||||||
"mailbox_defaults": "Výchozí nastavení",
|
"mailbox_defaults": "Výchozí nastavení",
|
||||||
"mailbox_defaults_info": "Definuje výchozí nastavení pro nové schránky",
|
"mailbox_defaults_info": "Definuje výchozí nastavení pro nové schránky",
|
||||||
"mailbox_defquota": "Výchozí velikost schránky",
|
"mailbox_defquota": "Výchozí velikost schránky",
|
||||||
|
"mailbox_templates": "Šablony schránek",
|
||||||
"mailbox_quota": "Max. velikost schránky",
|
"mailbox_quota": "Max. velikost schránky",
|
||||||
"mailboxes": "Mailové schránky",
|
"mailboxes": "Mailové schránky",
|
||||||
"max_aliases": "Max. počet aliasů",
|
"max_aliases": "Max. počet aliasů",
|
||||||
@@ -842,6 +853,8 @@
|
|||||||
"table_size_show_n": "Zobrazit %s položek",
|
"table_size_show_n": "Zobrazit %s položek",
|
||||||
"target_address": "Cílová adresa",
|
"target_address": "Cílová adresa",
|
||||||
"target_domain": "Cílová doména",
|
"target_domain": "Cílová doména",
|
||||||
|
"templates": "Šablony",
|
||||||
|
"template": "Šablona",
|
||||||
"tls_enforce_in": "Vynutit TLS pro příchozí",
|
"tls_enforce_in": "Vynutit TLS pro příchozí",
|
||||||
"tls_enforce_out": "Vynutit TLS pro odchozí",
|
"tls_enforce_out": "Vynutit TLS pro odchozí",
|
||||||
"tls_map_dest": "Cíl",
|
"tls_map_dest": "Cíl",
|
||||||
@@ -1006,6 +1019,9 @@
|
|||||||
"settings_map_added": "Přidána položka mapování nastavení",
|
"settings_map_added": "Přidána položka mapování nastavení",
|
||||||
"settings_map_removed": "Položka mapování nastavení: %s smazána",
|
"settings_map_removed": "Položka mapování nastavení: %s smazána",
|
||||||
"sogo_profile_reset": "SOGo profil uživatele %s vyresetován",
|
"sogo_profile_reset": "SOGo profil uživatele %s vyresetován",
|
||||||
|
"template_added": "Přidána šablona %s",
|
||||||
|
"template_modified": "Změny šablony %s byly uloženy",
|
||||||
|
"template_removed": "Šablona ID %s byla odstraněna",
|
||||||
"tls_policy_map_entry_deleted": "Položka mapy TLS pravidel ID %s smazána",
|
"tls_policy_map_entry_deleted": "Položka mapy TLS pravidel ID %s smazána",
|
||||||
"tls_policy_map_entry_saved": "Položka mapy TLS pravidel \"%s\" uložena",
|
"tls_policy_map_entry_saved": "Položka mapy TLS pravidel \"%s\" uložena",
|
||||||
"ui_texts": "Změny UI textů uloženy",
|
"ui_texts": "Změny UI textů uloženy",
|
||||||
|
|||||||
@@ -58,6 +58,7 @@
|
|||||||
"domain": "Domain",
|
"domain": "Domain",
|
||||||
"domain_matches_hostname": "Domain %s darf nicht dem Hostnamen entsprechen",
|
"domain_matches_hostname": "Domain %s darf nicht dem Hostnamen entsprechen",
|
||||||
"domain_quota_m": "Domain-Speicherplatz gesamt (MiB)",
|
"domain_quota_m": "Domain-Speicherplatz gesamt (MiB)",
|
||||||
|
"dry": "Synchronisation simulieren",
|
||||||
"enc_method": "Verschlüsselung",
|
"enc_method": "Verschlüsselung",
|
||||||
"exclude": "Elemente ausschließen (Regex)",
|
"exclude": "Elemente ausschließen (Regex)",
|
||||||
"full_name": "Vor- und Nachname",
|
"full_name": "Vor- und Nachname",
|
||||||
@@ -573,6 +574,7 @@
|
|||||||
"client_secret": "Client-Secret",
|
"client_secret": "Client-Secret",
|
||||||
"comment_info": "Ein privater Kommentar ist für den Benutzer nicht einsehbar. Ein öffentlicher Kommentar wird als Tooltip im Interface des Benutzers angezeigt.",
|
"comment_info": "Ein privater Kommentar ist für den Benutzer nicht einsehbar. Ein öffentlicher Kommentar wird als Tooltip im Interface des Benutzers angezeigt.",
|
||||||
"created_on": "Erstellt am",
|
"created_on": "Erstellt am",
|
||||||
|
"custom_attributes": "benutzerdefinierte Attribute",
|
||||||
"delete1": "Lösche Nachricht nach Übertragung vom Quell-Server",
|
"delete1": "Lösche Nachricht nach Übertragung vom Quell-Server",
|
||||||
"delete2": "Lösche Nachrichten von Ziel-Server, die nicht auf Quell-Server vorhanden sind",
|
"delete2": "Lösche Nachrichten von Ziel-Server, die nicht auf Quell-Server vorhanden sind",
|
||||||
"delete2duplicates": "Lösche Duplikate im Ziel",
|
"delete2duplicates": "Lösche Duplikate im Ziel",
|
||||||
@@ -613,6 +615,7 @@
|
|||||||
"max_quota": "Max. Größe per Mailbox (MiB)",
|
"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>",
|
"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)",
|
"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.",
|
"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)",
|
"mins_interval": "Intervall (min)",
|
||||||
"multiple_bookings": "Mehrfaches Buchen",
|
"multiple_bookings": "Mehrfaches Buchen",
|
||||||
@@ -857,7 +860,7 @@
|
|||||||
"sieve_preset_5": "Auto-Responder (Vacation, Urlaub)",
|
"sieve_preset_5": "Auto-Responder (Vacation, Urlaub)",
|
||||||
"sieve_preset_6": "E-Mails mit Nachricht abweisen",
|
"sieve_preset_6": "E-Mails mit Nachricht abweisen",
|
||||||
"sieve_preset_7": "Weiterleiten und behalten oder verwerfen",
|
"sieve_preset_7": "Weiterleiten und behalten oder verwerfen",
|
||||||
"sieve_preset_8": "Nachricht verwerfen, wenn Absender und Alias-Ziel identisch sind.",
|
"sieve_preset_8": "E-Mail eines bestimmten Absenders umleiten, als gelesen markieren und in Unterordner sortieren",
|
||||||
"sieve_preset_header": "Beispielinhalte zur Einsicht stehen nachstehend bereit. Siehe auch <a href=\"https://de.wikipedia.org/wiki/Sieve\" target=\"_blank\">Wikipedia</a>.",
|
"sieve_preset_header": "Beispielinhalte zur Einsicht stehen nachstehend bereit. Siehe auch <a href=\"https://de.wikipedia.org/wiki/Sieve\" target=\"_blank\">Wikipedia</a>.",
|
||||||
"sogo_visible": "Alias Sichtbarkeit in SOGo",
|
"sogo_visible": "Alias Sichtbarkeit in SOGo",
|
||||||
"sogo_visible_n": "Alias in SOGo verbergen",
|
"sogo_visible_n": "Alias in SOGo verbergen",
|
||||||
@@ -1124,6 +1127,7 @@
|
|||||||
"apple_connection_profile_complete": "Dieses Verbindungsprofil beinhaltet neben IMAP- und SMTP-Konfigurationen auch Pfade für die Konfiguration von CalDAV (Kalender) und CardDAV (Adressbücher) für ein Apple-Gerät.",
|
"apple_connection_profile_complete": "Dieses Verbindungsprofil beinhaltet neben IMAP- und SMTP-Konfigurationen auch Pfade für die Konfiguration von CalDAV (Kalender) und CardDAV (Adressbücher) für ein Apple-Gerät.",
|
||||||
"apple_connection_profile_mailonly": "Dieses Verbindungsprofil beinhaltet IMAP- und SMTP-Konfigurationen für ein Apple-Gerät.",
|
"apple_connection_profile_mailonly": "Dieses Verbindungsprofil beinhaltet IMAP- und SMTP-Konfigurationen für ein Apple-Gerät.",
|
||||||
"apple_connection_profile_with_app_password": "Es wird ein neues App-Passwort erzeugt und in das Profil eingefügt, damit bei der Einrichtung kein Passwort eingegeben werden muss. Geben Sie das Profil nicht weiter, da es einen vollständigen Zugriff auf Ihr Postfach ermöglicht.",
|
"apple_connection_profile_with_app_password": "Es wird ein neues App-Passwort erzeugt und in das Profil eingefügt, damit bei der Einrichtung kein Passwort eingegeben werden muss. Geben Sie das Profil nicht weiter, da es einen vollständigen Zugriff auf Ihr Postfach ermöglicht.",
|
||||||
|
"attribute": "Attribut",
|
||||||
"change_password": "Passwort ändern",
|
"change_password": "Passwort ändern",
|
||||||
"change_password_hint_app_passwords": "Ihre Mailbox hat %d App-Passwörter, die nicht geändert werden. Um diese zu verwalten, gehen Sie bitte zum App-Passwörter-Tab.",
|
"change_password_hint_app_passwords": "Ihre Mailbox hat %d App-Passwörter, die nicht geändert werden. Um diese zu verwalten, gehen Sie bitte zum App-Passwörter-Tab.",
|
||||||
"clear_recent_successful_connections": "Alle erfolgreichen Verbindungen bereinigen",
|
"clear_recent_successful_connections": "Alle erfolgreichen Verbindungen bereinigen",
|
||||||
@@ -1243,6 +1247,7 @@
|
|||||||
"tls_policy_warning": "<strong>Vorsicht:</strong> Entscheiden Sie sich unverschlüsselte Verbindungen abzulehnen, kann dies dazu führen, dass Kontakte Sie nicht mehr erreichen.<br>Nachrichten, die die Richtlinie nicht erfüllen, werden durch einen Hard-Fail im Mailsystem abgewiesen.<br>Diese Einstellung ist aktiv für die primäre Mailbox, für alle Alias-Adressen, die dieser Mailbox <b>direkt zugeordnet</b> sind (lediglich eine einzige Ziel-Adresse) und der Adressen, die sich aus Alias-Domains ergeben. Ausgeschlossen sind temporäre Aliasse (\"Spam-Alias-Adressen\"), Catch-All Alias-Adressen sowie Alias-Adressen mit mehreren Zielen.",
|
"tls_policy_warning": "<strong>Vorsicht:</strong> Entscheiden Sie sich unverschlüsselte Verbindungen abzulehnen, kann dies dazu führen, dass Kontakte Sie nicht mehr erreichen.<br>Nachrichten, die die Richtlinie nicht erfüllen, werden durch einen Hard-Fail im Mailsystem abgewiesen.<br>Diese Einstellung ist aktiv für die primäre Mailbox, für alle Alias-Adressen, die dieser Mailbox <b>direkt zugeordnet</b> sind (lediglich eine einzige Ziel-Adresse) und der Adressen, die sich aus Alias-Domains ergeben. Ausgeschlossen sind temporäre Aliasse (\"Spam-Alias-Adressen\"), Catch-All Alias-Adressen sowie Alias-Adressen mit mehreren Zielen.",
|
||||||
"user_settings": "Benutzereinstellungen",
|
"user_settings": "Benutzereinstellungen",
|
||||||
"username": "Benutzername",
|
"username": "Benutzername",
|
||||||
|
"value": "Wert",
|
||||||
"verify": "Verifizieren",
|
"verify": "Verifizieren",
|
||||||
"waiting": "Warte auf Ausführung",
|
"waiting": "Warte auf Ausführung",
|
||||||
"week": "Woche",
|
"week": "Woche",
|
||||||
|
|||||||
@@ -58,6 +58,7 @@
|
|||||||
"domain": "Domain",
|
"domain": "Domain",
|
||||||
"domain_matches_hostname": "Domain %s matches hostname",
|
"domain_matches_hostname": "Domain %s matches hostname",
|
||||||
"domain_quota_m": "Total domain quota (MiB)",
|
"domain_quota_m": "Total domain quota (MiB)",
|
||||||
|
"dry": "Simulate synchronization",
|
||||||
"enc_method": "Encryption method",
|
"enc_method": "Encryption method",
|
||||||
"exclude": "Exclude objects (regex)",
|
"exclude": "Exclude objects (regex)",
|
||||||
"full_name": "Full name",
|
"full_name": "Full name",
|
||||||
@@ -575,6 +576,7 @@
|
|||||||
"client_secret": "Client secret",
|
"client_secret": "Client secret",
|
||||||
"comment_info": "A private comment is not visible to the user, while a public comment is shown as tooltip when hovering it in a user's overview",
|
"comment_info": "A private comment is not visible to the user, while a public comment is shown as tooltip when hovering it in a user's overview",
|
||||||
"created_on": "Created on",
|
"created_on": "Created on",
|
||||||
|
"custom_attributes": "Custom attributes",
|
||||||
"delete1": "Delete from source when completed",
|
"delete1": "Delete from source when completed",
|
||||||
"delete2": "Delete messages on destination that are not on source",
|
"delete2": "Delete messages on destination that are not on source",
|
||||||
"delete2duplicates": "Delete duplicates on destination",
|
"delete2duplicates": "Delete duplicates on destination",
|
||||||
@@ -591,7 +593,8 @@
|
|||||||
"from_user": "{= from_user =} - From user part of envelope, e.g for \"moo@mailcow.tld\" it returns \"moo\"",
|
"from_user": "{= from_user =} - From user part of envelope, e.g for \"moo@mailcow.tld\" it returns \"moo\"",
|
||||||
"from_name": "{= from_name =} - From name of envelope, e.g for \"Mailcow <moo@mailcow.tld>\" it returns \"Mailcow\"",
|
"from_name": "{= from_name =} - From name of envelope, e.g for \"Mailcow <moo@mailcow.tld>\" it returns \"Mailcow\"",
|
||||||
"from_addr": "{= from_addr =} - From address part of envelope",
|
"from_addr": "{= from_addr =} - From address part of envelope",
|
||||||
"from_domain": "{= from_domain =} - From domain part of envelope"
|
"from_domain": "{= from_domain =} - From domain part of envelope",
|
||||||
|
"custom": "{= foo =} - If mailbox has the custom attribute \"foo\" with value \"bar\" it returns \"bar\""
|
||||||
},
|
},
|
||||||
"domain_footer_plain": "PLAIN footer",
|
"domain_footer_plain": "PLAIN footer",
|
||||||
"domain_quota": "Domain quota",
|
"domain_quota": "Domain quota",
|
||||||
@@ -622,6 +625,7 @@
|
|||||||
"max_quota": "Max. quota per mailbox (MiB)",
|
"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>",
|
"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>",
|
"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.",
|
"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)",
|
"mins_interval": "Interval (min)",
|
||||||
"multiple_bookings": "Multiple bookings",
|
"multiple_bookings": "Multiple bookings",
|
||||||
@@ -873,7 +877,7 @@
|
|||||||
"sieve_preset_5": "Auto responder (vacation)",
|
"sieve_preset_5": "Auto responder (vacation)",
|
||||||
"sieve_preset_6": "Reject mail with reponse",
|
"sieve_preset_6": "Reject mail with reponse",
|
||||||
"sieve_preset_7": "Redirect and keep/drop",
|
"sieve_preset_7": "Redirect and keep/drop",
|
||||||
"sieve_preset_8": "Discard message sent to an alias address the sender is part of",
|
"sieve_preset_8": "Redirect e-mail from a specific sender, mark as read and sort into subfolder",
|
||||||
"sieve_preset_header": "Please see the example presets below. For more details see <a href=\"https://en.wikipedia.org/wiki/Sieve_(mail_filtering_language)\" target=\"_blank\">Wikipedia</a>.",
|
"sieve_preset_header": "Please see the example presets below. For more details see <a href=\"https://en.wikipedia.org/wiki/Sieve_(mail_filtering_language)\" target=\"_blank\">Wikipedia</a>.",
|
||||||
"sogo_visible": "Alias is visible in SOGo",
|
"sogo_visible": "Alias is visible in SOGo",
|
||||||
"sogo_visible_n": "Hide alias in SOGo",
|
"sogo_visible_n": "Hide alias in SOGo",
|
||||||
@@ -1140,6 +1144,7 @@
|
|||||||
"apple_connection_profile_complete": "This connection profile includes IMAP and SMTP parameters as well as CalDAV (calendars) and CardDAV (contacts) paths for an Apple device.",
|
"apple_connection_profile_complete": "This connection profile includes IMAP and SMTP parameters as well as CalDAV (calendars) and CardDAV (contacts) paths for an Apple device.",
|
||||||
"apple_connection_profile_mailonly": "This connection profile includes IMAP and SMTP configuration parameters for an Apple device.",
|
"apple_connection_profile_mailonly": "This connection profile includes IMAP and SMTP configuration parameters for an Apple device.",
|
||||||
"apple_connection_profile_with_app_password": "A new app password is generated and added to the profile so that no password needs to be entered when setting up your device. Please do not share the file as it grants full access to your mailbox.",
|
"apple_connection_profile_with_app_password": "A new app password is generated and added to the profile so that no password needs to be entered when setting up your device. Please do not share the file as it grants full access to your mailbox.",
|
||||||
|
"attribute": "Attribute",
|
||||||
"change_password": "Change password",
|
"change_password": "Change password",
|
||||||
"change_password_hint_app_passwords": "Your account has %d app passwords that will not be changed. To manage these, go to the App passwords tab.",
|
"change_password_hint_app_passwords": "Your account has %d app passwords that will not be changed. To manage these, go to the App passwords tab.",
|
||||||
"clear_recent_successful_connections": "Clear seen successful connections",
|
"clear_recent_successful_connections": "Clear seen successful connections",
|
||||||
@@ -1270,6 +1275,7 @@
|
|||||||
"tls_policy_warning": "<strong>Warning:</strong> If you decide to enforce encrypted mail transfer, you may lose emails.<br>Messages to not satisfy the policy will be bounced with a hard fail by the mail system.<br>This option applies to your primary email address (login name), all addresses derived from alias domains as well as alias addresses <b>with only this single mailbox</b> as target.",
|
"tls_policy_warning": "<strong>Warning:</strong> If you decide to enforce encrypted mail transfer, you may lose emails.<br>Messages to not satisfy the policy will be bounced with a hard fail by the mail system.<br>This option applies to your primary email address (login name), all addresses derived from alias domains as well as alias addresses <b>with only this single mailbox</b> as target.",
|
||||||
"user_settings": "User settings",
|
"user_settings": "User settings",
|
||||||
"username": "Username",
|
"username": "Username",
|
||||||
|
"value": "Value",
|
||||||
"verify": "Verify",
|
"verify": "Verify",
|
||||||
"waiting": "Waiting",
|
"waiting": "Waiting",
|
||||||
"week": "week",
|
"week": "week",
|
||||||
|
|||||||
@@ -891,5 +891,17 @@
|
|||||||
"no_active_admin": "Viimeistä aktiivista järjestelmänvalvojaa ei voi poistaa käytöstä",
|
"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_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"
|
||||||
|
},
|
||||||
|
"datatables": {
|
||||||
|
"emptyTable": "Tietoja ei ole saatavilla taulukossa",
|
||||||
|
"expand_all": "Laajenna kaikki",
|
||||||
|
"lengthMenu": "Näytä menu merkinnät",
|
||||||
|
"loadingRecords": "Ladataan...",
|
||||||
|
"processing": "Ole hyvä ja odota...",
|
||||||
|
"search": "Etsi:",
|
||||||
|
"paginate": {
|
||||||
|
"first": "Ensimmäinen",
|
||||||
|
"last": "Edellinen"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,7 +89,7 @@
|
|||||||
"relay_transport_info": "<div class=\"badge fs-6 bg-info\">Info</div> Vous pouvez définir des cartes de transport vers une destination personnalisée pour ce domaine. sinon, une recherche MX sera effectuée.",
|
"relay_transport_info": "<div class=\"badge fs-6 bg-info\">Info</div> Vous pouvez définir des cartes de transport vers une destination personnalisée pour ce domaine. sinon, une recherche MX sera effectuée.",
|
||||||
"relay_unknown_only": "Relayer uniquement les boîtes inexistantes. Les boîtes existantes seront livrées localement.",
|
"relay_unknown_only": "Relayer uniquement les boîtes inexistantes. Les boîtes existantes seront livrées localement.",
|
||||||
"relayhost_wrapped_tls_info": "Veuillez <b>ne pas</b> utiliser des ports TLS wrappés (généralement utilisés sur le port 465).<br>\r\nUtilisez n'importe quel port non encapsulé et lancez STARTTLS. Une politique TLS pour appliquer TLS peut être créée dans \"Cartes de politique TLS\".",
|
"relayhost_wrapped_tls_info": "Veuillez <b>ne pas</b> utiliser des ports TLS wrappés (généralement utilisés sur le port 465).<br>\r\nUtilisez n'importe quel port non encapsulé et lancez STARTTLS. Une politique TLS pour appliquer TLS peut être créée dans \"Cartes de politique TLS\".",
|
||||||
"select": "Veuillez sélectionner...",
|
"select": "Veuillez sélectionner…",
|
||||||
"select_domain": "Sélectionner d'abord un domaine",
|
"select_domain": "Sélectionner d'abord un domaine",
|
||||||
"sieve_desc": "Description courte",
|
"sieve_desc": "Description courte",
|
||||||
"sieve_type": "Type de filtre",
|
"sieve_type": "Type de filtre",
|
||||||
@@ -207,7 +207,7 @@
|
|||||||
"last_applied": "Dernière application",
|
"last_applied": "Dernière application",
|
||||||
"license_info": "Une licence n’est pas requise, mais contribue au développement.<br><a href=\"https://www.servercow.de/mailcow?lang=en#sal\" target=\"_blank\" alt=\"SAL order\">Enregistrer votre GUID ici</a> or <a href=\"https://www.servercow.de/mailcow?lang=en#support\" target=\"_blank\" alt=\"Support order\">acheter le support pour votre intallation Mailcow.</a>",
|
"license_info": "Une licence n’est pas requise, mais contribue au développement.<br><a href=\"https://www.servercow.de/mailcow?lang=en#sal\" target=\"_blank\" alt=\"SAL order\">Enregistrer votre GUID ici</a> or <a href=\"https://www.servercow.de/mailcow?lang=en#support\" target=\"_blank\" alt=\"Support order\">acheter le support pour votre intallation Mailcow.</a>",
|
||||||
"link": "Lien",
|
"link": "Lien",
|
||||||
"loading": "Veuillez patienter...",
|
"loading": "Veuillez patienter…",
|
||||||
"logo_info": "Votre image sera redimensionnée à une hauteur de 40 pixels pour la barre de navigation du haut et à un maximum de 250 pixels en largeur pour la page d'accueil. Un graphique extensible est fortement recommandé.",
|
"logo_info": "Votre image sera redimensionnée à une hauteur de 40 pixels pour la barre de navigation du haut et à un maximum de 250 pixels en largeur pour la page d'accueil. Un graphique extensible est fortement recommandé.",
|
||||||
"lookup_mx": "Faire correspondre la destination à MX (.outlook.com pour acheminer tous les messages ciblés vers un MX * .outlook.com sur ce tronçon)",
|
"lookup_mx": "Faire correspondre la destination à MX (.outlook.com pour acheminer tous les messages ciblés vers un MX * .outlook.com sur ce tronçon)",
|
||||||
"main_name": "\"mailcow UI\" nom",
|
"main_name": "\"mailcow UI\" nom",
|
||||||
@@ -326,7 +326,11 @@
|
|||||||
"password_policy_lowerupper": "Doit contenir des caractères minuscules et majuscules",
|
"password_policy_lowerupper": "Doit contenir des caractères minuscules et majuscules",
|
||||||
"password_policy_numbers": "Doit contenir au moins un chiffre",
|
"password_policy_numbers": "Doit contenir au moins un chiffre",
|
||||||
"ip_check": "Vérification IP",
|
"ip_check": "Vérification IP",
|
||||||
"ip_check_disabled": "La vérification IP est désactivée. Vous pouvez l'activer sous<br> <strong>Système > Configuration > Options > Personnaliser</strong>"
|
"ip_check_disabled": "La vérification IP est désactivée. Vous pouvez l'activer sous<br> <strong>Système > Configuration > Options > Personnaliser</strong>",
|
||||||
|
"logo_normal_label": "Normal",
|
||||||
|
"logo_dark_label": "Inversé pour le mode sombre",
|
||||||
|
"allowed_methods": "Access-Control-Allow-Methods",
|
||||||
|
"allowed_origins": "Access-Control-Allow-Origin"
|
||||||
},
|
},
|
||||||
"danger": {
|
"danger": {
|
||||||
"access_denied": "Accès refusé ou données de formulaire non valides",
|
"access_denied": "Accès refusé ou données de formulaire non valides",
|
||||||
@@ -598,9 +602,9 @@
|
|||||||
"delete_these_items": "Veuillez confirmer les modifications apportées à l’identifiant d’objet suivant",
|
"delete_these_items": "Veuillez confirmer les modifications apportées à l’identifiant d’objet suivant",
|
||||||
"hibp_nok": "Trouvé ! Il s’agit d’un mot de passe potentiellement dangereux !",
|
"hibp_nok": "Trouvé ! Il s’agit d’un mot de passe potentiellement dangereux !",
|
||||||
"hibp_ok": "Aucune correspondance trouvée.",
|
"hibp_ok": "Aucune correspondance trouvée.",
|
||||||
"loading": "Veuillez patienter...",
|
"loading": "Veuillez patienter…",
|
||||||
"restart_container": "Redémarrer le conteneur",
|
"restart_container": "Redémarrer le conteneur",
|
||||||
"restart_container_info": "<b>Important:</b> Un redémarrage en douceur peut prendre un certain temps, veuillez attendre qu’il soit terminé..",
|
"restart_container_info": "<b>Important:</b> Un redémarrage en douceur peut prendre un certain temps, veuillez attendre qu’il soit terminé.",
|
||||||
"restart_now": "Redémarrer maintenant",
|
"restart_now": "Redémarrer maintenant",
|
||||||
"restarting_container": "Redémarrage du conteneur, cela peut prendre un certain temps"
|
"restarting_container": "Redémarrage du conteneur, cela peut prendre un certain temps"
|
||||||
},
|
},
|
||||||
@@ -935,7 +939,7 @@
|
|||||||
"disable_tfa": "Désactiver TFA jusqu’à la prochaine ouverture de session réussie",
|
"disable_tfa": "Désactiver TFA jusqu’à la prochaine ouverture de session réussie",
|
||||||
"enter_qr_code": "Votre code TOTP si votre appareil ne peut pas scanner les codes QR",
|
"enter_qr_code": "Votre code TOTP si votre appareil ne peut pas scanner les codes QR",
|
||||||
"error_code": "Code d'erreur",
|
"error_code": "Code d'erreur",
|
||||||
"init_webauthn": "Initialisation, veuillez patienter...",
|
"init_webauthn": "Initialisation, veuillez patienter…",
|
||||||
"key_id": "Un identifiant pour votre Périphérique",
|
"key_id": "Un identifiant pour votre Périphérique",
|
||||||
"key_id_totp": "Un identifiant pour votre clé",
|
"key_id_totp": "Un identifiant pour votre clé",
|
||||||
"none": "Désactiver",
|
"none": "Désactiver",
|
||||||
@@ -948,8 +952,8 @@
|
|||||||
"tfa_token_invalid": "Token TFA invalide",
|
"tfa_token_invalid": "Token TFA invalide",
|
||||||
"totp": "OTP (One Time Password = Mot de passe à usage unique : Google Authenticator, Authy, etc.)",
|
"totp": "OTP (One Time Password = Mot de passe à usage unique : Google Authenticator, Authy, etc.)",
|
||||||
"webauthn": "Authentification WebAuthn",
|
"webauthn": "Authentification WebAuthn",
|
||||||
"waiting_usb_auth": "<i>En attente d’un périphérique USB...</i><br><br>S’il vous plaît appuyez maintenant sur le bouton de votre périphérique USB WebAuthn.",
|
"waiting_usb_auth": "<i>En attente d’un périphérique USB…</i><br><br>S’il vous plaît appuyez maintenant sur le bouton de votre périphérique USB WebAuthn.",
|
||||||
"waiting_usb_register": "<i>En attente d’un périphérique USB...</i><br><br>Veuillez entrer votre mot de passe ci-dessus et confirmer votre inscription WebAuthn en appuyant sur le bouton de votre périphérique USB WebAuthn.",
|
"waiting_usb_register": "<i>En attente d’un périphérique USB…</i><br><br>Veuillez entrer votre mot de passe ci-dessus et confirmer votre inscription WebAuthn en appuyant sur le bouton de votre périphérique USB WebAuthn.",
|
||||||
"yubi_otp": "Authentification OTP Yubico"
|
"yubi_otp": "Authentification OTP Yubico"
|
||||||
},
|
},
|
||||||
"fido2": {
|
"fido2": {
|
||||||
@@ -999,9 +1003,9 @@
|
|||||||
"eas_reset": "Réinitialiser le cache de l’appareil Activesync",
|
"eas_reset": "Réinitialiser le cache de l’appareil Activesync",
|
||||||
"eas_reset_help": "Dans de nombreux cas, une réinitialisation du cache de l’appareil aidera à récupérer un profil Activesync cassé.<br><b>Attention :</b> Tous les éléments seront à nouveau téléchargés !",
|
"eas_reset_help": "Dans de nombreux cas, une réinitialisation du cache de l’appareil aidera à récupérer un profil Activesync cassé.<br><b>Attention :</b> Tous les éléments seront à nouveau téléchargés !",
|
||||||
"eas_reset_now": "Réinitialiser maintenant",
|
"eas_reset_now": "Réinitialiser maintenant",
|
||||||
"edit": "Editer",
|
"edit": "Éditer",
|
||||||
"email": "Email",
|
"email": "E-mail",
|
||||||
"email_and_dav": "Email, calendriers et contacts",
|
"email_and_dav": "E-mail, calendriers et contacts",
|
||||||
"encryption": "Cryptage",
|
"encryption": "Cryptage",
|
||||||
"excludes": "Exclut",
|
"excludes": "Exclut",
|
||||||
"expire_in": "Expire dans",
|
"expire_in": "Expire dans",
|
||||||
@@ -1015,7 +1019,7 @@
|
|||||||
"is_catch_all": "Attrape-tout pour le domaine(s)",
|
"is_catch_all": "Attrape-tout pour le domaine(s)",
|
||||||
"last_mail_login": "Dernière connexion mail",
|
"last_mail_login": "Dernière connexion mail",
|
||||||
"last_run": "Dernière exécution",
|
"last_run": "Dernière exécution",
|
||||||
"loading": "Chargement...",
|
"loading": "Chargement…",
|
||||||
"mailbox_details": "Détails de la boîte",
|
"mailbox_details": "Détails de la boîte",
|
||||||
"messages": "messages",
|
"messages": "messages",
|
||||||
"never": "jamais",
|
"never": "jamais",
|
||||||
@@ -1051,7 +1055,7 @@
|
|||||||
"shared_aliases": "Adresses alias partagées",
|
"shared_aliases": "Adresses alias partagées",
|
||||||
"shared_aliases_desc": "Les alias partagés ne sont pas affectés par les paramètres spécifiques à l’utilisateur tels que le filtre anti-spam ou la politique de chiffrement. Les filtres anti-spam correspondants ne peuvent être effectués que par un administrateur en tant que politique de domaine.",
|
"shared_aliases_desc": "Les alias partagés ne sont pas affectés par les paramètres spécifiques à l’utilisateur tels que le filtre anti-spam ou la politique de chiffrement. Les filtres anti-spam correspondants ne peuvent être effectués que par un administrateur en tant que politique de domaine.",
|
||||||
"show_sieve_filters": "Afficher le filtre de tamis actif de l’utilisateur",
|
"show_sieve_filters": "Afficher le filtre de tamis actif de l’utilisateur",
|
||||||
"sogo_profile_reset": "Remise é zéro du profil SOGo",
|
"sogo_profile_reset": "Remise à zéro du profil SOGo",
|
||||||
"sogo_profile_reset_help": "Ceci détruira un profil Sogo des utilisateurs et <b>supprimera toutes les données de contact et de calendrier irrécupérables</b>.",
|
"sogo_profile_reset_help": "Ceci détruira un profil Sogo des utilisateurs et <b>supprimera toutes les données de contact et de calendrier irrécupérables</b>.",
|
||||||
"sogo_profile_reset_now": "Remise à zéro du profil maintenant",
|
"sogo_profile_reset_now": "Remise à zéro du profil maintenant",
|
||||||
"spam_aliases": "Alias de courriel temporaire",
|
"spam_aliases": "Alias de courriel temporaire",
|
||||||
|
|||||||
@@ -394,7 +394,12 @@
|
|||||||
"filters": "Szűrők",
|
"filters": "Szűrők",
|
||||||
"login_as": "Bejelentkezés mint",
|
"login_as": "Bejelentkezés mint",
|
||||||
"quarantine": "Karantén műveletek",
|
"quarantine": "Karantén műveletek",
|
||||||
"bcc_maps": "BCC címek"
|
"bcc_maps": "BCC címek",
|
||||||
|
"domain_relayhost": "Relayhost megváltoztatása egy domainhez",
|
||||||
|
"protocol_access": "Protokoll-hozzáférés módosítása",
|
||||||
|
"quarantine_attachments": "Karantén mellékletek",
|
||||||
|
"quarantine_category": "Karantén értesítési kategória módosítása",
|
||||||
|
"quarantine_notification": "Karantén értesítések módosítása"
|
||||||
},
|
},
|
||||||
"diagnostics": {
|
"diagnostics": {
|
||||||
"dns_records": "DNS bejegyzések"
|
"dns_records": "DNS bejegyzések"
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -107,7 +107,8 @@
|
|||||||
"validate": "Проверить",
|
"validate": "Проверить",
|
||||||
"validation_success": "Проверка прошла успешно",
|
"validation_success": "Проверка прошла успешно",
|
||||||
"tags": "Теги",
|
"tags": "Теги",
|
||||||
"app_passwd_protocols": "Разрешенные протоколы для пароля приложения"
|
"app_passwd_protocols": "Разрешенные протоколы для пароля приложения",
|
||||||
|
"dry": "Имитировать синхронизацию"
|
||||||
},
|
},
|
||||||
"admin": {
|
"admin": {
|
||||||
"access": "Настройки доступа",
|
"access": "Настройки доступа",
|
||||||
@@ -625,11 +626,14 @@
|
|||||||
"auth_user": "{= auth_user =} - Аутентифицированное имя пользователя, указанное MTA",
|
"auth_user": "{= auth_user =} - Аутентифицированное имя пользователя, указанное MTA",
|
||||||
"from_user": "{= from_user =} - Из пользовательской части envelope, например, для \"moo@mailcow.tld\" возвращается \"moo\"",
|
"from_user": "{= from_user =} - Из пользовательской части envelope, например, для \"moo@mailcow.tld\" возвращается \"moo\"",
|
||||||
"from_addr": "{= from_addr =} - Из адресной части envelope",
|
"from_addr": "{= from_addr =} - Из адресной части envelope",
|
||||||
"from_domain": "{= from_domain =} - из доменной части envelope"
|
"from_domain": "{= from_domain =} - из доменной части envelope",
|
||||||
|
"custom": "{= foo =} - Если почтовый ящик имеет пользовательский атрибут \"foo\" со значением \"bar\", он возвращает \"bar\"."
|
||||||
},
|
},
|
||||||
"domain_footer": "Нижний колонтитул домена",
|
"domain_footer": "Нижний колонтитул домена",
|
||||||
"domain_footer_html": "HTML нижний колонтитул",
|
"domain_footer_html": "HTML нижний колонтитул",
|
||||||
"domain_footer_plain": "ПРОСТОЙ нижний колонтитул"
|
"domain_footer_plain": "ПРОСТОЙ нижний колонтитул",
|
||||||
|
"mbox_exclude": "Исключить почтовые ящики",
|
||||||
|
"custom_attributes": "Пользовательские атрибуты"
|
||||||
},
|
},
|
||||||
"fido2": {
|
"fido2": {
|
||||||
"confirm": "Подтвердить",
|
"confirm": "Подтвердить",
|
||||||
@@ -1198,7 +1202,9 @@
|
|||||||
"apple_connection_profile_with_app_password": "Новый пароль приложения генерируется и добавляется в профиль, поэтому при настройке устройства не требуется вводить пароль. Не предоставляйте доступ к файлу, поскольку он предоставляет полный доступ к вашему почтовому ящику.",
|
"apple_connection_profile_with_app_password": "Новый пароль приложения генерируется и добавляется в профиль, поэтому при настройке устройства не требуется вводить пароль. Не предоставляйте доступ к файлу, поскольку он предоставляет полный доступ к вашему почтовому ящику.",
|
||||||
"direct_protocol_access": "Этот пользователь почтового ящика имеет <b>прямой, внешний доступ</b> к следующим протоколам и приложениям. Эта настройка контролируется вашим администратором. Для предоставления доступа к отдельным протоколам и приложениям могут быть созданы пароли приложений.<br> Кнопка \"Вход в веб-почту\" обеспечивает единый вход в SOGo и всегда доступна.",
|
"direct_protocol_access": "Этот пользователь почтового ящика имеет <b>прямой, внешний доступ</b> к следующим протоколам и приложениям. Эта настройка контролируется вашим администратором. Для предоставления доступа к отдельным протоколам и приложениям могут быть созданы пароли приложений.<br> Кнопка \"Вход в веб-почту\" обеспечивает единый вход в SOGo и всегда доступна.",
|
||||||
"with_app_password": "с паролем приложения",
|
"with_app_password": "с паролем приложения",
|
||||||
"change_password_hint_app_passwords": "В вашей учетной записи есть {{number_of_app_passwords}} паролей приложений, которые не будут изменены. Чтобы управлять ими, перейдите на вкладку \"Пароли приложений\"."
|
"change_password_hint_app_passwords": "В вашей учетной записи есть {{number_of_app_passwords}} паролей приложений, которые не будут изменены. Чтобы управлять ими, перейдите на вкладку \"Пароли приложений\".",
|
||||||
|
"attribute": "Атрибут",
|
||||||
|
"value": "Значение"
|
||||||
},
|
},
|
||||||
"warning": {
|
"warning": {
|
||||||
"cannot_delete_self": "Вы не можете удалить сами себя",
|
"cannot_delete_self": "Вы не можете удалить сами себя",
|
||||||
|
|||||||
@@ -342,7 +342,12 @@
|
|||||||
"username": "Uporabniško ime",
|
"username": "Uporabniško ime",
|
||||||
"validate_license_now": "Potrdi GUID z licenčnim strežnikom",
|
"validate_license_now": "Potrdi GUID z licenčnim strežnikom",
|
||||||
"verify": "Preveri",
|
"verify": "Preveri",
|
||||||
"yes": "✓"
|
"yes": "✓",
|
||||||
|
"logo_normal_label": "Navadno",
|
||||||
|
"logo_dark_label": "Za temni način",
|
||||||
|
"cors_settings": "Nastavitve CORS",
|
||||||
|
"allowed_methods": "Dovoljene metode za upravljanje dostopa",
|
||||||
|
"allowed_origins": "Upravljanje-dostopa-Dovoljeni-Viri"
|
||||||
},
|
},
|
||||||
"danger": {
|
"danger": {
|
||||||
"alias_goto_identical": "Alias in goto naslov morata biti identična",
|
"alias_goto_identical": "Alias in goto naslov morata biti identična",
|
||||||
@@ -391,6 +396,161 @@
|
|||||||
"invalid_destination": "Ciljna oblika \"%s\" ni veljavna",
|
"invalid_destination": "Ciljna oblika \"%s\" ni veljavna",
|
||||||
"invalid_filter_type": "Neveljavna vrsta filtra",
|
"invalid_filter_type": "Neveljavna vrsta filtra",
|
||||||
"invalid_host": "Naveden je neveljaven gostitelj (host): %s",
|
"invalid_host": "Naveden je neveljaven gostitelj (host): %s",
|
||||||
"invalid_mime_type": "Neveljaven mime type"
|
"invalid_mime_type": "Neveljaven mime type",
|
||||||
|
"max_quota_in_use": "Kvota poštnega predala mora biti večja ali enaka %d MB",
|
||||||
|
"password_complexity": "Geslo ne ustreza varnostni politiki",
|
||||||
|
"pushover_credentials_missing": "Manjka Pushover token ali ključ",
|
||||||
|
"release_send_failed": "Sporočila ni bilo mogoče sprostiti: %s",
|
||||||
|
"tls_policy_map_dest_invalid": "Cilj politike ni veljaven",
|
||||||
|
"webauthn_authenticator_failed": "Izbrani avtentikator ni bil najden",
|
||||||
|
"reset_f2b_regex": "Regex filter ni bilo možno ponastaviti v ustreznem času. Prosim poskusite ponovno ali počakajte nekaj sekund in ponovno naložite stran.",
|
||||||
|
"target_domain_invalid": "Ciljna domena %s ni veljavna",
|
||||||
|
"validity_missing": "Prosim nastavite obdobje veljavnosti",
|
||||||
|
"invalid_recipient_map_old": "Naveden neveljaven izvirni prejemnik: %s",
|
||||||
|
"ip_list_empty": "Seznam dovoljenih IPjev ne sme biti prazen",
|
||||||
|
"is_alias": "%s je že znan kot alias naslov",
|
||||||
|
"is_alias_or_mailbox": "%s je že znan kot alias, poštni naslov, ali alias izveden iz alias domene",
|
||||||
|
"is_spam_alias": "%s že obstaja kot začasen alias (spam alias naslov)",
|
||||||
|
"last_key": "Zadnji ključ ne more biti izbrisan, prosim raje deaktivirajte dvofaktorsko avtentikacijo (TFA)",
|
||||||
|
"login_failed": "Prijava ni uspela",
|
||||||
|
"mailbox_defquota_exceeds_mailbox_maxquota": "Privzeta kvota presega najvišjo omejitev",
|
||||||
|
"mailbox_invalid": "Ime poštnega predala ni veljavno",
|
||||||
|
"mailbox_quota_exceeded": "Kvota presega omejitev domene (maksimalno %d MB)",
|
||||||
|
"mailbox_quota_exceeds_domain_quota": "Najvišja kvota presega omejitev domene",
|
||||||
|
"mailbox_quota_left_exceeded": "Ni dovolj prostora (preostali prostor: %d MB)",
|
||||||
|
"mailboxes_in_use": "Največje število poštnih predalov mora biti večje ali enako %d",
|
||||||
|
"malformed_username": "Nepravilno oblikovano uporabniško ime",
|
||||||
|
"map_content_empty": "Preslikava vsebine ne more biti prazna",
|
||||||
|
"max_alias_exceeded": "Preseženo največje število aliasov",
|
||||||
|
"max_mailbox_exceeded": "Preseženo največje število poštnih predalov (%d od %d)",
|
||||||
|
"maxquota_empty": "Največja kvota na poštni predal ne more biti 0",
|
||||||
|
"mysql_error": "Napaka MySQL: %s",
|
||||||
|
"network_host_invalid": "Nepravilno omrežje ali gostitel: %s",
|
||||||
|
"next_hop_interferes": "% moti naslednji skok %s",
|
||||||
|
"next_hop_interferes_any": "Obstoječi naslednji skok moti %s",
|
||||||
|
"nginx_reload_failed": "Ponovni zagon Nginx ni uspel: %s",
|
||||||
|
"no_user_defined": "Uporabnik ni določen",
|
||||||
|
"object_exists": "Objekt %s že obstaja",
|
||||||
|
"object_is_not_numeric": "Vrednost %s ni numerična",
|
||||||
|
"password_empty": "Geslo ne sme biti prazno",
|
||||||
|
"password_mismatch": "Potrditev gesla se ne ujema z geslom",
|
||||||
|
"policy_list_from_exists": "Zapis z tem imenom že obstaja",
|
||||||
|
"policy_list_from_invalid": "Zapis ima nepravilno obliko",
|
||||||
|
"private_key_error": "Napaka zasebnega ključa: %s",
|
||||||
|
"pushover_key": "Pushover ključ ni v pravilni obliki",
|
||||||
|
"pushover_token": "Pushover token ni v pravilni obliki",
|
||||||
|
"quota_not_0_not_numeric": "Quota mora biti število in večje ali enako 0",
|
||||||
|
"recipient_map_entry_exists": "Preslikava prejemnika \"%s\" že obstaja",
|
||||||
|
"redis_error": "Napaka Redis: %s",
|
||||||
|
"relayhost_invalid": "Vnos preslikave %s ni pravilen",
|
||||||
|
"resource_invalid": "Ime vira je neveljavno",
|
||||||
|
"rl_timeframe": "Časovni okvir za rate limit je nepravilen",
|
||||||
|
"rspamd_ui_pw_length": "Rspamd UI geslo mora biti dolgo vsaj 6 znakov",
|
||||||
|
"script_empty": "Script ne more biti prazen",
|
||||||
|
"sender_acl_invalid": "Vrednost ACL pošiljatelja %s ni veljavna",
|
||||||
|
"set_acl_failed": "Ni uspelo nastaviti ACL",
|
||||||
|
"settings_map_invalid": "ID preslikave nastavitev %s ni veljaven",
|
||||||
|
"sieve_error": "Napaka Sieve parserja: %s",
|
||||||
|
"spam_learn_error": "Napaka pri učenju spama: %s",
|
||||||
|
"subject_empty": "Predmet ne sme biti prazno",
|
||||||
|
"targetd_not_found": "Ciljna domena %s ni bila najdena",
|
||||||
|
"targetd_relay_domain": "Ciljna domena %s je relay domena",
|
||||||
|
"template_exists": "Predloga %s že obstaja",
|
||||||
|
"template_id_invalid": "ID predloge %s ni veljaven",
|
||||||
|
"template_name_invalid": "Ime predloge ni veljavno",
|
||||||
|
"text_empty": "Besedilo ne sme biti prazno",
|
||||||
|
"tfa_token_invalid": "Neveljaven token TFA",
|
||||||
|
"tls_policy_map_entry_exists": "Vpis preslikave TLS \"%s\" že obstaja",
|
||||||
|
"tls_policy_map_parameter_invalid": "Parameter politike ni pravilen",
|
||||||
|
"totp_verification_failed": "Neuspešno preverjanje TOTP",
|
||||||
|
"transport_dest_exists": "Cilj transporta \"%s\" že obstaja",
|
||||||
|
"webauthn_verification_failed": "Preverjanje WebAuthn ni uspelo: %s",
|
||||||
|
"webauthn_publickey_failed": "Na izbranem avtentikatorju ni shranjenega javnega ključa",
|
||||||
|
"webauthn_username_failed": "Izbrani avtentikator pripada drugemu uporabniškemu računu",
|
||||||
|
"unknown": "Pojavila se je neznana napaka",
|
||||||
|
"unknown_tfa_method": "Neznana metoda TFA",
|
||||||
|
"unlimited_quota_acl": "Neomejena kvota je prepovedana z ACL",
|
||||||
|
"username_invalid": "Uporabniško ime %s ne more biti uporabljeno",
|
||||||
|
"value_missing": "Prosim vnesite vse vrednosti",
|
||||||
|
"yotp_verification_failed": "Preverjanje Yubico OTP ni uspelo: %s",
|
||||||
|
"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"
|
||||||
|
},
|
||||||
|
"debug": {
|
||||||
|
"containers_info": "Informacije o vsebniku (containerju)",
|
||||||
|
"architecture": "Arhitektura",
|
||||||
|
"chart_this_server": "Diagram (ta strežnik)",
|
||||||
|
"container_running": "Aktiven",
|
||||||
|
"container_disabled": "Ustavljen ali onemogočen",
|
||||||
|
"container_stopped": "Ustavljen",
|
||||||
|
"cores": "Jedra",
|
||||||
|
"current_time": "Sistemski čas",
|
||||||
|
"disk_usage": "Zasedenost diska",
|
||||||
|
"docs": "Dokumenti",
|
||||||
|
"error_show_ip": "Ni mogoče preveriti javnega IP naslova",
|
||||||
|
"external_logs": "Zunanji dnevniki",
|
||||||
|
"last_modified": "Nazadnje spremenjeno",
|
||||||
|
"history_all_servers": "Zgodovina (vsi strežniki)",
|
||||||
|
"in_memory_logs": "In-memory dnevniki",
|
||||||
|
"jvm_memory_solr": "JVM zasedenost spomina",
|
||||||
|
"service": "Servis",
|
||||||
|
"show_ip": "Prikaži javni IP",
|
||||||
|
"size": "Velikost",
|
||||||
|
"solr_dead": "Solr se zaganja, je onemogočen ali se je ustavil.",
|
||||||
|
"solr_status": "Status Solr",
|
||||||
|
"started_at": "Zagnano ob",
|
||||||
|
"started_on": "Zagnano na",
|
||||||
|
"static_logs": "Statični dnevniki",
|
||||||
|
"success": "Uspešno",
|
||||||
|
"system_containers": "Sistem in Containerji",
|
||||||
|
"timezone": "Časovni pas",
|
||||||
|
"uptime": "Čas delovanja",
|
||||||
|
"update_available": "Posodobitev je na voljo",
|
||||||
|
"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"
|
||||||
|
},
|
||||||
|
"datatables": {
|
||||||
|
"infoFiltered": "(filtrirano od _MAX_ skupaj zapisov)",
|
||||||
|
"collapse_all": "Strni vse",
|
||||||
|
"decimal": ",",
|
||||||
|
"emptyTable": "Ni podatkov",
|
||||||
|
"expand_all": "Razširi vse",
|
||||||
|
"info": "Prikazano _START_ do _END_ od _TOTAL_ zapisov",
|
||||||
|
"infoEmpty": "Prikazano 0 do 0 od 0 zapisov",
|
||||||
|
"thousands": ".",
|
||||||
|
"lengthMenu": "Prikaži _MENU_ zapise",
|
||||||
|
"loadingRecords": "Nalaganje...",
|
||||||
|
"processing": "Prosim počakajte...",
|
||||||
|
"search": "Iskanje:",
|
||||||
|
"zeroRecords": "Ni ujemajočih zapisov",
|
||||||
|
"paginate": {
|
||||||
|
"first": "Prva",
|
||||||
|
"last": "Zadnja",
|
||||||
|
"previous": "Prejšnja",
|
||||||
|
"next": "Naslednja"
|
||||||
|
},
|
||||||
|
"aria": {
|
||||||
|
"sortAscending": ": aktivirajte za razvrstitev stolpca naraščajoče",
|
||||||
|
"sortDescending": ": aktivirajte za razvrstitev stolpca padajoče"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"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_name": "Ime",
|
||||||
|
"dns_records_status": "Trenutno stanje",
|
||||||
|
"dns_records_type": "Vrsta",
|
||||||
|
"optional": "Ta zapis je opcijski."
|
||||||
|
},
|
||||||
|
"edit": {
|
||||||
|
"acl": "ACL (Dovoljenje)",
|
||||||
|
"active": "Aktivno"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@
|
|||||||
"alias_domain": "Alias doména",
|
"alias_domain": "Alias doména",
|
||||||
"alias_domain_info": "<small>Len platné mená domén (oddelené čiarkou).</small>",
|
"alias_domain_info": "<small>Len platné mená domén (oddelené čiarkou).</small>",
|
||||||
"app_name": "Meno aplikácie",
|
"app_name": "Meno aplikácie",
|
||||||
"app_passwd_protocols": "Povolené protokoly pre heslá aplikácií",
|
"app_passwd_protocols": "Povolené protokoly k heslu aplikácie",
|
||||||
"app_password": "Pridať heslo aplikácie",
|
"app_password": "Pridať heslo aplikácie",
|
||||||
"automap": "Skúsiť automaticky mapovať priečinky (\"Sent items\", \"Sent\" => \"Sent\" atd.)",
|
"automap": "Skúsiť automaticky mapovať priečinky (\"Sent items\", \"Sent\" => \"Sent\" atd.)",
|
||||||
"backup_mx_options": "Možnosti preposielania",
|
"backup_mx_options": "Možnosti preposielania",
|
||||||
@@ -107,7 +107,6 @@
|
|||||||
"username": "Používateľské meno",
|
"username": "Používateľské meno",
|
||||||
"validate": "Overiť",
|
"validate": "Overiť",
|
||||||
"validation_success": "Úspešne overené",
|
"validation_success": "Úspešne overené",
|
||||||
"app_passwd_protocols": "Povolené protokoly k heslu aplikácie",
|
|
||||||
"tags": "Štítky"
|
"tags": "Štítky"
|
||||||
},
|
},
|
||||||
"admin": {
|
"admin": {
|
||||||
@@ -148,6 +147,8 @@
|
|||||||
"ays": "Naozaj chcete pokračovať?",
|
"ays": "Naozaj chcete pokračovať?",
|
||||||
"ban_list_info": "Zoznam zakázaných IP je zobrazený nižšie: <b>sieť (zostávajúci čas zákazu) - [akcia]</b>.<br />IP adresy zaradené na unban budú odstránené z aktívneho zoznamu v priebehu niekoľkých sekúnd.<br />Červené položky zobrazujú permanentné blokovanie.",
|
"ban_list_info": "Zoznam zakázaných IP je zobrazený nižšie: <b>sieť (zostávajúci čas zákazu) - [akcia]</b>.<br />IP adresy zaradené na unban budú odstránené z aktívneho zoznamu v priebehu niekoľkých sekúnd.<br />Červené položky zobrazujú permanentné blokovanie.",
|
||||||
"change_logo": "Zmeniť logo",
|
"change_logo": "Zmeniť logo",
|
||||||
|
"logo_normal_label": "Normálne",
|
||||||
|
"logo_dark_label": "Inverzné pre tmavý režim",
|
||||||
"configuration": "Konfigurácia",
|
"configuration": "Konfigurácia",
|
||||||
"convert_html_to_text": "Konvertovať HTML do obyčajného textu",
|
"convert_html_to_text": "Konvertovať HTML do obyčajného textu",
|
||||||
"credentials_transport_warning": "<b>Upozornenie</b>: Pridaním ďalšieho záznamu do transportnej mapy bude mať za následok aktualizovanie údajov pre všetky záznamy so zhodným ďalším skokom.",
|
"credentials_transport_warning": "<b>Upozornenie</b>: Pridaním ďalšieho záznamu do transportnej mapy bude mať za následok aktualizovanie údajov pre všetky záznamy so zhodným ďalším skokom.",
|
||||||
@@ -207,6 +208,9 @@
|
|||||||
"include_exclude": "Zahrnúť/Vylúčiť",
|
"include_exclude": "Zahrnúť/Vylúčiť",
|
||||||
"include_exclude_info": "Ak nič nevyberiete tak bude adresované <b>všetkým schránkam</b>",
|
"include_exclude_info": "Ak nič nevyberiete tak bude adresované <b>všetkým schránkam</b>",
|
||||||
"includes": "Zahrnúť týchto príjemcov",
|
"includes": "Zahrnúť týchto príjemcov",
|
||||||
|
"ip_check": "Kontrola IP",
|
||||||
|
"ip_check_disabled": "Kontrola IP je vypnutá. Môžete ju zapnúť v ponuke<br> <strong>Systém > Konfigurácia > Možnosti > Prispôsobiť</strong>",
|
||||||
|
"ip_check_opt_in": "Prihlásiť sa k používaniu služby tretej strany <strong>ipv4.mailcow.email</strong> a <strong>ipv6.mailcow.email</strong> za účelom zistenia externých IP adries.",
|
||||||
"is_mx_based": "Na základe MX",
|
"is_mx_based": "Na základe MX",
|
||||||
"last_applied": "Naposledy aplikované",
|
"last_applied": "Naposledy aplikované",
|
||||||
"license_info": "Licencia nie je potrebná, ale napomáha ďalšiemu vývoju.<br><a href=\"https://www.servercow.de/mailcow?lang=en#sal\" target=\"_blank\" alt=\"SAL order\">Registrujte váš GUID tu</a> alebo <a href=\"https://www.servercow.de/mailcow?lang=en#support\" target=\"_blank\" alt=\"Objednávka podpory\">zakúpte si podporu pre vašu mailcow inštaláciu.</a>",
|
"license_info": "Licencia nie je potrebná, ale napomáha ďalšiemu vývoju.<br><a href=\"https://www.servercow.de/mailcow?lang=en#sal\" target=\"_blank\" alt=\"SAL order\">Registrujte váš GUID tu</a> alebo <a href=\"https://www.servercow.de/mailcow?lang=en#support\" target=\"_blank\" alt=\"Objednávka podpory\">zakúpte si podporu pre vašu mailcow inštaláciu.</a>",
|
||||||
@@ -233,6 +237,7 @@
|
|||||||
"oauth2_renew_secret": "Vygenerovať nový tajný kľuč",
|
"oauth2_renew_secret": "Vygenerovať nový tajný kľuč",
|
||||||
"oauth2_revoke_tokens": "Odobrať všetky tokeny klienta",
|
"oauth2_revoke_tokens": "Odobrať všetky tokeny klienta",
|
||||||
"optional": "voliteľné",
|
"optional": "voliteľné",
|
||||||
|
"options": "Možnosti",
|
||||||
"password": "Heslo",
|
"password": "Heslo",
|
||||||
"password_length": "Dĺžka hesla",
|
"password_length": "Dĺžka hesla",
|
||||||
"password_policy": "Politika hesiel",
|
"password_policy": "Politika hesiel",
|
||||||
@@ -440,6 +445,9 @@
|
|||||||
"target_domain_invalid": "Cieľová doména %s je neplatná",
|
"target_domain_invalid": "Cieľová doména %s je neplatná",
|
||||||
"targetd_not_found": "Cieľová doména %s sa nenašla",
|
"targetd_not_found": "Cieľová doména %s sa nenašla",
|
||||||
"targetd_relay_domain": "Cieľová doména %s je posielaná ďalej (relay)",
|
"targetd_relay_domain": "Cieľová doména %s je posielaná ďalej (relay)",
|
||||||
|
"template_exists": "Šablóna %s už existuje",
|
||||||
|
"template_id_invalid": "Šablóna ID %s je neplatná",
|
||||||
|
"template_name_invalid": "Názov šablóny je neplatný",
|
||||||
"temp_error": "Dočasná chyba",
|
"temp_error": "Dočasná chyba",
|
||||||
"text_empty": "Text nemôže byť prázdny",
|
"text_empty": "Text nemôže byť prázdny",
|
||||||
"tfa_token_invalid": "Neplatný TFA token",
|
"tfa_token_invalid": "Neplatný TFA token",
|
||||||
@@ -529,7 +537,7 @@
|
|||||||
"allowed_protocols": "Povolené protokoly",
|
"allowed_protocols": "Povolené protokoly",
|
||||||
"app_name": "Meno aplikácie",
|
"app_name": "Meno aplikácie",
|
||||||
"app_passwd": "Heslo aplikácie",
|
"app_passwd": "Heslo aplikácie",
|
||||||
"app_passwd_protocols": "Povolené protokoly pre heslá aplikácií",
|
"app_passwd_protocols": "Povolené protokoly",
|
||||||
"automap": "Skúsiť automapovať priečinky (\"Sent items\", \"Sent\" => \"Sent\" atd.)",
|
"automap": "Skúsiť automapovať priečinky (\"Sent items\", \"Sent\" => \"Sent\" atd.)",
|
||||||
"backup_mx_options": "Možnosti preposielania",
|
"backup_mx_options": "Možnosti preposielania",
|
||||||
"bcc_dest_format": "Cieľ kópie musí byť jedna platná emailová adresa. Pokiaľ potrebujete posielať kópie na viac adries, vytvorte Alias a použite ho tu.",
|
"bcc_dest_format": "Cieľ kópie musí byť jedna platná emailová adresa. Pokiaľ potrebujete posielať kópie na viac adries, vytvorte Alias a použite ho tu.",
|
||||||
@@ -614,8 +622,8 @@
|
|||||||
"sieve_desc": "Krátky popis",
|
"sieve_desc": "Krátky popis",
|
||||||
"sieve_type": "Typ filtru",
|
"sieve_type": "Typ filtru",
|
||||||
"skipcrossduplicates": "Preskočiť duplikované správy naprieč priečinkami (akceptuje sa prvý nález)",
|
"skipcrossduplicates": "Preskočiť duplikované správy naprieč priečinkami (akceptuje sa prvý nález)",
|
||||||
"sogo_access": "Udeliť priamy prístup k prihláseniu do služby SOGo",
|
"sogo_access": "Prideliť priame prihlásenie do SOGo",
|
||||||
"sogo_access_info": "Jednotné prihlásenie (SSO) z mail UI zostáva funkčné. Toto nastavenie nemá vplyv na prístup k všetkým ostatným službám, ani neodstraňuje alebo nemení existujúci profil používateľa SOGo.",
|
"sogo_access_info": "Jednotné prihlásenie z používateľského mail rozhrania zostáva funkčné. Toto nastavenie nemá vplyv na prístup k ostatným službám, ani neodstraňuje alebo nemení existujúci profil používateľa SOGo.",
|
||||||
"sogo_visible": "Alias je viditeľný v SOGo",
|
"sogo_visible": "Alias je viditeľný v SOGo",
|
||||||
"sogo_visible_info": "Táto voľba ovplyvňuje len objekty, ktoré dokážu byť zobrazené v SOGo (zdieľané alebo nezdieľané alias adresy ukazujúc na minimálne jednu lokálnu mailovú schránku). Ak je skrytý, alias nebude prezentovaný ako voliteľný odosielateľ v SOGo.",
|
"sogo_visible_info": "Táto voľba ovplyvňuje len objekty, ktoré dokážu byť zobrazené v SOGo (zdieľané alebo nezdieľané alias adresy ukazujúc na minimálne jednu lokálnu mailovú schránku). Ak je skrytý, alias nebude prezentovaný ako voliteľný odosielateľ v SOGo.",
|
||||||
"spam_alias": "Vytvoriť alebo zmeniť časovo limitované alias adresy",
|
"spam_alias": "Vytvoriť alebo zmeniť časovo limitované alias adresy",
|
||||||
@@ -631,10 +639,7 @@
|
|||||||
"title": "Upraviť objekt",
|
"title": "Upraviť objekt",
|
||||||
"unchanged_if_empty": "Ak nemeníte, nechajte prázdne",
|
"unchanged_if_empty": "Ak nemeníte, nechajte prázdne",
|
||||||
"username": "Používateľské meno",
|
"username": "Používateľské meno",
|
||||||
"validate_save": "Validovať a uložiť",
|
"validate_save": "Validovať a uložiť"
|
||||||
"sogo_access": "Prideliť priame prihlásenie do SOGo",
|
|
||||||
"sogo_access_info": "Jednotné prihlásenie z používateľského mail rozhrania zostáva funkčné. Toto nastavenie nemá vplyv na prístup k ostatným službám, ani neodstraňuje alebo nemení existujúci profil používateľa SOGo.",
|
|
||||||
"app_passwd_protocols": "Povolené protokoly"
|
|
||||||
},
|
},
|
||||||
"fido2": {
|
"fido2": {
|
||||||
"confirm": "Potvrdiť",
|
"confirm": "Potvrdiť",
|
||||||
@@ -671,6 +676,7 @@
|
|||||||
"apps": "Aplikácie",
|
"apps": "Aplikácie",
|
||||||
"debug": "Systémové informácie",
|
"debug": "Systémové informácie",
|
||||||
"email": "E-Mail",
|
"email": "E-Mail",
|
||||||
|
"mailcow_system": "Systém",
|
||||||
"mailcow_config": "Konfigurácia",
|
"mailcow_config": "Konfigurácia",
|
||||||
"quarantine": "Karanténa",
|
"quarantine": "Karanténa",
|
||||||
"restart_netfilter": "Reštartovať netfilter",
|
"restart_netfilter": "Reštartovať netfilter",
|
||||||
@@ -706,6 +712,7 @@
|
|||||||
"add_mailbox": "Pridať mailovú schránku",
|
"add_mailbox": "Pridať mailovú schránku",
|
||||||
"add_recipient_map_entry": "Pridať mapu príjemcu",
|
"add_recipient_map_entry": "Pridať mapu príjemcu",
|
||||||
"add_resource": "Pridať zdroj",
|
"add_resource": "Pridať zdroj",
|
||||||
|
"add_template": "Pridať šablónu",
|
||||||
"add_tls_policy_map": "Pridať TLS mapu pravidiel",
|
"add_tls_policy_map": "Pridať TLS mapu pravidiel",
|
||||||
"address_rewriting": "Prepisovanie adries",
|
"address_rewriting": "Prepisovanie adries",
|
||||||
"alias": "Alias",
|
"alias": "Alias",
|
||||||
@@ -748,6 +755,7 @@
|
|||||||
"domain": "Doména",
|
"domain": "Doména",
|
||||||
"domain_admins": "Administrátori domény",
|
"domain_admins": "Administrátori domény",
|
||||||
"domain_aliases": "Alias domény",
|
"domain_aliases": "Alias domény",
|
||||||
|
"domain_templates": "Šablóny domén",
|
||||||
"domain_quota": "Kvóta",
|
"domain_quota": "Kvóta",
|
||||||
"domain_quota_total": "Celkové kvóta domény",
|
"domain_quota_total": "Celkové kvóta domény",
|
||||||
"domains": "Domény",
|
"domains": "Domény",
|
||||||
@@ -776,6 +784,7 @@
|
|||||||
"mailbox_defaults": "Predvolené nastavenia",
|
"mailbox_defaults": "Predvolené nastavenia",
|
||||||
"mailbox_defaults_info": "Definuje predvolené nastavenia pre nové schránky.",
|
"mailbox_defaults_info": "Definuje predvolené nastavenia pre nové schránky.",
|
||||||
"mailbox_defquota": "Predvolená veľkosť schránky",
|
"mailbox_defquota": "Predvolená veľkosť schránky",
|
||||||
|
"mailbox_templates": "Šablóny schránok",
|
||||||
"mailbox_quota": "Max. veľkosť schránky",
|
"mailbox_quota": "Max. veľkosť schránky",
|
||||||
"mailboxes": "Mailové schránky",
|
"mailboxes": "Mailové schránky",
|
||||||
"max_aliases": "Max. počet aliasov",
|
"max_aliases": "Max. počet aliasov",
|
||||||
@@ -843,6 +852,8 @@
|
|||||||
"table_size_show_n": "Zobraziť %s položiek",
|
"table_size_show_n": "Zobraziť %s položiek",
|
||||||
"target_address": "Cieľová adresa",
|
"target_address": "Cieľová adresa",
|
||||||
"target_domain": "Cieľová doména",
|
"target_domain": "Cieľová doména",
|
||||||
|
"templates": "Šablóny",
|
||||||
|
"template": "Šablóna",
|
||||||
"tls_enforce_in": "Vynútiť TLS pre prichádzajúcu poštu",
|
"tls_enforce_in": "Vynútiť TLS pre prichádzajúcu poštu",
|
||||||
"tls_enforce_out": "Vynútiť TLS pre odchádzajúcu poštu",
|
"tls_enforce_out": "Vynútiť TLS pre odchádzajúcu poštu",
|
||||||
"tls_map_dest": "Cieľ",
|
"tls_map_dest": "Cieľ",
|
||||||
@@ -1007,6 +1018,9 @@
|
|||||||
"settings_map_added": "Pridaná mapa nastavení",
|
"settings_map_added": "Pridaná mapa nastavení",
|
||||||
"settings_map_removed": "Odstránená mapa nastavení ID %s",
|
"settings_map_removed": "Odstránená mapa nastavení ID %s",
|
||||||
"sogo_profile_reset": "SOGo profil pre používateľa %s resetovaný",
|
"sogo_profile_reset": "SOGo profil pre používateľa %s resetovaný",
|
||||||
|
"template_added": "Pridaná šablóna %s",
|
||||||
|
"template_modified": "Zmeny šablóny %s boli uložené",
|
||||||
|
"template_removed": "Šablóna ID %s bola odstránená",
|
||||||
"tls_policy_map_entry_deleted": "Položka mapy TLS pravidiel %s vymazaná",
|
"tls_policy_map_entry_deleted": "Položka mapy TLS pravidiel %s vymazaná",
|
||||||
"tls_policy_map_entry_saved": "Položka mapy TLS pravidiel \"%s\" uložená",
|
"tls_policy_map_entry_saved": "Položka mapy TLS pravidiel \"%s\" uložená",
|
||||||
"ui_texts": "Zmeny v UI textoch uložené",
|
"ui_texts": "Zmeny v UI textoch uložené",
|
||||||
@@ -1065,9 +1079,9 @@
|
|||||||
"apple_connection_profile": "Apple konfiguračný profil",
|
"apple_connection_profile": "Apple konfiguračný profil",
|
||||||
"apple_connection_profile_complete": "Tento profil zahŕňa IMAP a SMTP parametre, ako aj CalDAV (kalendáre) a CardDAV (kontakty) pre zariadenia Apple.",
|
"apple_connection_profile_complete": "Tento profil zahŕňa IMAP a SMTP parametre, ako aj CalDAV (kalendáre) a CardDAV (kontakty) pre zariadenia Apple.",
|
||||||
"apple_connection_profile_mailonly": "Tento profil zahŕňa IMAP a SMTP konfiguračné parametre pre zariadenia Apple.",
|
"apple_connection_profile_mailonly": "Tento profil zahŕňa IMAP a SMTP konfiguračné parametre pre zariadenia Apple.",
|
||||||
"apple_connection_profile_with_app_password": "Nové heslo aplikácie sa vygeneruje a pridá do profilu, takže pri nastavovaní zariadenia nie je potrebné zadávať žiadne heslo. Súbor nezdieľajte, pretože poskytuje úplný prístup k vašej poštovej schránke.",
|
"apple_connection_profile_with_app_password": "Nové heslo aplikácie sa vygeneruje a pridá do profilu, takže pri nastavovaní zariadenia nie je potrebné zadávať žiadne heslo. Súbor nezdieľajte, pretože poskytuje úplný prístup k vašej mail schránke.",
|
||||||
"change_password": "Zmeniť heslo",
|
"change_password": "Zmeniť heslo",
|
||||||
"change_password_hint_app_passwords": "Váš účet má %d hesiel aplikácií, ktoré nebudú zmenené. Ak ich chcete spravovať, prejdite na kartu Heslá aplikácií.",
|
"change_password_hint_app_passwords": "Vaše konto má %d hesiel aplikácií, ktoré nebudú zmenené. Ak ich chcete spravovať, prejdite na kartu Heslá aplikácií.",
|
||||||
"clear_recent_successful_connections": "Vymazať nedávne úspešné prihlásenia",
|
"clear_recent_successful_connections": "Vymazať nedávne úspešné prihlásenia",
|
||||||
"client_configuration": "Zobraziť konfiguračné pokyny pre emailových klientov a smartfóny",
|
"client_configuration": "Zobraziť konfiguračné pokyny pre emailových klientov a smartfóny",
|
||||||
"create_app_passwd": "Vytvoriť heslo aplikácie",
|
"create_app_passwd": "Vytvoriť heslo aplikácie",
|
||||||
@@ -1078,7 +1092,7 @@
|
|||||||
"delete_ays": "Potvrďte zmazanie.",
|
"delete_ays": "Potvrďte zmazanie.",
|
||||||
"direct_aliases": "Priame alias adresy",
|
"direct_aliases": "Priame alias adresy",
|
||||||
"direct_aliases_desc": "Priame aliasy sú ovplyvnené spam filtrom a nastavením TLS pravidiel.",
|
"direct_aliases_desc": "Priame aliasy sú ovplyvnené spam filtrom a nastavením TLS pravidiel.",
|
||||||
"direct_protocol_access": "Tento používateľ mailovej schránky má <b>priamy, externý prístup</b> k nasledujúcim protokolom a aplikáciám. Toto nastavenie má pod kontrolou Váš správca. Na udelenie prístupu k jednotlivým protokolom a aplikáciám je možné vytvoriť heslá aplikácií.<br>Tlačidlo \" Prihláste sa do webmailu\" poskytuje jednotné prihlásenie do systému SOGo a je vždy k dispozícii.",
|
"direct_protocol_access": "Tento používateľ mailovej schránky má <b>priamy, externý prístup</b> k nasledujúcim protokolom a aplikáciám. Toto nastavenie kontroluje administrátor. Na udelenie prístupu k jednotlivým protokolom a aplikáciám je možné vytvoriť heslá aplikácií.<br>Tlačidlo \"Prihlásenie do webmailu\" poskytuje jednotné prihlásenie do systému SOGo a je vždy k dispozícii.",
|
||||||
"eas_reset": "Resetovať medzipamäť u ActiveSync zariadení",
|
"eas_reset": "Resetovať medzipamäť u ActiveSync zariadení",
|
||||||
"eas_reset_help": "Vo väčšine prípadov, reset medzipamäte ActiveSync pomôže opravit nefunkčný profil.<br><b>Pozor:</b> Všetky potrebné dáta budú opäť stiahnuté!",
|
"eas_reset_help": "Vo väčšine prípadov, reset medzipamäte ActiveSync pomôže opravit nefunkčný profil.<br><b>Pozor:</b> Všetky potrebné dáta budú opäť stiahnuté!",
|
||||||
"eas_reset_now": "Reset ActiveSync",
|
"eas_reset_now": "Reset ActiveSync",
|
||||||
@@ -1202,10 +1216,7 @@
|
|||||||
"weeks": "týždne",
|
"weeks": "týždne",
|
||||||
"with_app_password": "s heslom aplikácie",
|
"with_app_password": "s heslom aplikácie",
|
||||||
"year": "rok",
|
"year": "rok",
|
||||||
"years": "rokov",
|
"years": "rokov"
|
||||||
"apple_connection_profile_with_app_password": "Nové heslo aplikácie sa vygeneruje a pridá do profilu, takže pri nastavovaní zariadenia nie je potrebné zadávať žiadne heslo. Súbor nezdieľajte, pretože poskytuje úplný prístup k vašej mail schránke.",
|
|
||||||
"change_password_hint_app_passwords": "Vaše konto má %d hesiel aplikácií, ktoré nebudú zmenené. Ak ich chcete spravovať, prejdite na kartu Heslá aplikácií.",
|
|
||||||
"direct_protocol_access": "Tento používateľ mailovej schránky má <b>priamy, externý prístup</b> k nasledujúcim protokolom a aplikáciám. Toto nastavenie kontroluje administrátor. Na udelenie prístupu k jednotlivým protokolom a aplikáciám je možné vytvoriť heslá aplikácií.<br>Tlačidlo \"Prihlásenie do webmailu\" poskytuje jednotné prihlásenie do systému SOGo a je vždy k dispozícii."
|
|
||||||
},
|
},
|
||||||
"warning": {
|
"warning": {
|
||||||
"cannot_delete_self": "Nemožno vymazať prihláseného používateľa",
|
"cannot_delete_self": "Nemožno vymazať prihláseného používateľa",
|
||||||
|
|||||||
+102
-37
@@ -1,61 +1,113 @@
|
|||||||
{
|
{
|
||||||
"acl": {
|
"acl": {
|
||||||
"alias_domains": "Takma alan adı ekle",
|
"alias_domains": "Alias domain ekle",
|
||||||
"app_passwds": "Uygulama şifrelerini yönet",
|
"app_passwds": "Uygulama şifrelerini yönet",
|
||||||
"delimiter_action": "Sınırlama işlemi",
|
"bcc_maps": "BCC haritası",
|
||||||
"domain_relayhost": "Bir alan adı için relayhost sunucusunu değiştir",
|
"delimiter_action": "Sınırlandırma işlemi",
|
||||||
"eas_reset": "EAS cihazlarını sıfırla",
|
|
||||||
"mailbox_relayhost": "Bir posta kutusunun relayhost sunucularını değiştir",
|
|
||||||
"pushover": "Bildirim",
|
|
||||||
"quarantine": "Karantina işlemleri",
|
|
||||||
"quarantine_attachments": "Ekleri karantinaya al",
|
|
||||||
"quarantine_notification": "Karantina bildirimlerini değiştir",
|
|
||||||
"smtp_ip_access": "SMTP sunucularının değiştirilmesine izin ver",
|
|
||||||
"sogo_access": "SOGo erişiminin yönetilmesine izin ver",
|
|
||||||
"domain_desc": "Alan adı açıklamasını değiştir",
|
"domain_desc": "Alan adı açıklamasını değiştir",
|
||||||
"extend_sender_acl": "Gönderenin acl'sini harici adreslere göre genişletmeye izin ver",
|
"domain_relayhost": "Alan adı için relayhost sunucusunu değiştir",
|
||||||
"spam_policy": "Engellenenler / İzin verilenler",
|
"eas_reset": "EAS cihazlarını sıfırla",
|
||||||
"filters": "Fitreler"
|
"extend_sender_acl": "Gönderen ACL'sini harici adreslerle genişletmeye izin ver",
|
||||||
|
"filters": "Filtreler",
|
||||||
|
"login_as": "E-posta kullanıcısı olarak giriş yapın",
|
||||||
|
"mailbox_relayhost": "Bir e-posta için relayhost'u değiştirin",
|
||||||
|
"prohibited": "ACL tarafından yasaklandı",
|
||||||
|
"protocol_access": "Protokol erişimini değiştirin",
|
||||||
|
"pushover": "Pushover",
|
||||||
|
"quarantine": "Karantina eylemleri",
|
||||||
|
"quarantine_attachments": "Ekleri karantinaya al",
|
||||||
|
"quarantine_category": "Karantina bildirim kategorisini değiştir",
|
||||||
|
"quarantine_notification": "Karantina bildirimlerini değiştir",
|
||||||
|
"ratelimit": "Rate limit",
|
||||||
|
"recipient_maps": "Alıcı haritaları",
|
||||||
|
"smtp_ip_access": "SMTP için izin verilen host değerlerini değiştirme",
|
||||||
|
"sogo_access": "SOGo erişiminin yönetilmesine izin verin",
|
||||||
|
"sogo_profile_reset": "SOGo profilini sıfırla",
|
||||||
|
"spam_alias": "Geçici alias değerleri",
|
||||||
|
"spam_policy": "Kara Liste/Beyaz Liste",
|
||||||
|
"spam_score": "Spam skoru",
|
||||||
|
"syncjobs": "Görevleri senkronize et",
|
||||||
|
"tls_policy": "TLS ilkesi",
|
||||||
|
"unlimited_quota": "E-postalar için sınırsız kota"
|
||||||
},
|
},
|
||||||
"add": {
|
"add": {
|
||||||
"activate_filter_warn": "Aktif edilirse diğer tüm filtreler devre dışı bırakılacak.",
|
"activate_filter_warn": "Aktif edilirse diğer tüm filtreler devre dışı bırakılacak.",
|
||||||
|
"active": "Aktif",
|
||||||
|
"add": "Ekle",
|
||||||
"add_domain_only": "Sadece alan adı ekle",
|
"add_domain_only": "Sadece alan adı ekle",
|
||||||
"alias_address": "Takma ad adres(leri)",
|
"add_domain_restart": "Alan adını ekleyin ve SOGo'yu yeniden başlatın",
|
||||||
|
"alias_address": "Takma adres",
|
||||||
|
"alias_address_info": "<small>Bir alan adına ilişkin tüm iletileri yakalamak için tam e-posta adresi veya @example.com olacak şeklinde girin (virgülle ayırın).<b>sadece mailcow alan adları</b>.</small>",
|
||||||
"alias_domain": "Takma alan adı",
|
"alias_domain": "Takma alan adı",
|
||||||
"alias_domain_info": "<small>Sadece geçerli alan adları (virgülle ayırın).</small>",
|
"alias_domain_info": "<small>Sadece geçerli alan adları (virgülle ayrılmış).</small>",
|
||||||
"backup_mx_options": "İletme ayarları",
|
"app_name": "Uygulama adı",
|
||||||
"delete2": "Kaynakta olmayan hedefteki mesajları sil",
|
"app_password": "Uygulama şifresi ekle",
|
||||||
|
"app_passwd_protocols": "Uygulama şifresi için izin verilen protokoller",
|
||||||
|
"automap": "Klasörleri otomatik eşleştirmeyi deneyin (\"Gönderilen postalar\", \"Gönderilen\" => \"Gönderilen\" vb.)",
|
||||||
|
"backup_mx_options": "Relay ayarları",
|
||||||
|
"bcc_dest_format": "BCC hedefi tek bir geçerli e-posta adresi olmalıdır.<br>Bir kopyayı birden fazla adrese göndermeniz gerekiyorsa, bir takma ad oluşturun ve bunu burada kullanın.",
|
||||||
|
"comment_info": "Özel bir yorum kullanıcı tarafından görülemezken, herkese açık bir yorum kullanıcının genel görünümünde üzerine gelindiğinde tooltip olarak gösterilir",
|
||||||
|
"custom_params": "Özel parametreler",
|
||||||
|
"custom_params_hint": "Doğru: --param=xy, yanlış: --param xy",
|
||||||
|
"delete1": "Tamamlandığında kaynaktan sil",
|
||||||
|
"delete2": "Eğer kaynakta yoksa hedefteki mesajları sil",
|
||||||
"delete2duplicates": "Hedefteki kopyaları sil",
|
"delete2duplicates": "Hedefteki kopyaları sil",
|
||||||
"disable_login": "Giriş yapmaya izin verme ( Gelen mailler yine de kabul edilir)",
|
"description": "Açıklama",
|
||||||
|
"destination": "Hedef",
|
||||||
|
"disable_login": "Giriş yapmaya izin verme (gelen mailler yine de kabul edilir)",
|
||||||
"domain": "Alan adı",
|
"domain": "Alan adı",
|
||||||
"domain_matches_hostname": "Alan adı %s ana bilgisayar adıyla eşleşiyor",
|
"domain_matches_hostname": "Alan adı %s ana bilgisayar adıyla eşleşiyor",
|
||||||
"add_domain_restart": "Alan adı ekleyin ve SOGo'yu yeniden başlatın",
|
|
||||||
"alias_address_info": "<small>Bir alan adına ilişkin tüm iletileri yakalamak için tam e-posta adresi veya @example.com olacak şeklinde girin (virgülle ayırın).<b>sadece mailcow alan adları</b>.</small>",
|
|
||||||
"domain_quota_m": "Toplam alan adı kotası (MiB)",
|
"domain_quota_m": "Toplam alan adı kotası (MiB)",
|
||||||
|
"enc_method": "Şifreleme yöntemi",
|
||||||
|
"exclude": "Hariç tutma kuralı (regex)",
|
||||||
|
"full_name": "Tam isim",
|
||||||
|
"gal": "Global Adres Listesi",
|
||||||
|
"gal_info": "GAL bir alan alanının tüm nesnelerini içerir ve herhangi bir kullanıcı tarafından düzenlenemez. Eğer devre dışı bırakırsanız SOGo üzerindeki free/busy bilgileri kaybolur! <b>Değişiklikleri uygulamak için SOGo'yu yeniden başlatın.</b>",
|
||||||
"generate": "oluştur",
|
"generate": "oluştur",
|
||||||
"goto_ham": "Ham olarak<span class=\"text-success\"><b>işaretle</b></span>",
|
"goto_ham": "Ham olarak<span class=\"text-success\"><b>işaretle</b></span>",
|
||||||
"goto_null": "Postaları sessizce çöpe at",
|
"goto_null": "Postaları çöpe at",
|
||||||
"goto_spam": "Spam olarak<span class=\"text-danger\"><b>işaretle</b></span>",
|
"goto_spam": "Spam olarak<span class=\"text-danger\"><b>işaretle</b></span>",
|
||||||
"hostname": "Ana sunucu",
|
"hostname": "Ana sunucu",
|
||||||
|
"inactive": "İnaktif",
|
||||||
"kind": "Tür",
|
"kind": "Tür",
|
||||||
"mailbox_quota_m": "Posta kutusu başına maksimum kota (MiB)",
|
"mailbox_quota_def": "Varsayılan e-posta kotası",
|
||||||
"max_aliases": "Maksimum olası takma adı",
|
"mailbox_quota_m": "E-posta başına maksimum kota (MiB)",
|
||||||
"max_mailboxes": "Maksimum olası posta kutusu",
|
"mailbox_username": "Kullanıcı adı (e-posta adresinin sol kısmı)",
|
||||||
"nexthop": "Sonraki atlama",
|
"max_aliases": "Maksimum takma adı limiti",
|
||||||
|
"max_mailboxes": "Maksimum e-posta hesabı",
|
||||||
|
"mins_interval": "Sorgulama döngüsü (dakika)",
|
||||||
|
"multiple_bookings": "Birden fazla rezervasyon",
|
||||||
|
"nexthop": "Next hop",
|
||||||
|
"password": "Şifre",
|
||||||
|
"password_repeat": "Şifre (tekrar)",
|
||||||
"port": "Port",
|
"port": "Port",
|
||||||
"public_comment": "Genel yorum",
|
"post_domain_add": "SOGo konteynerinin \"sogo-mailcow\" yeni bir alan adı eklendikten sonra yeniden başlatılması gerekiyor!<br><br>Ayrıca alan adlarının DNS yapılandırması da gözden geçirilmelidir. DNS yapılandırması onaylandıktan sonra, yeni etki alanınız için otomatik olarak sertifika oluşturmak üzere \"acme-mailcow\"u yeniden başlatın (autoconfig.<domain>, autodiscover.<domain>).<br>Bu adım isteğe bağlıdır ve her 24 saatte bir yeniden denenecektir.",
|
||||||
"relay_all": "Tüm alıcılara ilet",
|
"private_comment": "Özel not",
|
||||||
"relay_all_info": "Eğer <b>hiçbir</b> alıcıya iletilmemesini seçerseniz, aktarılması gereken her alıcı için bir (\"kör\") posta kutusu eklemeniz gerekecektir.",
|
"public_comment": "Herkese açık not",
|
||||||
"relay_domain": "Bu alan adını ilet",
|
"quota_mb": "Kota (MiB)",
|
||||||
"relay_transport_info": "<div class=\"label label-info\">Bilgi</div> Bu etki alanı için özel bir hedef için aktarım eşlemeleri tanımlayabilirsiniz. Ayarlanmazsa, bir MX araması yapılacaktır.",
|
"relay_all": "Tüm alıcıları aktar",
|
||||||
"relay_unknown_only": "Yalnızca mevcut olmayan posta kutularını ilet. Mevcut posta kutuları yerel olarak teslim edilecektir.",
|
"relay_all_info": "↪ Tüm alıcıları <b>aktarmamayı</b> seçerseniz, aktarılması gereken her alıcı için bir (\"kör\") posta kutusu eklemeniz gerekecektir.",
|
||||||
"relayhost_wrapped_tls_info": "Lütfen TLS ile örtülmüş portları <b> kullanmayın</b> (çoğu 465 portunda çalışır).<br>\nÖrtülmemiş port kullan ve STARTTLS üzerinden yayınla. TLS'yi zorlamak için bir TLS ilkesi \"TLS ilke eşlemeleri\" sayfası içinde oluşturulabilir.",
|
"relay_domain": "Bu etki alanını aktarın",
|
||||||
"skipcrossduplicates": "Klasörler arasında yinelenen mesajları atlayın (ilk mesaj seçilir)",
|
"relay_transport_info": "<div class=\"badge fs-6 bg-info\">Bilgi</div> Bu alan adı nezdinde özel bir hedef için transport haritası tanımlayabilirsiniz. Eğer ayarlanmazsa, MX taraması yapılacaktır.",
|
||||||
|
"relay_unknown_only": "Yalnızca mevcut olmayan e-postaları aktarın. Mevcut e-postalar local olarak teslim edilecektir.",
|
||||||
|
"relayhost_wrapped_tls_info": "Lütfen örtülü TLS portları <b>kullanmayın</b> (çoğunlukla 465 portunda kullanılır).<br>\r\nÖrtülmüş olmayan herhangi bir bağlantı noktası kullanın ve STARTTLS üzerinden yayınlayın. TLS'yi zorlamak için bir TLS ilkesi \"TLS ilke eşlemeleri\" sayfası içinde oluşturulabilir.",
|
||||||
|
"select": "Lütfen seçiniz...",
|
||||||
|
"select_domain": "Lütfen önce alan adı seçin",
|
||||||
|
"sieve_desc": "Kısa açıklama",
|
||||||
|
"sieve_type": "Filtre türü",
|
||||||
|
"skipcrossduplicates": "Klasörler arasında yinelenen(kopya) mesajları es geçin (ilk gelen mail baz alınır)",
|
||||||
|
"subscribeall": "Tüm klasörlere abone ol",
|
||||||
|
"syncjob": "Senkronizasyon görevi ekle",
|
||||||
|
"syncjob_hint": "Parolaların düz metin olarak kaydedilmesi gerektiğini unutmayın!",
|
||||||
|
"tags": "Etiketler",
|
||||||
"target_address": "Adreslere git",
|
"target_address": "Adreslere git",
|
||||||
"target_address_info": "<small>Tam e-posta adres(leri) girin ( virgülle ayırın).</small>",
|
"target_address_info": "<small>Tam e-posta adresleri (virgülle ayrılmış).</small>",
|
||||||
"target_domain": "Hedef alan adı",
|
"target_domain": "Hedef alan adı",
|
||||||
"timeout1": "Uzak ana bilgisayara bağlantısı zaman aşımına uğradı",
|
"timeout1": "Uzak ana bilgisayara bağlantı için zaman aşımı",
|
||||||
"timeout2": "Yerel ana bilgisayara bağlantı zaman aşımına uğradı"
|
"timeout2": "Yerel ana bilgisayara bağlantı için zaman aşımı",
|
||||||
|
"username": "Kullanıcı Adı",
|
||||||
|
"validate": "Doğrula",
|
||||||
|
"validation_success": "Doğrulama başarılı"
|
||||||
},
|
},
|
||||||
"admin": {
|
"admin": {
|
||||||
"action": "İşlem",
|
"action": "İşlem",
|
||||||
@@ -82,5 +134,18 @@
|
|||||||
"f2b_ban_time": "Yasaklama süresi (saniye)",
|
"f2b_ban_time": "Yasaklama süresi (saniye)",
|
||||||
"f2b_max_attempts": "Maksimum giriş denemesi",
|
"f2b_max_attempts": "Maksimum giriş denemesi",
|
||||||
"f2b_retry_window": "Maksimum girişim için deneme pencere(leri)"
|
"f2b_retry_window": "Maksimum girişim için deneme pencere(leri)"
|
||||||
|
},
|
||||||
|
"warning": {
|
||||||
|
"cannot_delete_self": "Cannot delete logged in user",
|
||||||
|
"domain_added_sogo_failed": "Alan adı eklendi ancak SOGo yeniden başlatılamadı, lütfen sunucu log kayıtlarını kontrol edin.",
|
||||||
|
"dovecot_restart_failed": "Dovecot yeniden başlatılamadı, lütfen log kayıtlarını kontrol edin",
|
||||||
|
"fuzzy_learn_error": "Fuzzy hash hatayı öğrendi: %s",
|
||||||
|
"hash_not_found": "Hash bulunamadı veya zaten silinmiş",
|
||||||
|
"ip_invalid": "Geçersiz IP atlandı: %s",
|
||||||
|
"is_not_primary_alias": "Birincil olmayan alias %s atlandı",
|
||||||
|
"no_active_admin": "Son etkin yönetici devre dışı bırakılamaz",
|
||||||
|
"quota_exceeded_scope": "Domain kotası aşıldı: Bu domain kapsamında yalnızca sınırsız e-posta oluşturulabilir!",
|
||||||
|
"session_token": "Form token geçersiz: Token uyuşmadı",
|
||||||
|
"session_ua": "Form token geçersiz: User-Agent doğrulama hatası"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,7 +107,8 @@
|
|||||||
"kind": "Вид",
|
"kind": "Вид",
|
||||||
"delete1": "Видалити з джерела після завершення",
|
"delete1": "Видалити з джерела після завершення",
|
||||||
"delete2duplicates": "Видалити дублікати на місці призначення",
|
"delete2duplicates": "Видалити дублікати на місці призначення",
|
||||||
"domain_quota_m": "Загальна квота домену (МіБ)"
|
"domain_quota_m": "Загальна квота домену (МіБ)",
|
||||||
|
"dry": "Імітувати синхронізацію"
|
||||||
},
|
},
|
||||||
"admin": {
|
"admin": {
|
||||||
"access": "Налаштування доступу",
|
"access": "Налаштування доступу",
|
||||||
@@ -650,10 +651,13 @@
|
|||||||
"auth_user": "{= auth_user =} - Аутентифіковане ім'я користувача, вказане MTA",
|
"auth_user": "{= auth_user =} - Аутентифіковане ім'я користувача, вказане MTA",
|
||||||
"from_user": "{= from_user =} - З користувацької частини envelope, наприклад, для \"moo@mailcow.tld\" повертає \"moo\"",
|
"from_user": "{= from_user =} - З користувацької частини envelope, наприклад, для \"moo@mailcow.tld\" повертає \"moo\"",
|
||||||
"from_addr": "{= from_addr =} - З адресної частини envelope",
|
"from_addr": "{= from_addr =} - З адресної частини envelope",
|
||||||
"from_domain": "{= from_domain =} - З доменної частини envelope"
|
"from_domain": "{= from_domain =} - З доменної частини envelope",
|
||||||
|
"custom": "{= foo =} - Якщо поштова скринька має кастомний атрибут \"foo\" зі значенням \"bar\", то повертається \"bar\""
|
||||||
},
|
},
|
||||||
"domain_footer_html": "Нижній колонтитул HTML",
|
"domain_footer_html": "Нижній колонтитул HTML",
|
||||||
"domain_footer_plain": "ЗВИЧАЙНИЙ нижній колонтитул"
|
"domain_footer_plain": "ЗВИЧАЙНИЙ нижній колонтитул",
|
||||||
|
"custom_attributes": "Користувацькі атрибути",
|
||||||
|
"mbox_exclude": "Виключити поштові скриньки"
|
||||||
},
|
},
|
||||||
"fido2": {
|
"fido2": {
|
||||||
"confirm": "Підтвердити",
|
"confirm": "Підтвердити",
|
||||||
@@ -1248,7 +1252,9 @@
|
|||||||
"tls_policy_warning": "<strong>Попередження:</strong> якщо ви увімкнете примусове шифрування пошти, ви можете зіткнутися з втратою листів.<br>Повідомлення, які не відповідають політиці, будуть відкидатися з повідомленням поштовим сервером про серйозний збій.<br>Цей параметр застосовується до вашої основної адреси електронної пошти (логіну), усім особистим псевдонімам та псевдонімам доменів. Маються на увазі лише псевдоніми <b>з однією поштовою скринькою</b>, як одержувач.",
|
"tls_policy_warning": "<strong>Попередження:</strong> якщо ви увімкнете примусове шифрування пошти, ви можете зіткнутися з втратою листів.<br>Повідомлення, які не відповідають політиці, будуть відкидатися з повідомленням поштовим сервером про серйозний збій.<br>Цей параметр застосовується до вашої основної адреси електронної пошти (логіну), усім особистим псевдонімам та псевдонімам доменів. Маються на увазі лише псевдоніми <b>з однією поштовою скринькою</b>, як одержувач.",
|
||||||
"year": "рік",
|
"year": "рік",
|
||||||
"years": "років",
|
"years": "років",
|
||||||
"pushover_sound": "Звук"
|
"pushover_sound": "Звук",
|
||||||
|
"value": "Значення",
|
||||||
|
"attribute": "Атрибут"
|
||||||
},
|
},
|
||||||
"warning": {
|
"warning": {
|
||||||
"domain_added_sogo_failed": "Домен був доданий, але перезавантажити SOGo не вдалося, будь ласка, перевірте журнали сервера.",
|
"domain_added_sogo_failed": "Домен був доданий, але перезавантажити SOGo не вдалося, будь ласка, перевірте журнали сервера.",
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
<script type='text/javascript'>
|
<script type='text/javascript'>
|
||||||
var lang_user = {{ lang_user|raw }};
|
var lang_user = {{ lang_user|raw }};
|
||||||
|
var lang_admin = {{ lang_admin|raw }};
|
||||||
var lang_datatables = {{ lang_datatables|raw }};
|
var lang_datatables = {{ lang_datatables|raw }};
|
||||||
var csrf_token = '{{ csrf_token }}';
|
var csrf_token = '{{ csrf_token }}';
|
||||||
var pagination_size = Math.trunc('{{ pagination_size }}');
|
var pagination_size = Math.trunc('{{ pagination_size }}');
|
||||||
|
|||||||
@@ -168,7 +168,7 @@
|
|||||||
<label class="control-label col-sm-2">{{ lang.edit.ratelimit }}</label>
|
<label class="control-label col-sm-2">{{ lang.edit.ratelimit }}</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input name="rl_value" type="number" value="{{ rl.value }}" autocomplete="off" class="form-control placeholder="{{ lang.ratelimit.disabled }}">
|
<input name="rl_value" type="number" value="{{ rl.value }}" autocomplete="off" class="form-control" placeholder="{{ lang.ratelimit.disabled }}">
|
||||||
<select name="rl_frame" class="form-control">
|
<select name="rl_frame" class="form-control">
|
||||||
{% include 'mailbox/rl-frame.twig' %}
|
{% include 'mailbox/rl-frame.twig' %}
|
||||||
</select>
|
</select>
|
||||||
@@ -285,23 +285,41 @@
|
|||||||
{{ lang.edit.domain_footer_info_vars.from_user }}
|
{{ lang.edit.domain_footer_info_vars.from_user }}
|
||||||
{{ lang.edit.domain_footer_info_vars.from_name }}
|
{{ lang.edit.domain_footer_info_vars.from_name }}
|
||||||
{{ lang.edit.domain_footer_info_vars.from_addr }}
|
{{ lang.edit.domain_footer_info_vars.from_addr }}
|
||||||
{{ lang.edit.domain_footer_info_vars.from_domain }}</pre>
|
{{ lang.edit.domain_footer_info_vars.from_domain }}
|
||||||
|
{{ lang.edit.domain_footer_info_vars.custom }}</pre>
|
||||||
<form class="form-horizontal mt-4" data-id="domain_footer">
|
<form class="form-horizontal mt-4" data-id="domain_footer">
|
||||||
|
<div class="row mb-4">
|
||||||
|
<label class="control-label col-sm-2" for="mbox_exclude">{{ lang.edit.mbox_exclude }}</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<select data-live-search="true" data-width="100%" style="width:100%" id="editMboxExclude" name="mbox_exclude" size="10" multiple>
|
||||||
|
{% for mailbox in mailboxes %}
|
||||||
|
<option value="{{ mailbox }}" {% if mailbox in domain_footer.mbox_exclude %}selected{% endif %}>
|
||||||
|
{{ mailbox }}
|
||||||
|
</option>
|
||||||
|
{% endfor %}
|
||||||
|
{% for alias in aliases %}
|
||||||
|
<option data-subtext="Alias" value="{{ alias }}" {% if alias in domain_footer.mbox_exclude %}selected{% endif %}>
|
||||||
|
{{ alias }}
|
||||||
|
</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="row mb-2">
|
<div class="row mb-2">
|
||||||
<label class="control-label col-sm-2" for="domain_footer_html">{{ lang.edit.domain_footer_html }}:</label>
|
<label class="control-label col-sm-2" for="domain_footer_html">{{ lang.edit.domain_footer_html }}:</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<textarea spellcheck="false" autocorrect="off" autocapitalize="none" class="form-control" rows="10" id="domain_footer_html" name="footer_html">{{ domain_footer.html }}</textarea>
|
<textarea spellcheck="false" autocorrect="off" autocapitalize="none" class="form-control" rows="10" id="domain_footer_html" name="html">{{ domain_footer.html }}</textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-4">
|
<div class="row mb-4">
|
||||||
<label class="control-label col-sm-2" for="domain_footer_plain">{{ lang.edit.domain_footer_plain }}:</label>
|
<label class="control-label col-sm-2" for="domain_footer_plain">{{ lang.edit.domain_footer_plain }}:</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<textarea spellcheck="false" autocorrect="off" autocapitalize="none" class="form-control" rows="10" id="domain_footer_plain" name="footer_plain">{{ domain_footer.plain }}</textarea>
|
<textarea spellcheck="false" autocorrect="off" autocapitalize="none" class="form-control" rows="10" id="domain_footer_plain" name="plain">{{ domain_footer.plain }}</textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="offset-sm-2 col-sm-10">
|
<div class="offset-sm-2 col-sm-10">
|
||||||
<button class="btn btn-xs-lg d-block d-sm-inline btn-success" data-action="edit_selected" data-id="domain_footer" data-item="domain_footer" data-api-url='edit/domain-wide-footer' data-api-attr='{"domain":"{{ domain }}"}' href="#">{{ lang.edit.save }}</button>
|
<button class="btn btn-xs-lg d-block d-sm-inline btn-success" data-action="edit_selected" data-id="domain_footer" data-item="{{ domain }}" data-api-url='edit/domain/footer' data-api-attr='{}' href="#">{{ lang.edit.save }}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
<div id="mailbox-content" class="responsive-tabs">
|
<div id="mailbox-content" class="responsive-tabs">
|
||||||
<ul class="nav nav-tabs" role="tablist">
|
<ul class="nav nav-tabs" role="tablist">
|
||||||
<li role="presentation" class="nav-item"><button class="nav-link active" data-bs-toggle="tab" data-bs-target="#medit">{{ lang.edit.mailbox }}</button></li>
|
<li role="presentation" class="nav-item"><button class="nav-link active" data-bs-toggle="tab" data-bs-target="#medit">{{ lang.edit.mailbox }}</button></li>
|
||||||
|
<li role="presentation" class="nav-item"><button class="nav-link" data-bs-toggle="tab" data-bs-target="#mattr">{{ lang.edit.custom_attributes }}</button></li>
|
||||||
<li role="presentation" class="nav-item"><button class="nav-link" data-bs-toggle="tab" data-bs-target="#mpushover">{{ lang.edit.pushover }}</button></li>
|
<li role="presentation" class="nav-item"><button class="nav-link" data-bs-toggle="tab" data-bs-target="#mpushover">{{ lang.edit.pushover }}</button></li>
|
||||||
<li role="presentation" class="nav-item"><button class="nav-link" data-bs-toggle="tab" data-bs-target="#macl">{{ lang.edit.acl }}</button></li>
|
<li role="presentation" class="nav-item"><button class="nav-link" data-bs-toggle="tab" data-bs-target="#macl">{{ lang.edit.acl }}</button></li>
|
||||||
<li role="presentation" class="nav-item"><button class="nav-link" data-bs-toggle="tab" data-bs-target="#mrl">{{ lang.edit.ratelimit }}</button></li>
|
<li role="presentation" class="nav-item"><button class="nav-link" data-bs-toggle="tab" data-bs-target="#mrl">{{ lang.edit.ratelimit }}</button></li>
|
||||||
@@ -275,6 +276,37 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="mattr" class="tab-pane fade" role="tabpanel" aria-labelledby="mailbox-attr">
|
||||||
|
<div class="card mb-4">
|
||||||
|
<div class="card-header d-flex d-md-none fs-5">
|
||||||
|
<button class="btn flex-grow-1 text-start" data-bs-target="#collapse-tab-mattr" data-bs-toggle="collapse" aria-controls="collapse-tab-mattr">
|
||||||
|
{{ lang.edit.mailbox }} <span class="badge bg-info table-lines"></span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div id="collapse-tab-mattr" class="card-body collapse show" data-bs-parent="#mailbox-content">
|
||||||
|
<form class="form-inline" data-id="mbox_attr" role="form" method="post">
|
||||||
|
<table class="table table-condensed" style="white-space: nowrap;" id="mbox_attr_table">
|
||||||
|
<tr>
|
||||||
|
<th>{{ lang.user.attribute }}</th>
|
||||||
|
<th>{{ lang.user.value }}</th>
|
||||||
|
<th style="width:100px;"> </th>
|
||||||
|
</tr>
|
||||||
|
{% for key, val in result.custom_attributes %}
|
||||||
|
<tr>
|
||||||
|
<td><input class="input-sm input-xs-lg form-control" data-id="mbox_attr" type="text" name="attribute" required value="{{ key }}"></td>
|
||||||
|
<td><input class="input-sm input-xs-lg form-control" data-id="mbox_attr" type="text" name="value" required value="{{ val }}"></td>
|
||||||
|
<td><a href="#" role="button" class="btn btn-sm btn-xs-lg btn-secondary h-100 w-100" type="button">{{ lang.admin.remove_row }}</a></td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
<p><div class="btn-group">
|
||||||
|
<button class="btn btn-sm btn-xs-half d-block d-sm-inline btn-success" data-action="edit_selected" data-item="{{ mailbox }}" data-id="mbox_attr" data-api-url='edit/mailbox/custom-attribute' data-api-attr='{}' href="#"><i class="bi bi-check-lg"></i> {{ lang.admin.save }}</button>
|
||||||
|
<button class="btn btn-sm btn-xs-half d-block d-sm-inline btn-secondary" type="button" id="add_mbox_attr_row">{{ lang.admin.add_row }}</button>
|
||||||
|
</div></p>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div id="mpushover" class="tab-pane fade" role="tabpanel" aria-labelledby="mailbox-pushover">
|
<div id="mpushover" class="tab-pane fade" role="tabpanel" aria-labelledby="mailbox-pushover">
|
||||||
<div class="card mb-4">
|
<div class="card mb-4">
|
||||||
<div class="card-header d-flex d-md-none fs-5">
|
<div class="card-header d-flex d-md-none fs-5">
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
<input type="hidden" value="0" name="skipcrossduplicates">
|
<input type="hidden" value="0" name="skipcrossduplicates">
|
||||||
<input type="hidden" value="0" name="active">
|
<input type="hidden" value="0" name="active">
|
||||||
<input type="hidden" value="0" name="subscribeall">
|
<input type="hidden" value="0" name="subscribeall">
|
||||||
|
<input type="hidden" value="0" name="dry">
|
||||||
<div class="row mb-2">
|
<div class="row mb-2">
|
||||||
<label class="control-label col-sm-2" for="host1">{{ lang.edit.hostname }}</label>
|
<label class="control-label col-sm-2" for="host1">{{ lang.edit.hostname }}</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
@@ -95,7 +96,7 @@
|
|||||||
<div class="row mb-4">
|
<div class="row mb-4">
|
||||||
<label class="control-label col-sm-2" for="custom_params">{{ lang.add.custom_params }}</label>
|
<label class="control-label col-sm-2" for="custom_params">{{ lang.add.custom_params }}</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input type="text" class="form-control" name="custom_params" id="custom_params" value="{{ result.custom_params }}" placeholder="--dry --some-param=xy --other-param=yx">
|
<input type="text" class="form-control" name="custom_params" id="custom_params" value="{{ result.custom_params }}" placeholder="--some-param=xy --other-param=yx">
|
||||||
<small class="text-muted">{{ lang.add.custom_params_hint }}</small>
|
<small class="text-muted">{{ lang.add.custom_params_hint }}</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -141,6 +142,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row mb-2">
|
||||||
|
<div class="offset-sm-2 col-sm-10">
|
||||||
|
<div class="form-check">
|
||||||
|
<label><input type="checkbox" class="form-check-input" value="1" name="dry"{% if result.dry == '1' %} checked{% endif %}> {{ lang.add.dry }} (--dry)</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="row mb-4">
|
<div class="row mb-4">
|
||||||
<div class="offset-sm-2 col-sm-10">
|
<div class="offset-sm-2 col-sm-10">
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
|
|||||||
@@ -955,7 +955,7 @@
|
|||||||
<div class="row mb-4">
|
<div class="row mb-4">
|
||||||
<label class="control-label col-sm-2 text-sm-end" for="custom_params">{{ lang.add.custom_params }}</label>
|
<label class="control-label col-sm-2 text-sm-end" for="custom_params">{{ lang.add.custom_params }}</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input type="text" class="form-control" name="custom_params" placeholder="--dry --some-param=xy --other-param=yx">
|
<input type="text" class="form-control" name="custom_params" placeholder="--some-param=xy --other-param=yx">
|
||||||
<small class="text-muted">{{ lang.add.custom_params_hint }}</small>
|
<small class="text-muted">{{ lang.add.custom_params_hint }}</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -994,13 +994,20 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-4">
|
<div class="row mb-2">
|
||||||
<div class="offset-sm-2 col-sm-10">
|
<div class="offset-sm-2 col-sm-10">
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
<label><input type="checkbox" class="form-check-input" value="1" name="subscribeall" checked> {{ lang.add.subscribeall }} (--subscribeall)</label>
|
<label><input type="checkbox" class="form-check-input" value="1" name="subscribeall" checked> {{ lang.add.subscribeall }} (--subscribeall)</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row mb-4">
|
||||||
|
<div class="offset-sm-2 col-sm-10">
|
||||||
|
<div class="form-check">
|
||||||
|
<label><input type="checkbox" class="form-check-input" value="1" name="dry"> {{ lang.add.dry }} (--dry)</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="row mb-2">
|
<div class="row mb-2">
|
||||||
<div class="offset-sm-2 col-sm-10">
|
<div class="offset-sm-2 col-sm-10">
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
|
|||||||
@@ -167,6 +167,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row mb-2">
|
||||||
|
<div class="offset-sm-2 col-sm-10">
|
||||||
|
<div class="form-check">
|
||||||
|
<label><input type="checkbox" class="form-check-input" value="1" name="dry" checked> {{ lang.add.dry }} (--dry)</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="row mb-4">
|
<div class="row mb-4">
|
||||||
<div class="offset-sm-2 col-sm-10">
|
<div class="offset-sm-2 col-sm-10">
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
|
|||||||
+3
-3
@@ -77,7 +77,7 @@ services:
|
|||||||
- clamd
|
- clamd
|
||||||
|
|
||||||
rspamd-mailcow:
|
rspamd-mailcow:
|
||||||
image: mailcow/rspamd:1.92
|
image: mailcow/rspamd:1.94
|
||||||
stop_grace_period: 30s
|
stop_grace_period: 30s
|
||||||
depends_on:
|
depends_on:
|
||||||
- dovecot-mailcow
|
- dovecot-mailcow
|
||||||
@@ -218,7 +218,7 @@ services:
|
|||||||
- sogo
|
- sogo
|
||||||
|
|
||||||
dovecot-mailcow:
|
dovecot-mailcow:
|
||||||
image: mailcow/dovecot:1.25
|
image: mailcow/dovecot:1.26
|
||||||
depends_on:
|
depends_on:
|
||||||
- mysql-mailcow
|
- mysql-mailcow
|
||||||
dns:
|
dns:
|
||||||
@@ -526,7 +526,7 @@ services:
|
|||||||
- watchdog
|
- watchdog
|
||||||
|
|
||||||
dockerapi-mailcow:
|
dockerapi-mailcow:
|
||||||
image: mailcow/dockerapi:2.05
|
image: mailcow/dockerapi:2.06
|
||||||
security_opt:
|
security_opt:
|
||||||
- label=disable
|
- label=disable
|
||||||
restart: always
|
restart: always
|
||||||
|
|||||||
+6
-6
@@ -26,10 +26,10 @@ for bin in openssl curl docker git awk sha1sum grep cut; do
|
|||||||
done
|
done
|
||||||
|
|
||||||
if docker compose > /dev/null 2>&1; then
|
if docker compose > /dev/null 2>&1; then
|
||||||
if docker compose version --short | grep "^2." > /dev/null 2>&1; then
|
if docker compose version --short | grep -e "^2." -e "^v2." > /dev/null 2>&1; then
|
||||||
COMPOSE_VERSION=native
|
COMPOSE_VERSION=native
|
||||||
echo -e "\e[31mFound Docker Compose Plugin (native).\e[0m"
|
echo -e "\e[33mFound Docker Compose Plugin (native).\e[0m"
|
||||||
echo -e "\e[31mSetting the DOCKER_COMPOSE_VERSION Variable to native\e[0m"
|
echo -e "\e[33mSetting the DOCKER_COMPOSE_VERSION Variable to native\e[0m"
|
||||||
sleep 2
|
sleep 2
|
||||||
echo -e "\e[33mNotice: You´ll have to update this Compose Version via your Package Manager manually!\e[0m"
|
echo -e "\e[33mNotice: You´ll have to update this Compose Version via your Package Manager manually!\e[0m"
|
||||||
else
|
else
|
||||||
@@ -41,8 +41,8 @@ elif docker-compose > /dev/null 2>&1; then
|
|||||||
if ! [[ $(alias docker-compose 2> /dev/null) ]] ; then
|
if ! [[ $(alias docker-compose 2> /dev/null) ]] ; then
|
||||||
if docker-compose version --short | grep "^2." > /dev/null 2>&1; then
|
if docker-compose version --short | grep "^2." > /dev/null 2>&1; then
|
||||||
COMPOSE_VERSION=standalone
|
COMPOSE_VERSION=standalone
|
||||||
echo -e "\e[31mFound Docker Compose Standalone.\e[0m"
|
echo -e "\e[33mFound Docker Compose Standalone.\e[0m"
|
||||||
echo -e "\e[31mSetting the DOCKER_COMPOSE_VERSION Variable to standalone\e[0m"
|
echo -e "\e[33mSetting the DOCKER_COMPOSE_VERSION Variable to standalone\e[0m"
|
||||||
sleep 2
|
sleep 2
|
||||||
echo -e "\e[33mNotice: For an automatic update of docker-compose please use the update_compose.sh scripts located at the helper-scripts folder.\e[0m"
|
echo -e "\e[33mNotice: For an automatic update of docker-compose please use the update_compose.sh scripts located at the helper-scripts folder.\e[0m"
|
||||||
else
|
else
|
||||||
@@ -553,4 +553,4 @@ else
|
|||||||
echo -e "\e[33mCannot determine current git repository version...\e[0m"
|
echo -e "\e[33mCannot determine current git repository version...\e[0m"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
detect_bad_asn
|
detect_bad_asn
|
||||||
|
|||||||
Executable
+122
@@ -0,0 +1,122 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# Based on github.com/diafygi/acme-tiny, original copyright:
|
||||||
|
# Copyright Daniel Roesler, under MIT license, see LICENSE at github.com/diafygi/acme-tiny
|
||||||
|
import argparse, subprocess, json, os, sys, base64, binascii, time, hashlib, re, copy, textwrap, logging
|
||||||
|
try:
|
||||||
|
from urllib.request import urlopen, Request # Python 3
|
||||||
|
except ImportError: # pragma: no cover
|
||||||
|
from urllib2 import urlopen, Request # Python 2
|
||||||
|
|
||||||
|
DEFAULT_DIRECTORY_URL = "https://acme-v02.api.letsencrypt.org/directory"
|
||||||
|
|
||||||
|
LOGGER = logging.getLogger(__name__)
|
||||||
|
LOGGER.addHandler(logging.StreamHandler())
|
||||||
|
LOGGER.setLevel(logging.INFO)
|
||||||
|
|
||||||
|
def get_id(account_key, log=LOGGER, directory_url=DEFAULT_DIRECTORY_URL, contact=None):
|
||||||
|
directory, acct_headers, alg, jwk = None, None, None, None # global variables
|
||||||
|
|
||||||
|
# helper functions - base64 encode for jose spec
|
||||||
|
def _b64(b):
|
||||||
|
return base64.urlsafe_b64encode(b).decode('utf8').replace("=", "")
|
||||||
|
|
||||||
|
# helper function - run external commands
|
||||||
|
def _cmd(cmd_list, stdin=None, cmd_input=None, err_msg="Command Line Error"):
|
||||||
|
proc = subprocess.Popen(cmd_list, stdin=stdin, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
out, err = proc.communicate(cmd_input)
|
||||||
|
if proc.returncode != 0:
|
||||||
|
raise IOError("{0}\n{1}".format(err_msg, err))
|
||||||
|
return out
|
||||||
|
|
||||||
|
# helper function - make request and automatically parse json response
|
||||||
|
def _do_request(url, data=None, err_msg="Error", depth=0):
|
||||||
|
try:
|
||||||
|
resp = urlopen(Request(url, data=data, headers={"Content-Type": "application/jose+json", "User-Agent": "acme-tiny"}))
|
||||||
|
resp_data, code, headers = resp.read().decode("utf8"), resp.getcode(), resp.headers
|
||||||
|
except IOError as e:
|
||||||
|
resp_data = e.read().decode("utf8") if hasattr(e, "read") else str(e)
|
||||||
|
code, headers = getattr(e, "code", None), {}
|
||||||
|
try:
|
||||||
|
resp_data = json.loads(resp_data) # try to parse json results
|
||||||
|
except ValueError:
|
||||||
|
pass # ignore json parsing errors
|
||||||
|
if depth < 100 and code == 400 and resp_data['type'] == "urn:ietf:params:acme:error:badNonce":
|
||||||
|
raise IndexError(resp_data) # allow 100 retrys for bad nonces
|
||||||
|
if code not in [200, 201, 204]:
|
||||||
|
raise ValueError("{0}:\nUrl: {1}\nData: {2}\nResponse Code: {3}\nResponse: {4}".format(err_msg, url, data, code, resp_data))
|
||||||
|
return resp_data, code, headers
|
||||||
|
|
||||||
|
# helper function - make signed requests
|
||||||
|
def _send_signed_request(url, payload, err_msg, depth=0):
|
||||||
|
payload64 = "" if payload is None else _b64(json.dumps(payload).encode('utf8'))
|
||||||
|
new_nonce = _do_request(directory['newNonce'])[2]['Replay-Nonce']
|
||||||
|
protected = {"url": url, "alg": alg, "nonce": new_nonce}
|
||||||
|
protected.update({"jwk": jwk} if acct_headers is None else {"kid": acct_headers['Location']})
|
||||||
|
protected64 = _b64(json.dumps(protected).encode('utf8'))
|
||||||
|
protected_input = "{0}.{1}".format(protected64, payload64).encode('utf8')
|
||||||
|
out = _cmd(["openssl", "dgst", "-sha256", "-sign", account_key], stdin=subprocess.PIPE, cmd_input=protected_input, err_msg="OpenSSL Error")
|
||||||
|
data = json.dumps({"protected": protected64, "payload": payload64, "signature": _b64(out)})
|
||||||
|
try:
|
||||||
|
return _do_request(url, data=data.encode('utf8'), err_msg=err_msg, depth=depth)
|
||||||
|
except IndexError: # retry bad nonces (they raise IndexError)
|
||||||
|
return _send_signed_request(url, payload, err_msg, depth=(depth + 1))
|
||||||
|
|
||||||
|
# helper function - poll until complete
|
||||||
|
def _poll_until_not(url, pending_statuses, err_msg):
|
||||||
|
result, t0 = None, time.time()
|
||||||
|
while result is None or result['status'] in pending_statuses:
|
||||||
|
assert (time.time() - t0 < 3600), "Polling timeout" # 1 hour timeout
|
||||||
|
time.sleep(0 if result is None else 2)
|
||||||
|
result, _, _ = _send_signed_request(url, None, err_msg)
|
||||||
|
return result
|
||||||
|
|
||||||
|
# parse account key to get public key
|
||||||
|
log.info("Parsing account key...")
|
||||||
|
out = _cmd(["openssl", "rsa", "-in", account_key, "-noout", "-text"], err_msg="OpenSSL Error")
|
||||||
|
pub_pattern = r"modulus:[\s]+?00:([a-f0-9\:\s]+?)\npublicExponent: ([0-9]+)"
|
||||||
|
pub_hex, pub_exp = re.search(pub_pattern, out.decode('utf8'), re.MULTILINE|re.DOTALL).groups()
|
||||||
|
pub_exp = "{0:x}".format(int(pub_exp))
|
||||||
|
pub_exp = "0{0}".format(pub_exp) if len(pub_exp) % 2 else pub_exp
|
||||||
|
alg, jwk = "RS256", {
|
||||||
|
"e": _b64(binascii.unhexlify(pub_exp.encode("utf-8"))),
|
||||||
|
"kty": "RSA",
|
||||||
|
"n": _b64(binascii.unhexlify(re.sub(r"(\s|:)", "", pub_hex).encode("utf-8"))),
|
||||||
|
}
|
||||||
|
accountkey_json = json.dumps(jwk, sort_keys=True, separators=(',', ':'))
|
||||||
|
thumbprint = _b64(hashlib.sha256(accountkey_json.encode('utf8')).digest())
|
||||||
|
|
||||||
|
# get the ACME directory of urls
|
||||||
|
log.info("Getting directory...")
|
||||||
|
directory, _, _ = _do_request(directory_url, err_msg="Error getting directory")
|
||||||
|
log.info("Directory found!")
|
||||||
|
|
||||||
|
# create account and get the global key identifier
|
||||||
|
log.info("Registering account...")
|
||||||
|
reg_payload = {"termsOfServiceAgreed": True} if contact is None else {"termsOfServiceAgreed": True, "contact": contact}
|
||||||
|
account, code, acct_headers = _send_signed_request(directory['newAccount'], reg_payload, "Error registering")
|
||||||
|
log.info("Registered!" if code == 201 else "Already registered!")
|
||||||
|
|
||||||
|
return acct_headers['Location']
|
||||||
|
|
||||||
|
def main(argv=None):
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||||
|
description=textwrap.dedent("""\
|
||||||
|
Generate a CAA record for Mailcow.
|
||||||
|
|
||||||
|
Example Usage: python mailcow_gencaa.py --account-key data/assets/ssl/acme/account.pem
|
||||||
|
""")
|
||||||
|
)
|
||||||
|
parser.add_argument("--account-key", required=True, help="path to your Let's Encrypt account private key")
|
||||||
|
parser.add_argument("--quiet", action="store_const", const=logging.ERROR, help="suppress output except for errors")
|
||||||
|
parser.add_argument("--directory-url", default=DEFAULT_DIRECTORY_URL, help="certificate authority directory url, default is Let's Encrypt")
|
||||||
|
parser.add_argument("--contact", metavar="CONTACT", default=None, nargs="*", help="Contact details (e.g. mailto:aaa@bbb.com) for your account-key")
|
||||||
|
|
||||||
|
args = parser.parse_args(argv)
|
||||||
|
LOGGER.setLevel(args.quiet or LOGGER.level)
|
||||||
|
id = get_id(args.account_key, log=LOGGER, directory_url=args.directory_url, contact=args.contact)
|
||||||
|
print("Use this as your CAA record:")
|
||||||
|
print('issue 128 "letsencrypt.org;accounturi={}"'.format(id))
|
||||||
|
|
||||||
|
if __name__ == "__main__": # pragma: no cover
|
||||||
|
main(sys.argv[1:])
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# renovate: datasource=github-releases depName=nextcloud/server versioning=semver extractVersion=^v(?<version>.*)$
|
# renovate: datasource=github-releases depName=nextcloud/server versioning=semver extractVersion=^v(?<version>.*)$
|
||||||
NEXTCLOUD_VERSION=27.1.2
|
NEXTCLOUD_VERSION=27.1.4
|
||||||
|
|
||||||
echo -ne "Checking prerequisites..."
|
echo -ne "Checking prerequisites..."
|
||||||
sleep 1
|
sleep 1
|
||||||
@@ -106,6 +106,10 @@ elif [[ ${NC_UPDATE} == "y" ]]; then
|
|||||||
exit 1
|
exit 1
|
||||||
else
|
else
|
||||||
docker exec -it -u www-data $(docker ps -f name=php-fpm-mailcow -q) bash -c "php /web/nextcloud/updater/updater.phar"
|
docker exec -it -u www-data $(docker ps -f name=php-fpm-mailcow -q) bash -c "php /web/nextcloud/updater/updater.phar"
|
||||||
|
NC_SUBD=$(docker exec -i -u www-data $(docker ps -f name=php-fpm-mailcow -q) /web/nextcloud/occ config:system:get overwritehost)
|
||||||
|
mv ./data/conf/nginx/nextcloud.conf ./data/conf/nginx/nextcloud.conf-$(date +%s).bak
|
||||||
|
cp ./data/assets/nextcloud/nextcloud.conf ./data/conf/nginx/
|
||||||
|
sed -i "s/NC_SUBD/${NC_SUBD}/g" ./data/conf/nginx/nextcloud.conf
|
||||||
fi
|
fi
|
||||||
|
|
||||||
elif [[ ${NC_INSTALL} == "y" ]]; then
|
elif [[ ${NC_INSTALL} == "y" ]]; then
|
||||||
|
|||||||
@@ -32,51 +32,44 @@ prefetch_images() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
docker_garbage() {
|
docker_garbage() {
|
||||||
|
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
IMGS_TO_DELETE=()
|
IMGS_TO_DELETE=()
|
||||||
for container in $(grep -oP "image: \Kmailcow.+" "${SCRIPT_DIR}/docker-compose.yml"); do
|
|
||||||
REPOSITORY=${container/:*}
|
|
||||||
TAG=${container/*:}
|
|
||||||
V_MAIN=${container/*.}
|
|
||||||
V_SUB=${container/*.}
|
|
||||||
EXISTING_TAGS=$(docker images | grep ${REPOSITORY} | awk '{ print $2 }')
|
|
||||||
for existing_tag in ${EXISTING_TAGS[@]}; do
|
|
||||||
V_MAIN_EXISTING=${existing_tag/*.}
|
|
||||||
V_SUB_EXISTING=${existing_tag/*.}
|
|
||||||
# Not an integer
|
|
||||||
[[ ! $V_MAIN_EXISTING =~ ^[0-9]+$ ]] && continue
|
|
||||||
[[ ! $V_SUB_EXISTING =~ ^[0-9]+$ ]] && continue
|
|
||||||
|
|
||||||
if [[ $V_MAIN_EXISTING == "latest" ]]; then
|
declare -A IMAGES_INFO
|
||||||
echo "Found deprecated label \"latest\" for repository $REPOSITORY, it should be deleted."
|
COMPOSE_IMAGES=($(grep -oP "image: \Kmailcow.+" "${SCRIPT_DIR}/docker-compose.yml"))
|
||||||
IMGS_TO_DELETE+=($REPOSITORY:$existing_tag)
|
|
||||||
elif [[ $V_MAIN_EXISTING -lt $V_MAIN ]]; then
|
for existing_image in $(docker images --format "{{.ID}}:{{.Repository}}:{{.Tag}}" | grep 'mailcow/'); do
|
||||||
echo "Found tag $existing_tag for $REPOSITORY, which is older than the current tag $TAG and should be deleted."
|
ID=$(echo $existing_image | cut -d ':' -f 1)
|
||||||
IMGS_TO_DELETE+=($REPOSITORY:$existing_tag)
|
REPOSITORY=$(echo $existing_image | cut -d ':' -f 2)
|
||||||
elif [[ $V_SUB_EXISTING -lt $V_SUB ]]; then
|
TAG=$(echo $existing_image | cut -d ':' -f 3)
|
||||||
echo "Found tag $existing_tag for $REPOSITORY, which is older than the current tag $TAG and should be deleted."
|
|
||||||
IMGS_TO_DELETE+=($REPOSITORY:$existing_tag)
|
if [[ " ${COMPOSE_IMAGES[@]} " =~ " ${REPOSITORY}:${TAG} " ]]; then
|
||||||
|
continue
|
||||||
|
else
|
||||||
|
IMGS_TO_DELETE+=("$ID")
|
||||||
|
IMAGES_INFO["$ID"]="$REPOSITORY:$TAG"
|
||||||
fi
|
fi
|
||||||
done
|
|
||||||
done
|
done
|
||||||
|
|
||||||
if [[ ! -z ${IMGS_TO_DELETE[*]} ]]; then
|
if [[ ! -z ${IMGS_TO_DELETE[*]} ]]; then
|
||||||
echo "Run the following command to delete unused image tags:"
|
echo "The following unused mailcow images were found:"
|
||||||
echo
|
for id in "${IMGS_TO_DELETE[@]}"; do
|
||||||
echo " docker rmi ${IMGS_TO_DELETE[*]}"
|
echo " ${IMAGES_INFO[$id]} ($id)"
|
||||||
echo
|
done
|
||||||
if [ ! $FORCE ]; then
|
|
||||||
read -r -p "Do you want to delete old image tags right now? [y/N] " response
|
if [ ! $FORCE ]; then
|
||||||
if [[ "$response" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
|
read -r -p "Do you want to delete them to free up some space? [y/N] " response
|
||||||
docker rmi ${IMGS_TO_DELETE[*]}
|
if [[ "$response" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
|
||||||
|
docker rmi ${IMGS_TO_DELETE[*]}
|
||||||
|
else
|
||||||
|
echo "OK, skipped."
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
echo "OK, skipped."
|
echo "Running in forced mode! Force removing old mailcow images..."
|
||||||
|
docker rmi ${IMGS_TO_DELETE[*]}
|
||||||
fi
|
fi
|
||||||
else
|
echo -e "\e[32mFurther cleanup...\e[0m"
|
||||||
echo "Running image removal without extra confirmation due to force mode."
|
echo "If you want to cleanup further garbage collected by Docker, please make sure all containers are up and running before cleaning your system by executing \"docker system prune\""
|
||||||
docker rmi ${IMGS_TO_DELETE[*]}
|
|
||||||
fi
|
|
||||||
echo -e "\e[32mFurther cleanup...\e[0m"
|
|
||||||
echo "If you want to cleanup further garbage collected by Docker, please make sure all containers are up and running before cleaning your system by executing \"docker system prune\""
|
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,11 +171,11 @@ remove_obsolete_nginx_ports() {
|
|||||||
detect_docker_compose_command(){
|
detect_docker_compose_command(){
|
||||||
if ! [[ "${DOCKER_COMPOSE_VERSION}" =~ ^(native|standalone)$ ]]; then
|
if ! [[ "${DOCKER_COMPOSE_VERSION}" =~ ^(native|standalone)$ ]]; then
|
||||||
if docker compose > /dev/null 2>&1; then
|
if docker compose > /dev/null 2>&1; then
|
||||||
if docker compose version --short | grep "2." > /dev/null 2>&1; then
|
if docker compose version --short | grep -e "^2." -e "^v2." > /dev/null 2>&1; then
|
||||||
DOCKER_COMPOSE_VERSION=native
|
DOCKER_COMPOSE_VERSION=native
|
||||||
COMPOSE_COMMAND="docker compose"
|
COMPOSE_COMMAND="docker compose"
|
||||||
echo -e "\e[31mFound Docker Compose Plugin (native).\e[0m"
|
echo -e "\e[33mFound Docker Compose Plugin (native).\e[0m"
|
||||||
echo -e "\e[31mSetting the DOCKER_COMPOSE_VERSION Variable to native\e[0m"
|
echo -e "\e[33mSetting the DOCKER_COMPOSE_VERSION Variable to native\e[0m"
|
||||||
sed -i 's/^DOCKER_COMPOSE_VERSION=.*/DOCKER_COMPOSE_VERSION=native/' $SCRIPT_DIR/mailcow.conf
|
sed -i 's/^DOCKER_COMPOSE_VERSION=.*/DOCKER_COMPOSE_VERSION=native/' $SCRIPT_DIR/mailcow.conf
|
||||||
sleep 2
|
sleep 2
|
||||||
echo -e "\e[33mNotice: You'll have to update this Compose Version via your Package Manager manually!\e[0m"
|
echo -e "\e[33mNotice: You'll have to update this Compose Version via your Package Manager manually!\e[0m"
|
||||||
@@ -196,8 +189,8 @@ if ! [[ "${DOCKER_COMPOSE_VERSION}" =~ ^(native|standalone)$ ]]; then
|
|||||||
if docker-compose version --short | grep "^2." > /dev/null 2>&1; then
|
if docker-compose version --short | grep "^2." > /dev/null 2>&1; then
|
||||||
DOCKER_COMPOSE_VERSION=standalone
|
DOCKER_COMPOSE_VERSION=standalone
|
||||||
COMPOSE_COMMAND="docker-compose"
|
COMPOSE_COMMAND="docker-compose"
|
||||||
echo -e "\e[31mFound Docker Compose Standalone.\e[0m"
|
echo -e "\e[33mFound Docker Compose Standalone.\e[0m"
|
||||||
echo -e "\e[31mSetting the DOCKER_COMPOSE_VERSION Variable to standalone\e[0m"
|
echo -e "\e[33mSetting the DOCKER_COMPOSE_VERSION Variable to standalone\e[0m"
|
||||||
sed -i 's/^DOCKER_COMPOSE_VERSION=.*/DOCKER_COMPOSE_VERSION=standalone/' $SCRIPT_DIR/mailcow.conf
|
sed -i 's/^DOCKER_COMPOSE_VERSION=.*/DOCKER_COMPOSE_VERSION=standalone/' $SCRIPT_DIR/mailcow.conf
|
||||||
sleep 2
|
sleep 2
|
||||||
echo -e "\e[33mNotice: For an automatic update of docker-compose please use the update_compose.sh scripts located at the helper-scripts folder.\e[0m"
|
echo -e "\e[33mNotice: For an automatic update of docker-compose please use the update_compose.sh scripts located at the helper-scripts folder.\e[0m"
|
||||||
@@ -893,45 +886,54 @@ done
|
|||||||
# git remote set-url origin https://github.com/mailcow/mailcow-dockerized
|
# git remote set-url origin https://github.com/mailcow/mailcow-dockerized
|
||||||
|
|
||||||
DEFAULT_REPO=https://github.com/mailcow/mailcow-dockerized
|
DEFAULT_REPO=https://github.com/mailcow/mailcow-dockerized
|
||||||
CURRENT_REPO=$(git remote get-url origin)
|
CURRENT_REPO=$(git config --get remote.origin.url)
|
||||||
if [ "$CURRENT_REPO" != "$DEFAULT_REPO" ]; then
|
if [ "$CURRENT_REPO" != "$DEFAULT_REPO" ]; then
|
||||||
echo "The Repository currently used is not the default Mailcow Repository."
|
echo "The Repository currently used is not the default Mailcow Repository."
|
||||||
echo "Currently Repository: $CURRENT_REPO"
|
echo "Currently Repository: $CURRENT_REPO"
|
||||||
echo "Default Repository: $DEFAULT_REPO"
|
echo "Default Repository: $DEFAULT_REPO"
|
||||||
read -r -p "Should it be changed back to default? [y/N] " repo_response
|
if [ ! $FORCE ]; then
|
||||||
if [[ "$repo_response" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
|
read -r -p "Should it be changed back to default? [y/N] " repo_response
|
||||||
git remote set-url origin $DEFAULT_REPO
|
if [[ "$repo_response" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
|
||||||
|
git remote set-url origin $DEFAULT_REPO
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "Running in forced mode... setting Repo to default!"
|
||||||
|
git remote set-url origin $DEFAULT_REPO
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo -e "\e[32mCommitting current status...\e[0m"
|
if [ ! $DEV ]; then
|
||||||
[[ -z "$(git config user.name)" ]] && git config user.name moo
|
echo -e "\e[32mCommitting current status...\e[0m"
|
||||||
[[ -z "$(git config user.email)" ]] && git config user.email moo@cow.moo
|
[[ -z "$(git config user.name)" ]] && git config user.name moo
|
||||||
[[ ! -z $(git ls-files data/conf/rspamd/override.d/worker-controller-password.inc) ]] && git rm data/conf/rspamd/override.d/worker-controller-password.inc
|
[[ -z "$(git config user.email)" ]] && git config user.email moo@cow.moo
|
||||||
git add -u
|
[[ ! -z $(git ls-files data/conf/rspamd/override.d/worker-controller-password.inc) ]] && git rm data/conf/rspamd/override.d/worker-controller-password.inc
|
||||||
git commit -am "Before update on ${DATE}" > /dev/null
|
git add -u
|
||||||
echo -e "\e[32mFetching updated code from remote...\e[0m"
|
git commit -am "Before update on ${DATE}" > /dev/null
|
||||||
git fetch origin #${BRANCH}
|
echo -e "\e[32mFetching updated code from remote...\e[0m"
|
||||||
echo -e "\e[32mMerging local with remote code (recursive, strategy: \"${MERGE_STRATEGY:-theirs}\", options: \"patience\"...\e[0m"
|
git fetch origin #${BRANCH}
|
||||||
git config merge.defaultToUpstream true
|
echo -e "\e[32mMerging local with remote code (recursive, strategy: \"${MERGE_STRATEGY:-theirs}\", options: \"patience\"...\e[0m"
|
||||||
git merge -X${MERGE_STRATEGY:-theirs} -Xpatience -m "After update on ${DATE}"
|
git config merge.defaultToUpstream true
|
||||||
# Need to use a variable to not pass return codes of if checks
|
git merge -X${MERGE_STRATEGY:-theirs} -Xpatience -m "After update on ${DATE}"
|
||||||
MERGE_RETURN=$?
|
# Need to use a variable to not pass return codes of if checks
|
||||||
if [[ ${MERGE_RETURN} == 128 ]]; then
|
MERGE_RETURN=$?
|
||||||
echo -e "\e[31m\nOh no, what happened?\n=> You most likely added files to your local mailcow instance that were now added to the official mailcow repository. Please move them to another location before updating mailcow.\e[0m"
|
if [[ ${MERGE_RETURN} == 128 ]]; then
|
||||||
exit 1
|
echo -e "\e[31m\nOh no, what happened?\n=> You most likely added files to your local mailcow instance that were now added to the official mailcow repository. Please move them to another location before updating mailcow.\e[0m"
|
||||||
elif [[ ${MERGE_RETURN} == 1 ]]; then
|
exit 1
|
||||||
echo -e "\e[93mPotenial conflict, trying to fix...\e[0m"
|
elif [[ ${MERGE_RETURN} == 1 ]]; then
|
||||||
git status --porcelain | grep -E "UD|DU" | awk '{print $2}' | xargs rm -v
|
echo -e "\e[93mPotenial conflict, trying to fix...\e[0m"
|
||||||
git add -A
|
git status --porcelain | grep -E "UD|DU" | awk '{print $2}' | xargs rm -v
|
||||||
git commit -m "After update on ${DATE}" > /dev/null
|
git add -A
|
||||||
git checkout .
|
git commit -m "After update on ${DATE}" > /dev/null
|
||||||
echo -e "\e[32mRemoved and recreated files if necessary.\e[0m"
|
git checkout .
|
||||||
elif [[ ${MERGE_RETURN} != 0 ]]; then
|
echo -e "\e[32mRemoved and recreated files if necessary.\e[0m"
|
||||||
echo -e "\e[31m\nOh no, something went wrong. Please check the error message above.\e[0m"
|
elif [[ ${MERGE_RETURN} != 0 ]]; then
|
||||||
echo
|
echo -e "\e[31m\nOh no, something went wrong. Please check the error message above.\e[0m"
|
||||||
echo "Run $COMPOSE_COMMAND up -d to restart your stack without updates or try again after fixing the mentioned errors."
|
echo
|
||||||
exit 1
|
echo "Run $COMPOSE_COMMAND up -d to restart your stack without updates or try again after fixing the mentioned errors."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
elif [ $DEV ]; then
|
||||||
|
echo -e "\e[33mDEVELOPER MODE: Not creating a git diff and commiting it to prevent development stuff within a backup diff...\e[0m"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo -e "\e[32mFetching new images, if any...\e[0m"
|
echo -e "\e[32mFetching new images, if any...\e[0m"
|
||||||
|
|||||||
Reference in New Issue
Block a user