summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOskar Nyberg <oskar@mullvad.net>2024-02-14 15:07:47 +0100
committerOskar Nyberg <oskar@mullvad.net>2024-02-15 16:04:29 +0100
commit8ab10682e57bf4f42f4a789ee8566af69e5b161f (patch)
treee4f4f0bc9468c7333eb7ea8a5b3248e96502579b
parentd0650acef1db8ed2f2f2e1423f7567efcdc09802 (diff)
downloadmullvadvpn-8ab10682e57bf4f42f4a789ee8566af69e5b161f.tar.xz
mullvadvpn-8ab10682e57bf4f42f4a789ee8566af69e5b161f.zip
Add rpc and ipc calls for IP override along with redux additions
-rw-r--r--gui/src/main/daemon-rpc.ts10
-rw-r--r--gui/src/main/default-settings.ts1
-rw-r--r--gui/src/main/settings.ts16
-rw-r--r--gui/src/renderer/app.tsx4
-rw-r--r--gui/src/renderer/redux/settings-import/actions.ts40
-rw-r--r--gui/src/renderer/redux/settings-import/reducers.ts41
-rw-r--r--gui/src/renderer/redux/settings/actions.ts17
-rw-r--r--gui/src/renderer/redux/settings/reducers.ts9
-rw-r--r--gui/src/renderer/redux/store.ts7
-rw-r--r--gui/src/shared/daemon-rpc-types.ts7
-rw-r--r--gui/src/shared/ipc-schema.ts3
11 files changed, 153 insertions, 2 deletions
diff --git a/gui/src/main/daemon-rpc.ts b/gui/src/main/daemon-rpc.ts
index c01e6165fa..703ad027cc 100644
--- a/gui/src/main/daemon-rpc.ts
+++ b/gui/src/main/daemon-rpc.ts
@@ -697,6 +697,14 @@ export class DaemonRpc {
return result.getValue();
}
+ public async applyJsonSettings(settings: string): Promise<void> {
+ await this.callString(this.client.applyJsonSettings, settings);
+ }
+
+ public async clearAllRelayOverrides(): Promise<void> {
+ await this.callEmpty(this.client.clearAllRelayOverrides);
+ }
+
private subscriptionId(): number {
const current = this.nextSubscriptionId;
this.nextSubscriptionId += 1;
@@ -1167,6 +1175,7 @@ function convertFromSettings(settings: grpcTypes.Settings): ISettings | undefine
const obfuscationSettings = convertFromObfuscationSettings(settingsObject.obfuscationSettings);
const customLists = convertFromCustomListSettings(settings.getCustomLists());
const apiAccessMethods = convertFromApiAccessMethodSettings(settings.getApiAccessMethods()!);
+ const relayOverrides = settingsObject.relayOverridesList;
return {
...settings.toObject(),
bridgeState,
@@ -1177,6 +1186,7 @@ function convertFromSettings(settings: grpcTypes.Settings): ISettings | undefine
obfuscationSettings,
customLists,
apiAccessMethods,
+ relayOverrides,
};
}
diff --git a/gui/src/main/default-settings.ts b/gui/src/main/default-settings.ts
index 7f7656a56a..e942a535b6 100644
--- a/gui/src/main/default-settings.ts
+++ b/gui/src/main/default-settings.ts
@@ -77,6 +77,7 @@ export function getDefaultSettings(): ISettings {
},
customLists: [],
apiAccessMethods: getDefaultApiAccessMethods(),
+ relayOverrides: [],
};
}
diff --git a/gui/src/main/settings.ts b/gui/src/main/settings.ts
index 7c304f3e71..16996eebd9 100644
--- a/gui/src/main/settings.ts
+++ b/gui/src/main/settings.ts
@@ -1,3 +1,5 @@
+import fs from 'fs/promises';
+
import BridgeSettingsBuilder from '../shared/bridge-settings-builder';
import { ISettings } from '../shared/daemon-rpc-types';
import { ICurrentAppVersionInfo } from '../shared/ipc-types';
@@ -90,6 +92,17 @@ export default class Settings implements Readonly<ISettings> {
return this.daemonRpc.testCustomApiAccessMethod(method);
});
+ IpcMainEventChannel.settings.handleClearAllRelayOverrides(() => {
+ return this.daemonRpc.clearAllRelayOverrides();
+ });
+ IpcMainEventChannel.settings.handleImportText((text) => {
+ return this.daemonRpc.applyJsonSettings(text);
+ });
+ IpcMainEventChannel.settings.handleImportFile(async (path) => {
+ const settings = await fs.readFile(path);
+ return this.daemonRpc.applyJsonSettings(settings.toString());
+ });
+
IpcMainEventChannel.guiSettings.handleSetEnableSystemNotifications((flag: boolean) => {
this.guiSettings.enableSystemNotifications = flag;
});
@@ -160,6 +173,9 @@ export default class Settings implements Readonly<ISettings> {
public get apiAccessMethods() {
return this.settingsValue.apiAccessMethods;
}
+ public get relayOverrides() {
+ return this.settingsValue.relayOverrides;
+ }
public get gui() {
return this.guiSettings;
diff --git a/gui/src/renderer/app.tsx b/gui/src/renderer/app.tsx
index d4aef54f31..5e2c574d79 100644
--- a/gui/src/renderer/app.tsx
+++ b/gui/src/renderer/app.tsx
@@ -366,6 +366,9 @@ export default class AppRenderer {
IpcRendererEventChannel.settings.testApiAccessMethodById(id);
public testCustomApiAccessMethod = (method: CustomProxy) =>
IpcRendererEventChannel.settings.testCustomApiAccessMethod(method);
+ public importSettingsFile = (path: string) => IpcRendererEventChannel.settings.importFile(path);
+ public importSettingsText = (text: string) => IpcRendererEventChannel.settings.importText(text);
+ public clearAllRelayOverrides = () => IpcRendererEventChannel.settings.clearAllRelayOverrides();
public getMapData = () => IpcRendererEventChannel.map.getData();
public setAnimateMap = (displayMap: boolean): void =>
IpcRendererEventChannel.guiSettings.setAnimateMap(displayMap);
@@ -813,6 +816,7 @@ export default class AppRenderer {
reduxSettings.updateObfuscationSettings(newSettings.obfuscationSettings);
reduxSettings.updateCustomLists(newSettings.customLists);
reduxSettings.updateApiAccessMethods(newSettings.apiAccessMethods);
+ reduxSettings.updateRelayOverrides(newSettings.relayOverrides);
this.setReduxRelaySettings(newSettings.relaySettings);
this.setBridgeSettings(newSettings.bridgeSettings);
diff --git a/gui/src/renderer/redux/settings-import/actions.ts b/gui/src/renderer/redux/settings-import/actions.ts
new file mode 100644
index 0000000000..f31af1c1c6
--- /dev/null
+++ b/gui/src/renderer/redux/settings-import/actions.ts
@@ -0,0 +1,40 @@
+export interface SaveSettingsImportFormAction {
+ type: 'SAVE_SETTINGS_IMPORT_FORM';
+ value: string;
+ submit: boolean;
+}
+
+export interface ClearSettingsImportFormAction {
+ type: 'CLEAR_SETTINGS_IMPORT_FORM';
+}
+
+export interface UnsetSubmitSettingsImportFormAction {
+ type: 'UNSET_SUBMIT_SETTINGS_IMPORT_FORM';
+}
+
+export type SettingsImportAction =
+ | SaveSettingsImportFormAction
+ | ClearSettingsImportFormAction
+ | UnsetSubmitSettingsImportFormAction;
+
+function saveSettingsImportForm(value: string, submit: boolean): SaveSettingsImportFormAction {
+ return {
+ type: 'SAVE_SETTINGS_IMPORT_FORM',
+ value,
+ submit,
+ };
+}
+
+function clearSettingsImportForm(): ClearSettingsImportFormAction {
+ return {
+ type: 'CLEAR_SETTINGS_IMPORT_FORM',
+ };
+}
+
+function unsetSubmitSettingsImportForm(): UnsetSubmitSettingsImportFormAction {
+ return {
+ type: 'UNSET_SUBMIT_SETTINGS_IMPORT_FORM',
+ };
+}
+
+export default { saveSettingsImportForm, clearSettingsImportForm, unsetSubmitSettingsImportForm };
diff --git a/gui/src/renderer/redux/settings-import/reducers.ts b/gui/src/renderer/redux/settings-import/reducers.ts
new file mode 100644
index 0000000000..76908bc67a
--- /dev/null
+++ b/gui/src/renderer/redux/settings-import/reducers.ts
@@ -0,0 +1,41 @@
+import { ReduxAction } from '../store';
+
+export interface SettingsImportReduxState {
+ value: string;
+ submit: boolean;
+}
+
+const initialState: SettingsImportReduxState = {
+ value: '',
+ submit: false,
+};
+
+export default function (
+ state: SettingsImportReduxState = initialState,
+ action: ReduxAction,
+): SettingsImportReduxState {
+ switch (action.type) {
+ case 'SAVE_SETTINGS_IMPORT_FORM':
+ return {
+ ...state,
+ value: action.value,
+ submit: action.submit,
+ };
+
+ case 'CLEAR_SETTINGS_IMPORT_FORM':
+ return {
+ ...state,
+ value: '',
+ submit: false,
+ };
+
+ case 'UNSET_SUBMIT_SETTINGS_IMPORT_FORM':
+ return {
+ ...state,
+ submit: false,
+ };
+
+ default:
+ return state;
+ }
+}
diff --git a/gui/src/renderer/redux/settings/actions.ts b/gui/src/renderer/redux/settings/actions.ts
index 969f8b0a41..aa4e460e6f 100644
--- a/gui/src/renderer/redux/settings/actions.ts
+++ b/gui/src/renderer/redux/settings/actions.ts
@@ -7,6 +7,7 @@ import {
IDnsOptions,
IWireguardEndpointData,
ObfuscationSettings,
+ RelayOverride,
} from '../../../shared/daemon-rpc-types';
import { IGuiSettingsState } from '../../../shared/gui-settings-state';
import { BridgeSettingsRedux, IRelayLocationCountryRedux, RelaySettingsRedux } from './reducers';
@@ -116,6 +117,11 @@ export interface ISetCurrentApiAccessMethod {
accessMethod: AccessMethodSetting;
}
+export interface ISetRelayOverrides {
+ type: 'SET_RELAY_OVERRIDES';
+ relayOverrides: Array<RelayOverride>;
+}
+
export type SettingsAction =
| IUpdateGuiSettingsAction
| IUpdateRelayAction
@@ -137,7 +143,8 @@ export type SettingsAction =
| ISetObfuscationSettings
| ISetCustomLists
| ISetApiAccessMethods
- | ISetCurrentApiAccessMethod;
+ | ISetCurrentApiAccessMethod
+ | ISetRelayOverrides;
function updateGuiSettings(guiSettings: IGuiSettingsState): IUpdateGuiSettingsAction {
return {
@@ -298,6 +305,13 @@ function updateCurrentApiAccessMethod(setting: AccessMethodSetting): ISetCurrent
};
}
+function updateRelayOverrides(relayOverrides: Array<RelayOverride>): ISetRelayOverrides {
+ return {
+ type: 'SET_RELAY_OVERRIDES',
+ relayOverrides,
+ };
+}
+
export default {
updateGuiSettings,
updateRelay,
@@ -320,4 +334,5 @@ export default {
updateCustomLists,
updateApiAccessMethods,
updateCurrentApiAccessMethod,
+ updateRelayOverrides,
};
diff --git a/gui/src/renderer/redux/settings/reducers.ts b/gui/src/renderer/redux/settings/reducers.ts
index bb971f896a..07502ab280 100644
--- a/gui/src/renderer/redux/settings/reducers.ts
+++ b/gui/src/renderer/redux/settings/reducers.ts
@@ -16,6 +16,7 @@ import {
ProxySettings,
RelayEndpointType,
RelayLocation,
+ RelayOverride,
RelayProtocol,
TunnelProtocol,
} from '../../../shared/daemon-rpc-types';
@@ -112,6 +113,7 @@ export interface ISettingsReduxState {
customLists: CustomLists;
apiAccessMethods: ApiAccessMethodSettings;
currentApiAccessMethod?: AccessMethodSetting;
+ relayOverrides: Array<RelayOverride>;
}
const initialState: ISettingsReduxState = {
@@ -181,6 +183,7 @@ const initialState: ISettingsReduxState = {
customLists: [],
apiAccessMethods: getDefaultApiAccessMethods(),
currentApiAccessMethod: undefined,
+ relayOverrides: [],
};
export default function (
@@ -323,6 +326,12 @@ export default function (
currentApiAccessMethod: action.accessMethod,
};
+ case 'SET_RELAY_OVERRIDES':
+ return {
+ ...state,
+ relayOverrides: action.relayOverrides,
+ };
+
default:
return state;
}
diff --git a/gui/src/renderer/redux/store.ts b/gui/src/renderer/redux/store.ts
index 9634774038..1617acce3d 100644
--- a/gui/src/renderer/redux/store.ts
+++ b/gui/src/renderer/redux/store.ts
@@ -9,6 +9,8 @@ import connectionActions, { ConnectionAction } from './connection/actions';
import connectionReducer, { IConnectionReduxState } from './connection/reducers';
import settingsActions, { SettingsAction } from './settings/actions';
import settingsReducer, { ISettingsReduxState } from './settings/reducers';
+import { SettingsImportAction } from './settings-import/actions';
+import settingsImportReducer, { SettingsImportReduxState } from './settings-import/reducers';
import supportActions, { SupportAction } from './support/actions';
import supportReducer, { ISupportReduxState } from './support/reducers';
import userInterfaceActions, { UserInterfaceAction } from './userinterface/actions';
@@ -23,6 +25,7 @@ export interface IReduxState {
support: ISupportReduxState;
version: IVersionReduxState;
userInterface: IUserInterfaceReduxState;
+ settingsImport: SettingsImportReduxState;
}
export type ReduxAction =
@@ -31,7 +34,8 @@ export type ReduxAction =
| SettingsAction
| SupportAction
| VersionAction
- | UserInterfaceAction;
+ | UserInterfaceAction
+ | SettingsImportAction;
export type ReduxStore = ReturnType<typeof configureStore>;
export type ReduxDispatch = Dispatch<ReduxAction>;
@@ -43,6 +47,7 @@ export default function configureStore() {
support: supportReducer,
version: versionReducer,
userInterface: userInterfaceReducer,
+ settingsImport: settingsImportReducer,
};
const rootReducer = combineReducers(reducers);
diff --git a/gui/src/shared/daemon-rpc-types.ts b/gui/src/shared/daemon-rpc-types.ts
index f048549b7a..e24c124f4c 100644
--- a/gui/src/shared/daemon-rpc-types.ts
+++ b/gui/src/shared/daemon-rpc-types.ts
@@ -435,6 +435,7 @@ export interface ISettings {
obfuscationSettings: ObfuscationSettings;
customLists: CustomLists;
apiAccessMethods: ApiAccessMethodSettings;
+ relayOverrides: Array<RelayOverride>;
}
export type BridgeState = 'auto' | 'on' | 'off';
@@ -539,6 +540,12 @@ export type ApiAccessMethodSettings = {
custom: Array<AccessMethodSetting>;
};
+export interface RelayOverride {
+ hostname: string;
+ ipv4AddrIn?: string;
+ ipv6AddrIn?: string;
+}
+
export function parseSocketAddress(socketAddrStr: string): ISocketAddress {
const re = new RegExp(/(.+):(\d+)$/);
const matches = socketAddrStr.match(re);
diff --git a/gui/src/shared/ipc-schema.ts b/gui/src/shared/ipc-schema.ts
index f0e7777539..b94fe0a701 100644
--- a/gui/src/shared/ipc-schema.ts
+++ b/gui/src/shared/ipc-schema.ts
@@ -169,6 +169,8 @@ export const ipcSchema = {
},
settings: {
'': notifyRenderer<ISettings>(),
+ importFile: invoke<string, void>(),
+ importText: invoke<string, void>(),
apiAccessMethodSettingChange: notifyRenderer<AccessMethodSetting>(),
setAllowLan: invoke<boolean, void>(),
setShowBetaReleases: invoke<boolean, void>(),
@@ -188,6 +190,7 @@ export const ipcSchema = {
setApiAccessMethod: invoke<string, void>(),
testApiAccessMethodById: invoke<string, boolean>(),
testCustomApiAccessMethod: invoke<CustomProxy, boolean>(),
+ clearAllRelayOverrides: invoke<void, void>(),
},
guiSettings: {
'': notifyRenderer<IGuiSettingsState>(),