summaryrefslogtreecommitdiffhomepage
path: root/gui/src
diff options
context:
space:
mode:
Diffstat (limited to 'gui/src')
-rw-r--r--gui/src/main/default-settings.ts6
-rw-r--r--gui/src/main/grpc-type-convertions.ts21
-rw-r--r--gui/src/renderer/components/ApiAccessMethods.tsx23
-rw-r--r--gui/src/renderer/components/ContextMenu.tsx2
-rw-r--r--gui/src/renderer/components/InfoButton.tsx2
-rw-r--r--gui/src/renderer/components/cell/Label.tsx6
-rw-r--r--gui/src/shared/daemon-rpc-types.ts4
7 files changed, 59 insertions, 5 deletions
diff --git a/gui/src/main/default-settings.ts b/gui/src/main/default-settings.ts
index 46355dd439..bebc5b9a4e 100644
--- a/gui/src/main/default-settings.ts
+++ b/gui/src/main/default-settings.ts
@@ -104,6 +104,12 @@ export function getDefaultApiAccessMethods(): ApiAccessMethodSettings {
enabled: false,
type: 'bridges',
},
+ encryptedDnsProxy: {
+ id: '',
+ name: 'Encrypted DNS Proxy',
+ enabled: false,
+ type: 'encrypted-dns-proxy',
+ },
custom: [],
};
}
diff --git a/gui/src/main/grpc-type-convertions.ts b/gui/src/main/grpc-type-convertions.ts
index 6511f10c67..37e5c7fcf5 100644
--- a/gui/src/main/grpc-type-convertions.ts
+++ b/gui/src/main/grpc-type-convertions.ts
@@ -16,6 +16,7 @@ import {
DeviceEvent,
DeviceState,
DirectMethod,
+ EncryptedDnsProxy,
EndpointObfuscationType,
ErrorStateCause,
ErrorStateDetails,
@@ -1097,6 +1098,11 @@ function fillApiAccessMethodSetting<T extends grpcTypes.NewAccessMethodSetting>(
accessMethod.setBridges(bridges);
break;
}
+ case 'encrypted-dns-proxy': {
+ const encryptedDnsProxy = new grpcTypes.AccessMethod.EncryptedDnsProxy();
+ accessMethod.setEncryptedDnsProxy(encryptedDnsProxy);
+ break;
+ }
default:
accessMethod.setCustom(convertToCustomProxy(method));
}
@@ -1160,6 +1166,12 @@ function convertFromApiAccessMethodSettings(
const bridges = convertFromApiAccessMethodSetting(
ensureExists(accessMethods.getMullvadBridges(), "no 'Mullvad Bridges' access method was found"),
) as AccessMethodSetting<BridgesMethod>;
+ const encryptedDnsProxy = convertFromApiAccessMethodSetting(
+ ensureExists(
+ accessMethods.getEncryptedDnsProxy(),
+ "no 'Encrypted DNS proxy' access method was found",
+ ),
+ ) as AccessMethodSetting<EncryptedDnsProxy>;
const custom = accessMethods
.getCustomList()
.filter((setting) => setting.hasId() && setting.hasAccessMethod())
@@ -1170,6 +1182,7 @@ function convertFromApiAccessMethodSettings(
return {
direct,
mullvadBridges: bridges,
+ encryptedDnsProxy,
custom,
};
}
@@ -1177,7 +1190,11 @@ function convertFromApiAccessMethodSettings(
function isCustomProxy(
accessMethod: AccessMethodSetting,
): accessMethod is AccessMethodSetting<CustomProxy> {
- return accessMethod.type !== 'direct' && accessMethod.type !== 'bridges';
+ return (
+ accessMethod.type !== 'direct' &&
+ accessMethod.type !== 'bridges' &&
+ accessMethod.type !== 'encrypted-dns-proxy'
+ );
}
export function convertFromApiAccessMethodSetting(
@@ -1200,6 +1217,8 @@ function convertFromAccessMethod(method: grpcTypes.AccessMethod): AccessMethod {
return { type: 'direct' };
case grpcTypes.AccessMethod.AccessMethodCase.BRIDGES:
return { type: 'bridges' };
+ case grpcTypes.AccessMethod.AccessMethodCase.ENCRYPTED_DNS_PROXY:
+ return { type: 'encrypted-dns-proxy' };
case grpcTypes.AccessMethod.AccessMethodCase.CUSTOM: {
return convertFromCustomProxy(method.getCustom()!);
}
diff --git a/gui/src/renderer/components/ApiAccessMethods.tsx b/gui/src/renderer/components/ApiAccessMethods.tsx
index 57668df787..68b873bd64 100644
--- a/gui/src/renderer/components/ApiAccessMethods.tsx
+++ b/gui/src/renderer/components/ApiAccessMethods.tsx
@@ -36,6 +36,8 @@ import { StyledContent, StyledNavigationScrollbars, StyledSettingsContent } from
import { SmallButton, SmallButtonColor, SmallButtonGroup } from './SmallButton';
const StyledContextMenuButton = styled(Cell.Icon)({
+ alignItems: 'center',
+ justifyContent: 'center',
marginRight: '8px',
});
@@ -50,6 +52,7 @@ const StyledSpinner = styled(ImageView)({
});
const StyledNameLabel = styled(Cell.Label)({
+ display: 'block',
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
@@ -133,6 +136,10 @@ export default function ApiAccessMethods() {
method={methods.mullvadBridges}
inUse={methods.mullvadBridges.id === currentMethod?.id}
/>
+ <ApiAccessMethod
+ method={methods.encryptedDnsProxy}
+ inUse={methods.encryptedDnsProxy.id === currentMethod?.id}
+ />
{methods.custom.map((method) => (
<ApiAccessMethod
key={method.id}
@@ -211,7 +218,7 @@ function ApiAccessMethod(props: ApiAccessMethodProps) {
},
];
- // Edit and Delete shouldn't be available for direct and bridges.
+ // Edit and Delete shouldn't be available for direct, bridges or encrypted DNS proxy.
if (props.custom) {
items.push(
{ type: 'separator' as const },
@@ -290,6 +297,20 @@ function ApiAccessMethod(props: ApiAccessMethodProps) {
]}
/>
)}
+ {props.method.type === 'encrypted-dns-proxy' && (
+ <StyledMethodInfoButton
+ message={[
+ messages.pgettext(
+ 'api-access-methods-view',
+ 'With the “Encrypted DNS proxy” method, the app will communicate with our Mullvad API through a proxy address. It does this by retrieving an address from a DNS over HTTPS (DoH) server and then using that to reach our API servers.',
+ ),
+ messages.pgettext(
+ 'api-access-methods-view',
+ 'If you are not connected to our VPN, then the Encrypted DNS proxy will use your own non-VPN IP when connecting. The DoH servers are hosted by one of the following providers: Quad 9, CloudFlare, or Google.',
+ ),
+ ]}
+ />
+ )}
<ContextMenuContainer>
<ContextMenuTrigger>
<StyledContextMenuButton
diff --git a/gui/src/renderer/components/ContextMenu.tsx b/gui/src/renderer/components/ContextMenu.tsx
index fd84a8f0d9..2e01c9375f 100644
--- a/gui/src/renderer/components/ContextMenu.tsx
+++ b/gui/src/renderer/components/ContextMenu.tsx
@@ -36,6 +36,8 @@ const menuContext = React.createContext<MenuContext>({
const StyledMenuContainer = styled.div({
position: 'relative',
padding: '8px 4px',
+ display: 'flex',
+ justifyContent: 'center',
});
export function ContextMenuContainer(props: React.PropsWithChildren) {
diff --git a/gui/src/renderer/components/InfoButton.tsx b/gui/src/renderer/components/InfoButton.tsx
index 4ef2aa3c6e..7f77f115e7 100644
--- a/gui/src/renderer/components/InfoButton.tsx
+++ b/gui/src/renderer/components/InfoButton.tsx
@@ -8,7 +8,7 @@ import ImageView from './ImageView';
import { ModalAlert, ModalAlertType } from './Modal';
const StyledInfoButton = styled.button({
- margin: '0 16px 0 0',
+ margin: '0 16px 0 8px',
borderWidth: 0,
padding: 0,
cursor: 'default',
diff --git a/gui/src/renderer/components/cell/Label.tsx b/gui/src/renderer/components/cell/Label.tsx
index 1115edc829..b2b37c1e4c 100644
--- a/gui/src/renderer/components/cell/Label.tsx
+++ b/gui/src/renderer/components/cell/Label.tsx
@@ -15,11 +15,15 @@ const StyledLabel = styled.div<{ disabled: boolean }>(buttonText, (props) => ({
textAlign: 'left',
[`${LabelContainer} &&`]: {
- marginTop: '5px',
+ marginTop: '0px',
marginBottom: 0,
height: '20px',
lineHeight: '20px',
},
+
+ [`${LabelContainer}:has(${StyledSubLabel}) &&`]: {
+ marginTop: '5px',
+ },
}));
const StyledSubText = styled.span<{ disabled: boolean }>(tinyText, (props) => ({
diff --git a/gui/src/shared/daemon-rpc-types.ts b/gui/src/shared/daemon-rpc-types.ts
index bd8f99711b..1522d43b39 100644
--- a/gui/src/shared/daemon-rpc-types.ts
+++ b/gui/src/shared/daemon-rpc-types.ts
@@ -524,7 +524,8 @@ export type NamedCustomProxy = CustomProxy & { name: string };
export type DirectMethod = { type: 'direct' };
export type BridgesMethod = { type: 'bridges' };
-export type AccessMethod = DirectMethod | BridgesMethod | CustomProxy;
+export type EncryptedDnsProxy = { type: 'encrypted-dns-proxy' };
+export type AccessMethod = DirectMethod | BridgesMethod | EncryptedDnsProxy | CustomProxy;
export type NamedAccessMethod<T extends AccessMethod> = T & { name: string };
@@ -540,6 +541,7 @@ export type AccessMethodSetting<T extends AccessMethod = AccessMethod> =
export type ApiAccessMethodSettings = {
direct: AccessMethodSetting<DirectMethod>;
mullvadBridges: AccessMethodSetting<BridgesMethod>;
+ encryptedDnsProxy: AccessMethodSetting<EncryptedDnsProxy>;
custom: Array<AccessMethodSetting<CustomProxy>>;
};