summaryrefslogtreecommitdiffhomepage
path: root/gui/src/renderer
diff options
context:
space:
mode:
Diffstat (limited to 'gui/src/renderer')
-rw-r--r--gui/src/renderer/app.tsx3
-rw-r--r--gui/src/renderer/components/Filter.tsx12
-rw-r--r--gui/src/renderer/components/OpenVpnSettings.tsx35
-rw-r--r--gui/src/renderer/components/VpnSettings.tsx37
-rw-r--r--gui/src/renderer/components/WireguardSettings.tsx53
-rw-r--r--gui/src/renderer/components/select-location/SelectLocation.tsx16
-rw-r--r--gui/src/renderer/components/select-location/select-location-hooks.ts61
-rw-r--r--gui/src/renderer/lib/constraint-updater.ts111
8 files changed, 190 insertions, 138 deletions
diff --git a/gui/src/renderer/app.tsx b/gui/src/renderer/app.tsx
index bab17524d6..bdfe272061 100644
--- a/gui/src/renderer/app.tsx
+++ b/gui/src/renderer/app.tsx
@@ -23,7 +23,6 @@ import {
liftConstraint,
ObfuscationSettings,
RelaySettings,
- RelaySettingsUpdate,
TunnelState,
} from '../shared/daemon-rpc-types';
import { messages, relayLocations } from '../shared/gettext';
@@ -304,7 +303,7 @@ export default class AppRenderer {
public connectTunnel = () => IpcRendererEventChannel.tunnel.connect();
public disconnectTunnel = () => IpcRendererEventChannel.tunnel.disconnect();
public reconnectTunnel = () => IpcRendererEventChannel.tunnel.reconnect();
- public updateRelaySettings = (relaySettings: RelaySettingsUpdate) =>
+ public updateRelaySettings = (relaySettings: RelaySettings) =>
IpcRendererEventChannel.settings.updateRelaySettings(relaySettings);
public updateBridgeSettings = (bridgeSettings: BridgeSettings) =>
IpcRendererEventChannel.settings.updateBridgeSettings(bridgeSettings);
diff --git a/gui/src/renderer/components/Filter.tsx b/gui/src/renderer/components/Filter.tsx
index 2cbc9ab239..d989cbca95 100644
--- a/gui/src/renderer/components/Filter.tsx
+++ b/gui/src/renderer/components/Filter.tsx
@@ -4,7 +4,7 @@ import styled from 'styled-components';
import { colors } from '../../config.json';
import { Ownership } from '../../shared/daemon-rpc-types';
import { messages } from '../../shared/gettext';
-import { useAppContext } from '../context';
+import { useRelaySettingsUpdater } from '../lib/constraint-updater';
import {
EndpointType,
filterLocations,
@@ -38,7 +38,7 @@ const StyledNavigationScrollbars = styled(NavigationScrollbars)({
export default function Filter() {
const history = useHistory();
- const { updateRelaySettings } = useAppContext();
+ const relaySettingsUpdater = useRelaySettingsUpdater();
const initialProviders = useSelector(providersSelector);
const [providers, setProviders] = useState<Record<string, boolean>>(initialProviders);
@@ -69,9 +69,13 @@ export default function Filter() {
// Applies the changes by sending them to the daemon.
const onApply = useCallback(async () => {
- await updateRelaySettings({ normal: { providers: formattedProviderList, ownership } });
+ await relaySettingsUpdater((settings) => {
+ settings.providers = formattedProviderList;
+ settings.ownership = ownership;
+ return settings;
+ });
history.pop();
- }, [formattedProviderList, ownership, history, updateRelaySettings]);
+ }, [formattedProviderList, ownership, history, relaySettingsUpdater]);
return (
<BackAction action={history.pop}>
diff --git a/gui/src/renderer/components/OpenVpnSettings.tsx b/gui/src/renderer/components/OpenVpnSettings.tsx
index dc14cd979f..c848f5688b 100644
--- a/gui/src/renderer/components/OpenVpnSettings.tsx
+++ b/gui/src/renderer/components/OpenVpnSettings.tsx
@@ -3,12 +3,17 @@ import { sprintf } from 'sprintf-js';
import styled from 'styled-components';
import { strings } from '../../config.json';
-import { BridgeState, RelayProtocol, TunnelProtocol } from '../../shared/daemon-rpc-types';
+import {
+ BridgeState,
+ RelayProtocol,
+ TunnelProtocol,
+ wrapConstraint,
+} from '../../shared/daemon-rpc-types';
import { messages } from '../../shared/gettext';
import log from '../../shared/logging';
-import RelaySettingsBuilder from '../../shared/relay-settings-builder';
import { removeNonNumericCharacters } from '../../shared/string-helpers';
import { useAppContext } from '../context';
+import { useRelaySettingsUpdater } from '../lib/constraint-updater';
import { useHistory } from '../lib/history';
import { formatHtml } from '../lib/html-formatter';
import { useBoolean } from '../lib/utilityHooks';
@@ -177,34 +182,24 @@ function TransportProtocolSelector() {
}
function useProtocolAndPortUpdater() {
- const { updateRelaySettings } = useAppContext();
+ const relaySettingsUpdater = useRelaySettingsUpdater();
const updater = useCallback(
async (protocol: RelayProtocol | null, port?: number | null) => {
- const relayUpdate = RelaySettingsBuilder.normal()
- .tunnel.openvpn((openvpn) => {
- if (protocol) {
- openvpn.protocol.exact(protocol);
- } else {
- openvpn.protocol.any();
- }
-
+ try {
+ await relaySettingsUpdater((settings) => {
+ settings.openvpnConstraints.protocol = wrapConstraint(protocol);
if (port) {
- openvpn.port.exact(port);
- } else {
- openvpn.port.any();
+ settings.openvpnConstraints.port = wrapConstraint(port);
}
- })
- .build();
-
- try {
- await updateRelaySettings(relayUpdate);
+ return settings;
+ });
} catch (e) {
const error = e as Error;
log.error('Failed to update relay settings', error.message);
}
},
- [updateRelaySettings],
+ [relaySettingsUpdater],
);
return updater;
diff --git a/gui/src/renderer/components/VpnSettings.tsx b/gui/src/renderer/components/VpnSettings.tsx
index c884db3e5e..0aa90af8c3 100644
--- a/gui/src/renderer/components/VpnSettings.tsx
+++ b/gui/src/renderer/components/VpnSettings.tsx
@@ -3,11 +3,11 @@ import { sprintf } from 'sprintf-js';
import styled from 'styled-components';
import { colors, strings } from '../../config.json';
-import { IDnsOptions, TunnelProtocol } from '../../shared/daemon-rpc-types';
+import { IDnsOptions, TunnelProtocol, wrapConstraint } from '../../shared/daemon-rpc-types';
import { messages } from '../../shared/gettext';
import log from '../../shared/logging';
-import RelaySettingsBuilder from '../../shared/relay-settings-builder';
import { useAppContext } from '../context';
+import { useRelaySettingsUpdater } from '../lib/constraint-updater';
import { useHistory } from '../lib/history';
import { formatHtml } from '../lib/html-formatter';
import { RoutePath } from '../lib/routes';
@@ -663,25 +663,22 @@ function TunnelProtocolSetting() {
const tunnelProtocol = useSelector((state) =>
mapRelaySettingsToProtocol(state.settings.relaySettings),
);
- const { updateRelaySettings } = useAppContext();
+ const relaySettingsUpdater = useRelaySettingsUpdater();
- const setTunnelProtocol = useCallback(async (tunnelProtocol: TunnelProtocol | null) => {
- const relayUpdate = RelaySettingsBuilder.normal()
- .tunnel.tunnelProtocol((config) => {
- if (tunnelProtocol !== null) {
- config.tunnelProtocol.exact(tunnelProtocol);
- } else {
- config.tunnelProtocol.any();
- }
- })
- .build();
- try {
- await updateRelaySettings(relayUpdate);
- } catch (e) {
- const error = e as Error;
- log.error('Failed to update tunnel protocol constraints', error.message);
- }
- }, []);
+ const setTunnelProtocol = useCallback(
+ async (tunnelProtocol: TunnelProtocol | null) => {
+ try {
+ await relaySettingsUpdater((settings) => ({
+ ...settings,
+ tunnelProtocol: wrapConstraint(tunnelProtocol),
+ }));
+ } catch (e) {
+ const error = e as Error;
+ log.error('Failed to update tunnel protocol constraints', error.message);
+ }
+ },
+ [relaySettingsUpdater],
+ );
const tunnelProtocolItems: Array<SelectorItem<TunnelProtocol>> = useMemo(
() => [
diff --git a/gui/src/renderer/components/WireguardSettings.tsx b/gui/src/renderer/components/WireguardSettings.tsx
index e0e73f230e..7cd93b98bd 100644
--- a/gui/src/renderer/components/WireguardSettings.tsx
+++ b/gui/src/renderer/components/WireguardSettings.tsx
@@ -8,12 +8,13 @@ import {
liftConstraint,
LiftedConstraint,
ObfuscationType,
+ wrapConstraint,
} from '../../shared/daemon-rpc-types';
import { messages } from '../../shared/gettext';
import log from '../../shared/logging';
import { removeNonNumericCharacters } from '../../shared/string-helpers';
import { useAppContext } from '../context';
-import { createWireguardRelayUpdater } from '../lib/constraint-updater';
+import { useRelaySettingsUpdater } from '../lib/constraint-updater';
import { useHistory } from '../lib/history';
import { useBoolean } from '../lib/utilityHooks';
import { useSelector } from '../redux/store';
@@ -132,7 +133,7 @@ export default function WireguardSettings() {
function PortSelector() {
const relaySettings = useSelector((state) => state.settings.relaySettings);
- const { updateRelaySettings } = useAppContext();
+ const relaySettingsUpdater = useRelaySettingsUpdater();
const allowedPortRanges = useSelector((state) => state.settings.wireguardEndpointData.portRanges);
const wireguardPortItems = useMemo<Array<SelectorItem<number>>>(
@@ -147,23 +148,17 @@ function PortSelector() {
const setWireguardPort = useCallback(
async (port: number | null) => {
- const relayUpdate = createWireguardRelayUpdater(relaySettings)
- .tunnel.wireguard((wireguard) => {
- if (port !== null) {
- wireguard.port.exact(port);
- } else {
- wireguard.port.any();
- }
- })
- .build();
try {
- await updateRelaySettings(relayUpdate);
+ await relaySettingsUpdater((settings) => {
+ settings.wireguardConstraints.port = wrapConstraint(port);
+ return settings;
+ });
} catch (e) {
const error = e as Error;
log.error('Failed to update relay settings', error.message);
}
},
- [relaySettings],
+ [relaySettingsUpdater],
);
const parseValue = useCallback((port: string) => parseInt(port), []);
@@ -288,7 +283,7 @@ function Udp2tcpPortSetting() {
...obfuscationSettings,
udp2tcpSettings: {
...obfuscationSettings.udp2tcpSettings,
- port: port === 'any' ? 'any' : { only: port },
+ port: wrapConstraint(port),
},
});
},
@@ -324,7 +319,7 @@ function Udp2tcpPortSetting() {
function MultihopSetting() {
const relaySettings = useSelector((state) => state.settings.relaySettings);
- const { updateRelaySettings } = useAppContext();
+ const relaySettingsUpdater = useRelaySettingsUpdater();
const multihop = 'normal' in relaySettings ? relaySettings.normal.wireguard.useMultihop : false;
@@ -332,17 +327,17 @@ function MultihopSetting() {
const setMultihopImpl = useCallback(
async (enabled: boolean) => {
- const relayUpdate = createWireguardRelayUpdater(relaySettings)
- .tunnel.wireguard((wireguard) => wireguard.useMultihop(enabled))
- .build();
try {
- await updateRelaySettings(relayUpdate);
+ await relaySettingsUpdater((settings) => {
+ settings.wireguardConstraints.useMultihop = enabled;
+ return settings;
+ });
} catch (e) {
const error = e as Error;
log.error('Failed to update WireGuard multihop settings', error.message);
}
},
- [relaySettings, updateRelaySettings],
+ [relaySettingsUpdater],
);
const setMultihop = useCallback(
@@ -416,7 +411,7 @@ function MultihopSetting() {
}
function IpVersionSetting() {
- const { updateRelaySettings } = useAppContext();
+ const relaySettingsUpdater = useRelaySettingsUpdater();
const relaySettings = useSelector((state) => state.settings.relaySettings);
const ipVersion = useMemo(() => {
const ipVersion = 'normal' in relaySettings ? relaySettings.normal.wireguard.ipVersion : 'any';
@@ -439,23 +434,17 @@ function IpVersionSetting() {
const setIpVersion = useCallback(
async (ipVersion: IpVersion | null) => {
- const relayUpdate = createWireguardRelayUpdater(relaySettings)
- .tunnel.wireguard((wireguard) => {
- if (ipVersion !== null) {
- wireguard.ipVersion.exact(ipVersion);
- } else {
- wireguard.ipVersion.any();
- }
- })
- .build();
try {
- await updateRelaySettings(relayUpdate);
+ await relaySettingsUpdater((settings) => {
+ settings.wireguardConstraints.ipVersion = wrapConstraint(ipVersion);
+ return settings;
+ });
} catch (e) {
const error = e as Error;
log.error('Failed to update relay settings', error.message);
}
},
- [relaySettings, updateRelaySettings],
+ [relaySettingsUpdater],
);
return (
diff --git a/gui/src/renderer/components/select-location/SelectLocation.tsx b/gui/src/renderer/components/select-location/SelectLocation.tsx
index c812d84835..e09823586f 100644
--- a/gui/src/renderer/components/select-location/SelectLocation.tsx
+++ b/gui/src/renderer/components/select-location/SelectLocation.tsx
@@ -4,7 +4,7 @@ import { sprintf } from 'sprintf-js';
import { colors } from '../../../config.json';
import { Ownership } from '../../../shared/daemon-rpc-types';
import { messages } from '../../../shared/gettext';
-import { useAppContext } from '../../context';
+import { useRelaySettingsUpdater } from '../../lib/constraint-updater';
import { filterSpecialLocations } from '../../lib/filter-locations';
import { useHistory } from '../../lib/history';
import { formatHtml } from '../../lib/html-formatter';
@@ -57,7 +57,7 @@ import { SpacePreAllocationView } from './SpacePreAllocationView';
export default function SelectLocation() {
const history = useHistory();
- const { updateRelaySettings } = useAppContext();
+ const relaySettingsUpdater = useRelaySettingsUpdater();
const {
saveScrollPosition,
resetScrollPositions,
@@ -85,13 +85,17 @@ export default function SelectLocation() {
const onClearProviders = useCallback(async () => {
resetScrollPositions();
- await updateRelaySettings({ normal: { providers: [] } });
- }, [resetScrollPositions]);
+ if (relaySettings) {
+ await relaySettingsUpdater((settings) => ({ ...settings, providers: [] }));
+ }
+ }, [relaySettingsUpdater, resetScrollPositions, relaySettings]);
const onClearOwnership = useCallback(async () => {
resetScrollPositions();
- await updateRelaySettings({ normal: { ownership: Ownership.any } });
- }, [resetScrollPositions]);
+ if (relaySettings) {
+ await relaySettingsUpdater((settings) => ({ ...settings, ownership: Ownership.any }));
+ }
+ }, [relaySettingsUpdater, resetScrollPositions, relaySettings]);
const changeLocationType = useCallback(
(locationType: LocationType) => {
diff --git a/gui/src/renderer/components/select-location/select-location-hooks.ts b/gui/src/renderer/components/select-location/select-location-hooks.ts
index 105e701524..0490799123 100644
--- a/gui/src/renderer/components/select-location/select-location-hooks.ts
+++ b/gui/src/renderer/components/select-location/select-location-hooks.ts
@@ -4,30 +4,33 @@ import BridgeSettingsBuilder from '../../../shared/bridge-settings-builder';
import {
BridgeSettings,
RelayLocation,
- RelaySettingsUpdate,
+ RelaySettings,
+ wrapConstraint,
} from '../../../shared/daemon-rpc-types';
import log from '../../../shared/logging';
-import RelaySettingsBuilder from '../../../shared/relay-settings-builder';
import { useAppContext } from '../../context';
-import { createWireguardRelayUpdater } from '../../lib/constraint-updater';
+import { useRelaySettingsModifier } from '../../lib/constraint-updater';
import { useHistory } from '../../lib/history';
-import { useSelector } from '../../redux/store';
import { LocationType, SpecialBridgeLocationType } from './select-location-types';
import { useSelectLocationContext } from './SelectLocationContainer';
export function useOnSelectExitLocation() {
const onSelectLocation = useOnSelectLocation();
const history = useHistory();
+ const relaySettingsModifier = useRelaySettingsModifier();
const { connectTunnel } = useAppContext();
const onSelectRelay = useCallback(
async (relayLocation: RelayLocation) => {
+ const settings = relaySettingsModifier((settings) => ({
+ ...settings,
+ location: wrapConstraint(relayLocation),
+ }));
history.pop();
- const relayUpdate = RelaySettingsBuilder.normal().location.fromRaw(relayLocation).build();
- await onSelectLocation(relayUpdate);
+ await onSelectLocation({ normal: settings });
await connectTunnel();
},
- [history],
+ [history, relaySettingsModifier],
);
const onSelectSpecial = useCallback((_location: undefined) => {
@@ -40,23 +43,31 @@ export function useOnSelectExitLocation() {
export function useOnSelectEntryLocation() {
const onSelectLocation = useOnSelectLocation();
const { setLocationType } = useSelectLocationContext();
- const baseRelaySettings = useSelector((state) => state.settings.relaySettings);
+ const relaySettingsModifier = useRelaySettingsModifier();
- const onSelectRelay = useCallback(async (entryLocation: RelayLocation) => {
- setLocationType(LocationType.exit);
- const relayUpdate = createWireguardRelayUpdater(baseRelaySettings)
- .tunnel.wireguard((wireguard) => wireguard.entryLocation.exact(entryLocation))
- .build();
- await onSelectLocation(relayUpdate);
- }, []);
+ const onSelectRelay = useCallback(
+ async (entryLocation: RelayLocation) => {
+ setLocationType(LocationType.exit);
+ const settings = relaySettingsModifier((settings) => {
+ settings.wireguardConstraints.entryLocation = wrapConstraint(entryLocation);
+ return settings;
+ });
+ await onSelectLocation({ normal: settings });
+ },
+ [relaySettingsModifier],
+ );
- const onSelectSpecial = useCallback(async (_location: 'any') => {
- setLocationType(LocationType.exit);
- const relayUpdate = createWireguardRelayUpdater(baseRelaySettings)
- .tunnel.wireguard((wireguard) => wireguard.entryLocation.any())
- .build();
- await onSelectLocation(relayUpdate);
- }, []);
+ const onSelectSpecial = useCallback(
+ async (_location: 'any') => {
+ setLocationType(LocationType.exit);
+ const settings = relaySettingsModifier((settings) => {
+ settings.wireguardConstraints.entryLocation = 'any';
+ return settings;
+ });
+ await onSelectLocation({ normal: settings });
+ },
+ [relaySettingsModifier],
+ );
return [onSelectRelay, onSelectSpecial] as const;
}
@@ -64,12 +75,12 @@ export function useOnSelectEntryLocation() {
function useOnSelectLocation() {
const { updateRelaySettings } = useAppContext();
- return useCallback(async (relayUpdate: RelaySettingsUpdate) => {
+ return useCallback(async (relaySettings: RelaySettings) => {
try {
- await updateRelaySettings(relayUpdate);
+ await updateRelaySettings(relaySettings);
} catch (e) {
const error = e as Error;
- log.error(`Failed to select the exit location: ${error.message}`);
+ log.error(`Failed to select the location: ${error.message}`);
}
}, []);
}
diff --git a/gui/src/renderer/lib/constraint-updater.ts b/gui/src/renderer/lib/constraint-updater.ts
index 3ebbcccbc0..4acb351335 100644
--- a/gui/src/renderer/lib/constraint-updater.ts
+++ b/gui/src/renderer/lib/constraint-updater.ts
@@ -1,36 +1,89 @@
-import RelaySettingsBuilder from '../../shared/relay-settings-builder';
-import { RelaySettingsRedux } from '../redux/settings/reducers';
+import { useCallback } from 'react';
-export function createWireguardRelayUpdater(
- relaySettings: RelaySettingsRedux,
-): ReturnType<typeof RelaySettingsBuilder['normal']> {
- if ('normal' in relaySettings) {
- const constraints = relaySettings.normal.wireguard;
+import {
+ IOpenVpnConstraints,
+ IRelaySettingsNormal,
+ IWireguardConstraints,
+ Ownership,
+ wrapConstraint,
+} from '../../shared/daemon-rpc-types';
+import { useAppContext } from '../context';
+import { NormalRelaySettingsRedux } from '../redux/settings/reducers';
+import { useNormalRelaySettings } from './utilityHooks';
- const relayUpdate = RelaySettingsBuilder.normal().tunnel.wireguard((wireguard) => {
- if (constraints.port === 'any') {
- wireguard.port.any();
- } else {
- wireguard.port.exact(constraints.port);
- }
+export function wrapRelaySettingsOrDefault(
+ relaySettings?: NormalRelaySettingsRedux,
+): IRelaySettingsNormal<IOpenVpnConstraints, IWireguardConstraints> {
+ if (relaySettings) {
+ const openvpnPort = wrapConstraint(relaySettings.openvpn.port);
+ const openvpnProtocol = wrapConstraint(relaySettings.openvpn.protocol);
+ const wgPort = wrapConstraint(relaySettings.wireguard.port);
+ const wgIpVersion = wrapConstraint(relaySettings.wireguard.ipVersion);
+ const wgEntryLocation = wrapConstraint(relaySettings.wireguard.entryLocation);
+ const location = wrapConstraint(relaySettings.location);
+ const tunnelProtocol = wrapConstraint(relaySettings.tunnelProtocol);
- if (constraints.ipVersion === 'any') {
- wireguard.ipVersion.any();
- } else {
- wireguard.ipVersion.exact(constraints.ipVersion);
- }
+ return {
+ providers: [...relaySettings.providers],
+ ownership: relaySettings.ownership,
+ tunnelProtocol,
+ openvpnConstraints: {
+ port: openvpnPort,
+ protocol: openvpnProtocol,
+ },
+ wireguardConstraints: {
+ port: wgPort,
+ ipVersion: wgIpVersion,
+ useMultihop: relaySettings.wireguard.useMultihop,
+ entryLocation: wgEntryLocation,
+ },
+ location,
+ };
+ }
+
+ return {
+ location: 'any',
+ tunnelProtocol: 'any',
+ providers: [],
+ ownership: Ownership.any,
+ openvpnConstraints: {
+ port: 'any',
+ protocol: 'any',
+ },
+ wireguardConstraints: {
+ port: 'any',
+ ipVersion: 'any',
+ useMultihop: false,
+ entryLocation: 'any',
+ },
+ };
+}
- wireguard.useMultihop(constraints.useMultihop);
+type UpdateFunction = (
+ settings: IRelaySettingsNormal<IOpenVpnConstraints, IWireguardConstraints>,
+) => IRelaySettingsNormal<IOpenVpnConstraints, IWireguardConstraints>;
- if (constraints.entryLocation === 'any') {
- wireguard.entryLocation.any();
- } else if (constraints.entryLocation !== undefined) {
- wireguard.entryLocation.exact(constraints.entryLocation);
- }
- });
+export function useRelaySettingsModifier() {
+ const relaySettings = useNormalRelaySettings();
- return relayUpdate;
- } else {
- return RelaySettingsBuilder.normal();
- }
+ return useCallback(
+ (fn: UpdateFunction) => {
+ const settings = wrapRelaySettingsOrDefault(relaySettings);
+ return fn(settings);
+ },
+ [relaySettings],
+ );
+}
+
+export function useRelaySettingsUpdater() {
+ const { updateRelaySettings } = useAppContext();
+ const modifyRelaySettings = useRelaySettingsModifier();
+
+ return useCallback(
+ async (fn: UpdateFunction) => {
+ const modifiedSettings = modifyRelaySettings(fn);
+ await updateRelaySettings({ normal: modifiedSettings });
+ },
+ [updateRelaySettings, modifyRelaySettings],
+ );
}