summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/NotificationArea.tsx4
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/lib/notifications/no-open-vpn-server-available.ts69
-rw-r--r--desktop/packages/mullvad-vpn/src/shared/constants/urls.ts2
3 files changed, 64 insertions, 11 deletions
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/NotificationArea.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/NotificationArea.tsx
index 9a7ad3c928..17ccab76a3 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/NotificationArea.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/NotificationArea.tsx
@@ -51,9 +51,9 @@ export default function NotificationArea(props: IProps) {
const account = useSelector((state: IReduxState) => state.account);
const locale = useSelector((state: IReduxState) => state.userInterface.locale);
const tunnelState = useSelector((state: IReduxState) => state.connection.status);
+ const connection = useSelector((state: IReduxState) => state.connection);
const version = useSelector((state: IReduxState) => state.version);
const tunnelProtocol = useTunnelProtocol();
- const reduxConnection = useSelector((state) => state.connection);
const fullRelayList = useSelector((state) => state.settings.relayLocations);
const blockWhenDisconnected = useSelector(
@@ -95,8 +95,8 @@ export default function NotificationArea(props: IProps) {
hasExcludedApps,
}),
new NoOpenVpnServerAvailableNotificationProvider({
+ connection,
tunnelProtocol,
- tunnelState: reduxConnection.status,
relayLocations: fullRelayList,
}),
new ErrorNotificationProvider({
diff --git a/desktop/packages/mullvad-vpn/src/renderer/lib/notifications/no-open-vpn-server-available.ts b/desktop/packages/mullvad-vpn/src/renderer/lib/notifications/no-open-vpn-server-available.ts
index d84466b0ba..566a61c80b 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/lib/notifications/no-open-vpn-server-available.ts
+++ b/desktop/packages/mullvad-vpn/src/renderer/lib/notifications/no-open-vpn-server-available.ts
@@ -5,7 +5,6 @@ import {
ErrorStateCause,
TunnelParameterError,
TunnelProtocol,
- TunnelState,
} from '../../../shared/daemon-rpc-types';
import { messages } from '../../../shared/gettext';
import {
@@ -13,12 +12,16 @@ import {
InAppNotificationProvider,
InAppNotificationSubtitle,
} from '../../../shared/notifications';
-import { IRelayLocationCountryRedux } from '../../redux/settings/reducers';
+import { IConnectionReduxState } from '../../redux/connection/reducers';
+import {
+ IRelayLocationCountryRedux,
+ IRelayLocationRelayRedux,
+} from '../../redux/settings/reducers';
import { RoutePath } from '../routes';
interface NoOpenVpnServerAvailableNotificationContext {
+ connection: IConnectionReduxState;
tunnelProtocol: TunnelProtocol;
- tunnelState: TunnelState;
relayLocations: IRelayLocationCountryRedux[];
}
@@ -26,12 +29,20 @@ export class NoOpenVpnServerAvailableNotificationProvider implements InAppNotifi
public constructor(private context: NoOpenVpnServerAvailableNotificationContext) {}
public mayDisplay = () => {
- const { tunnelState, tunnelProtocol } = this.context;
+ const { connection, tunnelProtocol } = this.context;
+
+ const hasNoEnabledOpenVpnRelays = !this.anyOpenVpnLocationsEnabled();
+ const isSelectedRelayOpenVpn = this.isSelectedRelayOpenVpn();
+ const isTunnelProtocolOpenVpn = tunnelProtocol === 'openvpn';
+ const hasNoMatchingRelay =
+ connection.status.state === 'error' &&
+ connection.status.details.cause === ErrorStateCause.tunnelParameterError &&
+ connection.status.details.parameterError === TunnelParameterError.noMatchingRelay;
+
return (
- tunnelProtocol === 'openvpn' &&
- tunnelState.state === 'error' &&
- tunnelState.details.cause === ErrorStateCause.tunnelParameterError &&
- tunnelState.details.parameterError === TunnelParameterError.noMatchingRelay
+ isTunnelProtocolOpenVpn &&
+ hasNoMatchingRelay &&
+ (isSelectedRelayOpenVpn || hasNoEnabledOpenVpnRelays)
);
};
@@ -39,6 +50,7 @@ export class NoOpenVpnServerAvailableNotificationProvider implements InAppNotifi
let title: string = '';
const subtitle: InAppNotificationSubtitle[] = [];
const capitalizedOpenVpn = strings.openvpn.toUpperCase();
+
if (this.anyOpenVpnLocationsEnabled()) {
title = sprintf(
// TRANSLATORS: Notification title when there are no openVPN servers
@@ -111,6 +123,47 @@ export class NoOpenVpnServerAvailableNotificationProvider implements InAppNotifi
};
}
+ private isSelectedRelayOpenVpn() {
+ const selectedRelay = this.getSelectedRelay();
+
+ if (selectedRelay) {
+ // NOTE: Even though 'bridge' is not specifically OpenVPN
+ // it is only used together with OpenVPN and as such
+ // we want to target it as well.
+ return selectedRelay.endpointType === 'openvpn' || selectedRelay.endpointType === 'bridge';
+ }
+
+ return false;
+ }
+
+ private getSelectedRelay() {
+ const selectedRelay = this.context.relayLocations.reduce<IRelayLocationRelayRedux | undefined>(
+ (selectedRelay, location) => {
+ const isSelectedRelayCountry = location.name === this.context.connection.country;
+ if (isSelectedRelayCountry) {
+ const relayCity = location.cities.find(
+ (city) => city.name === this.context.connection.city,
+ );
+
+ if (relayCity) {
+ const relay = relayCity.relays.find(
+ (relay) => relay.hostname === this.context.connection.hostname,
+ );
+
+ if (relay) {
+ return relay;
+ }
+ }
+ }
+
+ return selectedRelay;
+ },
+ undefined,
+ );
+
+ return selectedRelay;
+ }
+
private anyOpenVpnLocationsEnabled() {
return this.context.relayLocations.some((location) => {
return location.cities.some((city) => {
diff --git a/desktop/packages/mullvad-vpn/src/shared/constants/urls.ts b/desktop/packages/mullvad-vpn/src/shared/constants/urls.ts
index f9a77a92b0..435200f7aa 100644
--- a/desktop/packages/mullvad-vpn/src/shared/constants/urls.ts
+++ b/desktop/packages/mullvad-vpn/src/shared/constants/urls.ts
@@ -5,7 +5,7 @@ export const urls = {
faq: 'https://mullvad.net/help/tag/mullvad-app/',
privacyGuide: 'https://mullvad.net/help/first-steps-towards-online-privacy/',
download: 'https://mullvad.net/download/vpn/',
- removingOpenVpnBlog: 'https://mullvad.net/en/blog/removing-openvpn-15th-january-2026',
+ removingOpenVpnBlog: 'https://mullvad.net/blog/removing-openvpn-15th-january-2026',
} as const;
type BaseUrl = (typeof urls)[keyof typeof urls];