]> BookStack Code Mirror - bookstack/blob - app/Auth/Access/Mfa/TotpService.php
Fixes for CodeStyle vol.2
[bookstack] / app / Auth / Access / Mfa / TotpService.php
1 <?php
2
3 namespace BookStack\Auth\Access\Mfa;
4
5 use BaconQrCode\Renderer\Color\Rgb;
6 use BaconQrCode\Renderer\Image\SvgImageBackEnd;
7 use BaconQrCode\Renderer\ImageRenderer;
8 use BaconQrCode\Renderer\RendererStyle\Fill;
9 use BaconQrCode\Renderer\RendererStyle\RendererStyle;
10 use BaconQrCode\Writer;
11 use PragmaRX\Google2FA\Google2FA;
12 use PragmaRX\Google2FA\Support\Constants;
13
14 class TotpService
15 {
16     protected $google2fa;
17
18     public function __construct(Google2FA $google2fa)
19     {
20         $this->google2fa = $google2fa;
21         // Use SHA1 as a default, Personal testing of other options in 2021 found
22         // many apps lack support for other algorithms yet still will scan
23         // the code causing a confusing UX.
24         $this->google2fa->setAlgorithm(Constants::SHA1);
25     }
26
27     /**
28      * Generate a new totp secret key.
29      */
30     public function generateSecret(): string
31     {
32         /** @noinspection PhpUnhandledExceptionInspection */
33         return $this->google2fa->generateSecretKey();
34     }
35
36     /**
37      * Generate a TOTP URL from secret key.
38      */
39     public function generateUrl(string $secret): string
40     {
41         return $this->google2fa->getQRCodeUrl(
42             setting('app-name'),
43             user()->email,
44             $secret
45         );
46     }
47
48     /**
49      * Generate a QR code to display a TOTP URL.
50      */
51     public function generateQrCodeSvg(string $url): string
52     {
53         $color = Fill::uniformColor(new Rgb(255, 255, 255), new Rgb(32, 110, 167));
54
55         return (new Writer(
56             new ImageRenderer(
57                 new RendererStyle(192, 0, null, null, $color),
58                 new SvgImageBackEnd()
59             )
60         ))->writeString($url);
61     }
62
63     /**
64      * Verify that the user provided code is valid for the secret.
65      * The secret must be known, not user-provided.
66      */
67     public function verifyCode(string $code, string $secret): bool
68     {
69         /** @noinspection PhpUnhandledExceptionInspection */
70         return $this->google2fa->verifyKey($secret, $code);
71     }
72 }