summaryrefslogtreecommitdiffhomepage
path: root/gui/src/renderer
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2023-10-31 15:24:22 +0100
committerDavid Lönnhager <david.l@mullvad.net>2023-10-31 15:24:22 +0100
commitf073ef8c37ecc4a0cd3d4525ed3bc310cfd2f7e0 (patch)
treef817e43aa5b924bf1b56aeb03e941913fa35e339 /gui/src/renderer
parent9b33f4440fd35d01eea663df5de7d83f65d96918 (diff)
parent3cedaf529da04bbd25fee4829fad4cc0ae2f561f (diff)
downloadmullvadvpn-f073ef8c37ecc4a0cd3d4525ed3bc310cfd2f7e0.tar.xz
mullvadvpn-f073ef8c37ecc4a0cd3d4525ed3bc310cfd2f7e0.zip
Merge branch 'refactor-relay-settings-update' into main
Diffstat (limited to 'gui/src/renderer')
-rw-r--r--gui/src/renderer/app.tsx9
-rw-r--r--gui/src/renderer/components/Filter.tsx12
-rw-r--r--gui/src/renderer/components/OpenVpnSettings.tsx66
-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.ts63
-rw-r--r--gui/src/renderer/lib/constraint-updater.ts111
8 files changed, 203 insertions, 164 deletions
diff --git a/gui/src/renderer/app.tsx b/gui/src/renderer/app.tsx
index bab17524d6..584e80ed4f 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,8 +303,8 @@ export default class AppRenderer {
public connectTunnel = () => IpcRendererEventChannel.tunnel.connect();
public disconnectTunnel = () => IpcRendererEventChannel.tunnel.disconnect();
public reconnectTunnel = () => IpcRendererEventChannel.tunnel.reconnect();
- public updateRelaySettings = (relaySettings: RelaySettingsUpdate) =>
- IpcRendererEventChannel.settings.updateRelaySettings(relaySettings);
+ public setRelaySettings = (relaySettings: RelaySettings) =>
+ IpcRendererEventChannel.settings.setRelaySettings(relaySettings);
public updateBridgeSettings = (bridgeSettings: BridgeSettings) =>
IpcRendererEventChannel.settings.updateBridgeSettings(bridgeSettings);
public setDnsOptions = (dnsOptions: IDnsOptions) =>
@@ -575,7 +574,7 @@ export default class AppRenderer {
this.reduxActions.userInterface.updateLocale(locale);
}
- private setRelaySettings(relaySettings: RelaySettings) {
+ private setReduxRelaySettings(relaySettings: RelaySettings) {
const actions = this.reduxActions;
if ('normal' in relaySettings) {
@@ -790,7 +789,7 @@ export default class AppRenderer {
reduxSettings.updateObfuscationSettings(newSettings.obfuscationSettings);
reduxSettings.updateCustomLists(newSettings.customLists);
- this.setRelaySettings(newSettings.relaySettings);
+ this.setReduxRelaySettings(newSettings.relaySettings);
this.setBridgeSettings(newSettings.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..f3224dc370 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';
@@ -120,6 +125,7 @@ export default function OpenVpnSettings() {
}
function TransportProtocolSelector() {
+ const relaySettingsUpdater = useRelaySettingsUpdater();
const relaySettings = useSelector((state) => state.settings.relaySettings);
const bridgeState = useSelector((state) => state.settings.bridgeState);
@@ -128,7 +134,15 @@ function TransportProtocolSelector() {
return protocol === 'any' ? null : protocol;
}, [relaySettings]);
- const protocolAndPortUpdater = useProtocolAndPortUpdater();
+ const onSelect = useCallback(
+ async (protocol: RelayProtocol | null) => {
+ await relaySettingsUpdater((settings) => {
+ settings.openvpnConstraints.protocol = wrapConstraint(protocol);
+ return settings;
+ });
+ },
+ [relaySettingsUpdater],
+ );
const items: SelectorItem<RelayProtocol>[] = useMemo(
() => [
@@ -152,7 +166,7 @@ function TransportProtocolSelector() {
title={messages.pgettext('openvpn-settings-view', 'Transport protocol')}
items={items}
value={protocol}
- onSelect={protocolAndPortUpdater}
+ onSelect={onSelect}
automaticValue={null}
/>
{bridgeState === 'on' && (
@@ -176,41 +190,8 @@ function TransportProtocolSelector() {
);
}
-function useProtocolAndPortUpdater() {
- const { updateRelaySettings } = useAppContext();
-
- 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();
- }
-
- if (port) {
- openvpn.port.exact(port);
- } else {
- openvpn.port.any();
- }
- })
- .build();
-
- try {
- await updateRelaySettings(relayUpdate);
- } catch (e) {
- const error = e as Error;
- log.error('Failed to update relay settings', error.message);
- }
- },
- [updateRelaySettings],
- );
-
- return updater;
-}
-
function PortSelector() {
+ const relaySettingsUpdater = useRelaySettingsUpdater();
const relaySettings = useSelector((state) => state.settings.relaySettings);
const protocol = useMemo(() => {
@@ -223,13 +204,14 @@ function PortSelector() {
return port === 'any' ? null : port;
}, [relaySettings]);
- const protocolAndPortUpdater = useProtocolAndPortUpdater();
-
const onSelect = useCallback(
async (port: number | null) => {
- await protocolAndPortUpdater(protocol, port);
+ await relaySettingsUpdater((settings) => {
+ settings.openvpnConstraints.port = wrapConstraint(port);
+ return settings;
+ });
},
- [protocolAndPortUpdater, protocol],
+ [relaySettingsUpdater],
);
const portItems = {
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..48d81e594c 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,36 +43,44 @@ 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;
}
function useOnSelectLocation() {
- const { updateRelaySettings } = useAppContext();
+ const { setRelaySettings } = useAppContext();
- return useCallback(async (relayUpdate: RelaySettingsUpdate) => {
+ return useCallback(async (relaySettings: RelaySettings) => {
try {
- await updateRelaySettings(relayUpdate);
+ await setRelaySettings(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..054f063465 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 { setRelaySettings } = useAppContext();
+ const modifyRelaySettings = useRelaySettingsModifier();
+
+ return useCallback(
+ async (fn: UpdateFunction) => {
+ const modifiedSettings = modifyRelaySettings(fn);
+ await setRelaySettings({ normal: modifiedSettings });
+ },
+ [setRelaySettings, modifyRelaySettings],
+ );
}