| 
									
										
										
										
											2021-07-03 03:53:33 +08:00
										 |  |  | <?php | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace BookStack\Http\Controllers\Auth; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | use BookStack\Actions\ActivityType; | 
					
						
							| 
									
										
										
										
											2021-08-02 22:04:43 +08:00
										 |  |  | use BookStack\Auth\Access\LoginService; | 
					
						
							|  |  |  | use BookStack\Auth\Access\Mfa\MfaSession; | 
					
						
							| 
									
										
										
										
											2021-07-03 03:53:33 +08:00
										 |  |  | use BookStack\Auth\Access\Mfa\MfaValue; | 
					
						
							|  |  |  | use BookStack\Auth\Access\Mfa\TotpService; | 
					
						
							|  |  |  | use BookStack\Auth\Access\Mfa\TotpValidationRule; | 
					
						
							| 
									
										
										
										
											2021-07-18 23:52:31 +08:00
										 |  |  | use BookStack\Exceptions\NotFoundException; | 
					
						
							| 
									
										
										
										
											2021-07-03 03:53:33 +08:00
										 |  |  | use BookStack\Http\Controllers\Controller; | 
					
						
							|  |  |  | use Illuminate\Http\Request; | 
					
						
							|  |  |  | use Illuminate\Validation\ValidationException; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class MfaTotpController extends Controller | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2021-07-18 23:52:31 +08:00
										 |  |  |     use HandlesPartialLogins; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-03 03:53:33 +08:00
										 |  |  |     protected const SETUP_SECRET_SESSION_KEY = 'mfa-setup-totp-secret'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Show a view that generates and displays a TOTP QR code. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function generate(TotpService $totp) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (session()->has(static::SETUP_SECRET_SESSION_KEY)) { | 
					
						
							|  |  |  |             $totpSecret = decrypt(session()->get(static::SETUP_SECRET_SESSION_KEY)); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             $totpSecret = $totp->generateSecret(); | 
					
						
							|  |  |  |             session()->put(static::SETUP_SECRET_SESSION_KEY, encrypt($totpSecret)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-15 01:02:16 +08:00
										 |  |  |         $qrCodeUrl = $totp->generateUrl($totpSecret, $this->currentOrLastAttemptedUser()); | 
					
						
							| 
									
										
										
										
											2021-07-03 03:53:33 +08:00
										 |  |  |         $svg = $totp->generateQrCodeSvg($qrCodeUrl); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-04 21:33:24 +08:00
										 |  |  |         $this->setPageTitle(trans('auth.mfa_gen_totp_title')); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-03 03:53:33 +08:00
										 |  |  |         return view('mfa.totp-generate', [ | 
					
						
							| 
									
										
										
										
											2021-09-02 03:58:19 +08:00
										 |  |  |             'url' => $qrCodeUrl, | 
					
						
							|  |  |  |             'svg' => $svg, | 
					
						
							| 
									
										
										
										
											2021-07-03 03:53:33 +08:00
										 |  |  |         ]); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Confirm the setup of TOTP and save the auth method secret | 
					
						
							|  |  |  |      * against the current user. | 
					
						
							| 
									
										
										
										
											2021-08-21 22:49:40 +08:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2021-07-03 03:53:33 +08:00
										 |  |  |      * @throws ValidationException | 
					
						
							| 
									
										
										
										
											2021-07-18 23:52:31 +08:00
										 |  |  |      * @throws NotFoundException | 
					
						
							| 
									
										
										
										
											2021-07-03 03:53:33 +08:00
										 |  |  |      */ | 
					
						
							|  |  |  |     public function confirm(Request $request) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $totpSecret = decrypt(session()->get(static::SETUP_SECRET_SESSION_KEY)); | 
					
						
							|  |  |  |         $this->validate($request, [ | 
					
						
							|  |  |  |             'code' => [ | 
					
						
							|  |  |  |                 'required', | 
					
						
							|  |  |  |                 'max:12', 'min:4', | 
					
						
							|  |  |  |                 new TotpValidationRule($totpSecret), | 
					
						
							| 
									
										
										
										
											2021-08-21 22:49:40 +08:00
										 |  |  |             ], | 
					
						
							| 
									
										
										
										
											2021-07-03 03:53:33 +08:00
										 |  |  |         ]); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-18 23:52:31 +08:00
										 |  |  |         MfaValue::upsertWithValue($this->currentOrLastAttemptedUser(), MfaValue::METHOD_TOTP, $totpSecret); | 
					
						
							| 
									
										
										
										
											2021-07-03 03:53:33 +08:00
										 |  |  |         session()->remove(static::SETUP_SECRET_SESSION_KEY); | 
					
						
							|  |  |  |         $this->logActivity(ActivityType::MFA_SETUP_METHOD, 'totp'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-21 22:14:24 +08:00
										 |  |  |         if (!auth()->check()) { | 
					
						
							|  |  |  |             $this->showSuccessNotification(trans('auth.mfa_setup_login_notification')); | 
					
						
							| 
									
										
										
										
											2021-08-21 22:49:40 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-21 22:14:24 +08:00
										 |  |  |             return redirect('/login'); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-03 03:53:33 +08:00
										 |  |  |         return redirect('/mfa/setup'); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-08-02 22:04:43 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Verify the MFA method submission on check. | 
					
						
							| 
									
										
										
										
											2021-08-21 22:49:40 +08:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2021-08-02 22:04:43 +08:00
										 |  |  |      * @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), | 
					
						
							| 
									
										
										
										
											2021-08-21 22:49:40 +08:00
										 |  |  |             ], | 
					
						
							| 
									
										
										
										
											2021-08-02 22:04:43 +08:00
										 |  |  |         ]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $mfaSession->markVerifiedForUser($user); | 
					
						
							| 
									
										
										
										
											2021-08-03 05:02:25 +08:00
										 |  |  |         $loginService->reattemptLoginFor($user); | 
					
						
							| 
									
										
										
										
											2021-08-02 22:04:43 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return redirect()->intended(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-07-03 03:53:33 +08:00
										 |  |  | } |