feat: move step-ca into a plugin (C4)

This commit is contained in:
LukeGus committed 2026-09-24 19:55:28 -05:00
1 parent 98d367d7e2
commit b027717c46
128 files changed
+3805 -1781

No files matched your search

-54
View File
@@ -3,8 +3,6 @@ import { useTranslation } from "react-i18next";
import { useBranding } from "@/contexts/BrandingContext";
import {
getNotificationPrivateEndpoints,
getStepCaPrivateEndpoints,
setStepCaPrivateEndpoints as setStepCaPrivateEndpointsApi,
setNotificationPrivateEndpoints as setNotificationPrivateEndpointsApi,
} from "@/api/private-endpoints-api";
import {
@@ -73,7 +71,6 @@ import {
type AdminUser,
} from "./AdminManagementSections";
import { toast } from "sonner";
import { getStepCaSettings, updateStepCaSettings } from "@/api/settings-api";
import { getDatabaseTransferUrl } from "@/lib/database-transfer-url";
import {
AdminDatabaseSection,
@@ -129,25 +126,6 @@ export function AdminSettingsPanel({
const [analyticsLocked, setAnalyticsLocked] = useState(false);
const [oidcSilentLoginDefaultLocked, setOidcSilentLoginDefaultLocked] =
useState(false);
const [stepCaPrivateEndpoints, setStepCaPrivateEndpoints] = useState<
string[]
>([]);
const [stepCaSettings, setStepCaSettings] = useState({
caUrl: "",
fingerprint: "",
provisioner: "",
});
useEffect(() => {
getStepCaSettings()
.then((s) =>
setStepCaSettings({
caUrl: s.caUrl,
fingerprint: s.fingerprint,
provisioner: s.provisioner,
}),
)
.catch(() => {});
}, []);
const [notificationPrivateEndpoints, setNotificationPrivateEndpoints] =
useState<string[]>([]);
const [hostDefaults, setHostDefaults] = useState<HostDefaults>({});
@@ -333,7 +311,6 @@ export function AdminSettingsPanel({
oidcSilent,
analytics,
notificationEndpoints,
stepCaEndpoints,
branding,
] = await Promise.allSettled([
getRegistrationAllowed(),
@@ -347,7 +324,6 @@ export function AdminSettingsPanel({
getOidcSilentLoginDefault(),
getAnalyticsEnabled(),
getNotificationPrivateEndpoints(),
getStepCaPrivateEndpoints(),
getBranding(),
]);
@@ -379,9 +355,6 @@ export function AdminSettingsPanel({
setAnalyticsEnabled(analytics.value.enabled);
setAnalyticsLocked(analytics.value.locked ?? false);
}
if (stepCaEndpoints.status === "fulfilled") {
setStepCaPrivateEndpoints(stepCaEndpoints.value);
}
if (notificationEndpoints.status === "fulfilled") {
setNotificationPrivateEndpoints(notificationEndpoints.value);
}
@@ -499,28 +472,6 @@ export function AdminSettingsPanel({
}
}
async function handleSaveStepCaSettings() {
try {
await updateStepCaSettings(stepCaSettings);
toast.success(t("admin.stepCaSaved"));
} catch (error) {
toast.error(
error instanceof Error ? error.message : t("admin.stepCaSaveFailed"),
);
}
}
async function handleSaveStepCaPrivateEndpoints(hosts: string[]) {
const previous = stepCaPrivateEndpoints;
setStepCaPrivateEndpoints(hosts);
try {
setStepCaPrivateEndpoints(await setStepCaPrivateEndpointsApi(hosts));
} catch {
setStepCaPrivateEndpoints(previous);
toast.error(t("admin.updateStepCaEndpointsFailed"));
}
}
async function handleSaveNotificationPrivateEndpoints(hosts: string[]) {
const previous = notificationPrivateEndpoints;
setNotificationPrivateEndpoints(hosts);
@@ -938,11 +889,6 @@ export function AdminSettingsPanel({
analyticsLocked={analyticsLocked}
handleToggleAnalytics={handleToggleAnalytics}
notificationPrivateEndpoints={notificationPrivateEndpoints}
stepCaPrivateEndpoints={stepCaPrivateEndpoints}
onSaveStepCaPrivateEndpoints={handleSaveStepCaPrivateEndpoints}
stepCaSettings={stepCaSettings}
setStepCaSettings={setStepCaSettings}
handleSaveStepCaSettings={handleSaveStepCaSettings}
onSaveNotificationPrivateEndpoints={
handleSaveNotificationPrivateEndpoints
}
-79
View File
@@ -18,13 +18,6 @@ type GeneralSettingsSectionProps = {
handleToggleAnalytics: () => void;
notificationPrivateEndpoints: string[];
onSaveNotificationPrivateEndpoints: (hosts: string[]) => void;
stepCaPrivateEndpoints: string[];
onSaveStepCaPrivateEndpoints: (hosts: string[]) => void;
stepCaSettings: { caUrl: string; fingerprint: string; provisioner: string };
setStepCaSettings: Dispatch<
SetStateAction<{ caUrl: string; fingerprint: string; provisioner: string }>
>;
handleSaveStepCaSettings: () => void;
allowRegistration: boolean;
handleToggleRegistration: () => void;
allowPasswordLogin: boolean;
@@ -57,11 +50,6 @@ export function AdminGeneralSettingsSection({
handleToggleAnalytics,
notificationPrivateEndpoints,
onSaveNotificationPrivateEndpoints,
stepCaPrivateEndpoints,
onSaveStepCaPrivateEndpoints,
stepCaSettings,
setStepCaSettings,
handleSaveStepCaSettings,
allowRegistration,
handleToggleRegistration,
allowPasswordLogin,
@@ -130,73 +118,6 @@ export function AdminGeneralSettingsSection({
}
/>
</div>
<div className="flex flex-col gap-1.5 py-2">
<span className="text-xs font-medium">
{t("admin.stepCaPrivateEndpoints")}
</span>
<span className="text-[11px] leading-snug text-muted-foreground">
{t("admin.stepCaPrivateEndpointsDesc")}
</span>
<Input
className="rounded-none"
defaultValue={stepCaPrivateEndpoints.join(", ")}
placeholder="ca.internal, sso.internal"
onBlur={(event) =>
onSaveStepCaPrivateEndpoints(
event.target.value
.split(",")
.map((entry) => entry.trim())
.filter(Boolean),
)
}
/>
</div>
<div className="flex flex-col gap-2 border-t border-border pt-3 mt-2">
<span className="text-[10px] font-bold uppercase tracking-widest text-muted-foreground">
{t("admin.stepCa")}
</span>
<span className="text-[11px] leading-snug text-muted-foreground">
{t("admin.stepCaDesc")}
</span>
<Input
className="rounded-none"
placeholder="https://ca.internal:9000"
value={stepCaSettings.caUrl}
onChange={(e) =>
setStepCaSettings((p) => ({ ...p, caUrl: e.target.value }))
}
/>
<Input
className="rounded-none font-mono text-xs"
placeholder={t("admin.stepCaFingerprint")}
value={stepCaSettings.fingerprint}
onChange={(e) =>
setStepCaSettings((p) => ({ ...p, fingerprint: e.target.value }))
}
/>
<div className="flex items-center gap-2">
<Input
className="rounded-none"
placeholder={t("admin.stepCaProvisioner")}
value={stepCaSettings.provisioner}
onChange={(e) =>
setStepCaSettings((p) => ({
...p,
provisioner: e.target.value,
}))
}
/>
<Button
variant="outline"
size="sm"
className="text-xs border-accent-brand/40 text-accent-brand hover:bg-accent-brand/10 hover:text-accent-brand h-7"
onClick={handleSaveStepCaSettings}
>
{t("common.save")}
</Button>
</div>
</div>
<div className="border-t border-border pt-3 mt-2">
<SettingRow
label={t("admin.allowRegistration")}
-3
View File
@@ -88,7 +88,6 @@ import { useSshAuthEditors } from "@/plugin-host/auth-registry";
import { useSshAuthProviders } from "@/hooks/useSshAuthProviders";
import { SshAuthProviderFields } from "./SshAuthProviderFields";
import type { PluginSettingsField } from "@termix/plugin-sdk/manifest";
import { ensureLegacyAuthUI } from "@/auth/legacy-auth-ui";
import { PluginComponent } from "@/plugin-host/component-registry";
import {
toCredentialOption,
@@ -97,8 +96,6 @@ import {
const CUSTOM_FONT_OPTION = "__custom__";
ensureLegacyAuthUI();
export function HostEditor({
host,
activeTab,