From e73e85c5a9faa79b50e4949328c1d2a3cbc49ddf Mon Sep 17 00:00:00 2001 From: EZSCALE Date: Sat, 7 Feb 2026 15:23:56 -0600 Subject: [PATCH] feat: streamline network panel, conditional self-service, remove IP add endpoints - Populate network panel from server data response instead of separate API call - Conditionally render self-service billing panel based on selfServiceMode config - Pass selfServiceMode to Smarty template vars - Remove addIPv4, addIPv6, serverIPs client endpoints and UI buttons - Remove upgrade/downgrade link from resources panel - Bump cache-busting version to v0.0.20 - Update CHANGELOG.md Co-Authored-By: Claude Opus 4.6 --- CHANGELOG.md | 9 +- modules/servers/VirtFusionDirect/client.php | 89 ------------- .../VirtFusionDirect/lib/ModuleFunctions.php | 1 + .../VirtFusionDirect/templates/js/module.js | 123 +++++------------- .../VirtFusionDirect/templates/overview.tpl | 19 +-- 5 files changed, 48 insertions(+), 193 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e7d4208..c5b2d71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ All notable changes to the VirtFusion Direct Provisioning Module for WHMCS. - **Power management** — Start, restart, graceful shutdown, and force power off controls in client area - **Server rebuild** — Reinstall with any available OS template from client area with confirmation dialog - **Server rename** — Change server display name via client area -- **Network management** — View, add, and remove IPv4 addresses and IPv6 subnets from client area +- **Network management** — View and remove IPv4 addresses; view IPv6 subnets from client area - **VNC console** — Browser-based console access (VirtFusion v6.1.0+) - **VNC runtime check** — VNC panel auto-hides when VNC is disabled on the server - **Backup management** — Assign and remove backup plans via API @@ -23,6 +23,7 @@ All notable changes to the VirtFusion Direct Provisioning Module for WHMCS. - **Traffic usage display** — Bandwidth used vs allocated - **Checkout validation** — `ShoppingCartValidateCheckout` hook ensures OS selection before order placement - **SSH key paste at checkout** — Users can paste a raw SSH public key during checkout; key is created via `POST /ssh_keys` during provisioning +- **SSH Ed25519 key generator** — Client-side keypair generation on checkout page using Web Crypto API; auto-fills public key and presents private key for download/copy - **Order form sliders** — Configurable option dropdowns replaced with styled range sliders for resource selection - **Self-service billing** — Credit balance display, usage breakdown, and credit top-up from client area - **Self-service config options** — Product config options 4-6: Self-Service Mode, Auto Top-Off Threshold, Auto Top-Off Amount @@ -41,6 +42,8 @@ All notable changes to the VirtFusion Direct Provisioning Module for WHMCS. - `changePackage()` now applies individual resource modifications from configurable options after updating the package - `initServerBuild()` accepts optional VF user ID parameter for SSH key creation - `ServerResource::process()` returns raw numeric resource values and `vncEnabled` boolean +- Network panel now populated from server data response instead of separate API call +- Self-service billing panel conditionally rendered based on `selfServiceMode` config option - Comprehensive README rewrite with installation, configuration, troubleshooting, and API reference ### Fixed @@ -54,10 +57,12 @@ All notable changes to the VirtFusion Direct Provisioning Module for WHMCS. - Memory conversion checks key name instead of display name - Fix TestConnection failing for new/unsaved servers — use `$params` directly instead of database lookup (serverid=0 is falsy) - Fix traffic "Used" showing `-` instead of `0 GB` when traffic is allocated but no usage reported yet -- Add cache-busting `?v=0.0.19` to JS/CSS includes in overview.tpl to prevent stale browser cache +- Bump cache-busting version to `?v=0.0.20` for JS/CSS includes in overview.tpl ### Removed - Firewall feature (non-functional — rulesets must be created in VirtFusion admin panel) +- IP add endpoints (`addIPv4`, `addIPv6`, `serverIPs`) and add buttons — IPs are managed by VirtFusion during provisioning +- Upgrade/Downgrade link from resources panel ## [0.0.18] - 2025-10-01 diff --git a/modules/servers/VirtFusionDirect/client.php b/modules/servers/VirtFusionDirect/client.php index 2950ec7..c081b53 100644 --- a/modules/servers/VirtFusionDirect/client.php +++ b/modules/servers/VirtFusionDirect/client.php @@ -180,50 +180,6 @@ switch ($action) { // IP Address Management // ================================================================= - /** - * Get server IP addresses (from server data). - */ - case 'serverIPs': - - $serviceID = $vf->validateServiceID(true); - - if (!$vf->validateUserOwnsService($serviceID)) { - $vf->output(['success' => false, 'errors' => 'service <> owner mismatch'], true, true, 403); - } - - $data = $vf->fetchServerData($serviceID); - - if ($data) { - $resource = (new ServerResource())->process($data); - $vf->output(['success' => true, 'data' => [ - 'ipv4' => $resource['primaryNetwork']['ipv4Unformatted'], - 'ipv6' => $resource['primaryNetwork']['ipv6Unformatted'], - ]], true, true, 200); - } - - $vf->output(['success' => false, 'errors' => 'Unable to retrieve IP addresses'], true, true, 500); - break; - - /** - * Add an IPv4 address. - */ - case 'addIPv4': - - $serviceID = $vf->validateServiceID(true); - - if (!$vf->validateUserOwnsService($serviceID)) { - $vf->output(['success' => false, 'errors' => 'service <> owner mismatch'], true, true, 403); - } - - $result = $vf->addIPv4($serviceID); - - if ($result) { - $vf->output(['success' => true, 'data' => ['message' => 'IPv4 address added successfully']], true, true, 200); - } - - $vf->output(['success' => false, 'errors' => 'Failed to add IPv4 address. No available addresses or limit reached.'], true, true, 500); - break; - /** * Remove an IPv4 address. */ @@ -249,51 +205,6 @@ switch ($action) { $vf->output(['success' => false, 'errors' => 'Failed to remove IPv4 address'], true, true, 500); break; - /** - * Add an IPv6 subnet. - */ - case 'addIPv6': - - $serviceID = $vf->validateServiceID(true); - - if (!$vf->validateUserOwnsService($serviceID)) { - $vf->output(['success' => false, 'errors' => 'service <> owner mismatch'], true, true, 403); - } - - $result = $vf->addIPv6($serviceID); - - if ($result) { - $vf->output(['success' => true, 'data' => ['message' => 'IPv6 subnet added successfully']], true, true, 200); - } - - $vf->output(['success' => false, 'errors' => 'Failed to add IPv6 subnet. No available subnets or limit reached.'], true, true, 500); - break; - - /** - * Remove an IPv6 subnet. - */ - case 'removeIPv6': - - $serviceID = $vf->validateServiceID(true); - - if (!$vf->validateUserOwnsService($serviceID)) { - $vf->output(['success' => false, 'errors' => 'service <> owner mismatch'], true, true, 403); - } - - $subnet = isset($_GET['subnet']) ? trim($_GET['subnet']) : ''; - if (empty($subnet)) { - $vf->output(['success' => false, 'errors' => 'Invalid IPv6 subnet'], true, true, 400); - } - - $result = $vf->removeIPv6($serviceID, $subnet); - - if ($result) { - $vf->output(['success' => true, 'data' => ['message' => 'IPv6 subnet removed successfully']], true, true, 200); - } - - $vf->output(['success' => false, 'errors' => 'Failed to remove IPv6 subnet'], true, true, 500); - break; - // ================================================================= // VNC Console // ================================================================= diff --git a/modules/servers/VirtFusionDirect/lib/ModuleFunctions.php b/modules/servers/VirtFusionDirect/lib/ModuleFunctions.php index d98c7c0..0a6d167 100644 --- a/modules/servers/VirtFusionDirect/lib/ModuleFunctions.php +++ b/modules/servers/VirtFusionDirect/lib/ModuleFunctions.php @@ -531,6 +531,7 @@ class ModuleFunctions extends Module 'systemURL' => Database::getSystemUrl(), 'serviceStatus' => $params['status'], 'serverHostname' => $serverHostname, + 'selfServiceMode' => (int) ($params['configoption4'] ?? 0), ], ]; } catch (\Throwable $e) { diff --git a/modules/servers/VirtFusionDirect/templates/js/module.js b/modules/servers/VirtFusionDirect/templates/js/module.js index c8cf44d..fbcd689 100644 --- a/modules/servers/VirtFusionDirect/templates/js/module.js +++ b/modules/servers/VirtFusionDirect/templates/js/module.js @@ -77,6 +77,41 @@ function vfServerData(serviceId, systemUrl) { $("#vf-resources-panel").show(); + // Populate network panel from server data + var ipv4List = $("#vf-ipv4-list"); + var ipv6List = $("#vf-ipv6-list"); + ipv4List.empty(); + ipv6List.empty(); + + var net = response.data.primaryNetwork || {}; + var ipv4Arr = net.ipv4Unformatted || []; + var ipv6Arr = net.ipv6Unformatted || []; + + if (ipv4Arr.length > 0) { + $.each(ipv4Arr, function (i, ip) { + var row = $('
'); + row.append('' + $('').text(ip).html() + ''); + if (i > 0) { + row.append(' '); + } + ipv4List.append(row); + }); + } else { + ipv4List.append('No IPv4 addresses'); + } + + if (ipv6Arr.length > 0) { + $.each(ipv6Arr, function (i, subnet) { + var row = $('
'); + row.append('' + $('').text(subnet).html() + ''); + ipv6List.append(row); + }); + } else { + ipv6List.append('No IPv6 subnets'); + } + + $("#vf-network-content").show(); + $("#vf-server-info").show(); } else { $("#vf-server-info-error").show(); @@ -301,92 +336,6 @@ function impersonateServerOwner(serviceId, systemUrl) { // Network / IP Management // ========================================================================= -function vfLoadServerIPs(serviceId, systemUrl) { - $.ajax({ - type: "GET", - dataType: "json", - url: systemUrl + "modules/servers/VirtFusionDirect/client.php?serviceID=" + encodeURIComponent(serviceId) + "&action=serverIPs" - }).done(function (response) { - if (response.success) { - var ipv4List = $("#vf-ipv4-list"); - var ipv6List = $("#vf-ipv6-list"); - ipv4List.empty(); - ipv6List.empty(); - - if (response.data.ipv4 && response.data.ipv4.length > 0) { - $.each(response.data.ipv4, function (i, ip) { - var row = $('
'); - row.append('' + $('').text(ip).html() + ''); - if (i > 0) { - row.append(' '); - } - ipv4List.append(row); - }); - } else { - ipv4List.append('No IPv4 addresses'); - } - - if (response.data.ipv6 && response.data.ipv6.length > 0) { - $.each(response.data.ipv6, function (i, subnet) { - var row = $('
'); - row.append('' + $('').text(subnet).html() + ''); - row.append(' '); - ipv6List.append(row); - }); - } else { - ipv6List.append('No IPv6 subnets'); - } - - $("#vf-network-content").show(); - } else { - $("#vf-network-content").show(); - $("#vf-ipv4-list").html('Unable to load'); - $("#vf-ipv6-list").html('Unable to load'); - } - }).fail(function () { - $("#vf-network-content").show(); - $("#vf-ipv4-list").html('Unable to load'); - $("#vf-ipv6-list").html('Unable to load'); - }).always(function () { - $("#vf-network-loader").hide(); - }); -} - -function vfAddIP(serviceId, systemUrl, action) { - var btn = $("#vf-add-" + (action === "addIPv4" ? "ipv4" : "ipv6")); - var spinner = btn.find(".vf-btn-spinner"); - var alertDiv = $("#vf-network-alert"); - - btn.prop("disabled", true); - spinner.show(); - alertDiv.hide(); - - $.ajax({ - type: "GET", - dataType: "json", - url: systemUrl + "modules/servers/VirtFusionDirect/client.php?serviceID=" + encodeURIComponent(serviceId) + "&action=" + encodeURIComponent(action) - }).done(function (response) { - if (response.success) { - alertDiv.removeClass("alert-danger").addClass("alert-success"); - alertDiv.text(response.data.message || "IP address added successfully."); - alertDiv.show(); - // Refresh IP list - vfLoadServerIPs(serviceId, systemUrl); - } else { - alertDiv.removeClass("alert-success").addClass("alert-danger"); - alertDiv.text(response.errors || "Failed to add IP address."); - alertDiv.show(); - } - }).fail(function () { - alertDiv.removeClass("alert-success").addClass("alert-danger"); - alertDiv.text("An error occurred. Please try again."); - alertDiv.show(); - }).always(function () { - spinner.hide(); - btn.prop("disabled", false); - }); -} - function vfRemoveIP(serviceId, systemUrl, action, identifier) { if (!confirm("Are you sure you want to remove this IP address?")) { return; @@ -406,7 +355,7 @@ function vfRemoveIP(serviceId, systemUrl, action, identifier) { alertDiv.removeClass("alert-danger").addClass("alert-success"); alertDiv.text(response.data.message || "IP address removed successfully."); alertDiv.show(); - vfLoadServerIPs(serviceId, systemUrl); + vfServerData(serviceId, systemUrl); } else { alertDiv.removeClass("alert-success").addClass("alert-danger"); alertDiv.text(response.errors || "Failed to remove IP address."); diff --git a/modules/servers/VirtFusionDirect/templates/overview.tpl b/modules/servers/VirtFusionDirect/templates/overview.tpl index 250ff9b..2f604dd 100644 --- a/modules/servers/VirtFusionDirect/templates/overview.tpl +++ b/modules/servers/VirtFusionDirect/templates/overview.tpl @@ -1,5 +1,5 @@ - - + + {if $serviceStatus eq 'Active'} @@ -175,30 +175,18 @@
-
-
-
-
@@ -247,7 +235,6 @@ - Upgrade / Downgrade Resources @@ -267,6 +254,7 @@ {* Self Service — Billing & Usage Panel *} +{if $selfServiceMode > 0} +{/if} {elseif $serviceStatus eq 'Suspended'}