Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
0.00% |
0 / 98 |
|
0.00% |
0 / 10 |
CRAP | |
0.00% |
0 / 1 |
| SocialLoginController | |
0.00% |
0 / 98 |
|
0.00% |
0 / 10 |
272 | |
0.00% |
0 / 1 |
| provider | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
0 | |||
| username | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| login | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
| validateLogin | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
| attemptLogin | |
0.00% |
0 / 52 |
|
0.00% |
0 / 1 |
72 | |||
| generateJwt | |
0.00% |
0 / 30 |
|
0.00% |
0 / 1 |
2 | |||
| base64UrlEncode | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
| getUser | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| getLoginMeta | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| getOAuthClient | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
| 1 | <?php |
| 2 | |
| 3 | namespace App\Http\Controllers\v1\Auth; |
| 4 | |
| 5 | use App\Traits\CompanyAuth; |
| 6 | use Illuminate\Http\Request; |
| 7 | use App\Events\User\LoggedIn; |
| 8 | use App\Http\Models\Auth\User; |
| 9 | use Illuminate\Http\JsonResponse; |
| 10 | use App\Http\Controllers\Controller; |
| 11 | use App\Http\Models\Passport\Client; |
| 12 | use Illuminate\Support\Facades\Log; |
| 13 | use Laravel\Socialite\Facades\Socialite; |
| 14 | |
| 15 | abstract class SocialLoginController extends Controller |
| 16 | { |
| 17 | use CompanyAuth; |
| 18 | |
| 19 | abstract public function provider(); |
| 20 | |
| 21 | public function username() |
| 22 | { |
| 23 | return 'email'; |
| 24 | } |
| 25 | |
| 26 | public function login(Request $request) |
| 27 | { |
| 28 | $this->validateLogin($request); |
| 29 | |
| 30 | return $this->attemptLogin($request); |
| 31 | } |
| 32 | |
| 33 | public function validateLogin(Request $request) |
| 34 | { |
| 35 | $request->validate([ |
| 36 | 'token' => 'required|string', |
| 37 | ]); |
| 38 | } |
| 39 | |
| 40 | public function attemptLogin(Request $request): JsonResponse |
| 41 | { |
| 42 | $client = $this->getOAuthClient(); |
| 43 | $authData = [ |
| 44 | 'grant_type' => 'social', |
| 45 | 'client_id' => $client->id, |
| 46 | 'client_secret' => $client->secret, |
| 47 | 'provider' => $this->provider(), |
| 48 | 'access_token' => $request->get('token'), |
| 49 | ]; |
| 50 | |
| 51 | $authRequest = Request::create(route('passport.token'), 'POST', $authData); |
| 52 | $response = app()->handle($authRequest); |
| 53 | $data = json_decode($response->getContent(), true); |
| 54 | |
| 55 | if (!empty($data)) { |
| 56 | if (array_key_exists("error", $data) && $data["error"] == "invalid_grant") { |
| 57 | $data = ['error' => trans('auth.failed')]; |
| 58 | return response()->json(data: $data, status: 400); |
| 59 | } |
| 60 | } |
| 61 | |
| 62 | $providerUser = Socialite::driver($this->provider())->stateless()->userFromToken($request->get('token')); |
| 63 | $email = $providerUser->getEmail(); |
| 64 | $user = $this->getUser($email); |
| 65 | $user->is_poc = $user->isPOC(); |
| 66 | |
| 67 | $about = $this->handleAdminInvitation($user); |
| 68 | |
| 69 | if ($about && $about['company_poc']) { |
| 70 | $data['is_company_poc'] = $about['company_poc']; |
| 71 | } |
| 72 | |
| 73 | $data = array_merge($data, [ |
| 74 | 'session_expires_in' => intval( |
| 75 | config('auth.passport.refresh_token_expiry') |
| 76 | ), |
| 77 | 'user_details' => $user, |
| 78 | 'company' => $user?->company?->slug, |
| 79 | 'provider' => $this->provider() |
| 80 | ]); |
| 81 | |
| 82 | Log::info('SocialLoginController::attemptLogin', [ |
| 83 | 'user' => $user, |
| 84 | 'email' => $email, |
| 85 | 'provider' => $this->provider(), |
| 86 | 'company' => $user?->company?->slug, |
| 87 | 'request' => $request->all(), |
| 88 | ]); |
| 89 | |
| 90 | $requireExtension = $request->get('include_extension'); |
| 91 | if (!$requireExtension) { |
| 92 | $prov = $this->provider(); |
| 93 | if (str_contains($prov, 'linkedin')) { |
| 94 | $prov = 'linkedin'; |
| 95 | } |
| 96 | |
| 97 | $url = config('app.url') . '/romeo/api/v1/user/auth/login/' . $prov; |
| 98 | |
| 99 | $request = Request::create($url, 'POST', [ |
| 100 | 'token' => $request->get('token'), |
| 101 | 'include_extension' => true |
| 102 | ]); |
| 103 | |
| 104 | $response = app()->handle($request); |
| 105 | $extensionData = json_decode($response->getContent(), true); |
| 106 | |
| 107 | $data['extension'] = $extensionData['result']; |
| 108 | } |
| 109 | |
| 110 | LoggedIn::dispatch($user, ['email' => $email, 'signin_source' => $this->provider()]); |
| 111 | |
| 112 | return response()->json($data); |
| 113 | } |
| 114 | |
| 115 | protected function generateJwt($user) |
| 116 | { |
| 117 | // Header |
| 118 | $header = json_encode([ |
| 119 | 'typ' => 'JWT', |
| 120 | 'alg' => 'HS256', |
| 121 | ]); |
| 122 | $base64UrlHeader = $this->base64UrlEncode($header); |
| 123 | |
| 124 | // Payload |
| 125 | $now = time(); |
| 126 | $common = [ |
| 127 | 'iat' => $now, |
| 128 | 'jti' => md5($now . rand()), |
| 129 | ]; |
| 130 | |
| 131 | $secret = 'GPn5ch5eLuyKXrtwDcesqkY8NQzYzDHm3HNdmTHAZ08='; |
| 132 | $companyExternalId = 1414; |
| 133 | $companyName = 'vengreso'; |
| 134 | $companyWebsite = 'https://vengreso.com'; |
| 135 | |
| 136 | $user_attributes = [ |
| 137 | 'user_external_id' => $user['id'], |
| 138 | 'user_email' => $user['email'], |
| 139 | 'user_first_name' => $user['first_name'], |
| 140 | 'user_last_name' => $user['last_name'], |
| 141 | 'company_external_id' => $user['id'], |
| 142 | 'company_name' => $companyName . '_' . $user['email'], |
| 143 | 'company_website' => 'https://' . $companyName . $user['email'] . '.com', |
| 144 | ]; |
| 145 | |
| 146 | $payload = json_encode(array_merge($common, $user_attributes)); |
| 147 | $base64UrlPayload = $this->base64UrlEncode($payload); |
| 148 | |
| 149 | // JWT |
| 150 | $message = $base64UrlHeader . '.' . $base64UrlPayload; |
| 151 | $signature = hash_hmac('sha256', $message, $secret, true); |
| 152 | $base64UrlSignature = $this->base64UrlEncode($signature); |
| 153 | $jwt = $base64UrlHeader . '.' . $base64UrlPayload . '.' . $base64UrlSignature; |
| 154 | |
| 155 | return $jwt; |
| 156 | } |
| 157 | |
| 158 | protected function base64UrlEncode($text) |
| 159 | { |
| 160 | return str_replace( |
| 161 | ['+', '/', '='], |
| 162 | ['-', '_', ''], |
| 163 | base64_encode($text) |
| 164 | ); |
| 165 | } |
| 166 | |
| 167 | protected function getUser($username) |
| 168 | { |
| 169 | return User::where($this->username(), $username)->first(); |
| 170 | } |
| 171 | |
| 172 | protected function getLoginMeta() |
| 173 | { |
| 174 | return []; |
| 175 | } |
| 176 | |
| 177 | protected function getOAuthClient() |
| 178 | { |
| 179 | $searchArray = ['password_client' => true]; |
| 180 | |
| 181 | return Client::where($searchArray)->first(); |
| 182 | } |
| 183 | } |