diff --git a/fe-app-tachyon/locales/calls.json b/fe-app-tachyon/locales/calls.json index 820fc133..f961e516 100644 --- a/fe-app-tachyon/locales/calls.json +++ b/fe-app-tachyon/locales/calls.json @@ -195,7 +195,7 @@ "key": "✔ Online", "places": [ "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9055", - "src/tachyon/tabs/dashboard/initController.ts:1976" + "src/tachyon/tabs/dashboard/initController.ts:1984" ] }, { @@ -207,11 +207,11 @@ "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9008", "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9017", "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9017", - "src/tachyon/tabs/dashboard/initController.ts:1906", - "src/tachyon/tabs/dashboard/initController.ts:1917", - "src/tachyon/tabs/dashboard/initController.ts:1918", - "src/tachyon/tabs/dashboard/initController.ts:1932", - "src/tachyon/tabs/dashboard/initController.ts:1933" + "src/tachyon/tabs/dashboard/initController.ts:1914", + "src/tachyon/tabs/dashboard/initController.ts:1925", + "src/tachyon/tabs/dashboard/initController.ts:1926", + "src/tachyon/tabs/dashboard/initController.ts:1940", + "src/tachyon/tabs/dashboard/initController.ts:1941" ] }, { @@ -219,7 +219,7 @@ "key": "✘ Offline", "places": [ "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9055", - "src/tachyon/tabs/dashboard/initController.ts:1976" + "src/tachyon/tabs/dashboard/initController.ts:1984" ] }, { @@ -228,8 +228,8 @@ "places": [ "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9001", "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9008", - "src/tachyon/tabs/dashboard/initController.ts:1906", - "src/tachyon/tabs/dashboard/initController.ts:1919" + "src/tachyon/tabs/dashboard/initController.ts:1914", + "src/tachyon/tabs/dashboard/initController.ts:1927" ] }, { @@ -539,9 +539,9 @@ "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:18226", "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/parental.js:464", "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/parental.js:470", - "src/tachyon/tabs/dashboard/initController.ts:1137", "src/tachyon/tabs/monitoring/initController.ts:722", - "src/tachyon/tabs/monitoring/render.ts:20" + "src/tachyon/tabs/monitoring/render.ts:20", + "src/tachyon/tabs/dashboard/initController.ts:1137" ] }, { @@ -583,7 +583,7 @@ "key": "Active Connections", "places": [ "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8986", - "src/tachyon/tabs/dashboard/initController.ts:1890" + "src/tachyon/tabs/dashboard/initController.ts:1898" ] }, { @@ -1457,7 +1457,7 @@ "src/tachyon/tabs/dashboard/initController.ts:927", "src/tachyon/tabs/dashboard/initController.ts:1365", "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:35", - "src/tachyon/tabs/dashboard/partials/renderSections.ts:594" + "src/tachyon/tabs/dashboard/partials/renderSections.ts:602" ] }, { @@ -2225,8 +2225,8 @@ "places": [ "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2661", "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2939", - "src/tachyon/tabs/dashboard/partials/renderSections.ts:574", - "src/tachyon/tabs/dashboard/partials/renderSections.ts:932" + "src/tachyon/tabs/dashboard/partials/renderSections.ts:582", + "src/tachyon/tabs/dashboard/partials/renderSections.ts:948" ] }, { @@ -2303,7 +2303,7 @@ "key": "Checking Connection...", "places": [ "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8775", - "src/tachyon/tabs/dashboard/initController.ts:1634" + "src/tachyon/tabs/dashboard/initController.ts:1642" ] }, { @@ -2348,10 +2348,10 @@ "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2656", "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2876", "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2932", - "src/tachyon/tabs/dashboard/partials/renderSections.ts:466", - "src/tachyon/tabs/dashboard/partials/renderSections.ts:568", - "src/tachyon/tabs/dashboard/partials/renderSections.ts:845", - "src/tachyon/tabs/dashboard/partials/renderSections.ts:921" + "src/tachyon/tabs/dashboard/partials/renderSections.ts:474", + "src/tachyon/tabs/dashboard/partials/renderSections.ts:576", + "src/tachyon/tabs/dashboard/partials/renderSections.ts:861", + "src/tachyon/tabs/dashboard/partials/renderSections.ts:937" ] }, { @@ -2607,9 +2607,9 @@ "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:2037", "src/partials/modal/renderModal.ts:263", "src/tachyon/tabs/diagnostic/initController.ts:1554", - "src/tachyon/tabs/dashboard/initController.ts:1277", "src/tachyon/tabs/monitoring/initController.ts:893", "src/tachyon/tabs/monitoring/initController.ts:948", + "src/tachyon/tabs/dashboard/initController.ts:1277", "src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:227", "src/tachyon/tabs/diagnostic/partials/renderDnsBenchmarkModal.ts:286", "src/tachyon/tabs/diagnostic/partials/renderLeakCheckModal.ts:379", @@ -2812,9 +2812,9 @@ "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2459", "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:5840", "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:15233", - "src/tachyon/methods/custom/getDashboardSections.ts:1695", + "src/tachyon/methods/custom/getDashboardSections.ts:1717", "src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:146", - "src/tachyon/tabs/dashboard/partials/renderSections.ts:314" + "src/tachyon/tabs/dashboard/partials/renderSections.ts:322" ] }, { @@ -2830,8 +2830,8 @@ "places": [ "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2583", "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2876", - "src/tachyon/tabs/dashboard/partials/renderSections.ts:472", - "src/tachyon/tabs/dashboard/partials/renderSections.ts:851" + "src/tachyon/tabs/dashboard/partials/renderSections.ts:480", + "src/tachyon/tabs/dashboard/partials/renderSections.ts:867" ] }, { @@ -2945,8 +2945,8 @@ "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2709", "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8449", "src/tachyon/tabs/dashboard/initController.ts:1202", - "src/tachyon/tabs/dashboard/partials/renderSections.ts:640", - "src/tachyon/tabs/dashboard/partials/renderSections.ts:641" + "src/tachyon/tabs/dashboard/partials/renderSections.ts:648", + "src/tachyon/tabs/dashboard/partials/renderSections.ts:649" ] }, { @@ -3872,8 +3872,8 @@ "places": [ "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8963", "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8975", - "src/tachyon/tabs/dashboard/initController.ts:1865", - "src/tachyon/tabs/dashboard/initController.ts:1878" + "src/tachyon/tabs/dashboard/initController.ts:1873", + "src/tachyon/tabs/dashboard/initController.ts:1886" ] }, { @@ -4799,12 +4799,12 @@ "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:20679", "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:20741", "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:20915", + "src/tachyon/methods/shell/index.ts:199", + "src/tachyon/methods/shell/index.ts:206", "src/tachyon/tabs/updates/initController.ts:693", "src/tachyon/tabs/updates/initController.ts:694", "src/tachyon/tabs/updates/initController.ts:773", - "src/tachyon/tabs/updates/initController.ts:989", - "src/tachyon/methods/shell/index.ts:199", - "src/tachyon/methods/shell/index.ts:206" + "src/tachyon/tabs/updates/initController.ts:989" ] }, { @@ -5278,7 +5278,7 @@ "key": "Fastest", "places": [ "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:5141", - "src/tachyon/methods/custom/getDashboardSections.ts:674" + "src/tachyon/methods/custom/getDashboardSections.ts:696" ] }, { @@ -7675,7 +7675,7 @@ "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8572", "src/tachyon/tabs/dashboard/initController.ts:918", "src/tachyon/tabs/dashboard/initController.ts:1356", - "src/tachyon/tabs/dashboard/partials/renderSections.ts:592" + "src/tachyon/tabs/dashboard/partials/renderSections.ts:600" ] }, { @@ -7796,7 +7796,7 @@ "key": "Memory Usage", "places": [ "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8987", - "src/tachyon/tabs/dashboard/initController.ts:1891" + "src/tachyon/tabs/dashboard/initController.ts:1899" ] }, { @@ -8440,10 +8440,10 @@ "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:5840", "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:10248", "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:15244", - "src/tachyon/methods/custom/getDashboardSections.ts:1698", + "src/tachyon/methods/custom/getDashboardSections.ts:1720", "src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:46", "src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:157", - "src/tachyon/tabs/dashboard/partials/renderSections.ts:317" + "src/tachyon/tabs/dashboard/partials/renderSections.ts:325" ] }, { @@ -8452,8 +8452,8 @@ "places": [ "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2583", "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2876", - "src/tachyon/tabs/dashboard/partials/renderSections.ts:473", - "src/tachyon/tabs/dashboard/partials/renderSections.ts:852" + "src/tachyon/tabs/dashboard/partials/renderSections.ts:481", + "src/tachyon/tabs/dashboard/partials/renderSections.ts:868" ] }, { @@ -8528,8 +8528,8 @@ "src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:118", "src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:124", "src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:190", - "src/tachyon/tabs/dashboard/partials/renderSections.ts:470", - "src/tachyon/tabs/dashboard/partials/renderSections.ts:849" + "src/tachyon/tabs/dashboard/partials/renderSections.ts:478", + "src/tachyon/tabs/dashboard/partials/renderSections.ts:865" ] }, { @@ -8922,7 +8922,7 @@ "key": "Other peers", "places": [ "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9097", - "src/tachyon/tabs/dashboard/initController.ts:2035" + "src/tachyon/tabs/dashboard/initController.ts:2043" ] }, { @@ -9471,8 +9471,8 @@ "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2741", "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8687", "src/tachyon/tabs/dashboard/initController.ts:1504", - "src/tachyon/tabs/dashboard/partials/renderSections.ts:678", - "src/tachyon/tabs/dashboard/partials/renderSections.ts:679" + "src/tachyon/tabs/dashboard/partials/renderSections.ts:686", + "src/tachyon/tabs/dashboard/partials/renderSections.ts:687" ] }, { @@ -10238,7 +10238,7 @@ "key": "Restarts", "places": [ "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2514", - "src/tachyon/tabs/dashboard/partials/renderSections.ts:377" + "src/tachyon/tabs/dashboard/partials/renderSections.ts:385" ] }, { @@ -10586,9 +10586,9 @@ "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:327", "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:3043", "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:3044", - "src/tachyon/methods/custom/getDashboardSections.ts:1693", + "src/tachyon/methods/custom/getDashboardSections.ts:1715", "src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:140", - "src/tachyon/tabs/dashboard/partials/renderSections.ts:312" + "src/tachyon/tabs/dashboard/partials/renderSections.ts:320" ] }, { @@ -11336,9 +11336,9 @@ "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:3824", "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:3843", "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16042", - "src/tachyon/tabs/diagnostic/initController.ts:610", "src/tachyon/methods/shell/index.ts:468", - "src/tachyon/methods/shell/index.ts:489" + "src/tachyon/methods/shell/index.ts:489", + "src/tachyon/tabs/diagnostic/initController.ts:610" ] }, { @@ -11376,7 +11376,7 @@ "key": "Services info", "places": [ "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8996", - "src/tachyon/tabs/dashboard/initController.ts:1901" + "src/tachyon/tabs/dashboard/initController.ts:1909" ] }, { @@ -11959,7 +11959,7 @@ "key": "State", "places": [ "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9079", - "src/tachyon/tabs/dashboard/initController.ts:2014" + "src/tachyon/tabs/dashboard/initController.ts:2022" ] }, { @@ -11973,7 +11973,7 @@ "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/parental.js:935", "src/tachyon/tabs/diagnostic/partials/renderLeakCheckModal.ts:142", "src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:481", - "src/tachyon/tabs/dashboard/partials/renderSections.ts:359" + "src/tachyon/tabs/dashboard/partials/renderSections.ts:367" ] }, { @@ -12022,9 +12022,9 @@ "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:15239", "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:333", "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:3049", - "src/tachyon/methods/custom/getDashboardSections.ts:1697", + "src/tachyon/methods/custom/getDashboardSections.ts:1719", "src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:152", - "src/tachyon/tabs/dashboard/partials/renderSections.ts:316" + "src/tachyon/tabs/dashboard/partials/renderSections.ts:324" ] }, { @@ -12235,7 +12235,7 @@ "key": "System info", "places": [ "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8984", - "src/tachyon/tabs/dashboard/initController.ts:1888" + "src/tachyon/tabs/dashboard/initController.ts:1896" ] }, { @@ -12454,7 +12454,7 @@ "places": [ "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9074", "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:2247", - "src/tachyon/tabs/dashboard/initController.ts:2004" + "src/tachyon/tabs/dashboard/initController.ts:2012" ] }, { @@ -12605,7 +12605,7 @@ "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2939", "src/tachyon/tabs/dashboard/partials/renderSections.ts:252", "src/tachyon/tabs/dashboard/partials/renderSections.ts:260", - "src/tachyon/tabs/dashboard/partials/renderSections.ts:933" + "src/tachyon/tabs/dashboard/partials/renderSections.ts:949" ] }, { @@ -12853,7 +12853,7 @@ "key": "This router", "places": [ "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9087", - "src/tachyon/tabs/dashboard/initController.ts:2025" + "src/tachyon/tabs/dashboard/initController.ts:2033" ] }, { @@ -13058,7 +13058,7 @@ "places": [ "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2338", "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8960", - "src/tachyon/tabs/dashboard/initController.ts:1862", + "src/tachyon/tabs/dashboard/initController.ts:1870", "src/tachyon/tabs/dashboard/partials/renderSections.ts:138" ] }, @@ -13095,7 +13095,7 @@ "key": "Traffic Total", "places": [ "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8972", - "src/tachyon/tabs/dashboard/initController.ts:1875" + "src/tachyon/tabs/dashboard/initController.ts:1883" ] }, { @@ -13472,9 +13472,9 @@ "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:15249", "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:354", "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:3066", - "src/tachyon/methods/custom/getDashboardSections.ts:1699", + "src/tachyon/methods/custom/getDashboardSections.ts:1721", "src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:162", - "src/tachyon/tabs/dashboard/partials/renderSections.ts:318" + "src/tachyon/tabs/dashboard/partials/renderSections.ts:326" ] }, { @@ -13548,7 +13548,7 @@ "key": "Unstable", "places": [ "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2534", - "src/tachyon/tabs/dashboard/partials/renderSections.ts:401" + "src/tachyon/tabs/dashboard/partials/renderSections.ts:409" ] }, { @@ -13698,8 +13698,8 @@ "places": [ "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8962", "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8974", - "src/tachyon/tabs/dashboard/initController.ts:1864", - "src/tachyon/tabs/dashboard/initController.ts:1877" + "src/tachyon/tabs/dashboard/initController.ts:1872", + "src/tachyon/tabs/dashboard/initController.ts:1885" ] }, { @@ -13790,8 +13790,8 @@ "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2725", "../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8555", "src/tachyon/tabs/dashboard/initController.ts:1331", - "src/tachyon/tabs/dashboard/partials/renderSections.ts:659", - "src/tachyon/tabs/dashboard/partials/renderSections.ts:660" + "src/tachyon/tabs/dashboard/partials/renderSections.ts:667", + "src/tachyon/tabs/dashboard/partials/renderSections.ts:668" ] }, { diff --git a/fe-app-tachyon/locales/tachyon.pot b/fe-app-tachyon/locales/tachyon.pot index b79c883f..b7a250af 100644 --- a/fe-app-tachyon/locales/tachyon.pot +++ b/fe-app-tachyon/locales/tachyon.pot @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: TACHYON\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-09-09 14:09+0300\n" -"PO-Revision-Date: 2026-09-09 14:09+0300\n" +"POT-Creation-Date: 2026-09-09 16:57+0300\n" +"PO-Revision-Date: 2026-09-09 16:57+0300\n" "Last-Translator: Dushnilin \n" "Language-Team: LANGUAGE \n" "Language: \n" @@ -136,7 +136,7 @@ msgid "✈️ Telegram Suite (Web + Bot API)" msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9055 -#: src/tachyon/tabs/dashboard/initController.ts:1976 +#: src/tachyon/tabs/dashboard/initController.ts:1984 msgid "✔ Online" msgstr "" @@ -145,23 +145,23 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9008 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9017 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9017 -#: src/tachyon/tabs/dashboard/initController.ts:1906 -#: src/tachyon/tabs/dashboard/initController.ts:1917 -#: src/tachyon/tabs/dashboard/initController.ts:1918 -#: src/tachyon/tabs/dashboard/initController.ts:1932 -#: src/tachyon/tabs/dashboard/initController.ts:1933 +#: src/tachyon/tabs/dashboard/initController.ts:1914 +#: src/tachyon/tabs/dashboard/initController.ts:1925 +#: src/tachyon/tabs/dashboard/initController.ts:1926 +#: src/tachyon/tabs/dashboard/initController.ts:1940 +#: src/tachyon/tabs/dashboard/initController.ts:1941 msgid "✔ Running" msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9055 -#: src/tachyon/tabs/dashboard/initController.ts:1976 +#: src/tachyon/tabs/dashboard/initController.ts:1984 msgid "✘ Offline" msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9001 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9008 -#: src/tachyon/tabs/dashboard/initController.ts:1906 -#: src/tachyon/tabs/dashboard/initController.ts:1919 +#: src/tachyon/tabs/dashboard/initController.ts:1914 +#: src/tachyon/tabs/dashboard/initController.ts:1927 msgid "✘ Stopped" msgstr "" @@ -360,9 +360,9 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:18226 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/parental.js:464 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/parental.js:470 -#: src/tachyon/tabs/dashboard/initController.ts:1137 #: src/tachyon/tabs/monitoring/initController.ts:722 #: src/tachyon/tabs/monitoring/render.ts:20 +#: src/tachyon/tabs/dashboard/initController.ts:1137 msgid "Active" msgstr "" @@ -389,7 +389,7 @@ msgid "Active Clients" msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8986 -#: src/tachyon/tabs/dashboard/initController.ts:1890 +#: src/tachyon/tabs/dashboard/initController.ts:1898 msgid "Active Connections" msgstr "" @@ -918,7 +918,7 @@ msgstr "" #: src/tachyon/tabs/dashboard/initController.ts:927 #: src/tachyon/tabs/dashboard/initController.ts:1365 #: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:35 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:594 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:602 msgid "Auto" msgstr "" @@ -1392,8 +1392,8 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2661 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2939 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:574 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:932 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:582 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:948 msgid "Check Connection" msgstr "" @@ -1443,7 +1443,7 @@ msgid "Check YouTube" msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8775 -#: src/tachyon/tabs/dashboard/initController.ts:1634 +#: src/tachyon/tabs/dashboard/initController.ts:1642 msgid "Checking Connection..." msgstr "" @@ -1479,10 +1479,10 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2656 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2876 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2932 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:466 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:568 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:845 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:921 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:474 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:576 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:861 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:937 msgid "Checking..." msgstr "" @@ -1642,9 +1642,9 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:2037 #: src/partials/modal/renderModal.ts:263 #: src/tachyon/tabs/diagnostic/initController.ts:1554 -#: src/tachyon/tabs/dashboard/initController.ts:1277 #: src/tachyon/tabs/monitoring/initController.ts:893 #: src/tachyon/tabs/monitoring/initController.ts:948 +#: src/tachyon/tabs/dashboard/initController.ts:1277 #: src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:227 #: src/tachyon/tabs/diagnostic/partials/renderDnsBenchmarkModal.ts:286 #: src/tachyon/tabs/diagnostic/partials/renderLeakCheckModal.ts:379 @@ -1772,9 +1772,9 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2459 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:5840 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:15233 -#: src/tachyon/methods/custom/getDashboardSections.ts:1695 +#: src/tachyon/methods/custom/getDashboardSections.ts:1717 #: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:146 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:314 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:322 msgid "Conflict" msgstr "" @@ -1784,8 +1784,8 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2583 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2876 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:472 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:851 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:480 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:867 msgid "Connected" msgstr "" @@ -1857,8 +1857,8 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2709 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8449 #: src/tachyon/tabs/dashboard/initController.ts:1202 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:640 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:641 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:648 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:649 msgid "Copy proxy link" msgstr "" @@ -2421,8 +2421,8 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8963 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8975 -#: src/tachyon/tabs/dashboard/initController.ts:1865 -#: src/tachyon/tabs/dashboard/initController.ts:1878 +#: src/tachyon/tabs/dashboard/initController.ts:1873 +#: src/tachyon/tabs/dashboard/initController.ts:1886 msgid "Downlink" msgstr "" @@ -2988,12 +2988,12 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:20679 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:20741 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:20915 +#: src/tachyon/methods/shell/index.ts:199 +#: src/tachyon/methods/shell/index.ts:206 #: src/tachyon/tabs/updates/initController.ts:693 #: src/tachyon/tabs/updates/initController.ts:694 #: src/tachyon/tabs/updates/initController.ts:773 #: src/tachyon/tabs/updates/initController.ts:989 -#: src/tachyon/methods/shell/index.ts:199 -#: src/tachyon/methods/shell/index.ts:206 msgid "Failed to execute" msgstr "" @@ -3290,7 +3290,7 @@ msgid "Faster server search interval" msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:5141 -#: src/tachyon/methods/custom/getDashboardSections.ts:674 +#: src/tachyon/methods/custom/getDashboardSections.ts:696 msgid "Fastest" msgstr "" @@ -4760,7 +4760,7 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8572 #: src/tachyon/tabs/dashboard/initController.ts:918 #: src/tachyon/tabs/dashboard/initController.ts:1356 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:592 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:600 msgid "Manual" msgstr "" @@ -4830,7 +4830,7 @@ msgid "Maximum time to wait for example.com to resolve during a DNS health check msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8987 -#: src/tachyon/tabs/dashboard/initController.ts:1891 +#: src/tachyon/tabs/dashboard/initController.ts:1899 msgid "Memory Usage" msgstr "" @@ -5231,17 +5231,17 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:5840 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:10248 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:15244 -#: src/tachyon/methods/custom/getDashboardSections.ts:1698 +#: src/tachyon/methods/custom/getDashboardSections.ts:1720 #: src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:46 #: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:157 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:317 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:325 msgid "Not configured" msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2583 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2876 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:473 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:852 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:481 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:868 msgid "Not connected" msgstr "" @@ -5298,8 +5298,8 @@ msgstr "" #: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:118 #: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:124 #: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:190 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:470 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:849 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:478 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:865 msgid "Not responding" msgstr "" @@ -5539,7 +5539,7 @@ msgid "Or paste hosts file content:" msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9097 -#: src/tachyon/tabs/dashboard/initController.ts:2035 +#: src/tachyon/tabs/dashboard/initController.ts:2043 msgid "Other peers" msgstr "" @@ -5869,8 +5869,8 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2741 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8687 #: src/tachyon/tabs/dashboard/initController.ts:1504 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:678 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:679 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:686 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:687 msgid "Priority details" msgstr "" @@ -6333,7 +6333,7 @@ msgid "Restart Zapret/ByeDPI" msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2514 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:377 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:385 msgid "Restarts" msgstr "" @@ -6552,9 +6552,9 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:327 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:3043 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:3044 -#: src/tachyon/methods/custom/getDashboardSections.ts:1693 +#: src/tachyon/methods/custom/getDashboardSections.ts:1715 #: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:140 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:312 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:320 msgid "Running" msgstr "" @@ -7002,9 +7002,9 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:3824 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:3843 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16042 -#: src/tachyon/tabs/diagnostic/initController.ts:610 #: src/tachyon/methods/shell/index.ts:468 #: src/tachyon/methods/shell/index.ts:489 +#: src/tachyon/tabs/diagnostic/initController.ts:610 msgid "Service action failed" msgstr "" @@ -7027,7 +7027,7 @@ msgid "Services are online and ready! Reloading page..." msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8996 -#: src/tachyon/tabs/dashboard/initController.ts:1901 +#: src/tachyon/tabs/dashboard/initController.ts:1909 msgid "Services info" msgstr "" @@ -7382,7 +7382,7 @@ msgid "Starting…" msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9079 -#: src/tachyon/tabs/dashboard/initController.ts:2014 +#: src/tachyon/tabs/dashboard/initController.ts:2022 msgid "State" msgstr "" @@ -7393,7 +7393,7 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/parental.js:935 #: src/tachyon/tabs/diagnostic/partials/renderLeakCheckModal.ts:142 #: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:481 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:359 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:367 msgid "Status" msgstr "" @@ -7424,9 +7424,9 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:15239 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:333 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:3049 -#: src/tachyon/methods/custom/getDashboardSections.ts:1697 +#: src/tachyon/methods/custom/getDashboardSections.ts:1719 #: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:152 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:316 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:324 msgid "Stopped" msgstr "" @@ -7553,7 +7553,7 @@ msgid "System diagnostics, AI Doctor and logs" msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8984 -#: src/tachyon/tabs/dashboard/initController.ts:1888 +#: src/tachyon/tabs/dashboard/initController.ts:1896 msgid "System info" msgstr "" @@ -7688,7 +7688,7 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9074 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:2247 -#: src/tachyon/tabs/dashboard/initController.ts:2004 +#: src/tachyon/tabs/dashboard/initController.ts:2012 msgid "Tailscale" msgstr "" @@ -7782,7 +7782,7 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2939 #: src/tachyon/tabs/dashboard/partials/renderSections.ts:252 #: src/tachyon/tabs/dashboard/partials/renderSections.ts:260 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:933 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:949 msgid "Test latency" msgstr "" @@ -7934,7 +7934,7 @@ msgid "This option requires a value." msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9087 -#: src/tachyon/tabs/dashboard/initController.ts:2025 +#: src/tachyon/tabs/dashboard/initController.ts:2033 msgid "This router" msgstr "" @@ -8058,7 +8058,7 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2338 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8960 -#: src/tachyon/tabs/dashboard/initController.ts:1862 +#: src/tachyon/tabs/dashboard/initController.ts:1870 #: src/tachyon/tabs/dashboard/partials/renderSections.ts:138 msgid "Traffic" msgstr "" @@ -8080,7 +8080,7 @@ msgid "Traffic statistics and active connections" msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8972 -#: src/tachyon/tabs/dashboard/initController.ts:1875 +#: src/tachyon/tabs/dashboard/initController.ts:1883 msgid "Traffic Total" msgstr "" @@ -8319,9 +8319,9 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:15249 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:354 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:3066 -#: src/tachyon/methods/custom/getDashboardSections.ts:1699 +#: src/tachyon/methods/custom/getDashboardSections.ts:1721 #: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:162 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:318 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:326 msgid "Unknown" msgstr "" @@ -8371,7 +8371,7 @@ msgid "Unspecified IP address is not allowed" msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2534 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:401 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:409 msgid "Unstable" msgstr "" @@ -8464,8 +8464,8 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8962 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8974 -#: src/tachyon/tabs/dashboard/initController.ts:1864 -#: src/tachyon/tabs/dashboard/initController.ts:1877 +#: src/tachyon/tabs/dashboard/initController.ts:1872 +#: src/tachyon/tabs/dashboard/initController.ts:1885 msgid "Uplink" msgstr "" @@ -8523,8 +8523,8 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2725 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8555 #: src/tachyon/tabs/dashboard/initController.ts:1331 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:659 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:660 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:667 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:668 msgid "URLTest details" msgstr "" diff --git a/fe-app-tachyon/locales/tachyon.ru.po b/fe-app-tachyon/locales/tachyon.ru.po index 81cc53ec..487e4c32 100644 --- a/fe-app-tachyon/locales/tachyon.ru.po +++ b/fe-app-tachyon/locales/tachyon.ru.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: TACHYON\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-09-09 17:09+0300\n" -"PO-Revision-Date: 2026-09-09 17:09+0300\n" +"POT-Creation-Date: 2026-09-09 19:57+0300\n" +"PO-Revision-Date: 2026-09-09 19:57+0300\n" "Last-Translator: Dushnilin\n" "Language-Team: none\n" "Language: ru\n" diff --git a/fe-app-tachyon/src/tachyon/methods/custom/getDashboardSections.ts b/fe-app-tachyon/src/tachyon/methods/custom/getDashboardSections.ts index 54e169b3..4b5151f6 100644 --- a/fe-app-tachyon/src/tachyon/methods/custom/getDashboardSections.ts +++ b/fe-app-tachyon/src/tachyon/methods/custom/getDashboardSections.ts @@ -383,12 +383,34 @@ function getJsonOutbounds(section: Tachyon.ConfigSection) { return values.length ? values : getListValues(section.outbound_json); } +const SINGLE_ENDPOINT_ACTIONS = new Set([ + 'vpn', + 'awg', + 'warp', + 'anytls', + 'snell', + 'mieru', + 'sudoku', + 'masque', + 'openvpn', +]); + +const ACTION_DISPLAY_NAMES: Record = { + awg: 'AmneziaWG', + warp: 'WARP', + anytls: 'AnyTLS', + snell: 'Snell', + mieru: 'Mieru', + sudoku: 'Sudoku', + masque: 'MASQUE', + openvpn: 'OpenVPN', +}; + function isConnectionAction(action?: string) { return Boolean( action && - ['connection', 'proxy', 'outbound', 'vpn', 'awg', 'warp'].includes( - action, - ), + (SINGLE_ENDPOINT_ACTIONS.has(action) || + ['connection', 'proxy', 'outbound'].includes(action)), ); } @@ -1616,13 +1638,16 @@ export async function getDashboardSections( }; } - if ( - sectionAction === 'vpn' || - sectionAction === 'awg' || - sectionAction === 'warp' - ) { + if (SINGLE_ENDPOINT_ACTIONS.has(sectionAction || '')) { const outboundTag = getOutboundTagBySection(sectionName); const outbound = proxies.find((proxy) => proxy.code === outboundTag); + const defaultLabel = + ACTION_DISPLAY_NAMES[sectionAction || ''] || + (sectionAction || '').toUpperCase(); + const customName = + outbound?.value?.name && outbound.value.name !== outboundTag + ? outbound.value.name + : ''; return { withTagSelect: false, @@ -1634,22 +1659,19 @@ export async function getDashboardSections( { code: outbound?.code || sectionName, displayName: + section.label || section.interface || - outbound?.value?.name || - (sectionAction === 'awg' - ? 'AmneziaWG' - : sectionAction.toUpperCase()), + customName || + defaultLabel, latency: outbound?.value?.history?.length ? outbound.value.history[0].delay > 0 ? outbound.value.history[0].delay : -1 : 0, type: - sectionAction === 'awg' - ? 'AmneziaWG' - : sectionAction === 'warp' - ? 'WARP' - : outbound?.value?.type || '', + ACTION_DISPLAY_NAMES[sectionAction || ''] || + outbound?.value?.type || + (sectionAction || '').toUpperCase(), selected: true, canCopyLink: false, runtimeAvailable: Boolean(outbound), diff --git a/fe-app-tachyon/src/tachyon/methods/custom/tests/getDashboardSections.test.ts b/fe-app-tachyon/src/tachyon/methods/custom/tests/getDashboardSections.test.ts index 2005e138..c931eeeb 100644 --- a/fe-app-tachyon/src/tachyon/methods/custom/tests/getDashboardSections.test.ts +++ b/fe-app-tachyon/src/tachyon/methods/custom/tests/getDashboardSections.test.ts @@ -1087,6 +1087,104 @@ describe('getDashboardSections', () => { ]); }); + it('exposes single-endpoint protocol sections (Mieru, Sudoku, AnyTLS, Snell, MASQUE, OpenVPN) on the dashboard', async () => { + mocks.getConfigSections.mockResolvedValue([ + { + '.name': 'mieru_sec', + '.type': 'section', + enabled: '1', + action: 'mieru', + }, + { + '.name': 'sudoku_sec', + '.type': 'section', + enabled: '1', + action: 'sudoku', + }, + { + '.name': 'anytls_sec', + '.type': 'section', + enabled: '1', + action: 'anytls', + }, + { + '.name': 'snell_sec', + '.type': 'section', + enabled: '1', + action: 'snell', + }, + { + '.name': 'masque_sec', + '.type': 'section', + enabled: '1', + action: 'masque', + }, + { + '.name': 'openvpn_sec', + '.type': 'section', + enabled: '1', + action: 'openvpn', + }, + ]); + mocks.getClashApiProxies.mockResolvedValue({ + success: true, + data: { + proxies: { + 'mieru_sec-out': proxy('Mieru', { + name: 'mieru_sec-out', + history: [{ time: '2026-09-09T00:00:00Z', delay: 42 }], + }), + 'sudoku_sec-out': proxy('Sudoku', { + name: 'sudoku_sec-out', + history: [{ time: '2026-09-09T00:00:00Z', delay: 55 }], + }), + 'anytls_sec-out': proxy('AnyTLS', { + name: 'anytls_sec-out', + history: [{ time: '2026-09-09T00:00:00Z', delay: 60 }], + }), + 'snell_sec-out': proxy('Snell', { + name: 'snell_sec-out', + history: [{ time: '2026-09-09T00:00:00Z', delay: 70 }], + }), + 'masque_sec-out': proxy('MASQUE', { + name: 'masque_sec-out', + history: [{ time: '2026-09-09T00:00:00Z', delay: 80 }], + }), + 'openvpn_sec-out': proxy('OpenVPN', { + name: 'openvpn_sec-out', + history: [{ time: '2026-09-09T00:00:00Z', delay: 90 }], + }), + }, + }, + }); + + const result = await getDashboardSections(); + + expect(result.success).toBe(true); + expect(result.data.map((s) => s.sectionName)).toEqual([ + 'mieru_sec', + 'sudoku_sec', + 'anytls_sec', + 'snell_sec', + 'masque_sec', + 'openvpn_sec', + ]); + expect(result.data[0].outbounds[0]).toMatchObject({ + code: 'mieru_sec-out', + displayName: 'Mieru', + type: 'Mieru', + latency: 42, + runtimeAvailable: true, + }); + expect(result.data[1].outbounds[0]).toMatchObject({ + code: 'sudoku_sec-out', + displayName: 'Sudoku', + type: 'Sudoku', + latency: 55, + runtimeAvailable: true, + }); + }); + it('fetches Clash API proxies directly in the browser to avoid rpcd output limits', async () => { mocks.getConfigSections.mockResolvedValue([ { '.name': 'settings', '.type': 'settings', yacd_secret_key: 'secret' }, diff --git a/fe-app-tachyon/src/tachyon/tabs/dashboard/initController.ts b/fe-app-tachyon/src/tachyon/tabs/dashboard/initController.ts index 30fd2d54..018c4b50 100644 --- a/fe-app-tachyon/src/tachyon/tabs/dashboard/initController.ts +++ b/fe-app-tachyon/src/tachyon/tabs/dashboard/initController.ts @@ -1626,9 +1626,17 @@ function updateLatencyProgressInline( return false; } - const isConnectionNode = ['vpn', 'awg', 'warp'].includes( - section.action || '', - ); + const isConnectionNode = [ + 'vpn', + 'awg', + 'warp', + 'anytls', + 'snell', + 'mieru', + 'sudoku', + 'masque', + 'openvpn', + ].includes(section.action || ''); const text = isConnectionNode ? _('Checking Connection...') diff --git a/fe-app-tachyon/src/tachyon/tabs/dashboard/partials/renderSections.ts b/fe-app-tachyon/src/tachyon/tabs/dashboard/partials/renderSections.ts index 1a75f5ec..7902849e 100644 --- a/fe-app-tachyon/src/tachyon/tabs/dashboard/partials/renderSections.ts +++ b/fe-app-tachyon/src/tachyon/tabs/dashboard/partials/renderSections.ts @@ -278,9 +278,17 @@ function renderDefaultState({ isCollapsed, onToggleCollapse, }: IRenderSectionsProps) { - const isConnectionNode = ['vpn', 'awg', 'warp'].includes( - section.action || '', - ); + const isConnectionNode = [ + 'vpn', + 'awg', + 'warp', + 'anytls', + 'snell', + 'mieru', + 'sudoku', + 'masque', + 'openvpn', + ].includes(section.action || ''); const isServiceNode = ['zapret', 'zapret2', 'byedpi'].includes(section.action || '') || Boolean(section.serviceStatus); @@ -805,9 +813,17 @@ function renderDefaultState({ ); if (!selectedOutbound) return ''; - const isConnectionNode = ['vpn', 'awg', 'warp'].includes( - section.action || '', - ); + const isConnectionNode = [ + 'vpn', + 'awg', + 'warp', + 'anytls', + 'snell', + 'mieru', + 'sudoku', + 'masque', + 'openvpn', + ].includes(section.action || ''); function getLatencyColor() { if (isConnectionNode) { diff --git a/fe-app-tachyon/src/tachyon/tabs/dashboard/partials/tests/renderSections.test.ts b/fe-app-tachyon/src/tachyon/tabs/dashboard/partials/tests/renderSections.test.ts index 57d47478..6ed44eba 100644 --- a/fe-app-tachyon/src/tachyon/tabs/dashboard/partials/tests/renderSections.test.ts +++ b/fe-app-tachyon/src/tachyon/tabs/dashboard/partials/tests/renderSections.test.ts @@ -297,4 +297,44 @@ describe('renderSections', () => { ); expect(latencyButtons).toHaveLength(0); }); + + it('renders latency test button and connection node item for Mieru section', () => { + const section: any = { + code: 'mieru-out', + sectionName: 'mieru', + displayName: 'My Mieru', + action: 'mieru', + withTagSelect: false, + outbounds: [ + { + code: 'mieru-out', + displayName: 'My Mieru', + latency: 65, + type: 'Mieru', + selected: true, + runtimeAvailable: true, + }, + ], + }; + + const el = renderSections({ + loading: false, + failed: false, + section, + onTestLatency: vi.fn(), + onChooseOutbound: vi.fn(), + onCopyOutbound: vi.fn(), + onShowUrlTestInfo: vi.fn(), + onShowPriorityInfo: vi.fn(), + onUpdateSubscription: vi.fn(), + latencyFetching: false, + subscriptionUpdating: false, + }); + + const latencyButtons = el.querySelectorAll( + '.dashboard-sections-grid-item-test-latency', + ); + expect(latencyButtons).toHaveLength(1); + expect(latencyButtons[0].tagName).toBe('BUTTON'); + }); }); diff --git a/fe-app-tachyon/src/tachyon/types.ts b/fe-app-tachyon/src/tachyon/types.ts index d6d46690..80229076 100644 --- a/fe-app-tachyon/src/tachyon/types.ts +++ b/fe-app-tachyon/src/tachyon/types.ts @@ -275,6 +275,12 @@ export namespace Tachyon { | 'byedpi' | 'awg' | 'warp' + | 'anytls' + | 'snell' + | 'mieru' + | 'sudoku' + | 'masque' + | 'openvpn' | 'dns' | 'hosts'; type LegacyConnectionType = 'proxy' | 'vpn' | 'block' | 'exclusion'; diff --git a/luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js b/luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js index 12ec230b..102f661c 100644 --- a/luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js +++ b/luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js @@ -2447,9 +2447,17 @@ function renderDefaultState({ isCollapsed, onToggleCollapse }) { - const isConnectionNode = ["vpn", "awg", "warp"].includes( - section.action || "" - ); + const isConnectionNode = [ + "vpn", + "awg", + "warp", + "anytls", + "snell", + "mieru", + "sudoku", + "masque", + "openvpn" + ].includes(section.action || ""); const isServiceNode = ["zapret", "zapret2", "byedpi"].includes(section.action || "") || Boolean(section.serviceStatus); if (isServiceNode) { const ss = section.serviceStatus; @@ -2845,9 +2853,17 @@ function renderDefaultState({ (o) => o.selected ); if (!selectedOutbound) return ""; - const isConnectionNode2 = ["vpn", "awg", "warp"].includes( - section.action || "" - ); + const isConnectionNode2 = [ + "vpn", + "awg", + "warp", + "anytls", + "snell", + "mieru", + "sudoku", + "masque", + "openvpn" + ].includes(section.action || ""); function getLatencyColor() { if (isConnectionNode2) { if (latencyFetching) @@ -4950,11 +4966,30 @@ function getJsonOutbounds(section) { const values = getListValues(section.outbound_jsons); return values.length ? values : getListValues(section.outbound_json); } +var SINGLE_ENDPOINT_ACTIONS = /* @__PURE__ */ new Set([ + "vpn", + "awg", + "warp", + "anytls", + "snell", + "mieru", + "sudoku", + "masque", + "openvpn" +]); +var ACTION_DISPLAY_NAMES = { + awg: "AmneziaWG", + warp: "WARP", + anytls: "AnyTLS", + snell: "Snell", + mieru: "Mieru", + sudoku: "Sudoku", + masque: "MASQUE", + openvpn: "OpenVPN" +}; function isConnectionAction(action) { return Boolean( - action && ["connection", "proxy", "outbound", "vpn", "awg", "warp"].includes( - action - ) + action && (SINGLE_ENDPOINT_ACTIONS.has(action) || ["connection", "proxy", "outbound"].includes(action)) ); } function isServiceAction(action) { @@ -5791,9 +5826,11 @@ async function getDashboardSections(options = {}) { outbounds }; } - if (sectionAction === "vpn" || sectionAction === "awg" || sectionAction === "warp") { + if (SINGLE_ENDPOINT_ACTIONS.has(sectionAction || "")) { const outboundTag = getOutboundTagBySection(sectionName); const outbound = proxies.find((proxy) => proxy.code === outboundTag); + const defaultLabel = ACTION_DISPLAY_NAMES[sectionAction || ""] || (sectionAction || "").toUpperCase(); + const customName = outbound?.value?.name && outbound.value.name !== outboundTag ? outbound.value.name : ""; return { withTagSelect: false, code: outbound?.code || sectionName, @@ -5803,9 +5840,9 @@ async function getDashboardSections(options = {}) { outbounds: [ { code: outbound?.code || sectionName, - displayName: section.interface || outbound?.value?.name || (sectionAction === "awg" ? "AmneziaWG" : sectionAction.toUpperCase()), + displayName: section.label || section.interface || customName || defaultLabel, latency: outbound?.value?.history?.length ? outbound.value.history[0].delay > 0 ? outbound.value.history[0].delay : -1 : 0, - type: sectionAction === "awg" ? "AmneziaWG" : sectionAction === "warp" ? "WARP" : outbound?.value?.type || "", + type: ACTION_DISPLAY_NAMES[sectionAction || ""] || outbound?.value?.type || (sectionAction || "").toUpperCase(), selected: true, canCopyLink: false, runtimeAvailable: Boolean(outbound) @@ -8769,9 +8806,17 @@ function updateLatencyProgressInline(sectionsWidget) { if (!label) { return false; } - const isConnectionNode = ["vpn", "awg", "warp"].includes( - section.action || "" - ); + const isConnectionNode = [ + "vpn", + "awg", + "warp", + "anytls", + "snell", + "mieru", + "sudoku", + "masque", + "openvpn" + ].includes(section.action || ""); const text = isConnectionNode ? _("Checking Connection...") : getLatencyTestLabel( sectionsWidget.latencyProgressSections[section.sectionName] ); diff --git a/luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/parental.js b/luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/parental.js index 668652ce..4f1c5ace 100644 --- a/luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/parental.js +++ b/luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/parental.js @@ -586,7 +586,7 @@ function createProfileContent(section) { .map((l) => l.trim()) .filter(Boolean); for (const line of lines) { - const clean = line.replace(/^(full:|keyword:|regex:)/, ""); + const clean = line.replace(/^(full:|keyword:|regex:)/, "").replace(/^\*?\./, ""); if (/^(full:|keyword:|regex:)/.test(line) && !clean) { return _("Invalid domain: empty prefix value"); } @@ -599,30 +599,30 @@ function createProfileContent(section) { } return true; }; - o.write = function (sectionId, value) { - const lines = `${value || ""}` - .split(/\r?\n/) - .map((l) => l.trim()) - .filter(Boolean); - const existingList = normalizeListValues( - uci.get(UCI_PACKAGE, sectionId, "blocked_domains"), - ); - for (const d of lines) { - if (!existingList.includes(d)) { - uci.add_list(UCI_PACKAGE, sectionId, "blocked_domains", d); - } - } - for (const d of existingList) { - if (!lines.includes(d)) { - uci.remove_list(UCI_PACKAGE, sectionId, "blocked_domains", d); - } - } - }; - o.load = function (sectionId) { + o.cfgvalue = function (sectionId) { return normalizeListValues( uci.get(UCI_PACKAGE, sectionId, "blocked_domains"), ).join("\n"); }; + o.load = o.cfgvalue; + o.formvalue = function (sectionId) { + const node = document.getElementById(this.cbid(sectionId)); + return node ? node.value : null; + }; + o.write = function (sectionId, value) { + const lines = []; + for (const raw of `${value || ""}`.split(/\r?\n/)) { + const l = raw.trim(); + if (l && !lines.includes(l)) { + lines.push(l); + } + } + if (lines.length === 0) { + uci.unset(UCI_PACKAGE, sectionId, "blocked_domains"); + } else { + uci.set(UCI_PACKAGE, sectionId, "blocked_domains", lines); + } + }; o.remove = function (sectionId) { uci.unset(UCI_PACKAGE, sectionId, "blocked_domains"); }; @@ -654,18 +654,23 @@ function createProfileContent(section) { if (!merged.includes(d)) merged.push(d); } textarea.value = merged.join("\n"); + textarea.dispatchEvent(new Event("input", { bubbles: true })); + textarea.dispatchEvent(new Event("change", { bubbles: true })); }); presetRow.appendChild(btn); }); container.appendChild(presetRow); + const cbid = this.cbid(sectionId); const textarea = E("textarea", { - id: `cbid.tachyon.${sectionId}.blocked_domains`, + id: cbid, + name: cbid, class: "cbi-input-textarea", style: "width:100%;min-height:100px;box-sizing:border-box;", placeholder: "tiktok.com\nroblox.com", }); - if (cfgvalue) textarea.value = cfgvalue; + const strVal = Array.isArray(cfgvalue) ? cfgvalue.join("\n") : (cfgvalue || ""); + if (strVal) textarea.value = strVal; container.appendChild(textarea); return container; }; @@ -1170,7 +1175,7 @@ function createParentalContent(section) { .map((l) => l.trim()) .filter(Boolean); for (const line of lines) { - const clean = line.replace(/^(full:|keyword:|regex:)/, ""); + const clean = line.replace(/^(full:|keyword:|regex:)/, "").replace(/^\*?\./, ""); if (/^(full:|keyword:|regex:)/.test(line) && !clean) { return _("Invalid domain: empty prefix value"); } @@ -1183,30 +1188,30 @@ function createParentalContent(section) { } return true; }; - o.write = function (sectionId, value) { - const lines = `${value || ""}` - .split(/\r?\n/) - .map((l) => l.trim()) - .filter(Boolean); - const existingList = normalizeListValues( - uci.get(UCI_PACKAGE, sectionId, "blocked_domains"), - ); - for (const d of lines) { - if (!existingList.includes(d)) { - uci.add_list(UCI_PACKAGE, sectionId, "blocked_domains", d); - } - } - for (const d of existingList) { - if (!lines.includes(d)) { - uci.remove_list(UCI_PACKAGE, sectionId, "blocked_domains", d); - } - } - }; - o.load = function (sectionId) { + o.cfgvalue = function (sectionId) { return normalizeListValues( uci.get(UCI_PACKAGE, sectionId, "blocked_domains"), ).join("\n"); }; + o.load = o.cfgvalue; + o.formvalue = function (sectionId) { + const node = document.getElementById(this.cbid(sectionId)); + return node ? node.value : null; + }; + o.write = function (sectionId, value) { + const lines = []; + for (const raw of `${value || ""}`.split(/\r?\n/)) { + const l = raw.trim(); + if (l && !lines.includes(l)) { + lines.push(l); + } + } + if (lines.length === 0) { + uci.unset(UCI_PACKAGE, sectionId, "blocked_domains"); + } else { + uci.set(UCI_PACKAGE, sectionId, "blocked_domains", lines); + } + }; o.remove = function (sectionId) { uci.unset(UCI_PACKAGE, sectionId, "blocked_domains"); }; @@ -1240,18 +1245,23 @@ function createParentalContent(section) { if (!merged.includes(d)) merged.push(d); } textarea.value = merged.join("\n"); + textarea.dispatchEvent(new Event("input", { bubbles: true })); + textarea.dispatchEvent(new Event("change", { bubbles: true })); }); presetRow.appendChild(btn); }); container.appendChild(presetRow); + const cbid = this.cbid(sectionId); const textarea = E("textarea", { - id: `cbid.tachyon.${sectionId}.blocked_domains`, + id: cbid, + name: cbid, class: "cbi-input-textarea", style: "width:100%;min-height:110px;box-sizing:border-box;", placeholder: "youtube.com\ngooglevideo.com", }); - if (cfgvalue) textarea.value = cfgvalue; + const strVal = Array.isArray(cfgvalue) ? cfgvalue.join("\n") : (cfgvalue || ""); + if (strVal) textarea.value = strVal; container.appendChild(textarea); return container; }; diff --git a/luci-app-tachyon/po/ru/tachyon.po b/luci-app-tachyon/po/ru/tachyon.po index 81cc53ec..487e4c32 100644 --- a/luci-app-tachyon/po/ru/tachyon.po +++ b/luci-app-tachyon/po/ru/tachyon.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: TACHYON\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-09-09 17:09+0300\n" -"PO-Revision-Date: 2026-09-09 17:09+0300\n" +"POT-Creation-Date: 2026-09-09 19:57+0300\n" +"PO-Revision-Date: 2026-09-09 19:57+0300\n" "Last-Translator: Dushnilin\n" "Language-Team: none\n" "Language: ru\n" diff --git a/luci-app-tachyon/po/templates/tachyon.pot b/luci-app-tachyon/po/templates/tachyon.pot index b79c883f..b7a250af 100644 --- a/luci-app-tachyon/po/templates/tachyon.pot +++ b/luci-app-tachyon/po/templates/tachyon.pot @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: TACHYON\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-09-09 14:09+0300\n" -"PO-Revision-Date: 2026-09-09 14:09+0300\n" +"POT-Creation-Date: 2026-09-09 16:57+0300\n" +"PO-Revision-Date: 2026-09-09 16:57+0300\n" "Last-Translator: Dushnilin \n" "Language-Team: LANGUAGE \n" "Language: \n" @@ -136,7 +136,7 @@ msgid "✈️ Telegram Suite (Web + Bot API)" msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9055 -#: src/tachyon/tabs/dashboard/initController.ts:1976 +#: src/tachyon/tabs/dashboard/initController.ts:1984 msgid "✔ Online" msgstr "" @@ -145,23 +145,23 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9008 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9017 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9017 -#: src/tachyon/tabs/dashboard/initController.ts:1906 -#: src/tachyon/tabs/dashboard/initController.ts:1917 -#: src/tachyon/tabs/dashboard/initController.ts:1918 -#: src/tachyon/tabs/dashboard/initController.ts:1932 -#: src/tachyon/tabs/dashboard/initController.ts:1933 +#: src/tachyon/tabs/dashboard/initController.ts:1914 +#: src/tachyon/tabs/dashboard/initController.ts:1925 +#: src/tachyon/tabs/dashboard/initController.ts:1926 +#: src/tachyon/tabs/dashboard/initController.ts:1940 +#: src/tachyon/tabs/dashboard/initController.ts:1941 msgid "✔ Running" msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9055 -#: src/tachyon/tabs/dashboard/initController.ts:1976 +#: src/tachyon/tabs/dashboard/initController.ts:1984 msgid "✘ Offline" msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9001 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9008 -#: src/tachyon/tabs/dashboard/initController.ts:1906 -#: src/tachyon/tabs/dashboard/initController.ts:1919 +#: src/tachyon/tabs/dashboard/initController.ts:1914 +#: src/tachyon/tabs/dashboard/initController.ts:1927 msgid "✘ Stopped" msgstr "" @@ -360,9 +360,9 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:18226 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/parental.js:464 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/parental.js:470 -#: src/tachyon/tabs/dashboard/initController.ts:1137 #: src/tachyon/tabs/monitoring/initController.ts:722 #: src/tachyon/tabs/monitoring/render.ts:20 +#: src/tachyon/tabs/dashboard/initController.ts:1137 msgid "Active" msgstr "" @@ -389,7 +389,7 @@ msgid "Active Clients" msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8986 -#: src/tachyon/tabs/dashboard/initController.ts:1890 +#: src/tachyon/tabs/dashboard/initController.ts:1898 msgid "Active Connections" msgstr "" @@ -918,7 +918,7 @@ msgstr "" #: src/tachyon/tabs/dashboard/initController.ts:927 #: src/tachyon/tabs/dashboard/initController.ts:1365 #: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:35 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:594 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:602 msgid "Auto" msgstr "" @@ -1392,8 +1392,8 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2661 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2939 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:574 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:932 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:582 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:948 msgid "Check Connection" msgstr "" @@ -1443,7 +1443,7 @@ msgid "Check YouTube" msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8775 -#: src/tachyon/tabs/dashboard/initController.ts:1634 +#: src/tachyon/tabs/dashboard/initController.ts:1642 msgid "Checking Connection..." msgstr "" @@ -1479,10 +1479,10 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2656 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2876 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2932 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:466 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:568 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:845 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:921 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:474 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:576 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:861 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:937 msgid "Checking..." msgstr "" @@ -1642,9 +1642,9 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:2037 #: src/partials/modal/renderModal.ts:263 #: src/tachyon/tabs/diagnostic/initController.ts:1554 -#: src/tachyon/tabs/dashboard/initController.ts:1277 #: src/tachyon/tabs/monitoring/initController.ts:893 #: src/tachyon/tabs/monitoring/initController.ts:948 +#: src/tachyon/tabs/dashboard/initController.ts:1277 #: src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:227 #: src/tachyon/tabs/diagnostic/partials/renderDnsBenchmarkModal.ts:286 #: src/tachyon/tabs/diagnostic/partials/renderLeakCheckModal.ts:379 @@ -1772,9 +1772,9 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2459 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:5840 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:15233 -#: src/tachyon/methods/custom/getDashboardSections.ts:1695 +#: src/tachyon/methods/custom/getDashboardSections.ts:1717 #: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:146 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:314 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:322 msgid "Conflict" msgstr "" @@ -1784,8 +1784,8 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2583 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2876 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:472 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:851 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:480 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:867 msgid "Connected" msgstr "" @@ -1857,8 +1857,8 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2709 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8449 #: src/tachyon/tabs/dashboard/initController.ts:1202 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:640 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:641 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:648 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:649 msgid "Copy proxy link" msgstr "" @@ -2421,8 +2421,8 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8963 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8975 -#: src/tachyon/tabs/dashboard/initController.ts:1865 -#: src/tachyon/tabs/dashboard/initController.ts:1878 +#: src/tachyon/tabs/dashboard/initController.ts:1873 +#: src/tachyon/tabs/dashboard/initController.ts:1886 msgid "Downlink" msgstr "" @@ -2988,12 +2988,12 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:20679 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:20741 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:20915 +#: src/tachyon/methods/shell/index.ts:199 +#: src/tachyon/methods/shell/index.ts:206 #: src/tachyon/tabs/updates/initController.ts:693 #: src/tachyon/tabs/updates/initController.ts:694 #: src/tachyon/tabs/updates/initController.ts:773 #: src/tachyon/tabs/updates/initController.ts:989 -#: src/tachyon/methods/shell/index.ts:199 -#: src/tachyon/methods/shell/index.ts:206 msgid "Failed to execute" msgstr "" @@ -3290,7 +3290,7 @@ msgid "Faster server search interval" msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:5141 -#: src/tachyon/methods/custom/getDashboardSections.ts:674 +#: src/tachyon/methods/custom/getDashboardSections.ts:696 msgid "Fastest" msgstr "" @@ -4760,7 +4760,7 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8572 #: src/tachyon/tabs/dashboard/initController.ts:918 #: src/tachyon/tabs/dashboard/initController.ts:1356 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:592 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:600 msgid "Manual" msgstr "" @@ -4830,7 +4830,7 @@ msgid "Maximum time to wait for example.com to resolve during a DNS health check msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8987 -#: src/tachyon/tabs/dashboard/initController.ts:1891 +#: src/tachyon/tabs/dashboard/initController.ts:1899 msgid "Memory Usage" msgstr "" @@ -5231,17 +5231,17 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:5840 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:10248 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:15244 -#: src/tachyon/methods/custom/getDashboardSections.ts:1698 +#: src/tachyon/methods/custom/getDashboardSections.ts:1720 #: src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:46 #: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:157 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:317 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:325 msgid "Not configured" msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2583 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2876 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:473 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:852 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:481 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:868 msgid "Not connected" msgstr "" @@ -5298,8 +5298,8 @@ msgstr "" #: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:118 #: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:124 #: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:190 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:470 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:849 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:478 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:865 msgid "Not responding" msgstr "" @@ -5539,7 +5539,7 @@ msgid "Or paste hosts file content:" msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9097 -#: src/tachyon/tabs/dashboard/initController.ts:2035 +#: src/tachyon/tabs/dashboard/initController.ts:2043 msgid "Other peers" msgstr "" @@ -5869,8 +5869,8 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2741 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8687 #: src/tachyon/tabs/dashboard/initController.ts:1504 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:678 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:679 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:686 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:687 msgid "Priority details" msgstr "" @@ -6333,7 +6333,7 @@ msgid "Restart Zapret/ByeDPI" msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2514 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:377 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:385 msgid "Restarts" msgstr "" @@ -6552,9 +6552,9 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:327 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:3043 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:3044 -#: src/tachyon/methods/custom/getDashboardSections.ts:1693 +#: src/tachyon/methods/custom/getDashboardSections.ts:1715 #: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:140 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:312 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:320 msgid "Running" msgstr "" @@ -7002,9 +7002,9 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:3824 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:3843 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16042 -#: src/tachyon/tabs/diagnostic/initController.ts:610 #: src/tachyon/methods/shell/index.ts:468 #: src/tachyon/methods/shell/index.ts:489 +#: src/tachyon/tabs/diagnostic/initController.ts:610 msgid "Service action failed" msgstr "" @@ -7027,7 +7027,7 @@ msgid "Services are online and ready! Reloading page..." msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8996 -#: src/tachyon/tabs/dashboard/initController.ts:1901 +#: src/tachyon/tabs/dashboard/initController.ts:1909 msgid "Services info" msgstr "" @@ -7382,7 +7382,7 @@ msgid "Starting…" msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9079 -#: src/tachyon/tabs/dashboard/initController.ts:2014 +#: src/tachyon/tabs/dashboard/initController.ts:2022 msgid "State" msgstr "" @@ -7393,7 +7393,7 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/parental.js:935 #: src/tachyon/tabs/diagnostic/partials/renderLeakCheckModal.ts:142 #: src/tachyon/tabs/diagnostic/partials/renderServiceCheckModal.ts:481 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:359 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:367 msgid "Status" msgstr "" @@ -7424,9 +7424,9 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:15239 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:333 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:3049 -#: src/tachyon/methods/custom/getDashboardSections.ts:1697 +#: src/tachyon/methods/custom/getDashboardSections.ts:1719 #: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:152 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:316 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:324 msgid "Stopped" msgstr "" @@ -7553,7 +7553,7 @@ msgid "System diagnostics, AI Doctor and logs" msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8984 -#: src/tachyon/tabs/dashboard/initController.ts:1888 +#: src/tachyon/tabs/dashboard/initController.ts:1896 msgid "System info" msgstr "" @@ -7688,7 +7688,7 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9074 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:2247 -#: src/tachyon/tabs/dashboard/initController.ts:2004 +#: src/tachyon/tabs/dashboard/initController.ts:2012 msgid "Tailscale" msgstr "" @@ -7782,7 +7782,7 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2939 #: src/tachyon/tabs/dashboard/partials/renderSections.ts:252 #: src/tachyon/tabs/dashboard/partials/renderSections.ts:260 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:933 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:949 msgid "Test latency" msgstr "" @@ -7934,7 +7934,7 @@ msgid "This option requires a value." msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9087 -#: src/tachyon/tabs/dashboard/initController.ts:2025 +#: src/tachyon/tabs/dashboard/initController.ts:2033 msgid "This router" msgstr "" @@ -8058,7 +8058,7 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2338 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8960 -#: src/tachyon/tabs/dashboard/initController.ts:1862 +#: src/tachyon/tabs/dashboard/initController.ts:1870 #: src/tachyon/tabs/dashboard/partials/renderSections.ts:138 msgid "Traffic" msgstr "" @@ -8080,7 +8080,7 @@ msgid "Traffic statistics and active connections" msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8972 -#: src/tachyon/tabs/dashboard/initController.ts:1875 +#: src/tachyon/tabs/dashboard/initController.ts:1883 msgid "Traffic Total" msgstr "" @@ -8319,9 +8319,9 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:15249 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:354 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:3066 -#: src/tachyon/methods/custom/getDashboardSections.ts:1699 +#: src/tachyon/methods/custom/getDashboardSections.ts:1721 #: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:162 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:318 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:326 msgid "Unknown" msgstr "" @@ -8371,7 +8371,7 @@ msgid "Unspecified IP address is not allowed" msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2534 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:401 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:409 msgid "Unstable" msgstr "" @@ -8464,8 +8464,8 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8962 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8974 -#: src/tachyon/tabs/dashboard/initController.ts:1864 -#: src/tachyon/tabs/dashboard/initController.ts:1877 +#: src/tachyon/tabs/dashboard/initController.ts:1872 +#: src/tachyon/tabs/dashboard/initController.ts:1885 msgid "Uplink" msgstr "" @@ -8523,8 +8523,8 @@ msgstr "" #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2725 #: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8555 #: src/tachyon/tabs/dashboard/initController.ts:1331 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:659 -#: src/tachyon/tabs/dashboard/partials/renderSections.ts:660 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:667 +#: src/tachyon/tabs/dashboard/partials/renderSections.ts:668 msgid "URLTest details" msgstr "" diff --git a/tachyon/files/usr/lib/core/constants.uc b/tachyon/files/usr/lib/core/constants.uc index 828e457b..78c0a8c5 100644 --- a/tachyon/files/usr/lib/core/constants.uc +++ b/tachyon/files/usr/lib/core/constants.uc @@ -136,7 +136,7 @@ function constants_map() { c.SB_DNS_INBOUND_ADDRESS = env("SB_DNS_INBOUND_ADDRESS", "127.0.0.42"); c.SB_DNS_INBOUND_PORT = env("SB_DNS_INBOUND_PORT", "53"); c.SB_DNS_BLOCK_INBOUND_TAG = env("SB_DNS_BLOCK_INBOUND_TAG", "dns-block-in"); - c.SB_DNS_BLOCK_INBOUND_ADDRESS = env("SB_DNS_BLOCK_INBOUND_ADDRESS", "127.0.0.43"); + c.SB_DNS_BLOCK_INBOUND_ADDRESS = env("SB_DNS_BLOCK_INBOUND_ADDRESS", "::"); c.SB_DNS_BLOCK_INBOUND_PORT = env("SB_DNS_BLOCK_INBOUND_PORT", "1053"); c.SB_SERVICE_MIXED_INBOUND_TAG = env("SB_SERVICE_MIXED_INBOUND_TAG", "service-mixed-in"); c.SB_SERVICE_MIXED_INBOUND_ADDRESS = env("SB_SERVICE_MIXED_INBOUND_ADDRESS", "127.0.0.1"); diff --git a/tachyon/files/usr/lib/nft/apply.uc b/tachyon/files/usr/lib/nft/apply.uc index 5152c702..41943ab7 100644 --- a/tachyon/files/usr/lib/nft/apply.uc +++ b/tachyon/files/usr/lib/nft/apply.uc @@ -11,7 +11,8 @@ let connections = require("config.connections"); let routing_rulesets = require("routing.rulesets"); let runtime_constants = require("singbox.constants"); const CONFIG_NAME = getenv("TACHYON_CONFIG_NAME") || "tachyon"; -const DNS_BLOCK_TARGET = getenv("SB_DNS_BLOCK_INBOUND_ADDRESS") || "127.0.0.43:1053"; +const DNS_BLOCK_PORT = int(getenv("SB_DNS_BLOCK_INBOUND_PORT") || runtime_constants.DNS_BLOCK_INBOUND_PORT); +const DNS_BLOCK_TARGET = ":" + DNS_BLOCK_PORT; const DNS_SOURCE_SET = runtime_constants.DNS_SOURCE_SET; const DNS_SOURCE6_SET = runtime_constants.DNS_SOURCE6_SET; @@ -1135,13 +1136,15 @@ function nft_add_dns_block_rules_from_schedules(schedules, table, profiles) { if (dev_str == "") continue; let is_mac = match(dev_str, /^([0-9a-fA-F]{2}[:-]){5}[0-9a-fA-F]{2}$/) != null; let family = is_mac ? 0 : core_ip.ip_family(dev_str); - if (!is_mac && family != 4) - continue; // dns-block-in listens on IPv4 only + if (!is_mac && family != 4 && family != 6) + continue; for (let interval in intervals) { let match_args = []; if (is_mac) { append_array(match_args, [ "ether", "saddr", lc(replace(dev_str, "-", ":")) ]); + } else if (family == 6) { + append_array(match_args, [ "ip6", "saddr", dev_str ]); } else { append_array(match_args, [ "ip", "saddr", dev_str ]); } @@ -1157,6 +1160,8 @@ function nft_add_dns_block_rules_from_schedules(schedules, table, profiles) { let tcp_args = []; if (is_mac) { append_array(tcp_args, [ "ether", "saddr", lc(replace(dev_str, "-", ":")) ]); + } else if (family == 6) { + append_array(tcp_args, [ "ip6", "saddr", dev_str ]); } else { append_array(tcp_args, [ "ip", "saddr", dev_str ]); } @@ -1199,12 +1204,14 @@ function nft_add_dns_block_rules_from_schedules(schedules, table, profiles) { if (dev_str == "") continue; let is_mac = match(dev_str, /^([0-9a-fA-F]{2}[:-]){5}[0-9a-fA-F]{2}$/) != null; let family = is_mac ? 0 : core_ip.ip_family(dev_str); - if (!is_mac && family != 4) + if (!is_mac && family != 4 && family != 6) continue; let match_args = []; if (is_mac) append_array(match_args, [ "ether", "saddr", lc(replace(dev_str, "-", ":")) ]); + else if (family == 6) + append_array(match_args, [ "ip6", "saddr", dev_str ]); else append_array(match_args, [ "ip", "saddr", dev_str ]); append_array(match_args, [ "udp", "dport", "53", "redirect", "to", DNS_BLOCK_TARGET, "counter", "comment", "\"" + comment + "\"" ]); @@ -1215,6 +1222,8 @@ function nft_add_dns_block_rules_from_schedules(schedules, table, profiles) { let tcp_args = []; if (is_mac) append_array(tcp_args, [ "ether", "saddr", lc(replace(dev_str, "-", ":")) ]); + else if (family == 6) + append_array(tcp_args, [ "ip6", "saddr", dev_str ]); else append_array(tcp_args, [ "ip", "saddr", dev_str ]); append_array(tcp_args, [ "tcp", "dport", "53", "redirect", "to", DNS_BLOCK_TARGET, "counter", "comment", "\"" + comment + "\"" ]); diff --git a/tachyon/files/usr/lib/singbox/constants.uc b/tachyon/files/usr/lib/singbox/constants.uc index b231416b..67ec83e9 100644 --- a/tachyon/files/usr/lib/singbox/constants.uc +++ b/tachyon/files/usr/lib/singbox/constants.uc @@ -16,7 +16,7 @@ const DNS_INBOUND_TAG = "dns-in"; const DNS_INBOUND_ADDRESS = "127.0.0.42"; const DNS_INBOUND_PORT = 53; const DNS_BLOCK_INBOUND_TAG = "dns-block-in"; -const DNS_BLOCK_INBOUND_ADDRESS = "127.0.0.43"; +const DNS_BLOCK_INBOUND_ADDRESS = "::"; const DNS_BLOCK_INBOUND_PORT = 1053; const SOURCE_DNS_INBOUND_TAG = "source-dns-in"; const SOURCE_DNS_INBOUND_ADDRESS = "::"; diff --git a/tachyon/files/usr/lib/singbox/generator.uc b/tachyon/files/usr/lib/singbox/generator.uc index a544fd30..21503b22 100644 --- a/tachyon/files/usr/lib/singbox/generator.uc +++ b/tachyon/files/usr/lib/singbox/generator.uc @@ -836,10 +836,12 @@ function schedule_domain_matcher_rule(rule, schedule) { push(keyword, trim(substr(value, 8))); else if (substr(value, 0, 6) == "regex:") push(regex, trim(substr(value, 6))); - else if (substr(value, 0, 1) == "." || index(value, "*") >= 0) - push(plain, value); + else if (substr(value, 0, 1) == ".") + push(plain, substr(value, 1)); + else if (index(value, "*") >= 0) + push(plain, replace(value, "*.", "")); else - push(full, value); + push(plain, value); } if (length(full) > 0) rule.domain = full; @@ -852,6 +854,22 @@ function schedule_domain_matcher_rule(rule, schedule) { return rule; } +function schedule_has_mac_devices(schedule) { + for (let raw in schedule_list_value(schedule, "device_ip")) { + let device = trim(as_string(raw)); + if (match(device, /^([0-9a-fA-F]{2}[:-]){5}[0-9a-fA-F]{2}$/) != null) + return true; + } + for (let p_name in schedule_list_value(schedule, "profile")) { + let prof = ctx.uci_cursor().get_all(CONFIG_NAME, p_name); + if (prof != null && section_enabled(prof)) { + if (schedule_has_mac_devices(prof)) + return true; + } + } + return false; +} + function schedule_blocked_domains(schedule) { let result = []; for (let domain in schedule_list_value(schedule, "blocked_domains")) { @@ -942,7 +960,7 @@ function add_content_block_dns_inbound(config) { push(config.inbounds, { type: "direct", tag: runtime_constants.DNS_BLOCK_INBOUND_TAG, - listen: runtime_constants.DNS_BLOCK_INBOUND_ADDRESS, + listen: core_ip.ipv6_supported() ? runtime_constants.DNS_BLOCK_INBOUND_ADDRESS : "0.0.0.0", listen_port: runtime_constants.DNS_BLOCK_INBOUND_PORT }); } @@ -952,6 +970,7 @@ function add_content_block_dns_rules(config, schedules) { for (let schedule in schedules) { let mode = option(schedule, "mode", "block"); let sources = schedule_source_ip_cidrs(schedule); + let has_mac = schedule_has_mac_devices(schedule); for (let raw_domain in schedule_blocked_domains(schedule)) { let domain_value = trim(as_string(raw_domain)); if (domain_value == "") @@ -966,7 +985,7 @@ function add_content_block_dns_rules(config, schedules) { if (matchers[key] != null) rule[key] = matchers[key]; } - if (length(sources) > 0) + if (length(sources) > 0 && !has_mac) rule.source_ip_cidr = sources; if (mode == "allow") rule.invert = true; @@ -1006,6 +1025,10 @@ function add_content_blocking(config) { return; add_content_block_dns_inbound(config); + unshift(config.route.rules, { + action: "hijack-dns", + inbound: [ runtime_constants.DNS_BLOCK_INBOUND_TAG ] + }); add_content_block_dns_rules(config, schedules); add_content_block_dns_rules(config, profiles); add_safesearch_dns_rules(config, safesearch_profiles); diff --git a/tests/content_blocking.sh b/tests/content_blocking.sh index 859c7418..a2da026f 100644 --- a/tests/content_blocking.sh +++ b/tests/content_blocking.sh @@ -82,7 +82,11 @@ generate_config "$WORK_DIR/fixture_always_on.json" "$OUT" assert_contains "$OUT" '"tag": "dns-block-in"' "always-on: dns-block-in inbound" assert_contains "$OUT" '"listen_port": 1053' "always-on: block inbound port 1053" -# DNS reject rules with source_ip_cidr for IP devices +# Hijack DNS route rule for dns-block-in +assert_contains "$OUT" '"action": "hijack-dns"' "always-on: hijack-dns route rule" + +# DNS reject rules with domain_suffix and source_ip_cidr for IP devices +assert_contains "$OUT" '"domain_suffix": [' "always-on: domain_suffix matching" grep -q '192.168.1.150/32' "$OUT" || fail "always-on: DNS rule must carry source_ip_cidr 192.168.1.150/32" assert_contains "$OUT" '"action": "reject"' "always-on: DNS reject action" @@ -226,9 +230,9 @@ JSON nft_ucode nft-add-dns-block-rules-fixture "$WORK_DIR/nft_fixture.json" "tachyon" # Time-gated rule: IP device, meta hour window, redirect to block target -assert_contains "$NFT_LOG" "dns_block ip saddr 192.168.1.150 meta hour \"22:00:00\"-\"23:59:59\" udp dport 53 redirect to 127.0.0.43:1053 counter comment" "time-gated udp redirect" -assert_contains "$NFT_LOG" "dns_block ip saddr 192.168.1.150 meta hour \"00:00:00\"-\"08:00:00\" udp dport 53 redirect to 127.0.0.43:1053" "midnight wrap udp redirect" -assert_contains "$NFT_LOG" "tcp dport 53 redirect to 127.0.0.43:1053" "tcp dns redirect" +assert_contains "$NFT_LOG" "dns_block ip saddr 192.168.1.150 meta hour \"22:00:00\"-\"23:59:59\" udp dport 53 redirect to :1053 counter comment" "time-gated udp redirect" +assert_contains "$NFT_LOG" "dns_block ip saddr 192.168.1.150 meta hour \"00:00:00\"-\"08:00:00\" udp dport 53 redirect to :1053" "midnight wrap udp redirect" +assert_contains "$NFT_LOG" "tcp dport 53 redirect to :1053" "tcp dns redirect" # MAC device redirect assert_contains "$NFT_LOG" "dns_block ether saddr 11:22:33:44:55:66 meta hour" "mac redirect with time" @@ -237,7 +241,7 @@ assert_contains "$NFT_LOG" "dns_block ether saddr 11:22:33:44:55:66 meta hour" " if grep -Fq "192.168.1.160 meta hour" "$NFT_LOG"; then fail "always-on schedule must not carry meta hour matcher" fi -assert_contains "$NFT_LOG" "ip saddr 192.168.1.160 udp dport 53 redirect to 127.0.0.43:1053" "always-on redirect" +assert_contains "$NFT_LOG" "ip saddr 192.168.1.160 udp dport 53 redirect to :1053" "always-on redirect" # ─── Validator: invalid blocked domain rejected ────────────────────────────── cat >"$WORK_DIR/invalid_domain.json" <<'JSON'