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/ExpenseController.php b/app/Controllers/ExpenseController.php index c734284d..525c16d0 100644 --- a/app/Controllers/ExpenseController.php +++ b/app/Controllers/ExpenseController.php @@ -34,8 +34,7 @@ class ExpenseController extends AdminController try { $data['tab_name'] = 'Expense'; $data['page_name'] = 'Expense'; - $descriptionPattern = '/^[a-zA-Z0-9\s\.\,\-\(\)\/\&\+]+$/u'; - + $descriptionPattern = '/^[a-zA-Z0-9\s\.\,\-\(\)\/\&\+\'"]+$/u'; // Raw GET filters $rawFilters = $this->request->getGet() ?? []; $rawFilters = is_array($rawFilters) ? $rawFilters : []; @@ -97,6 +96,7 @@ class ExpenseController extends AdminController // Clients for dropdown $data['clients'] = $this->clientModel ->select('id, client_name, short_name') + ->where('client_type', 1) ->where('is_active', 1) ->orderBy('client_name', 'ASC') ->findAll(); @@ -228,11 +228,12 @@ class ExpenseController extends AdminController ], ], 'amount' => [ - 'rules' => 'required|numeric|greater_than_equal_to[0]', + 'rules' => 'required|numeric|greater_than_equal_to[0]|less_than_equal_to[100000000]', 'errors' => [ 'required' => 'Amount is required', 'numeric' => 'Amount must be numeric', 'greater_than_equal_to' => 'Amount cannot be negative', + 'less_than_equal_to' => 'Amount cannot be greater than 100 Cr.', ], ], ]; 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 986579e6..a0df4c9d 100644 --- a/app/Controllers/TicketController.php +++ b/app/Controllers/TicketController.php @@ -1178,9 +1178,9 @@ class TicketController extends BaseController ], 'tpa_no' => [ 'label' => 'TPA ID', - 'rules' => 'permit_empty|regex_match[/^[a-zA-Z0-9\/]+$/]', + 'rules' => 'permit_empty|regex_match[/^[a-zA-Z0-9\/\-_]+$/]', 'errors' => [ - 'regex_match' => 'TPA ID can only contain letters, numbers, and /.' + 'regex_match' => 'TPA ID can only contain letters, numbers, /, -, and _.' ] ], 'emp_mobile' => ['label' => 'Employee Mobile No','rules' => 'required|numeric|exact_length[10]', @@ -1233,9 +1233,9 @@ class TicketController extends BaseController ], 'hospital_address' => [ 'label' => 'Hospital Address', - 'rules' => 'permit_empty|regex_match[/^[a-zA-Z0-9\s\-_.,#\/]+$/]', + 'rules' => 'permit_empty|regex_match[/^[a-zA-Z0-9\s.,#\/_-]+$/]', 'errors' => [ - 'regex_match' => 'The {field} contains invalid characters (Allowed: letters, numbers, spaces, dashes, commas, dots, # and /).' + 'regex_match' => 'The {field} contains invalid characters (Allowed: letters, numbers, spaces, -, _, ., ,, # and /).' ], ], 'hospital_state' => [ @@ -1531,9 +1531,9 @@ class TicketController extends BaseController ], 'tpa_no' => [ 'label' => 'TPA ID', - 'rules' => 'permit_empty|regex_match[/^[a-zA-Z0-9\/]+$/]', + 'rules' => 'permit_empty|regex_match[/^[a-zA-Z0-9\/\-_]+$/]', 'errors' => [ - 'regex_match' => 'TPA ID can only contain letters, numbers, and /.' + 'regex_match' => 'TPA ID can only contain letters, numbers, /, -, and _.' ] ], 'emp_mobile' => ['label' => 'Employee Mobile No','rules' => 'required|numeric|exact_length[10]', @@ -1586,9 +1586,9 @@ class TicketController extends BaseController ], 'hospital_address' => [ 'label' => 'Hospital Address', - 'rules' => 'permit_empty|regex_match[/^[a-zA-Z0-9\s\-_.,#\/]+$/]', + 'rules' => 'permit_empty|regex_match[/^[a-zA-Z0-9\s.,#\/_-]+$/]', 'errors' => [ - 'regex_match' => 'The {field} contains invalid characters (Allowed: letters, numbers, spaces, dashes, commas, dots, # and /).' + 'regex_match' => 'The {field} contains invalid characters (Allowed: letters, numbers, spaces, -, _, ., ,, # and /).' ], ], 'hospital_state' => [ @@ -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/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 = $('