diff --git a/web/src/components/probeshell/main-config-card.tsx b/web/src/components/probeshell/main-config-card.tsx
index 7f0447b6..168615b8 100644
--- a/web/src/components/probeshell/main-config-card.tsx
+++ b/web/src/components/probeshell/main-config-card.tsx
@@ -14,18 +14,23 @@ import {
} 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 {
+ Select,
+ SelectContent,
+ SelectItem,
+ SelectTrigger,
+ SelectValue,
+} from "@/components/ui/select";
import { Switch } from "@/components/ui/switch";
import type { ServerConfig } from "@/types/memshell";
import type { ProbeShellFormSchema } from "@/types/schema";
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: "自定义字节码执行" },
+ { value: "Server" as const, label: "server" },
+ { value: "JDK" as const, label: "jdk" },
+ { value: "Command" as const, label: "command" },
+ { value: "Bytecode" as const, label: "bytecode" },
] as const;
const MIDDLEWARE_OPTIONS = [
@@ -45,12 +50,11 @@ const MIDDLEWARE_OPTIONS = [
] as const;
const PROBE_METHOD_OPTIONS = [
- { value: "Sleep", label: "Sleep 延迟探测" },
+ { value: "Sleep", label: "Sleep" },
{ value: "DNSLog", label: "DNSLog" },
{ value: "ResponseBody", label: "ResponseBody" },
] as const;
-// 默认值配置
const DEFAULT_FORM_VALUES = {
reqParamName: "payload",
reqHeaderName: "X-PAYLOAD",
@@ -64,7 +68,7 @@ interface MainConfigCardProps {
}
export default function MainConfigCard({ form, servers }: MainConfigCardProps) {
- const { t } = useTranslation();
+ const { t } = useTranslation(["common", "probeshell"]);
const watchedProbeMethod = form.watch("probeMethod");
const watchedProbeContent = form.watch("probeContent");
@@ -75,12 +79,13 @@ export default function MainConfigCard({ form, servers }: MainConfigCardProps) {
Sleep: ["Server"],
} as const;
- const allowedValues = filterMap[watchedProbeMethod as keyof typeof filterMap];
-
+ const allowedValues =
+ filterMap[watchedProbeMethod as keyof typeof filterMap];
+
if (!allowedValues) return PROBE_OPTIONS;
-
- return PROBE_OPTIONS.filter(opt =>
- allowedValues.includes(opt.value as never)
+
+ return PROBE_OPTIONS.filter((opt) =>
+ allowedValues.includes(opt.value as never),
);
}, [watchedProbeMethod]);
@@ -100,64 +105,70 @@ export default function MainConfigCard({ form, servers }: MainConfigCardProps) {
resetFormValues();
}, [resetFormValues]);
- const ContentOptionsSelect = useMemo(() => (
-
(
-
- 探测内容
-
-
-
- )}
- />
- ), [form.control, filteredOptions]);
-
- const RequestParamField = useMemo(() => (
-
+ const ContentOptionsSelect = useMemo(
+ () => (
(
- Request Param Name
-
-
-
+ {t("probeshell:probeContent")}
+
)}
/>
-
- ), [form.control]);
+ ),
+ [form.control, filteredOptions, t],
+ );
- const SleepFields = useMemo(() => (
-
-
- ), [form.control]);
+ ),
+ [form.control, t],
+ );
const renderDynamicFields = useCallback(() => {
const isBodyMethod = watchedProbeMethod === "ResponseBody";
- const isCommandOrBytecode = watchedProbeContent === "Command" || watchedProbeContent === "Bytecode";
+ const isCommandOrBytecode =
+ watchedProbeContent === "Command" || watchedProbeContent === "Bytecode";
const isSleepMethod = watchedProbeMethod === "Sleep";
const isServerContent = watchedProbeContent === "Server";
@@ -211,90 +224,110 @@ export default function MainConfigCard({ form, servers }: MainConfigCardProps) {
return null;
}, [watchedProbeMethod, watchedProbeContent, RequestParamField, SleepFields]);
-
- const DNSLogSection = useMemo(() => (
+ const DNSLogSection = useMemo(
+ () => (
(
- DNSLog 地址
+ {t("probeshell:dnslog.host")}
-
+
)}
/>
- ), [form.control]);
+ ),
+ [form.control, t],
+ );
- const MiddlewareSelect = useMemo(() => (
- (
-
- 中间件类型
-
-
-
- )}
- />
- ), [form.control, servers]);
+ const MiddlewareSelect = useMemo(
+ () => (
+ (
+
+ {t("server")}
+
+
+
+ )}
+ />
+ ),
+ [form.control, servers, t],
+ );
- const SwitchGroup = useMemo(() => (
-
- (
-
-
-
-
- {t("mainConfig.debug")}
-
- )}
- />
- (
-
-
-
-
-
-
- )}
- />
- (
-
-
-
-
-
-
- )}
- />
-
- ), [form.control, t]);
+ const SwitchGroup = useMemo(
+ () => (
+
+ (
+
+
+
+
+ {t("debug")}
+
+ )}
+ />
+ (
+
+
+
+
+
+
+ )}
+ />
+ (
+
+
+
+
+
+
+ )}
+ />
+
+ ),
+ [form.control, t],
+ );
return (
@@ -302,17 +335,20 @@ export default function MainConfigCard({ form, servers }: MainConfigCardProps) {
- {t("configs.main-config")}
+ {t("mainConfig.title")}
-
+
(
- 探测方式
-
);
-}
\ No newline at end of file
+}
diff --git a/web/src/components/probeshell/package-config-card.tsx b/web/src/components/probeshell/package-config-card.tsx
index 07653704..9212eea3 100644
--- a/web/src/components/probeshell/package-config-card.tsx
+++ b/web/src/components/probeshell/package-config-card.tsx
@@ -2,8 +2,18 @@ import { PackageIcon } from "lucide-react";
import { useEffect, useState } from "react";
import { FormProvider, type UseFormReturn } from "react-hook-form";
import { useTranslation } from "react-i18next";
-import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card.tsx";
-import { FormControl, FormField, FormItem, FormLabel } from "@/components/ui/form.tsx";
+import {
+ Card,
+ CardContent,
+ CardHeader,
+ CardTitle,
+} from "@/components/ui/card.tsx";
+import {
+ FormControl,
+ FormField,
+ FormItem,
+ FormLabel,
+} from "@/components/ui/form.tsx";
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group.tsx";
import type { PackerConfig } from "@/types/memshell";
import type { ProbeShellFormSchema } from "@/types/schema";
@@ -21,7 +31,7 @@ export default function PackageConfigCard({
form: UseFormReturn;
}>) {
const [options, setOptions] = useState>([]);
- const { t } = useTranslation();
+ const { t } = useTranslation("common");
useEffect(() => {
const filteredOptions = (packerConfig ?? []).filter((name) => {
@@ -30,24 +40,27 @@ export default function PackageConfigCard({
const mappedOptions = filteredOptions.map((name) => {
return {
- name: t(`packageConfig.packer.${name}`),
+ name: name,
value: name,
};
});
setOptions(mappedOptions);
const currentValue = form.getValues("packingMethod");
- if (filteredOptions.length > 0 && (!currentValue || !filteredOptions.includes(currentValue))) {
+ if (
+ filteredOptions.length > 0 &&
+ (!currentValue || !filteredOptions.includes(currentValue))
+ ) {
form.setValue("packingMethod", filteredOptions[0]);
}
- }, [form, packerConfig, t]);
+ }, [form, packerConfig]);
return (
- {t("configs.package-config")}
+ {t("packerConfig.title")}
@@ -58,7 +71,7 @@ export default function PackageConfigCard({
name="packingMethod"
render={({ field }) => (
- {t("packageConfig.title")}
+ {t("packerMethod")}
{options.map(({ name, value }) => (
-
+
@@ -84,7 +100,9 @@ export default function PackageConfigCard({
) : (
-
{t("loading")}
+
+ {t("loading")}
+
)}
diff --git a/web/src/components/probeshell/quick-usage.tsx b/web/src/components/probeshell/quick-usage.tsx
index d3f993b2..6e591808 100644
--- a/web/src/components/probeshell/quick-usage.tsx
+++ b/web/src/components/probeshell/quick-usage.tsx
@@ -1,24 +1,27 @@
import { ScrollTextIcon } from "lucide-react";
import { useTranslation } from "react-i18next";
-import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card.tsx";
+import {
+ Card,
+ CardContent,
+ CardHeader,
+ CardTitle,
+} from "@/components/ui/card.tsx";
export function QuickUsage() {
- const { t } = useTranslation();
+ const { t } = useTranslation(["common", "probeshell"]);
return (
- {t("quickUsage.title")}
+ {t("common:quickUsage.title")}
- - {t("quickUsage.step1")}
- - {t("quickUsage.step2")}
- - {t("quickUsage.step3")}
- - {t("quickUsage.step4")}
- - {t("quickUsage.step5")}
+ - {t("probeshell:quickUsage.step1")}
+ - {t("probeshell:quickUsage.step2")}
+ - {t("probeshell:quickUsage.step3")}
diff --git a/web/src/components/probeshell/shell-result.tsx b/web/src/components/probeshell/shell-result.tsx
index f836c785..a9955a7a 100644
--- a/web/src/components/probeshell/shell-result.tsx
+++ b/web/src/components/probeshell/shell-result.tsx
@@ -1,6 +1,11 @@
import { useTranslation } from "react-i18next";
import { QuickUsage } from "@/components/probeshell/quick-usage";
-import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs.tsx";
+import {
+ Tabs,
+ TabsContent,
+ TabsList,
+ TabsTrigger,
+} from "@/components/ui/tabs.tsx";
import type { ProbeShellResult } from "@/types/probeshell";
import CodeViewer from "../code-viewer";
import { MultiPackResult } from "../memshell/results/multi-packer";
@@ -25,32 +30,37 @@ export default function ShellResult({
return (
- {t("generateResult.title1")}
+
+ {t("common:generateResult")}
+
- {
- allPackResults &&
- }
- {
- packResult && (
-
-
- {t("packageConfig.title")}:{packMethod}
-
- ({packResult?.length})
-
- }
- wrapLongLines={!showCode}
- showLineNumbers={showCode}
- language={showCode ? "java" : "text"}
- height={350}
- />
- )
- }
+ {allPackResults && (
+
+ )}
+ {packResult && (
+
+
+ {t("common:packerMethod")}:{packMethod}
+
+
+ ({packResult?.length})
+
+
+ }
+ wrapLongLines={!showCode}
+ showLineNumbers={showCode}
+ language={showCode ? "java" : "text"}
+ height={350}
+ />
+ )}