diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 68e0a71..df0e616 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -26,6 +26,9 @@ jobs: with: # You can specify the branches to release from branch: main + extra_plugins: | + @semantic-release/changelog + @semantic-release/git env: # GITHUB_TOKEN is required for authentication GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.releaserc.json b/.releaserc.json new file mode 100644 index 0000000..b9660c1 --- /dev/null +++ b/.releaserc.json @@ -0,0 +1,13 @@ +{ + "branches": ["main"], + "plugins": [ + "@semantic-release/commit-analyzer", + "@semantic-release/release-notes-generator", + ["@semantic-release/changelog", { "changelogFile": "CHANGELOG.md" }], + "@semantic-release/github", + ["@semantic-release/git", { + "assets": ["CHANGELOG.md"], + "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" + }] + ] +} diff --git a/CHANGELOG.md b/CHANGELOG.md index c5b2d71..d410757 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,68 +2,6 @@ All notable changes to the VirtFusion Direct Provisioning Module for WHMCS. -## [Unreleased] - -### Added -- **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 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 -- **Resource modification** — In-place memory, CPU, and traffic changes (VirtFusion v6.2.0+) -- **Resources panel** — Client area panel showing current memory, CPU, storage, traffic allocation with progress bars and upgrade/downgrade link -- **UsageUpdate cron** — Automated bandwidth and disk usage sync from VirtFusion to WHMCS -- **Dry run validation** — Test server creation parameters before provisioning -- **Admin "Validate Server Config" button** — Dry run from admin services tab -- **TestConnection** — Validate API credentials from WHMCS server settings -- **ServiceSingleSignOn** — Native WHMCS SSO integration for VirtFusion panel -- **Server status badge** — Visual indicator of server state in overview -- **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 -- **Auto top-off** — During WHMCS daily cron, automatically adds credit when balance falls below threshold -- **Self-service user creation** — New VirtFusion users created with self-service billing settings when enabled -- **CLAUDE.md** — Project architecture and development guidance for Claude Code - -### Changed -- Enable SSL/TLS certificate verification by default (was disabled) -- Remove `error_reporting(0)` that silenced all errors -- Add input sanitization on all user parameters (type casting, regex filtering) -- Return proper HTTP status codes (401, 403, 400, 500) instead of always 200 -- Add XSS protection with `htmlspecialchars()` and `encodeURIComponent()` -- Readable, unminified JavaScript with JSDoc header -- Dual panel/card CSS classes for Bootstrap 3/4/5 theme compatibility -- `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 -- Add `isset()` guards before `count()` on ipv4/ipv6 arrays in ServerResource to prevent PHP 8.0+ TypeError -- Add null checks after `getWhmcsService()` and `getCP()` in all Module/ModuleFunctions methods to prevent fatal null dereference -- Fix HTTP status codes throughout admin.php (404, 400, 500, 502 instead of always 200) -- Guard ConfigureService methods against `$this->cp === false` -- Replace `exit()` with `RuntimeException` in Curl.php -- Change `catch(Exception)` to `catch(Throwable)` in hooks.php for PHP 8.0+ compatibility -- Open VNC window before AJAX call to avoid popup blocker -- 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 -- 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 ### Changed diff --git a/CLAUDE.md b/CLAUDE.md index 267cc01..ad04e21 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -56,8 +56,15 @@ Releases are automated via GitHub Actions using semantic-release on pushes to `m - **`templates/overview.tpl`** — Smarty template for client area (server info, power, network, rebuild, resources, VNC, self-service billing, billing overview) - **`templates/js/module.js`** — Vanilla JS (1000+ lines) handling AJAX calls to `client.php`, DOM updates, status badges, power actions, all management UIs +- **`templates/js/keygen.js`** — Client-side SSH Ed25519 key generator using Web Crypto API (loaded on checkout page) - **`templates/css/module.css`** — Cross-theme styles with Bootstrap 3/4/5 dual class support (`panel card`, `panel-body card-body`) +### Removed Features + +- **Firewall** — Removed (non-functional; rulesets must be created in VirtFusion admin panel) +- **IP add buttons** — Removed (`addIPv4`, `addIPv6` endpoints and UI); IPs are managed by VirtFusion during provisioning +- **Upgrade/Downgrade link** — Removed from resources panel + ### Data Flow: Server Creation 1. WHMCS calls `VirtFusionDirect_CreateAccount()` → `ModuleFunctions::createAccount()` diff --git a/README.md b/README.md index 74fafd9..ac50078 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # VirtFusion Direct Provisioning Module for WHMCS -[![GitHub Super-Linter](https://github.com/EZSCALE/virtfusion-whmcs-module/actions/workflows/publish-release.yml/badge.svg)](https://github.com/EZSCALE/virtfusion-whmcs-module/actions) +[![Automated Release](https://github.com/EZSCALE/virtfusion-whmcs-module/actions/workflows/publish-release.yml/badge.svg)](https://github.com/EZSCALE/virtfusion-whmcs-module/actions) ![GitHub](https://img.shields.io/github/license/EZSCALE/virtfusion-whmcs-module) ![GitHub issues](https://img.shields.io/github/issues/EZSCALE/virtfusion-whmcs-module) ![GitHub pull requests](https://img.shields.io/github/issues-pr/EZSCALE/virtfusion-whmcs-module) @@ -62,8 +62,8 @@ You also need a VirtFusion API token with the following permissions: - **Control Panel SSO** - One-click login to VirtFusion panel - **Server Rebuild** - Reinstall with any available OS template - **Password Reset** - Reset VirtFusion panel login credentials -- **Network Management** - View, add, and remove IPv4 addresses and IPv6 subnets -- **Resources Panel** - Current memory, CPU, storage, traffic allocation with usage bars and upgrade/downgrade link +- **Network Management** - View and remove IPv4 addresses; view IPv6 subnets +- **Resources Panel** - Current memory, CPU, storage, traffic allocation with usage bars - **VNC Console** - Browser-based console access (panel auto-hides when VNC is disabled on the server) - **Self-Service Billing** - Credit balance display, usage breakdown, and credit top-up (when enabled) - **Bandwidth Usage** - Traffic usage display with allocation limits @@ -81,6 +81,7 @@ You also need a VirtFusion API token with the following permissions: ### Ordering Process - Dynamic OS template dropdown populated from VirtFusion API - SSH key selection dropdown for users with saved keys, with option to paste a new public key +- **SSH Ed25519 key generator** — Client-side keypair generation using Web Crypto API - Checkout validation ensuring OS selection before order placement - **Resource sliders** - Configurable option dropdowns are replaced with interactive range sliders - Compatible with all WHMCS order form templates @@ -107,26 +108,20 @@ You also need a VirtFusion API token with the following permissions: ## Installation -### Step 1: Download +### Step 1: Download & Install -Download the latest release from the [releases](https://github.com/EZSCALE/virtfusion-whmcs-module/releases) page, or clone the repository: +Download the latest release from the [releases](https://github.com/EZSCALE/virtfusion-whmcs-module/releases) page, or install directly via the command line: ```bash +cd /tmp git clone https://github.com/EZSCALE/virtfusion-whmcs-module.git +rsync -ahP --delete /tmp/virtfusion-whmcs-module/modules/servers/VirtFusionDirect/ /path/to/whmcs/modules/servers/VirtFusionDirect/ +rm -rf /tmp/virtfusion-whmcs-module ``` -### Step 2: Upload Files +Replace `/path/to/whmcs` with your actual WHMCS installation root. -Upload the `modules/` folder to your WHMCS installation root directory: - -``` -your-whmcs-root/ - modules/ - servers/ - VirtFusionDirect/ <-- This folder -``` - -The file structure should be: +The resulting file structure should be: ``` modules/servers/VirtFusionDirect/ @@ -149,11 +144,12 @@ modules/servers/VirtFusionDirect/ error.tpl # Error template css/module.css # Styles js/module.js # Client JavaScript + js/keygen.js # SSH Ed25519 key generator config/ ConfigOptionMapping-example.php # Config mapping example ``` -### Step 3: Set Up Server in WHMCS +### Step 2: Set Up Server in WHMCS 1. Go to **Configuration > System Settings > Servers** 2. Click **Add New Server** @@ -165,7 +161,7 @@ modules/servers/VirtFusionDirect/ 4. Click **Test Connection** to verify 5. Click **Save Changes** -### Step 4: Create Product +### Step 3: Create Product 1. Go to **Configuration > System Settings > Products/Services** 2. Create a new product or edit an existing one @@ -175,21 +171,30 @@ modules/servers/VirtFusionDirect/ - Set **Hypervisor Group ID**, **Package ID**, and **Default IPv4** count 4. Save the product -### Step 5: Set Up Custom Fields +### Step 4: Set Up Custom Fields See [Custom Fields](#custom-fields) section below. -### Step 6: Activate Hooks +### Step 5: Activate Hooks The hooks file (`hooks.php`) is automatically detected by WHMCS when the module is active. If you add the module files to an existing installation, you may need to re-save the product settings or clear the WHMCS template cache for hooks to take effect. ## Upgrading 1. Back up your existing `modules/servers/VirtFusionDirect/` directory -2. Download the new version and overwrite all files -3. If you have a custom `config/ConfigOptionMapping.php`, preserve it -4. If you have theme-overridden templates, review them for any new template variables -5. Clear the WHMCS template cache: **Configuration > System Settings > General Settings > clear template cache** +2. Back up `config/ConfigOptionMapping.php` if you have a custom mapping +3. Download and deploy the new version: + +```bash +cd /tmp +git clone https://github.com/EZSCALE/virtfusion-whmcs-module.git +rsync -ahP --delete /tmp/virtfusion-whmcs-module/modules/servers/VirtFusionDirect/ /path/to/whmcs/modules/servers/VirtFusionDirect/ +rm -rf /tmp/virtfusion-whmcs-module +``` + +4. Restore your custom `config/ConfigOptionMapping.php` if applicable +5. If you have theme-overridden templates, review them for any new template variables +6. Clear the WHMCS template cache: **Configuration > System Settings > General Settings > clear template cache** The module database table (`mod_virtfusion_direct`) is automatically migrated on first load. @@ -300,10 +305,7 @@ Four power control buttons: ### Network Management - View all IPv4 addresses and IPv6 subnets assigned to the server -- Add new IPv4 addresses (subject to pool availability) -- Add new IPv6 subnets (subject to pool availability) - Remove secondary IPv4 addresses (primary cannot be removed) -- Remove IPv6 subnets ### VNC Console - Opens a browser-based VNC console to the server @@ -409,10 +411,7 @@ WHMCS automatically loads theme-specific templates when they exist. Copy the ori | Method | Endpoint | Purpose | |---|---|---| -| `POST` | `/servers/{id}/ipv4` | Add IPv4 address | | `DELETE` | `/servers/{id}/ipv4` | Remove IPv4 address | -| `POST` | `/servers/{id}/ipv6` | Add IPv6 subnet | -| `DELETE` | `/servers/{id}/ipv6` | Remove IPv6 subnet | ### SSH Keys @@ -524,7 +523,7 @@ This data appears in the WHMCS client area and admin product details. 2. **Resource Modification** - Memory and CPU modification requires VirtFusion v6.2.0+. Traffic modification requires v6.0.0+. Backup management requires v4.3.0+. -3. **IPv6 Management** - IPv6 subnet assignment depends on the VirtFusion installation having IPv6 pools configured. If no pools are available, the add operation will fail with an appropriate error message. +3. **IPv6 Display** - IPv6 subnet display depends on the VirtFusion installation having IPv6 pools configured. If no IPv6 is assigned, the network panel shows "No IPv6 subnets". 4. **Order Form Custom Fields** - The custom fields ("Initial Operating System" and "Initial SSH Key") must be named exactly as specified. The module matches by field name with spaces removed and converted to lowercase. @@ -580,6 +579,7 @@ modules/servers/VirtFusionDirect/ error.tpl # Error display template css/module.css # Module styles (responsive, BS3/4/5 compatible) js/module.js # Client JavaScript (all AJAX interactions) + js/keygen.js # SSH Ed25519 key generator (Web Crypto API) config/ ConfigOptionMapping-example.php # Example custom option name mapping ``` diff --git a/SECURITY.md b/SECURITY.md index a63a9ec..3e65a8e 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,12 +2,12 @@ ## Supported Versions -The support version of this module with VirtFusion +Supported VirtFusion versions: -| Version | Supported | -|---------|--------------------| -| > 1.7.3 | :white_check_mark: | -| < 1.7.3 | :x: | +| Version | Supported | +|----------|--------------------| +| >= 1.7.3 | :white_check_mark: | +| < 1.7.3 | :x: | ## Reporting a Vulnerability diff --git a/modules/servers/VirtFusionDirect/hooks.php b/modules/servers/VirtFusionDirect/hooks.php index 2541876..70be304 100644 --- a/modules/servers/VirtFusionDirect/hooks.php +++ b/modules/servers/VirtFusionDirect/hooks.php @@ -139,7 +139,7 @@ add_hook('ClientAreaFooterOutput', 1, function ($vars) { $systemUrl = Database::getSystemUrl(); return " - + + +
diff --git a/modules/servers/VirtFusionDirect/lib/Database.php b/modules/servers/VirtFusionDirect/lib/Database.php index e711f1f..e489ed4 100644 --- a/modules/servers/VirtFusionDirect/lib/Database.php +++ b/modules/servers/VirtFusionDirect/lib/Database.php @@ -54,6 +54,7 @@ class Database public static function getSystemUrl() { $url = DB::table('tblconfiguration')->where('setting', '=', 'SystemURL')->first(); + if (!$url) return ''; return $url->value; } diff --git a/modules/servers/VirtFusionDirect/templates/js/module.js b/modules/servers/VirtFusionDirect/templates/js/module.js index fbcd689..65bf54b 100644 --- a/modules/servers/VirtFusionDirect/templates/js/module.js +++ b/modules/servers/VirtFusionDirect/templates/js/module.js @@ -25,13 +25,15 @@ function vfServerData(serviceId, systemUrl) { $("#vf-data-server-traffic-used").text(response.data.trafficUsed || "-"); $("#vf-data-server-storage").text(response.data.storage); $("#vf-data-server-cpu").text(response.data.cpu); - $("#vf-data-server-ipv4").text(response.data.primaryNetwork.ipv4); - $("#vf-data-server-ipv6").text(response.data.primaryNetwork.ipv6); + var pn = response.data.primaryNetwork || {}; + $("#vf-data-server-ipv4").text(pn.ipv4 || "-"); + $("#vf-data-server-ipv6").text(pn.ipv6 || "-"); // Update status badge var statusBadge = $("#vf-status-badge"); var status = (response.data.status || "unknown").toLowerCase(); statusBadge.text(status.charAt(0).toUpperCase() + status.slice(1)); + statusBadge.removeClass("vf-badge-active vf-badge-suspended vf-badge-awaiting"); if (status === "active" || status === "running") { statusBadge.addClass("vf-badge-active"); } else if (status === "suspended") { @@ -56,7 +58,7 @@ function vfServerData(serviceId, systemUrl) { if (trafficTotal > 0) { $("#vf-res-traffic").text(trafficUsed + " / " + trafficTotal + " GB"); var pct = Math.min(100, Math.round((trafficUsed / trafficTotal) * 100)); - $("#vf-res-traffic-bar").css("width", pct + "%"); + $("#vf-res-traffic-bar").css("width", pct + "%").removeClass("bg-danger bg-warning"); if (pct > 90) { $("#vf-res-traffic-bar").addClass("bg-danger"); } else if (pct > 70) { @@ -140,8 +142,9 @@ function vfServerDataAdmin(serviceId, systemUrl) { $("#vf-data-server-traffic").text(response.data.traffic); $("#vf-data-server-storage").text(response.data.storage); $("#vf-data-server-cpu").text(response.data.cpu); - $("#vf-data-server-ipv4").text(response.data.primaryNetwork.ipv4); - $("#vf-data-server-ipv6").text(response.data.primaryNetwork.ipv6); + var pnAdmin = response.data.primaryNetwork || {}; + $("#vf-data-server-ipv4").text(pnAdmin.ipv4 || "-"); + $("#vf-data-server-ipv6").text(pnAdmin.ipv6 || "-"); $("#vf-server-info").show(); } else { $("#vf-server-info-error").show(); @@ -383,6 +386,14 @@ function vfOpenVnc(serviceId, systemUrl) { // Open window immediately in click context to avoid popup blockers var vncWindow = window.open("", "_blank"); + if (!vncWindow) { + alertDiv.removeClass("alert-success").addClass("alert-danger"); + alertDiv.text("Popup blocked. Please allow popups for this site and try again."); + alertDiv.show(); + spinner.hide(); + btn.prop("disabled", false); + return; + } $.ajax({ type: "GET", diff --git a/modules/servers/VirtFusionDirect/templates/overview.tpl b/modules/servers/VirtFusionDirect/templates/overview.tpl index 2f604dd..11db47b 100644 --- a/modules/servers/VirtFusionDirect/templates/overview.tpl +++ b/modules/servers/VirtFusionDirect/templates/overview.tpl @@ -1,5 +1,5 @@ - - + + {if $serviceStatus eq 'Active'} @@ -274,7 +274,7 @@
Add Credit
-
+