add optial disconnect on regenerate credentials

This commit is contained in:
miloschwartz
2025-12-06 12:36:31 -05:00
parent 00174be8c0
commit f449fdc7ec
7 changed files with 281 additions and 84 deletions

View File

@@ -31,7 +31,8 @@ const reGenerateSecretParamsSchema = z.strictObject({
const reGenerateSecretBodySchema = z.strictObject({
// olmId: z.string().min(1).optional(),
secret: z.string().min(1)
secret: z.string().min(1),
disconnect: z.boolean().optional().default(true)
});
export type ReGenerateSecretBody = z.infer<typeof reGenerateSecretBodySchema>;
@@ -52,7 +53,7 @@ export async function reGenerateClientSecret(
);
}
const { secret } = parsedBody.data;
const { secret, disconnect } = parsedBody.data;
const parsedParams = reGenerateSecretParamsSchema.safeParse(req.params);
if (!parsedParams.success) {
@@ -114,18 +115,21 @@ export async function reGenerateClientSecret(
})
.where(eq(olms.olmId, existingOlms[0].olmId));
const payload = {
type: `olm/terminate`,
data: {}
};
// Don't await this to prevent blocking the response
sendToClient(existingOlms[0].olmId, payload).catch((error) => {
logger.error("Failed to send termination message to olm:", error);
});
// Only disconnect if explicitly requested
if (disconnect) {
const payload = {
type: `olm/terminate`,
data: {}
};
// Don't await this to prevent blocking the response
sendToClient(existingOlms[0].olmId, payload).catch((error) => {
logger.error("Failed to send termination message to olm:", error);
});
disconnectClient(existingOlms[0].olmId).catch((error) => {
logger.error("Failed to disconnect olm after re-key:", error);
});
disconnectClient(existingOlms[0].olmId).catch((error) => {
logger.error("Failed to disconnect olm after re-key:", error);
});
}
return response(res, {
data: {

View File

@@ -23,7 +23,7 @@ import { hashPassword } from "@server/auth/password";
import logger from "@server/logger";
import { and, eq } from "drizzle-orm";
import { OpenAPITags, registry } from "@server/openApi";
import { disconnectClient } from "#private/routers/ws";
import { disconnectClient, sendToClient } from "#private/routers/ws";
export const paramsSchema = z.object({
orgId: z.string()
@@ -31,7 +31,8 @@ export const paramsSchema = z.object({
const bodySchema = z.strictObject({
remoteExitNodeId: z.string().length(15),
secret: z.string().length(48)
secret: z.string().length(48),
disconnect: z.boolean().optional().default(true)
});
export async function reGenerateExitNodeSecret(
@@ -60,7 +61,7 @@ export async function reGenerateExitNodeSecret(
);
}
const { remoteExitNodeId, secret } = parsedBody.data;
const { remoteExitNodeId, secret, disconnect } = parsedBody.data;
const [existingRemoteExitNode] = await db
.select()
@@ -83,11 +84,31 @@ export async function reGenerateExitNodeSecret(
.set({ secretHash })
.where(eq(remoteExitNodes.remoteExitNodeId, remoteExitNodeId));
disconnectClient(existingRemoteExitNode.remoteExitNodeId).catch(
(error) => {
logger.error("Failed to disconnect newt after re-key:", error);
}
);
// Only disconnect if explicitly requested
if (disconnect) {
const payload = {
type: `remoteExitNode/terminate`,
data: {}
};
// Don't await this to prevent blocking the response
sendToClient(existingRemoteExitNode.remoteExitNodeId, payload).catch(
(error) => {
logger.error(
"Failed to send termination message to remote exit node:",
error
);
}
);
disconnectClient(existingRemoteExitNode.remoteExitNodeId).catch(
(error) => {
logger.error(
"Failed to disconnect remote exit node after re-key:",
error
);
}
);
}
return response(res, {
data: null,

View File

@@ -33,7 +33,8 @@ const updateSiteParamsSchema = z.strictObject({
const updateSiteBodySchema = z.strictObject({
type: z.enum(["newt", "wireguard"]),
secret: z.string().min(1).max(255).optional(),
pubKey: z.string().optional()
pubKey: z.string().optional(),
disconnect: z.boolean().optional().default(true)
});
export async function reGenerateSiteSecret(
@@ -63,7 +64,7 @@ export async function reGenerateSiteSecret(
}
const { siteId } = parsedParams.data;
const { type, pubKey, secret } = parsedBody.data;
const { type, pubKey, secret, disconnect } = parsedBody.data;
let existingNewt: Newt | null = null;
if (type === "newt") {
@@ -112,21 +113,24 @@ export async function reGenerateSiteSecret(
})
.where(eq(newts.newtId, existingNewts[0].newtId));
const payload = {
type: `newt/wg/terminate`,
data: {}
};
// Don't await this to prevent blocking the response
sendToClient(existingNewts[0].newtId, payload).catch((error) => {
logger.error(
"Failed to send termination message to newt:",
error
);
});
// Only disconnect if explicitly requested
if (disconnect) {
const payload = {
type: `newt/wg/terminate`,
data: {}
};
// Don't await this to prevent blocking the response
sendToClient(existingNewts[0].newtId, payload).catch((error) => {
logger.error(
"Failed to send termination message to newt:",
error
);
});
disconnectClient(existingNewts[0].newtId).catch((error) => {
logger.error("Failed to disconnect newt after re-key:", error);
});
disconnectClient(existingNewts[0].newtId).catch((error) => {
logger.error("Failed to disconnect newt after re-key:", error);
});
}
logger.info(`Regenerated Newt credentials for site ${siteId}`);
} else if (type === "wireguard") {