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
+}