namespace BookStack\Http\Controllers\Auth;
use BookStack\Actions\ActivityType;
+use BookStack\Auth\Access\LoginService;
+use BookStack\Auth\Access\Mfa\MfaSession;
use BookStack\Auth\Access\Mfa\MfaValue;
use BookStack\Auth\Access\Mfa\TotpService;
use BookStack\Auth\Access\Mfa\TotpValidationRule;
session()->put(static::SETUP_SECRET_SESSION_KEY, encrypt($totpSecret));
}
- $qrCodeUrl = $totp->generateUrl($totpSecret);
+ $qrCodeUrl = $totp->generateUrl($totpSecret, $this->currentOrLastAttemptedUser());
$svg = $totp->generateQrCodeSvg($qrCodeUrl);
+ $this->setPageTitle(trans('auth.mfa_gen_totp_title'));
+
return view('mfa.totp-generate', [
- 'secret' => $totpSecret,
+ 'url' => $qrCodeUrl,
'svg' => $svg,
]);
}
/**
* Confirm the setup of TOTP and save the auth method secret
* against the current user.
+ *
* @throws ValidationException
* @throws NotFoundException
*/
'required',
'max:12', 'min:4',
new TotpValidationRule($totpSecret),
- ]
+ ],
]);
MfaValue::upsertWithValue($this->currentOrLastAttemptedUser(), MfaValue::METHOD_TOTP, $totpSecret);
session()->remove(static::SETUP_SECRET_SESSION_KEY);
$this->logActivity(ActivityType::MFA_SETUP_METHOD, 'totp');
+ if (!auth()->check()) {
+ $this->showSuccessNotification(trans('auth.mfa_setup_login_notification'));
+
+ return redirect('/login');
+ }
+
return redirect('/mfa/setup');
}
+
+ /**
+ * Verify the MFA method submission on check.
+ *
+ * @throws NotFoundException
+ */
+ public function verify(Request $request, LoginService $loginService, MfaSession $mfaSession)
+ {
+ $user = $this->currentOrLastAttemptedUser();
+ $totpSecret = MfaValue::getValueForUser($user, MfaValue::METHOD_TOTP);
+
+ $this->validate($request, [
+ 'code' => [
+ 'required',
+ 'max:12', 'min:4',
+ new TotpValidationRule($totpSecret),
+ ],
+ ]);
+
+ $mfaSession->markVerifiedForUser($user);
+ $loginService->reattemptLoginFor($user);
+
+ return redirect()->intended();
+ }
}