generateSSOUrl($userParams); } } if (!function_exists('decrypt_nhance_sso_params')) { /** * Decrypt Nhance SSO parameters for testing * * @param string|null $encryptedParams Encrypted parameters, uses sample if null * @return array Decrypted user parameters */ function decrypt_nhance_sso_params($encryptedParams = null) { $helper = new NhanceSsoHelper(); return $helper->decryptUserParams($encryptedParams); } } if (!function_exists('test_nhance_sso_encryption')) { /** * Test Nhance SSO encryption/decryption functionality * * @return array Test results */ function test_nhance_sso_encryption() { $helper = new NhanceSsoHelper(); return $helper->runTests(); } } /** * Nhance SSO Helper Class */ class NhanceWelnessSsoHelper { private static $baseUrl = 'https://web.samuraijack.xyz/sso'; private static $clientId = 'nhance-gt-2tx7'; private static $encryptionKey = '32D1D5535157AF3D4667ADAB0CC795D77D022BB281AD3272EB134C72BD0B185E'; private static $algorithm = 'aes-256-cbc'; /** * Get sample user parameters */ private static function getSampleUserParams() { return [ 'name' => 'John Doe 3', 'email' => 'john.doe3@email.com', 'memberId' => 'TEST-REL-01', 'gender' => 'Male', 'dob' => '1997-01-01', 'policyName' => 'Nhance DEMO', 'phone' => '6676126763', 'employeeId' => 'EMP-NHANCE-TEST-03', 'policyNumber' => "EMP-NHANCE-TEST-03", 'policyStartDate' => '2025-09-08', 'policyEndDate' => '2026-09-08', 'moduleName' => 'home', 'relation' => 'self', 'planId' => 'NHANCE-PLAN-1', ]; } /** * Get sample encrypted parameters for testing */ private static function getSampleEncryptedParams() { // Generate sample encrypted params using sample data $sampleParams = (SELF::getSampleUserParams()); return SELF::encryptUserParams($sampleParams); } /** * Encrypt user parameters using AES-256-CBC */ private static function encryptUserParams($userParams) { try { // $jsonData = json_encode($userParams); // // Generate a random IV // $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length(SELF::$algorithm)); // // $iv = 'getvisitappdotcom'; // // Convert hex key to binary // $key = hex2bin(SELF::$encryptionKey); // // $key = (SELF::$encryptionKey); // // Encrypt the data // $encrypted = openssl_encrypt($jsonData, SELF::$algorithm, $key, 0, $iv); // if ($encrypted === false) { // throw new Exception("Encryption failed"); // } // // Combine IV and encrypted data, then encode // $encryptedData = base64_encode($iv . base64_decode($encrypted)); // // Make URL safe // return str_replace(['+', '/', '='], ['-', '_', ''], $encryptedData); $key = "getvisitappdotcom"; // Step 1: Build plaintext exactly like Node (raw join with '&') $str = ''; foreach ($userParams as $k => $v) { $str .= '&' . $k . '=' . $v; } $plainText = substr($str, 1); // remove leading & // Step 2: Derive 32-byte key with SHA256 $sha256Key = hash('sha256', $key, true); // Step 3: Fixed IV $iv = "getvisitappdocom"; // 16 bytes // Step 4: Encrypt $cipherRaw = openssl_encrypt( $plainText, 'aes-256-cbc', $sha256Key, OPENSSL_RAW_DATA, $iv ); // Step 5: base64url encode return rtrim(strtr(base64_encode($cipherRaw), '+/', '-_'), '='); } catch (Exception $e) { log_message('error', 'Nhance SSO Encryption Error: ' . $e->getMessage()); throw new Exception("Encryption failed: " . $e->getMessage()); } } /** * Decrypt user parameters for testing purposes */ public static function decryptUserParams($encryptedParams = null) { try { // Use sample encrypted params if none provided if ($encryptedParams === null) { $encryptedParams = SELF::getSampleEncryptedParams(); log_message('info', 'Using sample encrypted parameters for decryption test'); } // Handle URL format if full URL is passed if (strpos($encryptedParams, 'userParams=') !== false) { $encryptedParams = SELF::extractParamsFromUrl($encryptedParams); } // Make URL-safe characters back to base64 $encryptedParams = str_replace(['-', '_'], ['+', '/'], $encryptedParams); // Add padding if needed $encryptedParams = $encryptedParams . str_repeat('=', (4 - strlen($encryptedParams) % 4) % 4); // Decode base64 $data = base64_decode($encryptedParams); if ($data === false) { throw new Exception("Failed to decode base64 data"); } // Extract IV and encrypted data $ivLength = openssl_cipher_iv_length(SELF::$algorithm); $iv = substr($data, 0, $ivLength); $encrypted = base64_encode(substr($data, $ivLength)); // Convert hex key to binary $key = hex2bin(SELF::$encryptionKey); // Decrypt the data $decrypted = openssl_decrypt($encrypted, SELF::$algorithm, $key, 0, $iv); if ($decrypted === false) { throw new Exception("Decryption failed"); } // Decode JSON $userParams = json_decode($decrypted, true); if ($userParams === null) { throw new Exception("Failed to decode JSON data"); } return $userParams; } catch (Exception $e) { log_message('error', 'Nhance SSO Decryption Error: ' . $e->getMessage()); throw new Exception("Decryption error: " . $e->getMessage()); } } /** * Generate SSO URL with encrypted parameters */ public static function generateSSOUrl($userParams = null) { try { // Use sample parameters if none provided if ($userParams === null) { $userParams = SELF::getSampleUserParams(); log_message('info', 'Using sample user parameters for SSO URL generation'); } // Validate required parameters SELF::validateUserParams($userParams); // Encrypt user parameters $encryptedParams = SELF::encryptUserParams($userParams); // Build the SSO URL $ssoUrl = SELF::$baseUrl . '?userParams=' . $encryptedParams . '&clientId=' . SELF::$clientId; log_message('info', 'Nhance SSO URL generated successfully for user: ' . $userParams['email']); return $ssoUrl; } catch (Exception $e) { log_message('error', 'Nhance SSO URL Generation Error: ' . $e->getMessage()); throw new Exception("Failed to generate SSO URL: " . $e->getMessage()); } } /** * Validate user parameters */ private static function validateUserParams($userParams) { $requiredFields = [ 'name', 'email', 'phone', 'memberId', 'gender', 'dob', 'policyName', 'policyNumber', 'employeeId', 'moduleName', 'relation', 'planId', 'policyStartDate', 'policyEndDate' ]; foreach ($requiredFields as $field) { if (!isset($userParams[$field]) || empty($userParams[$field])) { throw new Exception("Required field '$field' is missing or empty"); } } // Validate date formats if (!SELF::validateDate($userParams['dob']) || !SELF::validateDate($userParams['policyStartDate']) || !SELF::validateDate($userParams['policyEndDate'])) { throw new Exception("Invalid date format. Use YYYY-MM-DD format"); } // Validate gender if (!in_array($userParams['gender'], ['Male', 'Female'])) { throw new Exception("Gender must be 'Male' or 'Female'"); } // Validate email if (!filter_var($userParams['email'], FILTER_VALIDATE_EMAIL)) { throw new Exception("Invalid email format"); } } /** * Validate date format (YYYY-MM-DD) */ private static function validateDate($date) { $d = \DateTime::createFromFormat('Y-m-d', $date); return $d && $d->format('Y-m-d') === $date; } /** * Extract encrypted parameters from SSO URL */ private static function extractParamsFromUrl($ssoUrl) { $parsedUrl = parse_url($ssoUrl); if (!isset($parsedUrl['query'])) { throw new Exception("No query parameters found in URL"); } parse_str($parsedUrl['query'], $queryParams); if (!isset($queryParams['userParams'])) { throw new Exception("userParams not found in URL"); } return $queryParams['userParams']; } /** * Run comprehensive tests */ public static function runTests() { $results = [ 'tests_passed' => 0, 'tests_failed' => 0, 'test_details' => [] ]; try { // Test 1: Sample data encryption/decryption log_message('info', 'Running Nhance SSO Test 1: Sample data round-trip'); $sampleParams = SELF::getSampleUserParams(); $ssoUrl = SELF::generateSSOUrl($sampleParams); $encryptedParams = SELF::extractParamsFromUrl($ssoUrl); $decryptedParams = SELF::decryptUserParams($encryptedParams); $test1Pass = json_encode($sampleParams) === json_encode($decryptedParams); $results['test_details']['sample_round_trip'] = [ 'status' => $test1Pass ? 'PASSED' : 'FAILED', 'original_params' => $sampleParams, 'decrypted_params' => $decryptedParams, 'sso_url' => $ssoUrl ]; if ($test1Pass) { $results['tests_passed']++; } else { $results['tests_failed']++; } // Test 2: Custom parameters log_message('info', 'Running Nhance SSO Test 2: Custom parameters'); $customParams = [ 'name' => 'Jane Smith Test', 'email' => 'jane.test@example.com', 'phone' => '1122334455', 'memberId' => 'TEST-CUSTOM-001', 'gender' => 'Female', 'dob' => '1985-03-20', 'policyName' => 'Custom Test Policy', 'policyNumber' => 'CUSTOM-POL-001', 'employeeId' => 'EMP-CUSTOM-001', 'moduleName' => 'home', 'relation' => 'self', 'planId' => 'NHANCE-PLAN-1', 'policyStartDate' => date('Y-m-d'), 'policyEndDate' => date('Y-m-d', strtotime('+2 years')) ]; $customSsoUrl = SELF::generateSSOUrl($customParams); $customEncryptedParams = SELF::extractParamsFromUrl($customSsoUrl); $customDecryptedParams = SELF::decryptUserParams($customEncryptedParams); $test2Pass = json_encode($customParams) === json_encode($customDecryptedParams); $results['test_details']['custom_round_trip'] = [ 'status' => $test2Pass ? 'PASSED' : 'FAILED', 'original_params' => $customParams, 'decrypted_params' => $customDecryptedParams, 'sso_url' => $customSsoUrl ]; if ($test2Pass) { $results['tests_passed']++; } else { $results['tests_failed']++; } // Test 3: Null parameter handling log_message('info', 'Running Nhance SSO Test 3: Null parameter handling'); $nullTestUrl = SELF::generateSSOUrl(null); $nullDecrypted = SELF::decryptUserParams(null); $test3Pass = !empty($nullTestUrl) && !empty($nullDecrypted); $results['test_details']['null_parameter_handling'] = [ 'status' => $test3Pass ? 'PASSED' : 'FAILED', 'generated_url' => $nullTestUrl, 'decrypted_sample' => $nullDecrypted ]; if ($test3Pass) { $results['tests_passed']++; } else { $results['tests_failed']++; } } catch (Exception $e) { $results['tests_failed']++; $results['test_details']['error'] = $e->getMessage(); log_message('error', 'Nhance SSO Test Error: ' . $e->getMessage()); } $results['overall_status'] = $results['tests_failed'] === 0 ? 'ALL_PASSED' : 'SOME_FAILED'; log_message('info', 'Nhance SSO Tests completed. Passed: ' . $results['tests_passed'] . ', Failed: ' . $results['tests_failed']); return $results; } } ?>