diff --git a/fe-app-podkop/src/podkop/methods/getFakeIPCheck.ts b/fe-app-podkop/src/podkop/methods/getFakeIPCheck.ts new file mode 100644 index 0000000..0e7bbe2 --- /dev/null +++ b/fe-app-podkop/src/podkop/methods/getFakeIPCheck.ts @@ -0,0 +1,24 @@ +import { executeShellCommand } from '../../helpers'; +import { Podkop } from '../types'; + +export async function getFakeIPCheck(): Promise< + Podkop.MethodResponse +> { + const response = await executeShellCommand({ + command: '/usr/bin/podkop', + args: ['check_fakeip'], + timeout: 10000, + }); + + if (response.stdout) { + return { + success: true, + data: JSON.parse(response.stdout) as Podkop.FakeIPCheckResult, + }; + } + + return { + success: false, + error: '', + }; +} diff --git a/fe-app-podkop/src/podkop/methods/index.ts b/fe-app-podkop/src/podkop/methods/index.ts index 2577428..70d753b 100644 --- a/fe-app-podkop/src/podkop/methods/index.ts +++ b/fe-app-podkop/src/podkop/methods/index.ts @@ -5,3 +5,4 @@ export * from './getSingBoxStatus'; export * from './getDNSCheck'; export * from './getNftRulesCheck'; export * from './getSingBoxCheck'; +export * from './getFakeIPCheck'; diff --git a/fe-app-podkop/src/podkop/tabs/diagnostic/checks/runFakeIPCheck.ts b/fe-app-podkop/src/podkop/tabs/diagnostic/checks/runFakeIPCheck.ts index 82b4eeb..55e0188 100644 --- a/fe-app-podkop/src/podkop/tabs/diagnostic/checks/runFakeIPCheck.ts +++ b/fe-app-podkop/src/podkop/tabs/diagnostic/checks/runFakeIPCheck.ts @@ -1,29 +1,101 @@ +import * as podkopMethods from '../../../methods'; +import * as fakeIPMethods from '../../../../fakeip/methods'; import { updateDiagnosticsCheck } from '../updateDiagnosticsCheck'; +import { insertIf } from '../../../../helpers'; +import { IDiagnosticsChecksItem } from '../../../../store'; export async function runFakeIPCheck() { const code = 'fake_ip_check'; updateDiagnosticsCheck({ code, - title: _('Fake IP checks'), - description: _('Not implemented yet'), - state: 'skipped', + title: _('FakeIP checks'), + description: _('Checking FakeIP, please wait'), + state: 'loading', + items: [], + }); + + const routerFakeIPResponse = await podkopMethods.getFakeIPCheck(); + const checkFakeIPResponse = await fakeIPMethods.getFakeIpCheck(); + const checkIPResponse = await fakeIPMethods.getIpCheck(); + + console.log('runFakeIPCheck', { + routerFakeIPResponse, + checkFakeIPResponse, + checkIPResponse, + }); + + const checks = { + router: routerFakeIPResponse.success && routerFakeIPResponse.data.fakeip, + browserFakeIP: + checkFakeIPResponse.success && checkFakeIPResponse.data.fakeip, + differentIP: + checkFakeIPResponse.success && + checkIPResponse.success && + checkFakeIPResponse.data.IP !== checkIPResponse.data.IP, + }; + + console.log('checks', checks); + + const allGood = checks.router || checks.browserFakeIP || checks.differentIP; + const atLeastOneGood = + checks.router && checks.browserFakeIP && checks.differentIP; + + function getMeta(): { + description: string; + state: 'loading' | 'warning' | 'success' | 'error' | 'skipped'; + } { + if (allGood) { + return { + state: 'success', + description: _('FakeIP checks passed'), + }; + } + + if (atLeastOneGood) { + return { + state: 'warning', + description: _('FakeIP checks partially passed'), + }; + } + + return { + state: 'error', + description: _('FakeIP checks failed'), + }; + } + + const { state, description } = getMeta(); + + updateDiagnosticsCheck({ + code, + title: _('FakeIP checks'), + description, + state, items: [ { - state: 'success', - key: 'success', + state: checks.router ? 'success' : 'warning', + key: checks.router + ? _('Router DNS is routed through sing-box') + : _('Router DNS is not routed through sing-box'), value: '', }, { - state: 'warning', - key: 'warning', - value: '', - }, - { - state: 'error', - key: 'error', + state: checks.browserFakeIP ? 'success' : 'error', + key: checks.browserFakeIP + ? _('Browser is using FakeIP correctly') + : _('Browser is not using FakeIP'), value: '', }, + ...insertIf(checks.browserFakeIP, [ + { + state: checks.differentIP ? 'success' : 'error', + key: checks.differentIP + ? _('Proxy traffic is routed via FakeIP') + : _('Proxy traffic is not routed via FakeIP'), + value: '', + }, + ]), ], }); } diff --git a/fe-app-podkop/src/podkop/tabs/diagnostic/checks/runNftCheck.ts b/fe-app-podkop/src/podkop/tabs/diagnostic/checks/runNftCheck.ts index ddc233a..eb3c93f 100644 --- a/fe-app-podkop/src/podkop/tabs/diagnostic/checks/runNftCheck.ts +++ b/fe-app-podkop/src/podkop/tabs/diagnostic/checks/runNftCheck.ts @@ -5,9 +5,6 @@ import { getFakeIpCheck, getIpCheck } from '../../../../fakeip'; export async function runNftCheck() { const code = 'nft_check'; - await getFakeIpCheck(); - await getIpCheck(); - updateDiagnosticsCheck({ code, title: _('Nftables checks'), @@ -16,6 +13,9 @@ export async function runNftCheck() { items: [], }); + await getFakeIpCheck(); + await getIpCheck(); + const nftablesChecks = await getNftRulesCheck(); if (!nftablesChecks.success) { diff --git a/fe-app-podkop/src/podkop/types.ts b/fe-app-podkop/src/podkop/types.ts index 558f99b..df38f94 100644 --- a/fe-app-podkop/src/podkop/types.ts +++ b/fe-app-podkop/src/podkop/types.ts @@ -97,4 +97,9 @@ export namespace Podkop { sing_box_process_running: 0 | 1; sing_box_ports_listening: 0 | 1; } + + export interface FakeIPCheckResult { + fakeip: boolean; + IP: string; + } } diff --git a/luci-app-podkop/htdocs/luci-static/resources/view/podkop/main.js b/luci-app-podkop/htdocs/luci-static/resources/view/podkop/main.js index 49df475..26f40fc 100644 --- a/luci-app-podkop/htdocs/luci-static/resources/view/podkop/main.js +++ b/luci-app-podkop/htdocs/luci-static/resources/view/podkop/main.js @@ -1268,6 +1268,25 @@ async function getSingBoxCheck() { }; } +// src/podkop/methods/getFakeIPCheck.ts +async function getFakeIPCheck() { + const response = await executeShellCommand({ + command: "/usr/bin/podkop", + args: ["check_fakeip"], + timeout: 1e4 + }); + if (response.stdout) { + return { + success: true, + data: JSON.parse(response.stdout) + }; + } + return { + success: false, + error: "" + }; +} + // src/podkop/services/tab.service.ts var TabService = class _TabService { constructor() { @@ -2774,8 +2793,6 @@ async function getFakeIpCheck() { // src/podkop/tabs/diagnostic/checks/runNftCheck.ts async function runNftCheck() { const code = "nft_check"; - await getFakeIpCheck(); - await getIpCheck(); updateDiagnosticsCheck({ code, title: _("Nftables checks"), @@ -2783,6 +2800,8 @@ async function runNftCheck() { state: "loading", items: [] }); + await getFakeIpCheck(); + await getIpCheck(); const nftablesChecks = await getNftRulesCheck(); if (!nftablesChecks.success) { updateDiagnosticsCheck({ @@ -2865,25 +2884,69 @@ async function runFakeIPCheck() { const code = "fake_ip_check"; updateDiagnosticsCheck({ code, - title: _("Fake IP checks"), - description: _("Not implemented yet"), - state: "skipped", + title: _("FakeIP checks"), + description: _("Checking FakeIP, please wait"), + state: "loading", + items: [] + }); + const routerFakeIPResponse = await getFakeIPCheck(); + const checkFakeIPResponse = await getFakeIpCheck(); + const checkIPResponse = await getIpCheck(); + console.log("runFakeIPCheck", { + routerFakeIPResponse, + checkFakeIPResponse, + checkIPResponse + }); + const checks = { + router: routerFakeIPResponse.success && routerFakeIPResponse.data.fakeip, + browserFakeIP: checkFakeIPResponse.success && checkFakeIPResponse.data.fakeip, + differentIP: checkFakeIPResponse.success && checkIPResponse.success && checkFakeIPResponse.data.IP !== checkIPResponse.data.IP + }; + console.log("checks", checks); + const allGood = checks.router || checks.browserFakeIP || checks.differentIP; + const atLeastOneGood = checks.router && checks.browserFakeIP && checks.differentIP; + function getMeta() { + if (allGood) { + return { + state: "success", + description: _("FakeIP checks passed") + }; + } + if (atLeastOneGood) { + return { + state: "warning", + description: _("FakeIP checks partially passed") + }; + } + return { + state: "error", + description: _("FakeIP checks failed") + }; + } + const { state, description } = getMeta(); + updateDiagnosticsCheck({ + code, + title: _("FakeIP checks"), + description, + state, items: [ { - state: "success", - key: "success", + state: checks.router ? "success" : "warning", + key: checks.router ? _("Router DNS is routed through sing-box") : _("Router DNS is not routed through sing-box"), value: "" }, { - state: "warning", - key: "warning", + state: checks.browserFakeIP ? "success" : "error", + key: checks.browserFakeIP ? _("Browser is using FakeIP correctly") : _("Browser is not using FakeIP"), value: "" }, - { - state: "error", - key: "error", - value: "" - } + ...insertIf(checks.browserFakeIP, [ + { + state: checks.differentIP ? "success" : "error", + key: checks.differentIP ? _("Proxy traffic is routed via FakeIP") : _("Proxy traffic is not routed via FakeIP"), + value: "" + } + ]) ] }); } @@ -2955,6 +3018,7 @@ return baseclass.extend({ getConfigSections, getDNSCheck, getDashboardSections, + getFakeIPCheck, getNftRulesCheck, getPodkopStatus, getProxyUrlName,