mirror of
https://github.com/fosrl/pangolin.git
synced 2026-04-10 11:56:36 +00:00
add new modes, port input, and domain picker
This commit is contained in:
@@ -1817,6 +1817,8 @@
|
|||||||
"editInternalResourceDialogModePort": "Port",
|
"editInternalResourceDialogModePort": "Port",
|
||||||
"editInternalResourceDialogModeHost": "Host",
|
"editInternalResourceDialogModeHost": "Host",
|
||||||
"editInternalResourceDialogModeCidr": "CIDR",
|
"editInternalResourceDialogModeCidr": "CIDR",
|
||||||
|
"editInternalResourceDialogModeHttp": "HTTP",
|
||||||
|
"editInternalResourceDialogModeHttps": "HTTPS",
|
||||||
"editInternalResourceDialogDestination": "Destination",
|
"editInternalResourceDialogDestination": "Destination",
|
||||||
"editInternalResourceDialogDestinationHostDescription": "The IP address or hostname of the resource on the site's network.",
|
"editInternalResourceDialogDestinationHostDescription": "The IP address or hostname of the resource on the site's network.",
|
||||||
"editInternalResourceDialogDestinationIPDescription": "The IP or hostname address of the resource on the site's network.",
|
"editInternalResourceDialogDestinationIPDescription": "The IP or hostname address of the resource on the site's network.",
|
||||||
@@ -1860,6 +1862,8 @@
|
|||||||
"createInternalResourceDialogModePort": "Port",
|
"createInternalResourceDialogModePort": "Port",
|
||||||
"createInternalResourceDialogModeHost": "Host",
|
"createInternalResourceDialogModeHost": "Host",
|
||||||
"createInternalResourceDialogModeCidr": "CIDR",
|
"createInternalResourceDialogModeCidr": "CIDR",
|
||||||
|
"createInternalResourceDialogModeHttp": "HTTP",
|
||||||
|
"createInternalResourceDialogModeHttps": "HTTPS",
|
||||||
"createInternalResourceDialogDestination": "Destination",
|
"createInternalResourceDialogDestination": "Destination",
|
||||||
"createInternalResourceDialogDestinationHostDescription": "The IP address or hostname of the resource on the site's network.",
|
"createInternalResourceDialogDestinationHostDescription": "The IP address or hostname of the resource on the site's network.",
|
||||||
"createInternalResourceDialogDestinationCidrDescription": "The CIDR range of the resource on the site's network.",
|
"createInternalResourceDialogDestinationCidrDescription": "The CIDR range of the resource on the site's network.",
|
||||||
@@ -2661,6 +2665,10 @@
|
|||||||
"editInternalResourceDialogDestinationLabel": "Destination",
|
"editInternalResourceDialogDestinationLabel": "Destination",
|
||||||
"editInternalResourceDialogDestinationDescription": "Specify the destination address for the internal resource. This can be a hostname, IP address, or CIDR range depending on the selected mode. Optionally set an internal DNS alias for easier identification.",
|
"editInternalResourceDialogDestinationDescription": "Specify the destination address for the internal resource. This can be a hostname, IP address, or CIDR range depending on the selected mode. Optionally set an internal DNS alias for easier identification.",
|
||||||
"editInternalResourceDialogPortRestrictionsDescription": "Restrict access to specific TCP/UDP ports or allow/block all ports.",
|
"editInternalResourceDialogPortRestrictionsDescription": "Restrict access to specific TCP/UDP ports or allow/block all ports.",
|
||||||
|
"createInternalResourceDialogHttpConfiguration": "HTTP configuration",
|
||||||
|
"createInternalResourceDialogHttpConfigurationDescription": "Choose the domain clients will use to reach this resource over HTTP or HTTPS.",
|
||||||
|
"editInternalResourceDialogHttpConfiguration": "HTTP configuration",
|
||||||
|
"editInternalResourceDialogHttpConfigurationDescription": "Choose the domain clients will use to reach this resource over HTTP or HTTPS.",
|
||||||
"editInternalResourceDialogTcp": "TCP",
|
"editInternalResourceDialogTcp": "TCP",
|
||||||
"editInternalResourceDialogUdp": "UDP",
|
"editInternalResourceDialogUdp": "UDP",
|
||||||
"editInternalResourceDialogIcmp": "ICMP",
|
"editInternalResourceDialogIcmp": "ICMP",
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ const createSiteResourceParamsSchema = z.strictObject({
|
|||||||
const createSiteResourceSchema = z
|
const createSiteResourceSchema = z
|
||||||
.strictObject({
|
.strictObject({
|
||||||
name: z.string().min(1).max(255),
|
name: z.string().min(1).max(255),
|
||||||
mode: z.enum(["host", "cidr", "port", "http", "https"]),
|
mode: z.enum(["host", "cidr", "http", "https"]),
|
||||||
siteId: z.int(),
|
siteId: z.int(),
|
||||||
// protocol: z.enum(["tcp", "udp"]).optional(),
|
// protocol: z.enum(["tcp", "udp"]).optional(),
|
||||||
// proxyPort: z.int().positive().optional(),
|
// proxyPort: z.int().positive().optional(),
|
||||||
@@ -286,8 +286,7 @@ export async function createSiteResource(
|
|||||||
|
|
||||||
const niceId = await getUniqueSiteResourceName(orgId);
|
const niceId = await getUniqueSiteResourceName(orgId);
|
||||||
let aliasAddress: string | null = null;
|
let aliasAddress: string | null = null;
|
||||||
if (mode == "host") {
|
if (mode === "host" || mode === "http" || mode === "https") {
|
||||||
// we can only have an alias on a host
|
|
||||||
aliasAddress = await getNextAvailableAliasAddress(orgId);
|
aliasAddress = await getNextAvailableAliasAddress(orgId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -299,7 +298,7 @@ export async function createSiteResource(
|
|||||||
niceId,
|
niceId,
|
||||||
orgId,
|
orgId,
|
||||||
name,
|
name,
|
||||||
mode: mode as "host" | "cidr",
|
mode,
|
||||||
destination,
|
destination,
|
||||||
destinationPort,
|
destinationPort,
|
||||||
enabled,
|
enabled,
|
||||||
|
|||||||
@@ -41,12 +41,12 @@ const listAllSiteResourcesByOrgQuerySchema = z.object({
|
|||||||
}),
|
}),
|
||||||
query: z.string().optional(),
|
query: z.string().optional(),
|
||||||
mode: z
|
mode: z
|
||||||
.enum(["host", "cidr"])
|
.enum(["host", "cidr", "http", "https"])
|
||||||
.optional()
|
.optional()
|
||||||
.catch(undefined)
|
.catch(undefined)
|
||||||
.openapi({
|
.openapi({
|
||||||
type: "string",
|
type: "string",
|
||||||
enum: ["host", "cidr"],
|
enum: ["host", "cidr", "http", "https"],
|
||||||
description: "Filter site resources by mode"
|
description: "Filter site resources by mode"
|
||||||
}),
|
}),
|
||||||
sort_by: z
|
sort_by: z
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ export type InternalResourceRow = {
|
|||||||
siteName: string;
|
siteName: string;
|
||||||
siteAddress: string | null;
|
siteAddress: string | null;
|
||||||
// mode: "host" | "cidr" | "port";
|
// mode: "host" | "cidr" | "port";
|
||||||
mode: "host" | "cidr";
|
mode: "host" | "cidr" | "http" | "https";
|
||||||
// protocol: string | null;
|
// protocol: string | null;
|
||||||
// proxyPort: number | null;
|
// proxyPort: number | null;
|
||||||
siteId: number;
|
siteId: number;
|
||||||
@@ -215,6 +215,14 @@ export default function ClientResourcesTable({
|
|||||||
{
|
{
|
||||||
value: "cidr",
|
value: "cidr",
|
||||||
label: t("editInternalResourceDialogModeCidr")
|
label: t("editInternalResourceDialogModeCidr")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "http",
|
||||||
|
label: t("editInternalResourceDialogModeHttp")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "https",
|
||||||
|
label: t("editInternalResourceDialogModeHttps")
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
selectedValue={searchParams.get("mode") ?? undefined}
|
selectedValue={searchParams.get("mode") ?? undefined}
|
||||||
@@ -227,10 +235,15 @@ export default function ClientResourcesTable({
|
|||||||
),
|
),
|
||||||
cell: ({ row }) => {
|
cell: ({ row }) => {
|
||||||
const resourceRow = row.original;
|
const resourceRow = row.original;
|
||||||
const modeLabels: Record<"host" | "cidr" | "port", string> = {
|
const modeLabels: Record<
|
||||||
|
"host" | "cidr" | "port" | "http" | "https",
|
||||||
|
string
|
||||||
|
> = {
|
||||||
host: t("editInternalResourceDialogModeHost"),
|
host: t("editInternalResourceDialogModeHost"),
|
||||||
cidr: t("editInternalResourceDialogModeCidr"),
|
cidr: t("editInternalResourceDialogModeCidr"),
|
||||||
port: t("editInternalResourceDialogModePort")
|
port: t("editInternalResourceDialogModePort"),
|
||||||
|
http: t("editInternalResourceDialogModeHttp"),
|
||||||
|
https: t("editInternalResourceDialogModeHttps")
|
||||||
};
|
};
|
||||||
return <span>{modeLabels[resourceRow.mode]}</span>;
|
return <span>{modeLabels[resourceRow.mode]}</span>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,12 @@ export default function CreateInternalResourceDialog({
|
|||||||
setIsSubmitting(true);
|
setIsSubmitting(true);
|
||||||
try {
|
try {
|
||||||
let data = { ...values };
|
let data = { ...values };
|
||||||
if (data.mode === "host" && isHostname(data.destination)) {
|
if (
|
||||||
|
(data.mode === "host" ||
|
||||||
|
data.mode === "http" ||
|
||||||
|
data.mode === "https") &&
|
||||||
|
isHostname(data.destination)
|
||||||
|
) {
|
||||||
const currentAlias = data.alias?.trim() || "";
|
const currentAlias = data.alias?.trim() || "";
|
||||||
if (!currentAlias) {
|
if (!currentAlias) {
|
||||||
let aliasValue = data.destination;
|
let aliasValue = data.destination;
|
||||||
|
|||||||
@@ -54,7 +54,12 @@ export default function EditInternalResourceDialog({
|
|||||||
async function handleSubmit(values: InternalResourceFormValues) {
|
async function handleSubmit(values: InternalResourceFormValues) {
|
||||||
try {
|
try {
|
||||||
let data = { ...values };
|
let data = { ...values };
|
||||||
if (data.mode === "host" && isHostname(data.destination)) {
|
if (
|
||||||
|
(data.mode === "host" ||
|
||||||
|
data.mode === "http" ||
|
||||||
|
data.mode === "https") &&
|
||||||
|
isHostname(data.destination)
|
||||||
|
) {
|
||||||
const currentAlias = data.alias?.trim() || "";
|
const currentAlias = data.alias?.trim() || "";
|
||||||
if (!currentAlias) {
|
if (!currentAlias) {
|
||||||
let aliasValue = data.destination;
|
let aliasValue = data.destination;
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ import { z } from "zod";
|
|||||||
import { SitesSelector, type Selectedsite } from "./site-selector";
|
import { SitesSelector, type Selectedsite } from "./site-selector";
|
||||||
import { CaretSortIcon } from "@radix-ui/react-icons";
|
import { CaretSortIcon } from "@radix-ui/react-icons";
|
||||||
import { MachinesSelector } from "./machines-selector";
|
import { MachinesSelector } from "./machines-selector";
|
||||||
|
import DomainPicker from "@app/components/DomainPicker";
|
||||||
|
|
||||||
// --- Helpers (shared) ---
|
// --- Helpers (shared) ---
|
||||||
|
|
||||||
@@ -120,12 +121,14 @@ export const cleanForFQDN = (name: string): string =>
|
|||||||
|
|
||||||
type Site = ListSitesResponse["sites"][0];
|
type Site = ListSitesResponse["sites"][0];
|
||||||
|
|
||||||
|
export type InternalResourceMode = "host" | "cidr" | "http" | "https";
|
||||||
|
|
||||||
export type InternalResourceData = {
|
export type InternalResourceData = {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
orgId: string;
|
orgId: string;
|
||||||
siteName: string;
|
siteName: string;
|
||||||
mode: "host" | "cidr";
|
mode: InternalResourceMode;
|
||||||
siteId: number;
|
siteId: number;
|
||||||
niceId: string;
|
niceId: string;
|
||||||
destination: string;
|
destination: string;
|
||||||
@@ -135,6 +138,10 @@ export type InternalResourceData = {
|
|||||||
disableIcmp?: boolean;
|
disableIcmp?: boolean;
|
||||||
authDaemonMode?: "site" | "remote" | null;
|
authDaemonMode?: "site" | "remote" | null;
|
||||||
authDaemonPort?: number | null;
|
authDaemonPort?: number | null;
|
||||||
|
httpHttpsPort?: number | null;
|
||||||
|
httpConfigSubdomain?: string | null;
|
||||||
|
httpConfigDomainId?: string | null;
|
||||||
|
httpConfigFullDomain?: string | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
const tagSchema = z.object({ id: z.string(), text: z.string() });
|
const tagSchema = z.object({ id: z.string(), text: z.string() });
|
||||||
@@ -142,7 +149,7 @@ const tagSchema = z.object({ id: z.string(), text: z.string() });
|
|||||||
export type InternalResourceFormValues = {
|
export type InternalResourceFormValues = {
|
||||||
name: string;
|
name: string;
|
||||||
siteId: number;
|
siteId: number;
|
||||||
mode: "host" | "cidr";
|
mode: InternalResourceMode;
|
||||||
destination: string;
|
destination: string;
|
||||||
alias?: string | null;
|
alias?: string | null;
|
||||||
niceId?: string;
|
niceId?: string;
|
||||||
@@ -151,6 +158,10 @@ export type InternalResourceFormValues = {
|
|||||||
disableIcmp?: boolean;
|
disableIcmp?: boolean;
|
||||||
authDaemonMode?: "site" | "remote" | null;
|
authDaemonMode?: "site" | "remote" | null;
|
||||||
authDaemonPort?: number | null;
|
authDaemonPort?: number | null;
|
||||||
|
httpHttpsPort?: number | null;
|
||||||
|
httpConfigSubdomain?: string | null;
|
||||||
|
httpConfigDomainId?: string | null;
|
||||||
|
httpConfigFullDomain?: string | null;
|
||||||
roles?: z.infer<typeof tagSchema>[];
|
roles?: z.infer<typeof tagSchema>[];
|
||||||
users?: z.infer<typeof tagSchema>[];
|
users?: z.infer<typeof tagSchema>[];
|
||||||
clients?: z.infer<typeof tagSchema>[];
|
clients?: z.infer<typeof tagSchema>[];
|
||||||
@@ -211,6 +222,14 @@ export function InternalResourceForm({
|
|||||||
variant === "create"
|
variant === "create"
|
||||||
? "createInternalResourceDialogModeCidr"
|
? "createInternalResourceDialogModeCidr"
|
||||||
: "editInternalResourceDialogModeCidr";
|
: "editInternalResourceDialogModeCidr";
|
||||||
|
const modeHttpKey =
|
||||||
|
variant === "create"
|
||||||
|
? "createInternalResourceDialogModeHttp"
|
||||||
|
: "editInternalResourceDialogModeHttp";
|
||||||
|
const modeHttpsKey =
|
||||||
|
variant === "create"
|
||||||
|
? "createInternalResourceDialogModeHttps"
|
||||||
|
: "editInternalResourceDialogModeHttps";
|
||||||
const destinationLabelKey =
|
const destinationLabelKey =
|
||||||
variant === "create"
|
variant === "create"
|
||||||
? "createInternalResourceDialogDestination"
|
? "createInternalResourceDialogDestination"
|
||||||
@@ -223,6 +242,18 @@ export function InternalResourceForm({
|
|||||||
variant === "create"
|
variant === "create"
|
||||||
? "createInternalResourceDialogAlias"
|
? "createInternalResourceDialogAlias"
|
||||||
: "editInternalResourceDialogAlias";
|
: "editInternalResourceDialogAlias";
|
||||||
|
const httpHttpsPortLabelKey =
|
||||||
|
variant === "create"
|
||||||
|
? "createInternalResourceDialogModePort"
|
||||||
|
: "editInternalResourceDialogModePort";
|
||||||
|
const httpConfigurationTitleKey =
|
||||||
|
variant === "create"
|
||||||
|
? "createInternalResourceDialogHttpConfiguration"
|
||||||
|
: "editInternalResourceDialogHttpConfiguration";
|
||||||
|
const httpConfigurationDescriptionKey =
|
||||||
|
variant === "create"
|
||||||
|
? "createInternalResourceDialogHttpConfigurationDescription"
|
||||||
|
: "editInternalResourceDialogHttpConfigurationDescription";
|
||||||
|
|
||||||
const formSchema = z.object({
|
const formSchema = z.object({
|
||||||
name: z.string().min(1, t(nameRequiredKey)).max(255, t(nameMaxKey)),
|
name: z.string().min(1, t(nameRequiredKey)).max(255, t(nameMaxKey)),
|
||||||
@@ -230,7 +261,7 @@ export function InternalResourceForm({
|
|||||||
.number()
|
.number()
|
||||||
.int()
|
.int()
|
||||||
.positive(siteRequiredKey ? t(siteRequiredKey) : undefined),
|
.positive(siteRequiredKey ? t(siteRequiredKey) : undefined),
|
||||||
mode: z.enum(["host", "cidr"]),
|
mode: z.enum(["host", "cidr", "http", "https"]),
|
||||||
destination: z
|
destination: z
|
||||||
.string()
|
.string()
|
||||||
.min(
|
.min(
|
||||||
@@ -240,6 +271,10 @@ export function InternalResourceForm({
|
|||||||
: undefined
|
: undefined
|
||||||
),
|
),
|
||||||
alias: z.string().nullish(),
|
alias: z.string().nullish(),
|
||||||
|
httpHttpsPort: z.number().int().min(1).max(65535).optional().nullable(),
|
||||||
|
httpConfigSubdomain: z.string().nullish(),
|
||||||
|
httpConfigDomainId: z.string().nullish(),
|
||||||
|
httpConfigFullDomain: z.string().nullish(),
|
||||||
niceId: z
|
niceId: z
|
||||||
.string()
|
.string()
|
||||||
.min(1)
|
.min(1)
|
||||||
@@ -394,6 +429,10 @@ export function InternalResourceForm({
|
|||||||
disableIcmp: resource.disableIcmp ?? false,
|
disableIcmp: resource.disableIcmp ?? false,
|
||||||
authDaemonMode: resource.authDaemonMode ?? "site",
|
authDaemonMode: resource.authDaemonMode ?? "site",
|
||||||
authDaemonPort: resource.authDaemonPort ?? null,
|
authDaemonPort: resource.authDaemonPort ?? null,
|
||||||
|
httpHttpsPort: resource.httpHttpsPort ?? null,
|
||||||
|
httpConfigSubdomain: resource.httpConfigSubdomain ?? null,
|
||||||
|
httpConfigDomainId: resource.httpConfigDomainId ?? null,
|
||||||
|
httpConfigFullDomain: resource.httpConfigFullDomain ?? null,
|
||||||
niceId: resource.niceId,
|
niceId: resource.niceId,
|
||||||
roles: [],
|
roles: [],
|
||||||
users: [],
|
users: [],
|
||||||
@@ -405,6 +444,10 @@ export function InternalResourceForm({
|
|||||||
mode: "host",
|
mode: "host",
|
||||||
destination: "",
|
destination: "",
|
||||||
alias: null,
|
alias: null,
|
||||||
|
httpHttpsPort: null,
|
||||||
|
httpConfigSubdomain: null,
|
||||||
|
httpConfigDomainId: null,
|
||||||
|
httpConfigFullDomain: null,
|
||||||
tcpPortRangeString: "*",
|
tcpPortRangeString: "*",
|
||||||
udpPortRangeString: "*",
|
udpPortRangeString: "*",
|
||||||
disableIcmp: false,
|
disableIcmp: false,
|
||||||
@@ -425,6 +468,10 @@ export function InternalResourceForm({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const mode = form.watch("mode");
|
const mode = form.watch("mode");
|
||||||
|
const httpConfigSubdomain = form.watch("httpConfigSubdomain");
|
||||||
|
const httpConfigDomainId = form.watch("httpConfigDomainId");
|
||||||
|
const httpConfigFullDomain = form.watch("httpConfigFullDomain");
|
||||||
|
const isHttpOrHttps = mode === "http" || mode === "https";
|
||||||
const authDaemonMode = form.watch("authDaemonMode") ?? "site";
|
const authDaemonMode = form.watch("authDaemonMode") ?? "site";
|
||||||
const hasInitialized = useRef(false);
|
const hasInitialized = useRef(false);
|
||||||
const previousResourceId = useRef<number | null>(null);
|
const previousResourceId = useRef<number | null>(null);
|
||||||
@@ -448,6 +495,10 @@ export function InternalResourceForm({
|
|||||||
mode: "host",
|
mode: "host",
|
||||||
destination: "",
|
destination: "",
|
||||||
alias: null,
|
alias: null,
|
||||||
|
httpHttpsPort: null,
|
||||||
|
httpConfigSubdomain: null,
|
||||||
|
httpConfigDomainId: null,
|
||||||
|
httpConfigFullDomain: null,
|
||||||
tcpPortRangeString: "*",
|
tcpPortRangeString: "*",
|
||||||
udpPortRangeString: "*",
|
udpPortRangeString: "*",
|
||||||
disableIcmp: false,
|
disableIcmp: false,
|
||||||
@@ -475,6 +526,10 @@ export function InternalResourceForm({
|
|||||||
mode: resource.mode ?? "host",
|
mode: resource.mode ?? "host",
|
||||||
destination: resource.destination ?? "",
|
destination: resource.destination ?? "",
|
||||||
alias: resource.alias ?? null,
|
alias: resource.alias ?? null,
|
||||||
|
httpHttpsPort: resource.httpHttpsPort ?? null,
|
||||||
|
httpConfigSubdomain: resource.httpConfigSubdomain ?? null,
|
||||||
|
httpConfigDomainId: resource.httpConfigDomainId ?? null,
|
||||||
|
httpConfigFullDomain: resource.httpConfigFullDomain ?? null,
|
||||||
tcpPortRangeString: resource.tcpPortRangeString ?? "*",
|
tcpPortRangeString: resource.tcpPortRangeString ?? "*",
|
||||||
udpPortRangeString: resource.udpPortRangeString ?? "*",
|
udpPortRangeString: resource.udpPortRangeString ?? "*",
|
||||||
disableIcmp: resource.disableIcmp ?? false,
|
disableIcmp: resource.disableIcmp ?? false,
|
||||||
@@ -701,6 +756,12 @@ export function InternalResourceForm({
|
|||||||
<SelectItem value="cidr">
|
<SelectItem value="cidr">
|
||||||
{t(modeCidrKey)}
|
{t(modeCidrKey)}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
|
<SelectItem value="http">
|
||||||
|
{t(modeHttpKey)}
|
||||||
|
</SelectItem>
|
||||||
|
<SelectItem value="https">
|
||||||
|
{t(modeHttpsKey)}
|
||||||
|
</SelectItem>
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
@@ -731,7 +792,7 @@ export function InternalResourceForm({
|
|||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{mode !== "cidr" && (
|
{mode === "host" && (
|
||||||
<div className="col-span-4">
|
<div className="col-span-4">
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
@@ -756,9 +817,120 @@ export function InternalResourceForm({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
{(mode === "http" || mode === "https") && (
|
||||||
|
<div className="col-span-4">
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="httpHttpsPort"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>
|
||||||
|
{t(
|
||||||
|
httpHttpsPortLabelKey
|
||||||
|
)}
|
||||||
|
</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input
|
||||||
|
type="number"
|
||||||
|
min={1}
|
||||||
|
max={65535}
|
||||||
|
value={
|
||||||
|
field.value ??
|
||||||
|
""
|
||||||
|
}
|
||||||
|
onChange={(e) => {
|
||||||
|
const raw =
|
||||||
|
e.target
|
||||||
|
.value;
|
||||||
|
if (
|
||||||
|
raw === ""
|
||||||
|
) {
|
||||||
|
field.onChange(
|
||||||
|
null
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const n =
|
||||||
|
Number(raw);
|
||||||
|
field.onChange(
|
||||||
|
Number.isFinite(
|
||||||
|
n
|
||||||
|
)
|
||||||
|
? n
|
||||||
|
: null
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{isHttpOrHttps ? (
|
||||||
|
<div className="space-y-4">
|
||||||
|
<div className="my-8">
|
||||||
|
<label className="font-medium block">
|
||||||
|
{t(httpConfigurationTitleKey)}
|
||||||
|
</label>
|
||||||
|
<div className="text-sm text-muted-foreground">
|
||||||
|
{t(httpConfigurationDescriptionKey)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<DomainPicker
|
||||||
|
key={
|
||||||
|
variant === "edit" && siteResourceId
|
||||||
|
? `http-domain-${siteResourceId}`
|
||||||
|
: "http-domain-create"
|
||||||
|
}
|
||||||
|
orgId={orgId}
|
||||||
|
cols={2}
|
||||||
|
hideFreeDomain
|
||||||
|
defaultSubdomain={
|
||||||
|
httpConfigSubdomain ?? undefined
|
||||||
|
}
|
||||||
|
defaultDomainId={
|
||||||
|
httpConfigDomainId ?? undefined
|
||||||
|
}
|
||||||
|
defaultFullDomain={
|
||||||
|
httpConfigFullDomain ?? undefined
|
||||||
|
}
|
||||||
|
onDomainChange={(res) => {
|
||||||
|
if (res === null) {
|
||||||
|
form.setValue(
|
||||||
|
"httpConfigSubdomain",
|
||||||
|
null
|
||||||
|
);
|
||||||
|
form.setValue(
|
||||||
|
"httpConfigDomainId",
|
||||||
|
null
|
||||||
|
);
|
||||||
|
form.setValue(
|
||||||
|
"httpConfigFullDomain",
|
||||||
|
null
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
form.setValue(
|
||||||
|
"httpConfigSubdomain",
|
||||||
|
res.subdomain ?? null
|
||||||
|
);
|
||||||
|
form.setValue(
|
||||||
|
"httpConfigDomainId",
|
||||||
|
res.domainId
|
||||||
|
);
|
||||||
|
form.setValue(
|
||||||
|
"httpConfigFullDomain",
|
||||||
|
res.fullDomain
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<div className="my-8">
|
<div className="my-8">
|
||||||
<label className="font-medium block">
|
<label className="font-medium block">
|
||||||
@@ -806,7 +978,11 @@ export function InternalResourceForm({
|
|||||||
value={tcpPortMode}
|
value={tcpPortMode}
|
||||||
onValueChange={(
|
onValueChange={(
|
||||||
v: PortMode
|
v: PortMode
|
||||||
) => setTcpPortMode(v)}
|
) =>
|
||||||
|
setTcpPortMode(
|
||||||
|
v
|
||||||
|
)
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<SelectTrigger className="w-[110px]">
|
<SelectTrigger className="w-[110px]">
|
||||||
@@ -815,13 +991,19 @@ export function InternalResourceForm({
|
|||||||
</FormControl>
|
</FormControl>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
<SelectItem value="all">
|
<SelectItem value="all">
|
||||||
{t("allPorts")}
|
{t(
|
||||||
|
"allPorts"
|
||||||
|
)}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
<SelectItem value="blocked">
|
<SelectItem value="blocked">
|
||||||
{t("blocked")}
|
{t(
|
||||||
|
"blocked"
|
||||||
|
)}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
<SelectItem value="custom">
|
<SelectItem value="custom">
|
||||||
{t("custom")}
|
{t(
|
||||||
|
"custom"
|
||||||
|
)}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
@@ -833,9 +1015,12 @@ export function InternalResourceForm({
|
|||||||
value={
|
value={
|
||||||
tcpCustomPorts
|
tcpCustomPorts
|
||||||
}
|
}
|
||||||
onChange={(e) =>
|
onChange={(
|
||||||
|
e
|
||||||
|
) =>
|
||||||
setTcpCustomPorts(
|
setTcpCustomPorts(
|
||||||
e.target
|
e
|
||||||
|
.target
|
||||||
.value
|
.value
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -899,7 +1084,11 @@ export function InternalResourceForm({
|
|||||||
value={udpPortMode}
|
value={udpPortMode}
|
||||||
onValueChange={(
|
onValueChange={(
|
||||||
v: PortMode
|
v: PortMode
|
||||||
) => setUdpPortMode(v)}
|
) =>
|
||||||
|
setUdpPortMode(
|
||||||
|
v
|
||||||
|
)
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<SelectTrigger className="w-[110px]">
|
<SelectTrigger className="w-[110px]">
|
||||||
@@ -908,13 +1097,19 @@ export function InternalResourceForm({
|
|||||||
</FormControl>
|
</FormControl>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
<SelectItem value="all">
|
<SelectItem value="all">
|
||||||
{t("allPorts")}
|
{t(
|
||||||
|
"allPorts"
|
||||||
|
)}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
<SelectItem value="blocked">
|
<SelectItem value="blocked">
|
||||||
{t("blocked")}
|
{t(
|
||||||
|
"blocked"
|
||||||
|
)}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
<SelectItem value="custom">
|
<SelectItem value="custom">
|
||||||
{t("custom")}
|
{t(
|
||||||
|
"custom"
|
||||||
|
)}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
@@ -926,9 +1121,12 @@ export function InternalResourceForm({
|
|||||||
value={
|
value={
|
||||||
udpCustomPorts
|
udpCustomPorts
|
||||||
}
|
}
|
||||||
onChange={(e) =>
|
onChange={(
|
||||||
|
e
|
||||||
|
) =>
|
||||||
setUdpCustomPorts(
|
setUdpCustomPorts(
|
||||||
e.target
|
e
|
||||||
|
.target
|
||||||
.value
|
.value
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -972,7 +1170,9 @@ export function InternalResourceForm({
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<FormLabel className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">
|
<FormLabel className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">
|
||||||
{t("editInternalResourceDialogIcmp")}
|
{t(
|
||||||
|
"editInternalResourceDialogIcmp"
|
||||||
|
)}
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@@ -1015,6 +1215,7 @@ export function InternalResourceForm({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-4 mt-4 p-1">
|
<div className="space-y-4 mt-4 p-1">
|
||||||
|
|||||||
Reference in New Issue
Block a user