3 namespace BookStack\Http\Controllers\Auth;
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;
13 class MfaController extends Controller
15 protected const TOTP_SETUP_SECRET_SESSION_KEY = 'mfa-setup-totp-secret';
18 * Show the view to setup MFA for the current user.
20 public function setup()
22 $userMethods = user()->mfaValues()
23 ->get(['id', 'method'])
25 return view('mfa.setup', [
26 'userMethods' => $userMethods,
31 * Show a view that generates and displays a TOTP QR code.
33 public function totpGenerate(TotpService $totp)
35 if (session()->has(static::TOTP_SETUP_SECRET_SESSION_KEY)) {
36 $totpSecret = decrypt(session()->get(static::TOTP_SETUP_SECRET_SESSION_KEY));
38 $totpSecret = $totp->generateSecret();
39 session()->put(static::TOTP_SETUP_SECRET_SESSION_KEY, encrypt($totpSecret));
42 $qrCodeUrl = $totp->generateUrl($totpSecret);
43 $svg = $totp->generateQrCodeSvg($qrCodeUrl);
45 return view('mfa.totp-generate', [
46 'secret' => $totpSecret,
52 * Confirm the setup of TOTP and save the auth method secret
53 * against the current user.
54 * @throws ValidationException
56 public function totpConfirm(Request $request)
58 $totpSecret = decrypt(session()->get(static::TOTP_SETUP_SECRET_SESSION_KEY));
59 $this->validate($request, [
63 new TotpValidationRule($totpSecret),
67 MfaValue::upsertWithValue(user(), MfaValue::METHOD_TOTP, $totpSecret);
68 $this->logActivity(ActivityType::MFA_SETUP_METHOD, 'totp');
70 return redirect('/mfa/setup');