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>
This commit is contained in:
parent
8f5540d073
commit
51b45b8599
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
|
@ -0,0 +1,18 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`CaptureSetup 1`] = `
|
||||
<DocumentFragment>
|
||||
<div
|
||||
style="padding: 1em 2em;"
|
||||
>
|
||||
<h3>
|
||||
mitmproxy is running.
|
||||
</h3>
|
||||
<p>
|
||||
No flows have been recorded yet.
|
||||
<br />
|
||||
To start capturing traffic, please configure your settings in the Capture tab.
|
||||
</p>
|
||||
</div>
|
||||
</DocumentFragment>
|
||||
`;
|
|
@ -28,6 +28,17 @@ exports[`RegularSpec 1`] = `
|
|||
tabindex="0"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="mode-status"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="text-success"
|
||||
>
|
||||
HTTP(S) proxy listening at 127.0.0.1:8080 and [::1]:8080.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DocumentFragment>
|
||||
|
@ -62,9 +73,13 @@ exports[`RegularSpec 2`] = `
|
|||
/>
|
||||
</div>
|
||||
<div
|
||||
class="mode-error text-danger"
|
||||
class="mode-status"
|
||||
>
|
||||
port already in use
|
||||
<div
|
||||
class="text-danger"
|
||||
>
|
||||
port already in use
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`CaptureSetup 1`] = `
|
||||
<DocumentFragment>
|
||||
<div
|
||||
style="padding: 1em 2em;"
|
||||
>
|
||||
<h3>
|
||||
mitmproxy is running.
|
||||
</h3>
|
||||
<p>
|
||||
No flows have been recorded yet.
|
||||
<br />
|
||||
Configure your client to use one of the following proxy servers:
|
||||
</p>
|
||||
<ul
|
||||
class="fa-ul"
|
||||
>
|
||||
<li>
|
||||
<i
|
||||
class="fa fa-li fa-check text-success"
|
||||
/>
|
||||
HTTP(S) proxy listening at 127.0.0.1:8080 and [::1]:8080.
|
||||
</li>
|
||||
<li>
|
||||
<i
|
||||
class="fa fa-li fa-exclamation text-error"
|
||||
/>
|
||||
Reverse proxy to example.com (reverse:example.com):
|
||||
<br />
|
||||
I failed somehow.
|
||||
</li>
|
||||
<li>
|
||||
<i
|
||||
class="fa fa-li fa-pause text-warning"
|
||||
/>
|
||||
SOCKS v5 proxy (socks5)
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</DocumentFragment>
|
||||
`;
|
|
@ -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 (
|
||||
<div style={{ padding: "1em 2em" }}>
|
||||
<h3>mitmproxy is running.</h3>
|
||||
<p>
|
||||
No flows have been recorded yet.
|
||||
<br />
|
||||
{configure_action_text}
|
||||
</p>
|
||||
<ul className="fa-ul">
|
||||
{servers.map((server) => (
|
||||
<li key={server.full_spec}>
|
||||
<ServerDescription {...server} />
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
{/*
|
||||
<p>You can also start additional servers:</p>
|
||||
<ul>
|
||||
<li>TODO</li>
|
||||
</ul>
|
||||
*/}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
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}):
|
||||
<br />
|
||||
{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}
|
||||
<div className="wireguard-config">
|
||||
<pre>{wireguard_conf}</pre>
|
||||
<canvas ref={qrCode} />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<i className={`fa fa-li ${icon}`} />
|
||||
{desc}
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -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";
|
||||
|
||||
|
|
|
@ -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 (
|
||||
<div style={{ padding: "1em 2em" }}>
|
||||
<h3>mitmproxy is running.</h3>
|
||||
<p>
|
||||
No flows have been recorded yet.
|
||||
<br />
|
||||
To start capturing traffic, please configure your settings in
|
||||
the Capture tab.
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
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 = (
|
||||
<>
|
||||
<div className="text-warning">
|
||||
{description} ({full_spec})
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
} else {
|
||||
desc = (
|
||||
<>
|
||||
{type === "local" ? (
|
||||
<div className="text-success">{description} is active.</div>
|
||||
) : (
|
||||
<div className="text-success">
|
||||
{description} listening at {listen_str}.
|
||||
</div>
|
||||
)}
|
||||
{wireguard_conf && (
|
||||
<div className="wireguard-config">
|
||||
<pre>{wireguard_conf}</pre>
|
||||
<canvas ref={qrCode} />
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
return <div>{desc}</div>;
|
||||
}
|
||||
|
||||
export function ServerStatus({
|
||||
error,
|
||||
backendState,
|
||||
}: {
|
||||
error?: string;
|
||||
backendState?: ServerInfo;
|
||||
}) {
|
||||
return (
|
||||
<div className="mode-status">
|
||||
{error ? (
|
||||
<div className="text-danger">{error}</div>
|
||||
) : (
|
||||
backendState && <ServerDescription {...backendState} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -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 <LocalRow key={server.ui_id} server={server} error={error} />;
|
||||
return (
|
||||
<LocalRow
|
||||
key={server.ui_id}
|
||||
server={server}
|
||||
backendState={backendState[getSpec(server)]}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
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 (
|
||||
<div>
|
||||
<ModeToggle
|
||||
|
@ -50,7 +62,7 @@ function LocalRow({ server, error }: { server: LocalState; error?: string }) {
|
|||
}
|
||||
/>
|
||||
</ModeToggle>
|
||||
{error && <div className="mode-error text-danger">{error}</div>}
|
||||
<ServerStatus error={error} backendState={backendState} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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 <RegularRow key={server.ui_id} server={server} error={error} />;
|
||||
return (
|
||||
<RegularRow
|
||||
key={server.ui_id}
|
||||
server={server}
|
||||
backendState={backendState[getSpec(server)]}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
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 (
|
||||
<div>
|
||||
<ModeToggle
|
||||
|
@ -63,7 +70,7 @@ function RegularRow({
|
|||
}
|
||||
/>
|
||||
</ModeToggle>
|
||||
{error && <div className="mode-error text-danger">{error}</div>}
|
||||
<ServerStatus error={error} backendState={backendState} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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 (
|
||||
<div>
|
||||
|
@ -16,15 +18,19 @@ export default function Reverse() {
|
|||
</p>
|
||||
<div className="mode-reverse-servers">
|
||||
{servers.map((server) => (
|
||||
<ReverseToggleRow key={server.ui_id} server={server} />
|
||||
<ReverseToggleRow
|
||||
key={server.ui_id}
|
||||
server={server}
|
||||
backendState={backendState[getSpec(server)]}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<div
|
||||
className="mode-reverse-add-server"
|
||||
onClick={() => dispatch(addServer())}
|
||||
>
|
||||
<i className="fa fa-plus-square-o" aria-hidden="true"></i>Add
|
||||
additional server
|
||||
<div
|
||||
className="mode-reverse-add-server"
|
||||
onClick={() => dispatch(addServer())}
|
||||
>
|
||||
<i className="fa fa-plus-square-o" aria-hidden="true"></i>
|
||||
Add additional server
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -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 (
|
||||
<div>
|
||||
<ModeToggle
|
||||
|
@ -99,9 +107,7 @@ export default function ReverseToggleRow({ server }: ReverseToggleRowProps) {
|
|||
onClick={deleteServer}
|
||||
></i>
|
||||
</ModeToggle>
|
||||
{server.error && (
|
||||
<div className="mode-error text-danger">{server.error}</div>
|
||||
)}
|
||||
<ServerStatus error={error} backendState={backendState} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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 (
|
||||
<WireGuardRow key={server.ui_id} server={server} error={error} />
|
||||
<WireGuardRow
|
||||
key={server.ui_id}
|
||||
server={server}
|
||||
backendState={backendState[getSpec(server)]}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -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 (
|
||||
<div>
|
||||
<ModeToggle
|
||||
|
@ -49,7 +53,7 @@ function WireGuardRow({
|
|||
>
|
||||
Run WireGuard Server
|
||||
</ModeToggle>
|
||||
{error && <div className="mode-error text-danger">{error}</div>}
|
||||
<ServerStatus error={error} backendState={backendState} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue