File manager - Edit - /usr/local/cpanel/whostmgr/docroot/cgi/cpguard/index.php
Back
<?php // Copyright (c) OPSSHIELD LLP. All rights reserved. // Author: OPSSHIELD LLP // Description: Landing page (optional redirect) to cPGuard centralized application portal. // File path: /usr/local/cpanel/whostmgr/cgi/cpguard/index.php // 1. User Authentication & Env Setup $user = $_ENV['REMOTE_USER'] ?? ''; $is_root = ($user === "root"); // 2. API Endpoint Handler (AJAX Request) if ($is_root && isset($_GET['link'])) { // Prepare Payload $payload = [ 'method' => 'portalLogin', 'user' => $user, 'data' => [] ]; $binaryPath = '/opt/cpguard/app/cpg-bridge'; // Validation if (!is_executable($binaryPath)) { die("error: Cannot execute cPGuard bridge binary."); } $descriptors = [ 0 => ['pipe', 'r'], // STDIN 1 => ['pipe', 'w'], // STDOUT 2 => ['pipe', 'w'] // STDERR ]; $process = proc_open($binaryPath, $descriptors, $pipes); if (is_resource($process)) { fwrite($pipes[0], json_encode($payload)); fclose($pipes[0]); $responseRaw = stream_get_contents($pipes[1]); $errorsRaw = stream_get_contents($pipes[2]); fclose($pipes[1]); fclose($pipes[2]); $exitCode = proc_close($process); if ($exitCode === 0) { $json = json_decode($responseRaw); // Valid URL check if ($json && isset($json->response) && filter_var($json->response, FILTER_VALIDATE_URL)) { echo trim($json->response); exit(0); } else { echo "Invalid response from bridge."; } } else { echo "Process failed (Code $exitCode): " . strip_tags($errorsRaw); } } else { echo "Failed to open process."; } die(); } $ajax_url = '?link'; // 3. Render Interface require_once('/usr/local/cpanel/php/WHM.php'); WHM::header('cPGuard Security', 0, 0); ?> <div class="cpg-wrapper"> <style> /* --- SCOPED CSS --- */ .cpg-wrapper { --cpg-text: #0f172a; --cpg-muted: #64748b; --cpg-brand: #3182ce; --cpg-accent: #2563eb; --cpg-bg: #fafafa; --cpg-line: #e2e8f0; --cpg-success: #10b981; --cpg-error: #e11d48; font-family: -apple-system, BlinkMacSystemFont, "Inter", "Segoe UI", Roboto, sans-serif; background: var(--cpg-bg); color: var(--cpg-text); line-height: 1.6; padding: 3rem 2rem; min-height: 60vh; display: flex; align-items: flex-start; /* Aligns content to top-left */ } .cpg-wrapper * { box-sizing: border-box; margin: 0; padding: 0; } .cpg-container { max-width: 650px; animation: cpgFadeIn 0.6s ease-out; } /* Typography */ .cpg-logo { margin-bottom: 2.5rem; } .cpg-logo img { height: 56px; width: auto; display: block; border: none; } .cpg-heading { font-size: clamp(2rem, 5vw, 2.8rem); font-weight: 800; letter-spacing: -0.03em; line-height: 1.1; margin-bottom: 1rem; color: var(--cpg-text); } .cpg-text-gradient { background: linear-gradient(135deg, var(--cpg-text) 0%, var(--cpg-muted) 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; } .cpg-text-error { color: var(--cpg-error); } .cpg-desc { font-size: 1.15rem; color: var(--cpg-muted); margin-bottom: 2rem; max-width: 55ch; font-weight: 400; } .cpg-line { width: 80px; height: 4px; background: linear-gradient(90deg, var(--cpg-brand), var(--cpg-accent)); border-radius: 2px; margin-bottom: 2rem; } /* Access Denied Specifics */ .cpg-meta { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.9rem; color: var(--cpg-muted); background: #e2e8f0; padding: 4px 10px; border-radius: 4px; display: inline-block; margin-top: 1rem; } /* Dashboard Specifics */ .cpg-info-box { display: flex; align-items: center; gap: 0.75rem; font-size: 1rem; color: var(--cpg-muted); margin-bottom: 2.5rem; padding-bottom: 2.5rem; border-bottom: 1px solid var(--cpg-line); } .cpg-info-box svg { width: 20px; height: 20px; color: var(--cpg-brand); flex-shrink: 0; } .cpg-info-box code { font-family: monospace; background: #fff; padding: 2px 6px; border-radius: 4px; color: var(--cpg-brand); border: 1px solid var(--cpg-line); font-weight: 600; } /* Buttons & Actions */ .cpg-btn-row { display: flex; align-items: center; gap: 1.5rem; flex-wrap: wrap; } .cpg-btn { display: inline-flex; align-items: center; gap: 0.75rem; padding: 1rem 1.8rem; font-size: 1.05rem; font-weight: 700; color: #fff; background: linear-gradient(135deg, var(--cpg-brand) 0%, var(--cpg-accent) 100%); border: none; border-radius: 10px; cursor: pointer; transition: all 0.2s ease; box-shadow: 0 4px 12px rgba(49, 130, 206, 0.25); } .cpg-btn:hover:not(.cpg-disabled) { transform: translateY(-2px); box-shadow: 0 6px 16px rgba(49, 130, 206, 0.35); } .cpg-btn:active:not(.cpg-disabled) { transform: translateY(0); } .cpg-btn.cpg-disabled { opacity: 0.6; pointer-events: none; } .cpg-btn.cpg-btn-success { background: linear-gradient(135deg, var(--cpg-success) 0%, #34d399 100%); } .cpg-btn.cpg-btn-error { background: var(--cpg-error); box-shadow: 0 4px 12px rgba(225, 29, 72, 0.25); } .cpg-btn svg { width: 20px; height: 20px; transition: transform 0.3s; } .cpg-btn:hover:not(.cpg-disabled) svg { transform: translateX(3px); } .cpg-error-msg { color: var(--cpg-error); font-weight: 600; font-size: 0.95rem; display: none; animation: cpgFadeIn 0.3s ease; } .cpg-helper { margin-top: 1rem; font-size: 0.9rem; color: var(--cpg-muted); } @keyframes cpgFadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } @media (max-width: 640px) { .cpg-wrapper { padding: 1.5rem; } .cpg-btn-row { flex-direction: column; align-items: flex-start; gap: 1rem; } .cpg-btn { width: 100%; justify-content: center; } } </style> <div class="cpg-container"> <div class="cpg-logo"> <img src="https://opsshield.com/images/cpguard-logo.svg" alt="cPGuard" /> </div> <?php if (!$is_root): ?> <h1 class="cpg-heading cpg-text-error">Access Denied</h1> <p class="cpg-desc"> This cPGuard interface is restricted to the root administrator only. You do not have permission to view this page. </p> <span class="cpg-meta">User: <?= htmlspecialchars($user); ?></span> <?php else: ?> <h1 class="cpg-heading cpg-text-gradient">Access Your Dashboard</h1> <div class="cpg-line"></div> <p class="cpg-desc"> The cPGuard UI is hosted on our dedicated App Portal. Click below to securely access your server dashboard. </p> <div class="cpg-info-box"> <svg fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9"> </path> </svg> <span>Portal hosted at <code>app.opsshield.com</code></span> </div> <div class="cpg-action-area"> <div class="cpg-btn-row"> <button class="cpg-btn" id="cpgRedirectBtn" type="button"> <span id="cpgBtnText">Continue to App Portal</span> <svg id="cpgBtnIcon" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 7l5 5m0 0l-5 5m5-5H6"></path> </svg> </button> <div class="cpg-error-msg" id="cpgErrorState"></div> </div> <p class="cpg-helper" id="cpgHelperText">Opens in a new tab • You can close this page after</p> </div> <script> (function () { const redirectBtn = document.getElementById('cpgRedirectBtn'); const btnText = document.getElementById('cpgBtnText'); const errorDiv = document.getElementById('cpgErrorState'); const helperText = document.getElementById('cpgHelperText'); if (!redirectBtn) return; redirectBtn.addEventListener('click', function (e) { e.preventDefault(); errorDiv.style.display = 'none'; redirectBtn.classList.remove('cpg-btn-error', 'cpg-btn-success'); redirectBtn.classList.add('cpg-disabled'); btnText.textContent = 'Generating Secure Link...'; // ✅ ALWAYS open new tab immediately (popup-safe) const newWindow = window.open('', '_blank'); if (!newWindow) { handleError("Popup blocked. Please allow popups."); return; } newWindow.document.write(` <html> <body style="font-family:sans-serif;text-align:center;padding-top:50px"> Please wait, redirecting to cPGuard… </body> </html> `); // AJAX request fetch('<?php echo $ajax_url; ?>', { credentials: 'same-origin' }) .then(r => r.text()) .then(text => { const url = text.trim(); if (!isValidUrl(url)) { newWindow.close(); handleError(url || 'Invalid response'); return; } // ✅ redirect ONLY the new tab newWindow.location.href = url; redirectBtn.innerHTML = ` <span>Portal Opened</span> <svg fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M5 13l4 4L19 7"></path> </svg>`; redirectBtn.classList.remove('cpg-disabled'); redirectBtn.classList.add('cpg-btn-success'); redirectBtn.style.pointerEvents = 'none'; }) .catch(err => { newWindow.close(); handleError('Network error'); console.error(err); }); }); function isValidUrl(string) { try { return Boolean(new URL(string)); } catch (_) { return false; } } function handleError(msg) { redirectBtn.classList.remove('cpg-disabled'); redirectBtn.classList.add('cpg-btn-error'); btnText.textContent = 'Retry Connection'; errorDiv.textContent = msg; errorDiv.style.display = 'block'; } })(); </script> <?php endif; ?> </div> </div> <?php WHM::footer(); ?>
| ver. 1.4 |
Github
|
.
| PHP 8.1.34 | Generation time: 0.23 |
proxy
|
phpinfo
|
Settings