diff options
| author | Markus Pettersson <markus.pettersson@mullvad.net> | 2024-01-31 13:11:59 +0100 |
|---|---|---|
| committer | Markus Pettersson <markus.pettersson@mullvad.net> | 2024-01-31 13:11:59 +0100 |
| commit | 0d9abfd26b0d0e2151eaebaae1bd01f2f439466b (patch) | |
| tree | 6f7c6c6fd29bcf69cd5906a56a14c3cdeeab3d45 /gui | |
| parent | 9b9da3ebbd90d52cec84c17edb4d99a472fd9a61 (diff) | |
| parent | 87cb3b634dd7b9a5e173637dff956f9544aaccd3 (diff) | |
| download | mullvadvpn-0d9abfd26b0d0e2151eaebaae1bd01f2f439466b.tar.xz mullvadvpn-0d9abfd26b0d0e2151eaebaae1bd01f2f439466b.zip | |
Merge branch 'correctly-handle-removal-disabling-of-access-method-des-561'
Diffstat (limited to 'gui')
| -rw-r--r-- | gui/.eslintrc.js | 6 | ||||
| -rw-r--r-- | gui/src/main/daemon-rpc.ts | 23 | ||||
| -rw-r--r-- | gui/src/main/default-settings.ts | 29 | ||||
| -rw-r--r-- | gui/src/renderer/components/ApiAccessMethods.tsx | 62 | ||||
| -rw-r--r-- | gui/src/renderer/components/EditApiAccessMethod.tsx | 5 | ||||
| -rw-r--r-- | gui/src/renderer/components/Switch.tsx | 2 | ||||
| -rw-r--r-- | gui/src/renderer/components/TransitionContainer.tsx | 1 | ||||
| -rw-r--r-- | gui/src/renderer/redux/settings/reducers.ts | 3 | ||||
| -rw-r--r-- | gui/src/shared/daemon-rpc-types.ts | 6 |
9 files changed, 100 insertions, 37 deletions
diff --git a/gui/.eslintrc.js b/gui/.eslintrc.js index 05bdf4cd45..4cf1921910 100644 --- a/gui/.eslintrc.js +++ b/gui/.eslintrc.js @@ -28,6 +28,10 @@ const namingConvention = [ format: ['camelCase'], }, { + selector: 'typeProperty', + format: ['camelCase'], + }, + { selector: 'typeLike', format: ['PascalCase'], }, @@ -103,6 +107,6 @@ module.exports = { '@typescript-eslint/no-use-before-define': 'off', '@typescript-eslint/explicit-module-boundary-types': 'off', '@typescript-eslint/no-non-null-assertion': 'off', - 'react/prop-types': 'off' + 'react/prop-types': 'off', }, }; diff --git a/gui/src/main/daemon-rpc.ts b/gui/src/main/daemon-rpc.ts index 681eb0a454..6290aa7a92 100644 --- a/gui/src/main/daemon-rpc.ts +++ b/gui/src/main/daemon-rpc.ts @@ -1163,7 +1163,7 @@ function convertFromSettings(settings: grpcTypes.Settings): ISettings | undefine const splitTunnel = settingsObject.splitTunnel ?? { enableExclusions: false, appsList: [] }; const obfuscationSettings = convertFromObfuscationSettings(settingsObject.obfuscationSettings); const customLists = convertFromCustomListSettings(settings.getCustomLists()); - const apiAccessMethods = convertFromApiAccessMethodSettings(settings.getApiAccessMethods()); + const apiAccessMethods = convertFromApiAccessMethodSettings(settings.getApiAccessMethods()!); return { ...settings.toObject(), bridgeState, @@ -1893,14 +1893,25 @@ function convertToSocksAuth(authentication: SocksAuth): grpcTypes.SocksAuth { } function convertFromApiAccessMethodSettings( - accessMethods?: grpcTypes.ApiAccessMethodSettings, + accessMethods: grpcTypes.ApiAccessMethodSettings, ): ApiAccessMethodSettings { - return ( + const direct = convertFromApiAccessMethodSetting( + ensureExists(accessMethods.getDirect(), "no 'Direct' access method was found"), + ); + const bridges = convertFromApiAccessMethodSetting( + ensureExists(accessMethods.getMullvadBridges(), "no 'Mullvad Bridges' access method was found"), + ); + const custom = accessMethods - ?.getAccessMethodSettingsList() + .getCustomList() .filter((setting) => setting.hasId() && setting.hasAccessMethod()) - .map(convertFromApiAccessMethodSetting) ?? [] - ); + .map(convertFromApiAccessMethodSetting) ?? []; + + return { + direct, + mullvadBridges: bridges, + custom, + }; } function convertFromApiAccessMethodSetting( diff --git a/gui/src/main/default-settings.ts b/gui/src/main/default-settings.ts index 4510a71896..7f7656a56a 100644 --- a/gui/src/main/default-settings.ts +++ b/gui/src/main/default-settings.ts @@ -1,4 +1,9 @@ -import { ISettings, ObfuscationType, Ownership } from '../shared/daemon-rpc-types'; +import { + ApiAccessMethodSettings, + ISettings, + ObfuscationType, + Ownership, +} from '../shared/daemon-rpc-types'; export function getDefaultSettings(): ISettings { return { @@ -71,6 +76,26 @@ export function getDefaultSettings(): ISettings { }, }, customLists: [], - apiAccessMethods: [], + apiAccessMethods: getDefaultApiAccessMethods(), + }; +} + +export function getDefaultApiAccessMethods(): ApiAccessMethodSettings { + // 'id's are UUIDs generated by the daemon when an access method is created, + // and as such we can't provide a good default value for them. + return { + direct: { + id: '', + name: 'Direct', + enabled: true, + type: 'direct', + }, + mullvadBridges: { + id: '', + name: 'Mullvad Bridges', + enabled: false, + type: 'bridges', + }, + custom: [], }; } diff --git a/gui/src/renderer/components/ApiAccessMethods.tsx b/gui/src/renderer/components/ApiAccessMethods.tsx index c8a6f98b19..0774fcc320 100644 --- a/gui/src/renderer/components/ApiAccessMethods.tsx +++ b/gui/src/renderer/components/ApiAccessMethods.tsx @@ -125,11 +125,20 @@ export default function ApiAccessMethods() { <StyledSettingsContent> <Cell.Group> - {methods.map((method) => ( + <ApiAccessMethod + method={methods.direct} + inUse={methods.direct.id === currentMethod?.id} + /> + <ApiAccessMethod + method={methods.mullvadBridges} + inUse={methods.mullvadBridges.id === currentMethod?.id} + /> + {methods.custom.map((method) => ( <ApiAccessMethod key={method.id} method={method} inUse={method.id === currentMethod?.id} + custom /> ))} </Cell.Group> @@ -150,6 +159,7 @@ export default function ApiAccessMethods() { interface ApiAccessMethodProps { method: AccessMethodSetting; inUse: boolean; + custom?: boolean; } function ApiAccessMethod(props: ApiAccessMethodProps) { @@ -186,8 +196,8 @@ function ApiAccessMethod(props: ApiAccessMethodProps) { } }, [testApiAccessMethod, props.method.id]); - const menuItems = useMemo<Array<ContextMenuItem>>( - () => [ + const menuItems = useMemo<Array<ContextMenuItem>>(() => { + const items: Array<ContextMenuItem> = [ { type: 'item' as const, label: 'Use', @@ -195,28 +205,30 @@ function ApiAccessMethod(props: ApiAccessMethodProps) { onClick: setApiAccessMethod, }, { type: 'item' as const, label: 'Test', onClick: () => testApiAccessMethod(props.method.id) }, - // Edit and Delete shouldn't be available for direct and bridges. - ...(props.method.type === 'direct' || props.method.type === 'bridges' - ? [] - : [ - { type: 'separator' as const }, - { - type: 'item' as const, - label: 'Edit', - onClick: () => - history.push( - generateRoutePath(RoutePath.editApiAccessMethods, { id: props.method.id }), - ), - }, - { - type: 'item' as const, - label: 'Delete', - onClick: showRemoveConfirmation, - }, - ]), - ], - [props.method.id, props.inUse, setApiAccessMethod, testApiAccessMethod, history.push], - ); + ]; + + // Edit and Delete shouldn't be available for direct and bridges. + if (props.custom) { + items.push( + { type: 'separator' as const }, + { + type: 'item' as const, + label: 'Edit', + onClick: () => + history.push( + generateRoutePath(RoutePath.editApiAccessMethods, { id: props.method.id }), + ), + }, + { + type: 'item' as const, + label: 'Delete', + onClick: showRemoveConfirmation, + }, + ); + } + + return items; + }, [props.method.id, props.inUse, setApiAccessMethod, testApiAccessMethod, history.push]); return ( <Cell.Row> diff --git a/gui/src/renderer/components/EditApiAccessMethod.tsx b/gui/src/renderer/components/EditApiAccessMethod.tsx index c56329214b..ecb633ae98 100644 --- a/gui/src/renderer/components/EditApiAccessMethod.tsx +++ b/gui/src/renderer/components/EditApiAccessMethod.tsx @@ -55,7 +55,10 @@ function AccessMethodForm() { // Use id in url to figure out which method is to be edited. undefined means this is a new method. const { id } = useParams<{ id: string | undefined }>(); - const method = methods.find((method) => method.id === id); + // Ugly way of iterating over all access methods, but it works. + const method = [methods.direct, methods.mullvadBridges, ...methods.custom].find( + (method) => method.id === id, + ); const updatedMethod = useRef<NewAccessMethodSetting | undefined>(method); const updateMethod = useCallback( diff --git a/gui/src/renderer/components/Switch.tsx b/gui/src/renderer/components/Switch.tsx index 595bc422a2..f87bf2a52b 100644 --- a/gui/src/renderer/components/Switch.tsx +++ b/gui/src/renderer/components/Switch.tsx @@ -5,7 +5,9 @@ import { colors } from '../../config.json'; interface IProps { id?: string; + // eslint-disable-next-line @typescript-eslint/naming-convention 'aria-labelledby'?: string; + // eslint-disable-next-line @typescript-eslint/naming-convention 'aria-describedby'?: string; isOn: boolean; onChange?: (isOn: boolean) => void; diff --git a/gui/src/renderer/components/TransitionContainer.tsx b/gui/src/renderer/components/TransitionContainer.tsx index 3e7007e3c8..9773c64512 100644 --- a/gui/src/renderer/components/TransitionContainer.tsx +++ b/gui/src/renderer/components/TransitionContainer.tsx @@ -48,6 +48,7 @@ interface StyledTransitionContentProps { export const StyledTransitionContent = styled.div.attrs< StyledTransitionContentProps, + // eslint-disable-next-line @typescript-eslint/naming-convention { 'data-testid': string } >({ 'data-testid': 'transition-content', diff --git a/gui/src/renderer/redux/settings/reducers.ts b/gui/src/renderer/redux/settings/reducers.ts index cdff32e22c..bb971f896a 100644 --- a/gui/src/renderer/redux/settings/reducers.ts +++ b/gui/src/renderer/redux/settings/reducers.ts @@ -1,3 +1,4 @@ +import { getDefaultApiAccessMethods } from '../../../main/default-settings'; import { IWindowsApplication } from '../../../shared/application-types'; import { AccessMethodSetting, @@ -178,7 +179,7 @@ const initialState: ISettingsReduxState = { }, }, customLists: [], - apiAccessMethods: [], + apiAccessMethods: getDefaultApiAccessMethods(), currentApiAccessMethod: undefined, }; diff --git a/gui/src/shared/daemon-rpc-types.ts b/gui/src/shared/daemon-rpc-types.ts index 71f6936804..f048549b7a 100644 --- a/gui/src/shared/daemon-rpc-types.ts +++ b/gui/src/shared/daemon-rpc-types.ts @@ -533,7 +533,11 @@ export type AccessMethodSetting = NewAccessMethodSetting & { id: string; }; -export type ApiAccessMethodSettings = Array<AccessMethodSetting>; +export type ApiAccessMethodSettings = { + direct: AccessMethodSetting; + mullvadBridges: AccessMethodSetting; + custom: Array<AccessMethodSetting>; +}; export function parseSocketAddress(socketAddrStr: string): ISocketAddress { const re = new RegExp(/(.+):(\d+)$/); |
