| 
									
										
										
										
											2020-01-26 22:42:50 +08:00
										 |  |  | <?php | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-18 00:56:55 +08:00
										 |  |  | namespace BookStack\Access\Controllers; | 
					
						
							| 
									
										
										
										
											2020-01-26 22:42:50 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-18 00:56:55 +08:00
										 |  |  | use BookStack\Access\LoginService; | 
					
						
							|  |  |  | use BookStack\Access\RegistrationService; | 
					
						
							|  |  |  | use BookStack\Access\SocialAuthService; | 
					
						
							| 
									
										
										
										
											2020-01-26 22:42:50 +08:00
										 |  |  | use BookStack\Exceptions\SocialDriverNotConfigured; | 
					
						
							|  |  |  | use BookStack\Exceptions\SocialSignInAccountNotUsed; | 
					
						
							|  |  |  | use BookStack\Exceptions\SocialSignInException; | 
					
						
							|  |  |  | use BookStack\Exceptions\UserRegistrationException; | 
					
						
							| 
									
										
										
										
											2023-05-19 03:53:39 +08:00
										 |  |  | use BookStack\Http\Controller; | 
					
						
							| 
									
										
										
										
											2020-01-26 22:42:50 +08:00
										 |  |  | use Illuminate\Http\Request; | 
					
						
							|  |  |  | use Illuminate\Support\Str; | 
					
						
							|  |  |  | use Laravel\Socialite\Contracts\User as SocialUser; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class SocialController extends Controller | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2021-07-18 00:45:00 +08:00
										 |  |  |     public function __construct( | 
					
						
							| 
									
										
										
										
											2023-10-19 21:18:42 +08:00
										 |  |  |         protected SocialAuthService $socialAuthService, | 
					
						
							|  |  |  |         protected RegistrationService $registrationService, | 
					
						
							|  |  |  |         protected LoginService $loginService, | 
					
						
							| 
									
										
										
										
											2021-08-21 22:49:40 +08:00
										 |  |  |     ) { | 
					
						
							| 
									
										
										
										
											2022-09-22 23:54:27 +08:00
										 |  |  |         $this->middleware('guest')->only(['register']); | 
					
						
							| 
									
										
										
										
											2020-01-26 22:42:50 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Redirect to the relevant social site. | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2021-03-11 06:37:53 +08:00
										 |  |  |      * @throws SocialDriverNotConfigured | 
					
						
							| 
									
										
										
										
											2020-01-26 22:42:50 +08:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2021-03-11 06:37:53 +08:00
										 |  |  |     public function login(string $socialDriver) | 
					
						
							| 
									
										
										
										
											2020-01-26 22:42:50 +08:00
										 |  |  |     { | 
					
						
							|  |  |  |         session()->put('social-callback', 'login'); | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-26 22:42:50 +08:00
										 |  |  |         return $this->socialAuthService->startLogIn($socialDriver); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Redirect to the social site for authentication intended to register. | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2020-01-26 22:42:50 +08:00
										 |  |  |      * @throws SocialDriverNotConfigured | 
					
						
							|  |  |  |      * @throws UserRegistrationException | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2021-03-11 06:37:53 +08:00
										 |  |  |     public function register(string $socialDriver) | 
					
						
							| 
									
										
										
										
											2020-01-26 22:42:50 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2020-02-03 01:31:00 +08:00
										 |  |  |         $this->registrationService->ensureRegistrationAllowed(); | 
					
						
							| 
									
										
										
										
											2020-01-26 22:42:50 +08:00
										 |  |  |         session()->put('social-callback', 'register'); | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-26 22:42:50 +08:00
										 |  |  |         return $this->socialAuthService->startRegister($socialDriver); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * The callback for social login services. | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2020-01-26 22:42:50 +08:00
										 |  |  |      * @throws SocialSignInException | 
					
						
							|  |  |  |      * @throws SocialDriverNotConfigured | 
					
						
							|  |  |  |      * @throws UserRegistrationException | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2021-03-11 06:37:53 +08:00
										 |  |  |     public function callback(Request $request, string $socialDriver) | 
					
						
							| 
									
										
										
										
											2020-01-26 22:42:50 +08:00
										 |  |  |     { | 
					
						
							|  |  |  |         if (!session()->has('social-callback')) { | 
					
						
							|  |  |  |             throw new SocialSignInException(trans('errors.social_no_action_defined'), '/login'); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Check request for error information
 | 
					
						
							|  |  |  |         if ($request->has('error') && $request->has('error_description')) { | 
					
						
							|  |  |  |             throw new SocialSignInException(trans('errors.social_login_bad_response', [ | 
					
						
							|  |  |  |                 'socialAccount' => $socialDriver, | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  |                 'error'         => $request->get('error_description'), | 
					
						
							| 
									
										
										
										
											2020-01-26 22:42:50 +08:00
										 |  |  |             ]), '/login'); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $action = session()->pull('social-callback'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Attempt login or fall-back to register if allowed.
 | 
					
						
							|  |  |  |         $socialUser = $this->socialAuthService->getSocialUser($socialDriver); | 
					
						
							| 
									
										
										
										
											2020-02-03 01:31:00 +08:00
										 |  |  |         if ($action === 'login') { | 
					
						
							| 
									
										
										
										
											2020-01-26 22:42:50 +08:00
										 |  |  |             try { | 
					
						
							|  |  |  |                 return $this->socialAuthService->handleLoginCallback($socialDriver, $socialUser); | 
					
						
							|  |  |  |             } catch (SocialSignInAccountNotUsed $exception) { | 
					
						
							| 
									
										
										
										
											2023-12-06 21:49:53 +08:00
										 |  |  |                 if ($this->socialAuthService->drivers()->isAutoRegisterEnabled($socialDriver)) { | 
					
						
							| 
									
										
										
										
											2020-01-26 22:42:50 +08:00
										 |  |  |                     return $this->socialRegisterCallback($socialDriver, $socialUser); | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-26 22:42:50 +08:00
										 |  |  |                 throw $exception; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-03 01:31:00 +08:00
										 |  |  |         if ($action === 'register') { | 
					
						
							| 
									
										
										
										
											2020-01-26 22:42:50 +08:00
										 |  |  |             return $this->socialRegisterCallback($socialDriver, $socialUser); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-10 20:37:21 +08:00
										 |  |  |         return redirect('/'); | 
					
						
							| 
									
										
										
										
											2020-01-26 22:42:50 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Detach a social account from a user. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2021-03-11 06:37:53 +08:00
										 |  |  |     public function detach(string $socialDriver) | 
					
						
							| 
									
										
										
										
											2020-01-26 22:42:50 +08:00
										 |  |  |     { | 
					
						
							|  |  |  |         $this->socialAuthService->detachSocialAccount($socialDriver); | 
					
						
							|  |  |  |         session()->flash('success', trans('settings.users_social_disconnected', ['socialAccount' => Str::title($socialDriver)])); | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-19 21:18:42 +08:00
										 |  |  |         return redirect('/my-account/auth#social-accounts'); | 
					
						
							| 
									
										
										
										
											2020-01-26 22:42:50 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Register a new user after a registration callback. | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2020-01-26 22:42:50 +08:00
										 |  |  |      * @throws UserRegistrationException | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     protected function socialRegisterCallback(string $socialDriver, SocialUser $socialUser) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $socialUser = $this->socialAuthService->handleRegistrationCallback($socialDriver, $socialUser); | 
					
						
							| 
									
										
										
										
											2021-03-20 00:16:26 +08:00
										 |  |  |         $socialAccount = $this->socialAuthService->newSocialAccount($socialDriver, $socialUser); | 
					
						
							| 
									
										
										
										
											2023-12-06 21:49:53 +08:00
										 |  |  |         $emailVerified = $this->socialAuthService->drivers()->isAutoConfirmEmailEnabled($socialDriver); | 
					
						
							| 
									
										
										
										
											2020-01-26 22:42:50 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // Create an array of the user data to create a new user instance
 | 
					
						
							|  |  |  |         $userData = [ | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  |             'name'     => $socialUser->getName(), | 
					
						
							|  |  |  |             'email'    => $socialUser->getEmail(), | 
					
						
							|  |  |  |             'password' => Str::random(32), | 
					
						
							| 
									
										
										
										
											2020-01-26 22:42:50 +08:00
										 |  |  |         ]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-11 03:09:22 +08:00
										 |  |  |         // Take name from email address if empty
 | 
					
						
							|  |  |  |         if (!$userData['name']) { | 
					
						
							|  |  |  |             $userData['name'] = explode('@', $userData['email'])[0]; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-03 01:31:00 +08:00
										 |  |  |         $user = $this->registrationService->registerUser($userData, $socialAccount, $emailVerified); | 
					
						
							| 
									
										
										
										
											2021-07-18 23:52:31 +08:00
										 |  |  |         $this->showSuccessNotification(trans('auth.register_success')); | 
					
						
							| 
									
										
										
										
											2021-07-18 00:45:00 +08:00
										 |  |  |         $this->loginService->login($user, $socialDriver); | 
					
						
							| 
									
										
										
										
											2020-01-26 22:42:50 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return redirect('/'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } |