mirror of
https://github.com/fosrl/pangolin.git
synced 2026-03-30 06:26:39 +00:00
🚧 edit niceid in private resources
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
import { Request, Response, NextFunction } from "express";
|
||||
import { z } from "zod";
|
||||
import { isLicensedOrSubscribed } from "#dynamic/lib/isLicencedOrSubscribed";
|
||||
import {
|
||||
clientSiteResources,
|
||||
clientSiteResourcesAssociationsCache,
|
||||
@@ -8,19 +7,13 @@ import {
|
||||
orgs,
|
||||
roles,
|
||||
roleSiteResources,
|
||||
SiteResource,
|
||||
siteResources,
|
||||
sites,
|
||||
Transaction,
|
||||
userSiteResources
|
||||
} from "@server/db";
|
||||
import { siteResources, SiteResource } from "@server/db";
|
||||
import response from "@server/lib/response";
|
||||
import HttpCode from "@server/types/HttpCode";
|
||||
import createHttpError from "http-errors";
|
||||
import { eq, and, ne } from "drizzle-orm";
|
||||
import { fromError } from "zod-validation-error";
|
||||
import logger from "@server/logger";
|
||||
import { OpenAPITags, registry } from "@server/openApi";
|
||||
import { updatePeerData, updateTargets } from "@server/routers/client/targets";
|
||||
import { tierMatrix } from "@server/lib/billing/tierMatrix";
|
||||
import {
|
||||
generateAliasConfig,
|
||||
generateRemoteSubnets,
|
||||
@@ -28,12 +21,17 @@ import {
|
||||
isIpInCidr,
|
||||
portRangeStringSchema
|
||||
} from "@server/lib/ip";
|
||||
import {
|
||||
getClientSiteResourceAccess,
|
||||
rebuildClientAssociationsFromSiteResource
|
||||
} from "@server/lib/rebuildClientAssociations";
|
||||
import { isLicensedOrSubscribed } from "#dynamic/lib/isLicencedOrSubscribed";
|
||||
import { tierMatrix } from "@server/lib/billing/tierMatrix";
|
||||
import { rebuildClientAssociationsFromSiteResource } from "@server/lib/rebuildClientAssociations";
|
||||
import response from "@server/lib/response";
|
||||
import logger from "@server/logger";
|
||||
import { OpenAPITags, registry } from "@server/openApi";
|
||||
import { updatePeerData, updateTargets } from "@server/routers/client/targets";
|
||||
import HttpCode from "@server/types/HttpCode";
|
||||
import { and, eq, ne } from "drizzle-orm";
|
||||
import { NextFunction, Request, Response } from "express";
|
||||
import createHttpError from "http-errors";
|
||||
import { z } from "zod";
|
||||
import { fromError } from "zod-validation-error";
|
||||
|
||||
const updateSiteResourceParamsSchema = z.strictObject({
|
||||
siteResourceId: z.string().transform(Number).pipe(z.int().positive())
|
||||
@@ -43,7 +41,15 @@ const updateSiteResourceSchema = z
|
||||
.strictObject({
|
||||
name: z.string().min(1).max(255).optional(),
|
||||
siteId: z.int(),
|
||||
// niceId: z.string().min(1).max(255).regex(/^[a-zA-Z0-9-]+$/, "niceId can only contain letters, numbers, and dashes").optional(),
|
||||
niceId: z
|
||||
.string()
|
||||
.min(1)
|
||||
.max(255)
|
||||
.regex(
|
||||
/^[a-zA-Z0-9-]+$/,
|
||||
"niceId can only contain letters, numbers, and dashes"
|
||||
)
|
||||
.optional(),
|
||||
// mode: z.enum(["host", "cidr", "port"]).optional(),
|
||||
mode: z.enum(["host", "cidr"]).optional(),
|
||||
// protocol: z.enum(["tcp", "udp"]).nullish(),
|
||||
@@ -167,6 +173,7 @@ export async function updateSiteResource(
|
||||
const {
|
||||
name,
|
||||
siteId, // because it can change
|
||||
niceId,
|
||||
mode,
|
||||
destination,
|
||||
alias,
|
||||
@@ -321,7 +328,8 @@ export async function updateSiteResource(
|
||||
|
||||
const sshPamSet =
|
||||
isLicensedSshPam &&
|
||||
(authDaemonPort !== undefined || authDaemonMode !== undefined)
|
||||
(authDaemonPort !== undefined ||
|
||||
authDaemonMode !== undefined)
|
||||
? {
|
||||
...(authDaemonPort !== undefined && {
|
||||
authDaemonPort
|
||||
@@ -334,15 +342,16 @@ export async function updateSiteResource(
|
||||
[updatedSiteResource] = await trx
|
||||
.update(siteResources)
|
||||
.set({
|
||||
name: name,
|
||||
siteId: siteId,
|
||||
mode: mode,
|
||||
destination: destination,
|
||||
enabled: enabled,
|
||||
name,
|
||||
siteId,
|
||||
niceId,
|
||||
mode,
|
||||
destination,
|
||||
enabled,
|
||||
alias: alias && alias.trim() ? alias : null,
|
||||
tcpPortRangeString: tcpPortRangeString,
|
||||
udpPortRangeString: udpPortRangeString,
|
||||
disableIcmp: disableIcmp,
|
||||
tcpPortRangeString,
|
||||
udpPortRangeString,
|
||||
disableIcmp,
|
||||
...sshPamSet
|
||||
})
|
||||
.where(
|
||||
@@ -423,7 +432,8 @@ export async function updateSiteResource(
|
||||
// Update the site resource
|
||||
const sshPamSet =
|
||||
isLicensedSshPam &&
|
||||
(authDaemonPort !== undefined || authDaemonMode !== undefined)
|
||||
(authDaemonPort !== undefined ||
|
||||
authDaemonMode !== undefined)
|
||||
? {
|
||||
...(authDaemonPort !== undefined && {
|
||||
authDaemonPort
|
||||
@@ -617,10 +627,14 @@ export async function handleMessagingForUpdatedSiteResource(
|
||||
mergedAllClients
|
||||
);
|
||||
|
||||
await updateTargets(newt.newtId, {
|
||||
oldTargets: oldTargets,
|
||||
newTargets: newTargets
|
||||
}, newt.version);
|
||||
await updateTargets(
|
||||
newt.newtId,
|
||||
{
|
||||
oldTargets: oldTargets,
|
||||
newTargets: newTargets
|
||||
},
|
||||
newt.version
|
||||
);
|
||||
}
|
||||
|
||||
const olmJobs: Promise<void>[] = [];
|
||||
|
||||
@@ -18,7 +18,7 @@ import { resourceQueries } from "@app/lib/queries";
|
||||
import { ListSitesResponse } from "@server/routers/site";
|
||||
import { useQueryClient } from "@tanstack/react-query";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useState } from "react";
|
||||
import { useState, useTransition } from "react";
|
||||
import {
|
||||
cleanForFQDN,
|
||||
InternalResourceForm,
|
||||
@@ -49,10 +49,9 @@ export default function EditInternalResourceDialog({
|
||||
const t = useTranslations();
|
||||
const api = createApiClient(useEnvContext());
|
||||
const queryClient = useQueryClient();
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
const [isSubmitting, startTransition] = useTransition();
|
||||
|
||||
async function handleSubmit(values: InternalResourceFormValues) {
|
||||
setIsSubmitting(true);
|
||||
try {
|
||||
let data = { ...values };
|
||||
if (data.mode === "host" && isHostname(data.destination)) {
|
||||
@@ -70,6 +69,7 @@ export default function EditInternalResourceDialog({
|
||||
name: data.name,
|
||||
siteId: data.siteId,
|
||||
mode: data.mode,
|
||||
niceId: data.niceId,
|
||||
destination: data.destination,
|
||||
alias:
|
||||
data.alias &&
|
||||
@@ -127,8 +127,6 @@ export default function EditInternalResourceDialog({
|
||||
),
|
||||
variant: "destructive"
|
||||
});
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,7 +160,9 @@ export default function EditInternalResourceDialog({
|
||||
orgId={orgId}
|
||||
siteResourceId={resource.id}
|
||||
formId="edit-internal-resource-form"
|
||||
onSubmit={handleSubmit}
|
||||
onSubmit={(values) =>
|
||||
startTransition(() => handleSubmit(values))
|
||||
}
|
||||
/>
|
||||
</CredenzaBody>
|
||||
<CredenzaFooter>
|
||||
|
||||
@@ -132,6 +132,7 @@ export type InternalResourceData = {
|
||||
siteName: string;
|
||||
mode: "host" | "cidr";
|
||||
siteId: number;
|
||||
niceId: string;
|
||||
destination: string;
|
||||
alias?: string | null;
|
||||
tcpPortRangeString?: string | null;
|
||||
@@ -149,6 +150,7 @@ export type InternalResourceFormValues = {
|
||||
mode: "host" | "cidr";
|
||||
destination: string;
|
||||
alias?: string | null;
|
||||
niceId?: string;
|
||||
tcpPortRangeString?: string | null;
|
||||
udpPortRangeString?: string | null;
|
||||
disableIcmp?: boolean;
|
||||
@@ -243,6 +245,12 @@ export function InternalResourceForm({
|
||||
: undefined
|
||||
),
|
||||
alias: z.string().nullish(),
|
||||
niceId: z
|
||||
.string()
|
||||
.min(1)
|
||||
.max(255)
|
||||
.regex(/^[a-zA-Z0-9-]+$/)
|
||||
.optional(),
|
||||
tcpPortRangeString: createPortRangeStringSchema(t),
|
||||
udpPortRangeString: createPortRangeStringSchema(t),
|
||||
disableIcmp: z.boolean().optional(),
|
||||
@@ -387,6 +395,7 @@ export function InternalResourceForm({
|
||||
disableIcmp: resource.disableIcmp ?? false,
|
||||
authDaemonMode: resource.authDaemonMode ?? "site",
|
||||
authDaemonPort: resource.authDaemonPort ?? null,
|
||||
niceId: resource.niceId,
|
||||
roles: [],
|
||||
users: [],
|
||||
clients: []
|
||||
@@ -534,7 +543,7 @@ export function InternalResourceForm({
|
||||
className="space-y-6"
|
||||
id={formId}
|
||||
>
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div className="grid gap-4">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="name"
|
||||
@@ -548,6 +557,19 @@ export function InternalResourceForm({
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="niceId"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>{t("identifier")}</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="siteId"
|
||||
|
||||
Reference in New Issue
Block a user