diff --git a/.env.sample b/.env.sample index 5c3f1bf8..3058d4ac 100755 --- a/.env.sample +++ b/.env.sample @@ -138,3 +138,11 @@ LEAD_CLIENT_FROM_MAIL_ID = # BDS Daily Report Emails Configuration bds.dailyReportEmails = + +#-------------------------------------------------------------------- +# MEDI ASSIST WELLNESS SSO Configuration +#-------------------------------------------------------------------- + +MEDIASSIST_WELLNESS_KEY = +MEDIASSIST_WELLNESS_IV = +MEDIASSIST_WELLNESS_LOGIN_URL = diff --git a/app/Config/Routes.php b/app/Config/Routes.php index b9988f4a..2325f818 100755 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -451,6 +451,7 @@ $routes->group("/util", ["filter" => "authMVC"], function ($routes) { $routes->get('croneDailyActivityReport', 'DashboardController::croneDailyActivityReport'); $routes->get('insertSampleTpaApiData/(:any)', 'TestingController::insertSampleTpaApiData/$1'); $routes->get('listEmployeeCountByClientPolicy', 'TestingController::listEmployeeCountByClientPolicy'); + $routes->get('testMediAssistWellness','TestingController::testMediAssistWellness'); }); $routes->post("policy_tranction/sendInstallmentRemainderMail","PolicyTransactionController::sendInstallmentRemainderMail"); diff --git a/app/Controllers/ApiServiceController.php b/app/Controllers/ApiServiceController.php index bb977a11..f4782afb 100644 --- a/app/Controllers/ApiServiceController.php +++ b/app/Controllers/ApiServiceController.php @@ -425,13 +425,17 @@ class ApiServiceController extends BaseController $userParams = []; foreach ($data as $row) { - if($row['wellness_vendor_id'] != null) + if($row['wellness_vendor_id'] == $this->vidal_primary_key) { $vidalApiController = new VidalApiController(); return $vidalApiController->getWellnessSSORedirectUrl($row['email']); + }else if ($row['wellness_vendor_id'] == $this->medi_assist_primary_key) + { + $mediAssistController = new MediAssistApiController(); + return $mediAssistController->getWellnessSSORedirectUrl($row['planId'], $row['memberId']); } - else if ($row['planId'] != null) // VISIT + else if ($row['planId'] != null && empty($row['wellness_vendor_id'])) // VISIT { $userParams['name'] = $row['name']; $userParams['email'] = $row['email']; diff --git a/app/Controllers/AppContentManagementController.php b/app/Controllers/AppContentManagementController.php index e13732b2..a3db36ec 100755 --- a/app/Controllers/AppContentManagementController.php +++ b/app/Controllers/AppContentManagementController.php @@ -247,7 +247,7 @@ class AppContentManagementController extends AdminController 'errors' => [ 'required' => 'Type is required', 'max_length' => 'Type cannot exceed 255 characters', - 'regex_match' => 'Type contains invalid characters' + 'regex_match' => 'Type can contain only letters, numbers, spaces, _ and -' ] ], 'content_section' => [ @@ -255,7 +255,7 @@ class AppContentManagementController extends AdminController 'errors' => [ 'required' => 'Content Section is required', 'max_length' => 'Content Section cannot exceed 255 characters', - 'regex_match' => 'Content Section contains invalid characters' + 'regex_match' => 'Content Section can contain only letters, numbers, spaces, _ and -' ] ], 'heading' => [ @@ -263,7 +263,7 @@ class AppContentManagementController extends AdminController 'errors' => [ 'required' => 'Heading is required', 'max_length' => 'Heading cannot exceed 255 characters', - 'regex_match' => 'Heading contains invalid characters. Only letters, numbers, spaces and basic punctuation are allowed' + 'regex_match' => 'Heading can contain only letters, numbers, spaces, and these characters: . , ; : ! ? ( ) & / -' ] ], 'content' => [ @@ -465,18 +465,22 @@ class AppContentManagementController extends AdminController if ($method === 'post') { $rules = [ 'category' => [ - 'rules' => 'required|max_length[100]|alpha_numeric_space', + // Allow letters, numbers, spaces and / - . , " ' + 'rules' => 'required|max_length[100]|regex_match[/^[a-zA-Z0-9 \\/\\-\\.\,\"\\\']+$/]', 'errors' => [ - 'required' => 'Category is required', - 'max_length' => 'Category cannot exceed 100 characters', - 'alpha_numeric_space' => 'Category contains invalid characters' + 'required' => 'Category is required', + 'max_length' => 'Category cannot exceed 100 characters', + 'regex_match' => 'Category can contain only letters, numbers, spaces, and these characters: / - . , " \'', + ] ], 'question' => [ - 'rules' => 'required|max_length[1000]', + // Allow only letters, numbers, spaces and basic punctuation . , ; : ! ? ( ) & / - + 'rules' => 'required|max_length[1000]|regex_match[/^[a-zA-Z0-9 _\\-.,;:!?()&\\/]+$/]', 'errors' => [ 'required' => 'Question is required', 'max_length' => 'Question cannot exceed 1000 characters', + 'regex_match' => 'Question can contain only letters, numbers, spaces, and these characters: . , ; : ! ? ( ) & / -', ] ], 'answer' => [ @@ -779,17 +783,18 @@ class AppContentManagementController extends AdminController * The `/i` flag makes the search case-insensitive. */ $dangerous_patterns = [ - '/<\s*script/i', // + '/<\s*object/i', // + '/<\s*embed/i', // + '/<\s*applet/i', // + '/on\w+\s*=/i', // on...= (e.g., onclick=, onmouseover=, onerror=) '/data\s*:\s*text\/html/i', // data:text/html - '/expression\s*\(/i', // CSS expression() + '/expression\s*\(/i', // CSS expression() + '/\balert\s*\(/i', // alert(...) ]; // Loop through the patterns and check if any of them exist in the decoded string. diff --git a/app/Controllers/MediAssistApiController.php b/app/Controllers/MediAssistApiController.php index 4e210522..70a73826 100644 --- a/app/Controllers/MediAssistApiController.php +++ b/app/Controllers/MediAssistApiController.php @@ -1349,7 +1349,72 @@ class MediAssistApiController extends BaseController } + public function getWellnessSSORedirectUrl($planId, $emp_code) + { + log_message('error', 'MEDI_ASSIST - Wellness SSO URL generation | Plan ID: ' . $planId . ' | Employee code: ' . $emp_code); + if (empty($planId) || empty($emp_code)) { + log_message('error', 'MEDI_ASSIST - Wellness SSO URL generation | Plan ID and employee code are required.'); + return [ + 'status' => 'failed', + 'message' => 'Coming soon........!', + ]; + } + // Configuration – prefer environment variables, fall back to demo values + $keyString = env('MEDIASSIST_WELLNESS_KEY'); + $ivString = env('MEDIASSIST_WELLNESS_IV'); + $loginUrlTemplate = env('MEDIASSIST_WELLNESS_LOGIN_URL'); + $cipher_algorithm = 'AES-256-CBC'; + + if (empty($keyString) || empty($ivString) || empty($loginUrlTemplate)) { + log_message('error', 'MEDI_ASSIST - Wellness SSO URL generation | Key string, IV string and login URL are required.'); + return [ + 'status' => 'failed', + 'message' => 'Key string, IV string and login URL are required.', + ]; + } + + // Plain SSO JSON payload, as per Medi Assist sample + $payload = [ + 'Id' => $emp_code, + 'expiryTime' => time() + (10 * 60), // 10 minutes + 'CPartnerId' => $planId, + ]; + + $plainJson = json_encode($payload, JSON_UNESCAPED_SLASHES); + + // Derive a 32‑byte key (AES‑256) and 16‑byte IV from the provided strings + // $key = substr(hash('sha256', $keyString, true), 0, 32); + // $iv = substr(hash('md5', $ivString, true), 0, 16); + + // Encrypt with AES‑256‑CBC + PKCS7 padding (OpenSSL default) + $cipherTextRaw = openssl_encrypt($plainJson, $cipher_algorithm, $keyString, OPENSSL_RAW_DATA, $ivString); + + + if ($cipherTextRaw === false) { + log_message('error', 'MEDI_ASSIST - Wellness SSO URL generation | Encryption failed while generating Medi Assist wellness token.'); + return [ + 'status' => 'failed', + 'message' => 'Encryption failed while generating Medi Assist wellness token.', + ]; + } + + + // Base64 encode and URL‑encode for use as EncryptedSSO + $encryptedSSO = urlencode(base64_encode($cipherTextRaw)); + // $encryptedSSO = rtrim(strtr(base64_encode($cipherTextRaw), '+/', '-_'), '='); + + // Build the final login URL + $loginUrl = str_replace(['{0}', '{1}'], [$planId, $encryptedSSO], $loginUrlTemplate); + + log_message('error', 'MEDI_ASSIST - Wellness SSO URL generation | Medi Assist wellness SSO URL generated successfully.'); + + return [ + 'status' => 'success', + 'message' => 'Medi Assist wellness SSO URL generated successfully.', + 'data' => $loginUrl + ]; + } diff --git a/app/Controllers/TestingController.php b/app/Controllers/TestingController.php index dce9636c..917af897 100644 --- a/app/Controllers/TestingController.php +++ b/app/Controllers/TestingController.php @@ -1304,4 +1304,74 @@ class TestingController extends BaseController 'data' => $list, ], 200); } + + /** + * Test Wellness SSO token generation for Medi Assist (MediBuddy). + * + * This uses the token-based authentication details shared by Medi Assist: + * - Cipher: AES-256-CBC + * - Padding: PKCS7 (OpenSSL default) + * - Login URL: https://login.mediassist.in/SSOLogon.aspx?PartnerCorpId={0}&EncryptedSSO={1} + * + * Environment variables (recommended): + * - MEDIASSIST_WELLNESS_KEY + * - MEDIASSIST_WELLNESS_IV + * - MEDIASSIST_WELLNESS_PARTNER_CORP_ID + * - MEDIASSIST_WELLNESS_LOGIN_URL + * + * If env values are not present, sensible dummy defaults are used so that + * the function can still be exercised. + */ + public function testMediAssistWellness() + { + + // Configuration – prefer environment variables, fall back to demo values + $keyString = env('MEDIASSIST_WELLNESS_KEY'); + $ivString = env('MEDIASSIST_WELLNESS_IV'); + $loginUrlTemplate = env('MEDIASSIST_WELLNESS_LOGIN_URL' ); + $partnerCorpId = '15963'; + $cipher_algorithm = 'AES-256-CBC'; + + // Plain SSO JSON payload, as per Medi Assist sample + $payload = [ + 'Id' => '15022', + 'expiryTime' => time() + (10 * 60), // 10 minutes + 'CPartnerId' => $partnerCorpId, + ]; + + $plainJson = json_encode($payload, JSON_UNESCAPED_SLASHES); + + // Derive a 32‑byte key (AES‑256) and 16‑byte IV from the provided strings + // $key = substr(hash('sha256', $keyString, true), 0, 32); + // $iv = substr(hash('md5', $ivString, true), 0, 16); + + // Encrypt with AES‑256‑CBC + PKCS7 padding (OpenSSL default) + $cipherTextRaw = openssl_encrypt( $plainJson, $cipher_algorithm, $keyString, OPENSSL_RAW_DATA, $ivString); + + + if ($cipherTextRaw === false) { + return $this->respond([ + 'status' => false, + 'message' => 'Encryption failed while generating Medi Assist wellness token.', + ], 500); + } + + + // Base64 encode and URL‑encode for use as EncryptedSSO + $encryptedSSO = urlencode(base64_encode($cipherTextRaw)); + // $encryptedSSO = rtrim(strtr(base64_encode($cipherTextRaw), '+/', '-_'), '='); + + // Build the final login URL + $loginUrl = str_replace(['{0}', '{1}'], [$partnerCorpId, $encryptedSSO], $loginUrlTemplate); + + return $this->respond([ + 'status' => true, + 'message' => 'Medi Assist wellness test URL generated successfully.', + 'data' => [ + 'loginUrl' => $loginUrl, + 'encryptedSSO' => $encryptedSSO, + 'plainPayload' => $payload, + ], + ], 200); + } } diff --git a/app/Controllers/TicketController.php b/app/Controllers/TicketController.php index ce11e595..a0df4c9d 100644 --- a/app/Controllers/TicketController.php +++ b/app/Controllers/TicketController.php @@ -3549,9 +3549,13 @@ class TicketController extends BaseController claim_dump_files.file_name, claim_dump_files.status, claim_dump_files.created_at, - up.first_name as user_name + up.first_name as user_name, + c.client_name, + cp.policy_no ') ->join('user_profiles as up', 'claim_dump_files.created_by = up.id', 'left') + ->join('client_policy as cp', 'claim_dump_files.client_policy_id = cp.id', 'left') + ->join('clients as c', 'cp.client_id = c.id', 'left') ->where('claim_dump_files.is_active', 1) ->orderBy('claim_dump_files.id', 'desc') ->findAll(); diff --git a/app/Views/cd_master_add_modal.php b/app/Views/cd_master_add_modal.php index 9ff01a91..c8bf0f05 100644 --- a/app/Views/cd_master_add_modal.php +++ b/app/Views/cd_master_add_modal.php @@ -129,7 +129,7 @@ if(res.status == true){ $('#cd_ac_no_for_cd_master_errorr').text(res.message); - // toastr.warning(res.message, 'warning'); + // toastr.warning(res.message, 'Warning'); // $('#cd_ac_no').val(''); $('#cd_master_btn_Submit').prop('disabled',true); return; diff --git a/app/Views/claim_dump_file_list.php b/app/Views/claim_dump_file_list.php index 9ba0451b..f9b14f6d 100644 --- a/app/Views/claim_dump_file_list.php +++ b/app/Views/claim_dump_file_list.php @@ -135,6 +135,8 @@ S.No  + Client + Policy File name User/Time Status @@ -150,6 +152,8 @@ + + @@ -740,13 +744,18 @@ })); $.each(data, function(index, item) { - var option = $('