+
-
-
-
+
+
+ {t("advanced-options")}
+
+
+
+
+
+
+
+
diff --git a/dashboard/src/features/hosts/schema/get-default.ts b/dashboard/src/features/hosts/schema/get-default.ts
index e9f31d8..efa6ec5 100644
--- a/dashboard/src/features/hosts/schema/get-default.ts
+++ b/dashboard/src/features/hosts/schema/get-default.ts
@@ -8,6 +8,8 @@ export const getDefaultValues = (): HostSchemaType => {
path: '',
address: '',
remark: '',
+ fragment: null,
+ mux: false,
security: 'inbound_default',
alpn: "",
allowinsecure: false,
diff --git a/dashboard/src/features/hosts/schema/hosts-schema.ts b/dashboard/src/features/hosts/schema/hosts-schema.ts
index afbe0eb..69b7530 100644
--- a/dashboard/src/features/hosts/schema/hosts-schema.ts
+++ b/dashboard/src/features/hosts/schema/hosts-schema.ts
@@ -1,30 +1,74 @@
import { z } from "zod";
+import i18n from "i18next";
+
+const numberInterval = (v: string | null | undefined) => {
+ return v ? /^[\d-]{1,32}$/.test(v) : false;
+};
+
+const packetsInterval = (v: string | null | undefined) => {
+ return v ? /^(:?tlshello|[\d-]{1,32})$/.test(v) : false;
+};
export const HostSchema = z.object({
- remark: z.string().min(1, 'Remark is required'),
- address: z.string().min(1, 'Address is required'),
- port: z.coerce.number()
- .gte(1, 'Port must be more than 1')
- .lte(65535, 'Port can not be more than 65535')
- .or(z.string()).nullable().optional(),
+ remark: z.string().min(1, "Remark is required"),
+ address: z.string().min(1, "Address is required"),
+ port: z.coerce
+ .number()
+ .gte(1, "Port must be more than 1")
+ .lte(65535, "Port can not be more than 65535")
+ .or(z.string())
+ .nullable()
+ .optional(),
path: z.string().nullable().optional(),
sni: z.string().nullable().optional(),
host: z.string().nullable().optional(),
- security: z.enum(['inbound_default', 'none', 'tls']).default("inbound_default"),
- alpn: z.enum(['h2', 'http/1.1', 'h2,http/1.1', 'none', '']).optional().default("none"),
+ mux: z.boolean().nullable().optional(),
+ fragment: z
+ .object({
+ interval: z
+ .string()
+ .refine(
+ (v) => numberInterval(v),
+ i18n.t("page.hosts.fragment.interval-error"),
+ ),
+ length: z
+ .string()
+ .refine(
+ (v) => numberInterval(v),
+ i18n.t("page.hosts.fragment.length-error"),
+ ),
+ packets: z
+ .string()
+ .refine(
+ (v) => packetsInterval(v),
+ i18n.t("page.hosts.fragment.packets-error"),
+ ),
+ })
+ .nullable()
+ .optional(),
+ security: z
+ .enum(["inbound_default", "none", "tls"])
+ .default("inbound_default"),
+ alpn: z
+ .enum(["h2", "http/1.1", "h2,http/1.1", "none", ""])
+ .optional()
+ .default("none"),
allowinsecure: z.boolean().default(false).optional(),
- fingerprint: z.enum([
- "",
- "none",
- "chrome",
- "firefox",
- "safari",
- "ios",
- "android",
- "edge",
- "360",
- "qq",
- "random",
- "randomized",
- ]).optional().default("none"),
+ fingerprint: z
+ .enum([
+ "",
+ "none",
+ "chrome",
+ "firefox",
+ "safari",
+ "ios",
+ "android",
+ "edge",
+ "360",
+ "qq",
+ "random",
+ "randomized",
+ ])
+ .optional()
+ .default("none"),
});
diff --git a/dashboard/src/features/hosts/tables/inbound-hosts/index.tsx b/dashboard/src/features/hosts/tables/inbound-hosts/index.tsx
index ab436fd..7cce230 100644
--- a/dashboard/src/features/hosts/tables/inbound-hosts/index.tsx
+++ b/dashboard/src/features/hosts/tables/inbound-hosts/index.tsx
@@ -10,7 +10,7 @@ import { useState } from 'react'
import { useInboundsQuery } from '@marzneshin/features/inbounds'
import { columns } from './columns'
import { HostSettingsDialog } from '../../dialogs/settings'
-import { useDialog } from '@marzneshin/components'
+import { useDialog } from '@marzneshin/hooks'
import { InboundNotSelectedAlertDialog } from './inbound-not-selected-alert-dialog'
export const InboundHostsTable = () => {
diff --git a/dashboard/src/globals.css b/dashboard/src/globals.css
index 62bcaa8..c52d140 100644
--- a/dashboard/src/globals.css
+++ b/dashboard/src/globals.css
@@ -58,8 +58,8 @@
--accent: 217.2 32.6% 17.5%;
--accent-foreground: 210 40% 98%;
- --destructive: 0 62.8% 30.6%;
- --destructive-accent: 0 55% 57%;
+ --destructive: 0 55% 57%;
+ --destructive-accent: 0 62.8% 30.6%;
--destructive-foreground: 210 40% 98%;
--border: 217.2 32.6% 17.5%;
diff --git a/dashboard/src/hooks/index.ts b/dashboard/src/hooks/index.ts
index 9e25e4d..f0caed8 100644
--- a/dashboard/src/hooks/index.ts
+++ b/dashboard/src/hooks/index.ts
@@ -1,2 +1,3 @@
export * from './use-screen-breakpoint'
+export * from './use-dialog'
export * from './use-mutation-dialog'
diff --git a/dashboard/src/hooks/use-dialog.ts b/dashboard/src/hooks/use-dialog.ts
new file mode 100644
index 0000000..abe52ee
--- /dev/null
+++ b/dashboard/src/hooks/use-dialog.ts
@@ -0,0 +1,3 @@
+
+import { useState } from "react";
+export const useDialog = () => useState
(false)