From e643dcc41349dc3c2bf65a06142ee768cda0eb89 Mon Sep 17 00:00:00 2001 From: Johannes Rauh Date: Tue, 2 Dec 2025 15:35:52 +0100 Subject: [PATCH] Add 'Download QR Code' action link So the user can download the QR code to backup if they lose access to their device. The download currently does only work in chrome and firefox, but not in safari. The reason is, that the action link uses `ipl\Web\Url` which adds '///' between the schema and the base path. The safari browser can't handle this. 'data:image/png;base64,...' is converted to 'data:///image/png;base64...'. --- .../forms/Account/TwoFactorConfigForm.php | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/application/forms/Account/TwoFactorConfigForm.php b/application/forms/Account/TwoFactorConfigForm.php index a77bf8a77..bff80be04 100644 --- a/application/forms/Account/TwoFactorConfigForm.php +++ b/application/forms/Account/TwoFactorConfigForm.php @@ -18,6 +18,7 @@ use ipl\Web\Common\CsrfCounterMeasure; use ipl\Web\Common\FormUid; use ipl\Web\Compat\CompatForm; use ipl\Web\Url; +use ipl\Web\Widget\ActionLink; use ipl\Web\Widget\CopyToClipboard; /** @@ -112,15 +113,28 @@ class TwoFactorConfigForm extends CompatForm $this->twoFactor = TwoFactorTotp::createFromSecret($secret, $this->user->getUsername()); } + $qrCode = $this->twoFactor->createQRCode(); + $this->addHtml(new FakeFormElement( - HtmlElement::create('img', Attributes::create([ - 'class' => 'two-factor-totp-qr-code', - 'src' => $this->twoFactor->createQRCode() - ])), + HtmlElement::create( + 'img', + Attributes::create(['class' => 'two-factor-totp-qr-code', 'src' => $qrCode]) + ), $this->translate('QR Code'), $this->translate('Use your authenticator app to scan the QR code.') )); + $this->addHtml(new FakeFormElement( + new ActionLink( + 'Download QR Code (e.g. for Recovery)', + $qrCode, + 'download', + Attributes::create(['download' => 'icinga-web-totp-qr-code.png']) + ), + description: $this->translate('Download the QR code to back up your two-factor' + . ' authentication in case you lose access to your device.') + )); + $manualAuthUrl = HtmlElement::create( 'div', Attributes::create(['class' => 'two-factor-totp-auth-url']),