diff --git a/internal/api/server.go b/internal/api/server.go index 7ed50d1..f8f3248 100644 --- a/internal/api/server.go +++ b/internal/api/server.go @@ -191,6 +191,7 @@ func (s *Server) routes() { s.mux.HandleFunc("GET /api/health", s.handleHealth) s.mux.HandleFunc("GET /metrics", s.handleMetrics) s.mux.HandleFunc("GET /api/version", s.handleVersion) + s.mux.HandleFunc("GET /api/system/info", s.auth(s.handleSystemInfo)) s.mux.HandleFunc("POST /api/auth/login", s.handleLogin) s.mux.HandleFunc("GET /api/auth/me", s.auth(s.handleMe)) s.mux.HandleFunc("POST /api/auth/logout", s.auth(s.handleLogout)) diff --git a/internal/api/system_info_handler.go b/internal/api/system_info_handler.go new file mode 100644 index 0000000..9582e12 --- /dev/null +++ b/internal/api/system_info_handler.go @@ -0,0 +1,18 @@ +package api + +import "net/http" + +// handleSystemInfo liefert öffentliche System-Verbindungsdaten +// (FQDN, IMAP-Port). Wird im Frontend für die IMAP-Zugang-Karte +// auf der Settings-Seite verwendet. +// +// GET /api/system/info — auth required (Endpoint zeigt nur generische, +// nicht-sensitive Verbindungsdaten an, ist aber an Login gebunden, um +// öffentliches Profiling der Installation zu vermeiden). +func (s *Server) handleSystemInfo(w http.ResponseWriter, r *http.Request) { + writeJSON(w, http.StatusOK, map[string]interface{}{ + "fqdn": s.fqdn, + "imap_port": 9993, + "imap_port_alt": 993, + }) +} diff --git a/src/app/settings/page.tsx b/src/app/settings/page.tsx index fa9cb22..dc6c2c0 100644 --- a/src/app/settings/page.tsx +++ b/src/app/settings/page.tsx @@ -1,6 +1,6 @@ "use client"; -import { useState } from "react"; +import { useEffect, useState } from "react"; import { useAuth } from "@/hooks/useAuth"; import { Navbar } from "@/components/navbar"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; @@ -23,6 +23,8 @@ import { getTOTPSetup, confirmTOTPSetup, disableTOTP, + getSystemInfo, + type SystemInfo, } from "@/lib/api"; export default function SettingsPage() { @@ -57,6 +59,28 @@ export default function SettingsPage() { const [disableError, setDisableError] = useState(""); const [disableLoading, setDisableLoading] = useState(false); + // ── System info (FQDN + IMAP-Ports) ─────────────────────────────────── + const [systemInfo, setSystemInfo] = useState(null); + const [systemInfoLoading, setSystemInfoLoading] = useState(true); + + useEffect(() => { + let cancelled = false; + setSystemInfoLoading(true); + getSystemInfo() + .then((info) => { + if (!cancelled) setSystemInfo(info); + }) + .catch(() => { + if (!cancelled) setSystemInfo(null); + }) + .finally(() => { + if (!cancelled) setSystemInfoLoading(false); + }); + return () => { + cancelled = true; + }; + }, []); + // Initialize email from user data once available if (user && !emailInitialized) { setEmail(user.email || ""); @@ -488,19 +512,30 @@ export default function SettingsPage() {