fix: XSS escaping, null guards, JS bug fixes, and documentation updates
- Escape $serverObject and $systemUrl in AdminHTML.php heredocs to prevent XSS - Add null guard in Database::getSystemUrl() to prevent fatal error - Guard primaryNetwork access in module.js to prevent null dereference - Reset badge/traffic-bar CSS classes on refresh to prevent accumulation - Add VNC popup-blocked check with user-facing message - Add BS3 input-group-btn dual class for theme compatibility - Escape billing template variables with |escape:'htmlall' - Add cache-busting to admin CSS/JS includes - Switch cache-busting format from version to date-based (20260207) - Create .releaserc.json for automated CHANGELOG.md management - Add changelog/git plugins to semantic-release workflow - Remove manual [Unreleased] section from CHANGELOG.md - Update README: install/upgrade with rsync, accuracy fixes, add keygen.js - Update CLAUDE.md: add keygen.js, document removed features - Fix SECURITY.md grammar and version operator Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
3
.github/workflows/publish-release.yml
vendored
3
.github/workflows/publish-release.yml
vendored
@@ -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 }}
|
||||
|
||||
13
.releaserc.json
Normal file
13
.releaserc.json
Normal file
@@ -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}"
|
||||
}]
|
||||
]
|
||||
}
|
||||
62
CHANGELOG.md
62
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
|
||||
|
||||
@@ -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()`
|
||||
|
||||
62
README.md
62
README.md
@@ -1,6 +1,6 @@
|
||||
# VirtFusion Direct Provisioning Module for WHMCS
|
||||
|
||||
[](https://github.com/EZSCALE/virtfusion-whmcs-module/actions)
|
||||
[](https://github.com/EZSCALE/virtfusion-whmcs-module/actions)
|
||||

|
||||

|
||||

|
||||
@@ -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
|
||||
```
|
||||
|
||||
10
SECURITY.md
10
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
|
||||
|
||||
|
||||
@@ -139,7 +139,7 @@ add_hook('ClientAreaFooterOutput', 1, function ($vars) {
|
||||
$systemUrl = Database::getSystemUrl();
|
||||
|
||||
return "
|
||||
<script src=\"" . htmlspecialchars($systemUrl, ENT_QUOTES, 'UTF-8') . "modules/servers/VirtFusionDirect/templates/js/keygen.js?v=0.0.20\"></script>
|
||||
<script src=\"" . htmlspecialchars($systemUrl, ENT_QUOTES, 'UTF-8') . "modules/servers/VirtFusionDirect/templates/js/keygen.js?v=20260207\"></script>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
var osTemplates = " . json_encode($dropdownOptions, JSON_THROW_ON_ERROR | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT) . ";
|
||||
|
||||
@@ -7,6 +7,7 @@ class AdminHTML
|
||||
|
||||
public static function options($systemUrl, $serviceId)
|
||||
{
|
||||
$systemUrl = htmlspecialchars($systemUrl, ENT_QUOTES, 'UTF-8');
|
||||
return <<<EOT
|
||||
<button onclick="impersonateServerOwner('${serviceId}', '${systemUrl}')" type="button" class="btn btn-primary">Impersonate Server Owner</button>
|
||||
<span class="text-info"> A valid VirtFusion admin session in the same browser is required for this functionality to work.</span>
|
||||
@@ -15,6 +16,7 @@ EOT;
|
||||
|
||||
public static function serverObject($serverObject)
|
||||
{
|
||||
$serverObject = htmlspecialchars($serverObject, ENT_QUOTES, 'UTF-8');
|
||||
return <<<EOT
|
||||
<textarea class="form-control" name="modulefields[1]" rows="10" style="width: 100%" disabled>${serverObject}</textarea>
|
||||
EOT;
|
||||
@@ -31,9 +33,10 @@ EOT;
|
||||
|
||||
public static function serverInfo($systemUrl, $serviceId)
|
||||
{
|
||||
$systemUrl = htmlspecialchars($systemUrl, ENT_QUOTES, 'UTF-8');
|
||||
return <<<EOT
|
||||
<link href="${systemUrl}modules/servers/VirtFusionDirect/templates/css/module.css" rel="stylesheet">
|
||||
<script src="${systemUrl}modules/servers/VirtFusionDirect/templates/js/module.js"></script>
|
||||
<link href="${systemUrl}modules/servers/VirtFusionDirect/templates/css/module.css?v=20260207" rel="stylesheet">
|
||||
<script src="${systemUrl}modules/servers/VirtFusionDirect/templates/js/module.js?v=20260207"></script>
|
||||
<div id="vf-loader" class="vf-loader">
|
||||
<div id="vf-loading"></div>
|
||||
</div>
|
||||
|
||||
@@ -54,6 +54,7 @@ class Database
|
||||
public static function getSystemUrl()
|
||||
{
|
||||
$url = DB::table('tblconfiguration')->where('setting', '=', 'SystemURL')->first();
|
||||
if (!$url) return '';
|
||||
return $url->value;
|
||||
}
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<link href="{$systemURL}modules/servers/VirtFusionDirect/templates/css/module.css?v=0.0.20" rel="stylesheet">
|
||||
<script src="{$systemURL}modules/servers/VirtFusionDirect/templates/js/module.js?v=0.0.20"></script>
|
||||
<link href="{$systemURL}modules/servers/VirtFusionDirect/templates/css/module.css?v=20260207" rel="stylesheet">
|
||||
<script src="{$systemURL}modules/servers/VirtFusionDirect/templates/js/module.js?v=20260207"></script>
|
||||
|
||||
{if $serviceStatus eq 'Active'}
|
||||
|
||||
@@ -274,7 +274,7 @@
|
||||
<h5 class="vf-bold">Add Credit</h5>
|
||||
<div class="input-group mb-2">
|
||||
<input type="number" id="vf-ss-credit-amount" class="form-control" placeholder="Amount" min="1" step="1">
|
||||
<div class="input-group-append">
|
||||
<div class="input-group-append input-group-btn">
|
||||
<button id="vf-ss-add-credit-btn" onclick="vfAddCredit('{$serviceid}','{$systemURL}')" type="button" class="btn btn-primary">
|
||||
<span id="vf-ss-add-credit-spinner" class="spinner-border spinner-border-sm" style="display:none;"></span>
|
||||
Add Credit
|
||||
@@ -328,29 +328,29 @@
|
||||
<div class="col-lg-6">
|
||||
<div class="row p-2">
|
||||
<div class="col-xs-6 col-6 text-right vf-bold">Product:</div>
|
||||
<div class="col-xs-6 col-6">{$groupname} - {$product}</div>
|
||||
<div class="col-xs-6 col-6">{$groupname|escape:'htmlall'} - {$product|escape:'htmlall'}</div>
|
||||
</div>
|
||||
<div class="row p-2">
|
||||
<div class="col-xs-6 col-6 text-right vf-bold">{$LANG.recurringamount}:</div>
|
||||
<div class="col-xs-6 col-6">{$recurringamount}</div>
|
||||
<div class="col-xs-6 col-6">{$recurringamount|escape:'htmlall'}</div>
|
||||
</div>
|
||||
<div class="row p-2">
|
||||
<div class="col-xs-6 col-6 text-right vf-bold">{$LANG.orderbillingcycle}:</div>
|
||||
<div class="col-xs-6 col-6">{$billingcycle}</div>
|
||||
<div class="col-xs-6 col-6">{$billingcycle|escape:'htmlall'}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div class="row p-2">
|
||||
<div class="col-xs-6 col-6 text-right vf-bold">{$LANG.clientareahostingregdate}:</div>
|
||||
<div class="col-xs-6 col-6">{$regdate}</div>
|
||||
<div class="col-xs-6 col-6">{$regdate|escape:'htmlall'}</div>
|
||||
</div>
|
||||
<div class="row p-2">
|
||||
<div class="col-xs-6 col-6 text-right vf-bold">{$LANG.clientareahostingnextduedate}:</div>
|
||||
<div class="col-xs-6 col-6">{$nextduedate}</div>
|
||||
<div class="col-xs-6 col-6">{$nextduedate|escape:'htmlall'}</div>
|
||||
</div>
|
||||
<div class="row p-2">
|
||||
<div class="col-xs-6 col-6 text-right vf-bold">{$LANG.orderpaymentmethod}:</div>
|
||||
<div class="col-xs-6 col-6">{$paymentmethod}</div>
|
||||
<div class="col-xs-6 col-6">{$paymentmethod|escape:'htmlall'}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user