diff options
| author | Oskar Nyberg <oskar@mullvad.net> | 2022-01-19 14:48:23 +0100 |
|---|---|---|
| committer | Oskar Nyberg <oskar@mullvad.net> | 2022-01-24 09:52:41 +0100 |
| commit | 6e2e91137ca688717cd2efab6f55c92037da0887 (patch) | |
| tree | 31e97ea0d7f1f7c80a9a27fadc0c06f4e0c77eb4 /gui/src | |
| parent | ecf45a3a01084771c7c5fe5d0a8f5b1f80f8f7bb (diff) | |
| download | mullvadvpn-6e2e91137ca688717cd2efab6f55c92037da0887.tar.xz mullvadvpn-6e2e91137ca688717cd2efab6f55c92037da0887.zip | |
Add requirements for UDP and bridge mode
Diffstat (limited to 'gui/src')
| -rw-r--r-- | gui/src/renderer/components/OpenVPNSettings.tsx | 134 | ||||
| -rw-r--r-- | gui/src/renderer/components/cell/Selector.tsx | 12 | ||||
| -rw-r--r-- | gui/src/renderer/containers/OpenVPNSettingsPage.tsx | 11 |
3 files changed, 105 insertions, 52 deletions
diff --git a/gui/src/renderer/components/OpenVPNSettings.tsx b/gui/src/renderer/components/OpenVPNSettings.tsx index 1696f45052..b029038d06 100644 --- a/gui/src/renderer/components/OpenVPNSettings.tsx +++ b/gui/src/renderer/components/OpenVPNSettings.tsx @@ -29,6 +29,12 @@ type OptionalPort = number | undefined; type OptionalRelayProtocol = RelayProtocol | undefined; +export enum BridgeModeAvailability { + available, + blockedDueToTunnelProtocol, + blockedDueToTransportProtocol, +} + function mapPortToSelectorItem(value: number): ISelectorItem<number> { return { label: value.toString(), value }; } @@ -45,12 +51,8 @@ export const StyledInputFrame = styled(Cell.InputFrame)({ flex: 0, }); -export const StyledSelectorForFooter = (styled(Selector)({ - marginBottom: 0, -}) as unknown) as new <T>() => Selector<T>; - interface IProps { - tunnelProtocolIsOpenVpn: boolean; + bridgeModeAvailablity: BridgeModeAvailability; openvpn: { protocol?: RelayProtocol; port?: number; @@ -71,7 +73,6 @@ export default class OpenVpnSettings extends React.Component<IProps, IState> { public state = { showBridgeStateConfirmationDialog: false }; private portItems: { [key in RelayProtocol]: Array<ISelectorItem<OptionalPort>> }; - private protocolItems: Array<ISelectorItem<OptionalRelayProtocol>>; constructor(props: IProps) { super(props); @@ -85,21 +86,6 @@ export default class OpenVpnSettings extends React.Component<IProps, IState> { udp: [automaticPort].concat(UDP_PORTS.map(mapPortToSelectorItem)), tcp: [automaticPort].concat(TCP_PORTS.map(mapPortToSelectorItem)), }; - - this.protocolItems = [ - { - label: messages.gettext('Automatic'), - value: undefined, - }, - { - label: messages.gettext('TCP'), - value: 'tcp', - }, - { - label: messages.gettext('UDP'), - value: 'udp', - }, - ]; } public render() { @@ -132,15 +118,36 @@ export default class OpenVpnSettings extends React.Component<IProps, IState> { </HeaderTitle> </SettingsHeader> - <AriaInputGroup> - <StyledSelectorContainer> + <StyledSelectorContainer> + <AriaInputGroup> <Selector title={messages.pgettext('openvpn-settings-view', 'Transport protocol')} - values={this.protocolItems} + values={this.protocolItems(this.props.bridgeState !== 'on')} value={this.props.openvpn.protocol} onSelect={this.onSelectOpenvpnProtocol} + hasFooter={this.props.bridgeState === 'on'} /> + {this.props.bridgeState === 'on' && ( + <Cell.Footer> + <AriaDescription> + <Cell.FooterText> + {formatMarkdown( + // TRANSLATORS: This is used to instruct users how to make UDP mode + // TRANSLATORS: available. + messages.pgettext( + 'openvpn-settings-view', + 'To activate UDP, change **Bridge mode** to **Automatic** or **Off**.', + ), + )} + </Cell.FooterText> + </AriaDescription> + </Cell.Footer> + )} + </AriaInputGroup> + </StyledSelectorContainer> + <StyledSelectorContainer> + <AriaInputGroup> {this.props.openvpn.protocol ? ( <Selector title={sprintf( @@ -157,41 +164,27 @@ export default class OpenVpnSettings extends React.Component<IProps, IState> { onSelect={this.onSelectOpenVpnPort} /> ) : undefined} - </StyledSelectorContainer> - </AriaInputGroup> + </AriaInputGroup> + </StyledSelectorContainer> <AriaInputGroup> <StyledSelectorContainer> - <StyledSelectorForFooter + <Selector title={ // TRANSLATORS: The title for the shadowsocks bridge selector section. messages.pgettext('openvpn-settings-view', 'Bridge mode') } - values={this.bridgeStateItems(this.props.tunnelProtocolIsOpenVpn)} + values={this.bridgeStateItems( + this.props.bridgeModeAvailablity === BridgeModeAvailability.available, + )} value={this.props.bridgeState} onSelect={this.onSelectBridgeState} + hasFooter /> </StyledSelectorContainer> <Cell.Footer> <AriaDescription> - <Cell.FooterText> - {this.props.tunnelProtocolIsOpenVpn - ? // This line is here to prevent prettier from moving up the next line. - // TRANSLATORS: This is used as a description for the bridge mode - // TRANSLATORS: setting. - messages.pgettext( - 'openvpn-settings-view', - 'Helps circumvent censorship, by routing your traffic through a bridge server before reaching an OpenVPN server. Obfuscation is added to make fingerprinting harder.', - ) - : formatMarkdown( - // TRANSLATORS: This is used to instruct users how to make the bridge - // TRANSLATORS: mode setting available. - messages.pgettext( - 'openvpn-settings-view', - 'To activate Bridge mode, go back and change **Tunnel protocol** to **OpenVPN**.', - ), - )} - </Cell.FooterText> + <Cell.FooterText>{this.bridgeModeFooterText()}</Cell.FooterText> </AriaDescription> </Cell.Footer> </AriaInputGroup> @@ -267,6 +260,24 @@ export default class OpenVpnSettings extends React.Component<IProps, IState> { ]; } + private protocolItems(udpAvailable: boolean): Array<ISelectorItem<OptionalRelayProtocol>> { + return [ + { + label: messages.gettext('Automatic'), + value: undefined, + }, + { + label: messages.gettext('TCP'), + value: 'tcp', + }, + { + label: messages.gettext('UDP'), + value: 'udp', + disabled: !udpAvailable, + }, + ]; + } + private onSelectOpenvpnProtocol = (protocol?: RelayProtocol) => { this.props.setOpenVpnRelayProtocolAndPort(protocol); }; @@ -294,6 +305,37 @@ export default class OpenVpnSettings extends React.Component<IProps, IState> { ); } + private bridgeModeFooterText() { + switch (this.props.bridgeModeAvailablity) { + case BridgeModeAvailability.blockedDueToTunnelProtocol: + return formatMarkdown( + // TRANSLATORS: This is used to instruct users how to make the bridge mode setting + // TRANSLATORS: available. + messages.pgettext( + 'openvpn-settings-view', + 'To activate Bridge mode, go back and change **Tunnel protocol** to **OpenVPN**.', + ), + ); + case BridgeModeAvailability.blockedDueToTransportProtocol: + return formatMarkdown( + // TRANSLATORS: This is used to instruct users how to make the bridge mode setting + // TRANSLATORS: available. + messages.pgettext( + 'openvpn-settings-view', + 'To activate Bridge mode, change **Transport protocol** to **Automatic** or **TCP**.', + ), + ); + case BridgeModeAvailability.available: + // This line is here to prevent prettier from moving up the next line. + // TRANSLATORS: This is used as a description for the bridge mode + // TRANSLATORS: setting. + return messages.pgettext( + 'openvpn-settings-view', + 'Helps circumvent censorship, by routing your traffic through a bridge server before reaching an OpenVPN server. Obfuscation is added to make fingerprinting harder.', + ); + } + } + private renderBridgeStateConfirmation = () => { return ( <ModalAlert diff --git a/gui/src/renderer/components/cell/Selector.tsx b/gui/src/renderer/components/cell/Selector.tsx index cd308fa3e4..68507b4591 100644 --- a/gui/src/renderer/components/cell/Selector.tsx +++ b/gui/src/renderer/components/cell/Selector.tsx @@ -17,11 +17,12 @@ interface ISelectorProps<T> { onSelect: (value: T) => void; selectedCellRef?: React.Ref<HTMLButtonElement>; className?: string; + hasFooter?: boolean; } -const Section = styled(Cell.Section)({ - marginBottom: 20, -}); +const Section = styled(Cell.Section)((props: { hasFooter: boolean }) => ({ + marginBottom: props.hasFooter ? 0 : '20px', +})); export default class Selector<T> extends React.Component<ISelectorProps<T>> { public render() { @@ -49,7 +50,10 @@ export default class Selector<T> extends React.Component<ISelectorProps<T>> { return ( <AriaInput> - <Section role="listbox" className={this.props.className}> + <Section + role="listbox" + className={this.props.className} + hasFooter={this.props.hasFooter ?? false}> {title} {items} </Section> diff --git a/gui/src/renderer/containers/OpenVPNSettingsPage.tsx b/gui/src/renderer/containers/OpenVPNSettingsPage.tsx index 9885afe971..e8033a2d70 100644 --- a/gui/src/renderer/containers/OpenVPNSettingsPage.tsx +++ b/gui/src/renderer/containers/OpenVPNSettingsPage.tsx @@ -2,7 +2,7 @@ import { connect } from 'react-redux'; import { BridgeState, RelayProtocol } from '../../shared/daemon-rpc-types'; import log from '../../shared/logging'; import RelaySettingsBuilder from '../../shared/relay-settings-builder'; -import OpenVPNSettings from '../components/OpenVPNSettings'; +import OpenVPNSettings, { BridgeModeAvailability } from '../components/OpenVPNSettings'; import withAppContext, { IAppContext } from '../context'; import { IHistoryProps, withHistory } from '../lib/history'; @@ -12,8 +12,15 @@ import { IReduxState, ReduxDispatch } from '../redux/store'; const mapStateToProps = (state: IReduxState) => { const protocolAndPort = mapRelaySettingsToProtocolAndPort(state.settings.relaySettings); + let bridgeModeAvailablity = BridgeModeAvailability.available; + if (mapRelaySettingsToProtocol(state.settings.relaySettings) !== 'openvpn') { + bridgeModeAvailablity = BridgeModeAvailability.blockedDueToTunnelProtocol; + } else if (protocolAndPort.openvpn.protocol === 'udp') { + bridgeModeAvailablity = BridgeModeAvailability.blockedDueToTransportProtocol; + } + return { - tunnelProtocolIsOpenVpn: mapRelaySettingsToProtocol(state.settings.relaySettings) === 'openvpn', + bridgeModeAvailablity, mssfix: state.settings.openVpn.mssfix, bridgeState: state.settings.bridgeState, ...protocolAndPort, |
