Merge branch 'dev' into feat/option-to-regenerate-keys

This commit is contained in:
Owen
2025-11-09 10:43:26 -08:00
40 changed files with 1669 additions and 1313 deletions

View File

@@ -37,6 +37,7 @@ const updateResourceParamsSchema = z
const updateHttpResourceBodySchema = z
.object({
name: z.string().min(1).max(255).optional(),
niceId: z.string().min(1).max(255).optional(),
subdomain: subdomainSchema.nullable().optional(),
ssl: z.boolean().optional(),
sso: z.boolean().optional(),
@@ -97,6 +98,7 @@ export type UpdateResourceResponse = Resource;
const updateRawResourceBodySchema = z
.object({
name: z.string().min(1).max(255).optional(),
niceId: z.string().min(1).max(255).optional(),
proxyPort: z.number().int().min(1).max(65535).optional(),
stickySession: z.boolean().optional(),
enabled: z.boolean().optional(),
@@ -236,6 +238,30 @@ async function updateHttpResource(
const updateData = parsedBody.data;
if (updateData.niceId) {
const [existingResource] = await db
.select()
.from(resources)
.where(
and(
eq(resources.niceId, updateData.niceId),
eq(resources.orgId, resource.orgId)
)
);
if (
existingResource &&
existingResource.resourceId !== resource.resourceId
) {
return next(
createHttpError(
HttpCode.CONFLICT,
`A resource with niceId "${updateData.niceId}" already exists`
)
);
}
}
if (updateData.domainId) {
const domainId = updateData.domainId;
@@ -362,6 +388,30 @@ async function updateRawResource(
const updateData = parsedBody.data;
if (updateData.niceId) {
const [existingResource] = await db
.select()
.from(resources)
.where(
and(
eq(resources.niceId, updateData.niceId),
eq(resources.orgId, resource.orgId)
)
);
if (
existingResource &&
existingResource.resourceId !== resource.resourceId
) {
return next(
createHttpError(
HttpCode.CONFLICT,
`A resource with niceId "${updateData.niceId}" already exists`
)
);
}
}
const updatedResource = await db
.update(resources)
.set(updateData)

View File

@@ -2,7 +2,7 @@ import { Request, Response, NextFunction } from "express";
import { z } from "zod";
import { db } from "@server/db";
import { sites } from "@server/db";
import { eq } from "drizzle-orm";
import { eq, and } from "drizzle-orm";
import response from "@server/lib/response";
import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors";
@@ -20,6 +20,7 @@ const updateSiteParamsSchema = z
const updateSiteBodySchema = z
.object({
name: z.string().min(1).max(255).optional(),
niceId: z.string().min(1).max(255).optional(),
dockerSocketEnabled: z.boolean().optional(),
remoteSubnets: z
.string()
@@ -89,6 +90,29 @@ export async function updateSite(
const { siteId } = parsedParams.data;
const updateData = parsedBody.data;
// if niceId is provided, check if it's already in use by another site
if (updateData.niceId) {
const existingSite = await db
.select()
.from(sites)
.where(
and(
eq(sites.niceId, updateData.niceId),
eq(sites.orgId, sites.orgId)
)
)
.limit(1);
if (existingSite.length > 0 && existingSite[0].siteId !== siteId) {
return next(
createHttpError(
HttpCode.CONFLICT,
`A site with niceId "${updateData.niceId}" already exists`
)
);
}
}
// if remoteSubnets is provided, ensure it's a valid comma-separated list of cidrs
if (updateData.remoteSubnets) {
const subnets = updateData.remoteSubnets.split(",").map((s) => s.trim());

View File

@@ -163,12 +163,8 @@ export async function createTarget(
);
if (existingTarget) {
return next(
createHttpError(
HttpCode.BAD_REQUEST,
`Target with IP ${targetData.ip}, port ${targetData.port}, method ${targetData.method} already exists for resource ID ${resourceId}`
)
);
// log a warning
logger.warn(`Target with IP ${targetData.ip}, port ${targetData.port}, method ${targetData.method} already exists for resource ID ${resourceId}`);
}
let newTarget: Target[] = [];

View File

@@ -48,12 +48,10 @@ export async function deleteTarget(
const { targetId } = parsedParams.data;
const [deletedTarget] = await db.transaction(async (tx) => {
return await tx
.delete(targets)
.where(eq(targets.targetId, targetId))
.returning();
});
const [deletedTarget] = await db
.delete(targets)
.where(eq(targets.targetId, targetId))
.returning();
if (!deletedTarget) {
return next(

View File

@@ -170,12 +170,8 @@ export async function updateTarget(
);
if (foundTarget) {
return next(
createHttpError(
HttpCode.BAD_REQUEST,
`Target with IP ${targetData.ip}, port ${targetData.port}, and method ${targetData.method} already exists on the same site.`
)
);
// log a warning
logger.warn(`Target with IP ${targetData.ip}, port ${targetData.port}, method ${targetData.method} already exists for resource ID ${target.resourceId}`);
}
const { internalPort, targetIps } = await pickPort(site.siteId!, db);