diff --git a/app/Controllers/SamlController.php b/app/Controllers/SamlController.php index 12b4c53..8e53870 100644 --- a/app/Controllers/SamlController.php +++ b/app/Controllers/SamlController.php @@ -3,7 +3,8 @@ namespace App\Controllers; use App\Models\SamlClientModel; -use App\Models\UserModel; +use App\Helpers\JWTToken; +use App\Helpers\RestAuthHelper; use OneLogin\Saml2\Auth as SamlAuth; use OneLogin\Saml2\Error as SamlError; use OneLogin\Saml2\Settings as SamlSettings; @@ -86,55 +87,151 @@ class SamlController extends BaseController public function acs() { try { - $clientId = $this->request->getGet('client_id'); - if (! $clientId) { - return $this->response->setStatusCode(400)->setBody('Client ID required'); + $postedEmail = $this->extractEmailFromPostedSamlResponse(); + if (! $postedEmail) { + return $this->redirectToFrontendSso([ + 'status' => 'failed', + 'code' => 400, + 'data' => '', + 'post_enrollment' => ['status' => 'failed', 'code' => 404, 'data' => ''], + 'message' => 'Unable to resolve email from SAML response', + ]); } + $at = strrchr($postedEmail, '@'); + if ($at === false) { + return $this->redirectToFrontendSso([ + 'status' => 'failed', + 'code' => 400, + 'data' => '', + 'post_enrollment' => ['status' => 'failed', 'code' => 404, 'data' => ''], + 'message' => 'Invalid email in SAML response', + ]); + } + + $domain = strtolower(substr($at, 1)); + $model = new SamlClientModel(); + $client = $model->getByDomain($domain); + if (! $client) { + return $this->redirectToFrontendSso([ + 'status' => 'failed', + 'code' => 404, + 'data' => '', + 'post_enrollment' => ['status' => 'failed', 'code' => 404, 'data' => ''], + 'message' => 'SAML not configured for this domain', + ]); + } + + $clientId = $client['id']; $auth = $this->getSamlAuth($clientId); + $auth->processResponse(); } catch (\Throwable $e) { - return redirect()->to(site_url('login'))->with('error', $e->getMessage()); + return $this->redirectToFrontendSso([ + 'status' => 'failed', + 'code' => 500, + 'data' => '', + 'post_enrollment' => ['status' => 'failed', 'code' => 404, 'data' => ''], + 'message' => $e->getMessage(), + ]); } - $auth->processResponse(); - if (! $auth->isAuthenticated()) { - return $this->response->setJSON($auth->getErrors()); + return $this->redirectToFrontendSso([ + 'status' => 'failed', + 'code' => 401, + 'data' => '', + 'post_enrollment' => ['status' => 'failed', 'code' => 404, 'data' => ''], + 'message' => implode(', ', $auth->getErrors()), + ]); } $attributes = $auth->getAttributes(); $nameId = $auth->getNameId(); $email = $this->resolveEmailFromSaml($nameId, $attributes); + $email = trim((string) $email); - $UserModel = new UserModel(); - $user = $UserModel->getUserByEmail($email); - - if (! $user || $user->is_active === '0') { - session()->remove('saml_client_id'); - - return redirect()->to(site_url('login'))->with('error', 'User not registered or inactive'); + // Same email lookup path used in RestAuthenticationController::getVerifiedUserData() + $empdata = RestAuthHelper::getPreAndPostDataByEmailOrMobile(['email_id' => $email]); + if (! empty($empdata['pre']['email_corporate'])) { + $email = (string) $empdata['pre']['email_corporate']; + } elseif (! empty($empdata['post']['email_id'])) { + $email = (string) $empdata['post']['email_id']; } - $user_team = $UserModel->getUserTeamsByUserID($user->id); + $postEnrollment = ['status' => 'failed', 'code' => 404, 'data' => '']; + if (! empty($empdata['post'])) { + $postData = $empdata['post']; + unset($postData['employee_id']); + $postData['token_type'] = 'post'; + $postEnrollment = [ + 'status' => 'success', + 'code' => 200, + 'data' => JWTToken::encode($postData), + ]; + } - session()->regenerate(true); + if (empty($empdata)) { + return $this->redirectToFrontendSso([ + 'status' => 'failed', + 'code' => 404, + 'data' => '', + 'post_enrollment' => $postEnrollment, + 'message' => 'User not found', + ]); + } - $session_data = [ - 'isLoggedIn' => true, - 'userid' => $user->id, - 'userData' => $user, - 'userProfile' => null, - 'user_team' => $user_team, - 'saml_name_id' => $nameId, - 'saml_attrs' => $attributes, + if (! empty($empdata['pre'])) { + $employeeData = $empdata['pre']; + unset($employeeData['employee_id']); + $employeeData['token_type'] = 'pre'; + $result = JWTToken::encode($employeeData); + + return $this->redirectToFrontendSso([ + 'status' => 'success', + 'code' => 200, + 'data' => $result, + 'post_enrollment' => $postEnrollment, + ]); + } + + return $this->redirectToFrontendSso([ + 'status' => 'failed', + 'code' => 404, + 'data' => '', + 'post_enrollment' => $postEnrollment, + 'message' => 'Employee not found in pre-enrollment', + ]); + } + + private function redirectToFrontendSso(array $payload) + { + $feUrl = rtrim((string) env('fe_url'), '/'); + if ($feUrl === '') { + $feUrl = rtrim((string) env('FE_URL'), '/'); + } + + $responsePayload = [ + 'status' => $payload['status'] ?? 'failed', + 'code' => $payload['code'] ?? 500, + 'data' => $payload['data'] ?? '', + 'post_enrollment' => $payload['post_enrollment'] ?? ['status' => 'failed', 'code' => 404, 'data' => ''], ]; - set_session_data($session_data); - set_session_data(['fingerprint' => generateFingerprint()]); - $this->getUserDeviceInfo($user->id, 'NhanceUser'); + // dd($responsePayload); + if (! empty($payload['message'])) { + $responsePayload['message'] = $payload['message']; + } - return redirect()->to(site_url('dashboard/view')); + $encodedPayload = base64_encode((string) json_encode($responsePayload)); + + $params = http_build_query([ + 'payload' => $encodedPayload, + ]); + + // dd($feUrl . '/sso-login?' . $params); + + return redirect()->to($feUrl . '/sso-login?' . $params); } protected function getUserDeviceInfo(int $userId, string $type_of_user): void @@ -183,6 +280,47 @@ class SamlController extends BaseController return (string) $nameId; } + private function extractEmailFromPostedSamlResponse(): ?string + { + $raw = $this->request->getPost('SAMLResponse'); + if (! is_string($raw) || $raw === '') { + return null; + } + + $decoded = base64_decode($raw, true); + if ($decoded === false || trim($decoded) === '') { + return null; + } + + libxml_use_internal_errors(true); + $xml = simplexml_load_string($decoded); + if ($xml === false) { + return null; + } + + $emailNodes = $xml->xpath("//*[local-name()='Attribute' and (@Name='email' or @Name='Email' or @Name='mail' or @Name='http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress' or @Name='http://schemas.microsoft.com/identity/claims/emailaddress')]/*[local-name()='AttributeValue']"); + if (is_array($emailNodes)) { + foreach ($emailNodes as $node) { + $val = trim((string) $node); + if ($val !== '' && filter_var($val, FILTER_VALIDATE_EMAIL)) { + return $val; + } + } + } + + $nameIdNodes = $xml->xpath("//*[local-name()='NameID']"); + if (is_array($nameIdNodes)) { + foreach ($nameIdNodes as $node) { + $val = trim((string) $node); + if ($val !== '' && filter_var($val, FILTER_VALIDATE_EMAIL)) { + return $val; + } + } + } + + return null; + } + public function logout() { try { @@ -253,4 +391,64 @@ class SamlController extends BaseController ->setHeader('Content-Type', 'application/xml; charset=utf-8') ->setBody($metadata); } -} + + + + // public function verifyMSAuthUser() + // { + + // $code = $this->request->getVar('code'); + // // echo $code; + // try { + // $token = $this->provider->getAccessToken('authorization_code', [ + // 'code' => $code + // ]); + + // $ownerDetails = $this->provider->getResourceOwner($token); + // $data = $ownerDetails->toArray(); + + // $name = $data['name'] ?? null; + // $email = $data['upn'] ?? $data['unique_name'] ?? null; + + // $res = checkUserExist($name, $email); + + // if($res['status'] == true) + // { + // $user = $res['data']; + // //get service for the organization + // $orgService = $this->organizationModel->find($user['org_id']); + // $user['service'] = json_decode($orgService['services_ids'],true); + // foreach ($user['service'] as $key => $value) + // { + // $serviceData = $this->serviceModel->find($value['service_id']); + // $user['service'][$key]['name'] = $serviceData['name']; + // $user['service'][$key]['icon'] = $serviceData['icon']; + // } + + // //get role + // $user['role'] = $this->userModel->getRole($user['role_id']); + + // //find user has the all access + // $user['plan_action'] = getUserPlanCreationRestrictionStatus($user); + + // $token = generateJWT($user); + + // return $this->respond([ 'status' => 200,'message' => 'Login successful','token' => $token ]); + + // }else{ + // return $this->respond([ 'status' => 401,'message' => 'Login Failed','data' => [] ]); + // } + + + + + // } catch (IdentityProviderException $e) { + // exit($e->getMessage()); + // } + + // } + //end of microsoft oAuth + + + +} \ No newline at end of file diff --git a/app/Libraries/MyGoogleDrive.php b/app/Libraries/MyGoogleDrive.php index 566098e..39a79a8 100755 --- a/app/Libraries/MyGoogleDrive.php +++ b/app/Libraries/MyGoogleDrive.php @@ -73,7 +73,7 @@ class MyGoogleDrive } if (php_sapi_name() != 'cli') { - throw new Exception('This application must be run on the command line.'); + throw new \Exception('This application must be run on the command line.'); } $authUrl = $this->client->createAuthUrl();