summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMarkus Pettersson <markus.pettersson@mullvad.net>2025-02-28 10:45:49 +0100
committerMarkus Pettersson <markus.pettersson@mullvad.net>2025-02-28 10:45:49 +0100
commit64f883ab70e36bdaf929ab6a8e0322024b9b9b38 (patch)
tree3ec3c33d2ef3f7a0b50bf615013b14a72d466241
parent4edeccf444519b25a7f6928d9daaaf3b7dbd491b (diff)
parent397474939cf5c21c5415f34040fec7e2092b6930 (diff)
downloadmullvadvpn-64f883ab70e36bdaf929ab6a8e0322024b9b9b38.tar.xz
mullvadvpn-64f883ab70e36bdaf929ab6a8e0322024b9b9b38.zip
Merge branch 'custom-lists-are-not-marked-with-entryexit-when-blocked-des-1349'
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/select-location/custom-list-helpers.ts75
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/select-location/select-location-helpers.ts4
2 files changed, 62 insertions, 17 deletions
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/select-location/custom-list-helpers.ts b/desktop/packages/mullvad-vpn/src/renderer/components/select-location/custom-list-helpers.ts
index 3f6149cd7f..10eacf0ebc 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/select-location/custom-list-helpers.ts
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/select-location/custom-list-helpers.ts
@@ -1,6 +1,10 @@
import { useMemo } from 'react';
-import { ICustomList, RelayLocation } from '../../../shared/daemon-rpc-types';
+import {
+ compareRelayLocationGeographical,
+ ICustomList,
+ RelayLocation,
+} from '../../../shared/daemon-rpc-types';
import { hasValue } from '../../../shared/utils';
import { searchMatch } from '../../lib/filter-locations';
import { useSelector } from '../../redux/store';
@@ -9,7 +13,12 @@ import {
usePreventDueToCustomBridgeSelected,
useSelectedLocation,
} from './RelayListContext';
-import { isCustomListDisabled, isExpanded, isSelected } from './select-location-helpers';
+import {
+ formatRowName,
+ isCustomListDisabled,
+ isExpanded,
+ isSelected,
+} from './select-location-helpers';
import {
CitySpecification,
CountrySpecification,
@@ -69,11 +78,12 @@ function prepareCustomList(
expandedLocations?: Array<RelayLocation>,
): CustomListSpecification {
const location = { customList: list.id };
- const locations = prepareLocations(list, fullRelayList, expandedLocations);
+ const locations = prepareLocations(list, fullRelayList, expandedLocations, disabledLocation);
const disabledReason = isCustomListDisabled(location, locations, disabledLocation);
+
return {
- label: list.name,
+ label: formatRowName(list.name, location, disabledReason),
list,
location,
active: disabledReason !== DisabledReason.inactive,
@@ -92,6 +102,7 @@ function prepareLocations(
list: ICustomList,
fullRelayList: GeographicalRelayList,
expandedLocations?: Array<RelayLocation>,
+ disabledLocation?: { location: RelayLocation; reason: DisabledReason },
) {
const locationCounter = {};
@@ -104,21 +115,24 @@ function prepareLocations(
?.cities.find((city) => city.location.city === location.city)
?.relays.find((relay) => relay.location.hostname === location.hostname);
- return relay && updateRelay(relay, list.id);
+ return relay && updateRelay(relay, list, disabledLocation);
} else if ('city' in location) {
// Search through all cities in all countries to find the matching city.
const city = fullRelayList
.find((country) => country.location.country === location.country)
?.cities.find((city) => city.location.city === location.city);
- return city && updateCity(city, list.id, locationCounter, expandedLocations);
+ return city && updateCity(city, list, locationCounter, expandedLocations, disabledLocation);
} else {
// Search through all countries to find the matching country.
const country = fullRelayList.find(
(country) => country.location.country === location.country,
);
- return country && updateCountry(country, list.id, locationCounter, expandedLocations);
+ return (
+ country &&
+ updateCountry(country, list, locationCounter, expandedLocations, disabledLocation)
+ );
}
})
.filter(hasValue);
@@ -128,9 +142,10 @@ function prepareLocations(
// for the custom list list.
function updateCountry(
country: CountrySpecification,
- customList: string,
+ list: ICustomList,
locationCounter: Record<string, number>,
expandedLocations?: Array<RelayLocation>,
+ disabledLocation?: { location: RelayLocation; reason: DisabledReason },
): CountrySpecification {
// Since there can be multiple instances of a location in a custom list, every instance needs to
// be unique to avoid expanding all instances when expanding one.
@@ -138,7 +153,7 @@ function updateCountry(
const count = locationCounter[counterKey] ?? 0;
locationCounter[counterKey] = count + 1;
- const location = { ...country.location, customList, count };
+ const location = { ...country.location, customList: list.id, count };
return {
...country,
location,
@@ -146,7 +161,7 @@ function updateCountry(
selected: false,
visible: true,
cities: country.cities.map((city) =>
- updateCity(city, customList, locationCounter, expandedLocations),
+ updateCity(city, list, locationCounter, expandedLocations, disabledLocation),
),
};
}
@@ -155,9 +170,10 @@ function updateCountry(
// for the custom list list.
function updateCity(
city: CitySpecification,
- customList: string,
+ list: ICustomList,
locationCounter: Record<string, number>,
expandedLocations?: Array<RelayLocation>,
+ disabledLocation?: { location: RelayLocation; reason: DisabledReason },
): CitySpecification {
// Since there can be multiple instances of a location in a custom list, every instance needs to
// be unique to avoid expanding all instances when expanding one.
@@ -165,23 +181,52 @@ function updateCity(
const count = locationCounter[counterKey] ?? 0;
locationCounter[counterKey] = count + 1;
- const location = { ...city.location, customList, count };
+ const location = { ...city.location, customList: list.id, count };
return {
...city,
location,
expanded: isExpanded(location, expandedLocations),
selected: false,
visible: true,
- relays: city.relays.map((relay) => updateRelay(relay, customList)),
+ relays: city.relays.map((relay) => updateRelay(relay, list, disabledLocation)),
};
}
// Update the RelaySpecification from the original relay list to contain the correct properties
// for the custom list list.
-function updateRelay(relay: RelaySpecification, customList: string): RelaySpecification {
+function updateRelay(
+ relay: RelaySpecification,
+ list: ICustomList,
+ disabledLocation?: { location: RelayLocation; reason: DisabledReason },
+): RelaySpecification {
+ let disabledReason = relay.disabledReason;
+
+ if (disabledLocation && disabledReason === undefined) {
+ // If this relay's custom list parent is the disabled location and the
+ // list consists of only a single item, then we should mark this relay
+ // as disabled
+ const isParentCustomListOfSingleItem =
+ list.id === disabledLocation.location.customList && list.locations.length === 1;
+
+ // If the relay is the same as the disabled location we should respect
+ // that and mark the relay as disabled
+ const isSameRelay = compareRelayLocationGeographical(relay.location, disabledLocation.location);
+
+ if (isParentCustomListOfSingleItem || isSameRelay) {
+ if (
+ disabledLocation.reason === DisabledReason.exit ||
+ disabledLocation.reason === DisabledReason.entry
+ ) {
+ disabledReason = disabledLocation.reason;
+ }
+ }
+ }
+
return {
...relay,
- location: { ...relay.location, customList },
+ disabledReason,
+ disabled: relay.disabled || disabledReason !== undefined,
+ location: { ...relay.location, customList: list.id },
selected: false,
visible: true,
};
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/select-location/select-location-helpers.ts b/desktop/packages/mullvad-vpn/src/renderer/components/select-location/select-location-helpers.ts
index 3d099adb7b..3f5f1985b5 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/select-location/select-location-helpers.ts
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/select-location/select-location-helpers.ts
@@ -128,7 +128,7 @@ export function isCityDisabled(
disabledLocation?: { location: RelayLocation; reason: DisabledReason },
): DisabledReason | undefined {
const relaysDisabled = city.relays.map((relay) =>
- isRelayDisabled(relay, { ...location, hostname: relay.hostname }),
+ isRelayDisabled(relay, { ...location, hostname: relay.hostname }, disabledLocation),
);
if (relaysDisabled.every((status) => status === DisabledReason.inactive)) {
return DisabledReason.inactive;
@@ -162,7 +162,7 @@ export function isCountryDisabled(
disabledLocation?: { location: RelayLocation; reason: DisabledReason },
): DisabledReason | undefined {
const citiesDisabled = country.cities.map((city) =>
- isCityDisabled(city, { ...location, city: city.code }),
+ isCityDisabled(city, { ...location, city: city.code }, disabledLocation),
);
if (citiesDisabled.every((status) => status === DisabledReason.inactive)) {
return DisabledReason.inactive;