mirror of
https://github.com/mailcow/mailcow-dockerized.git
synced 2026-06-18 20:40:38 +00:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7996cfbb06 | |||
| f924b7f0e3 | |||
| 9610a79c3e | |||
| 886dbcc419 | |||
| dc15994d40 |
@@ -69,6 +69,8 @@ RUN addgroup -g 5000 vmail \
|
|||||||
perl-par-packer \
|
perl-par-packer \
|
||||||
perl-parse-recdescent \
|
perl-parse-recdescent \
|
||||||
perl-lockfile-simple \
|
perl-lockfile-simple \
|
||||||
|
perl-parallel-forkmanager \
|
||||||
|
perl-redis \
|
||||||
libproc2 \
|
libproc2 \
|
||||||
perl-readonly \
|
perl-readonly \
|
||||||
perl-regexp-common \
|
perl-regexp-common \
|
||||||
|
|||||||
@@ -2,21 +2,15 @@
|
|||||||
|
|
||||||
use DBI;
|
use DBI;
|
||||||
use LockFile::Simple qw(lock trylock unlock);
|
use LockFile::Simple qw(lock trylock unlock);
|
||||||
use Proc::ProcessTable;
|
|
||||||
use Data::Dumper qw(Dumper);
|
use Data::Dumper qw(Dumper);
|
||||||
use IPC::Run 'run';
|
use IPC::Run 'run';
|
||||||
use File::Temp;
|
use File::Temp;
|
||||||
use Try::Tiny;
|
use Try::Tiny;
|
||||||
|
use Parallel::ForkManager;
|
||||||
|
use Redis;
|
||||||
use sigtrap 'handler' => \&sig_handler, qw(INT TERM KILL QUIT);
|
use sigtrap 'handler' => \&sig_handler, qw(INT TERM KILL QUIT);
|
||||||
|
|
||||||
sub trim { my $s = shift; $s =~ s/^\s+|\s+$//g; return $s };
|
sub trim { my $s = shift; $s =~ s/^\s+|\s+$//g; return $s };
|
||||||
my $t = Proc::ProcessTable->new;
|
|
||||||
my $imapsync_running = grep { $_->{cmndline} =~ /imapsync\s/i } @{$t->table};
|
|
||||||
if ($imapsync_running ge 1)
|
|
||||||
{
|
|
||||||
print "imapsync is active, exiting...";
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub qqw($) {
|
sub qqw($) {
|
||||||
my @params = ();
|
my @params = ();
|
||||||
@@ -35,26 +29,162 @@ sub qqw($) {
|
|||||||
return @params;
|
return @params;
|
||||||
}
|
}
|
||||||
|
|
||||||
$run_dir="/tmp";
|
our $pm;
|
||||||
$dsn = 'DBI:mysql:database=' . $ENV{'DBNAME'} . ';mysql_socket=/var/run/mysqld/mysqld.sock';
|
|
||||||
$lock_file = $run_dir . "/imapsync_busy";
|
sub sig_handler {
|
||||||
$lockmgr = LockFile::Simple->make(-autoclean => 1, -max => 1);
|
if (defined $pm) {
|
||||||
|
foreach my $child_pid (keys %{ $pm->{processes} }) {
|
||||||
|
kill 'TERM', $child_pid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
die "sig_handler received signal, preparing to exit...\n";
|
||||||
|
};
|
||||||
|
|
||||||
|
sub run_one_job {
|
||||||
|
my ($dbh, $row_ref, $master_user, $master_pass) = @_;
|
||||||
|
|
||||||
|
my $id = $row_ref->[0];
|
||||||
|
my $user1 = $row_ref->[1];
|
||||||
|
my $user2 = $row_ref->[2];
|
||||||
|
my $host1 = $row_ref->[3];
|
||||||
|
my $authmech1 = $row_ref->[4];
|
||||||
|
my $password1 = $row_ref->[5];
|
||||||
|
my $exclude = $row_ref->[6];
|
||||||
|
my $port1 = $row_ref->[7];
|
||||||
|
my $enc1 = $row_ref->[8];
|
||||||
|
my $delete2duplicates = $row_ref->[9];
|
||||||
|
my $maxage = $row_ref->[10];
|
||||||
|
my $subfolder2 = $row_ref->[11];
|
||||||
|
my $delete1 = $row_ref->[12];
|
||||||
|
my $delete2 = $row_ref->[13];
|
||||||
|
my $automap = $row_ref->[14];
|
||||||
|
my $skipcrossduplicates = $row_ref->[15];
|
||||||
|
my $maxbytespersecond = $row_ref->[16];
|
||||||
|
my $custom_params = $row_ref->[17];
|
||||||
|
my $subscribeall = $row_ref->[18];
|
||||||
|
my $timeout1 = $row_ref->[19];
|
||||||
|
my $timeout2 = $row_ref->[20];
|
||||||
|
my $dry = $row_ref->[21];
|
||||||
|
|
||||||
|
if ($enc1 eq "TLS") { $enc1 = "--tls1"; } elsif ($enc1 eq "SSL") { $enc1 = "--ssl1"; } else { undef $enc1; }
|
||||||
|
|
||||||
|
my $template = "/tmp/imapsync.XXXXXXX";
|
||||||
|
my $passfile1 = File::Temp->new(TEMPLATE => $template);
|
||||||
|
my $passfile2 = File::Temp->new(TEMPLATE => $template);
|
||||||
|
|
||||||
|
binmode( $passfile1, ":utf8" );
|
||||||
|
|
||||||
|
print $passfile1 "$password1\n";
|
||||||
|
print $passfile2 trim($master_pass) . "\n";
|
||||||
|
|
||||||
|
my $effective_bps = $maxbytespersecond;
|
||||||
|
if ($effective_bps eq "0" && $global_max_bps > 0) {
|
||||||
|
$effective_bps = $global_max_bps;
|
||||||
|
}
|
||||||
|
|
||||||
|
my @custom_params_a = qqw($custom_params);
|
||||||
|
my $custom_params_ref = \@custom_params_a;
|
||||||
|
|
||||||
|
my $generated_cmds = [ "/usr/local/bin/imapsync",
|
||||||
|
"--tmpdir", "/tmp",
|
||||||
|
"--nofoldersizes",
|
||||||
|
"--addheader",
|
||||||
|
($timeout1 le "0" ? () : ('--timeout1', $timeout1)),
|
||||||
|
($timeout2 le "0" ? () : ('--timeout2', $timeout2)),
|
||||||
|
($exclude eq "" ? () : ("--exclude", $exclude)),
|
||||||
|
($subfolder2 eq "" ? () : ('--subfolder2', $subfolder2)),
|
||||||
|
($maxage eq "0" ? () : ('--maxage', $maxage)),
|
||||||
|
($effective_bps eq "0" ? () : ('--maxbytespersecond', $effective_bps)),
|
||||||
|
($delete2duplicates ne "1" ? () : ('--delete2duplicates')),
|
||||||
|
($subscribeall ne "1" ? () : ('--subscribeall')),
|
||||||
|
($delete1 ne "1" ? () : ('--delete')),
|
||||||
|
($delete2 ne "1" ? () : ('--delete2')),
|
||||||
|
($automap ne "1" ? () : ('--automap')),
|
||||||
|
($skipcrossduplicates ne "1" ? () : ('--skipcrossduplicates')),
|
||||||
|
(!defined($enc1) ? () : ($enc1)),
|
||||||
|
"--host1", $host1,
|
||||||
|
"--user1", $user1,
|
||||||
|
"--passfile1", $passfile1->filename,
|
||||||
|
"--port1", $port1,
|
||||||
|
"--host2", "localhost",
|
||||||
|
"--user2", $user2 . '*' . trim($master_user),
|
||||||
|
"--passfile2", $passfile2->filename,
|
||||||
|
($dry eq "1" ? ('--dry') : ()),
|
||||||
|
'--no-modulesversion',
|
||||||
|
'--noreleasecheck'];
|
||||||
|
|
||||||
|
try {
|
||||||
|
my $is_running = $dbh->prepare("UPDATE imapsync SET is_running = 1, success = NULL, exit_status = NULL WHERE id = ?");
|
||||||
|
$is_running->bind_param( 1, $id );
|
||||||
|
$is_running->execute();
|
||||||
|
|
||||||
|
run [@$generated_cmds, @$custom_params_ref], '&>', \my $stdout;
|
||||||
|
|
||||||
|
my ($exit_code, $exit_status) = ($stdout =~ m/Exiting\swith\sreturn\svalue\s(\d+)\s\(([^:)]+)/);
|
||||||
|
|
||||||
|
my $success = 0;
|
||||||
|
if (defined $exit_code && $exit_code == 0) {
|
||||||
|
$success = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $update = $dbh->prepare("UPDATE imapsync SET returned_text = ?, success = ?, exit_status = ? WHERE id = ?");
|
||||||
|
$update->bind_param( 1, $stdout );
|
||||||
|
$update->bind_param( 2, $success );
|
||||||
|
$update->bind_param( 3, $exit_status );
|
||||||
|
$update->bind_param( 4, $id );
|
||||||
|
$update->execute();
|
||||||
|
} catch {
|
||||||
|
my $update = $dbh->prepare("UPDATE imapsync SET returned_text = 'Could not start or finish imapsync', success = 0 WHERE id = ?");
|
||||||
|
$update->bind_param( 1, $id );
|
||||||
|
$update->execute();
|
||||||
|
} finally {
|
||||||
|
my $update = $dbh->prepare("UPDATE imapsync SET last_run = NOW(), is_running = 0 WHERE id = ?");
|
||||||
|
$update->bind_param( 1, $id );
|
||||||
|
$update->execute();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
my $run_dir = "/tmp";
|
||||||
|
my $dsn = 'DBI:mysql:database=' . $ENV{'DBNAME'} . ';mysql_socket=/var/run/mysqld/mysqld.sock';
|
||||||
|
my $lock_file = $run_dir . "/imapsync_busy";
|
||||||
|
my $lockmgr = LockFile::Simple->make(-autoclean => 1, -max => 1);
|
||||||
$lockmgr->lock($lock_file) || die "can't lock ${lock_file}";
|
$lockmgr->lock($lock_file) || die "can't lock ${lock_file}";
|
||||||
$dbh = DBI->connect($dsn, $ENV{'DBUSER'}, $ENV{'DBPASS'}, {
|
|
||||||
|
my $max_parallel = 1;
|
||||||
|
our $global_max_bps = 0;
|
||||||
|
try {
|
||||||
|
my $redis = Redis->new(
|
||||||
|
server => 'redis-mailcow:6379',
|
||||||
|
password => $ENV{'REDISPASS'},
|
||||||
|
reconnect => 10,
|
||||||
|
every => 1_000_000,
|
||||||
|
);
|
||||||
|
my $val = $redis->get('SYNCJOBS_MAX_PARALLEL');
|
||||||
|
if (defined $val && $val =~ /^\d+$/) {
|
||||||
|
$max_parallel = int($val);
|
||||||
|
}
|
||||||
|
my $bps = $redis->get('SYNCJOBS_MAX_BPS');
|
||||||
|
if (defined $bps && $bps =~ /^\d+$/) {
|
||||||
|
$global_max_bps = int($bps);
|
||||||
|
}
|
||||||
|
$redis->quit();
|
||||||
|
} catch {
|
||||||
|
warn "Could not read settings from Redis, using defaults: $_";
|
||||||
|
};
|
||||||
|
$max_parallel = 1 if $max_parallel < 1;
|
||||||
|
$max_parallel = 50 if $max_parallel > 50;
|
||||||
|
|
||||||
|
my $dbh = DBI->connect($dsn, $ENV{'DBUSER'}, $ENV{'DBPASS'}, {
|
||||||
mysql_auto_reconnect => 1,
|
mysql_auto_reconnect => 1,
|
||||||
mysql_enable_utf8mb4 => 1
|
mysql_enable_utf8mb4 => 1
|
||||||
});
|
});
|
||||||
$dbh->do("UPDATE imapsync SET is_running = 0");
|
$dbh->do("UPDATE imapsync SET is_running = 0");
|
||||||
|
|
||||||
sub sig_handler {
|
|
||||||
# Send die to force exception in "run"
|
|
||||||
die "sig_handler received signal, preparing to exit...\n";
|
|
||||||
};
|
|
||||||
|
|
||||||
open my $file, '<', "/etc/sogo/sieve.creds";
|
open my $file, '<', "/etc/sogo/sieve.creds";
|
||||||
my $creds = <$file>;
|
my $creds = <$file>;
|
||||||
close $file;
|
close $file;
|
||||||
my ($master_user, $master_pass) = split /:/, $creds;
|
my ($master_user, $master_pass) = split /:/, $creds;
|
||||||
|
|
||||||
my $sth = $dbh->prepare("SELECT id,
|
my $sth = $dbh->prepare("SELECT id,
|
||||||
user1,
|
user1,
|
||||||
user2,
|
user2,
|
||||||
@@ -87,110 +217,43 @@ my $sth = $dbh->prepare("SELECT id,
|
|||||||
ORDER BY last_run");
|
ORDER BY last_run");
|
||||||
|
|
||||||
$sth->execute();
|
$sth->execute();
|
||||||
my $row;
|
my @jobs;
|
||||||
|
while (my $row = $sth->fetchrow_arrayref()) {
|
||||||
while ($row = $sth->fetchrow_arrayref()) {
|
push @jobs, [ @$row ];
|
||||||
|
|
||||||
$id = @$row[0];
|
|
||||||
$user1 = @$row[1];
|
|
||||||
$user2 = @$row[2];
|
|
||||||
$host1 = @$row[3];
|
|
||||||
$authmech1 = @$row[4];
|
|
||||||
$password1 = @$row[5];
|
|
||||||
$exclude = @$row[6];
|
|
||||||
$port1 = @$row[7];
|
|
||||||
$enc1 = @$row[8];
|
|
||||||
$delete2duplicates = @$row[9];
|
|
||||||
$maxage = @$row[10];
|
|
||||||
$subfolder2 = @$row[11];
|
|
||||||
$delete1 = @$row[12];
|
|
||||||
$delete2 = @$row[13];
|
|
||||||
$automap = @$row[14];
|
|
||||||
$skipcrossduplicates = @$row[15];
|
|
||||||
$maxbytespersecond = @$row[16];
|
|
||||||
$custom_params = @$row[17];
|
|
||||||
$subscribeall = @$row[18];
|
|
||||||
$timeout1 = @$row[19];
|
|
||||||
$timeout2 = @$row[20];
|
|
||||||
$dry = @$row[21];
|
|
||||||
|
|
||||||
if ($enc1 eq "TLS") { $enc1 = "--tls1"; } elsif ($enc1 eq "SSL") { $enc1 = "--ssl1"; } else { undef $enc1; }
|
|
||||||
|
|
||||||
my $template = $run_dir . '/imapsync.XXXXXXX';
|
|
||||||
my $passfile1 = File::Temp->new(TEMPLATE => $template);
|
|
||||||
my $passfile2 = File::Temp->new(TEMPLATE => $template);
|
|
||||||
|
|
||||||
binmode( $passfile1, ":utf8" );
|
|
||||||
|
|
||||||
print $passfile1 "$password1\n";
|
|
||||||
print $passfile2 trim($master_pass) . "\n";
|
|
||||||
|
|
||||||
my @custom_params_a = qqw($custom_params);
|
|
||||||
my $custom_params_ref = \@custom_params_a;
|
|
||||||
|
|
||||||
my $generated_cmds = [ "/usr/local/bin/imapsync",
|
|
||||||
"--tmpdir", "/tmp",
|
|
||||||
"--nofoldersizes",
|
|
||||||
"--addheader",
|
|
||||||
($timeout1 le "0" ? () : ('--timeout1', $timeout1)),
|
|
||||||
($timeout2 le "0" ? () : ('--timeout2', $timeout2)),
|
|
||||||
($exclude eq "" ? () : ("--exclude", $exclude)),
|
|
||||||
($subfolder2 eq "" ? () : ('--subfolder2', $subfolder2)),
|
|
||||||
($maxage eq "0" ? () : ('--maxage', $maxage)),
|
|
||||||
($maxbytespersecond eq "0" ? () : ('--maxbytespersecond', $maxbytespersecond)),
|
|
||||||
($delete2duplicates ne "1" ? () : ('--delete2duplicates')),
|
|
||||||
($subscribeall ne "1" ? () : ('--subscribeall')),
|
|
||||||
($delete1 ne "1" ? () : ('--delete')),
|
|
||||||
($delete2 ne "1" ? () : ('--delete2')),
|
|
||||||
($automap ne "1" ? () : ('--automap')),
|
|
||||||
($skipcrossduplicates ne "1" ? () : ('--skipcrossduplicates')),
|
|
||||||
(!defined($enc1) ? () : ($enc1)),
|
|
||||||
"--host1", $host1,
|
|
||||||
"--user1", $user1,
|
|
||||||
"--passfile1", $passfile1->filename,
|
|
||||||
"--port1", $port1,
|
|
||||||
"--host2", "localhost",
|
|
||||||
"--user2", $user2 . '*' . trim($master_user),
|
|
||||||
"--passfile2", $passfile2->filename,
|
|
||||||
($dry eq "1" ? ('--dry') : ()),
|
|
||||||
'--no-modulesversion',
|
|
||||||
'--noreleasecheck'];
|
|
||||||
|
|
||||||
try {
|
|
||||||
$is_running = $dbh->prepare("UPDATE imapsync SET is_running = 1, success = NULL, exit_status = NULL WHERE id = ?");
|
|
||||||
$is_running->bind_param( 1, ${id} );
|
|
||||||
$is_running->execute();
|
|
||||||
|
|
||||||
run [@$generated_cmds, @$custom_params_ref], '&>', \my $stdout;
|
|
||||||
|
|
||||||
# check exit code and status
|
|
||||||
($exit_code, $exit_status) = ($stdout =~ m/Exiting\swith\sreturn\svalue\s(\d+)\s\(([^:)]+)/);
|
|
||||||
|
|
||||||
$success = 0;
|
|
||||||
if (defined $exit_code && $exit_code == 0) {
|
|
||||||
$success = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
$update = $dbh->prepare("UPDATE imapsync SET returned_text = ?, success = ?, exit_status = ? WHERE id = ?");
|
|
||||||
$update->bind_param( 1, ${stdout} );
|
|
||||||
$update->bind_param( 2, ${success} );
|
|
||||||
$update->bind_param( 3, ${exit_status} );
|
|
||||||
$update->bind_param( 4, ${id} );
|
|
||||||
$update->execute();
|
|
||||||
} catch {
|
|
||||||
$update = $dbh->prepare("UPDATE imapsync SET returned_text = 'Could not start or finish imapsync', success = 0 WHERE id = ?");
|
|
||||||
$update->bind_param( 1, ${id} );
|
|
||||||
$update->execute();
|
|
||||||
} finally {
|
|
||||||
$update = $dbh->prepare("UPDATE imapsync SET last_run = NOW(), is_running = 0 WHERE id = ?");
|
|
||||||
$update->bind_param( 1, ${id} );
|
|
||||||
$update->execute();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$sth->finish();
|
$sth->finish();
|
||||||
$dbh->disconnect();
|
$dbh->disconnect();
|
||||||
|
|
||||||
|
$pm = Parallel::ForkManager->new($max_parallel);
|
||||||
|
|
||||||
|
JOB:
|
||||||
|
foreach my $job (@jobs) {
|
||||||
|
my $pid = $pm->start;
|
||||||
|
if ($pid) {
|
||||||
|
next JOB;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $child_dbh = DBI->connect($dsn, $ENV{'DBUSER'}, $ENV{'DBPASS'}, {
|
||||||
|
mysql_auto_reconnect => 1,
|
||||||
|
mysql_enable_utf8mb4 => 1
|
||||||
|
});
|
||||||
|
eval {
|
||||||
|
run_one_job($child_dbh, $job, $master_user, $master_pass);
|
||||||
|
};
|
||||||
|
if ($@) {
|
||||||
|
warn "run_one_job died for job $job->[0]: $@";
|
||||||
|
eval {
|
||||||
|
my $err_sth = $child_dbh->prepare("UPDATE imapsync SET last_run = NOW(), is_running = 0, success = 0, returned_text = ? WHERE id = ?");
|
||||||
|
$err_sth->bind_param(1, "Runner error: $@");
|
||||||
|
$err_sth->bind_param(2, $job->[0]);
|
||||||
|
$err_sth->execute();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
$child_dbh->disconnect();
|
||||||
|
|
||||||
|
$pm->finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
$pm->wait_all_children;
|
||||||
|
|
||||||
$lockmgr->unlock($lock_file);
|
$lockmgr->unlock($lock_file);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Whitelist generated by Postwhite v3.4 on Sun Mar 1 00:29:01 UTC 2026
|
# Whitelist generated by Postwhite v3.4 on Wed Apr 1 00:33:31 UTC 2026
|
||||||
# https://github.com/stevejenkins/postwhite/
|
# https://github.com/stevejenkins/postwhite/
|
||||||
# 2174 total rules
|
# 2246 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:2800::/53 permit
|
2a01:111:f403:2800::/53 permit
|
||||||
@@ -31,8 +31,10 @@
|
|||||||
2a02:a60:0:5::/64 permit
|
2a02:a60:0:5::/64 permit
|
||||||
2a0f:f640::/56 permit
|
2a0f:f640::/56 permit
|
||||||
2c0f:fb50:4000::/36 permit
|
2c0f:fb50:4000::/36 permit
|
||||||
|
2.207.151.32/27 permit
|
||||||
2.207.151.53 permit
|
2.207.151.53 permit
|
||||||
2.207.217.30 permit
|
2.207.217.30 permit
|
||||||
|
2.207.223.160/27 permit
|
||||||
3.64.237.68 permit
|
3.64.237.68 permit
|
||||||
3.65.3.180 permit
|
3.65.3.180 permit
|
||||||
3.70.123.177 permit
|
3.70.123.177 permit
|
||||||
@@ -58,8 +60,8 @@
|
|||||||
8.40.222.0/23 permit
|
8.40.222.0/23 permit
|
||||||
8.40.222.250/31 permit
|
8.40.222.250/31 permit
|
||||||
12.130.86.238 permit
|
12.130.86.238 permit
|
||||||
13.107.213.51 permit
|
13.107.213.38 permit
|
||||||
13.107.246.51 permit
|
13.107.246.38 permit
|
||||||
13.108.16.0/20 permit
|
13.108.16.0/20 permit
|
||||||
13.110.208.0/21 permit
|
13.110.208.0/21 permit
|
||||||
13.110.209.0/24 permit
|
13.110.209.0/24 permit
|
||||||
@@ -368,6 +370,7 @@
|
|||||||
64.132.88.0/23 permit
|
64.132.88.0/23 permit
|
||||||
64.132.92.0/24 permit
|
64.132.92.0/24 permit
|
||||||
64.181.194.190 permit
|
64.181.194.190 permit
|
||||||
|
64.181.213.254 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
|
||||||
@@ -453,7 +456,11 @@
|
|||||||
66.218.75.252/31 permit
|
66.218.75.252/31 permit
|
||||||
66.218.75.254 permit
|
66.218.75.254 permit
|
||||||
66.220.144.128/25 permit
|
66.220.144.128/25 permit
|
||||||
|
66.220.144.178 permit
|
||||||
|
66.220.144.179 permit
|
||||||
66.220.155.0/24 permit
|
66.220.155.0/24 permit
|
||||||
|
66.220.155.178 permit
|
||||||
|
66.220.155.179 permit
|
||||||
66.220.157.0/25 permit
|
66.220.157.0/25 permit
|
||||||
66.231.80.0/20 permit
|
66.231.80.0/20 permit
|
||||||
66.240.227.0/24 permit
|
66.240.227.0/24 permit
|
||||||
@@ -518,6 +525,8 @@
|
|||||||
69.162.98.0/24 permit
|
69.162.98.0/24 permit
|
||||||
69.169.224.0/20 permit
|
69.169.224.0/20 permit
|
||||||
69.171.232.0/24 permit
|
69.171.232.0/24 permit
|
||||||
|
69.171.232.180 permit
|
||||||
|
69.171.232.181 permit
|
||||||
69.171.244.0/23 permit
|
69.171.244.0/23 permit
|
||||||
70.42.149.35 permit
|
70.42.149.35 permit
|
||||||
72.3.185.0/24 permit
|
72.3.185.0/24 permit
|
||||||
@@ -639,6 +648,7 @@
|
|||||||
77.238.189.148/30 permit
|
77.238.189.148/30 permit
|
||||||
79.135.106.0/24 permit
|
79.135.106.0/24 permit
|
||||||
79.135.107.0/24 permit
|
79.135.107.0/24 permit
|
||||||
|
80.225.160.128/25 permit
|
||||||
81.169.146.243 permit
|
81.169.146.243 permit
|
||||||
81.169.146.245 permit
|
81.169.146.245 permit
|
||||||
81.169.146.246 permit
|
81.169.146.246 permit
|
||||||
@@ -657,6 +667,9 @@
|
|||||||
82.165.159.45 permit
|
82.165.159.45 permit
|
||||||
82.165.159.130 permit
|
82.165.159.130 permit
|
||||||
82.165.159.131 permit
|
82.165.159.131 permit
|
||||||
|
84.8.68.0/25 permit
|
||||||
|
84.8.192.128/25 permit
|
||||||
|
84.8.224.128/25 permit
|
||||||
85.9.206.169 permit
|
85.9.206.169 permit
|
||||||
85.9.210.45 permit
|
85.9.210.45 permit
|
||||||
85.158.136.0/21 permit
|
85.158.136.0/21 permit
|
||||||
@@ -1408,6 +1421,20 @@
|
|||||||
129.146.88.28 permit
|
129.146.88.28 permit
|
||||||
129.146.147.105 permit
|
129.146.147.105 permit
|
||||||
129.146.236.58 permit
|
129.146.236.58 permit
|
||||||
|
129.148.135.0/25 permit
|
||||||
|
129.148.148.0/25 permit
|
||||||
|
129.148.164.0/25 permit
|
||||||
|
129.148.180.0/25 permit
|
||||||
|
129.148.215.0/25 permit
|
||||||
|
129.149.6.0/25 permit
|
||||||
|
129.149.22.0/25 permit
|
||||||
|
129.149.38.0/25 permit
|
||||||
|
129.149.52.0/25 permit
|
||||||
|
129.149.68.0/25 permit
|
||||||
|
129.149.84.0/25 permit
|
||||||
|
129.149.100.0/25 permit
|
||||||
|
129.149.118.0/25 permit
|
||||||
|
129.149.126.0/25 permit
|
||||||
129.151.67.221 permit
|
129.151.67.221 permit
|
||||||
129.153.62.216 permit
|
129.153.62.216 permit
|
||||||
129.153.104.71 permit
|
129.153.104.71 permit
|
||||||
@@ -1420,16 +1447,19 @@
|
|||||||
129.159.22.159 permit
|
129.159.22.159 permit
|
||||||
129.159.87.137 permit
|
129.159.87.137 permit
|
||||||
129.213.195.191 permit
|
129.213.195.191 permit
|
||||||
|
130.35.116.0/25 permit
|
||||||
130.61.9.72 permit
|
130.61.9.72 permit
|
||||||
130.162.39.83 permit
|
130.162.39.83 permit
|
||||||
130.248.172.0/24 permit
|
130.248.172.0/24 permit
|
||||||
130.248.173.0/24 permit
|
130.248.173.0/24 permit
|
||||||
|
131.186.12.0/25 permit
|
||||||
131.253.30.0/24 permit
|
131.253.30.0/24 permit
|
||||||
131.253.121.0/26 permit
|
131.253.121.0/26 permit
|
||||||
132.145.13.209 permit
|
132.145.13.209 permit
|
||||||
132.226.26.225 permit
|
132.226.26.225 permit
|
||||||
132.226.49.32 permit
|
132.226.49.32 permit
|
||||||
132.226.56.24 permit
|
132.226.56.24 permit
|
||||||
|
134.98.248.128/25 permit
|
||||||
134.128.64.0/19 permit
|
134.128.64.0/19 permit
|
||||||
134.128.96.0/19 permit
|
134.128.96.0/19 permit
|
||||||
134.170.27.8 permit
|
134.170.27.8 permit
|
||||||
@@ -1460,6 +1490,10 @@
|
|||||||
136.147.182.0/24 permit
|
136.147.182.0/24 permit
|
||||||
136.147.224.0/20 permit
|
136.147.224.0/20 permit
|
||||||
136.179.50.206 permit
|
136.179.50.206 permit
|
||||||
|
136.248.224.128/25 permit
|
||||||
|
136.248.232.128/25 permit
|
||||||
|
138.1.108.0/25 permit
|
||||||
|
138.1.170.0/24 permit
|
||||||
139.60.152.0/22 permit
|
139.60.152.0/22 permit
|
||||||
139.138.35.44 permit
|
139.138.35.44 permit
|
||||||
139.138.46.121 permit
|
139.138.46.121 permit
|
||||||
@@ -1468,6 +1502,7 @@
|
|||||||
139.138.57.55 permit
|
139.138.57.55 permit
|
||||||
139.138.58.119 permit
|
139.138.58.119 permit
|
||||||
139.167.79.86 permit
|
139.167.79.86 permit
|
||||||
|
139.177.108.0/25 permit
|
||||||
139.180.17.0/24 permit
|
139.180.17.0/24 permit
|
||||||
140.238.148.191 permit
|
140.238.148.191 permit
|
||||||
141.148.55.217 permit
|
141.148.55.217 permit
|
||||||
@@ -1506,6 +1541,9 @@
|
|||||||
146.88.28.0/24 permit
|
146.88.28.0/24 permit
|
||||||
146.148.116.76 permit
|
146.148.116.76 permit
|
||||||
147.154.32.0/25 permit
|
147.154.32.0/25 permit
|
||||||
|
147.154.63.0/24 permit
|
||||||
|
147.154.126.0/24 permit
|
||||||
|
147.154.191.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
|
||||||
@@ -1517,12 +1555,16 @@
|
|||||||
149.72.234.184 permit
|
149.72.234.184 permit
|
||||||
149.72.248.236 permit
|
149.72.248.236 permit
|
||||||
149.97.173.180 permit
|
149.97.173.180 permit
|
||||||
|
149.118.160.128/25 permit
|
||||||
150.136.21.199 permit
|
150.136.21.199 permit
|
||||||
150.230.98.160 permit
|
150.230.98.160 permit
|
||||||
151.145.38.14 permit
|
151.145.38.14 permit
|
||||||
152.67.105.195 permit
|
152.67.105.195 permit
|
||||||
152.69.200.236 permit
|
152.69.200.236 permit
|
||||||
152.70.155.126 permit
|
152.70.155.126 permit
|
||||||
|
155.248.135.128/25 permit
|
||||||
|
155.248.140.0/25 permit
|
||||||
|
155.248.148.0/25 permit
|
||||||
155.248.208.51 permit
|
155.248.208.51 permit
|
||||||
155.248.220.138 permit
|
155.248.220.138 permit
|
||||||
155.248.234.149 permit
|
155.248.234.149 permit
|
||||||
@@ -1531,10 +1573,14 @@
|
|||||||
157.58.30.128/25 permit
|
157.58.30.128/25 permit
|
||||||
157.58.196.96/29 permit
|
157.58.196.96/29 permit
|
||||||
157.58.249.3 permit
|
157.58.249.3 permit
|
||||||
|
157.137.32.128/25 permit
|
||||||
|
157.137.96.128/25 permit
|
||||||
157.151.208.65 permit
|
157.151.208.65 permit
|
||||||
157.255.1.64/29 permit
|
157.255.1.64/29 permit
|
||||||
158.101.211.207 permit
|
158.101.211.207 permit
|
||||||
158.247.16.0/20 permit
|
158.247.16.0/20 permit
|
||||||
|
158.247.100.0/25 permit
|
||||||
|
159.13.4.0/25 permit
|
||||||
159.92.154.0/24 permit
|
159.92.154.0/24 permit
|
||||||
159.92.155.0/24 permit
|
159.92.155.0/24 permit
|
||||||
159.92.157.0/24 permit
|
159.92.157.0/24 permit
|
||||||
@@ -1568,6 +1614,7 @@
|
|||||||
161.71.64.0/20 permit
|
161.71.64.0/20 permit
|
||||||
162.88.4.0/23 permit
|
162.88.4.0/23 permit
|
||||||
162.88.8.0/24 permit
|
162.88.8.0/24 permit
|
||||||
|
162.88.24.0/23 permit
|
||||||
162.88.24.0/24 permit
|
162.88.24.0/24 permit
|
||||||
162.88.25.0/24 permit
|
162.88.25.0/24 permit
|
||||||
162.88.36.0/24 permit
|
162.88.36.0/24 permit
|
||||||
@@ -1585,10 +1632,12 @@
|
|||||||
164.152.23.32 permit
|
164.152.23.32 permit
|
||||||
164.152.25.241 permit
|
164.152.25.241 permit
|
||||||
164.177.132.168/30 permit
|
164.177.132.168/30 permit
|
||||||
|
165.1.100.0/25 permit
|
||||||
165.173.128.0/24 permit
|
165.173.128.0/24 permit
|
||||||
165.173.180.1 permit
|
165.173.180.1 permit
|
||||||
165.173.180.250/31 permit
|
165.173.180.250/31 permit
|
||||||
165.173.182.250/31 permit
|
165.173.182.250/31 permit
|
||||||
|
165.173.189.205 permit
|
||||||
166.78.68.0/22 permit
|
166.78.68.0/22 permit
|
||||||
166.78.68.221 permit
|
166.78.68.221 permit
|
||||||
166.78.69.169 permit
|
166.78.69.169 permit
|
||||||
@@ -1607,9 +1656,12 @@
|
|||||||
167.89.75.126 permit
|
167.89.75.126 permit
|
||||||
167.89.75.136 permit
|
167.89.75.136 permit
|
||||||
167.89.75.164 permit
|
167.89.75.164 permit
|
||||||
167.89.101.2 permit
|
|
||||||
167.89.101.192/28 permit
|
|
||||||
167.220.67.232/29 permit
|
167.220.67.232/29 permit
|
||||||
|
168.107.248.128/25 permit
|
||||||
|
168.110.160.128/25 permit
|
||||||
|
168.110.248.128/25 permit
|
||||||
|
168.129.184.128/25 permit
|
||||||
|
168.129.248.128/25 permit
|
||||||
168.138.5.36 permit
|
168.138.5.36 permit
|
||||||
168.138.73.51 permit
|
168.138.73.51 permit
|
||||||
168.138.77.31 permit
|
168.138.77.31 permit
|
||||||
@@ -1745,8 +1797,24 @@
|
|||||||
192.18.139.154 permit
|
192.18.139.154 permit
|
||||||
192.18.145.36 permit
|
192.18.145.36 permit
|
||||||
192.18.152.58 permit
|
192.18.152.58 permit
|
||||||
|
192.22.32.128/25 permit
|
||||||
|
192.22.96.128/25 permit
|
||||||
|
192.22.160.128/25 permit
|
||||||
|
192.22.224.128/25 permit
|
||||||
192.28.128.0/18 permit
|
192.28.128.0/18 permit
|
||||||
|
192.29.24.0/25 permit
|
||||||
|
192.29.44.0/25 permit
|
||||||
|
192.29.72.0/25 permit
|
||||||
|
192.29.88.0/25 permit
|
||||||
192.29.103.128/25 permit
|
192.29.103.128/25 permit
|
||||||
|
192.29.134.0/25 permit
|
||||||
|
192.29.151.128/25 permit
|
||||||
|
192.29.172.0/25 permit
|
||||||
|
192.29.178.0/25 permit
|
||||||
|
192.29.200.0/25 permit
|
||||||
|
192.29.216.0/25 permit
|
||||||
|
192.29.232.0/25 permit
|
||||||
|
192.29.248.0/25 permit
|
||||||
192.30.252.0/22 permit
|
192.30.252.0/22 permit
|
||||||
192.161.144.0/20 permit
|
192.161.144.0/20 permit
|
||||||
192.162.87.0/24 permit
|
192.162.87.0/24 permit
|
||||||
@@ -1754,11 +1822,6 @@
|
|||||||
192.237.159.42 permit
|
192.237.159.42 permit
|
||||||
192.237.159.43 permit
|
192.237.159.43 permit
|
||||||
192.254.112.0/20 permit
|
192.254.112.0/20 permit
|
||||||
192.254.112.60 permit
|
|
||||||
192.254.112.98/31 permit
|
|
||||||
192.254.113.10 permit
|
|
||||||
192.254.113.101 permit
|
|
||||||
192.254.114.176 permit
|
|
||||||
193.109.254.0/23 permit
|
193.109.254.0/23 permit
|
||||||
193.122.128.100 permit
|
193.122.128.100 permit
|
||||||
193.123.56.63 permit
|
193.123.56.63 permit
|
||||||
@@ -1927,6 +1990,7 @@
|
|||||||
207.211.30.128/25 permit
|
207.211.30.128/25 permit
|
||||||
207.211.31.0/25 permit
|
207.211.31.0/25 permit
|
||||||
207.211.41.113 permit
|
207.211.41.113 permit
|
||||||
|
207.211.132.0/25 permit
|
||||||
207.218.90.0/24 permit
|
207.218.90.0/24 permit
|
||||||
207.218.90.122 permit
|
207.218.90.122 permit
|
||||||
207.250.68.0/24 permit
|
207.250.68.0/24 permit
|
||||||
@@ -1934,6 +1998,8 @@
|
|||||||
208.43.21.28/30 permit
|
208.43.21.28/30 permit
|
||||||
208.43.21.64/29 permit
|
208.43.21.64/29 permit
|
||||||
208.43.21.72/30 permit
|
208.43.21.72/30 permit
|
||||||
|
208.56.9.224 permit
|
||||||
|
208.56.13.196 permit
|
||||||
208.64.132.0/22 permit
|
208.64.132.0/22 permit
|
||||||
208.71.40.63 permit
|
208.71.40.63 permit
|
||||||
208.71.40.64/31 permit
|
208.71.40.64/31 permit
|
||||||
@@ -1960,6 +2026,7 @@
|
|||||||
208.71.42.214 permit
|
208.71.42.214 permit
|
||||||
208.72.249.240/29 permit
|
208.72.249.240/29 permit
|
||||||
208.75.120.0/22 permit
|
208.75.120.0/22 permit
|
||||||
|
208.76.62.0/23 permit
|
||||||
208.76.62.0/24 permit
|
208.76.62.0/24 permit
|
||||||
208.76.63.0/24 permit
|
208.76.63.0/24 permit
|
||||||
208.82.237.96/29 permit
|
208.82.237.96/29 permit
|
||||||
@@ -2120,6 +2187,7 @@
|
|||||||
216.136.168.80/28 permit
|
216.136.168.80/28 permit
|
||||||
216.139.64.0/19 permit
|
216.139.64.0/19 permit
|
||||||
216.145.221.0/24 permit
|
216.145.221.0/24 permit
|
||||||
|
216.146.32.0/23 permit
|
||||||
216.146.32.0/24 permit
|
216.146.32.0/24 permit
|
||||||
216.146.33.0/24 permit
|
216.146.33.0/24 permit
|
||||||
216.198.0.0/18 permit
|
216.198.0.0/18 permit
|
||||||
@@ -2140,6 +2208,7 @@
|
|||||||
223.165.120.0/23 permit
|
223.165.120.0/23 permit
|
||||||
2001:0868:0100:0600::/64 permit
|
2001:0868:0100:0600::/64 permit
|
||||||
2001:4860:4000::/36 permit
|
2001:4860:4000::/36 permit
|
||||||
|
2001:4860:4864::/56 permit
|
||||||
2001:748:100:40::2:0/112 permit
|
2001:748:100:40::2:0/112 permit
|
||||||
2001:748:400:1300::3 permit
|
2001:748:400:1300::3 permit
|
||||||
2001:748:400:1300::4 permit
|
2001:748:400:1300::4 permit
|
||||||
@@ -2157,10 +2226,12 @@
|
|||||||
2001:748:400:3301::3 permit
|
2001:748:400:3301::3 permit
|
||||||
2001:748:400:3301::4 permit
|
2001:748:400:3301::4 permit
|
||||||
2404:6800:4000::/36 permit
|
2404:6800:4000::/36 permit
|
||||||
|
2404:6800:4864::/56 permit
|
||||||
2607:13c0:0001:0000:0000:0000:0000:7000/116 permit
|
2607:13c0:0001:0000:0000:0000:0000:7000/116 permit
|
||||||
2607:13c0:0002:0000:0000:0000:0000:1000/116 permit
|
2607:13c0:0002:0000:0000:0000:0000:1000/116 permit
|
||||||
2607:13c0:0004:0000:0000:0000:0000:0000/116 permit
|
2607:13c0:0004:0000:0000:0000:0000:0000/116 permit
|
||||||
2607:f8b0:4000::/36 permit
|
2607:f8b0:4000::/36 permit
|
||||||
|
2607:f8b0:4864::/56 permit
|
||||||
2620:109:c003:104::/64 permit
|
2620:109:c003:104::/64 permit
|
||||||
2620:109:c003:104::215 permit
|
2620:109:c003:104::215 permit
|
||||||
2620:109:c006:104::/64 permit
|
2620:109:c006:104::/64 permit
|
||||||
@@ -2172,8 +2243,9 @@
|
|||||||
2620:10d:c09c:400::8:1 permit
|
2620:10d:c09c:400::8:1 permit
|
||||||
2620:119:50c0:207::/64 permit
|
2620:119:50c0:207::/64 permit
|
||||||
2620:119:50c0:207::215 permit
|
2620:119:50c0:207::215 permit
|
||||||
2620:1ec:46::51 permit
|
2620:1ec:46::38 permit
|
||||||
2620:1ec:bdf::51 permit
|
2620:1ec:bdf::38 permit
|
||||||
2800:3f0:4000::/36 permit
|
2800:3f0:4000::/36 permit
|
||||||
|
2800:3f0:4864::/56 permit
|
||||||
49.12.4.251 permit # checks.mailcow.email
|
49.12.4.251 permit # checks.mailcow.email
|
||||||
2a01:4f8:c17:7906::10 permit # checks.mailcow.email
|
2a01:4f8:c17:7906::10 permit # checks.mailcow.email
|
||||||
|
|||||||
@@ -106,6 +106,7 @@ $template_data = [
|
|||||||
'f2b_data' => $f2b_data,
|
'f2b_data' => $f2b_data,
|
||||||
'f2b_banlist_url' => getBaseUrl() . "/f2b-banlist?id=" . $f2b_data['banlist_id'],
|
'f2b_banlist_url' => getBaseUrl() . "/f2b-banlist?id=" . $f2b_data['banlist_id'],
|
||||||
'q_data' => quarantine('settings'),
|
'q_data' => quarantine('settings'),
|
||||||
|
'sj_data' => mailbox('get', 'syncjob_settings'),
|
||||||
'qn_data' => quota_notification('get'),
|
'qn_data' => quota_notification('get'),
|
||||||
'pw_reset_data' => reset_password('get_notification'),
|
'pw_reset_data' => reset_password('get_notification'),
|
||||||
'rsettings_map' => file_get_contents('http://nginx:8081/settings.php'),
|
'rsettings_map' => file_get_contents('http://nginx:8081/settings.php'),
|
||||||
|
|||||||
@@ -3931,6 +3931,64 @@ paths:
|
|||||||
type: object
|
type: object
|
||||||
type: object
|
type: object
|
||||||
summary: Update sync job
|
summary: Update sync job
|
||||||
|
/api/v1/edit/syncjob_settings:
|
||||||
|
post:
|
||||||
|
responses:
|
||||||
|
"401":
|
||||||
|
$ref: "#/components/responses/Unauthorized"
|
||||||
|
"200":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
examples:
|
||||||
|
response:
|
||||||
|
value:
|
||||||
|
log:
|
||||||
|
- entity
|
||||||
|
- action
|
||||||
|
- object
|
||||||
|
msg:
|
||||||
|
- message
|
||||||
|
- entity name
|
||||||
|
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:
|
||||||
|
- Sync jobs
|
||||||
|
description: >-
|
||||||
|
Update the global sync job settings. Currently exposes the maximum
|
||||||
|
number of imapsync processes that are allowed to run in parallel.
|
||||||
|
Admin access required.
|
||||||
|
operationId: Update sync job settings
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
example:
|
||||||
|
max_parallel: 4
|
||||||
|
properties:
|
||||||
|
max_parallel:
|
||||||
|
description: >-
|
||||||
|
Maximum number of imapsync processes allowed to run in
|
||||||
|
parallel (1 = sequential behavior, max 50)
|
||||||
|
type: integer
|
||||||
|
type: object
|
||||||
|
summary: Update sync job settings
|
||||||
/api/v1/edit/user-acl:
|
/api/v1/edit/user-acl:
|
||||||
post:
|
post:
|
||||||
responses:
|
responses:
|
||||||
@@ -5629,6 +5687,36 @@ paths:
|
|||||||
description: You can list all syn jobs existing in system.
|
description: You can list all syn jobs existing in system.
|
||||||
operationId: Get sync jobs
|
operationId: Get sync jobs
|
||||||
summary: Get sync jobs
|
summary: Get sync jobs
|
||||||
|
/api/v1/get/syncjob_settings:
|
||||||
|
get:
|
||||||
|
responses:
|
||||||
|
"401":
|
||||||
|
$ref: "#/components/responses/Unauthorized"
|
||||||
|
"200":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
examples:
|
||||||
|
response:
|
||||||
|
value:
|
||||||
|
max_parallel: 4
|
||||||
|
schema:
|
||||||
|
properties:
|
||||||
|
max_parallel:
|
||||||
|
description: >-
|
||||||
|
Maximum number of imapsync processes allowed to run in
|
||||||
|
parallel (1 = sequential behavior)
|
||||||
|
type: integer
|
||||||
|
type: object
|
||||||
|
description: OK
|
||||||
|
headers: {}
|
||||||
|
tags:
|
||||||
|
- Sync jobs
|
||||||
|
description: >-
|
||||||
|
Return the global sync job settings. Currently exposes the maximum
|
||||||
|
number of imapsync processes allowed to run in parallel. Admin access
|
||||||
|
required.
|
||||||
|
operationId: Get sync job settings
|
||||||
|
summary: Get sync job settings
|
||||||
"/api/v1/get/tls-policy-map/{id}":
|
"/api/v1/get/tls-policy-map/{id}":
|
||||||
get:
|
get:
|
||||||
parameters:
|
parameters:
|
||||||
|
|||||||
@@ -2265,6 +2265,38 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'syncjob_settings':
|
||||||
|
if (!isset($_SESSION['mailcow_cc_role']) || $_SESSION['mailcow_cc_role'] != 'admin') {
|
||||||
|
$_SESSION['return'][] = array(
|
||||||
|
'type' => 'danger',
|
||||||
|
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||||
|
'msg' => 'access_denied'
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$max_parallel = intval($_data['max_parallel']);
|
||||||
|
if ($max_parallel < 1) { $max_parallel = 1; }
|
||||||
|
if ($max_parallel > 50) { $max_parallel = 50; }
|
||||||
|
$max_bps = intval($_data['max_bps']);
|
||||||
|
if ($max_bps < 0) { $max_bps = 0; }
|
||||||
|
try {
|
||||||
|
$redis->Set('SYNCJOBS_MAX_PARALLEL', $max_parallel);
|
||||||
|
$redis->Set('SYNCJOBS_MAX_BPS', $max_bps);
|
||||||
|
}
|
||||||
|
catch (RedisException $e) {
|
||||||
|
$_SESSION['return'][] = array(
|
||||||
|
'type' => 'danger',
|
||||||
|
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||||
|
'msg' => array('redis_error', $e->getMessage())
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$_SESSION['return'][] = array(
|
||||||
|
'type' => 'success',
|
||||||
|
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
|
||||||
|
'msg' => 'syncjob_settings_saved'
|
||||||
|
);
|
||||||
|
break;
|
||||||
case 'syncjob':
|
case 'syncjob':
|
||||||
if (!is_array($_data['id'])) {
|
if (!is_array($_data['id'])) {
|
||||||
$ids = array();
|
$ids = array();
|
||||||
@@ -4619,6 +4651,27 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
|||||||
}
|
}
|
||||||
return $syncjobdetails;
|
return $syncjobdetails;
|
||||||
break;
|
break;
|
||||||
|
case 'syncjob_settings':
|
||||||
|
if (!isset($_SESSION['mailcow_cc_role']) || $_SESSION['mailcow_cc_role'] != 'admin') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$settings = array();
|
||||||
|
try {
|
||||||
|
$max_parallel = $redis->Get('SYNCJOBS_MAX_PARALLEL');
|
||||||
|
}
|
||||||
|
catch (RedisException $e) {
|
||||||
|
$max_parallel = null;
|
||||||
|
}
|
||||||
|
$settings['max_parallel'] = intval($max_parallel) ?: 1;
|
||||||
|
try {
|
||||||
|
$max_bps = $redis->Get('SYNCJOBS_MAX_BPS');
|
||||||
|
}
|
||||||
|
catch (RedisException $e) {
|
||||||
|
$max_bps = null;
|
||||||
|
}
|
||||||
|
$settings['max_bps'] = intval($max_bps) ?: 0;
|
||||||
|
return $settings;
|
||||||
|
break;
|
||||||
case 'syncjobs':
|
case 'syncjobs':
|
||||||
$syncjobdata = array();
|
$syncjobdata = array();
|
||||||
if (isset($_data) && filter_var($_data, FILTER_VALIDATE_EMAIL)) {
|
if (isset($_data) && filter_var($_data, FILTER_VALIDATE_EMAIL)) {
|
||||||
|
|||||||
@@ -2150,7 +2150,7 @@ jQuery(function($){
|
|||||||
var table = $('#sync_job_table').DataTable({
|
var table = $('#sync_job_table').DataTable({
|
||||||
responsive: true,
|
responsive: true,
|
||||||
processing: true,
|
processing: true,
|
||||||
serverSide: false,
|
serverSide: true,
|
||||||
stateSave: true,
|
stateSave: true,
|
||||||
pageLength: pagination_size,
|
pageLength: pagination_size,
|
||||||
dom: "<'row'<'col-sm-12 col-md-6'f><'col-sm-12 col-md-6'l>>" +
|
dom: "<'row'<'col-sm-12 col-md-6'f><'col-sm-12 col-md-6'l>>" +
|
||||||
@@ -2162,10 +2162,15 @@ jQuery(function($){
|
|||||||
hideTableExpandCollapseBtn('#tab-syncjobs', '#sync_job_table');
|
hideTableExpandCollapseBtn('#tab-syncjobs', '#sync_job_table');
|
||||||
},
|
},
|
||||||
ajax: {
|
ajax: {
|
||||||
type: "GET",
|
type: "POST",
|
||||||
url: "/api/v1/get/syncjobs/all/no_log",
|
url: "/api/v1/search/syncjob",
|
||||||
|
contentType: "application/json",
|
||||||
|
processData: false,
|
||||||
|
data: function(d) {
|
||||||
|
return JSON.stringify(d);
|
||||||
|
},
|
||||||
dataSrc: function(json){
|
dataSrc: function(json){
|
||||||
$.each(json, function (i, item) {
|
$.each(json.data, function (i, item) {
|
||||||
item.log = '<a href="#syncjobLogModal" data-bs-toggle="modal" data-syncjob-id="' + encodeURIComponent(item.id) + '">' + lang.open_logs + '</a>'
|
item.log = '<a href="#syncjobLogModal" data-bs-toggle="modal" data-syncjob-id="' + encodeURIComponent(item.id) + '">' + lang.open_logs + '</a>'
|
||||||
item.user2 = escapeHtml(item.user2);
|
item.user2 = escapeHtml(item.user2);
|
||||||
if (!item.exclude > 0) {
|
if (!item.exclude > 0) {
|
||||||
@@ -2201,7 +2206,7 @@ jQuery(function($){
|
|||||||
item.exit_status = item.success + ' ' + item.exit_status;
|
item.exit_status = item.success + ' ' + item.exit_status;
|
||||||
});
|
});
|
||||||
|
|
||||||
return json;
|
return json.data;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
columns: [
|
columns: [
|
||||||
@@ -2225,6 +2230,7 @@ jQuery(function($){
|
|||||||
{
|
{
|
||||||
title: 'ID',
|
title: 'ID',
|
||||||
data: 'id',
|
data: 'id',
|
||||||
|
searchable: false,
|
||||||
responsivePriority: 3,
|
responsivePriority: 3,
|
||||||
defaultContent: ''
|
defaultContent: ''
|
||||||
},
|
},
|
||||||
@@ -2242,21 +2248,27 @@ jQuery(function($){
|
|||||||
{
|
{
|
||||||
title: lang.last_run,
|
title: lang.last_run,
|
||||||
data: 'last_run',
|
data: 'last_run',
|
||||||
|
searchable: false,
|
||||||
defaultContent: ''
|
defaultContent: ''
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: lang.syncjob_last_run_result,
|
title: lang.syncjob_last_run_result,
|
||||||
data: 'exit_status',
|
data: 'exit_status',
|
||||||
|
searchable: false,
|
||||||
|
orderable: false,
|
||||||
defaultContent: ''
|
defaultContent: ''
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Log',
|
title: 'Log',
|
||||||
data: 'log',
|
data: 'log',
|
||||||
|
searchable: false,
|
||||||
|
orderable: false,
|
||||||
defaultContent: ''
|
defaultContent: ''
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: lang.active,
|
title: lang.active,
|
||||||
data: 'active',
|
data: 'active',
|
||||||
|
searchable: false,
|
||||||
defaultContent: '',
|
defaultContent: '',
|
||||||
render: function (data, type) {
|
render: function (data, type) {
|
||||||
return 1==data?'<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>':0==data&&'<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>';
|
return 1==data?'<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>':0==data&&'<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>';
|
||||||
@@ -2265,23 +2277,31 @@ jQuery(function($){
|
|||||||
{
|
{
|
||||||
title: lang.status,
|
title: lang.status,
|
||||||
data: 'is_running',
|
data: 'is_running',
|
||||||
|
searchable: false,
|
||||||
|
orderable: false,
|
||||||
defaultContent: ''
|
defaultContent: ''
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: lang.excludes,
|
title: lang.excludes,
|
||||||
data: 'exclude',
|
data: 'exclude',
|
||||||
|
searchable: false,
|
||||||
|
orderable: false,
|
||||||
defaultContent: '',
|
defaultContent: '',
|
||||||
className: 'none'
|
className: 'none'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: lang.mins_interval,
|
title: lang.mins_interval,
|
||||||
data: 'mins_interval',
|
data: 'mins_interval',
|
||||||
|
searchable: false,
|
||||||
|
orderable: false,
|
||||||
defaultContent: '',
|
defaultContent: '',
|
||||||
className: 'none'
|
className: 'none'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: lang.action,
|
title: lang.action,
|
||||||
data: 'action',
|
data: 'action',
|
||||||
|
searchable: false,
|
||||||
|
orderable: false,
|
||||||
className: 'dt-sm-head-hidden dt-data-w100 dtr-col-md dt-text-right',
|
className: 'dt-sm-head-hidden dt-data-w100 dtr-col-md dt-text-right',
|
||||||
responsivePriority: 5,
|
responsivePriority: 5,
|
||||||
defaultContent: ''
|
defaultContent: ''
|
||||||
|
|||||||
@@ -1104,6 +1104,10 @@ if (isset($_GET['query'])) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "syncjob_settings":
|
||||||
|
$data = mailbox('get', 'syncjob_settings');
|
||||||
|
process_get_return($data);
|
||||||
|
break;
|
||||||
case "active-user-sieve":
|
case "active-user-sieve":
|
||||||
if (isset($object)) {
|
if (isset($object)) {
|
||||||
$sieve_filter = mailbox('get', 'active_user_sieve', $object);
|
$sieve_filter = mailbox('get', 'active_user_sieve', $object);
|
||||||
@@ -1672,6 +1676,55 @@ if (isset($_GET['query'])) {
|
|||||||
process_search_return($data);
|
process_search_return($data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "syncjob":
|
||||||
|
$table = ['imapsync', 'i'];
|
||||||
|
$primaryKey = 'id';
|
||||||
|
$columns = [
|
||||||
|
['db' => 'id', 'dt' => 2],
|
||||||
|
['db' => 'user2', 'dt' => 3],
|
||||||
|
['db' => 'host1', 'dt' => 4, 'search' => ['where_column' => "CONCAT_WS(' ', `i`.`user1`, `i`.`host1`)"]],
|
||||||
|
['db' => 'last_run', 'dt' => 5],
|
||||||
|
['db' => 'active', 'dt' => 8],
|
||||||
|
];
|
||||||
|
|
||||||
|
if ($_SESSION['mailcow_cc_role'] === 'admin') {
|
||||||
|
$data = SSP::simple($requestDecoded, $pdo, $table, $primaryKey, $columns);
|
||||||
|
} elseif ($_SESSION['mailcow_cc_role'] === 'domainadmin') {
|
||||||
|
$data = SSP::complex($requestDecoded, $pdo, $table, $primaryKey, $columns,
|
||||||
|
'INNER JOIN `mailbox` AS `mb` ON `mb`.`username` = `i`.`user2` ' .
|
||||||
|
'INNER JOIN `domain_admins` AS `da` ON `da`.`domain` = `mb`.`domain`',
|
||||||
|
[
|
||||||
|
'condition' => '`da`.`active` = 1 AND `da`.`username` = :username',
|
||||||
|
'bindings' => ['username' => $_SESSION['mailcow_cc_username']]
|
||||||
|
]);
|
||||||
|
} elseif ($_SESSION['mailcow_cc_role'] === 'user') {
|
||||||
|
$data = SSP::complex($requestDecoded, $pdo, $table, $primaryKey, $columns, null,
|
||||||
|
[
|
||||||
|
'condition' => '`i`.`user2` = :username',
|
||||||
|
'bindings' => ['username' => $_SESSION['mailcow_cc_username']]
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
http_response_code(403);
|
||||||
|
echo json_encode(array(
|
||||||
|
'type' => 'error',
|
||||||
|
'msg' => 'Insufficient permissions'
|
||||||
|
));
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($data['data'])) {
|
||||||
|
$syncjobData = [];
|
||||||
|
foreach ($data['data'] as $row) {
|
||||||
|
if ($details = mailbox('get', 'syncjob_details', $row[2], array('no_log'))) {
|
||||||
|
$syncjobData[] = $details;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$data['data'] = $syncjobData;
|
||||||
|
}
|
||||||
|
|
||||||
|
process_search_return($data);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
http_response_code(404);
|
http_response_code(404);
|
||||||
echo json_encode(array(
|
echo json_encode(array(
|
||||||
@@ -1970,6 +2023,9 @@ if (isset($_GET['query'])) {
|
|||||||
case "syncjob":
|
case "syncjob":
|
||||||
process_edit_return(mailbox('edit', 'syncjob', array_merge(array('id' => $items), $attr)));
|
process_edit_return(mailbox('edit', 'syncjob', array_merge(array('id' => $items), $attr)));
|
||||||
break;
|
break;
|
||||||
|
case "syncjob_settings":
|
||||||
|
process_edit_return(mailbox('edit', 'syncjob_settings', $attr));
|
||||||
|
break;
|
||||||
case "filter":
|
case "filter":
|
||||||
process_edit_return(mailbox('edit', 'filter', array_merge(array('id' => $items), $attr)));
|
process_edit_return(mailbox('edit', 'filter', array_merge(array('id' => $items), $attr)));
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"acl": {
|
||||||
|
"login_as": "E-poçt qutusu istifadəçisi olaraq daxil ol"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -372,6 +372,9 @@
|
|||||||
"spamfilter": "Spamfilter",
|
"spamfilter": "Spamfilter",
|
||||||
"subject": "Betreff",
|
"subject": "Betreff",
|
||||||
"success": "Erfolg",
|
"success": "Erfolg",
|
||||||
|
"syncjobs": "Sync-Jobs",
|
||||||
|
"syncjobs_max_bps": "Globales Bandbreitenlimit (Bytes/s)<br><small>Maximale Transferrate pro Sync-Job in Bytes pro Sekunde. 0 = kein Limit. Wird durch ein pro Sync-Job gesetztes Limit überschrieben.</small>",
|
||||||
|
"syncjobs_max_parallel": "Maximale Anzahl paralleler Sync-Jobs<br><small>Wie viele imapsync-Prozesse dürfen gleichzeitig laufen. 1 = sequentiell (aktuelles Verhalten).</small>",
|
||||||
"sys_mails": "System-E-Mails",
|
"sys_mails": "System-E-Mails",
|
||||||
"task": "Aufgabe",
|
"task": "Aufgabe",
|
||||||
"text": "Text",
|
"text": "Text",
|
||||||
@@ -1200,6 +1203,7 @@
|
|||||||
"template_modified": "Änderungen am Template %s wurden gespeichert",
|
"template_modified": "Änderungen am Template %s wurden gespeichert",
|
||||||
"template_removed": "Template ID %s wurde gelöscht",
|
"template_removed": "Template ID %s wurde gelöscht",
|
||||||
"sogo_profile_reset": "ActiveSync-Gerät des Benutzers %s wurde zurückgesetzt",
|
"sogo_profile_reset": "ActiveSync-Gerät des Benutzers %s wurde zurückgesetzt",
|
||||||
|
"syncjob_settings_saved": "Sync-Job-Einstellungen wurden gespeichert",
|
||||||
"tls_policy_map_entry_deleted": "TLS-Richtlinie mit der ID %s wurde gelöscht",
|
"tls_policy_map_entry_deleted": "TLS-Richtlinie mit der ID %s wurde gelöscht",
|
||||||
"tls_policy_map_entry_saved": "TLS-Richtlinieneintrag \"%s\" wurde gespeichert",
|
"tls_policy_map_entry_saved": "TLS-Richtlinieneintrag \"%s\" wurde gespeichert",
|
||||||
"ui_texts": "Änderungen an UI-Texten",
|
"ui_texts": "Änderungen an UI-Texten",
|
||||||
|
|||||||
@@ -382,6 +382,9 @@
|
|||||||
"spamfilter": "Spam filter",
|
"spamfilter": "Spam filter",
|
||||||
"subject": "Subject",
|
"subject": "Subject",
|
||||||
"success": "Success",
|
"success": "Success",
|
||||||
|
"syncjobs": "Sync jobs",
|
||||||
|
"syncjobs_max_bps": "Global bandwidth limit (bytes/s)<br><small>Maximum transfer rate per sync job in bytes per second. 0 = no limit. Overridden by a per-job limit.</small>",
|
||||||
|
"syncjobs_max_parallel": "Maximum parallel sync jobs<br><small>How many imapsync processes are allowed to run in parallel. 1 = sequential (legacy behavior).</small>",
|
||||||
"sys_mails": "System mails",
|
"sys_mails": "System mails",
|
||||||
"task": "Task",
|
"task": "Task",
|
||||||
"text": "Text",
|
"text": "Text",
|
||||||
@@ -1204,6 +1207,7 @@
|
|||||||
"settings_map_added": "Added settings map entry",
|
"settings_map_added": "Added settings map entry",
|
||||||
"settings_map_removed": "Removed settings map ID %s",
|
"settings_map_removed": "Removed settings map ID %s",
|
||||||
"sogo_profile_reset": "SOGo profile for user %s was reset",
|
"sogo_profile_reset": "SOGo profile for user %s was reset",
|
||||||
|
"syncjob_settings_saved": "Sync job settings have been saved",
|
||||||
"template_added": "Added template %s",
|
"template_added": "Added template %s",
|
||||||
"template_modified": "Changes to template %s have been saved",
|
"template_modified": "Changes to template %s have been saved",
|
||||||
"template_removed": "Template ID %s has been deleted",
|
"template_removed": "Template ID %s has been deleted",
|
||||||
|
|||||||
@@ -111,7 +111,8 @@
|
|||||||
"validation_success": "Validado com sucesso",
|
"validation_success": "Validado com sucesso",
|
||||||
"dry": "Simular sincronização",
|
"dry": "Simular sincronização",
|
||||||
"internal": "Interno",
|
"internal": "Interno",
|
||||||
"internal_info": "Aliases internos são acessíveis apenas a partir do próprio domínio ou alias de domínio."
|
"internal_info": "Aliases internos são acessíveis apenas a partir do próprio domínio ou alias de domínio.",
|
||||||
|
"sender_allowed": "Permitir enviar como este alias"
|
||||||
},
|
},
|
||||||
"admin": {
|
"admin": {
|
||||||
"access": "Acesso",
|
"access": "Acesso",
|
||||||
@@ -151,7 +152,7 @@
|
|||||||
"arrival_time": "Hora de chegada (hora do servidor)",
|
"arrival_time": "Hora de chegada (hora do servidor)",
|
||||||
"authed_user": "Usuário autoritário",
|
"authed_user": "Usuário autoritário",
|
||||||
"ays": "Tem certeza de que deseja continuar?",
|
"ays": "Tem certeza de que deseja continuar?",
|
||||||
"ban_list_info": "Veja uma lista de IPs banidos abaixo: <b>rede (tempo restante de banimento) - [ações]</b>. <br />Os IPs na fila para serem desbanidos serão removidos da lista de banimentos ativos em alguns segundos. <br />Rótulos vermelhos indicam proibições permanentes ativas na lista negra.",
|
"ban_list_info": "Veja abaixo a lista de IPs banidos: <b>rede (tempo restante do banimento) - [ações]</b>.<br />IPs na fila para serem desbanidos serão removidos da lista de banimentos ativos em alguns segundos.<br />Rótulos vermelhos indicam banimentos permanentes ativos na lista de bloqueio.",
|
||||||
"change_logo": "Alterar logotipo",
|
"change_logo": "Alterar logotipo",
|
||||||
"logo_normal_label": "Normal",
|
"logo_normal_label": "Normal",
|
||||||
"logo_dark_label": "Invertido para o modo escuro",
|
"logo_dark_label": "Invertido para o modo escuro",
|
||||||
@@ -188,9 +189,9 @@
|
|||||||
"excludes": "Exclui esses destinatários",
|
"excludes": "Exclui esses destinatários",
|
||||||
"f2b_ban_time": "Tempo (s) de proibição",
|
"f2b_ban_time": "Tempo (s) de proibição",
|
||||||
"f2b_ban_time_increment": "O tempo de banimento é incrementado com cada banimento",
|
"f2b_ban_time_increment": "O tempo de banimento é incrementado com cada banimento",
|
||||||
"f2b_blacklist": "Redes/hosts na lista negra",
|
"f2b_blacklist": "Redes/hosts na lista de bloqueio",
|
||||||
"f2b_filter": "Filtros Regex",
|
"f2b_filter": "Filtros Regex",
|
||||||
"f2b_list_info": "Um host ou rede na lista negra sempre superará uma entidade na lista branca. <b>As atualizações da lista levarão alguns segundos para serem aplicadas.</b>",
|
"f2b_list_info": "Um host ou rede na lista de bloqueio sempre terá prioridade sobre uma entidade na lista de permissões. <b>As atualizações das listas levarão alguns segundos para serem aplicadas.</b>",
|
||||||
"f2b_manage_external": "Gerenciar Fail2Ban externamente",
|
"f2b_manage_external": "Gerenciar Fail2Ban externamente",
|
||||||
"f2b_manage_external_info": "O Fail2ban ainda manterá a lista de banimentos, mas não definirá ativamente regras para bloquear o tráfego. Use a lista de banimento gerada abaixo para bloquear externamente o tráfego.",
|
"f2b_manage_external_info": "O Fail2ban ainda manterá a lista de banimentos, mas não definirá ativamente regras para bloquear o tráfego. Use a lista de banimento gerada abaixo para bloquear externamente o tráfego.",
|
||||||
"f2b_max_attempts": "Máximo de tentativas",
|
"f2b_max_attempts": "Máximo de tentativas",
|
||||||
@@ -200,7 +201,7 @@
|
|||||||
"f2b_parameters": "Parâmetros do Fail2ban",
|
"f2b_parameters": "Parâmetros do Fail2ban",
|
||||||
"f2b_regex_info": "Registros considerados: SoGo, Postfix, Dovecot, PHP-FPM.",
|
"f2b_regex_info": "Registros considerados: SoGo, Postfix, Dovecot, PHP-FPM.",
|
||||||
"f2b_retry_window": "Repita a (s) janela (s) para o máximo de tentativas",
|
"f2b_retry_window": "Repita a (s) janela (s) para o máximo de tentativas",
|
||||||
"f2b_whitelist": "Redes/hosts incluídos na lista branca",
|
"f2b_whitelist": "Redes/hosts na lista de permissões",
|
||||||
"filter_table": "Tabela de filtros",
|
"filter_table": "Tabela de filtros",
|
||||||
"forwarding_hosts": "Anfitriões de encaminhamento",
|
"forwarding_hosts": "Anfitriões de encaminhamento",
|
||||||
"forwarding_hosts_add_hint": "Você pode especificar endereços IPv4/IPv6, redes em notação CIDR, nomes de host (que serão resolvidos para endereços IP) ou nomes de domínio (que serão resolvidos para endereços IP consultando registros SPF ou, na ausência deles, registros MX).",
|
"forwarding_hosts_add_hint": "Você pode especificar endereços IPv4/IPv6, redes em notação CIDR, nomes de host (que serão resolvidos para endereços IP) ou nomes de domínio (que serão resolvidos para endereços IP consultando registros SPF ou, na ausência deles, registros MX).",
|
||||||
@@ -320,8 +321,8 @@
|
|||||||
"rspamd_com_settings": "Um nome de configuração será gerado automaticamente, veja os exemplos de predefinições abaixo. Para obter mais detalhes, consulte a documentação <a href=\"https://rspamd.com/doc/configuration/settings.html#settings-structure\" target=\"_blank\">do Rspamd</a>",
|
"rspamd_com_settings": "Um nome de configuração será gerado automaticamente, veja os exemplos de predefinições abaixo. Para obter mais detalhes, consulte a documentação <a href=\"https://rspamd.com/doc/configuration/settings.html#settings-structure\" target=\"_blank\">do Rspamd</a>",
|
||||||
"rspamd_global_filters": "Mapas de filtro globais",
|
"rspamd_global_filters": "Mapas de filtro globais",
|
||||||
"rspamd_global_filters_agree": "Eu vou ter cuidado!",
|
"rspamd_global_filters_agree": "Eu vou ter cuidado!",
|
||||||
"rspamd_global_filters_info": "Os mapas de filtros globais contêm diferentes tipos de listas negras e brancas globais.",
|
"rspamd_global_filters_info": "Os mapas de filtros globais contêm diferentes tipos de listas globais de bloqueio e de permissões.",
|
||||||
"rspamd_global_filters_regex": "Seus nomes explicam seu propósito. <code>Todo o conteúdo deve conter uma expressão regular válida no formato “/padrão/opções” (por exemplo, /. + @domain\\ .tld/i</code>). <br>\r\n Embora verificações rudimentares estejam sendo executadas em cada linha de regex, a funcionalidade do Rspamd pode ser interrompida se não conseguir ler a sintaxe corretamente. <br>\r\n O Rspamd tentará ler o conteúdo do mapa quando alterado. Se você tiver problemas, <a href=\"\" data-toggle=\"modal\" data-container=\"rspamd-mailcow\" data-target=\"#RestartContainer\">reinicie o Rspamd</a> para forçar o recarregamento do mapa. <br>Os elementos da lista negra são excluídos da quarentena.",
|
"rspamd_global_filters_regex": "Os nomes explicam sua finalidade. Todo o conteúdo deve conter uma expressão regular válida no formato \"/padrão/opções\" (por exemplo, <code>/.[+@domain.tld](mailto:+@domain.tld)/i</code>).<br>\nEmbora verificações básicas sejam executadas em cada linha de regex, a funcionalidade do Rspamd pode ser comprometida se ele não conseguir ler a sintaxe corretamente.<br>\nO Rspamd tentará ler o conteúdo do mapa quando ele for alterado. Se você tiver problemas, <a href=\"\" data-toggle=\"modal\" data-container=\"rspamd-mailcow\" data-target=\"#RestartContainer\">reinicie o Rspamd</a> para forçar o recarregamento do mapa.<br>Elementos na lista de bloqueio são excluídos da quarentena.",
|
||||||
"rspamd_settings_map": "Mapa de configurações do Rspamd",
|
"rspamd_settings_map": "Mapa de configurações do Rspamd",
|
||||||
"sal_level": "Nível de humor",
|
"sal_level": "Nível de humor",
|
||||||
"save": "Salvar alterações",
|
"save": "Salvar alterações",
|
||||||
@@ -556,7 +557,9 @@
|
|||||||
"mode_invalid": "Modo %s é inválido",
|
"mode_invalid": "Modo %s é inválido",
|
||||||
"mx_invalid": "Registro MX %s é inválido",
|
"mx_invalid": "Registro MX %s é inválido",
|
||||||
"required_data_missing": "Dados obrigatórios %s estão ausentes",
|
"required_data_missing": "Dados obrigatórios %s estão ausentes",
|
||||||
"version_invalid": "Versão %s é inválida"
|
"version_invalid": "Versão %s é inválida",
|
||||||
|
"tfa_removal_blocked": "A autenticação de dois fatores não pode ser removida, pois é obrigatória para a sua conta.",
|
||||||
|
"quarantine_category_invalid": "A categoria da quarentena deve ser uma das seguintes: add_header, reject, all"
|
||||||
},
|
},
|
||||||
"datatables": {
|
"datatables": {
|
||||||
"collapse_all": "Recolher tudo",
|
"collapse_all": "Recolher tudo",
|
||||||
@@ -746,13 +749,13 @@
|
|||||||
"sieve_desc": "Breve descrição",
|
"sieve_desc": "Breve descrição",
|
||||||
"sieve_type": "Tipo de filtro",
|
"sieve_type": "Tipo de filtro",
|
||||||
"skipcrossduplicates": "Ignore mensagens duplicadas entre pastas (primeiro a chegar, primeiro a ser servido)",
|
"skipcrossduplicates": "Ignore mensagens duplicadas entre pastas (primeiro a chegar, primeiro a ser servido)",
|
||||||
"sogo_access": "Encaminhamento direto para o SOGoo",
|
"sogo_access": "Encaminhamento direto para o SOGo",
|
||||||
"sogo_access_info": "Depois de fazer login, o usuário é automaticamente redirecionado para o SOGo.",
|
"sogo_access_info": "Após o login, o usuário é automaticamente redirecionado para o SOGo.",
|
||||||
"sogo_visible": "O alias é visível no SoGo",
|
"sogo_visible": "O alias é visível no SoGo",
|
||||||
"sogo_visible_info": "Essa opção afeta somente objetos, que podem ser exibidos no SoGo (endereços de alias compartilhados ou não compartilhados apontando para pelo menos uma mailbox local). Se estiver oculto, um alias não aparecerá como remetente selecionável no SoGo.",
|
"sogo_visible_info": "Essa opção afeta somente objetos, que podem ser exibidos no SoGo (endereços de alias compartilhados ou não compartilhados apontando para pelo menos uma mailbox local). Se estiver oculto, um alias não aparecerá como remetente selecionável no SoGo.",
|
||||||
"spam_alias": "Crie ou altere endereços de alias com limite de tempo",
|
"spam_alias": "Crie ou altere endereços de alias com limite de tempo",
|
||||||
"spam_filter": "Filtro de spam",
|
"spam_filter": "Filtro de spam",
|
||||||
"spam_policy": "Adicionar ou remover itens da lista branca/negra",
|
"spam_policy": "Adicionar ou remover itens da lista de permissões/bloqueio",
|
||||||
"spam_score": "Defina uma pontuação de spam personalizada",
|
"spam_score": "Defina uma pontuação de spam personalizada",
|
||||||
"subfolder2": "Sincronizar na subpasta no destino <br><small>(vazio = não usar subpasta</small>)",
|
"subfolder2": "Sincronizar na subpasta no destino <br><small>(vazio = não usar subpasta</small>)",
|
||||||
"syncjob": "Editar tarefa de sincronização",
|
"syncjob": "Editar tarefa de sincronização",
|
||||||
@@ -781,7 +784,9 @@
|
|||||||
"mta_sts_max_age_info": "Tempo em segundos que servidores de email de recepção podem armazenar esta política em cache até buscar novamente.",
|
"mta_sts_max_age_info": "Tempo em segundos que servidores de email de recepção podem armazenar esta política em cache até buscar novamente.",
|
||||||
"mta_sts_mx": "Servidor MX",
|
"mta_sts_mx": "Servidor MX",
|
||||||
"mta_sts_mx_info": "Permite envio apenas para nomes de host de servidor de email explicitamente listados; o MTA de envio verifica se o nome do host DNS MX corresponde à lista de políticas e permite entrega apenas com certificado TLS válido (protege contra MITM).",
|
"mta_sts_mx_info": "Permite envio apenas para nomes de host de servidor de email explicitamente listados; o MTA de envio verifica se o nome do host DNS MX corresponde à lista de políticas e permite entrega apenas com certificado TLS válido (protege contra MITM).",
|
||||||
"mta_sts_mx_notice": "Múltiplos servidores MX podem ser especificados (separados por vírgulas)."
|
"mta_sts_mx_notice": "Múltiplos servidores MX podem ser especificados (separados por vírgulas).",
|
||||||
|
"sender_allowed": "Permitir enviar como este alias",
|
||||||
|
"sender_allowed_info": "Se desativado, este alias poderá apenas receber e-mails. Use a ACL de remetente para substituir essa configuração e conceder a caixas de correio específicas permissão para enviar."
|
||||||
},
|
},
|
||||||
"fido2": {
|
"fido2": {
|
||||||
"confirm": "Confirme",
|
"confirm": "Confirme",
|
||||||
@@ -970,7 +975,7 @@
|
|||||||
"recipient_map_new": "Novo destinatário",
|
"recipient_map_new": "Novo destinatário",
|
||||||
"recipient_map_new_info": "O destino do mapa do destinatário deve ser um endereço de e-mail válido ou um nome de domínio.",
|
"recipient_map_new_info": "O destino do mapa do destinatário deve ser um endereço de e-mail válido ou um nome de domínio.",
|
||||||
"recipient_map_old": "Destinatário original",
|
"recipient_map_old": "Destinatário original",
|
||||||
"recipient_map_old_info": "O destino original do mapa de um destinatário deve ser um endereço de e-mail válido ou um nome de domínio.",
|
"recipient_map_old_info": "O destino original do mapa de destinatário deve ser um endereço de e-mail válido ou um nome de domínio.",
|
||||||
"recipient_maps": "Mapas de destinatários",
|
"recipient_maps": "Mapas de destinatários",
|
||||||
"relay_all": "Retransmita todos os destinatários",
|
"relay_all": "Retransmita todos os destinatários",
|
||||||
"relay_unknown": "Retransmitir mailboxes desconhecidas",
|
"relay_unknown": "Retransmitir mailboxes desconhecidas",
|
||||||
@@ -1061,7 +1066,7 @@
|
|||||||
"notified": "Notificado",
|
"notified": "Notificado",
|
||||||
"qhandler_success": "Solicitação enviada com sucesso para o sistema. Agora você pode fechar a janela.",
|
"qhandler_success": "Solicitação enviada com sucesso para o sistema. Agora você pode fechar a janela.",
|
||||||
"qid": "Respand AID",
|
"qid": "Respand AID",
|
||||||
"qinfo": "O sistema de quarentena salvará as mensagens rejeitadas no banco de dados (o remetente <em>não</em> terá a impressão de uma mensagem entregue), bem como as mensagens, que são entregues como cópia na pasta Lixo eletrônico de uma mailbox.\n <br>“Aprenda como spam e exclua” aprenderá uma mensagem como spam por meio do Teorema de Bayes e também calculará hashes difusos para negar mensagens semelhantes no futuro.\n <br>Esteja ciente de que aprender várias mensagens pode ser demorado, dependendo do seu sistema. <br>Os elementos da lista negra são excluídos da quarentena.",
|
"qinfo": "O sistema de quarentena irá salvar no banco de dados os e-mails rejeitados (o remetente <em>não</em> terá a impressão de que o e-mail foi entregue), bem como os e-mails que são entregues como cópia na pasta de spam de uma mailbox.\n<br>“Aprender como spam e excluir” irá classificar a mensagem como spam por meio do Teorema de Bayes e também calcular hashes fuzzy para bloquear mensagens semelhantes no futuro.\n<br>Esteja ciente de que o aprendizado de múltiplas mensagens pode, dependendo do seu sistema, levar tempo. <br>Elementos na lista de bloqueio são excluídos da quarentena.",
|
||||||
"qitem": "Item de quarentena",
|
"qitem": "Item de quarentena",
|
||||||
"quarantine": "Quarentena",
|
"quarantine": "Quarentena",
|
||||||
"quick_actions": "Ações",
|
"quick_actions": "Ações",
|
||||||
@@ -1237,7 +1242,12 @@
|
|||||||
"webauthn": "Autenticação WebAuthn",
|
"webauthn": "Autenticação WebAuthn",
|
||||||
"waiting_usb_auth": "<i>Aguardando o dispositivo USB...</i> <br><br>Toque no botão no seu dispositivo USB agora.",
|
"waiting_usb_auth": "<i>Aguardando o dispositivo USB...</i> <br><br>Toque no botão no seu dispositivo USB agora.",
|
||||||
"waiting_usb_register": "<i>Aguardando o dispositivo USB...</i> <br><br>Digite sua senha acima e confirme seu registro tocando no botão no seu dispositivo USB.",
|
"waiting_usb_register": "<i>Aguardando o dispositivo USB...</i> <br><br>Digite sua senha acima e confirme seu registro tocando no botão no seu dispositivo USB.",
|
||||||
"yubi_otp": "Autenticação Yubico OTP"
|
"yubi_otp": "Autenticação Yubico OTP",
|
||||||
|
"force_tfa": "Forçar o cadastro de 2FA no login",
|
||||||
|
"force_tfa_info": "O usuário será obrigado a configurar a autenticação de dois fatores antes de acessar o painel.",
|
||||||
|
"setup_title": "Autenticação de Dois Fatores Obrigatória",
|
||||||
|
"setup_required": "Sua conta exige autenticação de dois fatores. Configure um método de 2FA para continuar.",
|
||||||
|
"cancel_setup": "Cancelar e sair"
|
||||||
},
|
},
|
||||||
"user": {
|
"user": {
|
||||||
"action": "Ação",
|
"action": "Ação",
|
||||||
@@ -1276,7 +1286,7 @@
|
|||||||
"delete_ays": "Confirme o processo de exclusão.",
|
"delete_ays": "Confirme o processo de exclusão.",
|
||||||
"direct_aliases": "Endereços de alias diretos",
|
"direct_aliases": "Endereços de alias diretos",
|
||||||
"direct_aliases_desc": "Os endereços de alias diretos são afetados pelo filtro de spam e pelas configurações da política TLS.",
|
"direct_aliases_desc": "Os endereços de alias diretos são afetados pelo filtro de spam e pelas configurações da política TLS.",
|
||||||
"direct_protocol_access": "Esse usuário da mailbox tem <b>acesso externo direto</b> aos seguintes protocolos e aplicativos. Essa configuração é controlada pelo administrador. As senhas de aplicativos podem ser criadas para conceder acesso a protocolos e aplicativos individuais. <br>O botão “Login no webmail” fornece login único no SoGo e está sempre disponível.",
|
"direct_protocol_access": "Este usuário da mailbox possui <b>acesso direto e externo</b> aos seguintes protocolos e aplicações. Esta configuração é controlada pelo seu administrador. Senhas de aplicativo podem ser criadas para conceder acesso a protocolos e aplicações específicos.<br>O botão “Webmail” fornece login único (SSO) para o SOGo e está sempre disponível.",
|
||||||
"eas_reset": "Redefinir o cache do dispositivo ActiveSync",
|
"eas_reset": "Redefinir o cache do dispositivo ActiveSync",
|
||||||
"eas_reset_help": "Em muitos casos, uma redefinição do cache do dispositivo ajudará a recuperar um perfil quebrado do ActiveSync. <br><b>Atenção:</b> Todos os elementos serão baixados novamente!",
|
"eas_reset_help": "Em muitos casos, uma redefinição do cache do dispositivo ajudará a recuperar um perfil quebrado do ActiveSync. <br><b>Atenção:</b> Todos os elementos serão baixados novamente!",
|
||||||
"eas_reset_now": "Reinicie agora",
|
"eas_reset_now": "Reinicie agora",
|
||||||
@@ -1352,12 +1362,12 @@
|
|||||||
"sogo_profile_reset": "Redefinir perfil SoGo",
|
"sogo_profile_reset": "Redefinir perfil SoGo",
|
||||||
"sogo_profile_reset_help": "Isso destruirá o perfil SoGo de um usuário e <b>excluirá todos os dados de contato e calendário irrecuperáveis</b>.",
|
"sogo_profile_reset_help": "Isso destruirá o perfil SoGo de um usuário e <b>excluirá todos os dados de contato e calendário irrecuperáveis</b>.",
|
||||||
"sogo_profile_reset_now": "Redefina o perfil agora",
|
"sogo_profile_reset_now": "Redefina o perfil agora",
|
||||||
"spam_aliases": "Aliases de e-mail temporários",
|
"spam_aliases": "Aliases de e-mail de spam",
|
||||||
"spam_score_reset": "Redefinir para o padrão do servidor",
|
"spam_score_reset": "Redefinir para o padrão do servidor",
|
||||||
"spamfilter": "Filtro de spam",
|
"spamfilter": "Filtro de spam",
|
||||||
"spamfilter_behavior": "Avaliação",
|
"spamfilter_behavior": "Avaliação",
|
||||||
"spamfilter_bl": "Lista negra",
|
"spamfilter_bl": "Lista de bloqueio",
|
||||||
"spamfilter_bl_desc": "Endereços de e-mail na lista negra para <b>sempre</b> serem classificados como spam e rejeitados. E-mails rejeitados <b>não</b> serão copiados para a quarentena. Podem ser usados curingas. Um filtro só é aplicado a aliases diretos (aliases com uma única caixa de correio de destino), excluindo aliases abrangentes e a própria mailbox.",
|
"spamfilter_bl_desc": "Endereços de e-mail na lista de bloqueio para <b>sempre</b> classificar como spam e rejeitados. E-mails rejeitados <b>não</b> serão copiados para a quarentena. Coringas podem ser utilizados. O filtro é aplicado apenas a aliases diretos (aliases com uma única mailbox de destino), excluindo aliases catch-all e a própria mailbox.",
|
||||||
"spamfilter_default_score": "Valores padrão",
|
"spamfilter_default_score": "Valores padrão",
|
||||||
"spamfilter_green": "Verde: esta mensagem não é spam",
|
"spamfilter_green": "Verde: esta mensagem não é spam",
|
||||||
"spamfilter_hint": "O primeiro valor descreve a “pontuação baixa de spam”, o segundo representa a “alta pontuação de spam”.",
|
"spamfilter_hint": "O primeiro valor descreve a “pontuação baixa de spam”, o segundo representa a “alta pontuação de spam”.",
|
||||||
@@ -1368,8 +1378,8 @@
|
|||||||
"spamfilter_table_empty": "Não há dados para exibir",
|
"spamfilter_table_empty": "Não há dados para exibir",
|
||||||
"spamfilter_table_remove": "remover",
|
"spamfilter_table_remove": "remover",
|
||||||
"spamfilter_table_rule": "Regra",
|
"spamfilter_table_rule": "Regra",
|
||||||
"spamfilter_wl": "Lista branca",
|
"spamfilter_wl": "Lista de permissões",
|
||||||
"spamfilter_wl_desc": "Os endereços de e-mail incluídos na lista branca são programados para <b>nunca</b> serem classificados como spam. Podem ser usados curingas. Um filtro só é aplicado a aliases diretos (aliases com uma única mailbox de destino), excluindo aliases abrangentes e a própria mailbox.",
|
"spamfilter_wl_desc": "Endereços de e-mail na lista de permissões são configurados para <b>nunca</b> serem classificados como spam. Coringas podem ser utilizados. O filtro é aplicado apenas a aliases diretos (aliases com uma única mailbox de destino), excluindo aliases catch-all e a própria mailbox.",
|
||||||
"spamfilter_yellow": "Amarelo: esta mensagem pode ser spam, será marcada como spam e movida para sua pasta de lixo eletrônico",
|
"spamfilter_yellow": "Amarelo: esta mensagem pode ser spam, será marcada como spam e movida para sua pasta de lixo eletrônico",
|
||||||
"status": "Status",
|
"status": "Status",
|
||||||
"sync_jobs": "Trabalhos de sincronização",
|
"sync_jobs": "Trabalhos de sincronização",
|
||||||
@@ -1408,7 +1418,11 @@
|
|||||||
"authentication": "Autenticação",
|
"authentication": "Autenticação",
|
||||||
"overview": "Visão geral",
|
"overview": "Visão geral",
|
||||||
"protocols": "Protocolos",
|
"protocols": "Protocolos",
|
||||||
"tfa_info": "A autenticação de dois fatores ajuda a proteger sua conta. Se você habilitá-la, precisará de senhas de aplicativo para fazer login em aplicativos ou serviços que não suportam autenticação de dois fatores (por exemplo, clientes de email)."
|
"tfa_info": "A autenticação de dois fatores ajuda a proteger sua conta. Se você habilitá-la, precisará de senhas de aplicativo para fazer login em aplicativos ou serviços que não suportam autenticação de dois fatores (por exemplo, clientes de email).",
|
||||||
|
"expire_never": "Nunca expirar",
|
||||||
|
"forever": "Para sempre",
|
||||||
|
"pw_update_required": "Sua conta exige a alteração de senha. Defina uma nova senha para continuar.",
|
||||||
|
"spam_aliases_info": "Um alias de spam é um endereço de e-mail temporário que pode ser usado para proteger endereços de e-mail reais. <br>Opcionalmente, pode-se definir um tempo de expiração para que o alias seja automaticamente desativado após o período definido, descartando efetivamente endereços que tenham sido abusados ou vazados."
|
||||||
},
|
},
|
||||||
"warning": {
|
"warning": {
|
||||||
"cannot_delete_self": "Não é possível excluir o usuário conectado",
|
"cannot_delete_self": "Não é possível excluir o usuário conectado",
|
||||||
|
|||||||
@@ -558,7 +558,8 @@
|
|||||||
"mode_invalid": "Način %s ni veljaven",
|
"mode_invalid": "Način %s ni veljaven",
|
||||||
"mx_invalid": "Zapis MX %s je neveljaven",
|
"mx_invalid": "Zapis MX %s je neveljaven",
|
||||||
"version_invalid": "Različica %s je neveljavna",
|
"version_invalid": "Različica %s je neveljavna",
|
||||||
"tfa_removal_blocked": "Dvofaktorske avtentikacije ni mogoče odstraniti, ker je obvezna za vaš račun."
|
"tfa_removal_blocked": "Dvofaktorske avtentikacije ni mogoče odstraniti, ker je obvezna za vaš račun.",
|
||||||
|
"quarantine_category_invalid": "Kategorija karantene mora biti ena od: add_header, reject, all"
|
||||||
},
|
},
|
||||||
"debug": {
|
"debug": {
|
||||||
"containers_info": "Informacije o zabojniku",
|
"containers_info": "Informacije o zabojniku",
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
<li><button class="dropdown-item" data-bs-target="#tab-config-fwdhosts" aria-selected="false" aria-controls="tab-config-fwdhosts" role="tab" data-bs-toggle="tab">{{ lang.admin.forwarding_hosts }}</button></li>
|
<li><button class="dropdown-item" data-bs-target="#tab-config-fwdhosts" aria-selected="false" aria-controls="tab-config-fwdhosts" role="tab" data-bs-toggle="tab">{{ lang.admin.forwarding_hosts }}</button></li>
|
||||||
<li><button class="dropdown-item" data-bs-target="#tab-config-f2b" aria-selected="false" aria-controls="tab-config-f2b" role="tab" data-bs-toggle="tab">{{ lang.admin.f2b_parameters }}</button></li>
|
<li><button class="dropdown-item" data-bs-target="#tab-config-f2b" aria-selected="false" aria-controls="tab-config-f2b" role="tab" data-bs-toggle="tab">{{ lang.admin.f2b_parameters }}</button></li>
|
||||||
<li><button class="dropdown-item" data-bs-target="#tab-config-quarantine" aria-selected="false" aria-controls="tab-config-quarantine" role="tab" data-bs-toggle="tab">{{ lang.admin.quarantine }}</button></li>
|
<li><button class="dropdown-item" data-bs-target="#tab-config-quarantine" aria-selected="false" aria-controls="tab-config-quarantine" role="tab" data-bs-toggle="tab">{{ lang.admin.quarantine }}</button></li>
|
||||||
|
<li><button class="dropdown-item" data-bs-target="#tab-config-syncjobs" aria-selected="false" aria-controls="tab-config-syncjobs" role="tab" data-bs-toggle="tab">{{ lang.admin.syncjobs }}</button></li>
|
||||||
<li><button class="dropdown-item" data-bs-target="#tab-config-quota" aria-selected="false" aria-controls="tab-config-quota" role="tab" data-bs-toggle="tab">{{ lang.admin.quota_notifications }}</button></li>
|
<li><button class="dropdown-item" data-bs-target="#tab-config-quota" aria-selected="false" aria-controls="tab-config-quota" role="tab" data-bs-toggle="tab">{{ lang.admin.quota_notifications }}</button></li>
|
||||||
<li><button class="dropdown-item" data-bs-target="#tab-config-rsettings" aria-selected="false" aria-controls="tab-config-rsettings" role="tab" data-bs-toggle="tab">{{ lang.admin.rspamd_settings_map }}</button></li>
|
<li><button class="dropdown-item" data-bs-target="#tab-config-rsettings" aria-selected="false" aria-controls="tab-config-rsettings" role="tab" data-bs-toggle="tab">{{ lang.admin.rspamd_settings_map }}</button></li>
|
||||||
<li><button class="dropdown-item" data-bs-target="#tab-config-password-settings" aria-selected="false" aria-controls="tab-config-password-settings" role="tab" data-bs-toggle="tab">{{ lang.admin.password_settings }}</button></li>
|
<li><button class="dropdown-item" data-bs-target="#tab-config-password-settings" aria-selected="false" aria-controls="tab-config-password-settings" role="tab" data-bs-toggle="tab">{{ lang.admin.password_settings }}</button></li>
|
||||||
@@ -50,6 +51,7 @@
|
|||||||
{% include 'admin/tab-config-fwdhosts.twig' %}
|
{% include 'admin/tab-config-fwdhosts.twig' %}
|
||||||
{% include 'admin/tab-config-f2b.twig' %}
|
{% include 'admin/tab-config-f2b.twig' %}
|
||||||
{% include 'admin/tab-config-quarantine.twig' %}
|
{% include 'admin/tab-config-quarantine.twig' %}
|
||||||
|
{% include 'admin/tab-config-syncjobs.twig' %}
|
||||||
{% include 'admin/tab-config-quota.twig' %}
|
{% include 'admin/tab-config-quota.twig' %}
|
||||||
{% include 'admin/tab-config-rsettings.twig' %}
|
{% include 'admin/tab-config-rsettings.twig' %}
|
||||||
{% include 'admin/tab-config-customize.twig' %}
|
{% include 'admin/tab-config-customize.twig' %}
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
<div class="tab-pane fade" id="tab-config-syncjobs" role="tabpanel" aria-labelledby="tab-config-syncjobs">
|
||||||
|
<div class="card mb-4">
|
||||||
|
<div class="card-header d-flex fs-5">
|
||||||
|
<button class="btn d-md-none flex-grow-1 text-start" data-bs-target="#collapse-tab-config-syncjobs" data-bs-toggle="collapse" aria-controls="collapse-tab-config-syncjobs">
|
||||||
|
{{ lang.admin.syncjobs }}
|
||||||
|
</button>
|
||||||
|
<span class="d-none d-md-block">{{ lang.admin.syncjobs }}</span>
|
||||||
|
</div>
|
||||||
|
<div id="collapse-tab-config-syncjobs" class="card-body collapse" data-bs-parent="#admin-content">
|
||||||
|
<form class="form-horizontal" data-id="syncjob_settings" role="form" method="post">
|
||||||
|
<div class="row mb-4">
|
||||||
|
<label class="col-sm-4 control-label text-sm-end" for="syncjobs_max_parallel">{{ lang.admin.syncjobs_max_parallel|raw }}</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input type="number" class="form-control" id="syncjobs_max_parallel" name="max_parallel" value="{{ sj_data.max_parallel }}" min="1" max="50" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-4">
|
||||||
|
<label class="col-sm-4 control-label text-sm-end" for="syncjobs_max_bps">{{ lang.admin.syncjobs_max_bps|raw }}</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input type="number" class="form-control" id="syncjobs_max_bps" name="max_bps" value="{{ sj_data.max_bps }}" min="0">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-sm d-block d-sm-inline btn-success" data-action="edit_selected" data-item="self" data-id="syncjob_settings" data-api-url='edit/syncjob_settings' href="#"><i class="bi bi-check-lg"></i> {{ lang.admin.save }}</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
+1
-1
@@ -252,7 +252,7 @@ services:
|
|||||||
- sogo
|
- sogo
|
||||||
|
|
||||||
dovecot-mailcow:
|
dovecot-mailcow:
|
||||||
image: ghcr.io/mailcow/dovecot:2.3.21.1-2
|
image: ghcr.io/mailcow/dovecot:2.3.21.1-3
|
||||||
depends_on:
|
depends_on:
|
||||||
- mysql-mailcow
|
- mysql-mailcow
|
||||||
- netfilter-mailcow
|
- netfilter-mailcow
|
||||||
|
|||||||
Reference in New Issue
Block a user