diff options
| author | Emīls Piņķis <emils@mullvad.net> | 2019-05-31 13:10:43 +0100 |
|---|---|---|
| committer | Emīls Piņķis <emils@mullvad.net> | 2019-05-31 13:10:43 +0100 |
| commit | cd959bfea0ad60356aac91df1946fc51808628ac (patch) | |
| tree | 93794ebff6d1449aa7015c74dc4ac5ff51276d05 | |
| parent | 3e9d2fcf040b5f0193285f5b9a7a50f3c032a34f (diff) | |
| parent | 651e8e219210dd0bd7a673967ae26439697324ad (diff) | |
| download | mullvadvpn-cd959bfea0ad60356aac91df1946fc51808628ac.tar.xz mullvadvpn-cd959bfea0ad60356aac91df1946fc51808628ac.zip | |
Merge branch 'add-shadowsocks-toggle'
| -rw-r--r-- | CHANGELOG.md | 1 | ||||
| -rw-r--r-- | gui/src/main/daemon-rpc.ts | 5 | ||||
| -rw-r--r-- | gui/src/main/index.ts | 4 | ||||
| -rw-r--r-- | gui/src/renderer/app.tsx | 7 | ||||
| -rw-r--r-- | gui/src/renderer/components/AdvancedSettings.tsx | 91 | ||||
| -rw-r--r-- | gui/src/renderer/containers/AdvancedSettingsPage.tsx | 11 | ||||
| -rw-r--r-- | gui/src/renderer/redux/settings/actions.ts | 15 | ||||
| -rw-r--r-- | gui/src/renderer/redux/settings/reducers.ts | 10 | ||||
| -rw-r--r-- | gui/src/shared/ipc-event-channel.ts | 6 |
9 files changed, 126 insertions, 24 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 7587953ab4..a72d52c7ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ Line wrap the file at 100 chars. Th - Add missing GUI translations for Czech Republic, USA and UK in the select location view. - Add translations for the current location displayed on the main screen in the GUI. - Allow a subset of NDP (Router solicitation, router advertisement and redirects) in the firewall. +- Allow setting proxy mode from UI. #### Linux - Add standard window decorations to the application window. diff --git a/gui/src/main/daemon-rpc.ts b/gui/src/main/daemon-rpc.ts index 5df6e9013a..bd76896569 100644 --- a/gui/src/main/daemon-rpc.ts +++ b/gui/src/main/daemon-rpc.ts @@ -1,5 +1,6 @@ import { AccountToken, + BridgeState, DaemonEvent, IAccountData, IAppVersionInfo, @@ -417,6 +418,10 @@ export class DaemonRpc { await this.transport.send('set_block_when_disconnected', [blockWhenDisconnected]); } + public async setBridgeState(bridgeState: BridgeState): Promise<void> { + await this.transport.send('set_bridge_state', [bridgeState]); + } + public async setOpenVpnMssfix(mssfix?: number): Promise<void> { await this.transport.send('set_openvpn_mssfix', [mssfix]); } diff --git a/gui/src/main/index.ts b/gui/src/main/index.ts index 25cb537878..c7e8cc0870 100644 --- a/gui/src/main/index.ts +++ b/gui/src/main/index.ts @@ -6,6 +6,7 @@ import * as path from 'path'; import * as uuid from 'uuid'; import { AccountToken, + BridgeState, DaemonEvent, IAppVersionInfo, ILocation, @@ -813,6 +814,9 @@ class ApplicationMain { IpcMainEventChannel.settings.handleBlockWhenDisconnected((blockWhenDisconnected: boolean) => this.daemonRpc.setBlockWhenDisconnected(blockWhenDisconnected), ); + IpcMainEventChannel.settings.handleBridgeState((bridgeState: BridgeState) => + this.daemonRpc.setBridgeState(bridgeState), + ); IpcMainEventChannel.settings.handleOpenVpnMssfix((mssfix?: number) => this.daemonRpc.setOpenVpnMssfix(mssfix), ); diff --git a/gui/src/renderer/app.tsx b/gui/src/renderer/app.tsx index d98c7d23e9..6ac6467b81 100644 --- a/gui/src/renderer/app.tsx +++ b/gui/src/renderer/app.tsx @@ -32,6 +32,7 @@ import AccountExpiry from './lib/account-expiry'; import { AccountToken, + BridgeState, ILocation, IRelayList, ISettings, @@ -305,6 +306,12 @@ export default class AppRenderer { actions.settings.updateEnableIpv6(enableIpv6); } + public async setBridgeState(bridgeState: BridgeState) { + const actions = this.reduxActions; + await IpcRendererEventChannel.settings.setBridgeState(bridgeState); + actions.settings.updateBridgeState(bridgeState); + } + public async setBlockWhenDisconnected(blockWhenDisconnected: boolean) { const actions = this.reduxActions; await IpcRendererEventChannel.settings.setBlockWhenDisconnected(blockWhenDisconnected); diff --git a/gui/src/renderer/components/AdvancedSettings.tsx b/gui/src/renderer/components/AdvancedSettings.tsx index a1a844f8e6..5a4b7b0d5a 100644 --- a/gui/src/renderer/components/AdvancedSettings.tsx +++ b/gui/src/renderer/components/AdvancedSettings.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { Component, View } from 'reactxp'; import { sprintf } from 'sprintf-js'; import { colors } from '../../config.json'; -import { RelayProtocol } from '../../shared/daemon-rpc-types'; +import { BridgeState, RelayProtocol } from '../../shared/daemon-rpc-types'; import { messages } from '../../shared/gettext'; import styles from './AdvancedSettingsStyles'; import * as Cell from './Cell'; @@ -18,19 +18,12 @@ import SettingsHeader, { HeaderTitle } from './SettingsHeader'; const MIN_MSSFIX_VALUE = 1000; const MAX_MSSFIX_VALUE = 1450; -const PROTOCOLS: RelayProtocol[] = ['udp', 'tcp']; const UDP_PORTS = [1194, 1195, 1196, 1197, 1300, 1301, 1302]; const TCP_PORTS = [80, 443]; -const PORT_ITEMS: { [key in RelayProtocol]: Array<ISelectorItem<number>> } = { - udp: UDP_PORTS.map(mapPortToSelectorItem), - tcp: TCP_PORTS.map(mapPortToSelectorItem), -}; +type OptionalPort = number | undefined; -const PROTOCOL_ITEMS: Array<ISelectorItem<RelayProtocol>> = PROTOCOLS.map((value) => ({ - label: value.toUpperCase(), - value, -})); +type OptionalRelayProtocol = RelayProtocol | undefined; function mapPortToSelectorItem(value: number): ISelectorItem<number> { return { label: value.toString(), value }; @@ -42,6 +35,8 @@ interface IProps { protocol?: RelayProtocol; mssfix?: number; port?: number; + bridgeState: BridgeState; + setBridgeState: (value: BridgeState) => void; setEnableIpv6: (value: boolean) => void; setBlockWhenDisconnected: (value: boolean) => void; setOpenVpnMssfix: (value: number | undefined) => void; @@ -56,9 +51,53 @@ interface IState { } export default class AdvancedSettings extends Component<IProps, IState> { + private portItems: { [key in RelayProtocol]: Array<ISelectorItem<OptionalPort>> }; + private protocolItems: Array<ISelectorItem<OptionalRelayProtocol>>; + private bridgeStateItems: Array<ISelectorItem<BridgeState>>; + constructor(props: IProps) { super(props); + const automaticPort: ISelectorItem<OptionalPort> = { + label: messages.pgettext('advanced-settings-view', 'Automatic'), + value: undefined, + }; + + this.portItems = { + udp: [automaticPort].concat(UDP_PORTS.map(mapPortToSelectorItem)), + tcp: [automaticPort].concat(TCP_PORTS.map(mapPortToSelectorItem)), + }; + + this.protocolItems = [ + { + label: messages.pgettext('advanced-settings-view', 'Automatic'), + value: undefined, + }, + { + label: messages.pgettext('advanced-settings-view', 'TCP'), + value: 'tcp', + }, + { + label: messages.pgettext('advanced-settings-view', 'UDP'), + value: 'udp', + }, + ]; + + this.bridgeStateItems = [ + { + label: messages.pgettext('advanced-settings-view', 'Automatic'), + value: 'auto', + }, + { + label: messages.pgettext('advanced-settings-view', 'On'), + value: 'on', + }, + { + label: messages.pgettext('advanced-settings-view', 'Off'), + value: 'off', + }, + ]; + this.state = { persistedMssfix: props.mssfix, editedMssfix: props.mssfix, @@ -138,7 +177,7 @@ export default class AdvancedSettings extends Component<IProps, IState> { <View style={styles.advanced_settings__content}> <Selector title={messages.pgettext('advanced-settings-view', 'Network protocols')} - values={PROTOCOL_ITEMS} + values={this.protocolItems} value={this.props.protocol} onSelect={this.onSelectProtocol} /> @@ -154,7 +193,7 @@ export default class AdvancedSettings extends Component<IProps, IState> { portType: this.props.protocol.toUpperCase(), }, )} - values={PORT_ITEMS[this.props.protocol]} + values={this.portItems[this.props.protocol]} value={this.props.port} onSelect={this.onSelectPort} /> @@ -163,6 +202,16 @@ export default class AdvancedSettings extends Component<IProps, IState> { )} </View> + <Selector + title={ + // TRANSLATORS: The title for the shadowsocks bridge selector section. + messages.pgettext('advanced-settings-view', 'Shadowsocks bridge') + } + values={this.bridgeStateItems} + value={this.props.bridgeState} + onSelect={this.onSelectBridgeState} + /> + <Cell.Container> <Cell.Label>{messages.pgettext('advanced-settings-view', 'Mssfix')}</Cell.Label> <Cell.InputFrame style={styles.advanced_settings__mssfix_frame}> @@ -213,6 +262,10 @@ export default class AdvancedSettings extends Component<IProps, IState> { this.props.setRelayProtocolAndPort(this.props.protocol, port); }; + private onSelectBridgeState = (bridgeState: BridgeState) => { + this.props.setBridgeState(bridgeState); + }; + private onMssfixChange = (mssfixString: string) => { const mssfix = mssfixString.replace(/[^0-9]/g, ''); @@ -251,8 +304,8 @@ interface ISelectorItem<T> { interface ISelectorProps<T> { title: string; values: Array<ISelectorItem<T>>; - value?: T; - onSelect: (value?: T) => void; + value: T; + onSelect: (value: T) => void; } class Selector<T> extends Component<ISelectorProps<T>> { @@ -260,12 +313,6 @@ class Selector<T> extends Component<ISelectorProps<T>> { return ( <Cell.Section style={styles.advanced_settings__selector_section}> <Cell.SectionTitle>{this.props.title}</Cell.SectionTitle> - <SelectorCell - key={'auto'} - selected={this.props.value === undefined} - onSelect={this.props.onSelect}> - {messages.pgettext('advanced-settings-view', 'Automatic')} - </SelectorCell> {this.props.values.map((item, i) => ( <SelectorCell key={i} @@ -281,9 +328,9 @@ class Selector<T> extends Component<ISelectorProps<T>> { } interface ISelectorCell<T> { - value?: T; + value: T; selected: boolean; - onSelect: (value?: T) => void; + onSelect: (value: T) => void; children?: React.ReactText; } diff --git a/gui/src/renderer/containers/AdvancedSettingsPage.tsx b/gui/src/renderer/containers/AdvancedSettingsPage.tsx index 5fbdd57b25..a8784a62e2 100644 --- a/gui/src/renderer/containers/AdvancedSettingsPage.tsx +++ b/gui/src/renderer/containers/AdvancedSettingsPage.tsx @@ -2,7 +2,7 @@ import { goBack } from 'connected-react-router'; import log from 'electron-log'; import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; -import { RelayProtocol } from '../../shared/daemon-rpc-types'; +import { BridgeState, RelayProtocol } from '../../shared/daemon-rpc-types'; import AdvancedSettings from '../components/AdvancedSettings'; import RelaySettingsBuilder from '../lib/relay-settings-builder'; @@ -17,6 +17,7 @@ const mapStateToProps = (state: IReduxState) => { enableIpv6: state.settings.enableIpv6, blockWhenDisconnected: state.settings.blockWhenDisconnected, mssfix: state.settings.openVpn.mssfix, + bridgeState: state.settings.bridgeState, ...protocolAndPort, }; }; @@ -82,6 +83,14 @@ const mapDispatchToProps = (dispatch: ReduxDispatch, props: ISharedRouteProps) = } }, + setBridgeState: async (bridgeState: BridgeState) => { + try { + await props.app.setBridgeState(bridgeState); + } catch (e) { + log.error(`Failed to update bridge state: ${e.message}`); + } + }, + setOpenVpnMssfix: async (mssfix?: number) => { try { await props.app.setOpenVpnMssfix(mssfix); diff --git a/gui/src/renderer/redux/settings/actions.ts b/gui/src/renderer/redux/settings/actions.ts index 4587a1c513..742923276d 100644 --- a/gui/src/renderer/redux/settings/actions.ts +++ b/gui/src/renderer/redux/settings/actions.ts @@ -1,3 +1,4 @@ +import { BridgeState } from '../../../shared/daemon-rpc-types'; import { IGuiSettingsState } from '../../../shared/gui-settings-state'; import { IRelayLocationRedux, RelaySettingsRedux } from './reducers'; @@ -31,6 +32,11 @@ export interface IUpdateBlockWhenDisconnectedAction { blockWhenDisconnected: boolean; } +export interface IUpdateBridgeStateAction { + type: 'UPDATE_BRIDGE_STATE'; + bridgeState: BridgeState; +} + export interface IUpdateOpenVpnMssfixAction { type: 'UPDATE_OPENVPN_MSSFIX'; mssfix?: number; @@ -48,6 +54,7 @@ export type SettingsAction = | IUpdateAllowLanAction | IUpdateEnableIpv6Action | IUpdateBlockWhenDisconnectedAction + | IUpdateBridgeStateAction | IUpdateOpenVpnMssfixAction | IUpdateAutoStartAction; @@ -95,6 +102,13 @@ function updateBlockWhenDisconnected( }; } +function updateBridgeState(bridgeState: BridgeState): IUpdateBridgeStateAction { + return { + type: 'UPDATE_BRIDGE_STATE', + bridgeState, + }; +} + function updateOpenVpnMssfix(mssfix?: number): IUpdateOpenVpnMssfixAction { return { type: 'UPDATE_OPENVPN_MSSFIX', @@ -116,6 +130,7 @@ export default { updateAllowLan, updateEnableIpv6, updateBlockWhenDisconnected, + updateBridgeState, updateOpenVpnMssfix, updateAutoStart, }; diff --git a/gui/src/renderer/redux/settings/reducers.ts b/gui/src/renderer/redux/settings/reducers.ts index ca02ab0db2..7933fd3384 100644 --- a/gui/src/renderer/redux/settings/reducers.ts +++ b/gui/src/renderer/redux/settings/reducers.ts @@ -1,4 +1,4 @@ -import { RelayLocation, RelayProtocol } from '../../../shared/daemon-rpc-types'; +import { BridgeState, RelayLocation, RelayProtocol } from '../../../shared/daemon-rpc-types'; import { IGuiSettingsState } from '../../../shared/gui-settings-state'; import { ReduxAction } from '../store'; @@ -48,6 +48,7 @@ export interface ISettingsReduxState { relayLocations: IRelayLocationRedux[]; allowLan: boolean; enableIpv6: boolean; + bridgeState: BridgeState; blockWhenDisconnected: boolean; openVpn: { mssfix?: number; @@ -71,6 +72,7 @@ const initialState: ISettingsReduxState = { relayLocations: [], allowLan: false, enableIpv6: true, + bridgeState: 'auto', blockWhenDisconnected: false, openVpn: {}, }; @@ -131,6 +133,12 @@ export default function( autoStart: action.autoStart, }; + case 'UPDATE_BRIDGE_STATE': + return { + ...state, + bridgeState: action.bridgeState, + }; + default: return state; } diff --git a/gui/src/shared/ipc-event-channel.ts b/gui/src/shared/ipc-event-channel.ts index d9f9e4c3c3..11ca42597c 100644 --- a/gui/src/shared/ipc-event-channel.ts +++ b/gui/src/shared/ipc-event-channel.ts @@ -7,6 +7,7 @@ import { IGuiSettingsState } from './gui-settings-state'; import { IAppUpgradeInfo, ICurrentAppVersionInfo } from '../main/index'; import { AccountToken, + BridgeState, IAccountData, ILocation, IRelayList, @@ -55,6 +56,7 @@ interface ISettingsMethods extends IReceiver<ISettings> { setAllowLan(allowLan: boolean): Promise<void>; setEnableIpv6(enableIpv6: boolean): Promise<void>; setBlockWhenDisconnected(block: boolean): Promise<void>; + setBridgeState(state: BridgeState): Promise<void>; setOpenVpnMssfix(mssfix?: number): Promise<void>; updateRelaySettings(update: RelaySettingsUpdate): Promise<void>; } @@ -63,6 +65,7 @@ interface ISettingsHandlers extends ISender<ISettings> { handleAllowLan(fn: (allowLan: boolean) => Promise<void>): void; handleEnableIpv6(fn: (enableIpv6: boolean) => Promise<void>): void; handleBlockWhenDisconnected(fn: (block: boolean) => Promise<void>): void; + handleBridgeState(fn: (state: BridgeState) => Promise<void>): void; handleOpenVpnMssfix(fn: (mssfix?: number) => Promise<void>): void; handleUpdateRelaySettings(fn: (update: RelaySettingsUpdate) => Promise<void>): void; } @@ -120,6 +123,7 @@ const SETTINGS_CHANGED = 'settings-changed'; const SET_ALLOW_LAN = 'set-allow-lan'; const SET_ENABLE_IPV6 = 'set-enable-ipv6'; const SET_BLOCK_WHEN_DISCONNECTED = 'set-block-when-disconnected'; +const SET_BRIDGE_STATE = 'set-bridge-state'; const SET_OPENVPN_MSSFIX = 'set-openvpn-mssfix'; const UPDATE_RELAY_SETTINGS = 'update-relay-settings'; @@ -177,6 +181,7 @@ export class IpcRendererEventChannel { setAllowLan: requestSender(SET_ALLOW_LAN), setEnableIpv6: requestSender(SET_ENABLE_IPV6), setBlockWhenDisconnected: requestSender(SET_BLOCK_WHEN_DISCONNECTED), + setBridgeState: requestSender(SET_BRIDGE_STATE), setOpenVpnMssfix: requestSender(SET_OPENVPN_MSSFIX), updateRelaySettings: requestSender(UPDATE_RELAY_SETTINGS), }; @@ -253,6 +258,7 @@ export class IpcMainEventChannel { handleAllowLan: requestHandler(SET_ALLOW_LAN), handleEnableIpv6: requestHandler(SET_ENABLE_IPV6), handleBlockWhenDisconnected: requestHandler(SET_BLOCK_WHEN_DISCONNECTED), + handleBridgeState: requestHandler(SET_BRIDGE_STATE), handleOpenVpnMssfix: requestHandler(SET_OPENVPN_MSSFIX), handleUpdateRelaySettings: requestHandler(UPDATE_RELAY_SETTINGS), }; |
