git subrepo commit (merge) mailcow/src/mailcow-dockerized

subrepo: subdir:   "mailcow/src/mailcow-dockerized"
  merged:   "02ae5285"
upstream: origin:   "https://github.com/mailcow/mailcow-dockerized.git"
  branch:   "master"
  commit:   "649a5c01"
git-subrepo: version:  "0.4.3"
  origin:   "???"
  commit:   "???"
Change-Id: I870ad468fba026cc5abf3c5699ed1e12ff28b32b
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Qr/BaconQrCodeProvider.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Qr/BaconQrCodeProvider.php
new file mode 100644
index 0000000..4d5cf01
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Qr/BaconQrCodeProvider.php
@@ -0,0 +1,152 @@
+<?php
+
+namespace RobThree\Auth\Providers\Qr;
+
+use BaconQrCode\Writer;
+use BaconQrCode\Renderer\ImageRenderer;
+use BaconQrCode\Renderer\RendererStyle\RendererStyle;
+use BaconQrCode\Renderer\RendererStyle\Fill;
+use BaconQrCode\Renderer\Color\Rgb;
+use BaconQrCode\Renderer\RendererStyle\EyeFill;
+
+use BaconQrCode\Renderer\Image\EpsImageBackEnd;
+use BaconQrCode\Renderer\Image\ImageBackEndInterface;
+use BaconQrCode\Renderer\Image\ImagickImageBackEnd;
+use BaconQrCode\Renderer\Image\SvgImageBackEnd;
+
+class BaconQrCodeProvider implements IQRCodeProvider
+{
+    private $borderWidth = 4; // default from Bacon QR Code
+    private $backgroundColour;
+    private $foregroundColour;
+    private $format;
+
+    /**
+     * Ensure we using the latest Bacon QR Code and specify default options
+     *
+     * @param int $borderWidth space around the QR code, 4 is the default from Bacon QR Code
+     * @param string $backgroundColour hex reference for the background colour
+     * @param string $foregroundColour hex reference for the foreground colour
+     * @param string $format the desired output, png or svg
+     */
+    public function __construct($borderWidth = 4, $backgroundColour = '#ffffff', $foregroundColour = '#000000', $format = 'png')
+    {
+        if (! class_exists(ImagickImageBackEnd::class)) {
+            throw new \RuntimeException('Make sure you are using version 2 of Bacon QR Code');
+        }
+
+        $this->borderWidth = $borderWidth;
+        $this->backgroundColour = $this->handleColour($backgroundColour);
+        $this->foregroundColour = $this->handleColour($foregroundColour);
+        $this->format = strtolower($format);
+    }
+
+    /**
+     * Standard functions from IQRCodeProvider
+     */
+
+    public function getMimeType()
+    {
+        switch ($this->format) {
+            case 'png':
+                return 'image/png';
+            case 'gif':
+                return 'image/gif';
+            case 'jpg':
+            case 'jpeg':
+                return 'image/jpeg';
+            case 'svg':
+                return 'image/svg+xml';
+            case 'eps':
+                return 'application/postscript';
+        }
+
+        throw new \RuntimeException(sprintf('Unknown MIME-type: %s', $this->format));
+    }
+
+    public function getQRCodeImage($qrText, $size)
+    {
+        switch ($this->format) {
+            case 'svg':
+                $backend = new SvgImageBackEnd;
+                break;
+            case 'eps':
+                $backend = new EpsImageBackEnd;
+                break;
+            default:
+                $backend = new ImagickImageBackEnd($this->format);
+        }
+
+        $output = $this->getQRCodeByBackend($qrText, $size, $backend);
+
+        if ($this->format == 'svg') {
+            $svg = explode("\n", $output);
+            return $svg[1];
+        }
+
+        return $output;
+    }
+
+    /**
+     * Abstract QR code generation function
+     * providing colour changing support
+     */
+    private function getQRCodeByBackend($qrText, $size, ImageBackEndInterface $backend)
+    {
+        $rendererStyleArgs = array($size, $this->borderWidth);
+
+        if (is_array($this->foregroundColour) && is_array($this->backgroundColour)) {
+            $rendererStyleArgs = array_merge($rendererStyleArgs, array(
+                null,
+                null,
+                Fill::withForegroundColor(
+                    new Rgb(...$this->backgroundColour),
+                    new Rgb(...$this->foregroundColour),
+                    new EyeFill(null, null),
+                    new EyeFill(null, null),
+                    new EyeFill(null, null)
+                )
+            ));
+        }
+
+        $writer = new Writer(new ImageRenderer(
+            new RendererStyle(...$rendererStyleArgs),
+            $backend
+        ));
+
+        return $writer->writeString($qrText);
+    }
+
+    /**
+     * Ensure colour is an array of three values but also
+     * accept a string and assume its a 3 or 6 character hex
+     */
+    private function handleColour($colour)
+    {
+        if (is_string($colour) && $colour[0] == '#') {
+            $hexToRGB = function ($input) {
+                // split the array into three chunks
+                $split = str_split(trim($input, '#'), strlen($input) / 3);
+
+                // cope with three character hex reference
+                // three characters plus a # = 4
+                if (strlen($input) == 4) {
+                    array_walk($split, function (&$character) {
+                        $character = str_repeat($character, 2);
+                    });
+                }
+
+                // convert hex to rgb
+                return array_map('hexdec', $split);
+            };
+
+            return $hexToRGB($colour);
+        }
+
+        if (is_array($colour) && count($colour) == 3) {
+            return $colour;
+        }
+
+        throw new \RuntimeException('Invalid colour value');
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Qr/BaseHTTPQRCodeProvider.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Qr/BaseHTTPQRCodeProvider.php
index 5cb3add..bcc8d56 100644
--- a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Qr/BaseHTTPQRCodeProvider.php
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Qr/BaseHTTPQRCodeProvider.php
@@ -4,12 +4,18 @@
 
 abstract class BaseHTTPQRCodeProvider implements IQRCodeProvider
 {
+    /** @var bool */
     protected $verifyssl;
 
+    /**
+     * @param string $url
+     *
+     * @return string|bool
+     */
     protected function getContent($url)
     {
         $curlhandle = curl_init();
-        
+
         curl_setopt_array($curlhandle, array(
             CURLOPT_URL => $url,
             CURLOPT_RETURNTRANSFER => true,
@@ -20,8 +26,8 @@
             CURLOPT_USERAGENT => 'TwoFactorAuth'
         ));
         $data = curl_exec($curlhandle);
-        
+
         curl_close($curlhandle);
         return $data;
     }
-}
\ No newline at end of file
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Qr/EndroidQrCodeProvider.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Qr/EndroidQrCodeProvider.php
new file mode 100755
index 0000000..810aa9b
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Qr/EndroidQrCodeProvider.php
@@ -0,0 +1,70 @@
+<?php
+namespace RobThree\Auth\Providers\Qr;
+
+use Endroid\QrCode\ErrorCorrectionLevel;
+use Endroid\QrCode\QrCode;
+
+class EndroidQrCodeProvider implements IQRCodeProvider
+{
+    public $bgcolor;
+    public $color;
+    public $margin;
+    public $errorcorrectionlevel;
+
+    public function __construct($bgcolor = 'ffffff', $color = '000000', $margin = 0, $errorcorrectionlevel = 'H')
+    {
+        $this->bgcolor = $this->handleColor($bgcolor);
+        $this->color = $this->handleColor($color);
+        $this->margin = $margin;
+        $this->errorcorrectionlevel = $this->handleErrorCorrectionLevel($errorcorrectionlevel);
+    }
+
+    public function getMimeType()
+    {
+        return 'image/png';
+    }
+
+    public function getQRCodeImage($qrtext, $size)
+    {
+        return $this->qrCodeInstance($qrtext, $size)->writeString();
+    }
+
+    protected function qrCodeInstance($qrtext, $size)
+    {
+        $qrCode = new QrCode($qrtext);
+        $qrCode->setSize($size);
+
+        $qrCode->setErrorCorrectionLevel($this->errorcorrectionlevel);
+        $qrCode->setMargin($this->margin);
+        $qrCode->setBackgroundColor($this->bgcolor);
+        $qrCode->setForegroundColor($this->color);
+
+        return $qrCode;
+    }
+
+    private function handleColor($color)
+    {
+        $split = str_split($color, 2);
+        $r = hexdec($split[0]);
+        $g = hexdec($split[1]);
+        $b = hexdec($split[2]);
+
+        return ['r' => $r, 'g' => $g, 'b' => $b, 'a' => 0];
+    }
+
+    private function handleErrorCorrectionLevel($level)
+    {
+        switch ($level) {
+            case 'L':
+                return ErrorCorrectionLevel::LOW();
+            case 'M':
+                return ErrorCorrectionLevel::MEDIUM();
+            case 'Q':
+                return ErrorCorrectionLevel::QUARTILE();
+            case 'H':
+                return ErrorCorrectionLevel::HIGH();
+            default:
+                return ErrorCorrectionLevel::HIGH();
+        }
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Qr/EndroidQrCodeWithLogoProvider.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Qr/EndroidQrCodeWithLogoProvider.php
new file mode 100755
index 0000000..ed8cc98
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Qr/EndroidQrCodeWithLogoProvider.php
@@ -0,0 +1,35 @@
+<?php
+namespace RobThree\Auth\Providers\Qr;
+
+use Endroid\QrCode\ErrorCorrectionLevel;
+use Endroid\QrCode\QrCode;
+
+class EndroidQrCodeWithLogoProvider extends EndroidQrCodeProvider
+{
+    protected $logoPath;
+    protected $logoSize;
+
+    /**
+     * Adds an image to the middle of the QR Code.
+     * @param string $path Path to an image file
+     * @param array|int $size Just the width, or [width, height]
+     */
+    public function setLogo($path, $size = null)
+    {
+        $this->logoPath = $path;
+        $this->logoSize = (array)$size;
+    }
+
+    protected function qrCodeInstance($qrtext, $size) {
+        $qrCode = parent::qrCodeInstance($qrtext, $size);
+
+        if ($this->logoPath) {
+            $qrCode->setLogoPath($this->logoPath);
+            if ($this->logoSize) {
+                $qrCode->setLogoSize($this->logoSize[0], $this->logoSize[1]);
+            }
+        }
+
+        return $qrCode;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Qr/IQRCodeProvider.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Qr/IQRCodeProvider.php
index 83ed67b..e53a5ad 100644
--- a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Qr/IQRCodeProvider.php
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Qr/IQRCodeProvider.php
@@ -4,6 +4,21 @@
 
 interface IQRCodeProvider
 {
+    /**
+     * Generate and return the QR code to embed in a web page
+     *
+     * @param string $qrtext the value to encode in the QR code
+     * @param int $size the desired size of the QR code
+     *
+     * @return string file contents of the QR code
+     */
     public function getQRCodeImage($qrtext, $size);
+
+    /**
+     * Returns the appropriate mime type for the QR code
+     * that will be generated
+     *
+     * @return string
+     */
     public function getMimeType();
-}
\ No newline at end of file
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Qr/ImageChartsQRCodeProvider.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Qr/ImageChartsQRCodeProvider.php
index cc094c3..ea46ed4 100644
--- a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Qr/ImageChartsQRCodeProvider.php
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Qr/ImageChartsQRCodeProvider.php
@@ -3,37 +3,58 @@
 namespace RobThree\Auth\Providers\Qr;
 
 // https://image-charts.com
-class ImageChartsQRCodeProvider extends BaseHTTPQRCodeProvider 
+class ImageChartsQRCodeProvider extends BaseHTTPQRCodeProvider
 {
+    /** @var string */
     public $errorcorrectionlevel;
+
+    /** @var int */
     public $margin;
 
-    function __construct($verifyssl = false, $errorcorrectionlevel = 'L', $margin = 1) 
+    /**
+     * @param bool $verifyssl
+     * @param string $errorcorrectionlevel
+     * @param int $margin
+     */
+    public function __construct($verifyssl = false, $errorcorrectionlevel = 'L', $margin = 1)
     {
-        if (!is_bool($verifyssl))
-            throw new \QRException('VerifySSL must be bool');
+        if (!is_bool($verifyssl)) {
+            throw new QRException('VerifySSL must be bool');
+        }
 
         $this->verifyssl = $verifyssl;
-        
+
         $this->errorcorrectionlevel = $errorcorrectionlevel;
         $this->margin = $margin;
     }
-    
-    public function getMimeType() 
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getMimeType()
     {
         return 'image/png';
     }
-    
-    public function getQRCodeImage($qrtext, $size) 
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getQRCodeImage($qrtext, $size)
     {
         return $this->getContent($this->getUrl($qrtext, $size));
     }
-    
-    public function getUrl($qrtext, $size) 
+
+    /**
+     * @param string $qrtext the value to encode in the QR code
+     * @param int $size the desired size of the QR code
+     *
+     * @return string file contents of the QR code
+     */
+    public function getUrl($qrtext, $size)
     {
         return 'https://image-charts.com/chart?cht=qr'
-            . '&chs=' . ceil($size/2) . 'x' . ceil($size/2)
+            . '&chs=' . ceil($size / 2) . 'x' . ceil($size / 2)
             . '&chld=' . $this->errorcorrectionlevel . '|' . $this->margin
             . '&chl=' . rawurlencode($qrtext);
     }
-}
\ No newline at end of file
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Qr/QRException.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Qr/QRException.php
index c28e829..4e75f77 100644
--- a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Qr/QRException.php
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Qr/QRException.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace RobThree\Auth\Providers\Qr;
+
 use RobThree\Auth\TwoFactorAuthException;
 
-class QRException extends TwoFactorAuthException {}
\ No newline at end of file
+class QRException extends TwoFactorAuthException {}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Qr/QRServerProvider.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Qr/QRServerProvider.php
index 928b87b..2252dfc 100644
--- a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Qr/QRServerProvider.php
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Qr/QRServerProvider.php
@@ -3,22 +3,43 @@
 namespace RobThree\Auth\Providers\Qr;
 
 // http://goqr.me/api/doc/create-qr-code/
-class QRServerProvider extends BaseHTTPQRCodeProvider 
+class QRServerProvider extends BaseHTTPQRCodeProvider
 {
+    /** @var string */
     public $errorcorrectionlevel;
+
+    /** @var int */
     public $margin;
+
+    /** @var int */
     public $qzone;
+
+    /** @var string */
     public $bgcolor;
+
+    /** @var string */
     public $color;
+
+    /** @var string */
     public $format;
 
-    function __construct($verifyssl = false, $errorcorrectionlevel = 'L', $margin = 4, $qzone = 1, $bgcolor = 'ffffff', $color = '000000', $format = 'png') 
+    /**
+     * @param bool $verifyssl
+     * @param string $errorcorrectionlevel
+     * @param int $margin
+     * @param int $qzone
+     * @param string $bgcolor
+     * @param string $color
+     * @param string $format
+     */
+    public function __construct($verifyssl = false, $errorcorrectionlevel = 'L', $margin = 4, $qzone = 1, $bgcolor = 'ffffff', $color = '000000', $format = 'png')
     {
-        if (!is_bool($verifyssl))
+        if (!is_bool($verifyssl)) {
             throw new QRException('VerifySSL must be bool');
+        }
 
         $this->verifyssl = $verifyssl;
-        
+
         $this->errorcorrectionlevel = $errorcorrectionlevel;
         $this->margin = $margin;
         $this->qzone = $qzone;
@@ -26,37 +47,53 @@
         $this->color = $color;
         $this->format = $format;
     }
-    
-    public function getMimeType() 
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getMimeType()
     {
-        switch (strtolower($this->format))
-        {
-        	case 'png':
+        switch (strtolower($this->format)) {
+            case 'png':
                 return 'image/png';
-        	case 'gif':
+            case 'gif':
                 return 'image/gif';
-        	case 'jpg':
-        	case 'jpeg':
+            case 'jpg':
+            case 'jpeg':
                 return 'image/jpeg';
-        	case 'svg':
+            case 'svg':
                 return 'image/svg+xml';
-        	case 'eps':
+            case 'eps':
                 return 'application/postscript';
         }
-        throw new \QRException(sprintf('Unknown MIME-type: %s', $this->format));
+        throw new QRException(sprintf('Unknown MIME-type: %s', $this->format));
     }
-    
-    public function getQRCodeImage($qrtext, $size) 
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getQRCodeImage($qrtext, $size)
     {
         return $this->getContent($this->getUrl($qrtext, $size));
     }
-    
-    private function decodeColor($value) 
+
+    /**
+     * @param string $value
+     *
+     * @return string
+     */
+    private function decodeColor($value)
     {
         return vsprintf('%d-%d-%d', sscanf($value, "%02x%02x%02x"));
     }
-    
-    public function getUrl($qrtext, $size) 
+
+    /**
+     * @param string $qrtext the value to encode in the QR code
+     * @param int|string $size the desired size of the QR code
+     *
+     * @return string file contents of the QR code
+     */
+    public function getUrl($qrtext, $size)
     {
         return 'https://api.qrserver.com/v1/create-qr-code/'
             . '?size=' . $size . 'x' . $size
@@ -68,4 +105,4 @@
             . '&format=' . strtolower($this->format)
             . '&data=' . rawurlencode($qrtext);
     }
-}
\ No newline at end of file
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Qr/QRicketProvider.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Qr/QRicketProvider.php
index 59e27cc..166a8a9 100644
--- a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Qr/QRicketProvider.php
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Qr/QRicketProvider.php
@@ -3,45 +3,67 @@
 namespace RobThree\Auth\Providers\Qr;
 
 // http://qrickit.com/qrickit_apps/qrickit_api.php
-class QRicketProvider extends BaseHTTPQRCodeProvider 
+class QRicketProvider extends BaseHTTPQRCodeProvider
 {
+    /** @var string */
     public $errorcorrectionlevel;
-    public $margin;
-    public $qzone;
+
+    /** @var string */
     public $bgcolor;
+
+    /** @var string */
     public $color;
+
+    /** @var string */
     public $format;
 
-    function __construct($errorcorrectionlevel = 'L', $bgcolor = 'ffffff', $color = '000000', $format = 'p') 
+    /**
+     * @param string $errorcorrectionlevel
+     * @param string $bgcolor
+     * @param string $color
+     * @param string $format
+     */
+    public function __construct($errorcorrectionlevel = 'L', $bgcolor = 'ffffff', $color = '000000', $format = 'p')
     {
         $this->verifyssl = false;
-        
+
         $this->errorcorrectionlevel = $errorcorrectionlevel;
         $this->bgcolor = $bgcolor;
         $this->color = $color;
         $this->format = $format;
     }
-    
-    public function getMimeType() 
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getMimeType()
     {
-        switch (strtolower($this->format))
-        {
-        	case 'p':
+        switch (strtolower($this->format)) {
+            case 'p':
                 return 'image/png';
-        	case 'g':
+            case 'g':
                 return 'image/gif';
-        	case 'j':
+            case 'j':
                 return 'image/jpeg';
         }
-        throw new \QRException(sprintf('Unknown MIME-type: %s', $this->format));
+        throw new QRException(sprintf('Unknown MIME-type: %s', $this->format));
     }
-    
-    public function getQRCodeImage($qrtext, $size) 
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getQRCodeImage($qrtext, $size)
     {
         return $this->getContent($this->getUrl($qrtext, $size));
     }
-    
-    public function getUrl($qrtext, $size) 
+
+    /**
+     * @param string $qrtext the value to encode in the QR code
+     * @param int|string $size the desired size of the QR code
+     *
+     * @return string file contents of the QR code
+     */
+    public function getUrl($qrtext, $size)
     {
         return 'http://qrickit.com/api/qr'
             . '?qrsize=' . $size
@@ -51,4 +73,4 @@
             . '&t=' . strtolower($this->format)
             . '&d=' . rawurlencode($qrtext);
     }
-}
\ No newline at end of file
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Rng/CSRNGProvider.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Rng/CSRNGProvider.php
index 8dba7fc..088edab 100644
--- a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Rng/CSRNGProvider.php
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Rng/CSRNGProvider.php
@@ -4,11 +4,19 @@
 
 class CSRNGProvider implements IRNGProvider
 {
-    public function getRandomBytes($bytecount) {
+    /**
+     * {@inheritdoc}
+     */
+    public function getRandomBytes($bytecount)
+    {
         return random_bytes($bytecount);    // PHP7+
     }
-    
-    public function isCryptographicallySecure() {
+
+    /**
+     * {@inheritdoc}
+     */
+    public function isCryptographicallySecure()
+    {
         return true;
     }
-}
\ No newline at end of file
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Rng/HashRNGProvider.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Rng/HashRNGProvider.php
index eb42577..d17a5f8 100644
--- a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Rng/HashRNGProvider.php
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Rng/HashRNGProvider.php
@@ -1,28 +1,43 @@
 <?php
+
 namespace RobThree\Auth\Providers\Rng;
 
 class HashRNGProvider implements IRNGProvider
 {
+    /** @var string */
     private $algorithm;
-    
-    function __construct($algorithm = 'sha256' ) {
+
+    /**
+     * @param string $algorithm
+     */
+    public function __construct($algorithm = 'sha256')
+    {
         $algos = array_values(hash_algos());
-        if (!in_array($algorithm, $algos, true))
-            throw new \RNGException('Unsupported algorithm specified');
+        if (!in_array($algorithm, $algos, true)) {
+            throw new RNGException('Unsupported algorithm specified');
+        }
         $this->algorithm = $algorithm;
     }
-    
-    public function getRandomBytes($bytecount) {
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getRandomBytes($bytecount)
+    {
         $result = '';
         $hash = mt_rand();
         for ($i = 0; $i < $bytecount; $i++) {
-            $hash = hash($this->algorithm, $hash.mt_rand(), true);
-            $result .= $hash[mt_rand(0, strlen($hash)-1)];
+            $hash = hash($this->algorithm, $hash . mt_rand(), true);
+            $result .= $hash[mt_rand(0, strlen($hash) - 1)];
         }
         return $result;
     }
-    
-    public function isCryptographicallySecure() {
+
+    /**
+     * {@inheritdoc}
+     */
+    public function isCryptographicallySecure()
+    {
         return false;
     }
 }
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Rng/IRNGProvider.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Rng/IRNGProvider.php
index 6be2800..e4e71c2 100644
--- a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Rng/IRNGProvider.php
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Rng/IRNGProvider.php
@@ -4,6 +4,15 @@
 
 interface IRNGProvider
 {
+    /**
+     * @param int $bytecount the number of bytes of randomness to return
+     *
+     * @return string the random bytes
+     */
     public function getRandomBytes($bytecount);
+
+    /**
+     * @return bool whether this provider is cryptographically secure
+     */
     public function isCryptographicallySecure();
-}
\ No newline at end of file
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Rng/MCryptRNGProvider.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Rng/MCryptRNGProvider.php
index 0eeab2c..d1b6430 100644
--- a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Rng/MCryptRNGProvider.php
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Rng/MCryptRNGProvider.php
@@ -4,20 +4,34 @@
 
 class MCryptRNGProvider implements IRNGProvider
 {
+    /** @var int */
     private $source;
-    
-    function __construct($source = MCRYPT_DEV_URANDOM) {
+
+    /**
+     * @param int $source
+     */
+    public function __construct($source = MCRYPT_DEV_URANDOM)
+    {
         $this->source = $source;
     }
-    
-    public function getRandomBytes($bytecount) {
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getRandomBytes($bytecount)
+    {
         $result = @mcrypt_create_iv($bytecount, $this->source);
-        if ($result === false)
-            throw new \RNGException('mcrypt_create_iv returned an invalid value');
+        if ($result === false) {
+            throw new RNGException('mcrypt_create_iv returned an invalid value');
+        }
         return $result;
     }
-    
-    public function isCryptographicallySecure() {
+
+    /**
+     * {@inheritdoc}
+     */
+    public function isCryptographicallySecure()
+    {
         return true;
     }
-}
\ No newline at end of file
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Rng/OpenSSLRNGProvider.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Rng/OpenSSLRNGProvider.php
index dc66c64..eb82b3b 100644
--- a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Rng/OpenSSLRNGProvider.php
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Rng/OpenSSLRNGProvider.php
@@ -4,22 +4,37 @@
 
 class OpenSSLRNGProvider implements IRNGProvider
 {
+    /** @var bool */
     private $requirestrong;
-    
-    function __construct($requirestrong = true) {
+
+    /**
+     * @param bool $requirestrong
+     */
+    public function __construct($requirestrong = true)
+    {
         $this->requirestrong = $requirestrong;
     }
-    
-    public function getRandomBytes($bytecount) {
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getRandomBytes($bytecount)
+    {
         $result = openssl_random_pseudo_bytes($bytecount, $crypto_strong);
-        if ($this->requirestrong && ($crypto_strong === false))
-            throw new \RNGException('openssl_random_pseudo_bytes returned non-cryptographically strong value');
-        if ($result === false)
-            throw new \RNGException('openssl_random_pseudo_bytes returned an invalid value');
+        if ($this->requirestrong && ($crypto_strong === false)) {
+            throw new RNGException('openssl_random_pseudo_bytes returned non-cryptographically strong value');
+        }
+        if ($result === false) {
+            throw new RNGException('openssl_random_pseudo_bytes returned an invalid value');
+        }
         return $result;
     }
-    
-    public function isCryptographicallySecure() {
+
+    /**
+     * {@inheritdoc}
+     */
+    public function isCryptographicallySecure()
+    {
         return $this->requirestrong;
     }
-}
\ No newline at end of file
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Rng/RNGException.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Rng/RNGException.php
index eb5e913..f9a11ac 100644
--- a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Rng/RNGException.php
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Rng/RNGException.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace RobThree\Auth\Providers\Rng;
+
 use RobThree\Auth\TwoFactorAuthException;
 
-class RNGException extends TwoFactorAuthException {}
\ No newline at end of file
+class RNGException extends TwoFactorAuthException {}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Time/HttpTimeProvider.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Time/HttpTimeProvider.php
index 8e7806e..c346e5a 100644
--- a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Time/HttpTimeProvider.php
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Time/HttpTimeProvider.php
@@ -2,22 +2,33 @@
 
 namespace RobThree\Auth\Providers\Time;
 
+use DateTime;
+
 /**
  * Takes the time from any webserver by doing a HEAD request on the specified URL and extracting the 'Date:' header
  */
 class HttpTimeProvider implements ITimeProvider
 {
+    /** @var string */
     public $url;
-    public $options;
+
+    /** @var string */
     public $expectedtimeformat;
 
-    function __construct($url = 'https://google.com', $expectedtimeformat = 'D, d M Y H:i:s O+', array $options = null)
+    /** @var array */
+    public $options;
+
+    /**
+     * @param string $url
+     * @param string $expectedtimeformat
+     * @param array $options
+     */
+    public function __construct($url = 'https://google.com', $expectedtimeformat = 'D, d M Y H:i:s O+', array $options = null)
     {
         $this->url = $url;
         $this->expectedtimeformat = $expectedtimeformat;
-        $this->options = $options;
-        if ($this->options === null) {
-            $this->options = array(
+        if ($options === null) {
+            $options = array(
                 'http' => array(
                     'method' => 'HEAD',
                     'follow_location' => false,
@@ -32,9 +43,14 @@
                 )
             );
         }
+        $this->options = $options;
     }
 
-    public function getTime() {
+    /**
+     * {@inheritdoc}
+     */
+    public function getTime()
+    {
         try {
             $context  = stream_context_create($this->options);
             $fd = fopen($this->url, 'rb', false, $context);
@@ -42,13 +58,14 @@
             fclose($fd);
 
             foreach ($headers['wrapper_data'] as $h) {
-                if (strcasecmp(substr($h, 0, 5), 'Date:') === 0)
-                    return \DateTime::createFromFormat($this->expectedtimeformat, trim(substr($h,5)))->getTimestamp();
+                if (strcasecmp(substr($h, 0, 5), 'Date:') === 0) {
+                    return DateTime::createFromFormat($this->expectedtimeformat, trim(substr($h, 5)))->getTimestamp();
+                }
             }
-            throw new \TimeException(sprintf('Unable to retrieve time from %s (Invalid or no "Date:" header found)', $this->url));
+            throw new \Exception('Invalid or no "Date:" header found');
+        } catch (\Exception $ex) {
+            throw new TimeException(sprintf('Unable to retrieve time from %s (%s)', $this->url, $ex->getMessage()));
         }
-        catch (Exception $ex) {
-            throw new \TimeException(sprintf('Unable to retrieve time from %s (%s)', $this->url, $ex->getMessage()));
-        }
+
     }
-}
\ No newline at end of file
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Time/ITimeProvider.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Time/ITimeProvider.php
index a3b87a2..4799f17 100644
--- a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Time/ITimeProvider.php
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Time/ITimeProvider.php
@@ -4,5 +4,8 @@
 
 interface ITimeProvider
 {
+    /**
+     * @return int the current timestamp according to this provider
+     */
     public function getTime();
-}
\ No newline at end of file
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Time/LocalMachineTimeProvider.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Time/LocalMachineTimeProvider.php
index 572cedc..2fe6846 100644
--- a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Time/LocalMachineTimeProvider.php
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Time/LocalMachineTimeProvider.php
@@ -2,8 +2,10 @@
 
 namespace RobThree\Auth\Providers\Time;
 
-class LocalMachineTimeProvider implements ITimeProvider {
-    public function getTime() {
+class LocalMachineTimeProvider implements ITimeProvider
+{
+    public function getTime()
+    {
         return time();
     }
-}
\ No newline at end of file
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Time/NTPTimeProvider.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Time/NTPTimeProvider.php
index d69a3a6..a701850 100644
--- a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Time/NTPTimeProvider.php
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Time/NTPTimeProvider.php
@@ -7,24 +7,40 @@
  */
 class NTPTimeProvider implements ITimeProvider
 {
+    /** @var string */
     public $host;
+
+    /** @var int */
     public $port;
+
+    /** @var int */
     public $timeout;
 
-    function __construct($host = 'time.google.com', $port = 123, $timeout = 1)
+    /**
+     * @param string $host
+     * @param int $port
+     * @param int $timeout
+     */
+    public function __construct($host = 'time.google.com', $port = 123, $timeout = 1)
     {
         $this->host = $host;
 
-        if (!is_int($port) || $port <= 0 || $port > 65535)
-            throw new \TimeException('Port must be 0 < port < 65535');
+        if (!is_int($port) || $port <= 0 || $port > 65535) {
+            throw new TimeException('Port must be 0 < port < 65535');
+        }
         $this->port = $port;
 
-        if (!is_int($timeout) || $timeout < 0)
-            throw new \TimeException('Timeout must be >= 0');
+        if (!is_int($timeout) || $timeout < 0) {
+            throw new TimeException('Timeout must be >= 0');
+        }
         $this->timeout = $timeout;
     }
 
-    public function getTime() {
+    /**
+     * {@inheritdoc}
+     */
+    public function getTime()
+    {
         try {
             /* Create a socket and connect to NTP server */
             $sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
@@ -36,19 +52,19 @@
             socket_send($sock, $msg, strlen($msg), 0);
 
             /* Receive response and close socket */
-            if (socket_recv($sock, $recv, 48, MSG_WAITALL) === false)
+            if (socket_recv($sock, $recv, 48, MSG_WAITALL) === false) {
                 throw new \Exception(socket_strerror(socket_last_error($sock)));
+            }
             socket_close($sock);
 
             /* Interpret response */
             $data = unpack('N12', $recv);
-            $timestamp = sprintf('%u', $data[9]);
+            $timestamp = (int) sprintf('%u', $data[9]);
 
             /* NTP is number of seconds since 0000 UT on 1 January 1900 Unix time is seconds since 0000 UT on 1 January 1970 */
             return $timestamp - 2208988800;
-        }
-        catch (Exception $ex) {
-            throw new \TimeException(sprintf('Unable to retrieve time from %s (%s)', $this->host, $ex->getMessage()));
+        } catch (\Exception $ex) {
+            throw new TimeException(sprintf('Unable to retrieve time from %s (%s)', $this->host, $ex->getMessage()));
         }
     }
 }
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Time/TimeException.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Time/TimeException.php
index 8de544d..c5a06e2 100644
--- a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Time/TimeException.php
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/Providers/Time/TimeException.php
@@ -1,5 +1,7 @@
 <?php
 
+namespace RobThree\Auth\Providers\Time;
+
 use RobThree\Auth\TwoFactorAuthException;
 
-class TimeException extends TwoFactorAuthException {}
\ No newline at end of file
+class TimeException extends TwoFactorAuthException {}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/TwoFactorAuth.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/TwoFactorAuth.php
index 7bc067d..c46ac17 100644
--- a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/TwoFactorAuth.php
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/TwoFactorAuth.php
@@ -1,40 +1,82 @@
 <?php
+
 namespace RobThree\Auth;
 
 use RobThree\Auth\Providers\Qr\IQRCodeProvider;
+use RobThree\Auth\Providers\Qr\QRServerProvider;
+use RobThree\Auth\Providers\Rng\CSRNGProvider;
+use RobThree\Auth\Providers\Rng\HashRNGProvider;
 use RobThree\Auth\Providers\Rng\IRNGProvider;
+use RobThree\Auth\Providers\Rng\MCryptRNGProvider;
+use RobThree\Auth\Providers\Rng\OpenSSLRNGProvider;
+use RobThree\Auth\Providers\Time\HttpTimeProvider;
 use RobThree\Auth\Providers\Time\ITimeProvider;
+use RobThree\Auth\Providers\Time\LocalMachineTimeProvider;
+use RobThree\Auth\Providers\Time\NTPTimeProvider;
 
 // Based on / inspired by: https://github.com/PHPGangsta/GoogleAuthenticator
 // Algorithms, digits, period etc. explained: https://github.com/google/google-authenticator/wiki/Key-Uri-Format
 class TwoFactorAuth
 {
+    /** @var string */
     private $algorithm;
+
+    /** @var int */
     private $period;
+
+    /** @var int */
     private $digits;
+
+    /** @var string */
     private $issuer;
+
+    /** @var ?IQRCodeProvider */
     private $qrcodeprovider = null;
+
+    /** @var ?IRNGProvider */
     private $rngprovider = null;
+
+    /** @var ?ITimeProvider */
     private $timeprovider = null;
+
+    /** @var string */
     private static $_base32dict = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=';
+
+    /** @var array */
     private static $_base32;
+
+    /** @var array */
     private static $_base32lookup = array();
+
+    /** @var array */
     private static $_supportedalgos = array('sha1', 'sha256', 'sha512', 'md5');
 
-    function __construct($issuer = null, $digits = 6, $period = 30, $algorithm = 'sha1', IQRCodeProvider $qrcodeprovider = null, IRNGProvider $rngprovider = null, ITimeProvider $timeprovider = null)
+    /**
+     * @param ?string $issuer
+     * @param int $digits
+     * @param int $period
+     * @param string $algorithm
+     * @param ?IQRCodeProvider $qrcodeprovider
+     * @param ?IRNGProvider $rngprovider
+     * @param ?ITimeProvider $timeprovider
+     */
+    public function __construct($issuer = null, $digits = 6, $period = 30, $algorithm = 'sha1', IQRCodeProvider $qrcodeprovider = null, IRNGProvider $rngprovider = null, ITimeProvider $timeprovider = null)
     {
         $this->issuer = $issuer;
-        if (!is_int($digits) || $digits <= 0)
+        if (!is_int($digits) || $digits <= 0) {
             throw new TwoFactorAuthException('Digits must be int > 0');
+        }
         $this->digits = $digits;
 
-        if (!is_int($period) || $period <= 0)
+        if (!is_int($period) || $period <= 0) {
             throw new TwoFactorAuthException('Period must be int > 0');
+        }
         $this->period = $period;
 
         $algorithm = strtolower(trim($algorithm));
-        if (!in_array($algorithm, self::$_supportedalgos))
+        if (!in_array($algorithm, self::$_supportedalgos)) {
             throw new TwoFactorAuthException('Unsupported algorithm: ' . $algorithm);
+        }
         $this->algorithm = $algorithm;
         $this->qrcodeprovider = $qrcodeprovider;
         $this->rngprovider = $rngprovider;
@@ -46,22 +88,34 @@
 
     /**
      * Create a new secret
+     *
+     * @param int $bits
+     * @param bool $requirecryptosecure
+     *
+     * @return string
      */
     public function createSecret($bits = 80, $requirecryptosecure = true)
     {
         $secret = '';
-        $bytes = ceil($bits / 5);   //We use 5 bits of each byte (since we have a 32-character 'alphabet' / BASE32)
-        $rngprovider = $this->getRngprovider();
-        if ($requirecryptosecure && !$rngprovider->isCryptographicallySecure())
+        $bytes = (int) ceil($bits / 5);   //We use 5 bits of each byte (since we have a 32-character 'alphabet' / BASE32)
+        $rngprovider = $this->getRngProvider();
+        if ($requirecryptosecure && !$rngprovider->isCryptographicallySecure()) {
             throw new TwoFactorAuthException('RNG provider is not cryptographically secure');
+        }
         $rnd = $rngprovider->getRandomBytes($bytes);
-        for ($i = 0; $i < $bytes; $i++)
+        for ($i = 0; $i < $bytes; $i++) {
             $secret .= self::$_base32[ord($rnd[$i]) & 31];  //Mask out left 3 bits for 0-31 values
+        }
         return $secret;
     }
 
     /**
      * Calculate the code with given secret and point in time
+     *
+     * @param string $secret
+     * @param ?int $time
+     *
+     * @return string
      */
     public function getCode($secret, $time = null)
     {
@@ -73,15 +127,23 @@
         $value = unpack('N', $hashpart);                                                   // Unpack binary value
         $value = $value[1] & 0x7FFFFFFF;                                                   // Drop MSB, keep only 31 bits
 
-        return str_pad($value % pow(10, $this->digits), $this->digits, '0', STR_PAD_LEFT);
+        return str_pad((string) ($value % pow(10, $this->digits)), $this->digits, '0', STR_PAD_LEFT);
     }
 
     /**
      * Check if the code is correct. This will accept codes starting from ($discrepancy * $period) sec ago to ($discrepancy * period) sec from now
+     *
+     * @param string $secret
+     * @param string $code
+     * @param int $discrepancy
+     * @param ?int $time
+     * @param int $timeslice
+     *
+     * @return bool
      */
     public function verifyCode($secret, $code, $discrepancy = 1, $time = null, &$timeslice = 0)
     {
-        $timetamp = $this->getTime($time);
+        $timestamp = $this->getTime($time);
 
         $timeslice = 0;
 
@@ -90,7 +152,7 @@
         // of the match. Each iteration we either set the timeslice variable to the timeslice of the match
         // or set the value to itself.  This is an effort to maintain constant execution time for the code.
         for ($i = -$discrepancy; $i <= $discrepancy; $i++) {
-            $ts = $timetamp + ($i * $this->period);
+            $ts = $timestamp + ($i * $this->period);
             $slice = $this->getTimeSlice($ts);
             $timeslice = $this->codeEquals($this->getCode($secret, $ts), $code) ? $slice : $timeslice;
         }
@@ -100,17 +162,24 @@
 
     /**
      * Timing-attack safe comparison of 2 codes (see http://blog.ircmaxell.com/2014/11/its-all-about-time.html)
+     *
+     * @param string $safe
+     * @param string $user
+     *
+     * @return bool
      */
-    private function codeEquals($safe, $user) {
+    private function codeEquals($safe, $user)
+    {
         if (function_exists('hash_equals')) {
             return hash_equals($safe, $user);
         }
         // In general, it's not possible to prevent length leaks. So it's OK to leak the length. The important part is that
         // we don't leak information about the difference of the two strings.
-        if (strlen($safe)===strlen($user)) {
+        if (strlen($safe) === strlen($user)) {
             $result = 0;
-            for ($i = 0; $i < strlen($safe); $i++)
+            for ($i = 0; $i < strlen($safe); $i++) {
                 $result |= (ord($safe[$i]) ^ ord($user[$i]));
+            }
             return $result === 0;
         }
         return false;
@@ -118,11 +187,18 @@
 
     /**
      * Get data-uri of QRCode
+     *
+     * @param string $label
+     * @param string $secret
+     * @param mixed $size
+     *
+     * @return string
      */
     public function getQRCodeImageAsDataUri($label, $secret, $size = 200)
     {
-        if (!is_int($size) || $size <= 0)
+        if (!is_int($size) || $size <= 0) {
             throw new TwoFactorAuthException('Size must be int > 0');
+        }
 
         $qrcodeprovider = $this->getQrCodeProvider();
         return 'data:'
@@ -133,37 +209,52 @@
 
     /**
      * Compare default timeprovider with specified timeproviders and ensure the time is within the specified number of seconds (leniency)
+     * @param ?array $timeproviders
+     * @param int $leniency
+     *
+     * @return void
      */
     public function ensureCorrectTime(array $timeproviders = null, $leniency = 5)
     {
-        if ($timeproviders != null && !is_array($timeproviders))
-            throw new TwoFactorAuthException('No timeproviders specified');
-
-        if ($timeproviders == null)
+        if ($timeproviders === null) {
             $timeproviders = array(
-                new Providers\Time\NTPTimeProvider(),
-                new Providers\Time\HttpTimeProvider()
+                new NTPTimeProvider(),
+                new HttpTimeProvider()
             );
+        }
 
         // Get default time provider
         $timeprovider = $this->getTimeProvider();
 
         // Iterate specified time providers
         foreach ($timeproviders as $t) {
-            if (!($t instanceof ITimeProvider))
+            if (!($t instanceof ITimeProvider)) {
                 throw new TwoFactorAuthException('Object does not implement ITimeProvider');
+            }
 
             // Get time from default time provider and compare to specific time provider and throw if time difference is more than specified number of seconds leniency
-            if (abs($timeprovider->getTime() - $t->getTime()) > $leniency)
+            if (abs($timeprovider->getTime() - $t->getTime()) > $leniency) {
                 throw new TwoFactorAuthException(sprintf('Time for timeprovider is off by more than %d seconds when compared to %s', $leniency, get_class($t)));
+            }
         }
     }
 
-    private function getTime($time)
+    /**
+     * @param ?int $time
+     *
+     * @return int
+     */
+    private function getTime($time = null)
     {
         return ($time === null) ? $this->getTimeProvider()->getTime() : $time;
     }
 
+    /**
+     * @param int $time
+     * @param int $offset
+     *
+     * @return int
+     */
     private function getTimeSlice($time = null, $offset = 0)
     {
         return (int)floor($time / $this->period) + ($offset * $this->period);
@@ -171,6 +262,11 @@
 
     /**
      * Builds a string to be encoded in a QR code
+     *
+     * @param string $label
+     * @param string $secret
+     *
+     * @return string
      */
     public function getQRText($label, $secret)
     {
@@ -182,25 +278,33 @@
             . '&digits=' . intval($this->digits);
     }
 
+    /**
+     * @param string $value
+     * @return string
+     */
     private function base32Decode($value)
     {
-        if (strlen($value)==0) return '';
+        if (strlen($value) == 0) {
+            return '';
+        }
 
-        if (preg_match('/[^'.preg_quote(self::$_base32dict).']/', $value) !== 0)
+        if (preg_match('/[^' . preg_quote(self::$_base32dict) . ']/', $value) !== 0) {
             throw new TwoFactorAuthException('Invalid base32 string');
+        }
 
         $buffer = '';
-        foreach (str_split($value) as $char)
-        {
-            if ($char !== '=')
-                $buffer .= str_pad(decbin(self::$_base32lookup[$char]), 5, 0, STR_PAD_LEFT);
+        foreach (str_split($value) as $char) {
+            if ($char !== '=') {
+                $buffer .= str_pad(decbin(self::$_base32lookup[$char]), 5, '0', STR_PAD_LEFT);
+            }
         }
         $length = strlen($buffer);
         $blocks = trim(chunk_split(substr($buffer, 0, $length - ($length % 8)), 8, ' '));
 
         $output = '';
-        foreach (explode(' ', $blocks) as $block)
-            $output .= chr(bindec(str_pad($block, 8, 0, STR_PAD_RIGHT)));
+        foreach (explode(' ', $blocks) as $block) {
+            $output .= chr(bindec(str_pad($block, 8, '0', STR_PAD_RIGHT)));
+        }
         return $output;
     }
 
@@ -212,7 +316,7 @@
     {
         // Set default QR Code provider if none was specified
         if (null === $this->qrcodeprovider) {
-            return $this->qrcodeprovider = new Providers\Qr\QRServerProvider();
+            return $this->qrcodeprovider = new QRServerProvider();
         }
         return $this->qrcodeprovider;
     }
@@ -221,22 +325,22 @@
      * @return IRNGProvider
      * @throws TwoFactorAuthException
      */
-    public function getRngprovider()
+    public function getRngProvider()
     {
         if (null !== $this->rngprovider) {
             return $this->rngprovider;
         }
         if (function_exists('random_bytes')) {
-            return $this->rngprovider = new Providers\Rng\CSRNGProvider();
+            return $this->rngprovider = new CSRNGProvider();
         }
         if (function_exists('mcrypt_create_iv')) {
-            return $this->rngprovider = new Providers\Rng\MCryptRNGProvider();
+            return $this->rngprovider = new MCryptRNGProvider();
         }
         if (function_exists('openssl_random_pseudo_bytes')) {
-            return $this->rngprovider = new Providers\Rng\OpenSSLRNGProvider();
+            return $this->rngprovider = new OpenSSLRNGProvider();
         }
         if (function_exists('hash')) {
-            return $this->rngprovider = new Providers\Rng\HashRNGProvider();
+            return $this->rngprovider = new HashRNGProvider();
         }
         throw new TwoFactorAuthException('Unable to find a suited RNGProvider');
     }
@@ -249,8 +353,8 @@
     {
         // Set default time provider if none was specified
         if (null === $this->timeprovider) {
-            return $this->timeprovider = new Providers\Time\LocalMachineTimeProvider();
+            return $this->timeprovider = new LocalMachineTimeProvider();
         }
         return $this->timeprovider;
     }
-}
\ No newline at end of file
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/TwoFactorAuthException.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/TwoFactorAuthException.php
index af51b74..bce8370 100644
--- a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/TwoFactorAuthException.php
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/robthree/twofactorauth/lib/TwoFactorAuthException.php
@@ -4,4 +4,4 @@
 
 use Exception;
 
-class TwoFactorAuthException extends \Exception {}
\ No newline at end of file
+class TwoFactorAuthException extends Exception {}