diff --git a/application/forms/Account/TotpForm.php b/application/forms/Account/TotpForm.php
index d48d2239b..ed492ff60 100644
--- a/application/forms/Account/TotpForm.php
+++ b/application/forms/Account/TotpForm.php
@@ -174,6 +174,7 @@ class TotpForm extends PreferenceForm
'HtmlTag', [
'tag' => 'img',
'src' => $this->totp->createQRCode(),
+ 'class' => 'qr-code-image'
]
]
]
@@ -190,7 +191,7 @@ class TotpForm extends PreferenceForm
'HtmlTag',
[
'tag' => 'div',
- 'class' => 'control-group form-controls'
+ 'class' => 'control-group form-controls aligned-group'
]
]
]
diff --git a/library/Icinga/Authentication/Totp.php b/library/Icinga/Authentication/Totp.php
index 92fcdf9f5..5179a0da6 100644
--- a/library/Icinga/Authentication/Totp.php
+++ b/library/Icinga/Authentication/Totp.php
@@ -2,7 +2,6 @@
namespace Icinga\Authentication;
-use chillerlan\QRCode\Common\EccLevel;
use chillerlan\QRCode\Data\QRMatrix;
use chillerlan\QRCode\QRCode;
use chillerlan\QRCode\QROptions;
@@ -20,7 +19,6 @@ use ipl\Sql\Select;
use ipl\Sql\Update;
use ipl\Stdlib\Filter;
use OTPHP\TOTP as extTOTP;
-use Zend_Db_Expr;
class Totp
{
@@ -180,7 +178,6 @@ class Totp
public function verify(string $code): bool
{
if ($this->totpObject === null) {
-
return false;
}
@@ -217,7 +214,7 @@ class Totp
$this->setTotpObjects(true)
->setState(self::STATE_SECRET_CHECK_REQUIRED)
->setState(self::STATE_HAS_PENDING_CHANGES)
- ->removeState(self::STATE_APPROVED_TEMPORARY_SECRET);
+ ->removeState(self::STATE_APPROVED_TEMPORARY_SECRET);
return $this;
}
@@ -375,7 +372,6 @@ class Totp
public function createQRCode(): ?string
{
if ($this->temporaryTotpObject === null) {
-
return null;
}
@@ -387,19 +383,26 @@ class Totp
urlencode($this->temporarySecret),
);
$options = new QROptions();
+ $options->drawLightModules = true;
+ $options->svgUseFillAttributes = true;
+ $options->drawCircularModules = true;
+ $options->circleRadius = 0.4;
+ $options->connectPaths = true;
+ $options->keepAsSquare = [
+ QRMatrix::M_FINDER_DARK,
+ QRMatrix::M_FINDER_DOT,
+ QRMatrix::M_ALIGNMENT_DARK,
+ ];
- $options->scale = 5;
-
-// $options->svgLogo = __DIR__.'/github.svg'; // logo from: https://github.com/simple-icons/simple-icons
-// $options->svgLogoScale = 0.25;
-// $options->svgLogoCssClass = 'dark';
-//
-// $options->addLogoSpace = true;
-// $options->logoSpaceWidth = 19;
-// $options->logoSpaceHeight = 19;
-// $options->logoSpaceStartX = 25;
-// $options->logoSpaceStartY = 25;
-// $options->eccLevel = EccLevel::H;
+ $options->svgDefs = '
+
+
+
+
+ ';
return (new QRCode($options))->render($urlOTPAUTH);
}
@@ -538,8 +541,8 @@ class Totp
private function createTotpObject(string $secret = null): extTOTP
{
$totpObject = ($secret === null)
- ? extTOTP::generate($this->clock)
- : extTOTP::createFromSecret($secret, $this->clock);
+ ? extTOTP::generate($this->clock)
+ : extTOTP::createFromSecret($secret, $this->clock);
$totpObject->setLabel(self::TOTP_LABEL);
$totpObject->setIssuer($this->username);
@@ -574,7 +577,7 @@ class Totp
*/
private function setState(string $key): self
{
- if (! in_array($key, $this->currentStates, true)) {
+ if (!in_array($key, $this->currentStates, true)) {
$this->currentStates[] = $key;
}
diff --git a/public/css/icinga/forms.less b/public/css/icinga/forms.less
index f396f59c4..f188755bd 100644
--- a/public/css/icinga/forms.less
+++ b/public/css/icinga/forms.less
@@ -44,6 +44,11 @@ form.icinga-form {
justify-content: flex-end;
}
+ .aligned-group {
+ align-items: center;
+ justify-content: center;
+ }
+
&.inline {
width: auto;
@@ -595,3 +600,14 @@ form.icinga-form .form-info {
}
}
}
+
+// QR code image style
+.qr-code-image {
+ display: block;
+ margin: 0 auto;
+ width: 20em;
+ height: 20em;
+ border: .25em solid transparent;
+ border-radius: .25em;
+ box-shadow: 0 0 .25em 0 rgba(0,0,0,.4);
+}