+ {/* Status bar */}
+
+
+
+
+
+
+
Fail2Ban {fail2banInfo.version}
+
+ {fail2banInfo.active ? "Service is running" : "Service is not running"}
+
+
+
+
+ {fail2banInfo.active ? "Active" : "Inactive"}
+
+
+
+ {fail2banInfo.active && f2bDetails && (
+ <>
+ {/* Summary stats */}
+
+
+
Jails
+
{f2bDetails.jails.length}
+
+
+
Banned IPs
+
a + j.currently_banned, 0) > 0 ? "text-red-500" : "text-green-500"}`}>
+ {f2bDetails.jails.reduce((a, j) => a + j.currently_banned, 0)}
+
+
+
+
Total Bans
+
+ {f2bDetails.jails.reduce((a, j) => a + j.total_banned, 0)}
+
+
+
+
Failed Attempts
+
+ {f2bDetails.jails.reduce((a, j) => a + j.total_failed, 0)}
+
+
+
+
+ {/* Tab switcher */}
+
+
+
+
+
+ {/* JAILS TAB */}
+ {f2bActiveTab === "jails" && (
+
+ {f2bDetails.jails.map((jail) => (
+
+ {/* Jail header */}
+
+
+
0 ? "bg-red-500 animate-pulse" : "bg-green-500"}`} />
+ {jail.name}
+
+
+
+ Retries: {jail.maxretry}
+
+
+ Ban: {formatBanTime(jail.bantime)}
+
+
+ Window: {formatBanTime(jail.findtime)}
+
+
+
+
+ {/* Jail stats bar */}
+
+
+
Banned
+
0 ? "text-red-500" : "text-green-500"}`}>
+ {jail.currently_banned}
+
+
+
+
Total Bans
+
{jail.total_banned}
+
+
+
Failed Now
+
{jail.currently_failed}
+
+
+
Total Failed
+
{jail.total_failed}
+
+
+
+ {/* Banned IPs list */}
+ {jail.banned_ips.length > 0 && (
+
+
+
+ Banned IPs ({jail.banned_ips.length})
+
+
+ {jail.banned_ips.map((ip) => (
+
+
+
+
+ ))}
+
+
+
+ )}
+
+ {jail.currently_banned === 0 && (
+
+
No IPs currently banned in this jail
+
+ )}
+
+ ))}
+
+ {f2bDetails.jails.length === 0 && (
+
+ No jails configured
+
+ )}
+
+ )}
+
+ {/* ACTIVITY TAB */}
+ {f2bActiveTab === "activity" && (
+
+ {f2bActivity.length === 0 ? (
+
+ No recent activity in the Fail2Ban log
+
+ ) : (
+ f2bActivity.map((event, idx) => (
+
+
+
+ {event.action}
+
+
{event.ip}
+
{event.jail}
+
{event.timestamp}
+
+ ))
+ )}
+
+ )}
+ >
+ )}
+
+ {fail2banInfo.active && !f2bDetails && f2bDetailsLoading && (
+
+ )}
+
+ )}
+
+
+
+ {/* Lynis */}
+
+
+
+
+ Lynis Security Audit
+
+
+ System security auditing tool that performs comprehensive security scans
+
+
+
+ {toolsLoading ? (
+
+ ) : !lynisInfo?.installed ? (
+
+
+
+
+
+
+
+
Lynis Not Installed
+
Comprehensive security auditing and hardening tool
+
+
+
+ Not Installed
+
+
+
+
+
+
+
+
Lynis features:
+
+ - System hardening scoring (0-100)
+ - Vulnerability detection and suggestions
+ - Compliance checking (PCI-DSS, HIPAA, etc.)
+ - Installed from latest GitHub source
+
+
+
+
+
+
+
+ ) : (
+
+ {/* Status */}
+
+
+
+
+
+
+
Lynis {lynisInfo.version}
+
Security auditing tool installed
+
+
+
+ Installed
+
+
+
+ {/* Last Scan Info */}
+
+
+
Last Scan
+
+ {lynisInfo.last_scan || "No scan performed yet"}
+
+
+
+
Hardening Index
+
= 70 ? "text-green-500" :
+ lynisInfo.hardening_index >= 50 ? "text-yellow-500" :
+ "text-red-500"
+ }`}>
+ {lynisInfo.hardening_index !== null ? `${lynisInfo.hardening_index}/100` : "N/A"}
+
+
+
+
+
+
+
+ Run audits from the Proxmox terminal with: lynis audit system
+
+
+
+ )}
+
+
+
+ {/* Script Terminal Modals */}
+
{
+ setShowFail2banInstaller(false)
+ loadSecurityTools()
+ }}
+ scriptPath="/usr/local/share/proxmenux/scripts/security/fail2ban_installer.sh"
+ scriptName="fail2ban_installer"
+ params={{ EXECUTION_MODE: "web" }}
+ title="Fail2Ban Installation"
+ description="Installing and configuring Fail2Ban for SSH and Proxmox protection..."
+ />
+ {
+ setShowLynisInstaller(false)
+ loadSecurityTools()
+ }}
+ scriptPath="/usr/local/share/proxmenux/scripts/security/lynis_installer.sh"
+ scriptName="lynis_installer"
+ params={{ EXECUTION_MODE: "web" }}
+ title="Lynis Installation"
+ description="Installing Lynis security auditing tool from GitHub..."
+ />
+
+ setShow2FASetup(false)}
+ onSuccess={() => {
+ setSuccess("2FA enabled successfully!")
+ checkAuthStatus()
+ }}
+ />
+
+ )
+}
diff --git a/AppImage/components/settings.tsx b/AppImage/components/settings.tsx
index 29402a03..73625767 100644
--- a/AppImage/components/settings.tsx
+++ b/AppImage/components/settings.tsx
@@ -1,16 +1,11 @@
"use client"
import { useState, useEffect } from "react"
-import { Button } from "./ui/button"
-import { Input } from "./ui/input"
-import { Label } from "./ui/label"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "./ui/card"
-import { Shield, Lock, User, AlertCircle, CheckCircle, Info, LogOut, Wrench, Package, Key, Copy, Eye, EyeOff, Ruler, Trash2, RefreshCw, Clock, ShieldCheck, Globe, FileKey, AlertTriangle } from 'lucide-react'
-import { APP_VERSION } from "./release-notes-modal"
-import { getApiUrl, fetchApi } from "../lib/api-config"
-import { TwoFactorSetup } from "./two-factor-setup"
+import { Wrench, Package, Ruler } from "lucide-react"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./ui/select"
import { getNetworkUnit } from "../lib/format-network"
+import { fetchApi } from "../lib/api-config"
interface ProxMenuxTool {
key: string
@@ -18,99 +13,20 @@ interface ProxMenuxTool {
enabled: boolean
}
-interface ApiTokenEntry {
- id: string
- name: string
- token_prefix: string
- created_at: string
- expires_at: string
- revoked: boolean
-}
-
export function Settings() {
- const [authEnabled, setAuthEnabled] = useState(false)
- const [totpEnabled, setTotpEnabled] = useState(false)
- const [loading, setLoading] = useState(false)
- const [error, setError] = useState("")
- const [success, setSuccess] = useState("")
-
- // Setup form state
- const [showSetupForm, setShowSetupForm] = useState(false)
- const [username, setUsername] = useState("")
- const [password, setPassword] = useState("")
- const [confirmPassword, setConfirmPassword] = useState("")
-
- // Change password form state
- const [showChangePassword, setShowChangePassword] = useState(false)
- const [currentPassword, setCurrentPassword] = useState("")
- const [newPassword, setNewPassword] = useState("")
- const [confirmNewPassword, setConfirmNewPassword] = useState("")
-
- const [show2FASetup, setShow2FASetup] = useState(false)
- const [show2FADisable, setShow2FADisable] = useState(false)
- const [disable2FAPassword, setDisable2FAPassword] = useState("")
-
const [proxmenuxTools, setProxmenuxTools] = useState