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