Fix credential regeneration

This commit is contained in:
Owen
2026-10-21 10:38:02 -04:00
parent 09147cba47
commit d599de197b
2 changed files with 51 additions and 43 deletions
@@ -17,10 +17,7 @@ import { toast } from "@app/hooks/useToast";
import { useParams, useRouter } from "next/navigation";
import { AxiosResponse } from "axios";
import { useTranslations } from "next-intl";
import {
PickRemoteExitNodeDefaultsResponse,
QuickStartRemoteExitNodeResponse
} from "@server/routers/remoteExitNode/types";
import { PickRemoteExitNodeDefaultsResponse } from "@server/routers/remoteExitNode/types";
import { useRemoteExitNodeContext } from "@app/hooks/useRemoteExitNodeContext";
import ConfirmDeleteDialog from "@app/components/ConfirmDeleteDialog";
import {
@@ -30,8 +27,10 @@ import {
InfoSectionTitle
} from "@app/components/InfoSection";
import CopyToClipboard from "@app/components/CopyToClipboard";
import CopyTextBox from "@app/components/CopyTextBox";
import { Alert, AlertDescription, AlertTitle } from "@app/components/ui/alert";
import { InfoIcon } from "lucide-react";
import { build } from "@server/build";
export default function CredentialsPage() {
const { env } = useEnvContext();
@@ -42,11 +41,6 @@ export default function CredentialsPage() {
const { remoteExitNode } = useRemoteExitNodeContext();
const [modalOpen, setModalOpen] = useState(false);
const [credentials, setCredentials] =
useState<PickRemoteExitNodeDefaultsResponse | null>(null);
const [currentRemoteExitNodeId, setCurrentRemoteExitNodeId] = useState<
string | null
>(remoteExitNode.remoteExitNodeId);
const [regeneratedSecret, setRegeneratedSecret] = useState<string | null>(
null
);
@@ -60,28 +54,19 @@ export default function CredentialsPage() {
>(`/org/${orgId}/pick-remote-exit-node-defaults`);
const data = response.data.data;
setCredentials(data);
const rekeyRes = await api.put<
AxiosResponse<QuickStartRemoteExitNodeResponse>
>(`/re-key/${orgId}/regenerate-remote-exit-node-secret`, {
remoteExitNodeId: remoteExitNode.remoteExitNodeId,
secret: data.secret,
disconnect: shouldDisconnect
});
if (rekeyRes && rekeyRes.status === 200) {
const rekeyData = rekeyRes.data.data;
if (rekeyData && rekeyData.remoteExitNodeId) {
setCurrentRemoteExitNodeId(rekeyData.remoteExitNodeId);
setRegeneratedSecret(data.secret);
setCredentials({
...data,
remoteExitNodeId: rekeyData.remoteExitNodeId
});
setShowCredentialsAlert(true);
// Only the secret is rotated; the node keeps its existing ID
await api.put(
`/re-key/${orgId}/regenerate-remote-exit-node-secret`,
{
remoteExitNodeId: remoteExitNode.remoteExitNodeId,
secret: data.secret,
disconnect: shouldDisconnect
}
}
);
setRegeneratedSecret(data.secret);
setShowCredentialsAlert(true);
toast({
title: t("credentialsSaved"),
@@ -107,9 +92,9 @@ export default function CredentialsPage() {
);
};
const displayRemoteExitNodeId =
currentRemoteExitNodeId || remoteExitNode?.remoteExitNodeId || null;
const displayRemoteExitNodeId = remoteExitNode?.remoteExitNodeId || null;
const displaySecret = regeneratedSecret || null;
const showEndpoint = build !== "saas";
return (
<>
@@ -124,17 +109,19 @@ export default function CredentialsPage() {
</SettingsSectionDescription>
</SettingsSectionHeader>
<SettingsSectionBody>
<InfoSections cols={3}>
<InfoSection>
<InfoSectionTitle>
{t("endpoint")}
</InfoSectionTitle>
<InfoSectionContent>
<CopyToClipboard
text={env.app.dashboardUrl}
/>
</InfoSectionContent>
</InfoSection>
<InfoSections cols={showEndpoint ? 3 : 2}>
{showEndpoint && (
<InfoSection>
<InfoSectionTitle>
{t("endpoint")}
</InfoSectionTitle>
<InfoSectionContent>
<CopyToClipboard
text={env.app.dashboardUrl}
/>
</InfoSectionContent>
</InfoSection>
)}
<InfoSection>
<InfoSectionTitle>
{t("remoteExitNodeId")}
@@ -165,6 +152,21 @@ export default function CredentialsPage() {
</InfoSection>
</InfoSections>
{displaySecret && (
<div className="mt-4">
<CopyTextBox
text={`managed:
id: "${displayRemoteExitNodeId}"
secret: "${displaySecret}"${
showEndpoint
? `
endpoint: "${env.app.dashboardUrl}"`
: ""
}`}
/>
</div>
)}
{showCredentialsAlert && displaySecret && (
<Alert variant="neutral" className="mt-4">
<InfoIcon className="h-4 w-4" />
@@ -37,6 +37,7 @@ import { useParams, useRouter, useSearchParams } from "next/navigation";
import { useTranslations } from "next-intl";
import HeaderTitle from "@app/components/SettingsSectionTitle";
import { StrategySelect } from "@app/components/StrategySelect";
import { build } from "@server/build";
export default function CreateRemoteExitNodePage() {
const { env } = useEnvContext();
@@ -315,7 +316,12 @@ export default function CreateRemoteExitNodePage() {
<CopyTextBox
text={`managed:
id: "${defaults?.remoteExitNodeId}"
secret: "${defaults?.secret}"`}
secret: "${defaults?.secret}"${
build !== "saas"
? `
endpoint: "${env.app.dashboardUrl}"`
: ""
}`}
/>
</SettingsSectionBody>
</SettingsSection>