NobGit
public nobgit read

NobMail

Based on mailcow: dockerized

Languages

Repository composition by tracked source files.

PHP
PHP 49% JavaScript 35% HTML 9% CSS 4% Shell 2% Python 1% Lua 0% Perl 0% Ruby 0% SCSS 0%
Create file Wiki Documentation
Clone
https://nobgit.com/orgs/nobgit/nobmail.git
ssh://[email protected]:2222/orgs/nobgit/nobmail.git

Commit

Merge remote-tracking branch 'origin/staging' into nightly

9542698e
FreddleSpl0it <[email protected]> 1 year, 8 months ago
.github/workflows/check_prs_if_on_staging.yml      |    2 +-
 .gitignore                                         |    1 +
 data/Dockerfiles/dockerapi/main.py                 |    8 +-
 data/Dockerfiles/dockerapi/modules/DockerApi.py    |  145 +-
 data/Dockerfiles/dovecot/docker-entrypoint.sh      |   19 +-
 data/Dockerfiles/phpfpm/Dockerfile                 |    8 +-
 data/Dockerfiles/postfix/docker-entrypoint.sh      |   11 +
 data/Dockerfiles/rspamd/Dockerfile                 |    4 +-
 data/Dockerfiles/sogo/Dockerfile                   |    5 +-
 data/conf/postfix/main.cf                          |    2 +
 data/conf/postfix/master.cf                        |    2 +-
 data/conf/postfix/postscreen_access.cidr           |   61 +-
 data/conf/rspamd/local.d/mime_types.conf           |   74 +-
 data/conf/rspamd/local.d/options.inc               |    1 +
 data/web/inc/functions.mailbox.inc.php             |  309 ++-
 data/web/inc/lib/composer.lock                     |  123 +-
 .../inc/lib/vendor/composer/autoload_classmap.php  |    3 +-
 .../web/inc/lib/vendor/composer/autoload_files.php |    6 +
 data/web/inc/lib/vendor/composer/autoload_psr4.php |    1 +
 .../inc/lib/vendor/composer/autoload_static.php    |  104 +-
 data/web/inc/lib/vendor/composer/installed.json    |  130 +-
 data/web/inc/lib/vendor/composer/installed.php     |   25 +-
 .../symfony/deprecation-contracts/composer.json    |    2 +-
 .../inc/lib/vendor/symfony/polyfill-php81/LICENSE  |   19 +
 .../lib/vendor/symfony/polyfill-php81/Php81.php    |   37 +
 .../lib/vendor/symfony/polyfill-php81/README.md    |   18 +
 .../Resources/stubs/CURLStringFile.php             |   51 +
 .../Resources/stubs/ReturnTypeWillChange.php       |   20 +
 .../vendor/symfony/polyfill-php81/bootstrap.php    |   28 +
 .../vendor/symfony/polyfill-php81/composer.json    |   33 +
 data/web/inc/lib/vendor/twig/twig/.editorconfig    |   18 -
 data/web/inc/lib/vendor/twig/twig/.gitattributes   |    4 -
 .../lib/vendor/twig/twig/.github/workflows/ci.yml  |  149 --
 .../twig/twig/.github/workflows/documentation.yml  |   64 -
 data/web/inc/lib/vendor/twig/twig/.gitignore       |    6 -
 .../lib/vendor/twig/twig/.php-cs-fixer.dist.php    |   20 -
 data/web/inc/lib/vendor/twig/twig/CHANGELOG        |  177 +-
 data/web/inc/lib/vendor/twig/twig/LICENSE          |    2 +-
 data/web/inc/lib/vendor/twig/twig/README.rst       |    2 +-
 data/web/inc/lib/vendor/twig/twig/composer.json    |   21 +-
 .../vendor/twig/twig/src/AbstractTwigCallable.php  |  136 ++
 .../src/Attribute/FirstClassTwigCallableReady.php  |   20 +
 .../vendor/twig/twig/src/Attribute/YieldReady.php  |   20 +
 .../lib/vendor/twig/twig/src/Cache/ChainCache.php  |   79 +
 .../vendor/twig/twig/src/Cache/FilesystemCache.php |    8 +-
 .../twig/src/Cache/ReadOnlyFilesystemCache.php     |   25 +
 data/web/inc/lib/vendor/twig/twig/src/Compiler.php |   69 +-
 .../inc/lib/vendor/twig/twig/src/Environment.php   |  123 +-
 .../inc/lib/vendor/twig/twig/src/Error/Error.php   |   18 +-
 .../lib/vendor/twig/twig/src/Error/SyntaxError.php |    4 +-
 .../lib/vendor/twig/twig/src/ExpressionParser.php  |  400 +--
 .../twig/twig/src/Extension/AbstractExtension.php  |    2 +-
 .../twig/twig/src/Extension/CoreExtension.php      | 2553 +++++++++++---------
 .../twig/twig/src/Extension/DebugExtension.php     |   60 +-
 .../twig/twig/src/Extension/EscaperExtension.php   |  384 +--
 .../twig/twig/src/Extension/ExtensionInterface.php |    7 +
 .../twig/twig/src/Extension/GlobalsInterface.php   |    8 +-
 .../twig/twig/src/Extension/OptimizerExtension.php |    8 +-
 .../twig/twig/src/Extension/SandboxExtension.php   |   34 +-
 .../twig/twig/src/Extension/StagingExtension.php   |    8 +-
 .../twig/src/Extension/StringLoaderExtension.php   |   38 +-
 .../twig/src/Extension/YieldNotReadyExtension.php  |   30 +
 .../inc/lib/vendor/twig/twig/src/ExtensionSet.php  |  101 +-
 .../twig/src/FileExtensionEscapingStrategy.php     |    2 +-
 data/web/inc/lib/vendor/twig/twig/src/Lexer.php    |  147 +-
 .../vendor/twig/twig/src/Loader/ArrayLoader.php    |   14 +-
 .../vendor/twig/twig/src/Loader/ChainLoader.php    |   43 +-
 .../twig/twig/src/Loader/FilesystemLoader.php      |   20 +-
 data/web/inc/lib/vendor/twig/twig/src/Markup.php   |    4 +-
 .../vendor/twig/twig/src/Node/AutoEscapeNode.php   |    6 +-
 .../lib/vendor/twig/twig/src/Node/BlockNode.php    |   12 +-
 .../twig/twig/src/Node/BlockReferenceNode.php      |    8 +-
 .../inc/lib/vendor/twig/twig/src/Node/BodyNode.php |    3 +
 .../lib/vendor/twig/twig/src/Node/CaptureNode.php  |   57 +
 .../twig/twig/src/Node/CheckSecurityCallNode.php   |    4 +-
 .../twig/twig/src/Node/CheckSecurityNode.php       |   31 +-
 .../twig/twig/src/Node/CheckToStringNode.php       |    4 +-
 .../vendor/twig/twig/src/Node/DeprecatedNode.php   |   40 +-
 .../inc/lib/vendor/twig/twig/src/Node/DoNode.php   |    6 +-
 .../lib/vendor/twig/twig/src/Node/EmbedNode.php    |    6 +-
 .../src/Node/Expression/AbstractExpression.php     |    4 +
 .../twig/src/Node/Expression/ArrayExpression.php   |   66 +-
 .../Node/Expression/ArrowFunctionExpression.php    |    4 +-
 .../src/Node/Expression/Binary/EndsWithBinary.php  |    6 +-
 .../src/Node/Expression/Binary/EqualBinary.php     |    2 +-
 .../src/Node/Expression/Binary/GreaterBinary.php   |    2 +-
 .../Node/Expression/Binary/GreaterEqualBinary.php  |    2 +-
 .../src/Node/Expression/Binary/HasEveryBinary.php  |   33 +
 .../src/Node/Expression/Binary/HasSomeBinary.php   |   33 +
 .../twig/src/Node/Expression/Binary/InBinary.php   |    2 +-
 .../twig/src/Node/Expression/Binary/LessBinary.php |    2 +-
 .../src/Node/Expression/Binary/LessEqualBinary.php |    2 +-
 .../src/Node/Expression/Binary/MatchesBinary.php   |    2 +-
 .../src/Node/Expression/Binary/NotEqualBinary.php  |    2 +-
 .../src/Node/Expression/Binary/NotInBinary.php     |    2 +-
 .../Node/Expression/Binary/StartsWithBinary.php    |    6 +-
 .../Node/Expression/BlockReferenceExpression.php   |    9 +-
 .../twig/src/Node/Expression/CallExpression.php    |  197 +-
 .../src/Node/Expression/ConditionalExpression.php  |   27 +-
 .../src/Node/Expression/ConstantExpression.php     |    3 +
 .../src/Node/Expression/Filter/DefaultFilter.php   |   23 +-
 .../twig/src/Node/Expression/Filter/RawFilter.php  |   36 +
 .../twig/src/Node/Expression/FilterExpression.php  |   57 +-
 .../src/Node/Expression/FunctionExpression.php     |   51 +-
 .../Expression/FunctionNode/EnumCasesFunction.php  |   41 +
 .../twig/src/Node/Expression/GetAttrExpression.php |    2 +-
 .../twig/twig/src/Node/Expression/InlinePrint.php  |    3 +-
 .../src/Node/Expression/MethodCallExpression.php   |    6 +-
 .../twig/src/Node/Expression/NameExpression.php    |   14 +-
 .../src/Node/Expression/NullCoalesceExpression.php |    5 +-
 .../twig/src/Node/Expression/ParentExpression.php  |    6 +-
 .../twig/src/Node/Expression/Test/ConstantTest.php |    6 +-
 .../twig/src/Node/Expression/Test/DefinedTest.php  |    9 +-
 .../src/Node/Expression/Test/DivisiblebyTest.php   |    2 +-
 .../twig/src/Node/Expression/Test/SameasTest.php   |    2 +-
 .../twig/src/Node/Expression/TestExpression.php    |   40 +-
 .../lib/vendor/twig/twig/src/Node/FlushNode.php    |   17 +-
 .../lib/vendor/twig/twig/src/Node/ForLoopNode.php  |    8 +-
 .../inc/lib/vendor/twig/twig/src/Node/ForNode.php  |   19 +-
 .../inc/lib/vendor/twig/twig/src/Node/IfNode.php   |   13 +-
 .../lib/vendor/twig/twig/src/Node/ImportNode.php   |   16 +-
 .../lib/vendor/twig/twig/src/Node/IncludeNode.php  |   22 +-
 .../lib/vendor/twig/twig/src/Node/MacroNode.php    |   45 +-
 .../lib/vendor/twig/twig/src/Node/ModuleNode.php   |   99 +-
 .../vendor/twig/twig/src/Node/NameDeprecation.php  |   46 +
 .../web/inc/lib/vendor/twig/twig/src/Node/Node.php |  142 +-
 .../lib/vendor/twig/twig/src/Node/PrintNode.php    |   13 +-
 .../lib/vendor/twig/twig/src/Node/SandboxNode.php  |    6 +-
 .../inc/lib/vendor/twig/twig/src/Node/SetNode.php  |   51 +-
 .../inc/lib/vendor/twig/twig/src/Node/TextNode.php |    7 +-
 .../lib/vendor/twig/twig/src/Node/TypesNode.php    |   28 +
 .../inc/lib/vendor/twig/twig/src/Node/WithNode.php |   20 +-
 .../twig/src/NodeVisitor/AbstractNodeVisitor.php   |    4 +-
 .../twig/src/NodeVisitor/EscaperNodeVisitor.php    |   35 +-
 .../src/NodeVisitor/MacroAutoImportNodeVisitor.php |   10 +-
 .../twig/src/NodeVisitor/OptimizerNodeVisitor.php  |   70 +-
 .../src/NodeVisitor/SafeAnalysisNodeVisitor.php    |   28 +-
 .../twig/src/NodeVisitor/SandboxNodeVisitor.php    |   15 +-
 .../src/NodeVisitor/YieldNotReadyNodeVisitor.php   |   59 +
 data/web/inc/lib/vendor/twig/twig/src/Parser.php   |   77 +-
 .../twig/twig/src/Profiler/Dumper/BaseDumper.php   |    2 +-
 .../twig/src/Profiler/Dumper/BlackfireDumper.php   |    6 +-
 .../twig/twig/src/Profiler/Dumper/HtmlDumper.php   |    6 +-
 .../twig/twig/src/Profiler/Dumper/TextDumper.php   |    6 +-
 .../twig/src/Profiler/Node/EnterProfileNode.php    |    6 +-
 .../twig/src/Profiler/Node/LeaveProfileNode.php    |    4 +-
 .../Profiler/NodeVisitor/ProfilerNodeVisitor.php   |    9 +-
 .../lib/vendor/twig/twig/src/Profiler/Profile.php  |   17 +-
 .../lib/vendor/twig/twig/src/Resources/core.php    |  541 +++++
 .../lib/vendor/twig/twig/src/Resources/debug.php   |   25 +
 .../lib/vendor/twig/twig/src/Resources/escaper.php |   51 +
 .../twig/twig/src/Resources/string_loader.php      |   26 +
 .../twig/twig/src/Runtime/EscaperRuntime.php       |  327 +++
 .../src/RuntimeLoader/ContainerRuntimeLoader.php   |    8 +-
 .../src/RuntimeLoader/FactoryRuntimeLoader.php     |    8 +-
 .../twig/twig/src/Sandbox/SecurityPolicy.php       |   26 +-
 .../twig/src/Sandbox/SourcePolicyInterface.php     |   24 +
 data/web/inc/lib/vendor/twig/twig/src/Source.php   |   14 +-
 data/web/inc/lib/vendor/twig/twig/src/Template.php |  309 ++-
 .../lib/vendor/twig/twig/src/TemplateWrapper.php   |   39 +-
 .../twig/twig/src/Test/IntegrationTestCase.php     |   59 +-
 .../lib/vendor/twig/twig/src/Test/NodeTestCase.php |   74 +-
 data/web/inc/lib/vendor/twig/twig/src/Token.php    |   32 +-
 .../twig/twig/src/TokenParser/ApplyTokenParser.php |    8 +-
 .../twig/src/TokenParser/AutoEscapeTokenParser.php |    8 +-
 .../twig/twig/src/TokenParser/BlockTokenParser.php |   15 +-
 .../twig/src/TokenParser/DeprecatedTokenParser.php |   29 +-
 .../twig/twig/src/TokenParser/DoTokenParser.php    |    4 +-
 .../twig/twig/src/TokenParser/EmbedTokenParser.php |   18 +-
 .../twig/src/TokenParser/ExtendsTokenParser.php    |    7 +-
 .../twig/twig/src/TokenParser/FlushTokenParser.php |    4 +-
 .../twig/twig/src/TokenParser/ForTokenParser.php   |   16 +-
 .../twig/twig/src/TokenParser/FromTokenParser.php  |   16 +-
 .../twig/twig/src/TokenParser/IfTokenParser.php    |   12 +-
 .../twig/src/TokenParser/ImportTokenParser.php     |    8 +-
 .../twig/src/TokenParser/IncludeTokenParser.php    |   14 +-
 .../twig/twig/src/TokenParser/MacroTokenParser.php |   14 +-
 .../twig/src/TokenParser/SandboxTokenParser.php    |    6 +-
 .../twig/twig/src/TokenParser/SetTokenParser.php   |   10 +-
 .../twig/twig/src/TokenParser/TypesTokenParser.php |   86 +
 .../twig/twig/src/TokenParser/UseTokenParser.php   |   14 +-
 .../twig/twig/src/TokenParser/WithTokenParser.php  |   10 +-
 .../inc/lib/vendor/twig/twig/src/TokenStream.php   |   23 +-
 .../vendor/twig/twig/src/TwigCallableInterface.php |   53 +
 .../inc/lib/vendor/twig/twig/src/TwigFilter.php    |   78 +-
 .../inc/lib/vendor/twig/twig/src/TwigFunction.php  |   79 +-
 data/web/inc/lib/vendor/twig/twig/src/TwigTest.php |   67 +-
 .../twig/src/Util/CallableArgumentsExtractor.php   |  204 ++
 .../twig/twig/src/Util/DeprecationCollector.php    |   10 +-
 .../twig/twig/src/Util/ReflectionCallable.php      |   92 +
 data/web/inc/triggers.inc.php                      |   10 +-
 data/web/js/site/edit.js                           |    5 +
 data/web/json_api.php                              |    5 +-
 data/web/lang/lang.de-de.json                      |    8 +-
 data/web/lang/lang.en-gb.json                      |    6 +
 data/web/lang/lang.lv-lv.json                      |   99 +-
 data/web/lang/lang.pt-br.json                      |   63 +-
 data/web/lang/lang.ru-ru.json                      |    6 +
 data/web/lang/lang.tr-tr.json                      |   15 +-
 data/web/lang/lang.zh-cn.json                      |  169 +-
 data/web/lang/lang.zh-tw.json                      |   57 +-
 data/web/templates/edit/mailbox.twig               |   61 +-
 docker-compose.yml                                 |   16 +-
 helper-scripts/nextcloud.sh                        |    2 +-
 update.sh                                          |   30 +
 205 files changed, 7394 insertions(+), 3498 deletions(-)
 create mode 100644 data/web/inc/lib/vendor/symfony/polyfill-php81/LICENSE
 create mode 100644 data/web/inc/lib/vendor/symfony/polyfill-php81/Php81.php
 create mode 100644 data/web/inc/lib/vendor/symfony/polyfill-php81/README.md
 create mode 100644 data/web/inc/lib/vendor/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php
 create mode 100644 data/web/inc/lib/vendor/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php
 create mode 100644 data/web/inc/lib/vendor/symfony/polyfill-php81/bootstrap.php
 create mode 100644 data/web/inc/lib/vendor/symfony/polyfill-php81/composer.json
 delete mode 100644 data/web/inc/lib/vendor/twig/twig/.editorconfig
 delete mode 100644 data/web/inc/lib/vendor/twig/twig/.gitattributes
 delete mode 100644 data/web/inc/lib/vendor/twig/twig/.github/workflows/ci.yml
 delete mode 100644 data/web/inc/lib/vendor/twig/twig/.github/workflows/documentation.yml
 delete mode 100644 data/web/inc/lib/vendor/twig/twig/.gitignore
 delete mode 100644 data/web/inc/lib/vendor/twig/twig/.php-cs-fixer.dist.php
 create mode 100644 data/web/inc/lib/vendor/twig/twig/src/AbstractTwigCallable.php
 create mode 100644 data/web/inc/lib/vendor/twig/twig/src/Attribute/FirstClassTwigCallableReady.php
 create mode 100644 data/web/inc/lib/vendor/twig/twig/src/Attribute/YieldReady.php
 create mode 100644 data/web/inc/lib/vendor/twig/twig/src/Cache/ChainCache.php
 create mode 100644 data/web/inc/lib/vendor/twig/twig/src/Cache/ReadOnlyFilesystemCache.php
 create mode 100644 data/web/inc/lib/vendor/twig/twig/src/Extension/YieldNotReadyExtension.php
 create mode 100644 data/web/inc/lib/vendor/twig/twig/src/Node/CaptureNode.php
 create mode 100644 data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/HasEveryBinary.php
 create mode 100644 data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/HasSomeBinary.php
 create mode 100644 data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Filter/RawFilter.php
 create mode 100644 data/web/inc/lib/vendor/twig/twig/src/Node/Expression/FunctionNode/EnumCasesFunction.php
 create mode 100644 data/web/inc/lib/vendor/twig/twig/src/Node/NameDeprecation.php
 create mode 100644 data/web/inc/lib/vendor/twig/twig/src/Node/TypesNode.php
 create mode 100644 data/web/inc/lib/vendor/twig/twig/src/NodeVisitor/YieldNotReadyNodeVisitor.php
 create mode 100644 data/web/inc/lib/vendor/twig/twig/src/Resources/core.php
 create mode 100644 data/web/inc/lib/vendor/twig/twig/src/Resources/debug.php
 create mode 100644 data/web/inc/lib/vendor/twig/twig/src/Resources/escaper.php
 create mode 100644 data/web/inc/lib/vendor/twig/twig/src/Resources/string_loader.php
 create mode 100644 data/web/inc/lib/vendor/twig/twig/src/Runtime/EscaperRuntime.php
 create mode 100644 data/web/inc/lib/vendor/twig/twig/src/Sandbox/SourcePolicyInterface.php
 create mode 100644 data/web/inc/lib/vendor/twig/twig/src/TokenParser/TypesTokenParser.php
 create mode 100644 data/web/inc/lib/vendor/twig/twig/src/TwigCallableInterface.php
 create mode 100644 data/web/inc/lib/vendor/twig/twig/src/Util/CallableArgumentsExtractor.php
 create mode 100644 data/web/inc/lib/vendor/twig/twig/src/Util/ReflectionCallable.php

Diff

diff --cc .gitignore
index 43bc74e0,b22abfd6..a0558e6d
--- a/.gitignore
+++ b/.gitignore
@@@ -44,8 -44,8 +44,9 @@@ data/conf/rspamd/local.d/
  data/conf/rspamd/override.d/*
  data/conf/sogo/custom-theme.js
  data/conf/sogo/plist_ldap
 +data/conf/sogo/plist_ldap.sh
  data/conf/sogo/sieve.creds
+ data/conf/sogo/cron.creds
  data/conf/sogo/sogo-full.svg
  data/gitea/
  data/gogs/
diff --cc data/Dockerfiles/dovecot/docker-entrypoint.sh
index 7d9623a6,55eed795..c394bac5
--- a/data/Dockerfiles/dovecot/docker-entrypoint.sh
+++ b/data/Dockerfiles/dovecot/docker-entrypoint.sh
@@@ -254,6 -371,15 +254,8 @@@ EO
  # Create random master Password for SOGo SSO
  RAND_PASS=$(cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 32 | head -n 1)
  echo -n ${RAND_PASS} > /etc/phpfpm/sogo-sso.pass
+ # Creating additional creds file for SOGo notify crons (calendars, etc)
+ echo -n ${RAND_USER}@mailcow.local:${RAND_PASS} > /etc/sogo/cron.creds
 -cat <<EOF > /etc/dovecot/sogo-sso.conf
 -# Autogenerated by mailcow
 -passdb {
 -  driver = static
 -  args = allow_real_nets=${IPV4_NETWORK}.248/32 password={plain}${RAND_PASS}
 -}
 -EOF
  
  if [[ "${MASTER}" =~ ^([nN][oO]|[nN])+$ ]]; then
    # Toggling MASTER will result in a rebuild of containers, so the quota script will be recreated
diff --cc data/web/inc/functions.mailbox.inc.php
index 31e15870,9de66567..1b5b577f
--- a/data/web/inc/functions.mailbox.inc.php
+++ b/data/web/inc/functions.mailbox.inc.php
@@@ -1327,61 -1310,16 +1327,61 @@@ function mailbox($_action, $_type, $_da
                'object' => $username,
                'rl_frame' => $_data['rl_frame'],
                'rl_value' => $_data['rl_value']
 -            ));
 +            ), $_extra);
            }
-        
+ 
 -          update_sogo_static_view($username);
 +          try {
 +            update_sogo_static_view($username);
 +          } catch (PDOException $e) {
 +            $_SESSION['return'][] = array(
 +              'type' => 'danger',
 +              'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
 +              'msg' => $e->getMessage()
 +            );
 +          }
            $_SESSION['return'][] = array(
              'type' => 'success',
              'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
              'msg' => array('mailbox_added', htmlspecialchars($username))
            );
 -          return true;
 +        break;
 +        case 'mailbox_from_template':
-           $stmt = $pdo->prepare("SELECT * FROM `templates` 
++          $stmt = $pdo->prepare("SELECT * FROM `templates`
 +          WHERE `template` = :template AND type = 'mailbox'");
 +          $stmt->execute(array(
 +            ":template" => $_data['template']
 +          ));
 +          $mbox_template_data = $stmt->fetch(PDO::FETCH_ASSOC);
 +          if (empty($mbox_template_data)){
 +            $_SESSION['return'][] =  array(
 +              'type' => 'danger',
 +              'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
 +              'msg' => 'template_missing'
 +            );
 +            return false;
-           }  
-           
++          }
++
 +          $attribute_hash = sha1(json_encode($mbox_template_data["attributes"]));
-           $mbox_template_data = json_decode($mbox_template_data["attributes"], true);  
++          $mbox_template_data = json_decode($mbox_template_data["attributes"], true);
 +          $mbox_template_data['domain'] = $_data['domain'];
 +          $mbox_template_data['local_part'] = $_data['local_part'];
 +          $mbox_template_data['authsource'] = $_data['authsource'];
 +          $mbox_template_data['attribute_hash'] = $attribute_hash;
 +          $mbox_template_data['quota'] = intval($mbox_template_data['quota'] / 1048576);
-         
++
 +          $mailbox_attributes = array('acl' => array());
 +          foreach ($mbox_template_data as $key => $value){
 +            switch (true) {
 +              case (strpos($key, 'acl_') === 0 && $value != 0):
 +                array_push($mailbox_attributes['acl'], str_replace('acl_' , '', $key));
 +              break;
 +              default:
 +                $mailbox_attributes[$key] = $value;
 +              break;
 +            }
 +          }
 +
 +          return mailbox('add', 'mailbox', $mailbox_attributes, array('iam_create_login' => true));
          break;
          case 'resource':
            $domain             = idn_to_ascii(strtolower(trim($_data['domain'])), 0, INTL_IDNA_VARIANT_UTS46);
@@@ -3257,16 -3186,13 +3257,16 @@@
                  );
                  break;
                }
 -              $stmt = $pdo->prepare("INSERT INTO `tags_mailbox` (`username`, `tag_name`) VALUES (:username, :tag_name)");
 -              $stmt->execute(array(
 -                ':username' => $username,
 -                ':tag_name' => $tag,
 -              ));
 +              try {
 +                $stmt = $pdo->prepare("INSERT INTO `tags_mailbox` (`username`, `tag_name`) VALUES (:username, :tag_name)");
 +                $stmt->execute(array(
 +                  ':username' => $username,
 +                  ':tag_name' => $tag,
 +                ));
 +              } catch (Exception $e) {
 +              }
              }
-             
+ 
              $_SESSION['return'][] = array(
                'type' => 'success',
                'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
@@@ -3285,74 -3203,197 +3285,265 @@@
            }
            return true;
          break;
+         case 'mailbox_rename':
+           $domain = $_data['domain'];
+           $old_local_part = $_data['old_local_part'];
+           $old_username = $old_local_part . "@" . $domain;
+           $new_local_part = $_data['new_local_part'];
+           $new_username = $new_local_part . "@" . $domain;
+           $create_alias = intval($_data['create_alias']);
+ 
+           if (!filter_var($old_username, FILTER_VALIDATE_EMAIL)) {
+             $_SESSION['return'][] = array(
+               'type' => 'danger',
+               'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+               'msg' => array('username_invalid', $old_username)
+             );
+             return false;
+           }
+           if (!filter_var($new_username, FILTER_VALIDATE_EMAIL)) {
+             $_SESSION['return'][] = array(
+               'type' => 'danger',
+               'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+               'msg' => array('username_invalid', $new_username)
+             );
+             return false;
+           }
+ 
+           $is_now = mailbox('get', 'mailbox_details', $old_username);
+           if (empty($is_now)) {
+             $_SESSION['return'][] = array(
+               'type' => 'danger',
+               'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+               'msg' => 'access_denied'
+             );
+             return false;
+           }
+ 
+           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'
+             );
+             return false;
+           }
+ 
+           // get imap acls
+           try {
+             $exec_fields = array(
+               'cmd' => 'doveadm',
+               'task' => 'get_acl',
+               'id' => $old_username
+             );
+             $imap_acls = json_decode(docker('post', 'dovecot-mailcow', 'exec', $exec_fields), true);
+             // delete imap acls
+             foreach ($imap_acls as $imap_acl) {
+               $exec_fields = array(
+                 'cmd' => 'doveadm',
+                 'task' => 'delete_acl',
+                 'user' => $imap_acl['user'],
+                 'mailbox' => $imap_acl['mailbox'],
+                 'id' => $imap_acl['id']
+               );
+               docker('post', 'dovecot-mailcow', 'exec', $exec_fields);
+             }
+           } catch (Exception $e) {
+             $_SESSION['return'][] = array(
+               'type' => 'danger',
+               'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+               'msg' => $e->getMessage()
+             );
+             return false;
+           }
+ 
+           // rename username in sql
+           try {
+             $pdo->beginTransaction();
+             $pdo->exec('SET FOREIGN_KEY_CHECKS = 0');
+ 
+             // Update username in mailbox table
+             $pdo->prepare('UPDATE mailbox SET username = :new_username, local_part = :new_local_part WHERE username = :old_username')
+               ->execute([
+                 ':new_username' => $new_username,
+                 ':new_local_part' => $new_local_part,
+                 ':old_username' => $old_username
+               ]);
+ 
+             $pdo->prepare("UPDATE alias SET address = :new_username, goto = :new_username2 WHERE address = :old_username")
+             ->execute([
+               ':new_username' => $new_username,
+               ':new_username2' => $new_username,
+               ':old_username' => $old_username
+             ]);
+ 
+             // Update the username in all related tables
+             $tables = [
+               'tags_mailbox' => ['username'],
+               'sieve_filters' => ['username'],
+               'app_passwd' => ['mailbox'],
+               'user_acl' => ['username'],
+               'da_acl' => ['username'],
+               'quota2' => ['username'],
+               'quota2replica' => ['username'],
+               'pushover' => ['username'],
+               'alias' => ['goto'],
+               "imapsync" => ['user2'],
+               'bcc_maps' => ['local_dest', 'bcc_dest'],
+               'recipient_maps' => ['old_dest', 'new_dest'],
+               'sender_acl' => ['logged_in_as', 'send_as']
+             ];
+             foreach ($tables as $table => $columns) {
+               foreach ($columns as $column) {
+                 $stmt = $pdo->prepare("UPDATE $table SET $column = :new_username WHERE $column = :old_username")
+                   ->execute([
+                     ':new_username' => $new_username,
+                     ':old_username' => $old_username
+                   ]);
+               }
+             }
+ 
+             // Update c_uid, c_name and mail in _sogo_static_view table
+             $pdo->prepare("UPDATE _sogo_static_view SET c_uid = :new_username, c_name = :new_username2, mail = :new_username3 WHERE c_uid = :old_username")
+               ->execute([
+                 ':new_username' => $new_username,
+                 ':new_username2' => $new_username,
+                 ':new_username3' => $new_username,
+                 ':old_username' => $old_username
+               ]);
+ 
+             // Re-enable foreign key checks
+             $pdo->exec('SET FOREIGN_KEY_CHECKS = 1');
+             $pdo->commit();
+           } catch (PDOException $e) {
+             // Rollback the transaction if something goes wrong
+             $pdo->rollBack();
+             $_SESSION['return'][] = array(
+               'type' => 'danger',
+               'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+               'msg' => $e->getMessage()
+             );
+             return false;
+           }
+ 
+           // move maildir
+           $exec_fields = array(
+             'cmd' => 'maildir',
+             'task' => 'move',
+             'old_maildir' => $domain . '/' . $old_local_part,
+             'new_maildir' => $domain . '/' . $new_local_part
+           );
+           docker('post', 'dovecot-mailcow', 'exec', $exec_fields);
+ 
+           // rename username in sogo
+           $exec_fields = array(
+             'cmd' => 'sogo',
+             'task' => 'rename_user',
+             'old_username' => $old_username,
+             'new_username' => $new_username
+           );
+           docker('post', 'sogo-mailcow', 'exec', $exec_fields);
+ 
+           // set imap acls
+           foreach ($imap_acls as $imap_acl) {
+             $user_id = ($imap_acl['id'] == $old_username) ? $new_username : $imap_acl['id'];
+             $user = ($imap_acl['user'] == $old_username) ? $new_username : $imap_acl['user'];
+             $exec_fields = array(
+               'cmd' => 'doveadm',
+               'task' => 'set_acl',
+               'user' => $user,
+               'mailbox' => $imap_acl['mailbox'],
+               'id' => $user_id,
+               'rights' => $imap_acl['rights']
+             );
+             docker('post', 'dovecot-mailcow', 'exec', $exec_fields);
+           }
+ 
+           // create alias
+           if ($create_alias == 1) {
+             mailbox("add", "alias", array(
+               "address" => $old_username,
+               "goto" => $new_username,
+               "active" => 1,
+               "sogo_visible" => 1,
+               "private_comment" => sprintf($lang['success']['mailbox_renamed'], $old_username, $new_username)
+             ));
+           }
+ 
+           $_SESSION['return'][] = array(
+             'type' => 'success',
+             'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
+             'msg' => array('mailbox_renamed', $old_username, $new_username)
+           );
+         break;
 +        case 'mailbox_from_template':
-           $stmt = $pdo->prepare("SELECT * FROM `templates` 
++          $stmt = $pdo->prepare("SELECT * FROM `templates`
 +          WHERE `template` = :template AND type = 'mailbox'");
 +          $stmt->execute(array(
 +            ":template" => $_data['template']
 +          ));
 +          $mbox_template_data = $stmt->fetch(PDO::FETCH_ASSOC);
 +          if (empty($mbox_template_data)){
 +            $_SESSION['return'][] =  array(
 +              'type' => 'danger',
 +              'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
 +              'msg' => 'template_missing'
 +            );
 +            return false;
 +          }
 +
 +          $attribute_hash = sha1(json_encode($mbox_template_data["attributes"]));
 +          $is_now = mailbox('get', 'mailbox_details', $_data['username']);
 +          $name = ltrim(rtrim($_data['name'], '>'), '<');
 +          if ($is_now['attributes']['attribute_hash'] == $attribute_hash && $is_now['name'] == $name)
 +            return true;
 +
 +          $mbox_template_data = json_decode($mbox_template_data["attributes"], true);
 +          $mbox_template_data['attribute_hash'] = $attribute_hash;
 +          $mbox_template_data['name'] = $name;
 +          $quarantine_attributes = array('username' => $_data['username']);
 +          $tls_attributes = array('username' => $_data['username']);
 +          $ratelimit_attributes = array('object' => $_data['username']);
 +          $acl_attributes = array('username' => $_data['username'], 'user_acl' => array());
 +          $mailbox_attributes = array('username' => $_data['username']);
 +          foreach ($mbox_template_data as $key => $value){
 +            switch (true) {
 +              case (strpos($key, 'quarantine_') === 0):
 +                $quarantine_attributes[$key] = $value;
 +              break;
 +              case (strpos($key, 'tls_') === 0):
 +                if ($value == null)
 +                  $value = 0;
 +                $tls_attributes[$key] = $value;
 +              break;
 +              case (strpos($key, 'rl_') === 0):
 +                $ratelimit_attributes[$key] = $value;
 +              break;
 +              case (strpos($key, 'acl_') === 0 && $value != 0):
 +                array_push($acl_attributes['user_acl'], str_replace('acl_' , '', $key));
 +              break;
 +              default:
 +                $mailbox_attributes[$key] = $value;
 +              break;
 +            }
 +          }
-         
++
 +          $mailbox_attributes['quota'] = intval($mailbox_attributes['quota'] / 1048576);
 +          $result = mailbox('edit', 'mailbox', $mailbox_attributes);
 +          if ($result === false) return $result;
 +          $result = mailbox('edit', 'tls_policy', $tls_attributes);
 +          if ($result === false) return $result;
 +          $result = mailbox('edit', 'quarantine_notification', $quarantine_attributes);
 +          if ($result === false) return $result;
 +          $result = mailbox('edit', 'quarantine_category', $quarantine_attributes);
 +          if ($result === false) return $result;
 +          $result = ratelimit('edit', 'mailbox', $ratelimit_attributes);
 +          if ($result === false) return $result;
 +          $result = acl('edit', 'user', $acl_attributes);
 +          if ($result === false) return $result;
 +
 +          return true;
 +        break;
          case 'mailbox_templates':
            if ($_SESSION['mailcow_cc_role'] != "admin") {
              $_SESSION['return'][] = array(
@@@ -5537,16 -5575,8 +5728,16 @@@
                );
                continue;
              }
-                  
+ 
 -            update_sogo_static_view($username);
 +            try {
 +              update_sogo_static_view($username);
 +            }catch (PDOException $e) {
 +              $_SESSION['return'][] = array(
 +                'type' => 'success',
 +                'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
 +                'msg' => $e->getMessage()
 +              );
 +            }
              $_SESSION['return'][] = array(
                'type' => 'success',
                'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
@@@ -5759,17 -5789,7 +5950,17 @@@
        }
      break;
    }
-   if ($_action != 'get' && in_array($_type, array('domain', 'alias', 'alias_domain', 'resource')) && getenv('SKIP_SOGO') != "y") {            
+   if ($_action != 'get' && in_array($_type, array('domain', 'alias', 'alias_domain', 'resource')) && getenv('SKIP_SOGO') != "y") {
 -    update_sogo_static_view();
 +    try {
 +      update_sogo_static_view();
 +    }catch (PDOException $e) {
 +      $_SESSION['return'][] = array(
 +        'type' => 'success',
 +        'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
 +        'msg' => $e->getMessage()
 +      );
 +    }
    }
-   
++
 +  return true;
  }
diff --cc data/web/inc/lib/composer.lock
index f0659ee8,422d353a..fb1c3903
--- a/data/web/inc/lib/composer.lock
+++ b/data/web/inc/lib/composer.lock
@@@ -1833,70 -1039,9 +1833,70 @@@
              },
              "time": "2017-04-19T22:01:50+00:00"
          },
 +        {
 +            "name": "stevenmaguire/oauth2-keycloak",
 +            "version": "4.0.0",
 +            "source": {
 +                "type": "git",
 +                "url": "https://github.com/stevenmaguire/oauth2-keycloak.git",
 +                "reference": "05ead6bb6bcd2b6f96dfae87c769dcd3e5f6129d"
 +            },
 +            "dist": {
 +                "type": "zip",
 +                "url": "https://api.github.com/repos/stevenmaguire/oauth2-keycloak/zipball/05ead6bb6bcd2b6f96dfae87c769dcd3e5f6129d",
 +                "reference": "05ead6bb6bcd2b6f96dfae87c769dcd3e5f6129d",
 +                "shasum": ""
 +            },
 +            "require": {
 +                "firebase/php-jwt": "^4.0 || ^5.0 || ^6.0",
 +                "league/oauth2-client": "^2.0",
 +                "php": "~7.2 || ~8.0"
 +            },
 +            "require-dev": {
 +                "mockery/mockery": "~1.5.0",
 +                "phpunit/phpunit": "~9.6.4",
 +                "squizlabs/php_codesniffer": "~3.7.0"
 +            },
 +            "type": "library",
 +            "extra": {
 +                "branch-alias": {
 +                    "dev-master": "1.0.x-dev"
 +                }
 +            },
 +            "autoload": {
 +                "psr-4": {
 +                    "Stevenmaguire\\OAuth2\\Client\\": "src/"
 +                }
 +            },
 +            "notification-url": "https://packagist.org/downloads/",
 +            "license": [
 +                "MIT"
 +            ],
 +            "authors": [
 +                {
 +                    "name": "Steven Maguire",
 +                    "email": "[email protected]",
 +                    "homepage": "https://github.com/stevenmaguire"
 +                }
 +            ],
 +            "description": "Keycloak OAuth 2.0 Client Provider for The PHP League OAuth2-Client",
 +            "keywords": [
 +                "authorisation",
 +                "authorization",
 +                "client",
 +                "keycloak",
 +                "oauth",
 +                "oauth2"
 +            ],
 +            "support": {
 +                "issues": "https://github.com/stevenmaguire/oauth2-keycloak/issues",
 +                "source": "https://github.com/stevenmaguire/oauth2-keycloak/tree/4.0.0"
 +            },
 +            "time": "2023-03-14T09:43:47+00:00"
 +        },
          {
              "name": "symfony/deprecation-contracts",
-             "version": "v3.4.0",
+             "version": "v3.5.0",
              "source": {
                  "type": "git",
                  "url": "https://github.com/symfony/deprecation-contracts.git",
@@@ -2201,11 -1352,87 +2201,87 @@@
                      "type": "tidelift"
                  }
              ],
 -            "time": "2021-09-13T13:58:33+00:00"
 +            "time": "2024-01-29T20:11:03+00:00"
          },
+         {
+             "name": "symfony/polyfill-php81",
+             "version": "v1.31.0",
+             "source": {
+                 "type": "git",
+                 "url": "https://github.com/symfony/polyfill-php81.git",
+                 "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c"
+             },
+             "dist": {
+                 "type": "zip",
+                 "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c",
+                 "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c",
+                 "shasum": ""
+             },
+             "require": {
+                 "php": ">=7.2"
+             },
+             "type": "library",
+             "extra": {
+                 "thanks": {
+                     "name": "symfony/polyfill",
+                     "url": "https://github.com/symfony/polyfill"
+                 }
+             },
+             "autoload": {
+                 "files": [
+                     "bootstrap.php"
+                 ],
+                 "psr-4": {
+                     "Symfony\\Polyfill\\Php81\\": ""
+                 },
+                 "classmap": [
+                     "Resources/stubs"
+                 ]
+             },
+             "notification-url": "https://packagist.org/downloads/",
+             "license": [
+                 "MIT"
+             ],
+             "authors": [
+                 {
+                     "name": "Nicolas Grekas",
+                     "email": "[email protected]"
+                 },
+                 {
+                     "name": "Symfony Community",
+                     "homepage": "https://symfony.com/contributors"
+                 }
+             ],
+             "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions",
+             "homepage": "https://symfony.com",
+             "keywords": [
+                 "compatibility",
+                 "polyfill",
+                 "portable",
+                 "shim"
+             ],
+             "support": {
+                 "source": "https://github.com/symfony/polyfill-php81/tree/v1.31.0"
+             },
+             "funding": [
+                 {
+                     "url": "https://symfony.com/sponsor",
+                     "type": "custom"
+                 },
+                 {
+                     "url": "https://github.com/fabpot",
+                     "type": "github"
+                 },
+                 {
+                     "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                     "type": "tidelift"
+                 }
+             ],
+             "time": "2024-09-09T11:45:10+00:00"
+         },
          {
              "name": "symfony/translation",
 -            "version": "v6.0.5",
 +            "version": "v6.4.3",
              "source": {
                  "type": "git",
                  "url": "https://github.com/symfony/translation.git",
@@@ -2589,7 -1822,48 +2668,7 @@@
                      "type": "tidelift"
                  }
              ],
-             "time": "2022-09-28T08:42:51+00:00"
+             "time": "2024-09-09T17:55:12+00:00"
 -        },
 -        {
 -            "name": "yubico/u2flib-server",
 -            "version": "1.0.2",
 -            "source": {
 -                "type": "git",
 -                "url": "https://github.com/Yubico/php-u2flib-server.git",
 -                "reference": "55d813acf68212ad2cadecde07551600d6971939"
 -            },
 -            "dist": {
 -                "type": "zip",
 -                "url": "https://api.github.com/repos/Yubico/php-u2flib-server/zipball/55d813acf68212ad2cadecde07551600d6971939",
 -                "reference": "55d813acf68212ad2cadecde07551600d6971939",
 -                "shasum": ""
 -            },
 -            "require": {
 -                "ext-openssl": "*",
 -                "paragonie/random_compat": ">= 1",
 -                "php": ">=5.6"
 -            },
 -            "require-dev": {
 -                "phpunit/phpunit": "~5.7",
 -                "vimeo/psalm": "^0|^1|^2"
 -            },
 -            "type": "library",
 -            "autoload": {
 -                "classmap": [
 -                    "src/"
 -                ]
 -            },
 -            "notification-url": "https://packagist.org/downloads/",
 -            "license": [
 -                "BSD-2-Clause"
 -            ],
 -            "description": "Library for U2F implementation",
 -            "homepage": "https://developers.yubico.com/php-u2flib-server",
 -            "support": {
 -                "issues": "https://github.com/Yubico/php-u2flib-server/issues",
 -                "source": "https://github.com/Yubico/php-u2flib-server/tree/1.0.2"
 -            },
 -            "time": "2018-09-07T08:16:44+00:00"
          }
      ],
      "packages-dev": [],
diff --cc data/web/inc/lib/vendor/composer/autoload_files.php
index bac0d960,526f6b6f..c426e71d
--- a/data/web/inc/lib/vendor/composer/autoload_files.php
+++ b/data/web/inc/lib/vendor/composer/autoload_files.php
@@@ -6,15 -6,13 +6,17 @@@ $vendorDir = dirname(__DIR__)
  $baseDir = dirname($vendorDir);
  
  return array(
 +    '6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php',
      '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
 +    '7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php',
 +    'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php',
      'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
 +    '37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php',
      'a1105708a18b76903365ca1c4aa61b02' => $vendorDir . '/symfony/translation/Resources/functions.php',
      '667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php',
+     '6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php',
      '320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php',
+     '23c18046f52bef3eea034657bafda50f' => $vendorDir . '/symfony/polyfill-php81/bootstrap.php',
      'fe62ba7e10580d903cc46d808b5961a4' => $vendorDir . '/tightenco/collect/src/Collect/Support/helpers.php',
      'caf31cc6ec7cf2241cb6f12c226c3846' => $vendorDir . '/tightenco/collect/src/Collect/Support/alias.php',
      '04c6c5c2f7095ccf6c481d3e53e1776f' => $vendorDir . '/mustangostang/spyc/Spyc.php',
diff --cc data/web/inc/lib/vendor/composer/autoload_static.php
index 7564e972,6b2f04a5..5375b0be
--- a/data/web/inc/lib/vendor/composer/autoload_static.php
+++ b/data/web/inc/lib/vendor/composer/autoload_static.php
@@@ -7,15 -7,13 +7,17 @@@ namespace Composer\Autoload
  class ComposerStaticInit873464e4bd965a3168f133248b1b218b
  {
      public static $files = array (
 +        '6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php',
          '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
 +        '7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
 +        'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php',
          'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
 +        '37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php',
          'a1105708a18b76903365ca1c4aa61b02' => __DIR__ . '/..' . '/symfony/translation/Resources/functions.php',
          '667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php',
+         '6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php',
          '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
+         '23c18046f52bef3eea034657bafda50f' => __DIR__ . '/..' . '/symfony/polyfill-php81/bootstrap.php',
          'fe62ba7e10580d903cc46d808b5961a4' => __DIR__ . '/..' . '/tightenco/collect/src/Collect/Support/helpers.php',
          'caf31cc6ec7cf2241cb6f12c226c3846' => __DIR__ . '/..' . '/tightenco/collect/src/Collect/Support/alias.php',
          '04c6c5c2f7095ccf6c481d3e53e1776f' => __DIR__ . '/..' . '/mustangostang/spyc/Spyc.php',
@@@ -22,26 -24,26 +28,27 @@@
      );
  
      public static $prefixLengthsPsr4 = array (
--        'T' => 
++        'T' =>
          array (
              'Twig\\' => 5,
              'Tightenco\\Collect\\' => 18,
          ),
--        'S' => 
++        'S' =>
          array (
+             'Symfony\\Polyfill\\Php81\\' => 23,
              'Symfony\\Polyfill\\Php80\\' => 23,
              'Symfony\\Polyfill\\Mbstring\\' => 26,
              'Symfony\\Polyfill\\Ctype\\' => 23,
              'Symfony\\Contracts\\Translation\\' => 30,
              'Symfony\\Component\\VarDumper\\' => 28,
              'Symfony\\Component\\Translation\\' => 30,
 +            'Stevenmaguire\\OAuth2\\Client\\' => 28,
          ),
--        'R' => 
++        'R' =>
          array (
              'RobThree\\Auth\\' => 14,
          ),
--        'P' => 
++        'P' =>
          array (
              'Psr\\SimpleCache\\' => 16,
              'Psr\\Log\\' => 8,
@@@ -52,177 -51,128 +59,181 @@@
              'PhpMimeMailParser\\' => 18,
              'PHPMailer\\PHPMailer\\' => 20,
          ),
--        'M' => 
++        'M' =>
          array (
              'MatthiasMullie\\PathConverter\\' => 29,
              'MatthiasMullie\\Minify\\' => 22,
          ),
--        'L' => 
++        'L' =>
          array (
 +            'League\\OAuth2\\Client\\' => 21,
              'LdapRecord\\' => 11,
          ),
--        'I' => 
++        'I' =>
          array (
              'Illuminate\\Contracts\\' => 21,
          ),
--        'H' => 
++        'H' =>
          array (
              'Html2Text\\' => 10,
          ),
-         'G' => 
 -        'D' => 
++        'G' =>
 +        array (
 +            'GuzzleHttp\\Psr7\\' => 16,
 +            'GuzzleHttp\\Promise\\' => 19,
 +            'GuzzleHttp\\' => 11,
 +        ),
-         'F' => 
++        'F' =>
 +        array (
 +            'Firebase\\JWT\\' => 13,
 +        ),
-         'D' => 
++        'D' =>
          array (
              'Ddeboer\\Imap\\' => 13,
          ),
--        'C' => 
++        'C' =>
          array (
 +            'Carbon\\Doctrine\\' => 16,
              'Carbon\\' => 7,
          ),
      );
  
      public static $prefixDirsPsr4 = array (
--        'Twig\\' => 
++        'Twig\\' =>
          array (
              0 => __DIR__ . '/..' . '/twig/twig/src',
          ),
--        'Tightenco\\Collect\\' => 
++        'Tightenco\\Collect\\' =>
          array (
              0 => __DIR__ . '/..' . '/tightenco/collect/src/Collect',
          ),
-         'Symfony\\Polyfill\\Php80\\' => 
 -        'Symfony\\Polyfill\\Php81\\' => 
++        'Symfony\\Polyfill\\Php81\\' =>
+         array (
+             0 => __DIR__ . '/..' . '/symfony/polyfill-php81',
+         ),
 -        'Symfony\\Polyfill\\Php80\\' => 
++        'Symfony\\Polyfill\\Php80\\' =>
          array (
              0 => __DIR__ . '/..' . '/symfony/polyfill-php80',
          ),
--        'Symfony\\Polyfill\\Mbstring\\' => 
++        'Symfony\\Polyfill\\Mbstring\\' =>
          array (
              0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring',
          ),
--        'Symfony\\Polyfill\\Ctype\\' => 
++        'Symfony\\Polyfill\\Ctype\\' =>
          array (
              0 => __DIR__ . '/..' . '/symfony/polyfill-ctype',
          ),
--        'Symfony\\Contracts\\Translation\\' => 
++        'Symfony\\Contracts\\Translation\\' =>
          array (
              0 => __DIR__ . '/..' . '/symfony/translation-contracts',
          ),
--        'Symfony\\Component\\VarDumper\\' => 
++        'Symfony\\Component\\VarDumper\\' =>
          array (
              0 => __DIR__ . '/..' . '/symfony/var-dumper',
          ),
--        'Symfony\\Component\\Translation\\' => 
++        'Symfony\\Component\\Translation\\' =>
          array (
              0 => __DIR__ . '/..' . '/symfony/translation',
          ),
-         'Stevenmaguire\\OAuth2\\Client\\' => 
 -        'RobThree\\Auth\\' => 
++        'Stevenmaguire\\OAuth2\\Client\\' =>
 +        array (
 +            0 => __DIR__ . '/..' . '/stevenmaguire/oauth2-keycloak/src',
 +        ),
-         'RobThree\\Auth\\' => 
++        'RobThree\\Auth\\' =>
          array (
              0 => __DIR__ . '/..' . '/robthree/twofactorauth/lib',
          ),
--        'Psr\\SimpleCache\\' => 
++        'Psr\\SimpleCache\\' =>
          array (
              0 => __DIR__ . '/..' . '/psr/simple-cache/src',
          ),
--        'Psr\\Log\\' => 
++        'Psr\\Log\\' =>
          array (
              0 => __DIR__ . '/..' . '/psr/log/src',
          ),
-         'Psr\\Http\\Message\\' => 
 -        'Psr\\Container\\' => 
++        'Psr\\Http\\Message\\' =>
 +        array (
 +            0 => __DIR__ . '/..' . '/psr/http-factory/src',
 +            1 => __DIR__ . '/..' . '/psr/http-message/src',
 +        ),
-         'Psr\\Http\\Client\\' => 
++        'Psr\\Http\\Client\\' =>
 +        array (
 +            0 => __DIR__ . '/..' . '/psr/http-client/src',
 +        ),
-         'Psr\\Container\\' => 
++        'Psr\\Container\\' =>
          array (
              0 => __DIR__ . '/..' . '/psr/container/src',
          ),
-         'Psr\\Clock\\' => 
 -        'PhpMimeMailParser\\' => 
++        'Psr\\Clock\\' =>
 +        array (
 +            0 => __DIR__ . '/..' . '/psr/clock/src',
 +        ),
-         'PhpMimeMailParser\\' => 
++        'PhpMimeMailParser\\' =>
          array (
              0 => __DIR__ . '/..' . '/php-mime-mail-parser/php-mime-mail-parser/src',
          ),
--        'PHPMailer\\PHPMailer\\' => 
++        'PHPMailer\\PHPMailer\\' =>
          array (
              0 => __DIR__ . '/..' . '/phpmailer/phpmailer/src',
          ),
--        'MatthiasMullie\\PathConverter\\' => 
++        'MatthiasMullie\\PathConverter\\' =>
          array (
              0 => __DIR__ . '/..' . '/matthiasmullie/path-converter/src',
          ),
--        'MatthiasMullie\\Minify\\' => 
++        'MatthiasMullie\\Minify\\' =>
          array (
              0 => __DIR__ . '/..' . '/matthiasmullie/minify/src',
          ),
-         'League\\OAuth2\\Client\\' => 
 -        'LdapRecord\\' => 
++        'League\\OAuth2\\Client\\' =>
 +        array (
 +            0 => __DIR__ . '/..' . '/league/oauth2-client/src',
 +        ),
-         'LdapRecord\\' => 
++        'LdapRecord\\' =>
          array (
              0 => __DIR__ . '/..' . '/directorytree/ldaprecord/src',
          ),
--        'Illuminate\\Contracts\\' => 
++        'Illuminate\\Contracts\\' =>
          array (
              0 => __DIR__ . '/..' . '/illuminate/contracts',
          ),
--        'Html2Text\\' => 
++        'Html2Text\\' =>
          array (
              0 => __DIR__ . '/..' . '/soundasleep/html2text/src',
          ),
-         'GuzzleHttp\\Psr7\\' => 
 -        'Ddeboer\\Imap\\' => 
++        'GuzzleHttp\\Psr7\\' =>
 +        array (
 +            0 => __DIR__ . '/..' . '/guzzlehttp/psr7/src',
 +        ),
-         'GuzzleHttp\\Promise\\' => 
++        'GuzzleHttp\\Promise\\' =>
 +        array (
 +            0 => __DIR__ . '/..' . '/guzzlehttp/promises/src',
 +        ),
-         'GuzzleHttp\\' => 
++        'GuzzleHttp\\' =>
 +        array (
 +            0 => __DIR__ . '/..' . '/guzzlehttp/guzzle/src',
 +        ),
-         'Firebase\\JWT\\' => 
++        'Firebase\\JWT\\' =>
 +        array (
 +            0 => __DIR__ . '/..' . '/firebase/php-jwt/src',
 +        ),
-         'Ddeboer\\Imap\\' => 
++        'Ddeboer\\Imap\\' =>
          array (
              0 => __DIR__ . '/..' . '/ddeboer/imap/src',
          ),
-         'Carbon\\Doctrine\\' => 
 -        'Carbon\\' => 
++        'Carbon\\Doctrine\\' =>
 +        array (
 +            0 => __DIR__ . '/..' . '/carbonphp/carbon-doctrine-types/src/Carbon/Doctrine',
 +        ),
-         'Carbon\\' => 
++        'Carbon\\' =>
          array (
              0 => __DIR__ . '/..' . '/nesbot/carbon/src/Carbon',
          ),
      );
  
      public static $prefixesPsr0 = array (
--        'O' => 
++        'O' =>
          array (
--            'OAuth2' => 
++            'OAuth2' =>
              array (
                  0 => __DIR__ . '/..' . '/bshaffer/oauth2-server-php/src',
              ),
diff --cc data/web/inc/lib/vendor/composer/installed.json
index a9a3966f,dfb2fb0c..26e8bc42
--- a/data/web/inc/lib/vendor/composer/installed.json
+++ b/data/web/inc/lib/vendor/composer/installed.json
@@@ -1895,74 -1068,10 +1895,74 @@@
              ],
              "install-path": "../soundasleep/html2text"
          },
 +        {
 +            "name": "stevenmaguire/oauth2-keycloak",
 +            "version": "4.0.0",
 +            "version_normalized": "4.0.0.0",
 +            "source": {
 +                "type": "git",
 +                "url": "https://github.com/stevenmaguire/oauth2-keycloak.git",
 +                "reference": "05ead6bb6bcd2b6f96dfae87c769dcd3e5f6129d"
 +            },
 +            "dist": {
 +                "type": "zip",
 +                "url": "https://api.github.com/repos/stevenmaguire/oauth2-keycloak/zipball/05ead6bb6bcd2b6f96dfae87c769dcd3e5f6129d",
 +                "reference": "05ead6bb6bcd2b6f96dfae87c769dcd3e5f6129d",
 +                "shasum": ""
 +            },
 +            "require": {
 +                "firebase/php-jwt": "^4.0 || ^5.0 || ^6.0",
 +                "league/oauth2-client": "^2.0",
 +                "php": "~7.2 || ~8.0"
 +            },
 +            "require-dev": {
 +                "mockery/mockery": "~1.5.0",
 +                "phpunit/phpunit": "~9.6.4",
 +                "squizlabs/php_codesniffer": "~3.7.0"
 +            },
 +            "time": "2023-03-14T09:43:47+00:00",
 +            "type": "library",
 +            "extra": {
 +                "branch-alias": {
 +                    "dev-master": "1.0.x-dev"
 +                }
 +            },
 +            "installation-source": "dist",
 +            "autoload": {
 +                "psr-4": {
 +                    "Stevenmaguire\\OAuth2\\Client\\": "src/"
 +                }
 +            },
 +            "notification-url": "https://packagist.org/downloads/",
 +            "license": [
 +                "MIT"
 +            ],
 +            "authors": [
 +                {
 +                    "name": "Steven Maguire",
 +                    "email": "[email protected]",
 +                    "homepage": "https://github.com/stevenmaguire"
 +                }
 +            ],
 +            "description": "Keycloak OAuth 2.0 Client Provider for The PHP League OAuth2-Client",
 +            "keywords": [
 +                "authorisation",
 +                "authorization",
 +                "client",
 +                "keycloak",
 +                "oauth",
 +                "oauth2"
 +            ],
 +            "support": {
 +                "issues": "https://github.com/stevenmaguire/oauth2-keycloak/issues",
 +                "source": "https://github.com/stevenmaguire/oauth2-keycloak/tree/4.0.0"
 +            },
 +            "install-path": "../stevenmaguire/oauth2-keycloak"
 +        },
          {
              "name": "symfony/deprecation-contracts",
-             "version": "v3.4.0",
-             "version_normalized": "3.4.0.0",
+             "version": "v3.5.0",
+             "version_normalized": "3.5.0.0",
              "source": {
                  "type": "git",
                  "url": "https://github.com/symfony/deprecation-contracts.git",
@@@ -2280,10 -1395,89 +2280,89 @@@
              ],
              "install-path": "../symfony/polyfill-php80"
          },
+         {
+             "name": "symfony/polyfill-php81",
+             "version": "v1.31.0",
+             "version_normalized": "1.31.0.0",
+             "source": {
+                 "type": "git",
+                 "url": "https://github.com/symfony/polyfill-php81.git",
+                 "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c"
+             },
+             "dist": {
+                 "type": "zip",
+                 "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c",
+                 "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c",
+                 "shasum": ""
+             },
+             "require": {
+                 "php": ">=7.2"
+             },
+             "time": "2024-09-09T11:45:10+00:00",
+             "type": "library",
+             "extra": {
+                 "thanks": {
+                     "name": "symfony/polyfill",
+                     "url": "https://github.com/symfony/polyfill"
+                 }
+             },
+             "installation-source": "dist",
+             "autoload": {
+                 "files": [
+                     "bootstrap.php"
+                 ],
+                 "psr-4": {
+                     "Symfony\\Polyfill\\Php81\\": ""
+                 },
+                 "classmap": [
+                     "Resources/stubs"
+                 ]
+             },
+             "notification-url": "https://packagist.org/downloads/",
+             "license": [
+                 "MIT"
+             ],
+             "authors": [
+                 {
+                     "name": "Nicolas Grekas",
+                     "email": "[email protected]"
+                 },
+                 {
+                     "name": "Symfony Community",
+                     "homepage": "https://symfony.com/contributors"
+                 }
+             ],
+             "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions",
+             "homepage": "https://symfony.com",
+             "keywords": [
+                 "compatibility",
+                 "polyfill",
+                 "portable",
+                 "shim"
+             ],
+             "support": {
+                 "source": "https://github.com/symfony/polyfill-php81/tree/v1.31.0"
+             },
+             "funding": [
+                 {
+                     "url": "https://symfony.com/sponsor",
+                     "type": "custom"
+                 },
+                 {
+                     "url": "https://github.com/fabpot",
+                     "type": "github"
+                 },
+                 {
+                     "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                     "type": "tidelift"
+                 }
+             ],
+             "install-path": "../symfony/polyfill-php81"
+         },
          {
              "name": "symfony/translation",
 -            "version": "v6.0.5",
 -            "version_normalized": "6.0.5.0",
 +            "version": "v6.4.3",
 +            "version_normalized": "6.4.3.0",
              "source": {
                  "type": "git",
                  "url": "https://github.com/symfony/translation.git",
diff --cc data/web/inc/lib/vendor/composer/installed.php
index fed449fa,5d78fc9f..074ec9f8
--- a/data/web/inc/lib/vendor/composer/installed.php
+++ b/data/web/inc/lib/vendor/composer/installed.php
@@@ -298,19 -175,10 +298,19 @@@
              'aliases' => array(),
              'dev_requirement' => false,
          ),
 +        'stevenmaguire/oauth2-keycloak' => array(
 +            'pretty_version' => '4.0.0',
 +            'version' => '4.0.0.0',
 +            'reference' => '05ead6bb6bcd2b6f96dfae87c769dcd3e5f6129d',
 +            'type' => 'library',
 +            'install_path' => __DIR__ . '/../stevenmaguire/oauth2-keycloak',
 +            'aliases' => array(),
 +            'dev_requirement' => false,
 +        ),
          'symfony/deprecation-contracts' => array(
-             'pretty_version' => 'v3.4.0',
-             'version' => '3.4.0.0',
-             'reference' => '7c3aff79d10325257a001fcf92d991f24fc967cf',
+             'pretty_version' => 'v3.5.0',
+             'version' => '3.5.0.0',
+             'reference' => '0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1',
              'type' => 'library',
              'install_path' => __DIR__ . '/../symfony/deprecation-contracts',
              'aliases' => array(),
@@@ -343,10 -211,19 +343,19 @@@
              'aliases' => array(),
              'dev_requirement' => false,
          ),
+         'symfony/polyfill-php81' => array(
+             'pretty_version' => 'v1.31.0',
+             'version' => '1.31.0.0',
+             'reference' => '4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c',
+             'type' => 'library',
+             'install_path' => __DIR__ . '/../symfony/polyfill-php81',
+             'aliases' => array(),
+             'dev_requirement' => false,
+         ),
          'symfony/translation' => array(
 -            'pretty_version' => 'v6.0.5',
 -            'version' => '6.0.5.0',
 -            'reference' => 'e69501c71107cc3146b32aaa45f4edd0c3427875',
 +            'pretty_version' => 'v6.4.3',
 +            'version' => '6.4.3.0',
 +            'reference' => '637c51191b6b184184bbf98937702bcf554f7d04',
              'type' => 'library',
              'install_path' => __DIR__ . '/../symfony/translation',
              'aliases' => array(),
diff --cc data/web/inc/triggers.inc.php
index 8fa5dcd9,34e47a54..7f330ba1
--- a/data/web/inc/triggers.inc.php
+++ b/data/web/inc/triggers.inc.php
@@@ -60,59 -32,36 +60,59 @@@ if (isset($_POST["pw_reset"])) 
  }
  if (isset($_POST["verify_tfa_login"])) {
    if (verify_tfa_login($_SESSION['pending_mailcow_cc_username'], $_POST)) {
 -    if (isset($_SESSION['pending_mailcow_cc_username']) && isset($_SESSION['pending_pw_reset_token']) && isset($_SESSION['pending_pw_new_password'])) {
 -      reset_password("reset", array(
 -        'new_password' => $_SESSION['pending_pw_new_password'],
 -        'new_password2' => $_SESSION['pending_pw_new_password'],
 -        'token' => $_SESSION['pending_pw_reset_token'],
 -        'username' => $_SESSION['pending_mailcow_cc_username']
 -      ));
 -      unset($_SESSION['pending_pw_reset_token']);
 -      unset($_SESSION['pending_pw_new_password']);
 +    if ($_SESSION['pending_mailcow_cc_role'] == "admin") {
 +      $_SESSION['mailcow_cc_username'] = $_SESSION['pending_mailcow_cc_username'];
 +      $_SESSION['mailcow_cc_role'] = "admin";
        unset($_SESSION['pending_mailcow_cc_username']);
 +      unset($_SESSION['pending_mailcow_cc_role']);
        unset($_SESSION['pending_tfa_methods']);
-       
+ 
 -      header("Location: /");
 -      exit;
 -    } else {
 +		  header("Location: /debug");
 +      die();
 +    }
 +    elseif ($_SESSION['pending_mailcow_cc_role'] == "domainadmin") {
        $_SESSION['mailcow_cc_username'] = $_SESSION['pending_mailcow_cc_username'];
 -      $_SESSION['mailcow_cc_role'] = $_SESSION['pending_mailcow_cc_role'];
 +      $_SESSION['mailcow_cc_role'] = "domainadmin";
        unset($_SESSION['pending_mailcow_cc_username']);
        unset($_SESSION['pending_mailcow_cc_role']);
        unset($_SESSION['pending_tfa_methods']);
-       
+ 
 -      header("Location: /user");
 +		  header("Location: /mailbox");
 +      die();
 +    }
 +    elseif ($_SESSION['pending_mailcow_cc_role'] == "user") {
 +      if (isset($_SESSION['pending_pw_reset_token']) && isset($_SESSION['pending_pw_new_password'])) {
 +        reset_password("reset", array(
 +          'new_password' => $_SESSION['pending_pw_new_password'],
 +          'new_password2' => $_SESSION['pending_pw_new_password'],
 +          'token' => $_SESSION['pending_pw_reset_token'],
 +          'username' => $_SESSION['pending_mailcow_cc_username']
 +        ));
 +        unset($_SESSION['pending_pw_reset_token']);
 +        unset($_SESSION['pending_pw_new_password']);
 +        unset($_SESSION['pending_mailcow_cc_username']);
 +        unset($_SESSION['pending_tfa_methods']);
-   
++
 +        header("Location: /");
 +        die();
 +      } else {
 +        set_user_loggedin_session($_SESSION['pending_mailcow_cc_username']);
 +        $user_details = mailbox("get", "mailbox_details", $_SESSION['mailcow_cc_username']);
 +        $is_dual = (!empty($_SESSION["dual-login"]["username"])) ? true : false;
 +        if (intval($user_details['attributes']['sogo_access']) == 1 && !$is_dual) {
 +          header("Location: /SOGo/so/{$_SESSION['mailcow_cc_username']}");
 +          die();
 +        } else {
 +          header("Location: /user");
 +          die();
 +        }
 +      }
      }
 -  } else {
 -    unset($_SESSION['pending_pw_reset_token']);
 -    unset($_SESSION['pending_pw_new_password']);
 -    unset($_SESSION['pending_mailcow_cc_username']);
 -    unset($_SESSION['pending_mailcow_cc_role']);
 -    unset($_SESSION['pending_tfa_methods']);
    }
 +
 +  unset($_SESSION['pending_mailcow_cc_username']);
 +  unset($_SESSION['pending_mailcow_cc_role']);
 +  unset($_SESSION['pending_tfa_methods']);
  }
  
  if (isset($_GET["cancel_tfa_login"])) {
@@@ -146,9 -96,11 +147,10 @@@ if (isset($_POST["login_user"]) && isse
  		$_SESSION['mailcow_cc_username'] = $login_user;
  		$_SESSION['mailcow_cc_role'] = "domainadmin";
  		header("Location: /mailbox");
+     die();
  	}
  	elseif ($as == "user") {
 -		$_SESSION['mailcow_cc_username'] = $login_user;
 -		$_SESSION['mailcow_cc_role'] = "user";
 +    set_user_loggedin_session($login_user);
      $http_parameters = explode('&', $_SESSION['index_query_string']);
      unset($_SESSION['index_query_string']);
      if (in_array('mobileconfig', $http_parameters)) {
diff --cc docker-compose.yml
index 428e68b6,c462ba88..6b589113
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@@ -192,7 -177,7 +192,7 @@@ services
              - phpfpm
  
      sogo-mailcow:
-       image: mailcow/sogo:nightly-20240905
 -      image: mailcow/sogo:1.127
++      image: mailcow/sogo:nightly-20241112
        environment:
          - DBNAME=${DBNAME}
          - DBUSER=${DBUSER}
@@@ -239,7 -224,7 +239,7 @@@
              - sogo
  
      dovecot-mailcow:
-       image: mailcow/dovecot:nightly-20240819
 -      image: mailcow/dovecot:2.2
++      image: mailcow/dovecot:nightly-20241112
        depends_on:
          - mysql-mailcow
          - netfilter-mailcow