$authEndpoint, CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode(array( 'username' => $params["serverusername"], 'password' => $params["serverpassword"] )), CURLOPT_HTTPHEADER => array( "Content-Type: application/json" ), )); // Execute cURL request to authenticate $response = curl_exec($curl); // Check for errors if (curl_errno($curl)) { $token = false; $error = "cURL Error: " . curl_error($curl); } else { // Decode the response JSON to get the token $responseData = json_decode($response, true); $token = isset($responseData['access_token']) ? $responseData['access_token'] : false; $error = $token ? null : "Token not found in response"; } // Close cURL session curl_close($curl); return array($token, $error); } function apiRequest($endpoint, $token, $data = null, $method = 'POST') { // Prepare cURL request $curl = curl_init(); // Set default cURL options $options = array( CURLOPT_URL => $endpoint, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => array( "Authorization: Bearer " . $token, "Content-Type: application/json" ), ); // Handle different HTTP methods switch ($method) { case 'POST': if ($data !== null) { $options[CURLOPT_POST] = true; $options[CURLOPT_POSTFIELDS] = json_encode($data); } break; case 'GET': $options[CURLOPT_CUSTOMREQUEST] = 'GET'; break; case 'PUT': $options[CURLOPT_CUSTOMREQUEST] = 'PUT'; if ($data !== null) { $options[CURLOPT_POSTFIELDS] = json_encode($data); } break; case 'CONNECT': $options[CURLOPT_CUSTOMREQUEST] = 'CONNECT'; if ($data !== null) { $options[CURLOPT_POSTFIELDS] = json_encode($data); } break; case 'PATCH': $options[CURLOPT_CUSTOMREQUEST] = 'PATCH'; if ($data !== null) { $options[CURLOPT_POSTFIELDS] = json_encode($data); } break; case 'DELETE': $options[CURLOPT_CUSTOMREQUEST] = 'DELETE'; if ($data !== null) { $options[CURLOPT_POSTFIELDS] = json_encode($data); } break; default: // Handle unsupported methods throw new InvalidArgumentException("Unsupported method: $method"); } // Set the options for the cURL request curl_setopt_array($curl, $options); // Execute cURL request $response = curl_exec($curl); // Decode the response JSON $responseData = json_decode($response, true); // Close cURL session curl_close($curl); return $responseData; } ############### USER ACTIONS ################ # CREATE ACCOUNT function openpanel_CreateAccount($params) { list($jwtToken, $error) = getAuthToken($params); if (!$jwtToken) { return $error; // Return the error message as a plain string } try { $apiProtocol = getApiProtocol($params["serverhostname"]); $createUserEndpoint = $apiProtocol . $params["serverhostname"] . ':2087/api/users'; $packageId = $params['pid']; // Get the Product ID (Package ID) // Query the database to get the package name $result = select_query("tblproducts", "name", array("id" => $packageId)); $data = mysql_fetch_array($result); $packageName = $data['name']; // This is the package name // Prepare data for user creation $userData = array( 'username' => $params["username"], 'password' => $params["password"], 'email' => $params["clientsdetails"]["email"], 'plan_name' => $packageName ); // Make API request to create user $response = apiRequest($createUserEndpoint, $jwtToken, $userData); if (isset($response['success']) && $response['success'] === true) { return 'success'; } else { return isset($response['error']) ? $response['error'] : 'An unknown error occurred.'; } } catch (Exception $e) { logModuleCall( 'openpanel', __FUNCTION__, $params, $e->getMessage(), $e->getTraceAsString() ); return $e->getMessage(); } } # TERMINATE ACCOUNT function openpanel_TerminateAccount($params) { list($jwtToken, $error) = getAuthToken($params); if (!$jwtToken) { return $error; // Return the error message as a plain string } try { $apiProtocol = getApiProtocol($params["serverhostname"]); $userEndpoint = $apiProtocol . $params["serverhostname"] . ':2087/api/users/' . $params["username"]; // Step 1: Unsuspend the account if it's suspended try { $unsuspendData = array('action' => 'unsuspend'); $unsuspendResponse = apiRequest($userEndpoint, $jwtToken, $unsuspendData, 'PATCH'); } catch (Exception $e) { // If unsuspend fails, check if the account doesn't exist $errorMessage = $e->getMessage(); if (strpos($errorMessage, 'not found') !== false || strpos($errorMessage, 'User') !== false) { // Account does not exist, return an error message return 'Error: Account "' . $params["username"] . '" does not exist and could not be deleted.'; } else { return 'Failed to unsuspend account before termination: ' . $errorMessage; } } // Step 2: Now attempt to delete the account try { $response = apiRequest($userEndpoint, $jwtToken, null, 'DELETE'); if (isset($response['success']) && $response['success'] === true) { return 'success'; } else { return isset($response['error']) ? $response['error'] : 'An unknown error occurred during termination.'; } } catch (Exception $e) { // Log the exception for the delete action logModuleCall( 'openpanel', 'TerminateAccount - Delete Exception', $params, $e->getMessage(), $e->getTraceAsString() ); // Handle exception during the delete action return 'Error during account termination: ' . $e->getMessage(); } } catch (Exception $e) { logModuleCall( 'openpanel', __FUNCTION__, $params, $e->getMessage(), $e->getTraceAsString() ); return $e->getMessage(); } } # CHANGE PASSWORD FOR ACCOUNT function openpanel_ChangePassword($params) { list($jwtToken, $error) = getAuthToken($params); if (!$jwtToken) { return $error; // Return the error message as a plain string } try { $apiProtocol = getApiProtocol($params["serverhostname"]); $changePasswordEndpoint = $apiProtocol . $params["serverhostname"] . ':2087/api/users/' . $params["username"]; // Prepare data for password change $passwordData = array('password' => $params["password"]); // Make API request to change password for user $response = apiRequest($changePasswordEndpoint, $jwtToken, $passwordData, 'PATCH'); // Log the API request and response logModuleCall( 'openpanel', 'ChangePassword', $passwordData, $response ); // Check for success in the response if (isset($response['success']) && $response['success'] === true) { return 'success'; } else { // Return the error message from the response or a default message return isset($response['error']) ? $response['error'] : 'An unknown error occurred during password change.'; } } catch (Exception $e) { // Log the exception logModuleCall( 'openpanel', 'ChangePassword Exception', $params, $e->getMessage(), $e->getTraceAsString() ); // Return the exception message return 'Error: ' . $e->getMessage(); } } # SUSPEND ACCOUNT function openpanel_SuspendAccount($params) { list($jwtToken, $error) = getAuthToken($params); // If JWT token is not received, return error message if (!$jwtToken) { return json_encode(array("success" => false, "message" => $error)); } try { // Prepare the API endpoint for suspending the account $apiProtocol = getApiProtocol($params["serverhostname"]); $suspendAccountEndpoint = $apiProtocol . $params["serverhostname"] . ':2087/api/users/' . $params["username"]; // Prepare data for account suspension $suspendData = array('action' => 'suspend'); // Make the API request to suspend the account $response = apiRequest($suspendAccountEndpoint, $jwtToken, $suspendData, 'PATCH'); // Check the API response for success or failure if (isset($response['success']) && $response['success'] === true) { return 'success'; } else { // Return the error message from the API response return isset($response['error']) ? $response['error'] : 'An unknown error occurred.'; } } catch (Exception $e) { // Log the exception details logModuleCall( 'openpanel', 'SuspendAccount Exception', $params, $e->getMessage(), $e->getTraceAsString() ); // Return the exception message return 'Error: ' . $e->getMessage(); } } # UNSUSPEND ACCOUNT function openpanel_UnsuspendAccount($params) { list($jwtToken, $error) = getAuthToken($params); // If JWT token is not received, return error message if (!$jwtToken) { return json_encode(array("success" => false, "message" => $error)); } try { // Prepare the API endpoint to unsuspend the account $apiProtocol = getApiProtocol($params["serverhostname"]); $unsuspendAccountEndpoint = $apiProtocol . $params["serverhostname"] . ':2087/api/users/' . $params["username"]; // Prepare data for account unsuspension (if any) $unsuspendData = array('action' => 'unsuspend'); // Make the API request to unsuspend the account $response = apiRequest($unsuspendAccountEndpoint, $jwtToken, $unsuspendData, 'PATCH'); // Check the API response for success or failure if (isset($response['success']) && $response['success'] === true) { return 'success'; } else { // Return the error message from the API response return isset($response['error']) ? $response['error'] : 'An unknown error occurred.'; } } catch (Exception $e) { // Log the exception details logModuleCall( 'openpanel', 'UnsuspendAccount Exception', $params, $e->getMessage(), $e->getTraceAsString() ); // Return the exception message return 'Error: ' . $e->getMessage(); } } # CHANGE PACKAGE (PLAN) function openpanel_ChangePackage($params) { list($jwtToken, $error) = getAuthToken($params); if (!$jwtToken) { // Only log token issues as these are critical. logModuleCall('openpanel', 'ChangePackage', $params, "Error fetching token: $error"); return $error; } try { $apiProtocol = getApiProtocol($params["serverhostname"]); $changePlanEndpoint = $apiProtocol . $params["serverhostname"] . ':2087/api/users/' . $params["username"]; // Fetch the stored plan ID $storedPlanId = $params['configoption1']; // Retrieve available plans from the server $plans = getAvailablePlans($params); if (is_string($plans)) { logModuleCall('openpanel', 'ChangePackage', $params, "Error retrieving plans: $plans"); return "Error retrieving plans: $plans"; } // Find the actual plan name using the stored plan ID $planName = null; foreach ($plans as $plan) { if ($plan['id'] == $storedPlanId) { $planName = $plan['name']; break; } } if (!$planName) { logModuleCall('openpanel', 'ChangePackage', $params, "No matching plan name found for stored plan ID: $storedPlanId"); return "Error: No matching plan name found for stored plan ID: $storedPlanId"; } // Prepare data for changing plan $planData = array('plan_name' => $planName); // Make API request to change plan $response = apiRequest($changePlanEndpoint, $jwtToken, $planData, 'PUT'); // Log only on failure if (!(isset($response['success']) && $response['success'] === true)) { logModuleCall('openpanel', 'ChangePackage', array('command' => "opencli user-change_plan {$params['username']} $planName"), $response); return isset($response['error']) ? $response['error'] : 'An unknown error occurred during package change.'; } return 'success'; } catch (Exception $e) { logModuleCall('openpanel', 'ChangePackage Exception', $params, $e->getMessage(), $e->getTraceAsString()); return 'Error: ' . $e->getMessage(); } } ############### AUTOLOGIN LINKS ############## # LOGIN FOR USERS ON FRONT function openpanel_ClientArea($params) { list($jwtToken, $error) = getAuthToken($params); if (!$jwtToken) { return '
Error: ' . $error . '
'; } $apiProtocol = getApiProtocol($params["serverhostname"]); $getLoginLinkEndpoint = $apiProtocol . $params["serverhostname"] . ':2087/api/users/' . $params["username"]; // Prepare data for login link generation $loginData = array(); // Make API request to get login link $response = apiRequest($getLoginLinkEndpoint, $jwtToken, $loginData, 'CONNECT'); if (isset($response["link"])) { $code = ''; $code .= ' Login to OpenPanel '; $code .= ' '; } else { $code = 'Error: Unable to generate login link for OpenPanel. Please try again later.
'; if (isset($response["message"])) { $code .= 'Server Response: ' . htmlentities($response["message"]) . '
'; } } return $code; } # LOGIN FROM admin/configservers.php function openpanel_AdminLink($params) { $apiProtocol = getApiProtocol($params["serverhostname"]); $adminLoginEndpoint = $apiProtocol . $params["serverhostname"] . ':2087/login'; $code = ''; return $code; } # LOGIN FOR ADMINS FROM BACKEND function openpanel_LoginLink($params) { list($jwtToken, $error) = getAuthToken($params); if (!$jwtToken) { return 'Error: ' . $error . '
'; } $apiProtocol = getApiProtocol($params["serverhostname"]); $getLoginLinkEndpoint = $apiProtocol . $params["serverhostname"] . ':2087/api/users/' . $params["username"]; // Prepare data for login link generation $loginData = array(); // Make API request to get login link $response = apiRequest($getLoginLinkEndpoint, $jwtToken, $loginData, 'CONNECT'); if (isset($response["link"])) { $code = ''; $code .= ' Login to OpenPanel '; $code .= ' '; } else { // Log or print the response in case of error $code = 'Error: Unable to generate the login link. Please try again later.
'; if (isset($response["message"])) { $code .= 'Server Response: ' . htmlentities($response["message"]) . '
'; } } return $code; } function getAvailablePlans($params) { // Use WHMCS server parameters for OpenPanel $username = $params['serverusername']; // OpenPanel username $password = $params['serverpassword']; // OpenPanel password $hostname = $params['serverhostname']; // OpenPanel hostname $apiProtocol = getApiProtocol($hostname); $plansEndpoint = $apiProtocol . $hostname . ':2087/api/plans'; // Correct endpoint for OpenPanel API // Get the JWT token using the server credentials list($jwtToken, $error) = getAuthToken($params); if (!$jwtToken) { return "Error fetching token: $error"; // Return error if token cannot be fetched } // Prepare cURL request with Bearer token $curl = curl_init(); curl_setopt_array($curl, array( CURLOPT_URL => $plansEndpoint, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => array( "Authorization: Bearer " . $jwtToken, "Content-Type: application/json" ), CURLOPT_CUSTOMREQUEST => 'GET', // Enable SSL verification for production CURLOPT_SSL_VERIFYHOST => 2, // Verify the SSL certificate's host CURLOPT_SSL_VERIFYPEER => true, // Verify the SSL certificate )); // Execute the request $response = curl_exec($curl); // Capture any errors if (curl_errno($curl)) { return "cURL Error: " . curl_error($curl); // Return cURL error } // Close cURL session curl_close($curl); // Decode the response $plansResponse = json_decode($response, true); // Check if the plans were retrieved if (isset($plansResponse['plans']) && is_array($plansResponse['plans'])) { return $plansResponse['plans']; // Return the plans array } else { return "Error fetching plans: " . json_encode($plansResponse); // Return error } } function openpanel_ConfigOptions() { // Get the product ID from the request, if available $productId = isset($_REQUEST['id']) ? (int)$_REQUEST['id'] : 0; if (!$productId) { // If no product ID exists yet, prompt the user to save first return array( 'Note' => array( 'Description' => 'Please save the product first to configure options.', ), ); } // Fetch the server group assigned to this product $result = select_query('tblproducts', 'servergroup', array('id' => $productId)); $data = mysql_fetch_array($result); $serverGroupId = $data['servergroup']; if (!$serverGroupId) { // If no server group is selected yet, do not show the plans field return array( 'Note' => array( 'Description' => 'Please assign a server group to this product to fetch available plans.', ), ); } // Fetch servers in the selected server group $serversResult = select_query('tblservers', '*', array('disabled' => 0)); $servers = array(); while ($serverData = mysql_fetch_array($serversResult)) { // Check if the server belongs to the selected server group $serverGroupRelResult = select_query('tblservergroupsrel', 'groupid', array('serverid' => $serverData['id'])); while ($groupRel = mysql_fetch_array($serverGroupRelResult)) { if ($groupRel['groupid'] == $serverGroupId) { $servers[] = $serverData; break; } } } if (count($servers) == 0) { // No servers found in the group, show a message and don't load the plans field return array( 'Note' => array( 'Description' => 'No servers found in the assigned server group.', ), ); } // Use the first server in the group $server = $servers[0]; $params = array( 'serverhostname' => $server['hostname'], 'serverusername' => $server['username'], 'serverpassword' => decrypt($server['password']), ); // Fetch available plans from OpenPanel $plans = getAvailablePlans($params); // Handle errors in fetching plans if (is_string($plans)) { // Error message return array( 'Note' => array( 'Description' => 'Error fetching plans: ' . $plans, ), ); } // Populate plans in the dropdown $planOptions = array(); if ($plans && is_array($plans)) { foreach ($plans as $plan) { $planOptions[$plan['id']] = $plan['name']; } } return array( 'Plan' => array( 'Type' => 'dropdown', 'Options' => $planOptions, 'Description' => 'Select a plan from OpenPanel', ), ); } ############### MAINTENANCE ################ # TODO: GET USAGE FOR USERS!!!!!!!! function openpanel_UsageUpdate($params) { # resposne should be formated like this: #{ # "disk_usage": "1024 MB", # "disk_limit": "2048 MB", # "bandwidth_usage": "512 MB", # "bandwidth_limit": "1024 MB" #} $apiProtocol = getApiProtocol($params["serverhostname"]); $authEndpoint = $apiProtocol . $params["serverhostname"] . ':2087/api/'; // Authenticate and get JWT token list($jwtToken, $error) = getAuthToken($params); if (!$jwtToken) { return json_encode(array( "success" => false, "message" => $error )); } // Prepare API endpoint for getting usage $getUsageEndpoint = $apiProtocol . $params["serverhostname"] . ':2087/api/usage/'; // Prepare cURL request for getting usage $curl = curl_init(); curl_setopt_array($curl, array( CURLOPT_URL => $getUsageEndpoint, CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => 'PATCH', CURLOPT_HTTPHEADER => array( "Authorization: Bearer " . $jwtToken, "Content-Type: application/json" ), )); // Execute cURL request for getting usage $response = curl_exec($curl); // Check for errors if (curl_errno($curl)) { $result = json_encode(array( "success" => false, "message" => "cURL Error: " . curl_error($curl) )); } else { // Decode the response JSON $usageData = json_decode($response, true); // Loop through results and update database foreach ($usageData as $user => $values) { update_query("tblhosting", array( "diskusage" => $values['disk_usage'], "disklimit" => $values['disk_limit'], "lastupdate" => "now()" ), array("server" => $params['serverid'], "username" => $user)); } $result = json_encode(array( "success" => true, "message" => "Usage updated successfully" )); } // Close cURL session curl_close($curl); return $result; } ?>