410 lines
14 KiB
PHP
410 lines
14 KiB
PHP
<?php
|
|
namespace App\Helpers;
|
|
|
|
/**
|
|
* Nhance SSO Helper for CodeIgniter 4
|
|
*
|
|
* Usage:
|
|
* - Place this file in app/Helpers/nhance_sso_helper.php
|
|
* - Load helper: helper('nhance_sso');
|
|
*
|
|
* Functions:
|
|
* - generate_nhance_sso_url($userParams = null)
|
|
* - decrypt_nhance_sso_params($encryptedParams = null)
|
|
* - test_nhance_sso_encryption()
|
|
*/
|
|
|
|
if (!function_exists('generate_nhance_sso_url')) {
|
|
/**
|
|
* Generate Nhance SSO URL with encrypted parameters
|
|
*
|
|
* @param array|null $userParams User parameters array, uses sample data if null
|
|
* @return string Generated SSO URL
|
|
*/
|
|
function generate_nhance_sso_url($userParams = null) {
|
|
$helper = new NhanceSsoHelper();
|
|
return $helper->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;
|
|
}
|
|
}
|
|
|
|
?>
|