fix: IMAP-Serveradresse dynamisch aus Backend laden

Hardcodierte 192.168.1.131 in settings/page.tsx ersetzt durch
dynamischen API-Call GET /api/system/info → {fqdn, imap_port}.
Fallback auf window.location.hostname wenn API nicht antwortet.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
sysops
2026-04-06 11:06:58 +02:00
parent 3b05e949dd
commit 2a91f6e249
5 changed files with 70 additions and 4 deletions
+39 -4
View File
@@ -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<SystemInfo | null>(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() {
<Server className="h-3.5 w-3.5" aria-hidden="true" />
Server
</span>
<span className="font-mono">192.168.1.131</span>
<span className="font-mono">
{systemInfoLoading
? "Laden..."
: systemInfo?.fqdn ||
(typeof window !== "undefined"
? window.location.hostname
: "")}
</span>
<span className="text-muted-foreground flex items-center gap-1.5">
<Lock className="h-3.5 w-3.5" aria-hidden="true" />
IMAP-Port
</span>
<span className="font-mono">9993 (SSL/TLS)</span>
<span className="font-mono">
{systemInfo?.imap_port ?? 9993} (SSL/TLS)
</span>
<span className="text-muted-foreground flex items-center gap-1.5">
<Lock className="h-3.5 w-3.5" aria-hidden="true" />
Alternativ-Port
</span>
<span className="font-mono">993 (SSL/TLS)</span>
<span className="font-mono">
{systemInfo?.imap_port_alt ?? 993} (SSL/TLS)
</span>
<span className="text-muted-foreground flex items-center gap-1.5">
<Lock className="h-3.5 w-3.5" aria-hidden="true" />
+2
View File
@@ -121,6 +121,7 @@ export {
export type {
HealthResponse,
SystemInfo,
SMTPStatus,
StorageStats,
ServiceStatus,
@@ -142,6 +143,7 @@ export type {
} from "./system";
export {
getHealth,
getSystemInfo,
getSMTPStatus,
getStorageStats,
getSystemStats,
+10
View File
@@ -6,6 +6,12 @@ export interface HealthResponse {
status: string;
}
export interface SystemInfo {
fqdn: string;
imap_port: number;
imap_port_alt: number;
}
export interface SMTPStatus {
// global daemon fields (superadmin)
running?: boolean;
@@ -157,6 +163,10 @@ export async function getHealth(): Promise<HealthResponse> {
return request<HealthResponse>("/api/health");
}
export async function getSystemInfo(): Promise<SystemInfo> {
return request<SystemInfo>("/api/system/info");
}
export async function getSMTPStatus(): Promise<SMTPStatus> {
return request<SMTPStatus>("/api/admin/smtp/status");
}