import { ServerIcon } from "lucide-react"; import { useCallback, useEffect, useMemo } from "react"; import { FormProvider, type UseFormReturn } from "react-hook-form"; import { useTranslation } from "react-i18next"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { FormControl, FormField, FormFieldItem, FormFieldLabel, FormItem, FormLabel, FormMessage, } from "@/components/ui/form"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Switch } from "@/components/ui/switch"; import type { ProbeFormSchema } from "@/types/schema"; import type { ServerConfig } from "@/types/shell"; import { Separator } from "../ui/separator"; // 常量提取到组件外部 const PROBE_OPTIONS = [ { value: "Server" as const, label: "中间件类型" }, { value: "JDK" as const, label: "JDK 信息" }, { value: "Command" as const, label: "命令执行" }, { value: "Bytecode" as const, label: "自定义字节码执行" }, ] as const; const MIDDLEWARE_OPTIONS = [ { value: "Tomcat", label: "Tomcat" }, { value: "Jetty", label: "Jetty" }, { value: "Undertow", label: "Undertow" }, { value: "Resin", label: "Resin" }, { value: "JBoss", label: "JBoss" }, { value: "GlassFish", label: "GlassFish" }, { value: "BES", label: "BES" }, { value: "TongWeb", label: "TongWeb" }, { value: "InforSuite", label: "InforSuite" }, { value: "Apusic", label: "Apusic" }, { value: "SpringWebFlux", label: "SpringWebFlux" }, { value: "WebLogic", label: "WebLogic" }, { value: "WebSphere", label: "WebSphere" }, ] as const; const PROBE_METHOD_OPTIONS = [ { value: "Sleep", label: "Sleep 延迟探测" }, { value: "DNSLog", label: "DNSLog" }, { value: "ResponseBody", label: "ResponseBody" }, ] as const; // 默认值配置 const DEFAULT_FORM_VALUES = { reqParamName: "payload", reqHeaderName: "X-PAYLOAD", sleepServer: "Tomcat", seconds: 5, } as const; interface MainConfigCardProps { readonly form: UseFormReturn; readonly servers?: ServerConfig; } export default function MainConfigCard({ form, servers }: MainConfigCardProps) { const { t } = useTranslation(); const watchedProbeMethod = form.watch("probeMethod"); const watchedProbeContent = form.watch("probeContent"); const filteredOptions = useMemo(() => { const filterMap = { ResponseBody: ["Command", "Bytecode"], DNSLog: ["JDK", "Server"], Sleep: ["Server"], } as const; const allowedValues = filterMap[watchedProbeMethod as keyof typeof filterMap]; if (!allowedValues) return PROBE_OPTIONS; return PROBE_OPTIONS.filter(opt => allowedValues.includes(opt.value as never) ); }, [watchedProbeMethod]); const resetFormValues = useCallback(() => { if (filteredOptions.length === 0) return; const currentValues = form.getValues(); form.reset({ ...currentValues, probeMethod: watchedProbeMethod, probeContent: filteredOptions[0].value, ...DEFAULT_FORM_VALUES, }); }, [form, watchedProbeMethod, filteredOptions]); useEffect(() => { resetFormValues(); }, [resetFormValues]); const ContentOptionsSelect = useMemo(() => ( ( 探测内容 )} /> ), [form.control, filteredOptions]); const RequestParamField = useMemo(() => (
( Request Param Name )} />
), [form.control]); const SleepFields = useMemo(() => (
( 探测中间件 )} /> ( 命中延迟时间 (秒) field.onChange(+event.target.value)} /> )} />
), [form.control]); const renderDynamicFields = useCallback(() => { const isBodyMethod = watchedProbeMethod === "ResponseBody"; const isCommandOrBytecode = watchedProbeContent === "Command" || watchedProbeContent === "Bytecode"; const isSleepMethod = watchedProbeMethod === "Sleep"; const isServerContent = watchedProbeContent === "Server"; if (isBodyMethod && isCommandOrBytecode) { return RequestParamField; } if (isSleepMethod && isServerContent) { return SleepFields; } return null; }, [watchedProbeMethod, watchedProbeContent, RequestParamField, SleepFields]); const DNSLogSection = useMemo(() => ( ( DNSLog 地址 )} /> ), [form.control]); const MiddlewareSelect = useMemo(() => ( ( 中间件类型 )} /> ), [form.control, servers]); const SwitchGroup = useMemo(() => (
( {t("mainConfig.debug")} )} /> ( )} /> ( )} />
), [form.control, t]); return ( {t("configs.main-config")} ( 探测方式 )} /> {watchedProbeMethod === "ResponseBody" && MiddlewareSelect} {watchedProbeMethod === "DNSLog" && DNSLogSection} {watchedProbeMethod && ContentOptionsSelect} {SwitchGroup} {renderDynamicFields()} ( {t("mainConfig.shellClassName")} {t("optional")} )} /> ); }