summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md4
-rw-r--r--gui/packages/desktop/src/main/daemon-rpc.js7
-rw-r--r--gui/packages/desktop/src/main/index.js29
-rw-r--r--gui/packages/desktop/src/renderer/app.js7
-rw-r--r--gui/packages/desktop/src/renderer/components/AdvancedSettings.js15
-rw-r--r--gui/packages/desktop/src/renderer/components/Connect.js2
-rw-r--r--gui/packages/desktop/src/renderer/components/NotificationArea.js13
-rw-r--r--gui/packages/desktop/src/renderer/containers/AdvancedSettingsPage.js9
-rw-r--r--gui/packages/desktop/src/renderer/containers/ConnectPage.js1
-rw-r--r--gui/packages/desktop/src/renderer/lib/daemon-rpc-proxy.js4
-rw-r--r--gui/packages/desktop/src/renderer/redux/settings/actions.js16
-rw-r--r--gui/packages/desktop/src/renderer/redux/settings/reducers.js8
12 files changed, 102 insertions, 13 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9406d0055c..97830d19af 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -24,6 +24,10 @@ Line wrap the file at 100 chars. Th
## [Unreleased]
### Added
+- Handle "block when disconnected" extra kill-switch level in the GUI, showing the disconnected
+ state as blocked when appropriate and also having a toggle switch for the setting in the Advanced
+ Settings screen.
+
#### Linux
- Detect if the computer is offline. If so, don't sit in a reconnect loop, instead block and show
an error message.
diff --git a/gui/packages/desktop/src/main/daemon-rpc.js b/gui/packages/desktop/src/main/daemon-rpc.js
index 5064af6ba8..26da6e14af 100644
--- a/gui/packages/desktop/src/main/daemon-rpc.js
+++ b/gui/packages/desktop/src/main/daemon-rpc.js
@@ -383,6 +383,7 @@ export type Settings = {
accountToken: ?AccountToken,
allowLan: boolean,
autoConnect: boolean,
+ blockWhenDisconnected: boolean,
relaySettings: RelaySettings,
tunnelOptions: TunnelOptions,
};
@@ -391,6 +392,7 @@ const SettingsSchema = partialObject({
account_token: maybe(string),
allow_lan: boolean,
auto_connect: boolean,
+ block_when_disconnected: boolean,
relay_settings: RelaySettingsSchema,
tunnel_options: TunnelOptionsSchema,
});
@@ -404,6 +406,7 @@ export interface DaemonRpcProtocol {
updateRelaySettings(RelaySettingsUpdate): Promise<void>;
setAllowLan(boolean): Promise<void>;
setEnableIpv6(boolean): Promise<void>;
+ setBlockWhenDisconnected(boolean): Promise<void>;
setOpenVpnMssfix(?number): Promise<void>;
setAutoConnect(boolean): Promise<void>;
connectTunnel(): Promise<void>;
@@ -507,6 +510,10 @@ export class DaemonRpc implements DaemonRpcProtocol {
await this._transport.send('set_enable_ipv6', [enableIpv6]);
}
+ async setBlockWhenDisconnected(blockWhenDisconnected: boolean): Promise<void> {
+ await this._transport.send('set_block_when_disconnected', [blockWhenDisconnected]);
+ }
+
async setOpenVpnMssfix(mssfix: ?number): Promise<void> {
await this._transport.send('set_openvpn_mssfix', [mssfix]);
}
diff --git a/gui/packages/desktop/src/main/index.js b/gui/packages/desktop/src/main/index.js
index 92803129bd..a8785554fe 100644
--- a/gui/packages/desktop/src/main/index.js
+++ b/gui/packages/desktop/src/main/index.js
@@ -66,6 +66,7 @@ const ApplicationMain = {
accountToken: null,
allowLan: false,
autoConnect: false,
+ blockWhenDisconnected: false,
relaySettings: {
normal: {
location: 'any',
@@ -454,7 +455,7 @@ const ApplicationMain = {
_setTunnelState(newState: TunnelStateTransition) {
this._tunnelState = newState;
- this._updateTrayIcon(newState);
+ this._updateTrayIcon(newState, this._settings.blockWhenDisconnected);
this._updateLocation();
if (!this._shouldSuppressNotifications()) {
@@ -468,6 +469,7 @@ const ApplicationMain = {
_setSettings(newSettings: Settings) {
this._settings = newSettings;
+ this._updateTrayIcon(this._tunnelState, newSettings.blockWhenDisconnected);
if (this._ipcEventChannel) {
this._ipcEventChannel.settings.notify(newSettings);
@@ -648,7 +650,7 @@ const ApplicationMain = {
}
},
- _trayIconType(tunnelState: TunnelStateTransition): TrayIconType {
+ _trayIconType(tunnelState: TunnelStateTransition, blockWhenDisconnected: boolean): TrayIconType {
switch (tunnelState.state) {
case 'connected':
return 'secured';
@@ -668,26 +670,29 @@ const ApplicationMain = {
return 'securing';
case 'nothing':
- return 'unsecured';
+ // handle the same way as disconnected
+ break;
default:
- log.error(`Invalid after disconnect action: ${(tunnelState.details: empty)}`);
+ throw new Error(`Invalid after disconnect state: ${(tunnelState.details: empty)}`);
}
- break;
+ // fallthrough
case 'disconnected':
- return 'unsecured';
+ if (blockWhenDisconnected) {
+ return 'securing';
+ } else {
+ return 'unsecured';
+ }
default:
- log.error(`Invalid tunnel state: ${(tunnelState.state: empty)}`);
+ // unreachable, but can't prove it to flow because of the fallthrough
+ throw new Error(`Invalid tunnel state: ${tunnelState.state}`);
}
-
- // Unreachable, but flow doesn't agree
- return 'unsecured';
},
- _updateTrayIcon(tunnelState: TunnelStateTransition) {
- const type = this._trayIconType(tunnelState);
+ _updateTrayIcon(tunnelState: TunnelStateTransition, blockWhenDisconnected: boolean) {
+ const type = this._trayIconType(tunnelState, blockWhenDisconnected);
if (this._trayIconController) {
this._trayIconController.animateToIcon(type);
diff --git a/gui/packages/desktop/src/renderer/app.js b/gui/packages/desktop/src/renderer/app.js
index 6a806f0e6b..0f281ab42c 100644
--- a/gui/packages/desktop/src/renderer/app.js
+++ b/gui/packages/desktop/src/renderer/app.js
@@ -325,6 +325,12 @@ export default class AppRenderer {
actions.settings.updateEnableIpv6(enableIpv6);
}
+ async setBlockWhenDisconnected(blockWhenDisconnected: boolean) {
+ const actions = this._reduxActions;
+ await this._daemonRpc.setBlockWhenDisconnected(blockWhenDisconnected);
+ actions.settings.updateBlockWhenDisconnected(blockWhenDisconnected);
+ }
+
async setOpenVpnMssfix(mssfix: ?number) {
const actions = this._reduxActions;
actions.settings.updateOpenVpnMssfix(mssfix);
@@ -474,6 +480,7 @@ export default class AppRenderer {
reduxSettings.updateAllowLan(newSettings.allowLan);
reduxSettings.updateAutoConnect(newSettings.autoConnect);
reduxSettings.updateEnableIpv6(newSettings.tunnelOptions.enableIpv6);
+ reduxSettings.updateBlockWhenDisconnected(newSettings.blockWhenDisconnected);
reduxSettings.updateOpenVpnMssfix(newSettings.tunnelOptions.openvpn.mssfix);
this._setRelaySettings(newSettings.relaySettings);
diff --git a/gui/packages/desktop/src/renderer/components/AdvancedSettings.js b/gui/packages/desktop/src/renderer/components/AdvancedSettings.js
index ddfcf5f2ce..a885849cac 100644
--- a/gui/packages/desktop/src/renderer/components/AdvancedSettings.js
+++ b/gui/packages/desktop/src/renderer/components/AdvancedSettings.js
@@ -21,10 +21,12 @@ const MAX_MSSFIX_VALUE = 1450;
type Props = {
enableIpv6: boolean,
+ blockWhenDisconnected: boolean,
protocol: string,
mssfix: ?number,
port: string | number,
setEnableIpv6: (boolean) => void,
+ setBlockWhenDisconnected: (boolean) => void,
setOpenVpnMssfix: (?number) => void,
onUpdate: (protocol: string, port: string | number) => void,
onClose: () => void,
@@ -98,6 +100,19 @@ export class AdvancedSettings extends Component<Props, State> {
</Cell.Container>
<Cell.Footer>Enable IPv6 communication through the tunnel.</Cell.Footer>
+ <Cell.Container>
+ <Cell.Label>Block when disconnected</Cell.Label>
+ <Switch
+ isOn={this.props.blockWhenDisconnected}
+ onChange={this.props.setBlockWhenDisconnected}
+ />
+ </Cell.Container>
+ <Cell.Footer>
+ {
+ "Unless connected, always block all network traffic, even when you've disconnected or quit the app."
+ }
+ </Cell.Footer>
+
<View style={styles.advanced_settings__content}>
<Selector
title={'Network protocols'}
diff --git a/gui/packages/desktop/src/renderer/components/Connect.js b/gui/packages/desktop/src/renderer/components/Connect.js
index ae83f0a1f0..507171e372 100644
--- a/gui/packages/desktop/src/renderer/components/Connect.js
+++ b/gui/packages/desktop/src/renderer/components/Connect.js
@@ -22,6 +22,7 @@ type Props = {
accountExpiry: ?string,
selectedRelayName: string,
connectionInfoOpen: boolean,
+ blockWhenDisconnected: boolean,
onSettings: () => void,
onSelectLocation: () => void,
onConnect: () => void,
@@ -199,6 +200,7 @@ export default class Connect extends Component<Props> {
tunnelState={this.props.connection.status}
version={this.props.version}
openExternalLink={this.props.onExternalLink}
+ blockWhenDisconnected={this.props.blockWhenDisconnected}
/>
</View>
</View>
diff --git a/gui/packages/desktop/src/renderer/components/NotificationArea.js b/gui/packages/desktop/src/renderer/components/NotificationArea.js
index 1625d63431..dac5b916f6 100644
--- a/gui/packages/desktop/src/renderer/components/NotificationArea.js
+++ b/gui/packages/desktop/src/renderer/components/NotificationArea.js
@@ -20,6 +20,7 @@ type Props = {
tunnelState: TunnelStateTransition,
version: VersionReduxState,
openExternalLink: (string) => void,
+ blockWhenDisconnected: boolean,
};
type NotificationAreaPresentation =
@@ -62,7 +63,7 @@ export default class NotificationArea extends Component<Props, State> {
};
static getDerivedStateFromProps(props: Props, state: State) {
- const { version, tunnelState } = props;
+ const { version, tunnelState, blockWhenDisconnected } = props;
switch (tunnelState.state) {
case 'connecting':
@@ -89,6 +90,16 @@ export default class NotificationArea extends Component<Props, State> {
}
// fallthrough
+ case 'disconnected':
+ if (blockWhenDisconnected) {
+ return {
+ visible: true,
+ type: 'blocking',
+ reason: '',
+ };
+ }
+ // fallthrough
+
default:
if (!version.consistent) {
return {
diff --git a/gui/packages/desktop/src/renderer/containers/AdvancedSettingsPage.js b/gui/packages/desktop/src/renderer/containers/AdvancedSettingsPage.js
index f19fcd2f09..5a3cad6ed5 100644
--- a/gui/packages/desktop/src/renderer/containers/AdvancedSettingsPage.js
+++ b/gui/packages/desktop/src/renderer/containers/AdvancedSettingsPage.js
@@ -16,6 +16,7 @@ const mapStateToProps = (state: ReduxState) => {
return {
enableIpv6: state.settings.enableIpv6,
+ blockWhenDisconnected: state.settings.blockWhenDisconnected,
mssfix: state.settings.openVpn.mssfix,
...protocolAndPort,
};
@@ -73,6 +74,14 @@ const mapDispatchToProps = (dispatch: ReduxDispatch, props: SharedRouteProps) =>
}
},
+ setBlockWhenDisconnected: async (blockWhenDisconnected) => {
+ try {
+ await props.app.setBlockWhenDisconnected(blockWhenDisconnected);
+ } catch (e) {
+ log.error('Failed to update block when disconnected', e.message);
+ }
+ },
+
setOpenVpnMssfix: async (mssfix) => {
try {
await props.app.setOpenVpnMssfix(mssfix);
diff --git a/gui/packages/desktop/src/renderer/containers/ConnectPage.js b/gui/packages/desktop/src/renderer/containers/ConnectPage.js
index fbd7b8aa6b..77b8109b4f 100644
--- a/gui/packages/desktop/src/renderer/containers/ConnectPage.js
+++ b/gui/packages/desktop/src/renderer/containers/ConnectPage.js
@@ -63,6 +63,7 @@ const mapStateToProps = (state: ReduxState) => {
connection: state.connection,
version: state.version,
connectionInfoOpen: state.userInterface.connectionInfoOpen,
+ blockWhenDisconnected: state.settings.blockWhenDisconnected,
};
};
diff --git a/gui/packages/desktop/src/renderer/lib/daemon-rpc-proxy.js b/gui/packages/desktop/src/renderer/lib/daemon-rpc-proxy.js
index 5b928c8989..8b2e03c3dc 100644
--- a/gui/packages/desktop/src/renderer/lib/daemon-rpc-proxy.js
+++ b/gui/packages/desktop/src/renderer/lib/daemon-rpc-proxy.js
@@ -122,6 +122,10 @@ export default class DaemonRpcProxy implements DaemonRpcProtocol {
return this._sendMessage('setEnableIpv6', enableIpv6);
}
+ setBlockWhenDisconnected(blockWhenDisconnected: boolean): Promise<void> {
+ return this._sendMessage('setBlockWhenDisconnected', blockWhenDisconnected);
+ }
+
setOpenVpnMssfix(mssfix: ?number): Promise<void> {
return this._sendMessage('setOpenVpnMssfix', mssfix);
}
diff --git a/gui/packages/desktop/src/renderer/redux/settings/actions.js b/gui/packages/desktop/src/renderer/redux/settings/actions.js
index edb9f8e756..8a7de02e90 100644
--- a/gui/packages/desktop/src/renderer/redux/settings/actions.js
+++ b/gui/packages/desktop/src/renderer/redux/settings/actions.js
@@ -27,6 +27,11 @@ export type UpdateEnableIpv6Action = {
enableIpv6: boolean,
};
+export type UpdateBlockWhenDisconnectedAction = {
+ type: 'UPDATE_BLOCK_WHEN_DISCONNECTED',
+ blockWhenDisconnected: boolean,
+};
+
export type UpdateOpenVpnMssfixAction = {
type: 'UPDATE_OPENVPN_MSSFIX',
mssfix: ?number,
@@ -38,6 +43,7 @@ export type SettingsAction =
| UpdateAutoConnectAction
| UpdateAllowLanAction
| UpdateEnableIpv6Action
+ | UpdateBlockWhenDisconnectedAction
| UpdateOpenVpnMssfixAction;
function updateRelay(relay: RelaySettingsRedux): UpdateRelayAction {
@@ -77,6 +83,15 @@ function updateEnableIpv6(enableIpv6: boolean): UpdateEnableIpv6Action {
};
}
+function updateBlockWhenDisconnected(
+ blockWhenDisconnected: boolean,
+): UpdateBlockWhenDisconnectedAction {
+ return {
+ type: 'UPDATE_BLOCK_WHEN_DISCONNECTED',
+ blockWhenDisconnected,
+ };
+}
+
function updateOpenVpnMssfix(mssfix: ?number): UpdateOpenVpnMssfixAction {
return {
type: 'UPDATE_OPENVPN_MSSFIX',
@@ -90,5 +105,6 @@ export default {
updateAutoConnect,
updateAllowLan,
updateEnableIpv6,
+ updateBlockWhenDisconnected,
updateOpenVpnMssfix,
};
diff --git a/gui/packages/desktop/src/renderer/redux/settings/reducers.js b/gui/packages/desktop/src/renderer/redux/settings/reducers.js
index eba3341e7a..e94cba5132 100644
--- a/gui/packages/desktop/src/renderer/redux/settings/reducers.js
+++ b/gui/packages/desktop/src/renderer/redux/settings/reducers.js
@@ -49,6 +49,7 @@ export type SettingsReduxState = {
autoConnect: boolean,
allowLan: boolean,
enableIpv6: boolean,
+ blockWhenDisconnected: boolean,
openVpn: {
mssfix: ?number,
},
@@ -66,6 +67,7 @@ const initialState: SettingsReduxState = {
autoConnect: false,
allowLan: false,
enableIpv6: true,
+ blockWhenDisconnected: false,
openVpn: {
mssfix: null,
},
@@ -106,6 +108,12 @@ export default function(
enableIpv6: action.enableIpv6,
};
+ case 'UPDATE_BLOCK_WHEN_DISCONNECTED':
+ return {
+ ...state,
+ blockWhenDisconnected: action.blockWhenDisconnected,
+ };
+
case 'UPDATE_OPENVPN_MSSFIX':
return {
...state,