From 51b45b8599346b2f483a97e192ff88922e21910a Mon Sep 17 00:00:00 2001
From: Matteo Luppi <100372313+lups2000@users.noreply.github.com>
Date: Wed, 14 Aug 2024 15:48:36 +0200
Subject: [PATCH] Display current status for each mode (#7097)
* display current status for each mode
* review changes
* update snapshots
* update tests
* [autofix.ci] apply automated fixes
* fix bug
* use type
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
---
web/src/css/mode.less | 21 ++--
.../{ => Modes}/CaptureSetupSpec.tsx | 6 +-
.../__snapshots__/CaptureSetupSpec.tsx.snap | 18 +++
.../Modes/__snapshots__/RegularSpec.tsx.snap | 19 ++-
.../__snapshots__/CaptureSetupSpec.tsx.snap | 42 -------
web/src/js/components/CaptureSetup.tsx | 119 ------------------
web/src/js/components/MainView.tsx | 2 +-
web/src/js/components/Modes/CaptureSetup.tsx | 99 +++++++++++++++
web/src/js/components/Modes/Local.tsx | 26 ++--
web/src/js/components/Modes/Regular.tsx | 21 ++--
web/src/js/components/Modes/Reverse.tsx | 22 ++--
.../js/components/Modes/ReverseToggleRow.tsx | 14 ++-
web/src/js/components/Modes/Wireguard.tsx | 20 +--
13 files changed, 218 insertions(+), 211 deletions(-)
rename web/src/js/__tests__/components/{ => Modes}/CaptureSetupSpec.tsx (57%)
create mode 100644 web/src/js/__tests__/components/Modes/__snapshots__/CaptureSetupSpec.tsx.snap
delete mode 100644 web/src/js/__tests__/components/__snapshots__/CaptureSetupSpec.tsx.snap
delete mode 100644 web/src/js/components/CaptureSetup.tsx
create mode 100644 web/src/js/components/Modes/CaptureSetup.tsx
diff --git a/web/src/css/mode.less b/web/src/css/mode.less
index eddd2a2f1..c9073d1c0 100644
--- a/web/src/css/mode.less
+++ b/web/src/css/mode.less
@@ -5,6 +5,9 @@
.modes {
padding: 1em 2em;
+ overflow-y: auto;
+ height: 100%;
+ width: 100vw;
h3 {
margin-top: 30px;
@@ -47,9 +50,10 @@
}
}
- .mode-error {
+ .mode-status {
margin-left: 10px;
margin-top: 5px;
+ font-weight: 600;
}
.mode-local-input {
@@ -81,13 +85,16 @@
margin: 0 5px;
}
+ .mode-reverse-servers {
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+ }
+
.mode-reverse-add-server {
margin-left: 10px;
- margin-top: 15px;
display: flex;
flex-direction: row;
- align-items: center;
- justify-content: center;
cursor: pointer;
font-weight: 500;
@@ -96,10 +103,4 @@
margin-right: 5px;
}
}
-
- .mode-reverse-servers {
- display: flex;
- flex-direction: column;
- gap: 10px;
- }
}
diff --git a/web/src/js/__tests__/components/CaptureSetupSpec.tsx b/web/src/js/__tests__/components/Modes/CaptureSetupSpec.tsx
similarity index 57%
rename from web/src/js/__tests__/components/CaptureSetupSpec.tsx
rename to web/src/js/__tests__/components/Modes/CaptureSetupSpec.tsx
index 89536430c..204a3da29 100644
--- a/web/src/js/__tests__/components/CaptureSetupSpec.tsx
+++ b/web/src/js/__tests__/components/Modes/CaptureSetupSpec.tsx
@@ -1,7 +1,7 @@
import * as React from "react";
-import { render } from "../test-utils";
-import CaptureSetup from "../../components/CaptureSetup";
-import { TStore } from "../ducks/tutils";
+import { render } from "../../test-utils";
+import CaptureSetup from "../../../components/Modes/CaptureSetup";
+import { TStore } from "../../ducks/tutils";
test("CaptureSetup", async () => {
const store = TStore();
diff --git a/web/src/js/__tests__/components/Modes/__snapshots__/CaptureSetupSpec.tsx.snap b/web/src/js/__tests__/components/Modes/__snapshots__/CaptureSetupSpec.tsx.snap
new file mode 100644
index 000000000..1d00ff95e
--- /dev/null
+++ b/web/src/js/__tests__/components/Modes/__snapshots__/CaptureSetupSpec.tsx.snap
@@ -0,0 +1,18 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`CaptureSetup 1`] = `
+
+
+
+ mitmproxy is running.
+
+
+ No flows have been recorded yet.
+
+ To start capturing traffic, please configure your settings in the Capture tab.
+
+
+
+`;
diff --git a/web/src/js/__tests__/components/Modes/__snapshots__/RegularSpec.tsx.snap b/web/src/js/__tests__/components/Modes/__snapshots__/RegularSpec.tsx.snap
index d9d856e77..3f75142f6 100644
--- a/web/src/js/__tests__/components/Modes/__snapshots__/RegularSpec.tsx.snap
+++ b/web/src/js/__tests__/components/Modes/__snapshots__/RegularSpec.tsx.snap
@@ -28,6 +28,17 @@ exports[`RegularSpec 1`] = `
tabindex="0"
/>
+
+
+
+ HTTP(S) proxy listening at 127.0.0.1:8080 and [::1]:8080.
+
+
+
@@ -62,9 +73,13 @@ exports[`RegularSpec 2`] = `
/>
- port already in use
+
+ port already in use
+
diff --git a/web/src/js/__tests__/components/__snapshots__/CaptureSetupSpec.tsx.snap b/web/src/js/__tests__/components/__snapshots__/CaptureSetupSpec.tsx.snap
deleted file mode 100644
index d37caa1c8..000000000
--- a/web/src/js/__tests__/components/__snapshots__/CaptureSetupSpec.tsx.snap
+++ /dev/null
@@ -1,42 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`CaptureSetup 1`] = `
-
-
-
- mitmproxy is running.
-
-
- No flows have been recorded yet.
-
- Configure your client to use one of the following proxy servers:
-
-
- -
-
- HTTP(S) proxy listening at 127.0.0.1:8080 and [::1]:8080.
-
- -
-
- Reverse proxy to example.com (reverse:example.com):
-
- I failed somehow.
-
- -
-
- SOCKS v5 proxy (socks5)
-
-
-
-
-`;
diff --git a/web/src/js/components/CaptureSetup.tsx b/web/src/js/components/CaptureSetup.tsx
deleted file mode 100644
index 0faef56a3..000000000
--- a/web/src/js/components/CaptureSetup.tsx
+++ /dev/null
@@ -1,119 +0,0 @@
-import * as React from "react";
-import { useEffect, useRef } from "react";
-import { useAppSelector } from "../ducks";
-import { ServerInfo } from "../ducks/backendState";
-import { formatAddress } from "../utils";
-import QRCode from "qrcode";
-
-export default function CaptureSetup() {
- const servers = Object.values(
- useAppSelector((state) => state.backendState.servers),
- );
-
- let configure_action_text;
- if (servers.length === 0) {
- configure_action_text = "";
- } else if (servers.length === 1) {
- configure_action_text =
- "Configure your client to use the following proxy server:";
- } else {
- configure_action_text =
- "Configure your client to use one of the following proxy servers:";
- }
-
- return (
-
-
mitmproxy is running.
-
- No flows have been recorded yet.
-
- {configure_action_text}
-
-
- {servers.map((server) => (
- -
-
-
- ))}
-
- {/*
-
You can also start additional servers:
-
- */}
-
- );
-}
-
-export function ServerDescription({
- description,
- listen_addrs,
- last_exception,
- is_running,
- full_spec,
- wireguard_conf,
-}: ServerInfo) {
- const qrCode = useRef(null);
- useEffect(() => {
- if (wireguard_conf && qrCode.current)
- QRCode.toCanvas(qrCode.current, wireguard_conf, {
- margin: 0,
- scale: 3,
- });
- }, [wireguard_conf]);
-
- let listen_str;
- const all_same_port =
- listen_addrs.length === 1 ||
- (listen_addrs.length === 2 &&
- listen_addrs[0][1] === listen_addrs[1][1]);
- const unbound = listen_addrs.every((addr) =>
- ["::", "0.0.0.0"].includes(addr[0]),
- );
- if (all_same_port && unbound) {
- listen_str = formatAddress(["*", listen_addrs[0][1]]);
- } else {
- listen_str = listen_addrs.map(formatAddress).join(" and ");
- }
- description = description[0].toUpperCase() + description.substr(1);
- let desc, icon;
- if (last_exception) {
- icon = "fa-exclamation text-error";
- desc = (
- <>
- {description} ({full_spec}):
-
- {last_exception}
- >
- );
- } else if (!is_running) {
- icon = "fa-pause text-warning";
- desc = (
- <>
- {description} ({full_spec})
- >
- );
- } else {
- icon = "fa-check text-success";
- desc = `${description} listening at ${listen_str}.`;
-
- if (wireguard_conf) {
- desc = (
- <>
- {desc}
-
- >
- );
- }
- }
- return (
- <>
-
- {desc}
- >
- );
-}
diff --git a/web/src/js/components/MainView.tsx b/web/src/js/components/MainView.tsx
index 5fece4961..9c639f5df 100644
--- a/web/src/js/components/MainView.tsx
+++ b/web/src/js/components/MainView.tsx
@@ -3,7 +3,7 @@ import Splitter from "./common/Splitter";
import FlowTable from "./FlowTable";
import FlowView from "./FlowView";
import { useAppSelector } from "../ducks";
-import CaptureSetup from "./CaptureSetup";
+import CaptureSetup from "./Modes/CaptureSetup";
import Modes from "./Modes";
import { Tab } from "../ducks/ui/tabs";
diff --git a/web/src/js/components/Modes/CaptureSetup.tsx b/web/src/js/components/Modes/CaptureSetup.tsx
new file mode 100644
index 000000000..fae840592
--- /dev/null
+++ b/web/src/js/components/Modes/CaptureSetup.tsx
@@ -0,0 +1,99 @@
+import * as React from "react";
+import { useEffect, useRef } from "react";
+import { ServerInfo } from "../../ducks/backendState";
+import { formatAddress } from "../../utils";
+import QRCode from "qrcode";
+
+export default function CaptureSetup() {
+ return (
+
+
mitmproxy is running.
+
+ No flows have been recorded yet.
+
+ To start capturing traffic, please configure your settings in
+ the Capture tab.
+
+
+ );
+}
+
+function ServerDescription({
+ description,
+ listen_addrs,
+ is_running,
+ full_spec,
+ wireguard_conf,
+ type,
+}: ServerInfo) {
+ const qrCode = useRef(null);
+ useEffect(() => {
+ if (wireguard_conf && qrCode.current)
+ QRCode.toCanvas(qrCode.current, wireguard_conf, {
+ margin: 0,
+ scale: 3,
+ });
+ }, [wireguard_conf]);
+
+ let listen_str;
+ const all_same_port =
+ listen_addrs.length === 1 ||
+ (listen_addrs.length === 2 &&
+ listen_addrs[0][1] === listen_addrs[1][1]);
+ const unbound = listen_addrs.every((addr) =>
+ ["::", "0.0.0.0"].includes(addr[0]),
+ );
+ if (all_same_port && unbound) {
+ listen_str = formatAddress(["*", listen_addrs[0][1]]);
+ } else {
+ listen_str = listen_addrs.map(formatAddress).join(" and ");
+ }
+ description = description[0].toUpperCase() + description.substr(1);
+ let desc;
+ if (!is_running) {
+ desc = (
+ <>
+
+ {description} ({full_spec})
+
+ >
+ );
+ } else {
+ desc = (
+ <>
+ {type === "local" ? (
+ {description} is active.
+ ) : (
+
+ {description} listening at {listen_str}.
+
+ )}
+ {wireguard_conf && (
+
+ )}
+ >
+ );
+ }
+ return {desc}
;
+}
+
+export function ServerStatus({
+ error,
+ backendState,
+}: {
+ error?: string;
+ backendState?: ServerInfo;
+}) {
+ return (
+
+ {error ? (
+
{error}
+ ) : (
+ backendState &&
+ )}
+
+ );
+}
diff --git a/web/src/js/components/Modes/Local.tsx b/web/src/js/components/Modes/Local.tsx
index 408f6c90a..3abe91f34 100644
--- a/web/src/js/components/Modes/Local.tsx
+++ b/web/src/js/components/Modes/Local.tsx
@@ -4,17 +4,21 @@ import { useAppDispatch, useAppSelector } from "../../ducks";
import { setActive, setApplications } from "../../ducks/modes/local";
import ValueEditor from "../editors/ValueEditor";
import { getSpec, LocalState } from "../../modes/local";
+import { ServerStatus } from "./CaptureSetup";
+import { ServerInfo } from "../../ducks/backendState";
export default function Local() {
const serverState = useAppSelector((state) => state.modes.local);
const backendState = useAppSelector((state) => state.backendState.servers);
const servers = serverState.map((server) => {
- const error =
- server.error ||
- backendState[getSpec(server)]?.last_exception ||
- undefined;
- return ;
+ return (
+
+ );
});
return (
@@ -28,9 +32,17 @@ export default function Local() {
);
}
-function LocalRow({ server, error }: { server: LocalState; error?: string }) {
+function LocalRow({
+ server,
+ backendState,
+}: {
+ server: LocalState;
+ backendState?: ServerInfo;
+}) {
const dispatch = useAppDispatch();
+ const error = server.error || backendState?.last_exception || undefined;
+
return (
);
}
diff --git a/web/src/js/components/Modes/Regular.tsx b/web/src/js/components/Modes/Regular.tsx
index 7a40e08cc..799817ca7 100644
--- a/web/src/js/components/Modes/Regular.tsx
+++ b/web/src/js/components/Modes/Regular.tsx
@@ -4,17 +4,21 @@ import { useAppDispatch, useAppSelector } from "../../ducks";
import { setListenPort, setActive } from "../../ducks/modes/regular";
import ValueEditor from "../editors/ValueEditor";
import { getSpec, RegularState } from "../../modes/regular";
+import { ServerInfo } from "../../ducks/backendState";
+import { ServerStatus } from "./CaptureSetup";
export default function Regular() {
const serverState = useAppSelector((state) => state.modes.regular);
const backendState = useAppSelector((state) => state.backendState.servers);
const servers = serverState.map((server) => {
- const error =
- server.error ||
- backendState[getSpec(server)]?.last_exception ||
- undefined;
- return ;
+ return (
+
+ );
});
return (
@@ -31,15 +35,18 @@ export default function Regular() {
function RegularRow({
server,
- error,
+ backendState,
}: {
server: RegularState;
error?: string;
+ backendState?: ServerInfo;
}) {
const dispatch = useAppDispatch();
server.listen_host && console.warn("TODO: implement listen_host");
+ const error = server.error || backendState?.last_exception || undefined;
+
return (
);
}
diff --git a/web/src/js/components/Modes/Reverse.tsx b/web/src/js/components/Modes/Reverse.tsx
index f8efcffa3..c6bd28c6f 100644
--- a/web/src/js/components/Modes/Reverse.tsx
+++ b/web/src/js/components/Modes/Reverse.tsx
@@ -2,11 +2,13 @@ import * as React from "react";
import ReverseToggleRow from "./ReverseToggleRow";
import { useAppDispatch, useAppSelector } from "../../ducks";
import { addServer } from "../../ducks/modes/reverse";
+import { getSpec } from "../../modes/reverse";
export default function Reverse() {
const dispatch = useAppDispatch();
const servers = useAppSelector((state) => state.modes.reverse);
+ const backendState = useAppSelector((state) => state.backendState.servers);
return (
@@ -16,15 +18,19 @@ export default function Reverse() {
{servers.map((server) => (
-
+
))}
-
-
dispatch(addServer())}
- >
-
Add
- additional server
+
dispatch(addServer())}
+ >
+
+ Add additional server
+
);
diff --git a/web/src/js/components/Modes/ReverseToggleRow.tsx b/web/src/js/components/Modes/ReverseToggleRow.tsx
index 00ba45c69..e2ccc8644 100644
--- a/web/src/js/components/Modes/ReverseToggleRow.tsx
+++ b/web/src/js/components/Modes/ReverseToggleRow.tsx
@@ -13,12 +13,18 @@ import {
} from "../../ducks/modes/reverse";
import { ReverseProxyProtocols } from "../../backends/consts";
import { ReverseState } from "../../modes/reverse";
+import { ServerStatus } from "./CaptureSetup";
+import { ServerInfo } from "../../ducks/backendState";
interface ReverseToggleRowProps {
server: ReverseState;
+ backendState?: ServerInfo;
}
-export default function ReverseToggleRow({ server }: ReverseToggleRowProps) {
+export default function ReverseToggleRow({
+ server,
+ backendState,
+}: ReverseToggleRowProps) {
const dispatch = useAppDispatch();
const protocols = Object.values(ReverseProxyProtocols);
@@ -37,6 +43,8 @@ export default function ReverseToggleRow({ server }: ReverseToggleRowProps) {
await dispatch(removeServer(server));
};
+ const error = server.error || backendState?.last_exception || undefined;
+
return (
- {server.error && (
-
{server.error}
- )}
+
);
}
diff --git a/web/src/js/components/Modes/Wireguard.tsx b/web/src/js/components/Modes/Wireguard.tsx
index 775a7735c..0092fd44c 100644
--- a/web/src/js/components/Modes/Wireguard.tsx
+++ b/web/src/js/components/Modes/Wireguard.tsx
@@ -3,18 +3,20 @@ import { ModeToggle } from "./ModeToggle";
import { useAppDispatch, useAppSelector } from "../../ducks";
import { getSpec, WireguardState } from "../../modes/wireguard";
import { setActive } from "../../ducks/modes/wireguard";
+import { ServerInfo } from "../../ducks/backendState";
+import { ServerStatus } from "./CaptureSetup";
export default function Wireguard() {
const serverState = useAppSelector((state) => state.modes.wireguard);
const backendState = useAppSelector((state) => state.backendState.servers);
const servers = serverState.map((server) => {
- const error =
- server.error ||
- backendState[getSpec(server)]?.last_exception ||
- undefined;
return (
-
+
);
});
@@ -32,13 +34,15 @@ export default function Wireguard() {
function WireGuardRow({
server,
- error,
+ backendState,
}: {
server: WireguardState;
- error?: string;
+ backendState?: ServerInfo;
}) {
const dispatch = useAppDispatch();
+ const error = server.error || backendState?.last_exception || undefined;
+
return (
Run WireGuard Server
- {error &&
{error}
}
+
);
}