Feature/wireguard mode (#6959)
* define first components * Update CHANGELOG.md * Autofix generated JS files and do not patch them in tests (#6910) * autofix generated JS files and do not patch them in tests * autofix: setup python * [autofix.ci] apply automated fixes * autofix: setup node * add missing newline * fixup --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> * Update package-lock.json, bump esbuild (#6915) update node version, bump esbuild * Fix clipboard handling in safari (#6917) * fix clipboard handling in safari closes #6911, #6909 Co-authored-by: Can Yesilyurt <36952967+canyesilyurt@users.noreply.github.com> * [autofix.ci] apply automated fixes * update dependencies --------- Co-authored-by: Can Yesilyurt <36952967+canyesilyurt@users.noreply.github.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> * define first modes components * adapt code to reuse checkbox component * mitmproxy 10.3.1 * reopen main for development * [autofix.ci] apply automated fixes * improve mode toggle design * remove inline style * release script: add one less newline * fix zstd decompression (#6921) * fix zstd decompression (issue #6914) * add our fix to CHANGELOG * add explicit read_across_frames=True + move zstd test to test_encoding.py --------- Co-authored-by: Maximilian Hils <git@maximilianhils.com> * first attempt to make the modes functional * [autofix.ci] apply automated fixes * Update CHANGELOG.md * web: Upgrade Redux (#6926) * update redux and fix resulting test and type failures * update prettier * refactor code according to review * [autofix.ci] apply automated fixes * first prototype regular mode * [autofix.ci] apply automated fixes * Use upstream urwid again (#6929) use upstream urwid again * change name regular duck * Add `HttpConnectedHook` and `HttpConnectErrorHook` (#6930) * Add HttpConnectedHook and HttpConnectErrorHook * [autofix.ci] apply automated fixes --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> * rewrite updateMode function and error handling regular mode * remove label component * add input field to local mode and fix onKeyDown issue * add dropdown to reverse mode * [autofix.ci] apply automated fixes * change defualt string reverse dropdown * add new logic to handle modes in the duck * add local mode with no applications * [autofix.ci] apply automated fixes * regular mode is now persistent * forgot recieve event in regular mode * join receive and update event * make local mode functional * make wireguard mode functional * [autofix.ci] apply automated fixes * make reverse mode functional * [autofix.ci] apply automated fixes * fix bug reverse mode when refreshing * fix bug local mode * [autofix.ci] apply automated fixes * fix old test * implement first tests * [autofix.ci] apply automated fixes * make DNS mode listen for both UDP and TCP (#6912) Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> * remove wireguard and reverse modes * change name function to set local applications * remove error handling * remove left over * add some other review changes * [autofix.ci] apply automated fixes * release ci: strip "v" prefix from sigstore file * fix addListen Addr function * adjust reverse protocol attribute * create proper method to parse the mode * adjust passing applications to local mode * fix onKeyDown listener and add new input field to local mode * [autofix.ci] apply automated fixes * remove leftover * update tests * [autofix.ci] apply automated fixes * remove wireguard and reverse files * remove additional state local mode * adjust tests local mode * update tests local mode * update last tests modes * [autofix.ci] apply automated fixes * fix: OSError raised when ipv6 is disabled (#6942) the function should return None in this case * use fetchMock instead of jest.mock this is slightly nicer because we are testing at the application boundary * duck tests should use action creators and not manually construct actions * move toggleLocal to fetchMock * move updateMode and ModeState into utils this avoids circular imports. utils may not be the perfect place, but much better than the circular imports * nits * [autofix.ci] apply automated fixes * update tests regular and local mode * [autofix.ci] apply automated fixes * review changes tests * [autofix.ci] apply automated fixes * adjust parseMode issue * [autofix.ci] apply automated fixes * add first components for wireguard mode * fix CI * fix typo * add tests to wireguard mode * [autofix.ci] apply automated fixes --------- Co-authored-by: Maximilian Hils <git@maximilianhils.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Can Yesilyurt <36952967+canyesilyurt@users.noreply.github.com> Co-authored-by: mitmproxy release bot <noreply@mitmproxy.org> Co-authored-by: Andras Spitzer <sendai@swordsaint.net> Co-authored-by: Gaurav Jain <64748057+errorxyz@users.noreply.github.com> Co-authored-by: Walt Chen <godsarmycy@gmail.com>
This commit is contained in:
parent
d9770ad2b1
commit
e047e76b22
|
@ -0,0 +1,110 @@
|
||||||
|
import { enableFetchMocks } from "jest-fetch-mock";
|
||||||
|
import wireguardReducer, {
|
||||||
|
getMode,
|
||||||
|
initialState,
|
||||||
|
toggleWireguard,
|
||||||
|
} from "../../../ducks/modes/wireguard";
|
||||||
|
import { TStore } from "../tutils";
|
||||||
|
import * as options from "../../../ducks/options";
|
||||||
|
|
||||||
|
describe("wireguardReducer", () => {
|
||||||
|
it("should return the initial state", () => {
|
||||||
|
const state = wireguardReducer(undefined, {});
|
||||||
|
expect(state).toEqual(initialState);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should dispatch MODE_WIREGUARD_TOGGLE and updateMode", async () => {
|
||||||
|
enableFetchMocks();
|
||||||
|
|
||||||
|
const store = TStore();
|
||||||
|
|
||||||
|
expect(store.getState().modes.wireguard.active).toBe(false);
|
||||||
|
await store.dispatch(toggleWireguard());
|
||||||
|
expect(store.getState().modes.wireguard.active).toBe(true);
|
||||||
|
expect(fetchMock).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle RECEIVE_OPTIONS action with data.mode containing "wireguard", an host and a port', () => {
|
||||||
|
const action = {
|
||||||
|
type: options.RECEIVE,
|
||||||
|
data: {
|
||||||
|
mode: {
|
||||||
|
value: ["wireguard:/path_example@localhost:8081"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const newState = wireguardReducer(initialState, action);
|
||||||
|
expect(newState.active).toBe(true);
|
||||||
|
expect(newState.listen_host).toBe("localhost");
|
||||||
|
expect(newState.listen_port).toBe(8081);
|
||||||
|
expect(newState.path).toBe("/path_example");
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle RECEIVE_OPTIONS action with data.mode containing just "wireguard"', () => {
|
||||||
|
const initialState = {
|
||||||
|
active: false,
|
||||||
|
listen_host: "localhost",
|
||||||
|
listen_port: 8080,
|
||||||
|
};
|
||||||
|
const action = {
|
||||||
|
type: options.RECEIVE,
|
||||||
|
data: {
|
||||||
|
mode: {
|
||||||
|
value: ["wireguard"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const newState = wireguardReducer(initialState, action);
|
||||||
|
expect(newState.active).toBe(true);
|
||||||
|
expect(newState.listen_host).toBe("");
|
||||||
|
expect(newState.listen_port).toBe("");
|
||||||
|
expect(newState.path).toBe("");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle RECEIVE_OPTIONS action with data.mode containing another mode", () => {
|
||||||
|
const initialState = {
|
||||||
|
active: false,
|
||||||
|
listen_host: "localhost",
|
||||||
|
listen_port: 8080,
|
||||||
|
path: "/path_example",
|
||||||
|
};
|
||||||
|
const action = {
|
||||||
|
type: options.RECEIVE,
|
||||||
|
data: {
|
||||||
|
mode: {
|
||||||
|
value: ["local"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const newState = wireguardReducer(initialState, action);
|
||||||
|
expect(newState.active).toBe(false);
|
||||||
|
expect(newState.listen_host).toBe(initialState.listen_host);
|
||||||
|
expect(newState.listen_port).toBe(initialState.listen_port);
|
||||||
|
expect(newState.path).toBe(initialState.path);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("getMode", () => {
|
||||||
|
it("should return the correct mode string when active", () => {
|
||||||
|
const modes = {
|
||||||
|
wireguard: {
|
||||||
|
active: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const mode = getMode(modes);
|
||||||
|
expect(JSON.stringify(mode)).toBe(JSON.stringify(["wireguard"]));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return an empty string when not active", () => {
|
||||||
|
const modes = {
|
||||||
|
wireguard: {
|
||||||
|
active: false,
|
||||||
|
path: "/path_example",
|
||||||
|
listen_host: "localhost",
|
||||||
|
listen_port: 8080,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const mode = getMode(modes);
|
||||||
|
expect(JSON.stringify(mode)).toBe(JSON.stringify([]));
|
||||||
|
});
|
||||||
|
});
|
|
@ -132,6 +132,9 @@ export const testState: RootState = {
|
||||||
active: false,
|
active: false,
|
||||||
applications: "",
|
applications: "",
|
||||||
},
|
},
|
||||||
|
wireguard: {
|
||||||
|
active: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import Local from "./Modes/Local";
|
import Local from "./Modes/Local";
|
||||||
import Regular from "./Modes/Regular";
|
import Regular from "./Modes/Regular";
|
||||||
|
import Wireguard from "./Modes/Wireguard";
|
||||||
|
|
||||||
export default function Modes() {
|
export default function Modes() {
|
||||||
return (
|
return (
|
||||||
|
@ -12,6 +13,7 @@ export default function Modes() {
|
||||||
<div className="modes-container">
|
<div className="modes-container">
|
||||||
<Regular />
|
<Regular />
|
||||||
<Local />
|
<Local />
|
||||||
|
<Wireguard />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
import * as React from "react";
|
||||||
|
import { ModeToggle } from "./ModeToggle";
|
||||||
|
import { useAppDispatch, useAppSelector } from "../../ducks";
|
||||||
|
import { toggleWireguard } from "../../ducks/modes/wireguard";
|
||||||
|
|
||||||
|
export default function Wireguard() {
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
|
const { active, error } = useAppSelector((state) => state.modes.wireguard);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h4 className="mode-title">WireGuard Server</h4>
|
||||||
|
<p className="mode-description">
|
||||||
|
Start a WireGuard™ server and connect an external device for
|
||||||
|
transparent proxying.
|
||||||
|
</p>
|
||||||
|
<ModeToggle
|
||||||
|
value={active}
|
||||||
|
onChange={() => dispatch(toggleWireguard())}
|
||||||
|
>
|
||||||
|
Run WireGuard Server
|
||||||
|
</ModeToggle>
|
||||||
|
{error && <div className="mode-error text-danger">{error}</div>}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
|
@ -1,10 +1,12 @@
|
||||||
import { combineReducers } from "redux";
|
import { combineReducers } from "redux";
|
||||||
import regularReducer from "./modes/regular";
|
import regularReducer from "./modes/regular";
|
||||||
import localReducer from "./modes/local";
|
import localReducer from "./modes/local";
|
||||||
|
import wireguardReducer from "./modes/wireguard";
|
||||||
|
|
||||||
const modes = combineReducers({
|
const modes = combineReducers({
|
||||||
regular: regularReducer,
|
regular: regularReducer,
|
||||||
local: localReducer,
|
local: localReducer,
|
||||||
|
wireguard: wireguardReducer,
|
||||||
//add new modes here
|
//add new modes here
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { getMode as getRegularModeConfig } from "./regular";
|
import { getMode as getRegularModeConfig } from "./regular";
|
||||||
import { getMode as getLocalModeConfig } from "./local";
|
import { getMode as getLocalModeConfig } from "./local";
|
||||||
|
import { getMode as getWireguardModeConfig } from "./wireguard";
|
||||||
import { fetchApi, rpartition } from "../../utils";
|
import { fetchApi, rpartition } from "../../utils";
|
||||||
|
|
||||||
export interface ModeState {
|
export interface ModeState {
|
||||||
|
@ -17,6 +18,7 @@ export const updateMode = () => {
|
||||||
const activeModes: string[] = [
|
const activeModes: string[] = [
|
||||||
...getRegularModeConfig(modes),
|
...getRegularModeConfig(modes),
|
||||||
...getLocalModeConfig(modes),
|
...getLocalModeConfig(modes),
|
||||||
|
...getWireguardModeConfig(modes),
|
||||||
//add new modes here
|
//add new modes here
|
||||||
];
|
];
|
||||||
const response = await fetchApi.put("/options", {
|
const response = await fetchApi.put("/options", {
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
import {
|
||||||
|
RECEIVE as RECEIVE_OPTIONS,
|
||||||
|
UPDATE as UPDATE_OPTIONS,
|
||||||
|
} from "../options";
|
||||||
|
import {
|
||||||
|
ModeState,
|
||||||
|
includeModeState,
|
||||||
|
updateMode,
|
||||||
|
getModesOfType,
|
||||||
|
} from "./utils";
|
||||||
|
|
||||||
|
export const MODE_WIREGUARD_TOGGLE = "MODE_WIREGUARD_TOGGLE";
|
||||||
|
|
||||||
|
interface WireguardState extends ModeState {
|
||||||
|
path?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const initialState: WireguardState = {
|
||||||
|
active: false,
|
||||||
|
path: "",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getMode = (modes) => {
|
||||||
|
const wireguardMode = modes.wireguard;
|
||||||
|
return includeModeState("wireguard", wireguardMode);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const toggleWireguard = () => {
|
||||||
|
return async (dispatch) => {
|
||||||
|
dispatch({ type: MODE_WIREGUARD_TOGGLE });
|
||||||
|
|
||||||
|
const result = await dispatch(updateMode());
|
||||||
|
|
||||||
|
if (!result.success) {
|
||||||
|
//TODO: handle error
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const wireguardReducer = (state = initialState, action): WireguardState => {
|
||||||
|
switch (action.type) {
|
||||||
|
case MODE_WIREGUARD_TOGGLE:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
active: !state.active,
|
||||||
|
};
|
||||||
|
case UPDATE_OPTIONS:
|
||||||
|
case RECEIVE_OPTIONS:
|
||||||
|
if (action.data && action.data.mode) {
|
||||||
|
const currentModeConfig = getModesOfType(
|
||||||
|
"wireguard",
|
||||||
|
action.data.mode.value,
|
||||||
|
)[0];
|
||||||
|
const isActive = currentModeConfig !== undefined;
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
active: isActive,
|
||||||
|
path: isActive ? currentModeConfig.data : state.path,
|
||||||
|
listen_host: isActive
|
||||||
|
? currentModeConfig.listen_host
|
||||||
|
: state.listen_host,
|
||||||
|
listen_port: isActive
|
||||||
|
? (currentModeConfig.listen_port as number)
|
||||||
|
: state.listen_port,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default wireguardReducer;
|
Loading…
Reference in New Issue