]> BookStack Code Mirror - bookstack/blob - app/Http/Controllers/Auth/MfaTotpController.php
828af6b03281689772696c360cc08f5bfc0b4f2d
[bookstack] / app / Http / Controllers / Auth / MfaTotpController.php
1 <?php
2
3 namespace BookStack\Http\Controllers\Auth;
4
5 use BookStack\Actions\ActivityType;
6 use BookStack\Auth\Access\Mfa\MfaValue;
7 use BookStack\Auth\Access\Mfa\TotpService;
8 use BookStack\Auth\Access\Mfa\TotpValidationRule;
9 use BookStack\Exceptions\NotFoundException;
10 use BookStack\Http\Controllers\Controller;
11 use Illuminate\Http\Request;
12 use Illuminate\Validation\ValidationException;
13
14 class MfaTotpController extends Controller
15 {
16     use HandlesPartialLogins;
17
18     protected const SETUP_SECRET_SESSION_KEY = 'mfa-setup-totp-secret';
19
20     /**
21      * Show a view that generates and displays a TOTP QR code.
22      */
23     public function generate(TotpService $totp)
24     {
25         if (session()->has(static::SETUP_SECRET_SESSION_KEY)) {
26             $totpSecret = decrypt(session()->get(static::SETUP_SECRET_SESSION_KEY));
27         } else {
28             $totpSecret = $totp->generateSecret();
29             session()->put(static::SETUP_SECRET_SESSION_KEY, encrypt($totpSecret));
30         }
31
32         $qrCodeUrl = $totp->generateUrl($totpSecret);
33         $svg = $totp->generateQrCodeSvg($qrCodeUrl);
34
35         return view('mfa.totp-generate', [
36             'secret' => $totpSecret,
37             'svg' => $svg,
38         ]);
39     }
40
41     /**
42      * Confirm the setup of TOTP and save the auth method secret
43      * against the current user.
44      * @throws ValidationException
45      * @throws NotFoundException
46      */
47     public function confirm(Request $request)
48     {
49         $totpSecret = decrypt(session()->get(static::SETUP_SECRET_SESSION_KEY));
50         $this->validate($request, [
51             'code' => [
52                 'required',
53                 'max:12', 'min:4',
54                 new TotpValidationRule($totpSecret),
55             ]
56         ]);
57
58         MfaValue::upsertWithValue($this->currentOrLastAttemptedUser(), MfaValue::METHOD_TOTP, $totpSecret);
59         session()->remove(static::SETUP_SECRET_SESSION_KEY);
60         $this->logActivity(ActivityType::MFA_SETUP_METHOD, 'totp');
61
62         return redirect('/mfa/setup');
63     }
64 }