From 8b946945dbaa6cad6c036fcaca6176903c54290c Mon Sep 17 00:00:00 2001 From: Edmund Tan Date: Wed, 23 Jul 2025 12:46:31 +0800 Subject: [PATCH] added reset button --- UI/includes/enrollment.php | 74 +++++++++++++++ UI/public/assets/css/style.css | 4 + UI/public/assets/js/app.js | 94 +++++++++++++++++++ UI/public/dashboard.php | 14 +++ .../temp/check-organization.ps1 | 0 .../temp/check-organization.sh | 0 .../temp/cleanup-organization.ps1 | 0 7 files changed, 186 insertions(+) rename check-organization.ps1 => UI/temp/check-organization.ps1 (100%) rename check-organization.sh => UI/temp/check-organization.sh (100%) rename cleanup-organization.ps1 => UI/temp/cleanup-organization.ps1 (100%) diff --git a/UI/includes/enrollment.php b/UI/includes/enrollment.php index 291b6c8..848f263 100644 --- a/UI/includes/enrollment.php +++ b/UI/includes/enrollment.php @@ -490,6 +490,80 @@ EOF; return executeCommand("apt-get update && apt-get install -y $package"); } + /** + * Clean up router configuration for re-enrollment + */ + public function cleanupRouter() { + try { + $this->reportProgress('CLEANUP', 'Starting router cleanup process...', 0); + + // Check if running as root + if (!isRunningAsRoot()) { + throw new Exception('This operation must be run with root privileges (use sudo)'); + } + + // Step 1: Stop and disable the ziti-router service + $this->reportProgress('CLEANUP', 'Stopping ziti-router service...', 20); + if (!executeCommand('systemctl disable --now ziti-router.service 2>/dev/null')) { + logMessage('WARNING', 'Failed to disable ziti-router service (may not exist)'); + } + + // Step 2: Reset failed state + $this->reportProgress('CLEANUP', 'Resetting service failed state...', 40); + if (!executeCommand('systemctl reset-failed ziti-router.service 2>/dev/null')) { + logMessage('WARNING', 'Failed to reset service failed state (may not be needed)'); + } + + // Step 3: Clean service state + $this->reportProgress('CLEANUP', 'Cleaning service state...', 60); + if (!executeCommand('systemctl clean --what=state ziti-router.service 2>/dev/null')) { + logMessage('WARNING', 'Failed to clean service state (may not be supported)'); + } + + // Step 4: Remove configuration directory + $this->reportProgress('CLEANUP', 'Removing router configuration directory...', 80); + if (is_dir(CONFIG_DIR)) { + if (!executeCommand('rm -rf ' . CONFIG_DIR)) { + throw new Exception('Failed to remove router configuration directory: ' . CONFIG_DIR); + } + logMessage('INFO', 'Removed router configuration directory: ' . CONFIG_DIR); + } else { + logMessage('INFO', 'Router configuration directory does not exist: ' . CONFIG_DIR); + } + + // Step 5: Remove systemd service file if it exists + $this->reportProgress('CLEANUP', 'Removing systemd service file...', 90); + if (file_exists(SYSTEMD_SERVICE_FILE)) { + if (!executeCommand('rm -f ' . SYSTEMD_SERVICE_FILE)) { + logMessage('WARNING', 'Failed to remove systemd service file: ' . SYSTEMD_SERVICE_FILE); + } else { + logMessage('INFO', 'Removed systemd service file: ' . SYSTEMD_SERVICE_FILE); + // Reload systemd after removing service file + executeCommand('systemctl daemon-reload'); + } + } else { + logMessage('INFO', 'Systemd service file does not exist: ' . SYSTEMD_SERVICE_FILE); + } + + $this->reportProgress('CLEANUP', 'Router cleanup completed successfully!', 100); + + return [ + 'success' => true, + 'message' => 'Router configuration cleaned up successfully. You can now enroll a new router.' + ]; + + } catch (Exception $e) { + $errorMsg = $e->getMessage(); + logMessage('ERROR', 'Cleanup failed: ' . $errorMsg); + $this->reportProgress('CLEANUP_ERROR', $errorMsg, null); + + return [ + 'success' => false, + 'error' => $errorMsg + ]; + } + } + /** * Get system status information */ diff --git a/UI/public/assets/css/style.css b/UI/public/assets/css/style.css index 9730508..bf54a02 100644 --- a/UI/public/assets/css/style.css +++ b/UI/public/assets/css/style.css @@ -137,6 +137,10 @@ body { color: white; } +.btn-danger:hover { + background-color: #dc2626; +} + .btn-full { width: 100%; } diff --git a/UI/public/assets/js/app.js b/UI/public/assets/js/app.js index 7e7df45..492db8d 100644 --- a/UI/public/assets/js/app.js +++ b/UI/public/assets/js/app.js @@ -66,6 +66,14 @@ class EnrollmentUI { this.clearLogs(); }); } + + // Cleanup button + const cleanupBtn = document.getElementById('cleanupBtn'); + if (cleanupBtn) { + cleanupBtn.addEventListener('click', () => { + this.showCleanupConfirmation(); + }); + } } validateHashKey(input) { @@ -371,6 +379,92 @@ class EnrollmentUI { } } + showCleanupConfirmation() { + const confirmed = confirm( + '⚠️ WARNING: Router Cleanup\n\n' + + 'This action will:\n' + + '• Stop and disable the ziti-router service\n' + + '• Remove all router configuration files\n' + + '• Delete all certificates\n' + + '• Remove the systemd service file\n\n' + + 'This action cannot be undone!\n\n' + + 'Are you sure you want to proceed?' + ); + + if (confirmed) { + this.startCleanup(); + } + } + + async startCleanup() { + if (this.enrollmentInProgress) { + this.showAlert('Cannot perform cleanup while enrollment is in progress', 'error'); + return; + } + + const cleanupBtn = document.getElementById('cleanupBtn'); + + // Update UI + cleanupBtn.disabled = true; + cleanupBtn.innerHTML = 'Cleaning Up...'; + + this.showProgressContainer(); + this.clearLogs(); + this.updateProgress(0, 'Starting cleanup...'); + + try { + const formData = new FormData(); + formData.append('action', 'cleanup'); + formData.append('csrf_token', document.querySelector('input[name="csrf_token"]').value); + + const response = await fetch('dashboard.php', { + method: 'POST', + body: formData, + headers: { + 'X-Requested-With': 'XMLHttpRequest' + } + }); + + if (!response.ok) { + throw new Error(`HTTP ${response.status}`); + } + + const result = await response.json(); + + if (result.success) { + this.updateProgress(100, 'Cleanup completed successfully!'); + this.addLogEntry('success', result.message); + this.showAlert('Router cleanup completed successfully! The page will reload in 3 seconds.', 'success'); + + // Clear the hash key input field + const hashKeyInput = document.getElementById('hashKey'); + if (hashKeyInput) { + hashKeyInput.value = ''; + this.setInputState(hashKeyInput, 'neutral'); + } + + // Refresh system status immediately + this.loadSystemStatus(); + + // Auto-reload page after 3 seconds + setTimeout(() => { + window.location.reload(); + }, 3000); + } else { + throw new Error(result.error || 'Cleanup failed'); + } + + } catch (error) { + console.error('Cleanup failed:', error); + this.updateProgress(null, 'Cleanup failed'); + this.addLogEntry('error', `Cleanup failed: ${error.message}`); + this.showAlert(`Cleanup failed: ${error.message}`, 'error'); + } finally { + cleanupBtn.disabled = false; + cleanupBtn.innerHTML = '🗑️ Clean Up Router'; + } + } + // Utility method to format file sizes formatFileSize(bytes) { if (bytes === 0) return '0 Bytes'; diff --git a/UI/public/dashboard.php b/UI/public/dashboard.php index 30db07c..ea0f09d 100644 --- a/UI/public/dashboard.php +++ b/UI/public/dashboard.php @@ -49,6 +49,16 @@ if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQU echo json_encode($result); exit; } + + if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'cleanup') { + // Handle cleanup request + AuthManager::requireCSRF(); + + // Start cleanup + $result = $enrollmentManager->cleanupRouter(); + echo json_encode($result); + exit; + } } // Get system status for initial page load @@ -218,6 +228,9 @@ $systemStatus = $enrollmentManager->getSystemStatus(); + @@ -266,6 +279,7 @@ $systemStatus = $enrollmentManager->getSystemStatus();
  • Paste the 32-character hash key
  • Click "Start Enrollment" to begin the process
  • Monitor the progress and logs for status updates
  • +
  • To re-enroll: Click "Clean Up Router" to reset configuration, then enter a new hash key
  • diff --git a/check-organization.ps1 b/UI/temp/check-organization.ps1 similarity index 100% rename from check-organization.ps1 rename to UI/temp/check-organization.ps1 diff --git a/check-organization.sh b/UI/temp/check-organization.sh similarity index 100% rename from check-organization.sh rename to UI/temp/check-organization.sh diff --git a/cleanup-organization.ps1 b/UI/temp/cleanup-organization.ps1 similarity index 100% rename from cleanup-organization.ps1 rename to UI/temp/cleanup-organization.ps1