Kaynağa Gözat

i18n: translate hardcoded inbound action + security warning strings (#4502)

The inbound row actions (delete / reset traffic / clone / export links /
export subscription links / show JSON / export-all variants) and the
security warning alert on the Settings page were emitting English text
directly. Replace them with i18n keys and add translations across all
13 supported locales.
Sanaei 1 gün önce
ebeveyn
işleme
95aebf1d83

+ 25 - 25
frontend/src/pages/inbounds/InboundsPage.tsx

@@ -235,15 +235,15 @@ export default function InboundsPage() {
   const exportInboundLinks = useCallback((dbInbound: any) => {
     const projected = checkFallback(dbInbound);
     openText({
-      title: 'Export inbound links',
+      title: t('pages.inbounds.exportLinksTitle'),
       content: projected.genInboundLinks(remarkModel, hostOverrideFor(dbInbound)),
       fileName: projected.remark || 'inbound',
     });
-  }, [checkFallback, remarkModel, hostOverrideFor, openText]);
+  }, [checkFallback, remarkModel, hostOverrideFor, openText, t]);
 
   const exportInboundClipboard = useCallback((dbInbound: any) => {
-    openText({ title: 'Inbound JSON', content: JSON.stringify(dbInbound, null, 2) });
-  }, [openText]);
+    openText({ title: t('pages.inbounds.inboundJsonTitle'), content: JSON.stringify(dbInbound, null, 2) });
+  }, [openText, t]);
 
   const exportInboundSubs = useCallback((dbInbound: any) => {
     const inbound = dbInbound.toInbound();
@@ -255,11 +255,11 @@ export default function InboundsPage() {
       }
     }
     openText({
-      title: 'Export subscription links',
+      title: t('pages.inbounds.exportSubsTitle'),
       content: [...new Set(subLinks)].join('\n'),
       fileName: `${dbInbound.remark || 'inbound'}-Subs`,
     });
-  }, [subSettings, openText]);
+  }, [subSettings, openText, t]);
 
   const exportAllLinks = useCallback(async () => {
     const hydrated = await Promise.all(
@@ -270,8 +270,8 @@ export default function InboundsPage() {
       const projected = checkFallback(ib);
       out.push(projected.genInboundLinks(remarkModel, hostOverrideFor(ib)));
     }
-    openText({ title: 'Export all inbound links', content: out.join('\r\n'), fileName: 'All-Inbounds' });
-  }, [dbInbounds, hydrateInbound, checkFallback, remarkModel, hostOverrideFor, openText]);
+    openText({ title: t('pages.inbounds.exportAllLinksTitle'), content: out.join('\r\n'), fileName: 'All-Inbounds' });
+  }, [dbInbounds, hydrateInbound, checkFallback, remarkModel, hostOverrideFor, openText, t]);
 
   const exportAllSubs = useCallback(async () => {
     const hydrated = await Promise.all(
@@ -287,8 +287,8 @@ export default function InboundsPage() {
         }
       }
     }
-    openText({ title: 'Export all subscription links', content: [...new Set(out)].join('\r\n'), fileName: 'All-Inbounds-Subs' });
-  }, [dbInbounds, hydrateInbound, subSettings, openText]);
+    openText({ title: t('pages.inbounds.exportAllSubsTitle'), content: [...new Set(out)].join('\r\n'), fileName: 'All-Inbounds-Subs' });
+  }, [dbInbounds, hydrateInbound, subSettings, openText, t]);
 
   const importInbound = useCallback(() => {
     openPrompt({
@@ -321,37 +321,37 @@ export default function InboundsPage() {
 
   const confirmDelete = useCallback((dbInbound: any) => {
     modal.confirm({
-      title: `Delete inbound "${dbInbound.remark}"?`,
-      content: 'This removes the inbound and all its clients. This cannot be undone.',
-      okText: 'Delete',
+      title: t('pages.inbounds.deleteConfirmTitle', { remark: dbInbound.remark }),
+      content: t('pages.inbounds.deleteConfirmContent'),
+      okText: t('delete'),
       okType: 'danger',
-      cancelText: 'Cancel',
+      cancelText: t('cancel'),
       onOk: async () => {
         const msg = await HttpUtil.post(`/panel/api/inbounds/del/${dbInbound.id}`);
         if (msg?.success) await refresh();
       },
     });
-  }, [modal, refresh]);
+  }, [modal, refresh, t]);
 
   const confirmResetTraffic = useCallback((dbInbound: any) => {
     modal.confirm({
-      title: `Reset traffic for "${dbInbound.remark}"?`,
-      content: 'Resets up/down counters to 0 for this inbound.',
-      okText: 'Reset',
-      cancelText: 'Cancel',
+      title: t('pages.inbounds.resetConfirmTitle', { remark: dbInbound.remark }),
+      content: t('pages.inbounds.resetConfirmContent'),
+      okText: t('reset'),
+      cancelText: t('cancel'),
       onOk: async () => {
         const msg = await HttpUtil.post(`/panel/api/inbounds/${dbInbound.id}/resetTraffic`);
         if (msg?.success) await refresh();
       },
     });
-  }, [modal, refresh]);
+  }, [modal, refresh, t]);
 
   const confirmClone = useCallback((dbInbound: any) => {
     modal.confirm({
-      title: `Clone inbound "${dbInbound.remark}"?`,
-      content: 'Creates a copy with a new port and an empty client list.',
-      okText: 'Clone',
-      cancelText: 'Cancel',
+      title: t('pages.inbounds.cloneConfirmTitle', { remark: dbInbound.remark }),
+      content: t('pages.inbounds.cloneConfirmContent'),
+      okText: t('pages.inbounds.clone'),
+      cancelText: t('cancel'),
       onOk: async () => {
         const baseInbound = dbInbound.toInbound();
         let clonedSettings: string;
@@ -380,7 +380,7 @@ export default function InboundsPage() {
         if (msg?.success) await refresh();
       },
     });
-  }, [modal, refresh]);
+  }, [modal, refresh, t]);
 
   const onGeneralAction = useCallback((key: GeneralAction) => {
     switch (key) {

+ 8 - 8
frontend/src/pages/settings/SettingsPage.tsx

@@ -175,14 +175,14 @@ export default function SettingsPage() {
   const confAlerts = useMemo<string[]>(() => {
     const out: string[] = [];
     if (window.location.protocol !== 'https:') {
-      out.push('Panel is served over plain HTTP — set up TLS for production.');
+      out.push(t('pages.settings.warnHttp'));
     }
     if (allSetting.webPort === 2053) {
-      out.push('Default port 2053 is well-known — change it to a random port.');
+      out.push(t('pages.settings.warnDefaultPort'));
     }
     const segs = window.location.pathname.split('/').length < 4;
     if (segs && allSetting.webBasePath === '/') {
-      out.push('Default base path "/" is well-known — change it to a random path.');
+      out.push(t('pages.settings.warnDefaultBasePath'));
     }
     if (allSetting.subEnable) {
       let subPath = allSetting.subPath;
@@ -190,7 +190,7 @@ export default function SettingsPage() {
         try { subPath = new URL(allSetting.subURI).pathname; } catch { /* noop */ }
       }
       if (subPath === '/sub/') {
-        out.push('Default subscription path "/sub/" is well-known — change it.');
+        out.push(t('pages.settings.warnDefaultSubPath'));
       }
     }
     if (allSetting.subJsonEnable) {
@@ -199,11 +199,11 @@ export default function SettingsPage() {
         try { p = new URL(allSetting.subJsonURI).pathname; } catch { /* noop */ }
       }
       if (p === '/json/') {
-        out.push('Default JSON subscription path "/json/" is well-known — change it.');
+        out.push(t('pages.settings.warnDefaultJsonPath'));
       }
     }
     return out;
-  }, [allSetting]);
+  }, [allSetting, t]);
 
   const pageClass = useMemo(() => {
     const classes = ['settings-page'];
@@ -286,10 +286,10 @@ export default function SettingsPage() {
                       closable
                       className="conf-alert"
                       onClose={() => setAlertVisible(false)}
-                      title="Security warnings"
+                      title={t('pages.settings.securityWarnings')}
                       description={(
                         <>
-                          <b>Your panel may be exposed:</b>
+                          <b>{t('pages.settings.panelExposed')}</b>
                           <ul>
                             {confAlerts.map((msg, i) => <li key={i}>{msg}</li>)}
                           </ul>

+ 18 - 0
web/translation/ar-EG.json

@@ -283,6 +283,17 @@
       "modifyInbound": "تعديل الإدخال",
       "deleteInbound": "حذف الإدخال",
       "deleteInboundContent": "متأكد إنك عايز تحذف الإدخال؟",
+      "deleteConfirmTitle": "حذف الإدخال \"{remark}\"؟",
+      "deleteConfirmContent": "سيؤدي هذا إلى إزالة الإدخال وجميع عملائه. لا يمكن التراجع.",
+      "resetConfirmTitle": "إعادة تعيين ترافيك \"{remark}\"؟",
+      "resetConfirmContent": "يعيد عدادات الإرسال/الاستقبال لهذا الإدخال إلى 0.",
+      "cloneConfirmTitle": "نسخ الإدخال \"{remark}\"؟",
+      "cloneConfirmContent": "ينشئ نسخة بمنفذ جديد وقائمة عملاء فارغة.",
+      "exportLinksTitle": "تصدير روابط الإدخال",
+      "exportSubsTitle": "تصدير روابط الاشتراك",
+      "exportAllLinksTitle": "تصدير كل روابط الإدخالات",
+      "exportAllSubsTitle": "تصدير كل روابط الاشتراكات",
+      "inboundJsonTitle": "JSON الإدخال",
       "deleteClient": "حذف العميل",
       "deleteClientContent": "متأكد إنك عايز تحذف العميل؟",
       "resetTrafficContent": "متأكد إنك عايز تعيد ضبط الترافيك؟",
@@ -583,6 +594,13 @@
       "resetDefaultConfig": "استرجاع الافتراضي",
       "panelSettings": "عام",
       "securitySettings": "المصادقة",
+      "securityWarnings": "تحذيرات الأمان",
+      "panelExposed": "قد تكون لوحتك مكشوفة:",
+      "warnHttp": "اللوحة تُقدَّم عبر HTTP عادي — قم بإعداد TLS للإنتاج.",
+      "warnDefaultPort": "المنفذ الافتراضي 2053 معروف — غيّره إلى منفذ عشوائي.",
+      "warnDefaultBasePath": "المسار الأساسي الافتراضي \"/\" معروف — غيّره إلى مسار عشوائي.",
+      "warnDefaultSubPath": "مسار الاشتراك الافتراضي \"/sub/\" معروف — قم بتغييره.",
+      "warnDefaultJsonPath": "مسار اشتراك JSON الافتراضي \"/json/\" معروف — قم بتغييره.",
       "TGBotSettings": "بوت Telegram",
       "panelListeningIP": "IP الاستماع",
       "panelListeningIPDesc": "عنوان IP للبانل. (سيبه فاضي عشان يستمع على كل الـ IPs)",

+ 18 - 0
web/translation/en-US.json

@@ -283,6 +283,17 @@
       "modifyInbound": "Modify Inbound",
       "deleteInbound": "Delete Inbound",
       "deleteInboundContent": "Are you sure you want to delete this inbound?",
+      "deleteConfirmTitle": "Delete inbound \"{remark}\"?",
+      "deleteConfirmContent": "This removes the inbound and all its clients. This cannot be undone.",
+      "resetConfirmTitle": "Reset traffic for \"{remark}\"?",
+      "resetConfirmContent": "Resets up/down counters to 0 for this inbound.",
+      "cloneConfirmTitle": "Clone inbound \"{remark}\"?",
+      "cloneConfirmContent": "Creates a copy with a new port and an empty client list.",
+      "exportLinksTitle": "Export inbound links",
+      "exportSubsTitle": "Export subscription links",
+      "exportAllLinksTitle": "Export all inbound links",
+      "exportAllSubsTitle": "Export all subscription links",
+      "inboundJsonTitle": "Inbound JSON",
       "deleteClient": "Delete Client",
       "deleteClientContent": "Are you sure you want to delete this client?",
       "resetTrafficContent": "Are you sure you want to reset traffic?",
@@ -583,6 +594,13 @@
       "resetDefaultConfig": "Reset to Default",
       "panelSettings": "General",
       "securitySettings": "Authentication",
+      "securityWarnings": "Security warnings",
+      "panelExposed": "Your panel may be exposed:",
+      "warnHttp": "Panel is served over plain HTTP — set up TLS for production.",
+      "warnDefaultPort": "Default port 2053 is well-known — change it to a random port.",
+      "warnDefaultBasePath": "Default base path \"/\" is well-known — change it to a random path.",
+      "warnDefaultSubPath": "Default subscription path \"/sub/\" is well-known — change it.",
+      "warnDefaultJsonPath": "Default JSON subscription path \"/json/\" is well-known — change it.",
       "TGBotSettings": "Telegram Bot",
       "panelListeningIP": "Listen IP",
       "panelListeningIPDesc": "The IP address for the web panel. (leave blank to listen on all IPs)",

+ 18 - 0
web/translation/es-ES.json

@@ -283,6 +283,17 @@
       "modifyInbound": "Modificar Entrada",
       "deleteInbound": "Eliminar Entrada",
       "deleteInboundContent": "¿Confirmar eliminación de entrada?",
+      "deleteConfirmTitle": "¿Eliminar el inbound \"{remark}\"?",
+      "deleteConfirmContent": "Esto elimina el inbound y todos sus clientes. No se puede deshacer.",
+      "resetConfirmTitle": "¿Restablecer el tráfico de \"{remark}\"?",
+      "resetConfirmContent": "Restablece los contadores de subida/bajada a 0 para este inbound.",
+      "cloneConfirmTitle": "¿Clonar el inbound \"{remark}\"?",
+      "cloneConfirmContent": "Crea una copia con un puerto nuevo y una lista de clientes vacía.",
+      "exportLinksTitle": "Exportar enlaces del inbound",
+      "exportSubsTitle": "Exportar enlaces de suscripción",
+      "exportAllLinksTitle": "Exportar todos los enlaces de inbound",
+      "exportAllSubsTitle": "Exportar todos los enlaces de suscripción",
+      "inboundJsonTitle": "JSON del inbound",
       "deleteClient": "Eliminar cliente",
       "deleteClientContent": "¿Está seguro de que desea eliminar el cliente?",
       "resetTrafficContent": "¿Confirmar restablecimiento de tráfico?",
@@ -583,6 +594,13 @@
       "resetDefaultConfig": "Restablecer a Configuración Predeterminada",
       "panelSettings": "Configuraciones del Panel",
       "securitySettings": "Configuraciones de Seguridad",
+      "securityWarnings": "Advertencias de seguridad",
+      "panelExposed": "Es posible que su panel esté expuesto:",
+      "warnHttp": "El panel se sirve por HTTP sin cifrar — configure TLS para producción.",
+      "warnDefaultPort": "El puerto por defecto 2053 es conocido — cámbielo a uno aleatorio.",
+      "warnDefaultBasePath": "La ruta base por defecto \"/\" es conocida — cámbiela a una ruta aleatoria.",
+      "warnDefaultSubPath": "La ruta de suscripción por defecto \"/sub/\" es conocida — cámbiela.",
+      "warnDefaultJsonPath": "La ruta de suscripción JSON por defecto \"/json/\" es conocida — cámbiela.",
       "TGBotSettings": "Configuraciones de Bot de Telegram",
       "panelListeningIP": "IP de Escucha del Panel",
       "panelListeningIPDesc": "Dejar en blanco por defecto para monitorear todas las IPs.",

+ 18 - 0
web/translation/fa-IR.json

@@ -283,6 +283,17 @@
       "modifyInbound": "ویرایش ورودی",
       "deleteInbound": "حذف ورودی",
       "deleteInboundContent": "آیا مطمئن به حذف ورودی هستید؟",
+      "deleteConfirmTitle": "اینباند «{remark}» حذف شود؟",
+      "deleteConfirmContent": "این اینباند و تمام کلاینت‌های آن حذف می‌شود. این عمل غیرقابل بازگشت است.",
+      "resetConfirmTitle": "ترافیک اینباند «{remark}» صفر شود؟",
+      "resetConfirmContent": "شمارنده‌های ارسال/دریافت این اینباند به صفر برمی‌گردد.",
+      "cloneConfirmTitle": "اینباند «{remark}» کپی شود؟",
+      "cloneConfirmContent": "یک نسخه با پورت جدید و لیست کلاینت خالی ساخته می‌شود.",
+      "exportLinksTitle": "خروجی لینک‌های اینباند",
+      "exportSubsTitle": "خروجی لینک‌های ساب",
+      "exportAllLinksTitle": "خروجی لینک‌های همه اینباندها",
+      "exportAllSubsTitle": "خروجی لینک‌های ساب همه اینباندها",
+      "inboundJsonTitle": "JSON اینباند",
       "deleteClient": "حذف کاربر",
       "deleteClientContent": "آیا مطمئن به حذف کاربر هستید؟",
       "resetTrafficContent": "آیا مطمئن به ریست ترافیک هستید؟",
@@ -583,6 +594,13 @@
       "resetDefaultConfig": "برگشت به پیش‌فرض",
       "panelSettings": "پیکربندی",
       "securitySettings": "احرازهویت",
+      "securityWarnings": "هشدارهای امنیتی",
+      "panelExposed": "ممکن است پنل شما در معرض خطر باشد:",
+      "warnHttp": "پنل از طریق HTTP ساده ارائه می‌شود — برای محیط عملیاتی TLS فعال کنید.",
+      "warnDefaultPort": "پورت پیش‌فرض 2053 شناخته‌شده است — آن را به یک پورت تصادفی تغییر دهید.",
+      "warnDefaultBasePath": "مسیر پایه پیش‌فرض «/» شناخته‌شده است — آن را به یک مسیر تصادفی تغییر دهید.",
+      "warnDefaultSubPath": "مسیر ساب پیش‌فرض «/sub/» شناخته‌شده است — تغییرش دهید.",
+      "warnDefaultJsonPath": "مسیر JSON ساب پیش‌فرض «/json/» شناخته‌شده است — تغییرش دهید.",
       "TGBotSettings": "ربات تلگرام",
       "panelListeningIP": "آدرس آی‌پی",
       "panelListeningIPDesc": "آدرس آی‌پی برای وب پنل. برای گوش‌دادن به‌تمام آی‌پی‌ها خالی‌بگذارید",

+ 18 - 0
web/translation/id-ID.json

@@ -283,6 +283,17 @@
       "modifyInbound": "Ubah Masuk",
       "deleteInbound": "Hapus Masuk",
       "deleteInboundContent": "Apakah Anda yakin ingin menghapus masuk?",
+      "deleteConfirmTitle": "Hapus inbound \"{remark}\"?",
+      "deleteConfirmContent": "Tindakan ini menghapus inbound beserta semua kliennya. Tidak dapat dibatalkan.",
+      "resetConfirmTitle": "Reset trafik \"{remark}\"?",
+      "resetConfirmContent": "Mengatur ulang counter unggah/unduh ke 0 untuk inbound ini.",
+      "cloneConfirmTitle": "Klon inbound \"{remark}\"?",
+      "cloneConfirmContent": "Membuat salinan dengan port baru dan daftar klien kosong.",
+      "exportLinksTitle": "Ekspor tautan inbound",
+      "exportSubsTitle": "Ekspor tautan langganan",
+      "exportAllLinksTitle": "Ekspor semua tautan inbound",
+      "exportAllSubsTitle": "Ekspor semua tautan langganan",
+      "inboundJsonTitle": "JSON inbound",
       "deleteClient": "Hapus Klien",
       "deleteClientContent": "Apakah Anda yakin ingin menghapus klien?",
       "resetTrafficContent": "Apakah Anda yakin ingin mereset traffic?",
@@ -583,6 +594,13 @@
       "resetDefaultConfig": "Reset ke Default",
       "panelSettings": "Umum",
       "securitySettings": "Otentikasi",
+      "securityWarnings": "Peringatan keamanan",
+      "panelExposed": "Panel Anda mungkin terekspos:",
+      "warnHttp": "Panel disajikan melalui HTTP biasa — siapkan TLS untuk produksi.",
+      "warnDefaultPort": "Port default 2053 sudah umum diketahui — ubah ke port acak.",
+      "warnDefaultBasePath": "Base path default \"/\" sudah umum diketahui — ubah ke path acak.",
+      "warnDefaultSubPath": "Path langganan default \"/sub/\" sudah umum diketahui — ubahlah.",
+      "warnDefaultJsonPath": "Path langganan JSON default \"/json/\" sudah umum diketahui — ubahlah.",
       "TGBotSettings": "Bot Telegram",
       "panelListeningIP": "IP Pendengar",
       "panelListeningIPDesc": "Alamat IP untuk panel web. (biarkan kosong untuk mendengarkan semua IP)",

+ 18 - 0
web/translation/ja-JP.json

@@ -283,6 +283,17 @@
       "modifyInbound": "インバウンド修正",
       "deleteInbound": "インバウンド削除",
       "deleteInboundContent": "インバウンドを削除してもよろしいですか?",
+      "deleteConfirmTitle": "インバウンド「{remark}」を削除しますか?",
+      "deleteConfirmContent": "インバウンドと関連付けされたすべてのクライアントを削除します。元に戻せません。",
+      "resetConfirmTitle": "「{remark}」のトラフィックをリセットしますか?",
+      "resetConfirmContent": "このインバウンドの送受信カウンタを 0 にリセットします。",
+      "cloneConfirmTitle": "インバウンド「{remark}」を複製しますか?",
+      "cloneConfirmContent": "新しいポートと空のクライアント一覧でコピーを作成します。",
+      "exportLinksTitle": "インバウンドリンクのエクスポート",
+      "exportSubsTitle": "サブスクリプションリンクのエクスポート",
+      "exportAllLinksTitle": "全インバウンドリンクのエクスポート",
+      "exportAllSubsTitle": "全サブスクリプションリンクのエクスポート",
+      "inboundJsonTitle": "インバウンド JSON",
       "deleteClient": "クライアント削除",
       "deleteClientContent": "クライアントを削除してもよろしいですか?",
       "resetTrafficContent": "トラフィックをリセットしてもよろしいですか?",
@@ -583,6 +594,13 @@
       "resetDefaultConfig": "デフォルト設定にリセット",
       "panelSettings": "一般",
       "securitySettings": "セキュリティ設定",
+      "securityWarnings": "セキュリティ警告",
+      "panelExposed": "パネルが露出している可能性があります:",
+      "warnHttp": "パネルが平文 HTTP で提供されています — 本番環境には TLS を設定してください。",
+      "warnDefaultPort": "デフォルトポート 2053 はよく知られています — ランダムなポートに変更してください。",
+      "warnDefaultBasePath": "デフォルトのベースパス \"/\" はよく知られています — ランダムなパスに変更してください。",
+      "warnDefaultSubPath": "デフォルトのサブスクリプションパス \"/sub/\" はよく知られています — 変更してください。",
+      "warnDefaultJsonPath": "デフォルトの JSON サブスクリプションパス \"/json/\" はよく知られています — 変更してください。",
       "TGBotSettings": "Telegramボット設定",
       "panelListeningIP": "パネル監視IP",
       "panelListeningIPDesc": "デフォルトではすべてのIPを監視する",

+ 18 - 0
web/translation/pt-BR.json

@@ -283,6 +283,17 @@
       "modifyInbound": "Modificar Inbound",
       "deleteInbound": "Excluir Inbound",
       "deleteInboundContent": "Tem certeza de que deseja excluir o inbound?",
+      "deleteConfirmTitle": "Excluir o inbound \"{remark}\"?",
+      "deleteConfirmContent": "Isto remove o inbound e todos os seus clientes. Não é possível desfazer.",
+      "resetConfirmTitle": "Redefinir o tráfego de \"{remark}\"?",
+      "resetConfirmContent": "Zera os contadores de envio/recebimento para este inbound.",
+      "cloneConfirmTitle": "Clonar o inbound \"{remark}\"?",
+      "cloneConfirmContent": "Cria uma cópia com uma nova porta e lista de clientes vazia.",
+      "exportLinksTitle": "Exportar links do inbound",
+      "exportSubsTitle": "Exportar links de assinatura",
+      "exportAllLinksTitle": "Exportar todos os links de inbound",
+      "exportAllSubsTitle": "Exportar todos os links de assinatura",
+      "inboundJsonTitle": "JSON do inbound",
       "deleteClient": "Excluir Cliente",
       "deleteClientContent": "Tem certeza de que deseja excluir o cliente?",
       "resetTrafficContent": "Tem certeza de que deseja redefinir o tráfego?",
@@ -583,6 +594,13 @@
       "resetDefaultConfig": "Redefinir para Padrão",
       "panelSettings": "Geral",
       "securitySettings": "Autenticação",
+      "securityWarnings": "Avisos de segurança",
+      "panelExposed": "Seu painel pode estar exposto:",
+      "warnHttp": "O painel é servido por HTTP simples — configure TLS para produção.",
+      "warnDefaultPort": "A porta padrão 2053 é bem conhecida — altere para uma porta aleatória.",
+      "warnDefaultBasePath": "O caminho base padrão \"/\" é bem conhecido — altere para um caminho aleatório.",
+      "warnDefaultSubPath": "O caminho de assinatura padrão \"/sub/\" é bem conhecido — altere-o.",
+      "warnDefaultJsonPath": "O caminho de assinatura JSON padrão \"/json/\" é bem conhecido — altere-o.",
       "TGBotSettings": "Bot do Telegram",
       "panelListeningIP": "IP de Escuta",
       "panelListeningIPDesc": "O endereço IP para o painel web. (deixe em branco para escutar em todos os IPs)",

+ 18 - 0
web/translation/ru-RU.json

@@ -283,6 +283,17 @@
       "modifyInbound": "Изменить подключение",
       "deleteInbound": "Удалить подключение",
       "deleteInboundContent": "Вы уверены, что хотите удалить подключение?",
+      "deleteConfirmTitle": "Удалить подключение \"{remark}\"?",
+      "deleteConfirmContent": "Подключение и все его клиенты будут удалены. Это действие нельзя отменить.",
+      "resetConfirmTitle": "Сбросить трафик \"{remark}\"?",
+      "resetConfirmContent": "Сбрасывает счётчики отправки/получения этого подключения до 0.",
+      "cloneConfirmTitle": "Клонировать подключение \"{remark}\"?",
+      "cloneConfirmContent": "Создаёт копию с новым портом и пустым списком клиентов.",
+      "exportLinksTitle": "Экспортировать ссылки подключения",
+      "exportSubsTitle": "Экспортировать ссылки подписки",
+      "exportAllLinksTitle": "Экспортировать все ссылки подключений",
+      "exportAllSubsTitle": "Экспортировать все ссылки подписок",
+      "inboundJsonTitle": "JSON подключения",
       "deleteClient": "Удалить клиента",
       "deleteClientContent": "Вы уверены, что хотите удалить клиента?",
       "resetTrafficContent": "Вы уверены, что хотите сбросить трафик?",
@@ -583,6 +594,13 @@
       "resetDefaultConfig": "Восстановить настройки по умолчанию",
       "panelSettings": "Панель",
       "securitySettings": "Учетная запись",
+      "securityWarnings": "Предупреждения безопасности",
+      "panelExposed": "Ваша панель может быть открыта:",
+      "warnHttp": "Панель работает по обычному HTTP — настройте TLS для продакшна.",
+      "warnDefaultPort": "Стандартный порт 2053 широко известен — измените его на случайный.",
+      "warnDefaultBasePath": "Базовый путь по умолчанию \"/\" широко известен — измените его на случайный.",
+      "warnDefaultSubPath": "Путь подписки по умолчанию \"/sub/\" широко известен — измените его.",
+      "warnDefaultJsonPath": "JSON-путь подписки по умолчанию \"/json/\" широко известен — измените его.",
       "TGBotSettings": "Telegram-Бот",
       "panelListeningIP": "IP-адрес для управления панелью",
       "panelListeningIPDesc": "Оставьте пустым для подключения с любого IP",

+ 18 - 0
web/translation/tr-TR.json

@@ -283,6 +283,17 @@
       "modifyInbound": "Geleni Düzenle",
       "deleteInbound": "Geleni Sil",
       "deleteInboundContent": "Geleni silmek istediğinizden emin misiniz?",
+      "deleteConfirmTitle": "\"{remark}\" inbound silinsin mi?",
+      "deleteConfirmContent": "Bu işlem inbound'u ve tüm istemcilerini siler. Geri alınamaz.",
+      "resetConfirmTitle": "\"{remark}\" trafiği sıfırlansın mı?",
+      "resetConfirmContent": "Bu inbound için gönderme/alma sayaçlarını 0'a sıfırlar.",
+      "cloneConfirmTitle": "\"{remark}\" inbound klonlansın mı?",
+      "cloneConfirmContent": "Yeni bir port ve boş istemci listesiyle bir kopya oluşturur.",
+      "exportLinksTitle": "Inbound bağlantılarını dışa aktar",
+      "exportSubsTitle": "Abonelik bağlantılarını dışa aktar",
+      "exportAllLinksTitle": "Tüm inbound bağlantılarını dışa aktar",
+      "exportAllSubsTitle": "Tüm abonelik bağlantılarını dışa aktar",
+      "inboundJsonTitle": "Inbound JSON",
       "deleteClient": "Müşteriyi Sil",
       "deleteClientContent": "Müşteriyi silmek istediğinizden emin misiniz?",
       "resetTrafficContent": "Trafiği sıfırlamak istediğinizden emin misiniz?",
@@ -583,6 +594,13 @@
       "resetDefaultConfig": "Varsayılana Sıfırla",
       "panelSettings": "Genel",
       "securitySettings": "Kimlik Doğrulama",
+      "securityWarnings": "Güvenlik uyarıları",
+      "panelExposed": "Paneliniz açıkta olabilir:",
+      "warnHttp": "Panel düz HTTP üzerinden sunuluyor — üretim için TLS kurun.",
+      "warnDefaultPort": "Varsayılan port 2053 yaygın olarak biliniyor — rastgele bir porta değiştirin.",
+      "warnDefaultBasePath": "Varsayılan temel yol \"/\" yaygın olarak biliniyor — rastgele bir yola değiştirin.",
+      "warnDefaultSubPath": "Varsayılan abonelik yolu \"/sub/\" yaygın olarak biliniyor — değiştirin.",
+      "warnDefaultJsonPath": "Varsayılan JSON abonelik yolu \"/json/\" yaygın olarak biliniyor — değiştirin.",
       "TGBotSettings": "Telegram Bot",
       "panelListeningIP": "Dinleme IP",
       "panelListeningIPDesc": "Web paneli için IP adresi. (tüm IP'leri dinlemek için boş bırakın)",

+ 18 - 0
web/translation/uk-UA.json

@@ -283,6 +283,17 @@
       "modifyInbound": "Змінити вхідний",
       "deleteInbound": "Видалити вхідні",
       "deleteInboundContent": "Ви впевнені, що хочете видалити вхідні?",
+      "deleteConfirmTitle": "Видалити вхідні \"{remark}\"?",
+      "deleteConfirmContent": "Це видалить вхідні та всіх його клієнтів. Цю дію неможливо скасувати.",
+      "resetConfirmTitle": "Скинути трафік \"{remark}\"?",
+      "resetConfirmContent": "Скидає лічильники відправки/отримання цього вхідного до 0.",
+      "cloneConfirmTitle": "Клонувати вхідні \"{remark}\"?",
+      "cloneConfirmContent": "Створює копію з новим портом і порожнім списком клієнтів.",
+      "exportLinksTitle": "Експортувати посилання вхідних",
+      "exportSubsTitle": "Експортувати посилання підписок",
+      "exportAllLinksTitle": "Експортувати всі посилання вхідних",
+      "exportAllSubsTitle": "Експортувати всі посилання підписок",
+      "inboundJsonTitle": "JSON вхідних",
       "deleteClient": "Видалити клієнта",
       "deleteClientContent": "Ви впевнені, що хочете видалити клієнт?",
       "resetTrafficContent": "Ви впевнені, що хочете скинути трафік?",
@@ -583,6 +594,13 @@
       "resetDefaultConfig": "Відновити значення за замовчуванням",
       "panelSettings": "Загальні",
       "securitySettings": "Автентифікація",
+      "securityWarnings": "Попередження безпеки",
+      "panelExposed": "Ваша панель може бути відкрита:",
+      "warnHttp": "Панель працює через звичайний HTTP — налаштуйте TLS для продакшну.",
+      "warnDefaultPort": "Стандартний порт 2053 широко відомий — змініть його на випадковий.",
+      "warnDefaultBasePath": "Базовий шлях за замовчуванням \"/\" широко відомий — змініть його на випадковий.",
+      "warnDefaultSubPath": "Шлях підписки за замовчуванням \"/sub/\" широко відомий — змініть його.",
+      "warnDefaultJsonPath": "JSON-шлях підписки за замовчуванням \"/json/\" широко відомий — змініть його.",
       "TGBotSettings": "Telegram Бот",
       "panelListeningIP": "Слухати IP",
       "panelListeningIPDesc": "IP-адреса для веб-панелі. (залиште порожнім, щоб слухати всі IP-адреси)",

+ 18 - 0
web/translation/vi-VN.json

@@ -283,6 +283,17 @@
       "modifyInbound": "Chỉnh sửa điểm vào (Inbound)",
       "deleteInbound": "Xóa điểm vào (Inbound)",
       "deleteInboundContent": "Xác nhận xóa điểm vào? (Inbound)",
+      "deleteConfirmTitle": "Xóa inbound \"{remark}\"?",
+      "deleteConfirmContent": "Hành động này xóa inbound và toàn bộ khách hàng của nó. Không thể hoàn tác.",
+      "resetConfirmTitle": "Đặt lại lưu lượng của \"{remark}\"?",
+      "resetConfirmContent": "Đặt lại bộ đếm lên/xuống về 0 cho inbound này.",
+      "cloneConfirmTitle": "Sao chép inbound \"{remark}\"?",
+      "cloneConfirmContent": "Tạo bản sao với cổng mới và danh sách khách hàng trống.",
+      "exportLinksTitle": "Xuất liên kết inbound",
+      "exportSubsTitle": "Xuất liên kết đăng ký",
+      "exportAllLinksTitle": "Xuất tất cả liên kết inbound",
+      "exportAllSubsTitle": "Xuất tất cả liên kết đăng ký",
+      "inboundJsonTitle": "JSON inbound",
       "deleteClient": "Xóa người dùng",
       "deleteClientContent": "Bạn có chắc chắn muốn xóa người dùng không?",
       "resetTrafficContent": "Xác nhận đặt lại lưu lượng?",
@@ -583,6 +594,13 @@
       "resetDefaultConfig": "Đặt lại cấu hình mặc định",
       "panelSettings": "Bảng điều khiển",
       "securitySettings": "Bảo mật",
+      "securityWarnings": "Cảnh báo bảo mật",
+      "panelExposed": "Bảng điều khiển của bạn có thể bị lộ:",
+      "warnHttp": "Panel đang chạy trên HTTP thuần — thiết lập TLS cho môi trường thật.",
+      "warnDefaultPort": "Cổng mặc định 2053 đã quá phổ biến — đổi sang cổng ngẫu nhiên.",
+      "warnDefaultBasePath": "Đường dẫn cơ sở mặc định \"/\" đã quá phổ biến — đổi sang đường dẫn ngẫu nhiên.",
+      "warnDefaultSubPath": "Đường dẫn đăng ký mặc định \"/sub/\" đã quá phổ biến — đổi nó.",
+      "warnDefaultJsonPath": "Đường dẫn đăng ký JSON mặc định \"/json/\" đã quá phổ biến — đổi nó.",
       "TGBotSettings": "Bot Telegram",
       "panelListeningIP": "IP Nghe của bảng điều khiển",
       "panelListeningIPDesc": "Mặc định để trống để nghe tất cả các IP.",

+ 18 - 0
web/translation/zh-CN.json

@@ -283,6 +283,17 @@
       "modifyInbound": "修改入站",
       "deleteInbound": "删除入站",
       "deleteInboundContent": "确定要删除入站吗?",
+      "deleteConfirmTitle": "删除入站 \"{remark}\"?",
+      "deleteConfirmContent": "将删除此入站及其所有客户端。该操作不可撤销。",
+      "resetConfirmTitle": "重置 \"{remark}\" 的流量?",
+      "resetConfirmContent": "将此入站的上/下行计数器清零。",
+      "cloneConfirmTitle": "克隆入站 \"{remark}\"?",
+      "cloneConfirmContent": "使用新端口和空客户端列表创建副本。",
+      "exportLinksTitle": "导出入站链接",
+      "exportSubsTitle": "导出订阅链接",
+      "exportAllLinksTitle": "导出所有入站链接",
+      "exportAllSubsTitle": "导出所有订阅链接",
+      "inboundJsonTitle": "入站 JSON",
       "deleteClient": "删除客户端",
       "deleteClientContent": "确定要删除客户端吗?",
       "resetTrafficContent": "确定要重置流量吗?",
@@ -583,6 +594,13 @@
       "resetDefaultConfig": "重置为默认配置",
       "panelSettings": "常规",
       "securitySettings": "安全设定",
+      "securityWarnings": "安全警告",
+      "panelExposed": "您的面板可能已暴露:",
+      "warnHttp": "面板通过明文 HTTP 提供服务 — 生产环境请配置 TLS。",
+      "warnDefaultPort": "默认端口 2053 众所周知 — 请更改为随机端口。",
+      "warnDefaultBasePath": "默认根路径 \"/\" 众所周知 — 请更改为随机路径。",
+      "warnDefaultSubPath": "默认订阅路径 \"/sub/\" 众所周知 — 请更改。",
+      "warnDefaultJsonPath": "默认 JSON 订阅路径 \"/json/\" 众所周知 — 请更改。",
       "TGBotSettings": "Telegram 机器人配置",
       "panelListeningIP": "面板监听 IP",
       "panelListeningIPDesc": "默认留空监听所有 IP",

+ 18 - 0
web/translation/zh-TW.json

@@ -283,6 +283,17 @@
       "modifyInbound": "修改入站",
       "deleteInbound": "刪除入站",
       "deleteInboundContent": "確定要刪除入站嗎?",
+      "deleteConfirmTitle": "刪除入站「{remark}」?",
+      "deleteConfirmContent": "將刪除此入站及其所有客戶端。此操作無法復原。",
+      "resetConfirmTitle": "重置「{remark}」的流量?",
+      "resetConfirmContent": "將此入站的上/下行計數器歸零。",
+      "cloneConfirmTitle": "複製入站「{remark}」?",
+      "cloneConfirmContent": "使用新連接埠和空客戶端清單建立副本。",
+      "exportLinksTitle": "匯出入站連結",
+      "exportSubsTitle": "匯出訂閱連結",
+      "exportAllLinksTitle": "匯出所有入站連結",
+      "exportAllSubsTitle": "匯出所有訂閱連結",
+      "inboundJsonTitle": "入站 JSON",
       "deleteClient": "刪除客戶端",
       "deleteClientContent": "確定要刪除客戶端嗎?",
       "resetTrafficContent": "確定要重置流量嗎?",
@@ -583,6 +594,13 @@
       "resetDefaultConfig": "重置為預設配置",
       "panelSettings": "常規",
       "securitySettings": "安全設定",
+      "securityWarnings": "安全警告",
+      "panelExposed": "您的面板可能已暴露:",
+      "warnHttp": "面板透過明文 HTTP 提供服務 — 生產環境請設定 TLS。",
+      "warnDefaultPort": "預設連接埠 2053 廣為人知 — 請更改為隨機連接埠。",
+      "warnDefaultBasePath": "預設根路徑 \"/\" 廣為人知 — 請更改為隨機路徑。",
+      "warnDefaultSubPath": "預設訂閱路徑 \"/sub/\" 廣為人知 — 請更改。",
+      "warnDefaultJsonPath": "預設 JSON 訂閱路徑 \"/json/\" 廣為人知 — 請更改。",
       "TGBotSettings": "Telegram 機器人配置",
       "panelListeningIP": "面板監聽 IP",
       "panelListeningIPDesc": "預設留空監聽所有 IP",