fix install script5
This commit is contained in:
parent
181884b931
commit
cb8a83eb34
|
|
@ -0,0 +1,311 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Main dashboard for ZitiNexus Router Enrollment UI
|
||||||
|
* This is a copy for direct access when document root is set to main UI directory
|
||||||
|
*/
|
||||||
|
|
||||||
|
require_once 'includes/auth.php';
|
||||||
|
require_once 'includes/enrollment.php';
|
||||||
|
|
||||||
|
// Require authentication
|
||||||
|
AuthManager::requireAuth();
|
||||||
|
|
||||||
|
// Get current user
|
||||||
|
$currentUser = AuthManager::getCurrentUser();
|
||||||
|
|
||||||
|
// Initialize enrollment manager
|
||||||
|
$enrollmentManager = new EnrollmentManager();
|
||||||
|
|
||||||
|
// Handle AJAX requests
|
||||||
|
if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest') {
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
if (isset($_GET['action']) && $_GET['action'] === 'get_status') {
|
||||||
|
// Get system status
|
||||||
|
$status = $enrollmentManager->getSystemStatus();
|
||||||
|
echo json_encode($status);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'enroll') {
|
||||||
|
// Handle enrollment request
|
||||||
|
AuthManager::requireCSRF();
|
||||||
|
|
||||||
|
$hashKey = sanitizeInput($_POST['hashKey'] ?? '');
|
||||||
|
$apiEndpoint = sanitizeInput($_POST['apiEndpoint'] ?? DEFAULT_API_ENDPOINT);
|
||||||
|
|
||||||
|
// Validate inputs
|
||||||
|
if (!ApiClient::validateHashKey($hashKey)) {
|
||||||
|
echo json_encode(['success' => false, 'error' => 'Invalid hash key format']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ApiClient::validateApiEndpoint($apiEndpoint)) {
|
||||||
|
echo json_encode(['success' => false, 'error' => 'Invalid API endpoint format']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start enrollment
|
||||||
|
$result = $enrollmentManager->enrollRouter($hashKey, $apiEndpoint);
|
||||||
|
echo json_encode($result);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get system status for initial page load
|
||||||
|
$systemStatus = $enrollmentManager->getSystemStatus();
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title><?php echo APP_NAME; ?> - Dashboard</title>
|
||||||
|
<link rel="stylesheet" href="assets/css/style.css">
|
||||||
|
<link rel="icon" type="image/x-icon" href="assets/images/favicon.ico">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="dashboard-container">
|
||||||
|
<!-- Header -->
|
||||||
|
<header class="header">
|
||||||
|
<div class="header-content">
|
||||||
|
<h1 class="header-title"><?php echo APP_NAME; ?></h1>
|
||||||
|
<div class="header-actions">
|
||||||
|
<div class="user-info">
|
||||||
|
Welcome, <strong><?php echo htmlspecialchars($currentUser['username']); ?></strong>
|
||||||
|
<span class="text-xs">
|
||||||
|
| Logged in: <?php echo date('M j, Y g:i A', $currentUser['login_time']); ?>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<button id="refreshStatus" class="btn btn-secondary" title="Refresh System Status">
|
||||||
|
🔄 Refresh
|
||||||
|
</button>
|
||||||
|
<a href="index.php?action=logout" class="btn btn-secondary">
|
||||||
|
Logout
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<!-- Main Content -->
|
||||||
|
<main class="main-content">
|
||||||
|
<!-- System Status Card -->
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<h2 class="card-title">System Status</h2>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="status-grid">
|
||||||
|
<div class="status-item">
|
||||||
|
<div id="zitiStatusIcon" class="status-icon <?php echo $systemStatus['ziti_status'] === 'installed' ? 'success' : 'error'; ?>">
|
||||||
|
<?php echo $systemStatus['ziti_status'] === 'installed' ? '✓' : '✗'; ?>
|
||||||
|
</div>
|
||||||
|
<div class="status-content">
|
||||||
|
<h4>Ziti CLI Status</h4>
|
||||||
|
<p id="zitiStatus">
|
||||||
|
<?php
|
||||||
|
if ($systemStatus['ziti_status'] === 'installed') {
|
||||||
|
echo 'Installed (' . htmlspecialchars($systemStatus['ziti_version']) . ')';
|
||||||
|
} else {
|
||||||
|
echo 'Not Installed';
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="status-item">
|
||||||
|
<div id="serviceStatusIcon" class="status-icon <?php echo $systemStatus['service_active'] ? 'success' : 'error'; ?>">
|
||||||
|
<?php echo $systemStatus['service_active'] ? '▶' : '⏹'; ?>
|
||||||
|
</div>
|
||||||
|
<div class="status-content">
|
||||||
|
<h4>Router Service</h4>
|
||||||
|
<p id="serviceStatus">
|
||||||
|
<?php echo $systemStatus['service_active'] ? 'Running' : 'Stopped'; ?>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="status-item">
|
||||||
|
<div id="configStatusIcon" class="status-icon <?php
|
||||||
|
if ($systemStatus['config_exists'] && $systemStatus['certificates_exist']) {
|
||||||
|
echo 'success';
|
||||||
|
} elseif ($systemStatus['config_exists']) {
|
||||||
|
echo 'warning';
|
||||||
|
} else {
|
||||||
|
echo 'error';
|
||||||
|
}
|
||||||
|
?>">
|
||||||
|
<?php
|
||||||
|
if ($systemStatus['config_exists'] && $systemStatus['certificates_exist']) {
|
||||||
|
echo '⚙';
|
||||||
|
} elseif ($systemStatus['config_exists']) {
|
||||||
|
echo '⚠';
|
||||||
|
} else {
|
||||||
|
echo '✗';
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
<div class="status-content">
|
||||||
|
<h4>Configuration</h4>
|
||||||
|
<p id="configStatus">
|
||||||
|
<?php
|
||||||
|
if ($systemStatus['config_exists'] && $systemStatus['certificates_exist']) {
|
||||||
|
echo 'Configured';
|
||||||
|
} elseif ($systemStatus['config_exists']) {
|
||||||
|
echo 'Partial';
|
||||||
|
} else {
|
||||||
|
echo 'Not Configured';
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="status-item">
|
||||||
|
<div class="status-icon success">
|
||||||
|
🖥
|
||||||
|
</div>
|
||||||
|
<div class="status-content">
|
||||||
|
<h4>Hostname</h4>
|
||||||
|
<p id="hostname"><?php echo htmlspecialchars($systemStatus['hostname']); ?></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Enrollment Form Card -->
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<h2 class="card-title">Router Enrollment</h2>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<form id="enrollmentForm" class="enrollment-form">
|
||||||
|
<input type="hidden" name="csrf_token" value="<?php echo generateCSRFToken(); ?>">
|
||||||
|
|
||||||
|
<div class="form-row">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="apiEndpoint" class="form-label">API Endpoint</label>
|
||||||
|
<input
|
||||||
|
type="url"
|
||||||
|
id="apiEndpoint"
|
||||||
|
name="apiEndpoint"
|
||||||
|
class="form-input"
|
||||||
|
value="<?php echo DEFAULT_API_ENDPOINT; ?>"
|
||||||
|
placeholder="https://backend.zitinexus.com"
|
||||||
|
required
|
||||||
|
>
|
||||||
|
<small class="text-sm text-secondary">ZitiNexus Portal API endpoint</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="hashKey" class="form-label">Hash Key</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="hashKey"
|
||||||
|
name="hashKey"
|
||||||
|
class="form-input"
|
||||||
|
placeholder="32-character hexadecimal hash key"
|
||||||
|
maxlength="32"
|
||||||
|
pattern="[a-fA-F0-9]{32}"
|
||||||
|
required
|
||||||
|
>
|
||||||
|
<small class="text-sm text-secondary">Router enrollment hash key from ZitiNexus Portal</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group-full">
|
||||||
|
<button type="submit" id="enrollBtn" class="btn btn-primary">
|
||||||
|
Start Enrollment
|
||||||
|
</button>
|
||||||
|
<button type="button" id="clearLogs" class="btn btn-secondary" style="margin-left: 1rem;">
|
||||||
|
Clear Logs
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<!-- Progress Container -->
|
||||||
|
<div id="progressContainer" class="progress-container">
|
||||||
|
<div class="progress-bar">
|
||||||
|
<div id="progressFill" class="progress-fill"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="progress-steps">
|
||||||
|
<div class="progress-step">Initialize</div>
|
||||||
|
<div class="progress-step">Requirements</div>
|
||||||
|
<div class="progress-step">Install</div>
|
||||||
|
<div class="progress-step">Directories</div>
|
||||||
|
<div class="progress-step">Register</div>
|
||||||
|
<div class="progress-step">Configure</div>
|
||||||
|
<div class="progress-step">Enroll</div>
|
||||||
|
<div class="progress-step">Service</div>
|
||||||
|
<div class="progress-step">Start</div>
|
||||||
|
<div class="progress-step">Report</div>
|
||||||
|
<div class="progress-step">Complete</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="logContainer" class="log-container">
|
||||||
|
<!-- Log entries will be added here dynamically -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Information Card -->
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<h2 class="card-title">Information</h2>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 2rem;">
|
||||||
|
<div>
|
||||||
|
<h4 class="font-medium mb-2">How to Use</h4>
|
||||||
|
<ol class="text-sm text-secondary" style="padding-left: 1.5rem;">
|
||||||
|
<li>Obtain a hash key from the ZitiNexus Portal by creating a router enrollment</li>
|
||||||
|
<li>Enter the API endpoint (default is pre-filled)</li>
|
||||||
|
<li>Paste the 32-character hash key</li>
|
||||||
|
<li>Click "Start Enrollment" to begin the process</li>
|
||||||
|
<li>Monitor the progress and logs for status updates</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h4 class="font-medium mb-2">System Requirements</h4>
|
||||||
|
<ul class="text-sm text-secondary" style="padding-left: 1.5rem;">
|
||||||
|
<li>Ubuntu 22.04 or 24.04 LTS</li>
|
||||||
|
<li>Root/sudo access required</li>
|
||||||
|
<li>Internet connectivity</li>
|
||||||
|
<li>systemctl available</li>
|
||||||
|
<li>curl and jq packages (auto-installed)</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h4 class="font-medium mb-2">File Locations</h4>
|
||||||
|
<ul class="text-sm text-secondary" style="padding-left: 1.5rem;">
|
||||||
|
<li><code>/etc/zitirouter/</code> - Configuration directory</li>
|
||||||
|
<li><code>/etc/zitirouter/certs/</code> - Certificates</li>
|
||||||
|
<li><code>/var/log/ziti-router-enrollment.log</code> - Enrollment log</li>
|
||||||
|
<li><code>/etc/systemd/system/ziti-router.service</code> - Service file</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h4 class="font-medium mb-2">Service Management</h4>
|
||||||
|
<ul class="text-sm text-secondary" style="padding-left: 1.5rem;">
|
||||||
|
<li><code>systemctl status ziti-router</code> - Check status</li>
|
||||||
|
<li><code>systemctl start ziti-router</code> - Start service</li>
|
||||||
|
<li><code>systemctl stop ziti-router</code> - Stop service</li>
|
||||||
|
<li><code>journalctl -u ziti-router -f</code> - View logs</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="assets/js/app.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Debug script to check asset paths
|
||||||
|
*/
|
||||||
|
|
||||||
|
require_once 'includes/config.php';
|
||||||
|
|
||||||
|
echo "<h1>Asset Path Debug</h1>";
|
||||||
|
echo "<p><strong>Current Script:</strong> " . $_SERVER['SCRIPT_FILENAME'] . "</p>";
|
||||||
|
echo "<p><strong>Document Root:</strong> " . $_SERVER['DOCUMENT_ROOT'] . "</p>";
|
||||||
|
echo "<p><strong>Script Name:</strong> " . $_SERVER['SCRIPT_NAME'] . "</p>";
|
||||||
|
echo "<p><strong>Request URI:</strong> " . $_SERVER['REQUEST_URI'] . "</p>";
|
||||||
|
|
||||||
|
echo "<h2>Asset Paths:</h2>";
|
||||||
|
echo "<p><strong>CSS Path:</strong> " . getAssetPath('css/style.css') . "</p>";
|
||||||
|
echo "<p><strong>JS Path:</strong> " . getAssetPath('js/app.js') . "</p>";
|
||||||
|
|
||||||
|
echo "<h2>File Existence Check:</h2>";
|
||||||
|
$cssPath = getAssetPath('css/style.css');
|
||||||
|
$jsPath = getAssetPath('js/app.js');
|
||||||
|
|
||||||
|
echo "<p><strong>CSS File Exists:</strong> " . (file_exists($cssPath) ? 'YES' : 'NO') . " ($cssPath)</p>";
|
||||||
|
echo "<p><strong>JS File Exists:</strong> " . (file_exists($jsPath) ? 'YES' : 'NO') . " ($jsPath)</p>";
|
||||||
|
|
||||||
|
echo "<h2>Directory Structure:</h2>";
|
||||||
|
echo "<pre>";
|
||||||
|
echo "Current directory: " . getcwd() . "\n";
|
||||||
|
echo "Assets directory exists: " . (is_dir('assets') ? 'YES' : 'NO') . "\n";
|
||||||
|
echo "Public directory exists: " . (is_dir('public') ? 'YES' : 'NO') . "\n";
|
||||||
|
|
||||||
|
if (is_dir('assets')) {
|
||||||
|
echo "\nAssets directory contents:\n";
|
||||||
|
$files = scandir('assets');
|
||||||
|
foreach ($files as $file) {
|
||||||
|
if ($file !== '.' && $file !== '..') {
|
||||||
|
echo " - $file\n";
|
||||||
|
if (is_dir("assets/$file")) {
|
||||||
|
$subfiles = scandir("assets/$file");
|
||||||
|
foreach ($subfiles as $subfile) {
|
||||||
|
if ($subfile !== '.' && $subfile !== '..') {
|
||||||
|
echo " - $subfile\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
echo "</pre>";
|
||||||
|
|
||||||
|
echo "<h2>Test Direct Paths:</h2>";
|
||||||
|
echo "<p><strong>Direct CSS:</strong> assets/css/style.css - " . (file_exists('assets/css/style.css') ? 'EXISTS' : 'NOT FOUND') . "</p>";
|
||||||
|
echo "<p><strong>Direct JS:</strong> assets/js/app.js - " . (file_exists('assets/js/app.js') ? 'EXISTS' : 'NOT FOUND') . "</p>";
|
||||||
|
?>
|
||||||
|
|
@ -149,16 +149,24 @@ function executeCommand($command, &$output = null, &$returnCode = null) {
|
||||||
* Get the correct asset path based on current directory structure
|
* Get the correct asset path based on current directory structure
|
||||||
*/
|
*/
|
||||||
function getAssetPath($asset) {
|
function getAssetPath($asset) {
|
||||||
// Determine if we're in the public directory or main directory
|
// Clean the asset path
|
||||||
$currentDir = dirname($_SERVER['SCRIPT_FILENAME']);
|
$asset = ltrim($asset, '/');
|
||||||
$publicDir = realpath(__DIR__ . '/../public');
|
|
||||||
|
|
||||||
if ($currentDir === $publicDir) {
|
// Get the current script's directory and the request URI
|
||||||
// We're in the public directory, use relative paths
|
$scriptDir = dirname($_SERVER['SCRIPT_FILENAME']);
|
||||||
return '../assets/' . ltrim($asset, '/');
|
$requestUri = $_SERVER['REQUEST_URI'];
|
||||||
|
$scriptName = $_SERVER['SCRIPT_NAME'];
|
||||||
|
|
||||||
|
// Check if we're accessing files from the public directory
|
||||||
|
// but the document root is set to the main UI directory
|
||||||
|
if (strpos($scriptName, '/public/') !== false ||
|
||||||
|
strpos($requestUri, '/public/') !== false ||
|
||||||
|
basename($scriptDir) === 'public') {
|
||||||
|
// We're in the public directory context, use relative paths
|
||||||
|
return '../assets/' . $asset;
|
||||||
} else {
|
} else {
|
||||||
// We're in the main directory, use direct paths
|
// We're in the main directory context, use direct paths
|
||||||
return 'assets/' . ltrim($asset, '/');
|
return 'assets/' . $asset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,136 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Login page for ZitiNexus Router Enrollment UI
|
||||||
|
* This is a copy for direct access when document root is set to main UI directory
|
||||||
|
*/
|
||||||
|
|
||||||
|
require_once 'includes/auth.php';
|
||||||
|
|
||||||
|
// Redirect if already authenticated
|
||||||
|
if (isAuthenticated() && isSessionValid()) {
|
||||||
|
header('Location: dashboard.php');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle messages
|
||||||
|
$message = '';
|
||||||
|
$messageType = '';
|
||||||
|
|
||||||
|
if (isset($_GET['error'])) {
|
||||||
|
switch ($_GET['error']) {
|
||||||
|
case 'session_expired':
|
||||||
|
$message = 'Your session has expired. Please log in again.';
|
||||||
|
$messageType = 'warning';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$message = 'An error occurred. Please try again.';
|
||||||
|
$messageType = 'error';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($_GET['message'])) {
|
||||||
|
switch ($_GET['message']) {
|
||||||
|
case 'logged_out':
|
||||||
|
$message = 'You have been logged out successfully.';
|
||||||
|
$messageType = 'info';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($loginError)) {
|
||||||
|
$message = $loginError;
|
||||||
|
$messageType = 'error';
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title><?php echo APP_NAME; ?> - Login</title>
|
||||||
|
<link rel="stylesheet" href="assets/css/style.css">
|
||||||
|
<link rel="icon" type="image/x-icon" href="assets/images/favicon.ico">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="login-container">
|
||||||
|
<div class="login-card">
|
||||||
|
<div class="login-header">
|
||||||
|
<h1><?php echo APP_NAME; ?></h1>
|
||||||
|
<p>Router Enrollment Management Interface</p>
|
||||||
|
<p class="text-sm text-secondary">Version <?php echo APP_VERSION; ?></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php if ($message): ?>
|
||||||
|
<div class="alert alert-<?php echo $messageType; ?>">
|
||||||
|
<?php echo htmlspecialchars($message); ?>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<form method="POST" action="index.php">
|
||||||
|
<input type="hidden" name="action" value="login">
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="username" class="form-label">Username</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="username"
|
||||||
|
name="username"
|
||||||
|
class="form-input"
|
||||||
|
required
|
||||||
|
autocomplete="username"
|
||||||
|
value="<?php echo isset($_POST['username']) ? htmlspecialchars($_POST['username']) : ''; ?>"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="password" class="form-label">Password</label>
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
id="password"
|
||||||
|
name="password"
|
||||||
|
class="form-input"
|
||||||
|
required
|
||||||
|
autocomplete="current-password"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit" class="btn btn-primary btn-full">
|
||||||
|
Sign In
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div style="margin-top: 2rem; padding-top: 1rem; border-top: 1px solid var(--border-color); text-align: center;">
|
||||||
|
<p class="text-sm text-secondary">
|
||||||
|
Default credentials: <strong>admin</strong> / <strong>admin123</strong>
|
||||||
|
</p>
|
||||||
|
<p class="text-xs text-secondary" style="margin-top: 0.5rem;">
|
||||||
|
Please change the default password in production
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Auto-focus on username field
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
const usernameField = document.getElementById('username');
|
||||||
|
if (usernameField && !usernameField.value) {
|
||||||
|
usernameField.focus();
|
||||||
|
} else {
|
||||||
|
const passwordField = document.getElementById('password');
|
||||||
|
if (passwordField) {
|
||||||
|
passwordField.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle form submission
|
||||||
|
document.querySelector('form').addEventListener('submit', function(e) {
|
||||||
|
const submitBtn = this.querySelector('button[type="submit"]');
|
||||||
|
submitBtn.disabled = true;
|
||||||
|
submitBtn.innerHTML = '<span class="spinner"></span>Signing In...';
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -184,6 +184,15 @@ deploy_ui() {
|
||||||
# Copy main UI files
|
# Copy main UI files
|
||||||
cp -r public includes assets "$WEB_DIR/" || error_exit "Failed to copy UI files"
|
cp -r public includes assets "$WEB_DIR/" || error_exit "Failed to copy UI files"
|
||||||
|
|
||||||
|
# Copy root-level PHP files for direct access (when document root is main directory)
|
||||||
|
if [[ -f "index.php" ]]; then
|
||||||
|
cp index.php "$WEB_DIR/" || log "WARNING" "Failed to copy root index.php"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -f "dashboard.php" ]]; then
|
||||||
|
cp dashboard.php "$WEB_DIR/" || log "WARNING" "Failed to copy root dashboard.php"
|
||||||
|
fi
|
||||||
|
|
||||||
# Copy optional files if they exist
|
# Copy optional files if they exist
|
||||||
if [[ -f "README.md" ]]; then
|
if [[ -f "README.md" ]]; then
|
||||||
cp README.md "$WEB_DIR/" || log "WARNING" "Failed to copy README.md"
|
cp README.md "$WEB_DIR/" || log "WARNING" "Failed to copy README.md"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue