diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php index c5d561c18500..ec52fd49644a 100644 --- a/app/Http/Controllers/Auth/LoginController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -168,9 +168,9 @@ class LoginController extends BaseController $this->fireLockoutEvent($request); return response() - ->json(['message' => 'Too many login attempts, you are being throttled'], 401) - ->header('X-App-Version', config('ninja.app_version')) - ->header('X-Api-Version', config('ninja.minimum_client_version')); + ->json(['message' => 'Too many login attempts, you are being throttled'], 401) + ->header('X-App-Version', config('ninja.app_version')) + ->header('X-Api-Version', config('ninja.minimum_client_version')); } if ($this->attemptLogin($request)) { @@ -250,7 +250,7 @@ class LoginController extends BaseController // $truth->setCompanyToken(CompanyToken::where('user_id', auth()->user()->id)->where('company_id', $user->account->default_company->id)->first()); /*On the hosted platform, only owners can login for free/pro accounts*/ - if(Ninja::isHosted() && !$cu->first()->is_owner && !$user->account->isEnterpriseClient()) + if (Ninja::isHosted() && !$cu->first()->is_owner && !$user->account->isEnterpriseClient()) return response()->json(['message' => 'Pro / Free accounts only the owner can log in. Please upgrade'], 403); event(new UserLoggedIn($user, $user->account->default_company, Ninja::eventVars($user->id))); @@ -267,9 +267,9 @@ class LoginController extends BaseController $this->incrementLoginAttempts($request); return response() - ->json(['message' => ctrans('texts.invalid_credentials')], 401) - ->header('X-App-Version', config('ninja.app_version')) - ->header('X-Api-Version', config('ninja.minimum_client_version')); + ->json(['message' => ctrans('texts.invalid_credentials')], 401) + ->header('X-App-Version', config('ninja.app_version')) + ->header('X-Api-Version', config('ninja.minimum_client_version')); } } @@ -358,15 +358,22 @@ class LoginController extends BaseController */ public function oauthApiLogin() { + $message = 'Provider not supported'; if (request()->input('provider') == 'google') { return $this->handleGoogleOauth(); } elseif (request()->input('provider') == 'microsoft') { if (request()->has('token')) { - return $this->handleMicrosoftOauth(request()->get('token')); + return $this->handleSocialiteLogin('microsoft', request()->get('token')); } else { $message = 'Bearer token missing for the microsoft login'; } + } elseif (request()->input('provider') == 'apple') { + if (request()->has('token')) { + return $this->handleSocialiteLogin('apple', request()->get('token')); + } else { + $message = 'Token is missing for the apple login'; + } } return response() @@ -375,103 +382,110 @@ class LoginController extends BaseController ->header('X-Api-Version', config('ninja.minimum_client_version')); } - private function handleMicrosoftOauth($token) + private function getSocialiteUser(string $provider, string $token) { - $user = Socialite::driver('microsoft')->userFromToken($token); + return Socialite::driver($provider)->userFromToken($token); + } + private function handleSocialiteLogin($provider, $token) + { + $user = $this->getSocialiteUser($provider, $token); if ($user) { - $query = [ - 'oauth_user_id' => $user->id, - 'oauth_provider_id' => 'microsoft', - ]; - if ($existing_user = MultiDB::hasUser($query)) { + return $this->loginOrCreateFromSocialite($user, $provider); + } + return response() + ->json(['message' => ctrans('texts.invalid_credentials')], 401) + ->header('X-App-Version', config('ninja.app_version')) + ->header('X-Api-Version', config('ninja.minimum_client_version')); - if (!$existing_user->account) - return response()->json(['message' => 'User exists, but not attached to any companies! Orphaned user!'], 400); + } - Auth::login($existing_user, true); - $cu = $this->hydrateCompanyUser(); + private function loginOrCreateFromSocialite($user, $provider) + { + $query = [ + 'oauth_user_id' => $user->id, + 'oauth_provider_id' => $provider, + ]; + if ($existing_user = MultiDB::hasUser($query)) { - if ($cu->count() == 0) - return response()->json(['message' => 'User found, but not attached to any companies, please see your administrator'], 400); + if (!$existing_user->account) + return response()->json(['message' => 'User exists, but not attached to any companies! Orphaned user!'], 400); - if (Ninja::isHosted() && !$cu->first()->is_owner && !$existing_user->account->isEnterpriseClient()) - return response()->json(['message' => 'Pro / Free accounts only the owner can log in. Please upgrade'], 403); - - return $this->timeConstrainedResponse($cu); - - } - //If this is a result user/email combo - lets add their OAuth details details - if ($existing_login_user = MultiDB::hasUser(['email' => $user->email])) { - if (!$existing_login_user->account) - return response()->json(['message' => 'User exists, but not attached to any companies! Orphaned user!'], 400); - - Auth::login($existing_login_user, true); - - auth()->user()->update([ - 'oauth_user_id' => $user->id, - 'oauth_provider_id' => 'microsoft', - ]); - - $cu = $this->hydrateCompanyUser(); - - if ($cu->count() == 0) - return response()->json(['message' => 'User found, but not attached to any companies, please see your administrator'], 400); - - if (Ninja::isHosted() && !$cu->first()->is_owner && !$existing_login_user->account->isEnterpriseClient()) - return response()->json(['message' => 'Pro / Free accounts only the owner can log in. Please upgrade'], 403); - - return $this->timeConstrainedResponse($cu); - } - - $name = OAuth::splitName($user->name); - - $new_account = [ - 'first_name' => $name[0], - 'last_name' => $name[1], - 'password' => '', - 'email' => $user->email, - 'oauth_user_id' => $user->id, - 'oauth_provider_id' => 'microsoft', - ]; - - MultiDB::setDefaultDatabase(); - - $account = CreateAccount::dispatchNow($new_account, request()->getClientIp()); - - Auth::login($account->default_company->owner(), true); - auth()->user()->email_verified_at = now(); - auth()->user()->save(); + Auth::login($existing_user, true); $cu = $this->hydrateCompanyUser(); if ($cu->count() == 0) return response()->json(['message' => 'User found, but not attached to any companies, please see your administrator'], 400); - if (Ninja::isHosted() && !$cu->first()->is_owner && !auth()->user()->account->isEnterpriseClient()) + if (Ninja::isHosted() && !$cu->first()->is_owner && !$existing_user->account->isEnterpriseClient()) + return response()->json(['message' => 'Pro / Free accounts only the owner can log in. Please upgrade'], 403); + + return $this->timeConstrainedResponse($cu); + + } + //If this is a result user/email combo - lets add their OAuth details details + if ($existing_login_user = MultiDB::hasUser(['email' => $user->email])) { + if (!$existing_login_user->account) + return response()->json(['message' => 'User exists, but not attached to any companies! Orphaned user!'], 400); + + Auth::login($existing_login_user, true); + + auth()->user()->update([ + 'oauth_user_id' => $user->id, + 'oauth_provider_id' => $provider, + ]); + + $cu = $this->hydrateCompanyUser(); + + if ($cu->count() == 0) + return response()->json(['message' => 'User found, but not attached to any companies, please see your administrator'], 400); + + if (Ninja::isHosted() && !$cu->first()->is_owner && !$existing_login_user->account->isEnterpriseClient()) return response()->json(['message' => 'Pro / Free accounts only the owner can log in. Please upgrade'], 403); return $this->timeConstrainedResponse($cu); } + $name = OAuth::splitName($user->name); + $new_account = [ + 'first_name' => $name[0], + 'last_name' => $name[1], + 'password' => '', + 'email' => $user->email, + 'oauth_user_id' => $user->id, + 'oauth_provider_id' => $provider, + ]; - return response() - ->json(['message' => ctrans('texts.invalid_credentials')], 401) - ->header('X-App-Version', config('ninja.app_version')) - ->header('X-Api-Version', config('ninja.minimum_client_version')); + MultiDB::setDefaultDatabase(); + $account = CreateAccount::dispatchNow($new_account, request()->getClientIp()); + Auth::login($account->default_company->owner(), true); + auth()->user()->email_verified_at = now(); + auth()->user()->save(); + + $cu = $this->hydrateCompanyUser(); + + if ($cu->count() == 0) + return response()->json(['message' => 'User found, but not attached to any companies, please see your administrator'], 400); + + if (Ninja::isHosted() && !$cu->first()->is_owner && !auth()->user()->account->isEnterpriseClient()) + return response()->json(['message' => 'Pro / Free accounts only the owner can log in. Please upgrade'], 403); + + return $this->timeConstrainedResponse($cu); } - private function hydrateCompanyUser() :Builder + + private function hydrateCompanyUser(): Builder { $cu = CompanyUser::query()->where('user_id', auth()->user()->id); - if(CompanyUser::query()->where('user_id', auth()->user()->id)->where('company_id', auth()->user()->account->default_company_id)->exists()) + if (CompanyUser::query()->where('user_id', auth()->user()->id)->where('company_id', auth()->user()->account->default_company_id)->exists()) $set_company = auth()->user()->account->default_company; - else{ + else { $set_company = $cu->first()->company; } @@ -487,14 +501,13 @@ class LoginController extends BaseController if($cu->count() == 0) return $cu; - if(auth()->user()->company_users()->count() != auth()->user()->tokens()->distinct('company_id')->count()) - { + if (auth()->user()->company_users()->count() != auth()->user()->tokens()->distinct('company_id')->count()) { - auth()->user()->companies->each(function($company){ + auth()->user()->companies->each(function ($company) { - if(!CompanyToken::where('user_id', auth()->user()->id)->where('company_id', $company->id)->exists()){ + if (!CompanyToken::where('user_id', auth()->user()->id)->where('company_id', $company->id)->exists()) { - CreateCompanyToken::dispatchNow($company, auth()->user(), "Google_O_Auth"); + CreateCompanyToken::dispatchNow($company, auth()->user(), "Google_O_Auth"); }