mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2025-11-18 03:26:17 +00:00
Update AppImage
This commit is contained in:
@@ -287,6 +287,11 @@ export function ProxmoxDashboard() {
|
|||||||
setupTokenRefresh()
|
setupTokenRefresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleLogout = () => {
|
||||||
|
localStorage.removeItem("proxmenux-auth-token")
|
||||||
|
setIsAuthenticated(false)
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const checkAuth = async () => {
|
const checkAuth = async () => {
|
||||||
console.log("[v0] Checking authentication status...")
|
console.log("[v0] Checking authentication status...")
|
||||||
@@ -443,6 +448,17 @@ export function ProxmoxDashboard() {
|
|||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<ThemeToggle />
|
<ThemeToggle />
|
||||||
|
|
||||||
|
{authRequired && isAuthenticated && (
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="sm"
|
||||||
|
onClick={handleLogout}
|
||||||
|
className="border-border/50 bg-transparent hover:bg-secondary"
|
||||||
|
>
|
||||||
|
Logout
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Mobile Actions */}
|
{/* Mobile Actions */}
|
||||||
@@ -457,6 +473,12 @@ export function ProxmoxDashboard() {
|
|||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<ThemeToggle />
|
<ThemeToggle />
|
||||||
|
|
||||||
|
{authRequired && isAuthenticated && (
|
||||||
|
<Button variant="ghost" size="sm" onClick={handleLogout} className="h-8 px-2 text-xs">
|
||||||
|
Logout
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -184,6 +184,11 @@ export function Settings() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleLogout = () => {
|
||||||
|
localStorage.removeItem("proxmenux-auth-token")
|
||||||
|
window.location.reload()
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
<div>
|
<div>
|
||||||
@@ -316,6 +321,10 @@ export function Settings() {
|
|||||||
|
|
||||||
{authEnabled && (
|
{authEnabled && (
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
|
<Button onClick={handleLogout} variant="outline" className="w-full bg-transparent">
|
||||||
|
Logout
|
||||||
|
</Button>
|
||||||
|
|
||||||
{!showChangePassword && (
|
{!showChangePassword && (
|
||||||
<Button onClick={() => setShowChangePassword(true)} variant="outline" className="w-full">
|
<Button onClick={() => setShowChangePassword(true)} variant="outline" className="w-full">
|
||||||
<Lock className="h-4 w-4 mr-2" />
|
<Lock className="h-4 w-4 mr-2" />
|
||||||
|
|||||||
@@ -47,13 +47,13 @@ def hash_password(password: str) -> str:
|
|||||||
def load_auth_config():
|
def load_auth_config():
|
||||||
"""Load authentication configuration from file"""
|
"""Load authentication configuration from file"""
|
||||||
if not AUTH_CONFIG_FILE.exists():
|
if not AUTH_CONFIG_FILE.exists():
|
||||||
return {"auth_enabled": False}
|
return {} # Return empty dict if file doesn't exist
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(AUTH_CONFIG_FILE, 'r') as f:
|
with open(AUTH_CONFIG_FILE, 'r') as f:
|
||||||
return json.load(f)
|
return json.load(f)
|
||||||
except:
|
except (json.JSONDecodeError, FileNotFoundError): # Handle potential errors
|
||||||
return {"auth_enabled": False}
|
return {} # Return empty dict on error
|
||||||
|
|
||||||
def save_auth_config(config):
|
def save_auth_config(config):
|
||||||
"""Save authentication configuration to file"""
|
"""Save authentication configuration to file"""
|
||||||
@@ -97,7 +97,8 @@ def auth_status():
|
|||||||
"""Check if authentication is enabled and if current session is valid"""
|
"""Check if authentication is enabled and if current session is valid"""
|
||||||
try:
|
try:
|
||||||
auth_config = load_auth_config()
|
auth_config = load_auth_config()
|
||||||
is_enabled = auth_config.get("auth_enabled", False)
|
is_configured = auth_config is not None and len(auth_config) > 0
|
||||||
|
is_enabled = auth_config.get("auth_enabled", False) if is_configured else False
|
||||||
|
|
||||||
# Check if user has valid token
|
# Check if user has valid token
|
||||||
is_authenticated = False
|
is_authenticated = False
|
||||||
@@ -114,6 +115,7 @@ def auth_status():
|
|||||||
|
|
||||||
return jsonify({
|
return jsonify({
|
||||||
"auth_enabled": is_enabled,
|
"auth_enabled": is_enabled,
|
||||||
|
"auth_configured": is_configured, # New field to indicate if auth has been set up
|
||||||
"authenticated": is_authenticated or not is_enabled
|
"authenticated": is_authenticated or not is_enabled
|
||||||
})
|
})
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -188,7 +190,7 @@ def auth_login():
|
|||||||
# Load auth config
|
# Load auth config
|
||||||
auth_config = load_auth_config()
|
auth_config = load_auth_config()
|
||||||
|
|
||||||
if not auth_config.get("auth_enabled", False):
|
if not auth_config or not auth_config.get("auth_enabled", False):
|
||||||
return jsonify({"error": "Authentication is not enabled"}), 400
|
return jsonify({"error": "Authentication is not enabled"}), 400
|
||||||
|
|
||||||
# Verify credentials
|
# Verify credentials
|
||||||
@@ -668,18 +670,18 @@ def get_intel_gpu_processes_from_text():
|
|||||||
processes.append(process_info)
|
processes.append(process_info)
|
||||||
|
|
||||||
except (ValueError, IndexError) as e:
|
except (ValueError, IndexError) as e:
|
||||||
# print(f"[v0] Error parsing process line: {e}", flush=True)
|
# print(f"[v0] Error parsing process line: {e}")
|
||||||
pass
|
pass
|
||||||
continue
|
continue
|
||||||
break
|
break
|
||||||
|
|
||||||
if not header_found:
|
if not header_found:
|
||||||
# print(f"[v0] No process table found in intel_gpu_top output", flush=True)
|
# print(f"[v0] No process table found in intel_gpu_top output")
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return processes
|
return processes
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# print(f"[v0] Error getting processes from intel_gpu_top text: {e}", flush=True)
|
# print(f"[v0] Error getting processes from intel_gpu_top text: {e}")
|
||||||
pass
|
pass
|
||||||
import traceback
|
import traceback
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
@@ -1397,8 +1399,8 @@ def get_smart_data(disk_name):
|
|||||||
try:
|
try:
|
||||||
commands_to_try = [
|
commands_to_try = [
|
||||||
['smartctl', '-a', '-j', f'/dev/{disk_name}'], # JSON output (preferred)
|
['smartctl', '-a', '-j', f'/dev/{disk_name}'], # JSON output (preferred)
|
||||||
['smartctl', '-a', '-j', '-d', 'ata', f'/dev/{disk_name}'], # JSON with ATA device type
|
['smartctl', '-a', '-d', 'ata', f'/dev/{disk_name}'], # JSON with ATA device type
|
||||||
['smartctl', '-a', '-j', '-d', 'sat', f'/dev/{disk_name}'], # JSON with SAT device type
|
['smartctl', '-a', '-d', 'sat', f'/dev/{disk_name}'], # JSON with SAT device type
|
||||||
['smartctl', '-a', f'/dev/{disk_name}'], # Text output (fallback)
|
['smartctl', '-a', f'/dev/{disk_name}'], # Text output (fallback)
|
||||||
['smartctl', '-a', '-d', 'ata', f'/dev/{disk_name}'], # Text with ATA device type
|
['smartctl', '-a', '-d', 'ata', f'/dev/{disk_name}'], # Text with ATA device type
|
||||||
['smartctl', '-a', '-d', 'sat', f'/dev/{disk_name}'], # Text with SAT device type
|
['smartctl', '-a', '-d', 'sat', f'/dev/{disk_name}'], # Text with SAT device type
|
||||||
@@ -3080,7 +3082,7 @@ def get_detailed_gpu_info(gpu):
|
|||||||
clients = best_json['clients']
|
clients = best_json['clients']
|
||||||
processes = []
|
processes = []
|
||||||
|
|
||||||
for client_id, client_data in clients.items():
|
for client_id, client_data in clients:
|
||||||
process_info = {
|
process_info = {
|
||||||
'name': client_data.get('name', 'Unknown'),
|
'name': client_data.get('name', 'Unknown'),
|
||||||
'pid': client_data.get('pid', 'Unknown'),
|
'pid': client_data.get('pid', 'Unknown'),
|
||||||
|
|||||||
Reference in New Issue
Block a user