diff --git a/frontend/src/test/subscription-general-tab.test.tsx b/frontend/src/test/subscription-general-tab.test.tsx
index 738e77d..dcee505 100644
--- a/frontend/src/test/subscription-general-tab.test.tsx
+++ b/frontend/src/test/subscription-general-tab.test.tsx
@@ -17,7 +17,12 @@ function LocationProbe() {
}
describe('SubscriptionGeneralTab', () => {
- it('keeps the stored subscription port when the field is cleared', () => {
+ // P7 made the subscription port optional: clearing the field applies
+ // subPort 0, the explicit "no port in generated links" setting (the sub
+ // server keeps binding the default port). This field opts out of the
+ // shared keep-stored-value-on-clear semantic via onNumber's onClear —
+ // see utils/onNumber.ts and SettingService.BuildSubURIBase.
+ it('applies subPort 0 (no port in generated links) when the field is cleared', () => {
const updateSetting = vi.fn();
renderWithProviders(
@@ -33,8 +38,7 @@ describe('SubscriptionGeneralTab', () => {
fireEvent.change(portInput, { target: { value: '' } });
fireEvent.blur(portInput);
- expect(updateSetting).not.toHaveBeenCalled();
- expect((portInput as HTMLInputElement).value).toBe('2096');
+ expect(updateSetting).toHaveBeenCalledWith({ subPort: 0 });
});
it('forwards typed subscription ports unchanged', () => {
diff --git a/internal/web/translation/ar-EG.json b/internal/web/translation/ar-EG.json
index 77443d1..f7bf54b 100644
--- a/internal/web/translation/ar-EG.json
+++ b/internal/web/translation/ar-EG.json
@@ -282,6 +282,28 @@
"streamTab": "تدفق",
"securityTab": "الأمان",
"sniffingTab": "تنصت",
+ "forwardingTab": "Forwarding",
+ "forwarding": {
+ "mode": "Forwarding",
+ "direct": "Direct",
+ "forward": "Forward (entry → exit)",
+ "landing": "Landing",
+ "managed": "Managed landing",
+ "manual": "Manual endpoint",
+ "target": "Landing inbound",
+ "targetPlaceholder": "Pick a SOCKS (mixed) inbound",
+ "targetDisabled": "disabled",
+ "address": "Landing address",
+ "port": "Exit port",
+ "protocol": "Entry → exit protocol",
+ "username": "SOCKS5 username",
+ "password": "Landing password",
+ "importLink": "Import from link",
+ "importPlaceholder": "socks5://user:pass@host:port",
+ "importApply": "Import",
+ "importFailed": "Could not parse that link",
+ "help": "Applies when this inbound is deployed to an agent node: on every config pull the panel compiles this forwarding into a dedicated outbound plus a routing rule for that agent. A managed landing's address and credentials are resolved from the chosen inbound at build time."
+ },
"sniffingMetadataOnly": "البيانات الوصفية فقط",
"sniffingRouteOnly": "التوجيه فقط",
"sniffingIpsExcluded": "IP المستثناة",
@@ -1251,16 +1273,6 @@
"Balancers": "موازنات التحميل",
"balancerTagRequired": "الوسم مطلوب",
"balancerSelectorRequired": "اختر صادراً واحداً على الأقل",
- "routeTester": "اختبار المسار",
- "routeTesterDesc": "اسأل Xray الشغال أي صادر هيتعامل مع الاتصال ده. مفيش ترافيك بيتبعت — القرار بييجي مباشرة من محرك التوجيه الحي.",
- "routeTesterDest": "نطاق أو IP",
- "routeTesterPort": "المنفذ",
- "routeTesterInbound": "الوارد",
- "routeTesterProtocol": "البروتوكول المكتشف",
- "routeTesterTest": "اختبر المسار",
- "routeTesterMatchedOutbound": "الصادر المطابق",
- "routeTesterViaBalancer": "عبر موازن التحميل",
- "routeTesterDefaultOutbound": "ما في قاعدة توجيه اتطابقت — الترافيك رايح للصادر الافتراضي (الأول).",
"Routings": "قواعد التوجيه",
"logLevel": "مستوى السجلات",
"logLevelDesc": "مستوى السجل الخاص بالأخطاء، اللي بيوضح المعلومات المطلوبة للتسجيل.",
@@ -1717,7 +1729,6 @@
"inbounds": "الواردات",
"clients": "العملاء",
"offline": "🔴 غير متصل",
- "online": "🟢 متصل",
"commands": {
"unknown": "❗ أمر مش معروف.",
"pleaseChoose": "👇 من فضلك اختار:\r\n",
@@ -1730,8 +1741,6 @@
"helpAdminCommands": "عشان تعيد تشغيل Xray Core:\r\n/restart\r\n\r\nعشان تدور على إيميل عميل:\r\n/usage [Email]\r\n\r\nعشان تدور على إدخالات (مع إحصائيات العملاء):\r\n/inbound [Remark]\r\n\r\nID شات Telegram:\r\n/id",
"helpClientCommands": "عشان تدور على الإحصائيات، استخدم الأمر ده:\r\n\r\n/usage [Email]\r\n\r\nID شات Telegram:\r\n/id",
"restartUsage": "\r\n\r\n/restart",
- "restartSuccess": "✅ العملية نجحت!",
- "restartFailed": "❗ حصل خطأ في العملية.\r\n\r\nError: {{ .Error }}.",
"xrayNotRunning": "❗ Xray Core مش شغال.",
"startDesc": "عرض القائمة الرئيسية",
"helpDesc": "مساعدة البوت",
diff --git a/internal/web/translation/en-US.json b/internal/web/translation/en-US.json
index a23cdfc..8dac390 100644
--- a/internal/web/translation/en-US.json
+++ b/internal/web/translation/en-US.json
@@ -1383,16 +1383,6 @@
"Balancers": "Balancers",
"balancerTagRequired": "Tag is required",
"balancerSelectorRequired": "Pick at least one outbound",
- "routeTester": "Route Tester",
- "routeTesterDesc": "Ask the running Xray which outbound would handle a connection. No traffic is sent — the decision comes straight from the live routing engine.",
- "routeTesterDest": "Domain or IP",
- "routeTesterPort": "Port",
- "routeTesterInbound": "Inbound",
- "routeTesterProtocol": "Sniffed protocol",
- "routeTesterTest": "Test Route",
- "routeTesterMatchedOutbound": "Matched outbound",
- "routeTesterViaBalancer": "via balancer",
- "routeTesterDefaultOutbound": "No routing rule matched — traffic goes to the default (first) outbound.",
"Routings": "Routing Rules",
"importRules": "Import Rules",
"exportRules": "Export Rules",
@@ -1739,7 +1729,6 @@
"inbounds": "Inbounds",
"clients": "Clients",
"offline": "🔴 Offline",
- "online": "🟢 Online",
"commands": {
"unknown": "❗ Unknown command.",
"pleaseChoose": "👇 Please choose:\r\n",
@@ -1752,8 +1741,6 @@
"helpAdminCommands": "To restart Xray Core:\r\n/restart\r\n\r\nTo search for a client email:\r\n/usage [Email]\r\n\r\nTo search for inbounds (with client stats):\r\n/inbound [Remark]\r\n\r\nTelegram Chat ID:\r\n/id",
"helpClientCommands": "To search for statistics, use the following command:\r\n\r\n/usage [Email]\r\n\r\nTelegram Chat ID:\r\n/id",
"restartUsage": "\r\n\r\n/restart",
- "restartSuccess": "✅ Operation successful!",
- "restartFailed": "❗ Error in operation.\r\n\r\nError: {{ .Error }}.",
"xrayNotRunning": "❗ Xray Core is not running.",
"startDesc": "Show the main menu",
"helpDesc": "Bot help",
diff --git a/internal/web/translation/es-ES.json b/internal/web/translation/es-ES.json
index 114024f..a9c0cef 100644
--- a/internal/web/translation/es-ES.json
+++ b/internal/web/translation/es-ES.json
@@ -282,6 +282,28 @@
"streamTab": "Transmisión",
"securityTab": "Seguridad",
"sniffingTab": "Inspección",
+ "forwardingTab": "Forwarding",
+ "forwarding": {
+ "mode": "Forwarding",
+ "direct": "Direct",
+ "forward": "Forward (entry → exit)",
+ "landing": "Landing",
+ "managed": "Managed landing",
+ "manual": "Manual endpoint",
+ "target": "Landing inbound",
+ "targetPlaceholder": "Pick a SOCKS (mixed) inbound",
+ "targetDisabled": "disabled",
+ "address": "Landing address",
+ "port": "Exit port",
+ "protocol": "Entry → exit protocol",
+ "username": "SOCKS5 username",
+ "password": "Landing password",
+ "importLink": "Import from link",
+ "importPlaceholder": "socks5://user:pass@host:port",
+ "importApply": "Import",
+ "importFailed": "Could not parse that link",
+ "help": "Applies when this inbound is deployed to an agent node: on every config pull the panel compiles this forwarding into a dedicated outbound plus a routing rule for that agent. A managed landing's address and credentials are resolved from the chosen inbound at build time."
+ },
"sniffingMetadataOnly": "Solo metadatos",
"sniffingRouteOnly": "Solo enrutamiento",
"sniffingIpsExcluded": "IPs excluidas",
@@ -1243,16 +1265,6 @@
"Balancers": "Equilibradores",
"balancerTagRequired": "La etiqueta es obligatoria",
"balancerSelectorRequired": "Elige al menos una salida",
- "routeTester": "Prueba de ruta",
- "routeTesterDesc": "Pregunta al Xray en ejecución qué salida gestionaría una conexión. No se envía tráfico real — la decisión viene directamente del motor de enrutamiento en vivo.",
- "routeTesterDest": "Dominio o IP",
- "routeTesterPort": "Puerto",
- "routeTesterInbound": "Entrante",
- "routeTesterProtocol": "Protocolo detectado",
- "routeTesterTest": "Probar ruta",
- "routeTesterMatchedOutbound": "Salida coincidente",
- "routeTesterViaBalancer": "vía balanceador",
- "routeTesterDefaultOutbound": "Ninguna regla de enrutamiento coincidió — el tráfico va a la salida predeterminada (primera).",
"Routings": "Reglas de enrutamiento",
"logLevel": "Nivel de registro",
"logLevelDesc": "El nivel de registro para registros de errores, que indica la información que debe registrarse.",
@@ -1717,7 +1729,6 @@
"inbounds": "Entradas",
"clients": "Clientes",
"offline": "🔴 Sin conexión",
- "online": "🟢 En línea",
"commands": {
"unknown": "❗ Comando desconocido",
"pleaseChoose": "👇 Por favor elige:\r\n",
@@ -1730,8 +1741,6 @@
"helpAdminCommands": "Para reiniciar Xray Core:\r\n/restart\r\n\r\nPara buscar un correo electrónico de cliente:\r\n/usage [Correo electrónico]\r\n\r\nPara buscar entradas (con estadísticas de cliente):\r\n/inbound [Observación]\r\n\r\nID de Chat de Telegram:\r\n/id",
"helpClientCommands": "Para buscar estadísticas, utiliza el siguiente comando:\r\n/usage [Correo electrónico]\r\n\r\nID de Chat de Telegram:\r\n/id",
"restartUsage": "\r\n\r\n/restart",
- "restartSuccess": "✅ ¡Operación exitosa!",
- "restartFailed": "❗ Error en la operación.\r\n\r\nError: {{ .Error }}.",
"xrayNotRunning": "❗ Xray Core no está en ejecución.",
"startDesc": "Mostrar el menú principal",
"helpDesc": "Ayuda del bot",
diff --git a/internal/web/translation/fa-IR.json b/internal/web/translation/fa-IR.json
index 86e0c00..8fc2352 100644
--- a/internal/web/translation/fa-IR.json
+++ b/internal/web/translation/fa-IR.json
@@ -282,6 +282,28 @@
"streamTab": "انتقال",
"securityTab": "امنیت",
"sniffingTab": "شنود",
+ "forwardingTab": "Forwarding",
+ "forwarding": {
+ "mode": "Forwarding",
+ "direct": "Direct",
+ "forward": "Forward (entry → exit)",
+ "landing": "Landing",
+ "managed": "Managed landing",
+ "manual": "Manual endpoint",
+ "target": "Landing inbound",
+ "targetPlaceholder": "Pick a SOCKS (mixed) inbound",
+ "targetDisabled": "disabled",
+ "address": "Landing address",
+ "port": "Exit port",
+ "protocol": "Entry → exit protocol",
+ "username": "SOCKS5 username",
+ "password": "Landing password",
+ "importLink": "Import from link",
+ "importPlaceholder": "socks5://user:pass@host:port",
+ "importApply": "Import",
+ "importFailed": "Could not parse that link",
+ "help": "Applies when this inbound is deployed to an agent node: on every config pull the panel compiles this forwarding into a dedicated outbound plus a routing rule for that agent. A managed landing's address and credentials are resolved from the chosen inbound at build time."
+ },
"sniffingMetadataOnly": "فقط متادیتا",
"sniffingRouteOnly": "فقط مسیریابی",
"sniffingIpsExcluded": "IPهای مستثنا",
@@ -1243,16 +1265,6 @@
"Balancers": "بالانسرها",
"balancerTagRequired": "تگ الزامی است",
"balancerSelectorRequired": "حداقل یک خروجی انتخاب کنید",
- "routeTester": "آزمایش مسیر",
- "routeTesterDesc": "از Xray در حال اجرا بپرسید یک اتصال از کدام خروجی عبور میکند. هیچ ترافیکی ارسال نمیشود — پاسخ مستقیماً از موتور مسیریابی زنده میآید.",
- "routeTesterDest": "دامنه یا IP",
- "routeTesterPort": "پورت",
- "routeTesterInbound": "ورودی",
- "routeTesterProtocol": "پروتکل تشخیصی",
- "routeTesterTest": "آزمایش مسیر",
- "routeTesterMatchedOutbound": "خروجی منطبق",
- "routeTesterViaBalancer": "از طریق بالانسر",
- "routeTesterDefaultOutbound": "هیچ قانونی منطبق نشد — ترافیک به خروجی پیشفرض (اولین خروجی) میرود.",
"Routings": "قوانین مسیریابی",
"importRules": "ورود قوانین",
"exportRules": "خروج قوانین",
@@ -1717,7 +1729,6 @@
"inbounds": "ورودیها",
"clients": "کاربران",
"offline": "🔴 آفلاین",
- "online": "🟢 آنلاین",
"commands": {
"unknown": "❗ دستور ناشناخته",
"pleaseChoose": "👇 لطفاً انتخاب کنید:\r\n",
@@ -1730,8 +1741,6 @@
"helpAdminCommands": "برای راهاندازی مجدد Xray Core:\r\n/restart\r\n\r\nبرای جستجوی ایمیل مشتری:\r\n/usage [ایمیل]\r\n\r\nبرای جستجوی ورودیها (با آمار مشتری):\r\n/inbound [توضیحات]\r\n\r\nشناسه گفتگوی تلگرام:\r\n/id",
"helpClientCommands": "برای جستجوی آمار، از دستور زیر استفاده کنید:\r\n/usage [ایمیل]\r\n\r\nشناسه گفتگوی تلگرام:\r\n/id",
"restartUsage": "\r\n\r\n/restart",
- "restartSuccess": "✅ عملیات با موفقیت انجام شد!",
- "restartFailed": "❗ خطا در عملیات.\r\n\r\nخطا: {{ .Error }}.",
"xrayNotRunning": "❗ Xray Core در حال اجرا نیست.",
"startDesc": "نمایش منوی اصلی",
"helpDesc": "راهنمای ربات",
diff --git a/internal/web/translation/id-ID.json b/internal/web/translation/id-ID.json
index 8f78b7f..34a8100 100644
--- a/internal/web/translation/id-ID.json
+++ b/internal/web/translation/id-ID.json
@@ -282,6 +282,28 @@
"streamTab": "Aliran",
"securityTab": "Keamanan",
"sniffingTab": "Sniffing",
+ "forwardingTab": "Forwarding",
+ "forwarding": {
+ "mode": "Forwarding",
+ "direct": "Direct",
+ "forward": "Forward (entry → exit)",
+ "landing": "Landing",
+ "managed": "Managed landing",
+ "manual": "Manual endpoint",
+ "target": "Landing inbound",
+ "targetPlaceholder": "Pick a SOCKS (mixed) inbound",
+ "targetDisabled": "disabled",
+ "address": "Landing address",
+ "port": "Exit port",
+ "protocol": "Entry → exit protocol",
+ "username": "SOCKS5 username",
+ "password": "Landing password",
+ "importLink": "Import from link",
+ "importPlaceholder": "socks5://user:pass@host:port",
+ "importApply": "Import",
+ "importFailed": "Could not parse that link",
+ "help": "Applies when this inbound is deployed to an agent node: on every config pull the panel compiles this forwarding into a dedicated outbound plus a routing rule for that agent. A managed landing's address and credentials are resolved from the chosen inbound at build time."
+ },
"sniffingMetadataOnly": "Hanya metadata",
"sniffingRouteOnly": "Hanya routing",
"sniffingIpsExcluded": "IP yang dikecualikan",
@@ -1251,16 +1273,6 @@
"Balancers": "Penyeimbang",
"balancerTagRequired": "Tag wajib diisi",
"balancerSelectorRequired": "Pilih setidaknya satu outbound",
- "routeTester": "Uji Rute",
- "routeTesterDesc": "Tanyakan kepada Xray yang berjalan outbound mana yang akan menangani koneksi. Tidak ada lalu lintas yang dikirim — keputusan langsung datang dari mesin routing langsung.",
- "routeTesterDest": "Domain atau IP",
- "routeTesterPort": "Port",
- "routeTesterInbound": "Inbound",
- "routeTesterProtocol": "Protokol yang terdeteksi",
- "routeTesterTest": "Uji Rute",
- "routeTesterMatchedOutbound": "Outbound yang cocok",
- "routeTesterViaBalancer": "melalui penyeimbang",
- "routeTesterDefaultOutbound": "Tidak ada aturan routing yang cocok — lalu lintas menuju outbound default (pertama).",
"Routings": "Aturan Pengalihan",
"logLevel": "Tingkat Log",
"logLevelDesc": "Tingkat log untuk log kesalahan, menunjukkan informasi yang perlu dicatat.",
@@ -1717,7 +1729,6 @@
"inbounds": "Inbound",
"clients": "Klien",
"offline": "🔴 Offline",
- "online": "🟢 Online",
"commands": {
"unknown": "❗ Perintah tidak dikenal.",
"pleaseChoose": "👇 Harap pilih:\r\n",
@@ -1730,8 +1741,6 @@
"helpAdminCommands": "Untuk memulai ulang Xray Core:\r\n/restart\r\n\r\nUntuk mencari email klien:\r\n/usage [Email]\r\n\r\nUntuk mencari inbound (dengan statistik klien):\r\n/inbound [Catatan]\r\n\r\nID Obrolan Telegram:\r\n/id",
"helpClientCommands": "Untuk mencari statistik, gunakan perintah berikut:\r\n/usage [Email]\r\n\r\nID Obrolan Telegram:\r\n/id",
"restartUsage": "\r\n\r\n/restart",
- "restartSuccess": "✅ Operasi berhasil!",
- "restartFailed": "❗ Kesalahan dalam operasi.\r\n\r\nError: {{ .Error }}.",
"xrayNotRunning": "❗ Xray Core tidak berjalan.",
"startDesc": "Tampilkan menu utama",
"helpDesc": "Bantuan bot",
diff --git a/internal/web/translation/ja-JP.json b/internal/web/translation/ja-JP.json
index 785d165..550013c 100644
--- a/internal/web/translation/ja-JP.json
+++ b/internal/web/translation/ja-JP.json
@@ -282,6 +282,28 @@
"streamTab": "ストリーム",
"securityTab": "セキュリティ",
"sniffingTab": "スニッフィング",
+ "forwardingTab": "Forwarding",
+ "forwarding": {
+ "mode": "Forwarding",
+ "direct": "Direct",
+ "forward": "Forward (entry → exit)",
+ "landing": "Landing",
+ "managed": "Managed landing",
+ "manual": "Manual endpoint",
+ "target": "Landing inbound",
+ "targetPlaceholder": "Pick a SOCKS (mixed) inbound",
+ "targetDisabled": "disabled",
+ "address": "Landing address",
+ "port": "Exit port",
+ "protocol": "Entry → exit protocol",
+ "username": "SOCKS5 username",
+ "password": "Landing password",
+ "importLink": "Import from link",
+ "importPlaceholder": "socks5://user:pass@host:port",
+ "importApply": "Import",
+ "importFailed": "Could not parse that link",
+ "help": "Applies when this inbound is deployed to an agent node: on every config pull the panel compiles this forwarding into a dedicated outbound plus a routing rule for that agent. A managed landing's address and credentials are resolved from the chosen inbound at build time."
+ },
"sniffingMetadataOnly": "メタデータのみ",
"sniffingRouteOnly": "ルーティングのみ",
"sniffingIpsExcluded": "除外する IP",
@@ -1251,16 +1273,6 @@
"Balancers": "負荷分散",
"balancerTagRequired": "タグは必須です",
"balancerSelectorRequired": "アウトバウンドを少なくとも1つ選んでください",
- "routeTester": "ルートテスト",
- "routeTesterDesc": "実行中の Xray にどのアウトバウンドが接続を処理するか問い合わせます。実際のトラフィックは送信されません — 判断はライブルーティングエンジンから直接取得されます。",
- "routeTesterDest": "ドメインまたは IP",
- "routeTesterPort": "ポート",
- "routeTesterInbound": "インバウンド",
- "routeTesterProtocol": "検出されたプロトコル",
- "routeTesterTest": "ルートをテスト",
- "routeTesterMatchedOutbound": "マッチしたアウトバウンド",
- "routeTesterViaBalancer": "バランサー経由",
- "routeTesterDefaultOutbound": "ルーティングルールに一致しませんでした — トラフィックはデフォルト(最初の)アウトバウンドに送られます。",
"Routings": "ルーティングルール",
"logLevel": "ログレベル",
"logLevelDesc": "エラーログのレベルを指定し、記録する情報を示します",
@@ -1717,7 +1729,6 @@
"inbounds": "インバウンド",
"clients": "クライアント",
"offline": "🔴 オフライン",
- "online": "🟢 オンライン",
"commands": {
"unknown": "❗ 不明なコマンド",
"pleaseChoose": "👇 選択してください:\r\n",
@@ -1730,8 +1741,6 @@
"helpAdminCommands": "Xray Coreを再起動するには:\r\n/restart\r\n\r\nクライアントの電子メールを検索するには:\r\n/usage [電子メール]\r\n\r\nインバウンド(クライアントの統計情報を含む)を検索するには:\r\n/inbound [備考]\r\n\r\nTelegramチャットID:\r\n/id",
"helpClientCommands": "統計情報を検索するには、次のコマンドを使用してください:\r\n/usage [電子メール]\r\n\r\nTelegramチャットID:\r\n/id",
"restartUsage": "\r\n\r\n/restart",
- "restartSuccess": "✅ 操作成功!",
- "restartFailed": "❗ 操作エラー。\r\n\r\nエラー: {{ .Error }}",
"xrayNotRunning": "❗ Xray Core は動作していません。",
"startDesc": "メインメニューを表示",
"helpDesc": "ボットのヘルプ",
diff --git a/internal/web/translation/pt-BR.json b/internal/web/translation/pt-BR.json
index 00f4075..f841f31 100644
--- a/internal/web/translation/pt-BR.json
+++ b/internal/web/translation/pt-BR.json
@@ -282,6 +282,28 @@
"streamTab": "Transmissão",
"securityTab": "Segurança",
"sniffingTab": "Inspeção",
+ "forwardingTab": "Forwarding",
+ "forwarding": {
+ "mode": "Forwarding",
+ "direct": "Direct",
+ "forward": "Forward (entry → exit)",
+ "landing": "Landing",
+ "managed": "Managed landing",
+ "manual": "Manual endpoint",
+ "target": "Landing inbound",
+ "targetPlaceholder": "Pick a SOCKS (mixed) inbound",
+ "targetDisabled": "disabled",
+ "address": "Landing address",
+ "port": "Exit port",
+ "protocol": "Entry → exit protocol",
+ "username": "SOCKS5 username",
+ "password": "Landing password",
+ "importLink": "Import from link",
+ "importPlaceholder": "socks5://user:pass@host:port",
+ "importApply": "Import",
+ "importFailed": "Could not parse that link",
+ "help": "Applies when this inbound is deployed to an agent node: on every config pull the panel compiles this forwarding into a dedicated outbound plus a routing rule for that agent. A managed landing's address and credentials are resolved from the chosen inbound at build time."
+ },
"sniffingMetadataOnly": "Apenas metadados",
"sniffingRouteOnly": "Apenas roteamento",
"sniffingIpsExcluded": "IPs excluídos",
@@ -1251,16 +1273,6 @@
"Balancers": "Balanceadores",
"balancerTagRequired": "A tag é obrigatória",
"balancerSelectorRequired": "Selecione pelo menos uma saída",
- "routeTester": "Teste de rota",
- "routeTesterDesc": "Pergunte ao Xray em execução qual saída trataria uma conexão. Nenhum tráfego é enviado — a decisão vem diretamente do motor de roteamento ao vivo.",
- "routeTesterDest": "Domínio ou IP",
- "routeTesterPort": "Porta",
- "routeTesterInbound": "Entrada",
- "routeTesterProtocol": "Protocolo detectado",
- "routeTesterTest": "Testar rota",
- "routeTesterMatchedOutbound": "Saída correspondente",
- "routeTesterViaBalancer": "via balanceador",
- "routeTesterDefaultOutbound": "Nenhuma regra de roteamento correspondeu — o tráfego vai para a saída padrão (primeira).",
"Routings": "Regras de Roteamento",
"logLevel": "Nível de Log",
"logLevelDesc": "O nível de log para erros, indicando a informação que precisa ser registrada.",
@@ -1717,7 +1729,6 @@
"inbounds": "Entradas",
"clients": "Clientes",
"offline": "🔴 Offline",
- "online": "🟢 Online",
"commands": {
"unknown": "❗ Comando desconhecido.",
"pleaseChoose": "👇 Escolha:\r\n",
@@ -1730,8 +1741,6 @@
"helpAdminCommands": "Para reiniciar o Xray Core:\r\n/restart\r\n\r\nPara pesquisar por um email de cliente:\r\n/usage [Email]\r\n\r\nPara pesquisar por inbounds (com estatísticas do cliente):\r\n/inbound [Remark]\r\n\r\nTelegram Chat ID:\r\n/id",
"helpClientCommands": "Para pesquisar por estatísticas, use o seguinte comando:\r\n\r\n/usage [Email]\r\n\r\nTelegram Chat ID:\r\n/id",
"restartUsage": "\r\n\r\n/restart",
- "restartSuccess": "✅ Operação bem-sucedida!",
- "restartFailed": "❗ Erro na operação.\r\n\r\nErro: {{ .Error }}.",
"xrayNotRunning": "❗ Xray Core não está em execução.",
"startDesc": "Mostrar menu principal",
"helpDesc": "Ajuda do bot",
diff --git a/internal/web/translation/ru-RU.json b/internal/web/translation/ru-RU.json
index da0d943..2772f5e 100644
--- a/internal/web/translation/ru-RU.json
+++ b/internal/web/translation/ru-RU.json
@@ -282,6 +282,28 @@
"streamTab": "Поток",
"securityTab": "Безопасность",
"sniffingTab": "Сниффинг",
+ "forwardingTab": "Forwarding",
+ "forwarding": {
+ "mode": "Forwarding",
+ "direct": "Direct",
+ "forward": "Forward (entry → exit)",
+ "landing": "Landing",
+ "managed": "Managed landing",
+ "manual": "Manual endpoint",
+ "target": "Landing inbound",
+ "targetPlaceholder": "Pick a SOCKS (mixed) inbound",
+ "targetDisabled": "disabled",
+ "address": "Landing address",
+ "port": "Exit port",
+ "protocol": "Entry → exit protocol",
+ "username": "SOCKS5 username",
+ "password": "Landing password",
+ "importLink": "Import from link",
+ "importPlaceholder": "socks5://user:pass@host:port",
+ "importApply": "Import",
+ "importFailed": "Could not parse that link",
+ "help": "Applies when this inbound is deployed to an agent node: on every config pull the panel compiles this forwarding into a dedicated outbound plus a routing rule for that agent. A managed landing's address and credentials are resolved from the chosen inbound at build time."
+ },
"sniffingMetadataOnly": "Только метаданные",
"sniffingRouteOnly": "Только маршрутизация",
"sniffingIpsExcluded": "Исключённые IP",
@@ -1251,16 +1273,6 @@
"Balancers": "Балансировщик",
"balancerTagRequired": "Тег обязателен",
"balancerSelectorRequired": "Выберите хотя бы одно исходящее",
- "routeTester": "Тест маршрута",
- "routeTesterDesc": "Спросите запущенный Xray, через какой исходящий будет обработано соединение. Трафик не отправляется — решение поступает напрямую от живого движка маршрутизации.",
- "routeTesterDest": "Домен или IP",
- "routeTesterPort": "Порт",
- "routeTesterInbound": "Входящий",
- "routeTesterProtocol": "Обнаруженный протокол",
- "routeTesterTest": "Тест маршрута",
- "routeTesterMatchedOutbound": "Совпавший исходящий",
- "routeTesterViaBalancer": "через балансировщик",
- "routeTesterDefaultOutbound": "Ни одно правило маршрутизации не совпало — трафик направляется в исходящий по умолчанию (первый).",
"Routings": "Маршрутизация",
"logLevel": "Уровень логов",
"logLevelDesc": "Уровень журнала для журналов ошибок, указывающий информацию, которую необходимо записать.",
@@ -1717,7 +1729,6 @@
"inbounds": "Входящие",
"clients": "Клиенты",
"offline": "🔴 Не в сети",
- "online": "🟢 В сети",
"commands": {
"unknown": "❗ Неизвестная команда",
"pleaseChoose": "👇 Пожалуйста, выберите:\r\n",
@@ -1730,8 +1741,6 @@
"helpAdminCommands": "🔃 Для перезапуска Xray Core:\r\n/restart\r\n\r\n🔎 Для поиска клиента по email:\r\n/usage [Email]\r\n\r\n📊 Для поиска входящих подключений (со статистикой клиентов):\r\n/inbound [имя подключения]\r\n\r\n🆔 Ваш Telegram User ID:\r\n/id",
"helpClientCommands": "💲 Для просмотра информации о вашей подписке используйте команду:\r\n/usage [Email]\r\n\r\n🆔 Ваш Telegram User ID:\r\n/id",
"restartUsage": "\r\n\r\n/restart",
- "restartSuccess": "✅ Ядро Xray успешно перезапущено.",
- "restartFailed": "❗ Ошибка при перезапуске Xray-core.\r\n\r\nОшибка: {{ .Error }}.",
"xrayNotRunning": "❗ Xray Core не запущен.",
"startDesc": "Показать главное меню",
"helpDesc": "Справка по боту",
diff --git a/internal/web/translation/tr-TR.json b/internal/web/translation/tr-TR.json
index 901cb4f..030b40f 100644
--- a/internal/web/translation/tr-TR.json
+++ b/internal/web/translation/tr-TR.json
@@ -282,6 +282,28 @@
"streamTab": "Akış (Stream)",
"securityTab": "Güvenlik",
"sniffingTab": "Dinleme (Sniffing)",
+ "forwardingTab": "Forwarding",
+ "forwarding": {
+ "mode": "Forwarding",
+ "direct": "Direct",
+ "forward": "Forward (entry → exit)",
+ "landing": "Landing",
+ "managed": "Managed landing",
+ "manual": "Manual endpoint",
+ "target": "Landing inbound",
+ "targetPlaceholder": "Pick a SOCKS (mixed) inbound",
+ "targetDisabled": "disabled",
+ "address": "Landing address",
+ "port": "Exit port",
+ "protocol": "Entry → exit protocol",
+ "username": "SOCKS5 username",
+ "password": "Landing password",
+ "importLink": "Import from link",
+ "importPlaceholder": "socks5://user:pass@host:port",
+ "importApply": "Import",
+ "importFailed": "Could not parse that link",
+ "help": "Applies when this inbound is deployed to an agent node: on every config pull the panel compiles this forwarding into a dedicated outbound plus a routing rule for that agent. A managed landing's address and credentials are resolved from the chosen inbound at build time."
+ },
"sniffingMetadataOnly": "Yalnızca üst veri",
"sniffingRouteOnly": "Yalnızca yönlendirme",
"sniffingIpsExcluded": "Hariç tutulan IP'ler",
@@ -1251,16 +1273,6 @@
"Balancers": "Dengeleyiciler",
"balancerTagRequired": "Etiket zorunludur",
"balancerSelectorRequired": "En az bir giden bağlantı seçin",
- "routeTester": "Rota Testi",
- "routeTesterDesc": "Çalışan Xray'e hangi giden bağlantının bir isteği işleyeceğini sorun. Gerçek trafik gönderilmez — karar doğrudan canlı yönlendirme motorundan gelir.",
- "routeTesterDest": "Alan adı veya IP",
- "routeTesterPort": "Port",
- "routeTesterInbound": "Gelen",
- "routeTesterProtocol": "Algılanan protokol",
- "routeTesterTest": "Rotayı Test Et",
- "routeTesterMatchedOutbound": "Eşleşen giden",
- "routeTesterViaBalancer": "dengeleyici aracılığıyla",
- "routeTesterDefaultOutbound": "Hiçbir yönlendirme kuralı eşleşmedi — trafik varsayılan (ilk) giden bağlantıya yönlendirilir.",
"Routings": "Yönlendirme Kuralları",
"logLevel": "Günlük Seviyesi",
"logLevelDesc": "Hata günlükleri için kayıt seviyesi; hangi detayda bilginin kaydedileceğini belirler.",
@@ -1717,7 +1729,6 @@
"inbounds": "Gelen Bağlantılar",
"clients": "Kullanıcılar",
"offline": "🔴 Çevrimdışı",
- "online": "🟢 Çevrimiçi",
"commands": {
"unknown": "❗ Bilinmeyen komut.",
"pleaseChoose": "👇 Lütfen seçin:\r\n",
@@ -1730,8 +1741,6 @@
"helpAdminCommands": "Xray Core'u yeniden başlatmak için:\r\n/restart\r\n\r\nBir kullanıcının istatistiklerini aramak için:\r\n/usage [E-posta]\r\n\r\nGelen bağlantılarnı aramak için (kullanıcı istatistikleri ile):\r\n/inbound [Açıklama]\r\n\r\nTelegram Sohbet Kimliği (Chat ID):\r\n/id",
"helpClientCommands": "İstatistiklerinizi görmek için şu komutu kullanın:\r\n\r\n/usage [E-posta]\r\n\r\nTelegram Sohbet Kimliği:\r\n/id",
"restartUsage": "/restart",
- "restartSuccess": "✅ İşlem başarılı!",
- "restartFailed": "❗ İşlem hatası.\r\n\r\nHata: {{ .Error }}.",
"xrayNotRunning": "❗ Xray Core çalışmıyor.",
"startDesc": "Ana menüyü göster",
"helpDesc": "Bot yardımı",
diff --git a/internal/web/translation/uk-UA.json b/internal/web/translation/uk-UA.json
index 8fd25d4..52174be 100644
--- a/internal/web/translation/uk-UA.json
+++ b/internal/web/translation/uk-UA.json
@@ -282,6 +282,28 @@
"streamTab": "Потік",
"securityTab": "Безпека",
"sniffingTab": "Сніфінг",
+ "forwardingTab": "Forwarding",
+ "forwarding": {
+ "mode": "Forwarding",
+ "direct": "Direct",
+ "forward": "Forward (entry → exit)",
+ "landing": "Landing",
+ "managed": "Managed landing",
+ "manual": "Manual endpoint",
+ "target": "Landing inbound",
+ "targetPlaceholder": "Pick a SOCKS (mixed) inbound",
+ "targetDisabled": "disabled",
+ "address": "Landing address",
+ "port": "Exit port",
+ "protocol": "Entry → exit protocol",
+ "username": "SOCKS5 username",
+ "password": "Landing password",
+ "importLink": "Import from link",
+ "importPlaceholder": "socks5://user:pass@host:port",
+ "importApply": "Import",
+ "importFailed": "Could not parse that link",
+ "help": "Applies when this inbound is deployed to an agent node: on every config pull the panel compiles this forwarding into a dedicated outbound plus a routing rule for that agent. A managed landing's address and credentials are resolved from the chosen inbound at build time."
+ },
"sniffingMetadataOnly": "Лише метадані",
"sniffingRouteOnly": "Лише маршрутизація",
"sniffingIpsExcluded": "Виключені IP",
@@ -1243,16 +1265,6 @@
"Balancers": "Балансери",
"balancerTagRequired": "Тег обов'язковий",
"balancerSelectorRequired": "Виберіть принаймні один вихідний",
- "routeTester": "Тест маршруту",
- "routeTesterDesc": "Запитайте запущений Xray, через який вихідний буде оброблено з'єднання. Реальний трафік не надсилається — рішення надходить безпосередньо від живого рушія маршрутизації.",
- "routeTesterDest": "Домен або IP",
- "routeTesterPort": "Порт",
- "routeTesterInbound": "Вхідний",
- "routeTesterProtocol": "Виявлений протокол",
- "routeTesterTest": "Тест маршруту",
- "routeTesterMatchedOutbound": "Відповідний вихідний",
- "routeTesterViaBalancer": "через балансувальник",
- "routeTesterDefaultOutbound": "Жодне правило маршрутизації не збіглося — трафік надходить до вихідного за замовчуванням (першого).",
"Routings": "Правила маршрутизації",
"importRules": "Імпортувати правила",
"exportRules": "Експортувати правила",
@@ -1717,7 +1729,6 @@
"inbounds": "Вхідні",
"clients": "Клієнти",
"offline": "🔴 Не в мережі",
- "online": "🟢 У мережі",
"commands": {
"unknown": "❗ Невідома команда.",
"pleaseChoose": "👇 Будь ласка, виберіть:\r\n",
@@ -1730,8 +1741,6 @@
"helpAdminCommands": "Для перезапуску Xray Core:\r\n/restart\r\n\r\nДля пошуку електронної пошти клієнта:\r\n/usage [Електронна пошта]\r\n\r\nДля пошуку вхідних (зі статистикою клієнта):\r\n/inbound [Примітка]\r\n\r\nID чату Telegram:\r\n/id",
"helpClientCommands": "Для пошуку статистики використовуйте наступну команду:\r\n/usage [Електронна пошта]\r\n\r\nID чату Telegram:\r\n/id",
"restartUsage": "\r\n\r\n/restart",
- "restartSuccess": "✅ Операція успішна!",
- "restartFailed": "❗ Помилка в операції.\r\n\r\nПомилка: {{ .Error }}.",
"xrayNotRunning": "❗ Xray Core не запущений.",
"startDesc": "Показати головне меню",
"helpDesc": "Довідка по боту",
diff --git a/internal/web/translation/vi-VN.json b/internal/web/translation/vi-VN.json
index 5e076db..f18807c 100644
--- a/internal/web/translation/vi-VN.json
+++ b/internal/web/translation/vi-VN.json
@@ -282,6 +282,28 @@
"streamTab": "Luồng",
"securityTab": "Bảo mật",
"sniffingTab": "Dò gói",
+ "forwardingTab": "Forwarding",
+ "forwarding": {
+ "mode": "Forwarding",
+ "direct": "Direct",
+ "forward": "Forward (entry → exit)",
+ "landing": "Landing",
+ "managed": "Managed landing",
+ "manual": "Manual endpoint",
+ "target": "Landing inbound",
+ "targetPlaceholder": "Pick a SOCKS (mixed) inbound",
+ "targetDisabled": "disabled",
+ "address": "Landing address",
+ "port": "Exit port",
+ "protocol": "Entry → exit protocol",
+ "username": "SOCKS5 username",
+ "password": "Landing password",
+ "importLink": "Import from link",
+ "importPlaceholder": "socks5://user:pass@host:port",
+ "importApply": "Import",
+ "importFailed": "Could not parse that link",
+ "help": "Applies when this inbound is deployed to an agent node: on every config pull the panel compiles this forwarding into a dedicated outbound plus a routing rule for that agent. A managed landing's address and credentials are resolved from the chosen inbound at build time."
+ },
"sniffingMetadataOnly": "Chỉ siêu dữ liệu",
"sniffingRouteOnly": "Chỉ định tuyến",
"sniffingIpsExcluded": "IP bị loại trừ",
@@ -1251,16 +1273,6 @@
"Balancers": "Cân bằng",
"balancerTagRequired": "Tag là bắt buộc",
"balancerSelectorRequired": "Chọn ít nhất một outbound",
- "routeTester": "Kiểm tra tuyến đường",
- "routeTesterDesc": "Hỏi Xray đang chạy outbound nào sẽ xử lý kết nối. Không có lưu lượng nào được gửi — quyết định đến thẳng từ công cụ định tuyến trực tiếp.",
- "routeTesterDest": "Tên miền hoặc IP",
- "routeTesterPort": "Cổng",
- "routeTesterInbound": "Inbound",
- "routeTesterProtocol": "Giao thức nhận diện",
- "routeTesterTest": "Kiểm tra tuyến",
- "routeTesterMatchedOutbound": "Outbound phù hợp",
- "routeTesterViaBalancer": "qua bộ cân bằng tải",
- "routeTesterDefaultOutbound": "Không có quy tắc định tuyến nào khớp — lưu lượng đến outbound mặc định (đầu tiên).",
"Routings": "Quy tắc định tuyến",
"logLevel": "Mức đăng nhập",
"logLevelDesc": "Cấp độ nhật ký cho nhật ký lỗi, cho biết thông tin cần được ghi lại.",
@@ -1717,7 +1729,6 @@
"inbounds": "Inbound",
"clients": "Client",
"offline": "🔴 Ngoại tuyến",
- "online": "🟢 Trực tuyến",
"commands": {
"unknown": "❗ Lệnh không rõ",
"pleaseChoose": "👇 Vui lòng chọn:\r\n",
@@ -1730,8 +1741,6 @@
"helpAdminCommands": "Để khởi động lại Xray Core:\r\n/restart\r\n\r\nĐể tìm kiếm email của khách hàng:\r\n/usage [Email]\r\n\r\nĐể tìm kiếm các nhập (với số liệu thống kê của khách hàng):\r\n/inbound [Ghi chú]\r\n\r\nID Trò chuyện Telegram:\r\n/id",
"helpClientCommands": "Để tìm kiếm thống kê, sử dụng lệnh sau:\r\n/usage [Email]\r\n\r\nID Trò chuyện Telegram:\r\n/id",
"restartUsage": "\r\n\r\n/restart",
- "restartSuccess": "✅ Hoạt động thành công!",
- "restartFailed": "❗ Lỗi trong quá trình hoạt động.\r\n\r\nLỗi: {{ .Error }}.",
"xrayNotRunning": "❗ Xray Core không chạy.",
"startDesc": "Hiển thị menu chính",
"helpDesc": "Trợ giúp bot",
diff --git a/internal/web/translation/zh-CN.json b/internal/web/translation/zh-CN.json
index e26d3d4..0c92364 100644
--- a/internal/web/translation/zh-CN.json
+++ b/internal/web/translation/zh-CN.json
@@ -1273,16 +1273,6 @@
"Balancers": "负载均衡",
"balancerTagRequired": "标签为必填项",
"balancerSelectorRequired": "至少选择一个出站",
- "routeTester": "路由测试",
- "routeTesterDesc": "向运行中的 Xray 查询某个连接将使用哪个出站。不会发送真实流量 — 结果直接来自实时路由引擎。",
- "routeTesterDest": "域名或 IP",
- "routeTesterPort": "端口",
- "routeTesterInbound": "入站",
- "routeTesterProtocol": "嗅探协议",
- "routeTesterTest": "测试路由",
- "routeTesterMatchedOutbound": "匹配出站",
- "routeTesterViaBalancer": "经由负载均衡器",
- "routeTesterDefaultOutbound": "无路由规则匹配 — 流量将发往默认(第一个)出站。",
"Routings": "路由规则",
"logLevel": "日志级别",
"logLevelDesc": "错误日志的日志级别,用于指示需要记录的信息",
@@ -1739,7 +1729,6 @@
"inbounds": "入站",
"clients": "客户端",
"offline": "🔴 离线",
- "online": "🟢 在线",
"commands": {
"unknown": "❗ 未知命令",
"pleaseChoose": "👇 请选择:\r\n",
@@ -1752,8 +1741,6 @@
"helpAdminCommands": "要重新启动 Xray Core:\r\n/restart\r\n\r\n要搜索客户电子邮件:\r\n/usage [电子邮件]\r\n\r\n要搜索入站(带有客户统计数据):\r\n/inbound [备注]\r\n\r\nTelegram 聊天 ID:\r\n/id",
"helpClientCommands": "要搜索统计数据,请使用以下命令:\r\n/usage [电子邮件]\r\n\r\nTelegram 聊天 ID:\r\n/id",
"restartUsage": "\r\n\r\n/restart",
- "restartSuccess": "✅ 操作成功!",
- "restartFailed": "❗ 操作错误。\r\n\r\n错误: {{ .Error }}.",
"xrayNotRunning": "❗ Xray Core 未运行。",
"startDesc": "显示主菜单",
"helpDesc": "机器人帮助",
diff --git a/internal/web/translation/zh-TW.json b/internal/web/translation/zh-TW.json
index 12bd300..f73f689 100644
--- a/internal/web/translation/zh-TW.json
+++ b/internal/web/translation/zh-TW.json
@@ -282,6 +282,28 @@
"streamTab": "傳輸",
"securityTab": "安全",
"sniffingTab": "嗅探",
+ "forwardingTab": "Forwarding",
+ "forwarding": {
+ "mode": "Forwarding",
+ "direct": "Direct",
+ "forward": "Forward (entry → exit)",
+ "landing": "Landing",
+ "managed": "Managed landing",
+ "manual": "Manual endpoint",
+ "target": "Landing inbound",
+ "targetPlaceholder": "Pick a SOCKS (mixed) inbound",
+ "targetDisabled": "disabled",
+ "address": "Landing address",
+ "port": "Exit port",
+ "protocol": "Entry → exit protocol",
+ "username": "SOCKS5 username",
+ "password": "Landing password",
+ "importLink": "Import from link",
+ "importPlaceholder": "socks5://user:pass@host:port",
+ "importApply": "Import",
+ "importFailed": "Could not parse that link",
+ "help": "Applies when this inbound is deployed to an agent node: on every config pull the panel compiles this forwarding into a dedicated outbound plus a routing rule for that agent. A managed landing's address and credentials are resolved from the chosen inbound at build time."
+ },
"sniffingMetadataOnly": "僅中繼資料",
"sniffingRouteOnly": "僅路由",
"sniffingIpsExcluded": "排除的 IP",
@@ -1251,16 +1273,6 @@
"Balancers": "負載均衡",
"balancerTagRequired": "標籤為必填",
"balancerSelectorRequired": "至少選擇一個出站",
- "routeTester": "路由測試",
- "routeTesterDesc": "向執行中的 Xray 查詢某個連線將使用哪個出站。不會傳送真實流量 — 結果直接來自即時路由引擎。",
- "routeTesterDest": "網域或 IP",
- "routeTesterPort": "埠號",
- "routeTesterInbound": "入站",
- "routeTesterProtocol": "嗅探協議",
- "routeTesterTest": "測試路由",
- "routeTesterMatchedOutbound": "匹配出站",
- "routeTesterViaBalancer": "經由負載均衡器",
- "routeTesterDefaultOutbound": "無路由規則匹配 — 流量將導向預設(第一個)出站。",
"Routings": "路由規則",
"logLevel": "日誌級別",
"logLevelDesc": "錯誤日誌的日誌級別,用於指示需要記錄的資訊",
@@ -1717,7 +1729,6 @@
"inbounds": "入站",
"clients": "客戶端",
"offline": "🔴 離線",
- "online": "🟢 上線",
"commands": {
"unknown": "❗ 未知命令",
"pleaseChoose": "👇 請選擇:\r\n",
@@ -1730,8 +1741,6 @@
"helpAdminCommands": "要重新啟動 Xray Core:\r\n/restart\r\n\r\n要搜尋客戶電子郵件:\r\n/usage [電子郵件]\r\n\r\n要搜尋入站(帶有客戶統計資料):\r\n/inbound [備註]\r\n\r\nTelegram 聊天 ID:\r\n/id",
"helpClientCommands": "要搜尋統計資料,請使用以下命令:\r\n/usage [電子郵件]\r\n\r\nTelegram 聊天 ID:\r\n/id",
"restartUsage": "\r\n\r\n/restart",
- "restartSuccess": "✅ 操作成功!",
- "restartFailed": "❗ 操作錯誤。\r\n\r\n錯誤: {{ .Error }}.",
"xrayNotRunning": "❗ Xray Core 未運行。",
"startDesc": "顯示主選單",
"helpDesc": "機器人幫助",