import type { Dispatch, SetStateAction } from "react"; import { useTranslation } from "react-i18next"; import { Button } from "@/components/button"; import { Input } from "@/components/input"; import { PasswordInput } from "@/components/password-input"; import { SettingRow } from "@/components/section-card"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/select"; import { Database, Lock, Pencil, Plus, RefreshCw, Server, Settings, Shield, Trash2, } from "lucide-react"; import { AccordionSection, AdminToggle } from "./AdminSettingsShared"; import type { SSOProvider, SSOProviderType } from "@/types/index"; import type { HostDefaults } from "@/api/settings-api"; import type { AcmeSettings, AcmeChallengeType } from "@/api/acme-ssl-api"; type GeneralSettingsSectionProps = { open: boolean; onToggle: () => void; allowRegistration: boolean; handleToggleRegistration: () => void; allowPasswordLogin: boolean; handleTogglePasswordLogin: () => void; oidcAutoProvision: boolean; handleToggleOidcAutoProvision: () => void; oidcSilentLoginDefault: boolean; handleToggleOidcSilentLoginDefault: () => void; allowPasswordReset: boolean; handleTogglePasswordReset: () => void; commandHistoryEnabled: boolean; handleToggleCommandHistory: () => void; sessionTimeout: string; setSessionTimeout: Dispatch>; handleSaveSessionTimeout: () => void; statusInterval: string; setStatusInterval: Dispatch>; metricsInterval: string; setMetricsInterval: Dispatch>; metricsHistoryRetention: string; setMetricsHistoryRetention: Dispatch>; handleSaveMonitoring: () => void; guacEnabled: boolean; handleToggleGuacamole: () => void; guacUrl: string; setGuacUrl: Dispatch>; handleSaveGuacamole: () => void; logLevel: string; handleSaveLogLevel: (level: string) => void; tailscaleApiKey: string; setTailscaleApiKey: Dispatch>; handleSaveTailscaleApiKey: () => void; }; export function AdminGeneralSettingsSection({ open, onToggle, allowRegistration, handleToggleRegistration, allowPasswordLogin, handleTogglePasswordLogin, oidcAutoProvision, handleToggleOidcAutoProvision, oidcSilentLoginDefault, handleToggleOidcSilentLoginDefault, allowPasswordReset, handleTogglePasswordReset, commandHistoryEnabled, handleToggleCommandHistory, sessionTimeout, setSessionTimeout, handleSaveSessionTimeout, statusInterval, setStatusInterval, metricsInterval, setMetricsInterval, metricsHistoryRetention, setMetricsHistoryRetention, handleSaveMonitoring, guacEnabled, handleToggleGuacamole, guacUrl, setGuacUrl, handleSaveGuacamole, logLevel, handleSaveLogLevel, tailscaleApiKey, setTailscaleApiKey, handleSaveTailscaleApiKey, }: GeneralSettingsSectionProps) { const { t } = useTranslation(); return ( } open={open} onToggle={onToggle} >
{t("admin.sessionTimeout")}
setSessionTimeout(e.target.value)} className="w-20 text-sm" /> {t("admin.hours")}
{t("admin.sessionTimeoutRange")}
{t("admin.monitoringDefaults")}
setStatusInterval(e.target.value)} className="w-20 text-sm" /> {t("admin.sec")}
setMetricsInterval(e.target.value)} className="w-20 text-sm" /> {t("admin.sec")}
setMetricsHistoryRetention(e.target.value)} className="w-20 text-sm" /> {t("admin.days")}
{t("admin.metricsHistoryRetentionRange")}
{t("admin.enableGuacamoleDesc")}{" "} {t("admin.enableGuacamoleDocsLink")} } > {guacEnabled && (
setGuacUrl(e.target.value)} placeholder="guacd:4822" className="text-sm" />
)}
{t("admin.tailscaleApiKey")} {t("admin.tailscaleApiKeyDescription")}{" "} {t("admin.tailscaleApiKeyDocsLink")}
setTailscaleApiKey(e.target.value)} placeholder="tskey-api-..." className="text-sm" />
{t("admin.logLevel")}
{["debug", "info", "warn", "error"].map((l) => ( ))}
); } type OidcSettingsSectionProps = { open: boolean; onToggle: () => void; oidcClientId: string; setOidcClientId: Dispatch>; oidcClientSecret: string; setOidcClientSecret: Dispatch>; oidcAuthUrl: string; setOidcAuthUrl: Dispatch>; oidcIssuerUrl: string; setOidcIssuerUrl: Dispatch>; oidcTokenUrl: string; setOidcTokenUrl: Dispatch>; oidcUserIdentifier: string; setOidcUserIdentifier: Dispatch>; oidcDisplayName: string; setOidcDisplayName: Dispatch>; oidcScopes: string; setOidcScopes: Dispatch>; oidcUserinfoUrl: string; setOidcUserinfoUrl: Dispatch>; oidcAllowedUsers: string; setOidcAllowedUsers: Dispatch>; oidcAdminGroup: string; setOidcAdminGroup: Dispatch>; oidcGroupClaim: string; setOidcGroupClaim: Dispatch>; oidcSaving: boolean; handleRemoveOidc: () => void; handleSaveOidc: () => void; }; export function AdminOidcSettingsSection({ open, onToggle, oidcClientId, setOidcClientId, oidcClientSecret, setOidcClientSecret, oidcAuthUrl, setOidcAuthUrl, oidcIssuerUrl, setOidcIssuerUrl, oidcTokenUrl, setOidcTokenUrl, oidcUserIdentifier, setOidcUserIdentifier, oidcDisplayName, setOidcDisplayName, oidcScopes, setOidcScopes, oidcUserinfoUrl, setOidcUserinfoUrl, oidcAllowedUsers, setOidcAllowedUsers, oidcAdminGroup, setOidcAdminGroup, oidcGroupClaim, setOidcGroupClaim, oidcSaving, handleRemoveOidc, handleSaveOidc, }: OidcSettingsSectionProps) { const { t } = useTranslation(); return ( } open={open} onToggle={onToggle} >
{t("admin.oidcDescription").split("*")[0]} * {t("admin.oidcDescription").split("*")[1]}{" "} {t("admin.oidcDocsLink")}
setOidcClientId(e.target.value)} placeholder="your-client-id" className="text-xs" />
setOidcClientSecret(e.target.value)} placeholder="your-client-secret" className="text-xs" />
setOidcAuthUrl(e.target.value)} placeholder="https://provider/oauth2/auth" className="text-xs" />
setOidcIssuerUrl(e.target.value)} placeholder="https://provider" className="text-xs" />
setOidcTokenUrl(e.target.value)} placeholder="https://provider/oauth2/token" className="text-xs" />
setOidcUserIdentifier(e.target.value)} placeholder="sub" className="text-xs" />
setOidcDisplayName(e.target.value)} placeholder="name" className="text-xs" />
setOidcScopes(e.target.value)} placeholder="openid email profile" className="text-xs" />
setOidcUserinfoUrl(e.target.value)} placeholder="https://provider/oauth2/userinfo" className="text-xs" />
{t("admin.oidcAllowedUsersDesc")}