73 changes: 34 additions & 39 deletions src/Api/ProtonVPN.Api.Tests/Handlers/AlternativeHostHandlerTest.cs

Large diffs are not rendered by default.

18 changes: 9 additions & 9 deletions src/Api/ProtonVPN.Api/ApiHostProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,27 +18,32 @@
*/

using System;
using System.Threading.Tasks;
using ProtonVPN.Api.Contracts;
using ProtonVPN.Common.Configuration;
using ProtonVPN.Common.Vpn;
using ProtonVPN.Core.Settings;
using ProtonVPN.Core.Vpn;

namespace ProtonVPN.Api
{
public class ApiHostProvider : IApiHostProvider, IVpnStateAware
public class ApiHostProvider : IApiHostProvider
{
private const int MAX_HOURS_WITH_PROXY = 24;

private readonly string _apiHost;
private readonly IAppSettings _appSettings;
private bool _isDisconnected = true;

public ApiHostProvider(IAppSettings appSettings, IConfiguration config)
public ApiHostProvider(IAppSettings appSettings, IConfiguration config, IVpnStatusNotifier vpnStatusNotifier)
{
_appSettings = appSettings;
_apiHost = new Uri(config.Urls.ApiUrl).Host;

vpnStatusNotifier.VpnStatusChanged += OnVpnStatusChanged;
}

private void OnVpnStatusChanged(object sender, VpnStatus vpnStatus)
{
_isDisconnected = vpnStatus == VpnStatus.Disconnected;
}

public string GetHost()
Expand All @@ -53,10 +58,5 @@ public bool IsProxyActive()
DateTime.UtcNow.Subtract(_appSettings.LastPrimaryApiFailDateUtc).TotalHours < MAX_HOURS_WITH_PROXY &&
!string.IsNullOrEmpty(_appSettings.ActiveAlternativeApiBaseUrl);
}

public async Task OnVpnStateChanged(VpnStateChangedEventArgs e)
{
_isDisconnected = e.State.Status == VpnStatus.Disconnected;
}
}
}
19 changes: 14 additions & 5 deletions src/Api/ProtonVPN.Api/Handlers/AlternativeHostHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,19 @@
using System.Threading;
using System.Threading.Tasks;
using Polly.Timeout;
using ProtonVPN.Api.Contracts;
using ProtonVPN.Api.Contracts.Exceptions;
using ProtonVPN.Common.Configuration;
using ProtonVPN.Common.Extensions;
using ProtonVPN.Logging.Contracts;
using ProtonVPN.Logging.Contracts.Events.ApiLogs;
using ProtonVPN.Common.Networking;
using ProtonVPN.Common.Vpn;
using ProtonVPN.Core.Auth;
using ProtonVPN.Core.Settings;
using ProtonVPN.Core.Vpn;
using ProtonVPN.Dns.Contracts;
using ProtonVPN.Dns.Contracts.AlternativeRouting;
using ProtonVPN.Dns.Contracts.Exceptions;
using ProtonVPN.Logging.Contracts;
using ProtonVPN.Logging.Contracts.Events.ApiLogs;

namespace ProtonVPN.Api.Handlers
{
Expand Down Expand Up @@ -68,6 +68,7 @@ public AlternativeHostHandler(
IAlternativeHostsManager alternativeHostsManager,
IAppSettings appSettings,
GuestHoleState guestHoleState,
IVpnStatusNotifier vpnStatusNotifier,
IConfiguration configuration)
{
_logger = logger;
Expand All @@ -78,11 +79,13 @@ public AlternativeHostHandler(
_guestHoleState = guestHoleState;
_defaultApiHost = new Uri(configuration.Urls.ApiUrl).Host;
_alternativeRoutingCheckInterval = configuration.AlternativeRoutingCheckInterval;

vpnStatusNotifier.VpnStatusChanged += OnVpnStatusChanged;
}

public async Task OnVpnStateChanged(VpnStateChangedEventArgs e)
private void OnVpnStatusChanged(object sender, VpnStatus vpnStatus)
{
_isDisconnected = e.State.Status == VpnStatus.Disconnected;
_isDisconnected = vpnStatus == VpnStatus.Disconnected;
}

protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
Expand Down Expand Up @@ -308,6 +311,9 @@ private async Task DisableAlternativeRoutingAsync()
{
_lastAlternativeRoutingCheckDateUtc = null;
_activeAlternativeHost = null;

_appSettings.LastPrimaryApiFailDateUtc = DateTime.MaxValue;
_appSettings.ActiveAlternativeApiBaseUrl = string.Empty;
}
finally
{
Expand Down Expand Up @@ -398,6 +404,9 @@ private async Task EnableAlternativeRoutingAsync(string alternativeHost)
{
_lastAlternativeRoutingCheckDateUtc = DateTime.UtcNow;
_activeAlternativeHost = alternativeHost;

_appSettings.LastPrimaryApiFailDateUtc = DateTime.UtcNow;
_appSettings.ActiveAlternativeApiBaseUrl = alternativeHost;
}
finally
{
Expand Down
4 changes: 2 additions & 2 deletions src/GlobalAssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

[assembly: AssemblyVersion("3.2.9.0")]
[assembly: AssemblyFileVersion("3.2.9.0")]
[assembly: AssemblyVersion("3.2.10.0")]
[assembly: AssemblyFileVersion("3.2.10.0")]
[assembly: ComVisible(false)]
[assembly: AssemblyInformationalVersion("$AssemblyVersion")]
[assembly: SupportedOSPlatform("windows")]
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,46 @@
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Security.Cryptography.X509Certificates;
using Microsoft.Web.WebView2.Core;
using ProtonVPN.Api.Contracts;
using ProtonVPN.Api.Handlers.TlsPinning;
using ProtonVPN.Common.Configuration;
using ProtonVPN.HumanVerification.Contracts;
using ProtonVPN.Logging.Contracts;
using ProtonVPN.Logging.Contracts.Events.AppLogs;
using ProtonVPN.HumanVerification.Contracts;

namespace ProtonVPN.HumanVerification.Gui
{
public partial class WebView
{
private const string CSP_HEADER = "Content-Security-Policy";

private readonly IConfiguration _config;
private readonly IApiHostProvider _apiHostProvider;
private readonly ICertificateValidator _certificateValidator;
private readonly IHumanVerificationConfig _humanVerificationConfig;
private readonly ILogger _logger;
private readonly HttpClient _httpClient;

public WebView(ICertificateValidator certificateValidator,
public WebView(
IConfiguration config,
IApiHostProvider apiHostProvider,
ICertificateValidator certificateValidator,
IHumanVerificationConfig humanVerificationConfig,
ILogger logger)
ILogger logger,
TlsPinnedCertificateHandler tlsPinnedCertificateHandler)
{
_config = config;
_apiHostProvider = apiHostProvider;
_certificateValidator = certificateValidator;
_humanVerificationConfig = humanVerificationConfig;
_logger = logger;
_httpClient = new HttpClient(tlsPinnedCertificateHandler);

InitializeComponent();
InitializeWebView();
}
Expand Down Expand Up @@ -68,6 +86,9 @@ private async void OnCoreWebView2InitializationCompleted(object sender,
{
await WebView2.CoreWebView2.ClearServerCertificateErrorActionsAsync();
WebView2.CoreWebView2.ServerCertificateErrorDetected += OnServerCertificateErrorDetected;

WebView2.CoreWebView2.AddWebResourceRequestedFilter("*", CoreWebView2WebResourceContext.All);
WebView2.CoreWebView2.WebResourceRequested += OnWebResourceRequested;
}
else
{
Expand All @@ -80,6 +101,51 @@ private async void OnCoreWebView2InitializationCompleted(object sender,
}
}

private void OnWebResourceRequested(object sender, CoreWebView2WebResourceRequestedEventArgs e)
{
HttpRequestMessage request = new(new HttpMethod(e.Request.Method), e.Request.Uri);
foreach (KeyValuePair<string, string> pair in e.Request.Headers)
{
request.Headers.Add(pair.Key, pair.Value);
}

if (_apiHostProvider.IsProxyActive())
{
request.Headers.Add("X-PM-DoH-Host", _config.DoHVerifyApiHost);
}

try
{
HttpResponseMessage response = _httpClient.Send(request);
e.Response = ModifyResponseMessage(response);
}
catch (HttpRequestException ex)
{
_logger.Error<AppLog>("Failed to fetch webview resource.", ex);
}
}

private CoreWebView2WebResourceResponse ModifyResponseMessage(HttpResponseMessage response)
{
CoreWebView2WebResourceResponse modifiedResponse =
WebView2.CoreWebView2.Environment.CreateWebResourceResponse(
response.Content.ReadAsStream(),
(int)response.StatusCode,
response.ReasonPhrase,
string.Empty);

IEnumerable<KeyValuePair<string, IEnumerable<string>>> headers = response.Headers
.Where(h => h.Key != CSP_HEADER)
.Concat(response.Content.Headers);

foreach (KeyValuePair<string, IEnumerable<string>> header in headers)
{
modifiedResponse.Headers.AppendHeader(header.Key, string.Join(",", header.Value));
}

return modifiedResponse;
}

private void LogWebViewInitializationException(Exception e)
{
_logger.Error<AppLog>("Failed to initialize CoreWebView2.", e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ public void SetRequestToken(string token)
{
_requestToken = token;
RaisePropertyChanged(nameof(Url));

_logger.Info<AppLog>($"Human verification url changed to: {Url}");
}

private void OnWebMessageReceived(CoreWebView2WebMessageReceivedEventArgs e)
Expand Down
1 change: 1 addition & 0 deletions src/ProtonVPN.App/BugReporting/BugReportingModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ protected override void Load(ContainerBuilder builder)
builder.RegisterType<UserSettingsLog>().AsImplementedInterfaces().SingleInstance();
builder.RegisterType<NetworkAdapterLog>().AsImplementedInterfaces().SingleInstance();
builder.RegisterType<RoutingTableLog>().AsImplementedInterfaces().SingleInstance();
builder.RegisterType<AppInstallLog>().AsImplementedInterfaces().SingleInstance();

builder.RegisterType<NetworkLogWriter>().SingleInstance();
builder.RegisterType<FormElementBuilder>().As<IFormElementBuilder>().SingleInstance();
Expand Down
42 changes: 42 additions & 0 deletions src/ProtonVPN.App/BugReporting/Diagnostic/AppInstallLog.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2023 Proton AG
*
* This file is part of ProtonVPN.
*
* ProtonVPN is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ProtonVPN is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ProtonVPN. If not, see <https://www.gnu.org/licenses/>.
*/

using System.IO;
using ProtonVPN.Common.Configuration;

namespace ProtonVPN.BugReporting.Diagnostic
{
public class AppInstallLog : BaseLog
{
private readonly IConfiguration _configuration;

public AppInstallLog(IConfiguration configuration) : base(configuration.DiagnosticsLogFolder, "Install.log.txt")
{
_configuration = configuration;
}

public override void Write()
{
if (File.Exists(_configuration.AppInstallLogPath))
{
File.Copy(_configuration.AppInstallLogPath, Path, true);
}
}
}
}
2 changes: 1 addition & 1 deletion src/ProtonVPN.App/Core/Bootstraper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ private void RegisterEvents()
await Resolve<LoginViewModel>().OnVpnStateChanged(e);
await Resolve<ReportBugModalViewModel>().OnVpnStateChanged(e);
await Resolve<GuestHoleConnector>().OnVpnStateChanged(e);
await Resolve<AlternativeHostHandler>().OnVpnStateChanged(e);
Resolve<IVpnStatusNotifier>().OnVpnStateChanged(e.State.Status);
});

vpnServiceManager.RegisterPortForwardingStateCallback((state) =>
Expand Down
1 change: 1 addition & 0 deletions src/ProtonVPN.App/Core/Ioc/AppModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ protected override void Load(ContainerBuilder builder)
builder.RegisterType<WebAuthenticator>().AsImplementedInterfaces().SingleInstance();
builder.RegisterType<NetShieldStatsManager>().AsImplementedInterfaces().SingleInstance();
builder.RegisterType<UpgradeModalManager>().AsImplementedInterfaces().SingleInstance();
builder.RegisterType<VpnStatusNotifier>().AsImplementedInterfaces().SingleInstance();
}
}
}
35 changes: 35 additions & 0 deletions src/ProtonVPN.App/Core/Service/Vpn/VpnStatusNotifier.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright (c) 2023 Proton AG
*
* This file is part of ProtonVPN.
*
* ProtonVPN is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ProtonVPN is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ProtonVPN. If not, see <https://www.gnu.org/licenses/>.
*/

using System;
using ProtonVPN.Api.Contracts;
using ProtonVPN.Common.Vpn;

namespace ProtonVPN.Core.Service.Vpn
{
public class VpnStatusNotifier : IVpnStatusNotifier
{
public event EventHandler<VpnStatus> VpnStatusChanged;

public void OnVpnStateChanged(VpnStatus vpnStatus)
{
VpnStatusChanged?.Invoke(this, vpnStatus);
}
}
}
5 changes: 5 additions & 0 deletions src/ProtonVPN.Common/Configuration/Config.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ public class Config : IConfiguration
[Required]
public string DiagnosticsZipPath { get; set; }

[Required]
public string AppInstallLogPath { get; set; }

[Required]
public string TranslationsFolder { get; set; }

Expand Down Expand Up @@ -205,6 +208,8 @@ public class Config : IConfiguration

public List<string> DoHProviders { get; set; } = new();

public string DoHVerifyApiHost { get; set; }

[Required]
public string DefaultLocale { get; set; }

Expand Down
5 changes: 5 additions & 0 deletions src/ProtonVPN.Common/Configuration/IConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ public interface IConfiguration
[Required]
string DiagnosticsZipPath { get; set; }

[Required]
string AppInstallLogPath { get; set; }

[Required]
string TranslationsFolder { get; set; }

Expand Down Expand Up @@ -204,6 +207,8 @@ public interface IConfiguration

List<string> DoHProviders { get; set; }

string DoHVerifyApiHost { get; set; }

[Required]
string DefaultLocale { get; set; }

Expand Down
19 changes: 11 additions & 8 deletions src/ProtonVPN.Common/Configuration/Source/DefaultConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,9 @@ public IConfiguration Value()

string localAppDataFolder =
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "ProtonVPN");
string commonAppDataFolder =
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "ProtonVPN");
string serviceDataFolder = Path.Combine(baseFolder, "ServiceData");
string appLogFolder = Path.Combine(localAppDataFolder, "Logs");
string serviceLogFolder = Path.Combine(commonAppDataFolder, "Logs");
string serviceLogFolder = Path.Combine(serviceDataFolder, "Logs");
int osBits = Environment.Is64BitOperatingSystem ? 64 : 32;

string wireGuardConfigFilename = "ProtonVPN";
Expand All @@ -69,13 +68,15 @@ public IConfiguration Value()

DiagnosticsZipPath = Path.Combine(localAppDataFolder, "DiagnosticLogs", "diagnostic_logs.zip"),

AppInstallLogPath = Path.Combine(Path.GetDirectoryName(baseFolder) ?? string.Empty, "Install.log.txt"),

TranslationsFolder = baseFolder,

ServiceName = "ProtonVPN Service",

ServiceExePath = Path.Combine(baseFolder, "ProtonVPNService.exe"),

ServiceSettingsFilePath = Path.Combine(commonAppDataFolder, "ServiceSettings.json"),
ServiceSettingsFilePath = Path.Combine(serviceDataFolder, "ServiceSettings.json"),

ServersJsonCacheFilePath = Path.Combine(localAppDataFolder, "Servers.json"),

Expand All @@ -89,7 +90,7 @@ public IConfiguration Value()

UpdateFilePath = Path.Combine(localAppDataFolder, "Updates", "update.txt"),

UpdatesPath = Path.Combine(commonAppDataFolder, "Updates"),
UpdatesPath = Path.Combine(serviceDataFolder, "Updates"),

CalloutServiceName = "ProtonVPNCallout",

Expand Down Expand Up @@ -234,7 +235,7 @@ public IConfiguration Value()

TlsVerifyExePath = Path.Combine(baseFolder, "ProtonVPN.TlsVerify.exe"),

TlsExportCertFolder = Path.Combine(commonAppDataFolder, "ExportCert"),
TlsExportCertFolder = Path.Combine(serviceDataFolder, "ExportCert"),

TapAdapterId = "tapprotonvpn",

Expand All @@ -255,9 +256,9 @@ public IConfiguration Value()

TunAdapterName = "ProtonVPN",

LogFilePath = Path.Combine(commonAppDataFolder, "WireGuard", "log.bin"),
LogFilePath = Path.Combine(serviceDataFolder, "WireGuard", "log.bin"),

ConfigFilePath = Path.Combine(commonAppDataFolder, "WireGuard", $"{wireGuardConfigFilename}.conf"),
ConfigFilePath = Path.Combine(serviceDataFolder, "WireGuard", $"{wireGuardConfigFilename}.conf"),

ServiceName = "ProtonVPN WireGuard",

Expand Down Expand Up @@ -332,6 +333,8 @@ public IConfiguration Value()
"https://dns.google/dns-query",
},

DoHVerifyApiHost = "verify-api.protonvpn.com",

NtpServerUrl = "time.windows.com",

ServerValidationPublicKey = "MCowBQYDK2VwAyEANpYpt/FlSRwEuGLMoNAGOjy1BTyEJPJvKe00oln7LZk=",
Expand Down
22 changes: 0 additions & 22 deletions src/ProtonVPN.InstallActions/Os.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -299,26 +299,4 @@ void Os::RemovePinnedIcons(PCWSTR shortcut_path)
}

CoUninitialize();
}

void Os::SetFolderPermissions(LPWSTR path, LPCWSTR security_descriptor)
{
PSECURITY_DESCRIPTOR pSD = nullptr;
if (ConvertStringSecurityDescriptorToSecurityDescriptorW(security_descriptor, SDDL_REVISION_1, &pSD, nullptr))
{
if (SetFileSecurity(path, DACL_SECURITY_INFORMATION, pSD))
{
LogMessage(format(L"Folder {0} permissions changed successfully.", path));
}
else
{
LogMessage(format(L"Failed to change folder {0} permissions.", path), GetLastError());
}

LocalFree(pSD);
}
else
{
LogMessage(format(L"Failed to convert security descriptor {0}", security_descriptor), GetLastError());
}
}
1 change: 0 additions & 1 deletion src/ProtonVPN.InstallActions/Os.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ namespace Os
std::string GetEnvVariable(std::string name);
long ChangeShortcutTarget(const wchar_t* shortcut_path, const wchar_t* target_path);
void RemovePinnedIcons(PCWSTR shortcut_path);
void SetFolderPermissions(LPWSTR path, LPCWSTR security_descriptor);

enum DriverState
{
Expand Down
27 changes: 0 additions & 27 deletions src/ProtonVPN.InstallActions/dllmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,33 +170,6 @@ extern "C" EXPORT DWORD UpdateTaskbarIconTarget(const wchar_t* launcher_path)
return shortcut_path.empty() ? 0 : Os::ChangeShortcutTarget(shortcut_path.c_str(), launcher_path);
}

extern "C" EXPORT DWORD SetUpdatesFolderPermission(const wchar_t* folder_path)
{
const size_t folder_path_length = wcslen(folder_path);
wchar_t* path = new wchar_t[folder_path_length + 1];

if (wcscpy_s(path, folder_path_length + 1, folder_path) == 0)
{
wstring securityDescriptor =
L"D:(A;;0x1301bf;;;SY)"
"(A;OICIIO;GA;;;SY)"
"(A;;0x1301bf;;;BA)"
"(A;OICIIO;GA;;;BA)"
"(A;;0x1200a9;;;BU)"
"(A;OICIIO;GXGR;;;BU)"
"(A;OICIIO;GA;;;CO)"
"(A;;0x1200a9;;;AC)"
"(A;OICIIO;GXGR;;;AC)";
Os::SetFolderPermissions(path, securityDescriptor.c_str());
}
else
{
LogMessage(L"Failed to copy string.");
}

return 0;
}

extern "C" EXPORT DWORD RemovePinnedIcons(const wchar_t* shortcut_path)
{
Os::RemovePinnedIcons(shortcut_path);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"project": "windows-vpn",
"locale": "e27f01b74da6d1986b368ddb2b75cb85f77a65e3"
"locale": "9d19b5d046f957064e21d2a9940b0ce1e223ad27"
}
8 changes: 4 additions & 4 deletions src/ProtonVPN.Translations/Properties/Resources.be-BY.resx
Original file line number Diff line number Diff line change
Expand Up @@ -2661,7 +2661,7 @@
<value>Тарыфны план VPN Plus забяспечвае пакрыццё ўсяго свету</value>
</data>
<data name="Servers_UpsellBanner_NotTheCountryYouWanted">
<value>Не тая краіна, якую хацелі? Палепшыце, каб выбраць любы сервер</value>
<value>Не тая краіна, якую хацелі? Палепшыце свой тарыфны план, каб выбіраць любы сервер</value>
</data>
<data name="Servers_btn_Connect">
<value>Падключыцца</value>
Expand Down Expand Up @@ -3234,7 +3234,7 @@ This setting instructs the Proton VPN to start automatically when the user logs
<value>Яшчэ больш хуткі VPN</value>
</data>
<data name="Upsell_Countries_StreamMovies">
<value>Прагляд трансляцый вашых улюбёных фільмаў</value>
<value>Трансляцыі вашых абраных фільмаў</value>
</data>
<data name="Upsell_Countries_Subtitle">
<value>Калі вы паляпшаеце да Plus</value>
Expand All @@ -3260,7 +3260,7 @@ This setting instructs the Proton VPN to start automatically when the user logs
<value>Найвышэйшая хуткасць (10 Гбіт/с)</value>
</data>
<data name="Upsell_Country_Bullet3">
<value>Прагляд трансляцый вашых улюбёных фільмаў</value>
<value>Трансляцыі вашых абраных фільмаў</value>
</data>
<data name="Upsell_Country_Bullet4">
<value>Абараняйце да 10 прылад</value>
Expand Down Expand Up @@ -3332,7 +3332,7 @@ This setting instructs the Proton VPN to start automatically when the user logs
<comment>The button label in "allow non-standard ports" modal</comment>
</data>
<data name="Upsell_NonStandardPorts_msg">
<value>У вас дадатковыя або прафесійныя камп'ютарныя патрабаванні, якія патрабуюць нестандартныя парты? Палепшыце да VPN Plus, каб атрымаць доступ да гэтай і іншых прэміяльных функцый.</value>
<value>У вас дадатковыя або прафесійныя камп'ютарныя патрабаванні, дзе неабходна выкарыстоўваць нестандартныя порты? Палепшыце да VPN Plus, каб атрымаць доступ да гэтай і іншых прэміяльных функцый.</value>
<comment>The text in "allow non-standard ports" modal</comment>
</data>
<data name="Upsell_NonStandardPorts_ttl">
Expand Down
38 changes: 19 additions & 19 deletions src/ProtonVPN.Translations/Properties/Resources.es-419.resx
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@
<comment>The question displayed when trying to logout while connected to VPN</comment>
</data>
<data name="App_msg_UpdateConnectedConfirm">
<value>Para completar el proceso de actualización, Proton VPN se desconectará temporalmente y desactivará el interruptor de apagado permanente si alguno de estos está activo. ¿Quiere continuar?</value>
<value>Para completar el proceso de actualización, Proton VPN se desconectará temporalmente y desactivará el interruptor de bloqueo permanente si alguno de estos está activo. ¿Quiere continuar?</value>
<comment>The question displayed when trying to update the app while connected to VPN</comment>
</data>
<data name="App_ttl">
Expand Down Expand Up @@ -1592,7 +1592,7 @@ Siga &lt;Hyperlink Command="{Binding OpenArticleCommand}"&gt;&lt;Run Text="estas
<value>Algunos componentes de Proton VPN pueden estar bloqueados o desactivados, lo que le impide conectarse. Haga clic en Activar para resolverlo.&lt;LineBreak/&gt;Tome en cuenta que esta operación requiere privilegios de administrador.</value>
</data>
<data name="Dialogs_DisconnectError_btn_DisableKillSwitch">
<value>Desactivar el interruptor de apagado</value>
<value>Desactivar el interruptor de bloqueo</value>
<comment>The text on Disable button in Disconnect modal window</comment>
</data>
<data name="Dialogs_DisconnectError_btn_Upgrade">
Expand All @@ -1608,7 +1608,7 @@ Siga &lt;Hyperlink Command="{Binding OpenArticleCommand}"&gt;&lt;Run Text="estas
<comment>The message displayed in Disconnect modal window while trying to identify connection problem</comment>
</data>
<data name="Dialogs_DisconnectError_msg_KillSwitch">
<value>El interruptor de apagado está protegiendo su IP bloqueando todas las conexiones. En caso de problemas, puede desactivarlo.</value>
<value>El interruptor de bloqueo está protegiendo su IP bloqueando todas las conexiones. En caso de problemas, puede desactivarlo.</value>
<comment>The text displayed in Disconnect modal window if the disconnect occurred with kill switch turned on.</comment>
</data>
<data name="Dialogs_DisconnectError_msg_NoServers">
Expand Down Expand Up @@ -1664,10 +1664,10 @@ Siga &lt;Hyperlink Command="{Binding OpenArticleCommand}"&gt;&lt;Run Text="estas
<value>Salir de la aplicación le desconectará de la VPN.</value>
</data>
<data name="Dialogs_Exit_msg_KillSwitchOn">
<value>El interruptor de apagado está bloqueando todas las conexiones para evitar fugas de datos. Salir de la aplicación desactivará el interruptor.</value>
<value>El interruptor de bloqueo está bloqueando todas las conexiones para evitar fugas de datos. Salir de la aplicación desactivará el interruptor.</value>
</data>
<data name="Dialogs_Exit_msg_PermanentKillSwitch">
<value>El interruptor de apagado permanente está activado. Al salir de la aplicación bloqueará todas las conexiones salientes hasta que Proton VPN se conecte de nuevo.</value>
<value>El interruptor de bloqueo permanente está activado. Al salir de la aplicación bloqueará todas las conexiones salientes hasta que Proton VPN se conecte de nuevo.</value>
</data>
<data name="Dialogs_HumanVerification_ttl">
<value>Verificación humana</value>
Expand All @@ -1676,10 +1676,10 @@ Siga &lt;Hyperlink Command="{Binding OpenArticleCommand}"&gt;&lt;Run Text="estas
<value>El reloj de su sistema parece no estar sincronizado lo que podría evitar que la VPN se conecte correctamente. Consulte &lt;Hyperlink Command="{Binding OpenKbArticleCommand}"&gt;aquí&lt;/Hyperlink&gt; para más información.</value>
</data>
<data name="Dialogs_KillSwitchConfirmation_msg">
<value>Con el interruptor de apagado permanente, si la VPN no está conectada por alguna razón, no podrá acceder a Internet.</value>
<value>Con el interruptor de bloqueo permanente, si la VPN no está conectada por alguna razón, no podrá acceder a Internet.</value>
</data>
<data name="Dialogs_KillSwitchConfirmation_ttl">
<value>¿Activar el interruptor de apagado permanente?</value>
<value>¿Activar el interruptor de bloqueo permanente?</value>
</data>
<data name="Dialogs_MaximumDeviceLimit_Disconnect_Ok">
<value>Entendido</value>
Expand Down Expand Up @@ -1726,7 +1726,7 @@ Siga &lt;Hyperlink Command="{Binding OpenArticleCommand}"&gt;&lt;Run Text="estas
<comment>The error message displayed on the outdated app window when the app version is outdated</comment>
</data>
<data name="Dialogs_OutdatedApp_msg_KillSwitchActive">
<value>Tenga en cuenta que el interruptor de apagado está activado. Actualizar o salir de la aplicación lo desactivará.</value>
<value>Tenga en cuenta que el interruptor de bloqueo está activado. Actualizar o salir de la aplicación lo desactivará.</value>
<comment>The error message displayed on the outdated app window when the app version is outdated and kill switch is enabled</comment>
</data>
<data name="Dialogs_P2PBlocked_msg_Blocked">
Expand All @@ -1753,7 +1753,7 @@ Siga &lt;Hyperlink Command="{Binding OpenArticleCommand}"&gt;&lt;Run Text="estas
<value>Entendido</value>
</data>
<data name="Dialogs_SplitTunnelWarning_msg">
<value>Para que la tunelización dividida funcione correctamente, debe desactivar el interruptor de apagado.</value>
<value>Para que la tunelización dividida funcione correctamente, debe desactivar el interruptor de bloqueo.</value>
</data>
<data name="Dialogs_SubscriptionExpired_ListOption1_One">
<value>Cientos de servidores en {0} país</value>
Expand Down Expand Up @@ -1910,7 +1910,7 @@ Siga &lt;Hyperlink Command="{Binding OpenArticleCommand}"&gt;&lt;Run Text="estas
<value>Repare su instalación.</value>
</data>
<data name="KillSwitch">
<value>Interruptor de apagado</value>
<value>Interruptor de bloqueo</value>
<comment>Title for the kill switch feature. This feature is available from the side bar as a quick settings.</comment>
</data>
<data name="License_ttl">
Expand All @@ -1937,7 +1937,7 @@ Siga &lt;Hyperlink Command="{Binding OpenArticleCommand}"&gt;&lt;Run Text="estas
<comment>The text on Login button in Login window (logs in the user)</comment>
</data>
<data name="Login_lbl_KillSwitch">
<value>El interruptor de apagado está activado</value>
<value>El interruptor de bloqueo está activado</value>
<comment>The text displayed on the login window when user was force logged out while kill switch is active</comment>
</data>
<data name="Login_lbl_Password">
Expand Down Expand Up @@ -2342,7 +2342,7 @@ Siga &lt;Hyperlink Command="{Binding OpenArticleCommand}"&gt;&lt;Run Text="estas
<comment>The watermark text displayed in empty Server combo box in Profile window</comment>
</data>
<data name="Profiles_Profile_msg_DiscardChangesConfirm">
<value>Hay cambios de perfil sin guardar. ¿&lt;LineBreak/&gt;&lt;LineBreak/&gt;¿Está seguro que quiere descartarlo?</value>
<value>Hay cambios de perfil sin guardar. &lt;LineBreak/&gt;&lt;LineBreak/&gt;¿En verdad desea descartarlos?</value>
<comment>The message displayed in Question dialog when cancelling changes in Profile window.</comment>
</data>
<data name="Profiles_Profile_ttl_Create">
Expand Down Expand Up @@ -2434,11 +2434,11 @@ Siga &lt;Hyperlink Command="{Binding OpenArticleCommand}"&gt;&lt;Run Text="estas
<comment>The label for Profiles list in combo box in Quick Launch window</comment>
</data>
<data name="QuickSettings_btn_KillSwitchOff">
<value>Interruptor de apagado desactivado</value>
<value>Interruptor de bloqueo desactivado</value>
<comment>The text for the clickable option to disable the kill switch feature.</comment>
</data>
<data name="QuickSettings_btn_KillSwitchOn">
<value>Interruptor de apagado activado</value>
<value>Interruptor de bloqueo activado</value>
<comment>The text for the clickable option to enable the kill switch feature.</comment>
</data>
<data name="QuickSettings_btn_LearnMore">
Expand All @@ -2454,7 +2454,7 @@ Siga &lt;Hyperlink Command="{Binding OpenArticleCommand}"&gt;&lt;Run Text="estas
<value>Bloquear malware, anuncios y rastreadores</value>
</data>
<data name="QuickSettings_btn_PermanentKillSwitch">
<value>Interruptor de apagado permanente</value>
<value>Interruptor de bloqueo permanente</value>
<comment>The text for the clickable option to enable the kill switch feature permanently (even when the VPN app is not running).</comment>
</data>
<data name="QuickSettings_btn_PortForwardingOff">
Expand Down Expand Up @@ -2746,7 +2746,7 @@ Siga &lt;Hyperlink Command="{Binding OpenArticleCommand}"&gt;&lt;Run Text="estas
<comment>The label for Split Tunneling toggle switch in Advanced tab of Settings window</comment>
</data>
<data name="Settings_Advanced_lbl_SplitTunnel_Info">
<value>Excluye una aplicación o una dirección IP del tráfico VPN o incluye solo aplicaciones específicas. No se puede activar junto con el interruptor de apagado.</value>
<value>Excluye una aplicación o una dirección IP del tráfico VPN o incluye solo aplicaciones específicas. No se puede activar junto con el interruptor de bloqueo.</value>
<comment>The description of Split Tunneling setting displayed in the tooltip of ( i ) image next to the label for Split Tunneling toggle switch in Advanced tab of Settings window</comment>
</data>
<data name="Settings_Advanced_lbl_btn_LearnMore">
Expand All @@ -2773,7 +2773,7 @@ Siga &lt;Hyperlink Command="{Binding OpenArticleCommand}"&gt;&lt;Run Text="estas
<comment>The WireGuard protocol name displayed in the Protocol combo box in Connection tab of Settings window. Do not translate.</comment>
</data>
<data name="Settings_Connection_Warning_CustomDnsServer">
<value>Usar servidores DNS personalizados desactivará NetShield. Los servidores DNS son responsables de dirigirle a los sitios web correctos. &lt;LineBreak/&gt;&lt;LineBreak/&gt;Solo use servidores DNS en los que confíe. ¿Quiere activar los servidores DNS personalizados?</value>
<value>Usar servidores DNS personalizados desactivará NetShield. Los servidores DNS son responsables de dirigirle a los sitios web correctos. &lt;LineBreak/&gt;&lt;LineBreak/&gt;Solo use servidores DNS en los que confíe. ¿Desea activar los servidores DNS personalizados?</value>
<comment>The text displayed in Custom DNS Servers warning modal window when use is trying to turn the feature ON when NetShield feature is turned on as well</comment>
</data>
<data name="Settings_Connection_btn_Upgrade">
Expand Down Expand Up @@ -2943,11 +2943,11 @@ This setting instructs the Proton VPN to start automatically when the user logs
<comment>The text displayed in a tooltip of Connection section of Sidebar section of main app window</comment>
</data>
<data name="Sidebar_Connection_lbl_KillSwitch">
<value>¡Interruptor de apagado activado!</value>
<value>¡Interruptor de bloqueo activado!</value>
<comment>The text displayed in the sidebar when connection dropped and kill switch is turned on</comment>
</data>
<data name="Sidebar_Connection_lbl_KillSwitch_Info">
<value>El interruptor de apagado está bloqueando todas las conexiones para evitar que se filtren sus datos.</value>
<value>El interruptor de bloqueo está bloqueando todas las conexiones para evitar que se filtren sus datos.</value>
<comment>Tooltip message shown in sidebar connection status box when hovered on exclamation mark icon</comment>
</data>
<data name="Sidebar_Countries_AllLocationCount">
Expand Down
6 changes: 3 additions & 3 deletions src/ProtonVPN.Translations/Properties/Resources.es-ES.resx
Original file line number Diff line number Diff line change
Expand Up @@ -1586,10 +1586,10 @@ Por favor, sigue &lt;Hyperlink Command="{Binding OpenArticleCommand}"&gt;&lt;Run
<value>Mostrar menos</value>
</data>
<data name="Dialogs_DisabledService_msg_ExtraInfo">
<value>Algunas aplicaciones como los antivirus o los optimizadores de PC pueden interferir con los Servicios del Sistema que Proton VPN requiere para asegurar su conexión. Al hacer clic en Activar, está permitiendo que Windows reactive los Servicios de Proton VPN.&lt;LineBreak/&gt;Si el problema persiste, intente reiniciar su PC o reinstalar Proton VPN.</value>
<value>Algunas aplicaciones como los antivirus o los optimizadores de PC pueden interferir con los servicios del sistema que Proton VPN requiere para asegurar tu conexión. Al hacer clic en Activar, estás permitiendo que Windows reactiva los servicios de Proton VPN.&lt;LineBreak/&gt;Si el problema persiste, intenta reiniciar tu PC o reinstalar Proton VPN.</value>
</data>
<data name="Dialogs_DisabledService_msg_Info">
<value>Algunos componentes de Proton VPN pueden estar bloqueados o desactivados, impidiéndole conectarse. Haga clic en Activar para solucionarlo.&lt;LineBreak/&gt;Tenga en cuenta que esta operación requiere privilegios de administrador.</value>
<value>Algunos componentes de Proton VPN pueden estar bloqueados o desactivados, impidiéndote conectarte. Haz clic en Activar para solucionarlo.&lt;LineBreak/&gt;Ten en cuenta que esta operación requiere privilegios de administrador.</value>
</data>
<data name="Dialogs_DisconnectError_btn_DisableKillSwitch">
<value>Desactivar Kill Switch</value>
Expand Down Expand Up @@ -2342,7 +2342,7 @@ Por favor, sigue &lt;Hyperlink Command="{Binding OpenArticleCommand}"&gt;&lt;Run
<comment>The watermark text displayed in empty Server combo box in Profile window</comment>
</data>
<data name="Profiles_Profile_msg_DiscardChangesConfirm">
<value>Hay cambios de perfil no guardados. &lt;LineBreak/&gt;&lt;LineBreak/&gt;¿Estás seguro de que quieres descartarlos?</value>
<value>Hay cambios de perfil sin guardar. &lt;LineBreak/&gt;&lt;LineBreak/&gt;¿Estás seguro que quieres descartarlos?</value>
<comment>The message displayed in Question dialog when cancelling changes in Profile window.</comment>
</data>
<data name="Profiles_Profile_ttl_Create">
Expand Down
2 changes: 1 addition & 1 deletion src/ProtonVPN.Translations/Properties/Resources.fi-FI.resx
Original file line number Diff line number Diff line change
Expand Up @@ -2860,7 +2860,7 @@ Ota se käyttöön seuraamalla &lt;Hyperlink Command="{Binding OpenArticleComman
<comment>The label for Early Access toggle switch in General tab of Settings window</comment>
</data>
<data name="Settings_General_lbl_EarlyAccess_Info">
<value>Saat uusimmat päivitykset ensimmäisten joukossa. Huomoi, että varhaiset kehitysversiot saattavat olla epävakaita.</value>
<value>Saat uusimmat päivitykset ensimmäisten joukossa. Huomioi, että varhaiset kehitysversiot saattavat olla epävakaita.</value>
<comment>The description of Early Access setting displayed in the tooltip of ( i ) image next to the label for Early Access toggle switch in General tab of Settings window</comment>
</data>
<data name="Settings_General_lbl_Language">
Expand Down
30 changes: 15 additions & 15 deletions src/ProtonVPN.Translations/Properties/Resources.id-ID.resx
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@
<value>Langkah</value>
</data>
<data name="BugReport_lbl_Username">
<value>Nama Pengguna</value>
<value>Nama pengguna</value>
<comment>The label for the username in Issue Report window</comment>
</data>
<data name="BugReport_lbl_UsernamePlaceholder">
Expand Down Expand Up @@ -1719,10 +1719,10 @@ Mohon ikuti &lt;Hyperlink Command="{Binding OpenArticleCommand}"&gt;&lt;Run Text
<comment>The warning message displayed when P2P traffic is detected on servers not allowing it.</comment>
</data>
<data name="Dialogs_PortForwardingConfirmation_msg">
<value>Aktifkan Port Forwarding hanya ketika Anda perlu memastikan perlindungan privasi dan keamanan terkuat.&lt;LineBreak/&gt;&lt;LineBreak/&gt;&lt;Hyperlink Command="{Binding ReadPortForwardingRisksCommand}"&gt;Apakah saya memerlukan Port Forwarding?&lt;/Hyperlink&gt;</value>
<value>Aktifkan Penerusan Port hanya ketika Anda perlu memastikan perlindungan privasi dan keamanan terkuat.&lt;LineBreak/&gt;&lt;LineBreak/&gt;&lt;Hyperlink Command="{Binding ReadPortForwardingRisksCommand}"&gt;Apakah saya memerlukan Penerusan Port?&lt;/Hyperlink&gt;</value>
</data>
<data name="Dialogs_PortForwardingConfirmation_ttl">
<value>Aktifkan Port Forwarding?</value>
<value>Aktifkan Penerusan Port?</value>
</data>
<data name="Dialogs_Proxy_msg_ProxyDetected">
<value>Proton VPN mendeteksi keberadaan server proxy pada jaringan lokal Anda. Aplikasi Proton VPN tidak akan dapat melindungi lalu lintas data yang melintas melalui proxy ini. Dengan kata lain, koneksi Anda tidak akan sepenuhnya terlindungi sebagaimana mestinya.</value>
Expand Down Expand Up @@ -2200,7 +2200,7 @@ Mohon ikuti &lt;Hyperlink Command="{Binding OpenArticleCommand}"&gt;&lt;Run Text
<comment>The title of onboarding step 4 in Onboarding overlay of main app window</comment>
</data>
<data name="PortForwarding">
<value>Port Forwarding</value>
<value>Penerusan Port</value>
</data>
<data name="PortForwarding_lbl_ActivePort">
<value>Port yang aktif:</value>
Expand All @@ -2212,7 +2212,7 @@ Mohon ikuti &lt;Hyperlink Command="{Binding OpenArticleCommand}"&gt;&lt;Run Text
<value>Tentukan nomor port ini pada aplikasi BitTorrent Anda untuk memperoleh kecepatan yang lebih.</value>
</data>
<data name="PortForwarding_lbl_ServerWarning">
<value>Untuk menggunakan Port Forwarding, silakan &lt;Hyperlink Command="{Binding ConnectToBestP2PServerCommand}"&gt;hubungkan&lt;/Hyperlink&gt; diri Anda ke server yang mendukung P2P.</value>
<value>Untuk menggunakan Penerusan Port, silakan &lt;Hyperlink Command="{Binding ConnectToBestP2PServerCommand}"&gt;hubungkan&lt;/Hyperlink&gt; diri Anda ke server yang mendukung P2P.</value>
</data>
<data name="ProfileConnector_msg_MissingAuthCert">
<value>Proton VPN tidak dapat mengambil sertifikat autentikasi karena masalah jaringan.</value>
Expand Down Expand Up @@ -2246,7 +2246,7 @@ Mohon ikuti &lt;Hyperlink Command="{Binding OpenArticleCommand}"&gt;&lt;Run Text
<comment>The error message displayed in the Profile window when a profile name is empty</comment>
</data>
<data name="Profiles_Profile_Error_msg_NameExists">
<value>Nama profil telah digunakan</value>
<value>Nama profil sudah ada</value>
<comment>The error message displayed in the Profile window when a profile name is already used by another profile</comment>
</data>
<data name="Profiles_Profile_Error_msg_NameTooLong_Other">
Expand Down Expand Up @@ -2437,10 +2437,10 @@ Mohon ikuti &lt;Hyperlink Command="{Binding OpenArticleCommand}"&gt;&lt;Run Text
<comment>The text for the clickable option to enable the kill switch feature permanently (even when the VPN app is not running).</comment>
</data>
<data name="QuickSettings_btn_PortForwardingOff">
<value>Port Forwarding Nonaktif</value>
<value>Penerusan Port Nonaktif</value>
</data>
<data name="QuickSettings_btn_PortForwardingOn">
<value>Port Forwarding Aktif</value>
<value>Penerusan Port Aktif</value>
</data>
<data name="QuickSettings_btn_SecureCoreOff">
<value>Secure Core Nonaktif</value>
Expand Down Expand Up @@ -2690,19 +2690,19 @@ Mohon ikuti &lt;Hyperlink Command="{Binding OpenArticleCommand}"&gt;&lt;Run Text
<value>Adapter TUN</value>
</data>
<data name="Settings_Advanced_lbl_PortForwarding">
<value>Port Forwarding</value>
<value>Penerusan Port</value>
</data>
<data name="Settings_Advanced_lbl_PortForwardingInQuickSettings">
<value>Pintasan Port Forwarding</value>
<value>Pintasan Penerusan Port</value>
</data>
<data name="Settings_Advanced_lbl_PortForwardingInQuickSettings_Info">
<value>Akses pengaturan Port Forwarding dari menu Quick Settings</value>
<value>Akses pengaturan Penerusan Port dari menu Pengaturan Cepat</value>
</data>
<data name="Settings_Advanced_lbl_PortForwardingNotifications">
<value>Notifikasi Port Forwarding</value>
<value>Notifikasi Penerusan Port</value>
</data>
<data name="Settings_Advanced_lbl_PortForwardingNotifications_Info">
<value>Dapatkan notifikasi pada saat nomor port yang digunakan pada prosedur Port Forwarding diubah</value>
<value>Dapatkan notifikasi pada saat nomor port pada prosedur Penerusan Port berubah</value>
</data>
<data name="Settings_Advanced_lbl_PortForwarding_Info">
<value>Percepat akses torrent dan gaming Anda dengan memberikan izin kepada aplikasi lokal yang didukung untuk dapat dijangkau melalui internet. &lt;Hyperlink Command="{Binding LearnMoreAboutPortForwardingCommand}"&gt;Pelajari lebih lanjut&lt;/Hyperlink&gt;</value>
Expand Down Expand Up @@ -3056,7 +3056,7 @@ This setting instructs the Proton VPN to start automatically when the user logs
<value>Catatan: Gunakan tab browser baru dan/atau bersihkan cache Anda untuk memastikan konten baru muncul.</value>
</data>
<data name="Sidebar_Streaming_More">
<value>dan banyak lagi</value>
<value>dan masih banyak lagi</value>
</data>
<data name="StartMinimizedMode_val_Disabled">
<value>Dinonaktifkan</value>
Expand Down Expand Up @@ -3227,7 +3227,7 @@ This setting instructs the Proton VPN to start automatically when the user logs
<value>Atur akses jarak jauh ke perangkat pada jaringan lokal Anda</value>
</data>
<data name="Upsell_PortForwarding_Subtitle">
<value>Akses &lt;Bold&gt;port forwarding&lt;/Bold&gt; dengan VPN Plus</value>
<value>Akses &lt;Bold&gt;penerusan port&lt;/Bold&gt; dengan VPN Plus</value>
</data>
<data name="Upsell_PortForwarding_Title">
<value>Buat koneksi P2P Anda secepat kilat</value>
Expand Down
4 changes: 2 additions & 2 deletions src/ProtonVPN.Translations/Properties/Resources.it-IT.resx
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@
<comment>The label in Issue Report window</comment>
</data>
<data name="BugReport_lbl_IncludeLogs">
<value>Invia log errore</value>
<value>Invia i log degli errori</value>
<comment>The label in Issue Report window</comment>
</data>
<data name="BugReport_lbl_IncludeLogsInfo">
Expand Down Expand Up @@ -2500,7 +2500,7 @@ Segui le &lt;Hyperlink Command="{Binding OpenArticleCommand}"&gt;&lt;Run Text="t
<value>Tracker fermato</value>
</data>
<data name="QuickSettings_lbl_NetShieldStatsTrackersTooltip">
<value>I Trackers sono siti di terze parti che collezionano, memorizzano e vendono informazioni riguardanti la tua attività sul web.</value>
<value>I tracker sono siti di terze parti che raccolgono, memorizzano e vendono informazioni riguardanti la tua attività sul web.</value>
</data>
<data name="QuickSettings_lbl_NetShieldWarning">
<value>Se i siti web non si caricano, prova a disabilitare NetShield</value>
Expand Down
4 changes: 2 additions & 2 deletions src/ProtonVPN.Translations/Properties/Resources.ko-KR.resx
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@
<comment>The label for licensing information in About window</comment>
</data>
<data name="About_lnk_ReadLicense">
<value>더 알아보기</value>
<value>읽어보기</value>
<comment>The text of "Read here" hyperlink in About window to read the licensing information</comment>
</data>
<data name="About_lnk_Update">
Expand Down Expand Up @@ -230,7 +230,7 @@
<comment>The text displayed in Account window for NetShield</comment>
</data>
<data name="Account_lbl_NoLogs">
<value>엄격한 비로그 방침</value>
<value>엄격한 노-로그 방침</value>
<comment>The text displayed in Account window</comment>
</data>
<data name="Account_lbl_P2P">
Expand Down
6 changes: 3 additions & 3 deletions src/ProtonVPN.Translations/Properties/Resources.nb-NO.resx
Original file line number Diff line number Diff line change
Expand Up @@ -1628,7 +1628,7 @@ Vennligst følg &lt;Hyperlink Command="{Binding OpenArticleCommand}"&gt;&lt;Run
<comment>The text displayed in Disconnect modal window if TAP error is detected</comment>
</data>
<data name="Dialogs_DisconnectError_msg_TlsCertificateError">
<value>Det har oppstått et problem med å validere VPN-tjenersertifikatet, som kan tyde på at nettverkstilkoblingen tukles med eller at tjeneren du prøver å koble til, har et konfigurasjonsproblem. Få hjelp fra vår kundestøtte ved å sende en &lt;Hyperlink Command="{Binding ReportBugCommand}"&gt;&lt;Run Text="Issue Report"/&gt;&lt;/Hyperlink&gt;.</value>
<value>Det har oppstått et problem med å validere VPN-tjenersertifikatet, som kan tyde på at nettverkstilkoblingen tukles med eller at tjeneren du prøver å koble til, har et konfigurasjonsproblem. Få hjelp fra vår kundestøtte ved å sende en &lt;Hyperlink Command="{Binding ReportBugCommand}"&gt;&lt;Run Text="feilmelding"/&gt;&lt;/Hyperlink&gt;.</value>
<comment>The error description displayed in Disconnect modal window if VPN server certificate validation error has occurred</comment>
</data>
<data name="Dialogs_DoNotShowThisMessageAgain">
Expand Down Expand Up @@ -1806,7 +1806,7 @@ Vennligst følg &lt;Hyperlink Command="{Binding OpenArticleCommand}"&gt;&lt;Run
<comment>The text displayed in troubleshooting modal window</comment>
</data>
<data name="Dialogs_Troubleshooting_msg_Antivirus">
<value>&lt;Bold&gt;Innblanding fra Antivirus&lt;/Bold&gt; - Midlertidig deaktiver eller fjern antivirus-programvaren din.</value>
<value>&lt;Bold&gt;Antivirusforstyrrelser&lt;/Bold&gt; - Midlertidig deaktiver eller fjern antivirus-programvaren din.</value>
<comment>The text displayed in troubleshooting modal window</comment>
</data>
<data name="Dialogs_Troubleshooting_msg_Firewall">
Expand Down Expand Up @@ -2582,7 +2582,7 @@ Vennligst følg &lt;Hyperlink Command="{Binding OpenArticleCommand}"&gt;&lt;Run
<comment>The label for server load in Server Load popup. Popup opens by pressing mouse button on server load image in Countries tab of Sidebar section of main app window.</comment>
</data>
<data name="Servers_Load_lbl_LoadInfo">
<value>{0}% Belastning</value>
<value>{0}% belastning</value>
<comment>The tooltip text of server load image in Countries tab of Sidebar section of main app window, the server load in Connection section of Sidebar of main app window. The {0} is a placeholder for load percentage value.</comment>
</data>
<data name="Servers_Load_lbl_LoadInfo_NoData">
Expand Down
2 changes: 1 addition & 1 deletion src/ProtonVPN.Translations/Properties/Resources.ro-RO.resx
Original file line number Diff line number Diff line change
Expand Up @@ -3081,7 +3081,7 @@ This setting instructs the Proton VPN to start automatically when the user logs
<value>Tor</value>
</data>
<data name="Sidebar_FeaturesPopup_Tor_Desc">
<value>Direcționează traficul de internet prin rețeaua Tor. Mai lent, dar mai privat.</value>
<value>Direcționați traficul de internet prin rețeaua Tor. Mai lent, dar mai privat.</value>
</data>
<data name="Sidebar_Profiles_btn_Create">
<value>Creare profil</value>
Expand Down
90 changes: 45 additions & 45 deletions src/ProtonVPN.Translations/Properties/Resources.ru-RU.resx
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,7 @@
<value>{0} стран</value>
</data>
<data name="Countries_lbl_Other">
<value>{0} страны</value>
<value>{0} стран</value>
</data>
<data name="Country_val_AD">
<value>Андорра</value>
Expand Down Expand Up @@ -2292,7 +2292,7 @@
<comment>The error message displayed in the Profile window when a country is not selected</comment>
</data>
<data name="Profiles_Profile_Error_msg_GatewayEmpty">
<value>Пожалуйста, выберите шлюз</value>
<value>Выберите шлюз</value>
<comment>The error message displayed in the Profile window when a gateway is not selected</comment>
</data>
<data name="Profiles_Profile_Error_msg_NameEmpty">
Expand Down Expand Up @@ -2476,11 +2476,11 @@
<comment>The label for Profiles list in combo box in Quick Launch window</comment>
</data>
<data name="QuickSettings_btn_KillSwitchOff">
<value>Выключить Kill switch</value>
<value>Выключить Kill Switch</value>
<comment>The text for the clickable option to disable the kill switch feature.</comment>
</data>
<data name="QuickSettings_btn_KillSwitchOn">
<value>Включить Kill switch</value>
<value>Включить Kill Switch</value>
<comment>The text for the clickable option to enable the kill switch feature.</comment>
</data>
<data name="QuickSettings_btn_LearnMore">
Expand Down Expand Up @@ -2581,7 +2581,7 @@
<value>{0} защищённых серверов</value>
</data>
<data name="Secure_Servers_lbl_Other">
<value>{0} защищённого сервера</value>
<value>{0} защищённых серверов</value>
</data>
<data name="ServerType_val_B2B">
<value>Шлюзы</value>
Expand Down Expand Up @@ -2627,7 +2627,7 @@
<comment>The name of Tor server feature</comment>
</data>
<data name="Servers_FreeConnections">
<value>Бесплатные подключения (1)</value>
<value>Free подключения (1)</value>
</data>
<data name="Servers_Load_lbl_IP">
<value>IP-адрес сервера:</value>
Expand Down Expand Up @@ -2658,7 +2658,7 @@
<comment>The heading of Secure Core server info displayed in Server Load popup. The {0} is a placeholder for entry country, {1} - exit country. Popup opens by pressing mouse button on server load image in Countries tab of Sidebar section of main app window.</comment>
</data>
<data name="Servers_UpsellBanner">
<value>Get worldwide coverage with VPN Plus</value>
<value>Получите всемирное покрытие с помощью VPN Plus</value>
</data>
<data name="Servers_UpsellBanner_NotTheCountryYouWanted">
<value>Не та страна, которую вы хотели? Улучшите тариф для выбора любого сервера</value>
Expand Down Expand Up @@ -3213,25 +3213,25 @@ This setting instructs the Proton VPN to start automatically when the user logs
<comment>The text button of the Auto Reconnection tooltip that opens the Notification Settings</comment>
</data>
<data name="Upsell_Accelerator_Bullet1">
<value>Access faster, less crowded servers.</value>
<value>Получите доступ к более быстрым и менее загруженным серверам.</value>
</data>
<data name="Upsell_Accelerator_Bullet2">
<value>Increase connection speeds by up to 400% with &lt;Bold&gt;VPN Accelerator&lt;/Bold&gt;.</value>
<value>Увеличьте скорость подключения до 400 % с помощью &lt;Bold&gt;VPN Accelerator&lt;/Bold&gt;.</value>
</data>
<data name="Upsell_Accelerator_Bullet3">
<value>Improved speed and stability when connected to distant servers.</value>
<value>Повышенная скорость и стабильность при подключении к удаленным серверам.</value>
</data>
<data name="Upsell_Accelerator_Title">
<value>Browse at even higher speeds (up to 10 Gbps)</value>
<value>Просматривайте веб-страницы на еще более высоких скоростях (до 10 Гбит/с).</value>
</data>
<data name="Upsell_Countries_AccessGeoblockedContent">
<value>Access geoblocked content</value>
<value>Получите доступ к содержимому, заблокированному по географическому признаку</value>
</data>
<data name="Upsell_Countries_ChooseAnyLocation">
<value>Choose any location</value>
<value>Выберите любое местоположение</value>
</data>
<data name="Upsell_Countries_HigherVpnSpeed">
<value>Even higher VPN speed</value>
<value>Еще более высокая скорость VPN</value>
</data>
<data name="Upsell_Countries_StreamMovies">
<value>Смотрите любимые фильмы</value>
Expand All @@ -3245,19 +3245,19 @@ This setting instructs the Proton VPN to start automatically when the user logs
<comment>The message displayed in plus upgrade modal window. {0} is a placeholder for "X secure servers" (Secure_Servers_lbl) and {1} for "X countries" (Countries_lbl).</comment>
</data>
<data name="Upsell_Country_Bullet1_One">
<value>Connect to {0} country</value>
<value>Подключайтесь к {0} стране</value>
</data>
<data name="Upsell_Country_Bullet1_Few">
<value>Connect to {0} countries</value>
<value>Подключайтесь к {0} странам</value>
</data>
<data name="Upsell_Country_Bullet1_Many">
<value>Connect to {0} countries</value>
<value>Подключайтесь к {0} странам</value>
</data>
<data name="Upsell_Country_Bullet1_Other">
<value>Connect to {0} countries</value>
<value>Подключайтесь к {0} странам</value>
</data>
<data name="Upsell_Country_Bullet2">
<value>Higher speeds (10 Gbps)</value>
<value>Более высокие скорости (10 Гбит/с)</value>
</data>
<data name="Upsell_Country_Bullet3">
<value>Смотрите любимые фильмы</value>
Expand All @@ -3269,44 +3269,44 @@ This setting instructs the Proton VPN to start automatically when the user logs
<value>30-дневная гарантия возврата денег</value>
</data>
<data name="Upsell_Country_Subtitle">
<value>Unlock &lt;Bold&gt;country selection&lt;/Bold&gt; with VPN Plus</value>
<value>Разблокируйте &lt;Bold&gt;выбор страны&lt;/Bold&gt; с VPN Plus</value>
</data>
<data name="Upsell_Country_Title">
<value>Хотите выбрать определенную страну?</value>
</data>
<data name="Upsell_CustomDns_Bullet1">
<value>Connect to VPN with your &lt;Bold&gt;custom domain name system (DNS)&lt;/Bold&gt;</value>
<value>Подключайтесь к VPN с помощью своей &lt;Bold&gt;системы пользовательских доменных имен (DNS)&lt;/Bold&gt;</value>
</data>
<data name="Upsell_CustomDns_Bullet2">
<value>Save frequently used connections with &lt;Bold&gt;profiles&lt;/Bold&gt;</value>
<value>Сохраняйте часто используемые подключения с помощью &lt;Bold&gt;профилей&lt;/Bold&gt;</value>
</data>
<data name="Upsell_CustomDns_Bullet3">
<value>Get faster access to your profiles with &lt;Bold&gt;Quick Connect&lt;/Bold&gt;</value>
<value>Получите более быстрый доступ к своим профилям с помощью &lt;Bold&gt;Быстрого подключения&lt;/Bold&gt;</value>
</data>
<data name="Upsell_CustomDns_Title">
<value>Unlock advanced VPN customization</value>
<value>Разблокируйте расширенные настройки VPN</value>
</data>
<data name="Upsell_FreeConnections_Locations">
<value>Free server locations ({0})</value>
<value>Месторасположение серверов Free ({0})</value>
<comment>{0} represents a number of free server locations.</comment>
</data>
<data name="Upsell_FreeConnections_Subtitle">
<value>Proton Free automatically connects you to the fastest available server. This will normally be the closest server to your location.</value>
<value>Proton Free автоматически подключает вас к самому быстрому из доступных серверов. Обычно это ближайший к вашему местоположению сервер.</value>
</data>
<data name="Upsell_FreeConnections_Title">
<value>Бесплатные подключения</value>
</data>
<data name="Upsell_ModerateNat_Bullet1">
<value>Improve online gaming and video call performance</value>
<value>Повысьте качество онлайн-игр и видеозвонков</value>
</data>
<data name="Upsell_ModerateNat_Bullet2">
<value>NAT type 2 (moderate) optimizes speed and stability by enabling direct connections between devices</value>
<value>NAT2 (умеренное) оптимизирует скорость и стабильность, обеспечивая прямое соединение между устройствами</value>
</data>
<data name="Upsell_ModerateNat_Subtitle">
<value>Unlock &lt;Bold&gt;NAT type 2&lt;/Bold&gt; with VPN Plus</value>
<value>Разблокируйте &lt;Bold&gt;NAT2&lt;/Bold&gt; с помощью VPN Plus</value>
</data>
<data name="Upsell_ModerateNat_Title">
<value>Level up your gaming experience</value>
<value>Повысьте уровень своего игрового опыта</value>
</data>
<data name="Upsell_Netshield_BlockAds">
<value>Блокируйте рекламу и трекеры</value>
Expand Down Expand Up @@ -3340,38 +3340,38 @@ This setting instructs the Proton VPN to start automatically when the user logs
<comment>The title in "allow non-standard ports" modal</comment>
</data>
<data name="Upsell_Plan_Business_Info">
<value>Доступно с VPN для бизнеса.</value>
<value>Доступно с VPN Business.</value>
<comment>The tooltip text of the business plan badge</comment>
</data>
<data name="Upsell_PortForwarding_Bullet1">
<value>Improve your peer-to-peer download speeds</value>
<value>Повысьте скорость одноранговых загрузок.</value>
</data>
<data name="Upsell_PortForwarding_Bullet2">
<value>Connect to online gaming servers and host multiplayer games</value>
<value>Подключайтесь к игровым онлайн-серверам и организуйте многопользовательские игры</value>
</data>
<data name="Upsell_PortForwarding_Bullet3">
<value>Set up remote access to devices on your local network</value>
<value>Настройте удаленный доступ к устройствам в локальной сети</value>
</data>
<data name="Upsell_PortForwarding_Subtitle">
<value>Unlock &lt;Bold&gt;port forwarding&lt;/Bold&gt; with VPN Plus</value>
<value>Разблокируйте &lt;Bold&gt;переадресацию портов&lt;/Bold&gt; с VPN Plus</value>
</data>
<data name="Upsell_PortForwarding_Title">
<value>Supercharge your P2P connections</value>
<value>Повысьте эффективность своих подключений P2P</value>
</data>
<data name="Upsell_Profiles_Bullet1">
<value>Save your preferred server, city, or country.</value>
<value>Сохраните предпочитаемый сервер, город или страну.</value>
</data>
<data name="Upsell_Profiles_Bullet2">
<value>Set custom protocols and premium VPN features.</value>
<value>Настройка пользовательских протоколов и платных функций VPN.</value>
</data>
<data name="Upsell_Profiles_Bullet3">
<value>Set up auto-connect for even faster access.</value>
<value>Настройте автоподключение для еще более быстрого доступа.</value>
</data>
<data name="Upsell_Profiles_Subtitle">
<value>Unlock &lt;Bold&gt;profiles&lt;/Bold&gt; with VPN Plus</value>
<value>Разблокировать &lt;Bold&gt;профили&lt;/Bold&gt; с VPN Plus</value>
</data>
<data name="Upsell_Profiles_Title">
<value>Get quick access to your frequent connections</value>
<value>Получите быстрый доступ к своим частым подключениям</value>
</data>
<data name="Upsell_SecureCore_ExtraEncryption">
<value>Добавьте еще один уровень шифрования к своему подключению к VPN</value>
Expand All @@ -3389,16 +3389,16 @@ This setting instructs the Proton VPN to start automatically when the user logs
<value>Двойное шифрование с Secure Core</value>
</data>
<data name="Upsell_SplitTunneling_Bullet1">
<value>Split your traffic into VPN and non-VPN tunnels</value>
<value>Разделите трафик на тунели VPN и тунели без VPN</value>
</data>
<data name="Upsell_SplitTunneling_Bullet2">
<value>Let trusted apps and IP addresses bypass VPN for faster speeds</value>
<value>Позволяйте доверенным приложениям и адресам IP обходить VPN для повышения скорости.</value>
</data>
<data name="Upsell_SplitTunneling_Bullet3">
<value>Access both home and local content when browsing from abroad</value>
<value>Получайте доступ к домашнему и местному содержимому при просмотре сайтов из-за границы</value>
</data>
<data name="Upsell_SplitTunneling_Subtitle">
<value>Unlock &lt;Bold&gt;split tunneling&lt;/Bold&gt; with VPN Plus</value>
<value>Разблокируйте &lt;Bold&gt;раздельное туннелирование&lt;/Bold&gt; с VPN Plus</value>
</data>
<data name="Upsell_SplitTunneling_Title">
<value>Получите лучшее из обоих миров</value>
Expand Down
8 changes: 4 additions & 4 deletions src/ProtonVPN.Translations/Properties/Resources.tr-TR.resx
Original file line number Diff line number Diff line change
Expand Up @@ -1582,7 +1582,7 @@
<value>Ayrıntılı bilgi alın</value>
</data>
<data name="Dialogs_DisabledService_btn_ShowLess">
<value>Daha az göster</value>
<value>Daha az görüntüle</value>
</data>
<data name="Dialogs_DisabledService_msg_ExtraInfo">
<value>Antivirüs ya da bilgisayar iyileştirici gibi bazı uygulamalar, Proton VPN uygulamasının bağlantınızın güvenliğini sağlamak için kullandığı sistem hizmetlerini etkileyebilir. Aç düğmesine tıkladığınızda, Windows'un Proton VPN hizmetlerini yeniden açmasına izin vermiş olursunuz.&lt;LineBreak/&gt;Sorun sürerse, bilgisayarınızı yeniden başlatmayı ya da Proton VPN uygulamasını yeniden kurmayı deneyin.</value>
Expand Down Expand Up @@ -1631,7 +1631,7 @@
<comment>The error description displayed in Disconnect modal window if VPN server certificate validation error has occurred</comment>
</data>
<data name="Dialogs_DoNotShowThisMessageAgain">
<value>Bu iletiyi bir daha gösterme</value>
<value>Bu ileti bir daha görüntülenmesin</value>
</data>
<data name="Dialogs_EnableSmartProtocol_btn_Enable">
<value>Aç</value>
Expand Down Expand Up @@ -2072,7 +2072,7 @@
<value>Secure Core kullanılsın</value>
</data>
<data name="Modal_DiscourageSecureCore_DoNotShowItAgain">
<value>Bir daha gösterme</value>
<value>Bir daha görüntülenmesin</value>
</data>
<data name="Modal_DiscourageSecureCore_LearnMore">
<value>Ayrıntılı bilgi alın</value>
Expand Down Expand Up @@ -2891,7 +2891,7 @@ This setting instructs the Proton VPN to start automatically when the user logs
<comment>The text of Reconnect hyperlink next to Reconnect Required message in Settings window (reconnects to same VPN server)</comment>
</data>
<data name="Settings_msg_ReconnectRequired">
<value>Bazı değişikliklerin etkili olması için yeniden bağlanılması gerekli.</value>
<value>Bazı değişikliklerin etkili olması için bağlantının yeniden kurulması gerekli.</value>
<comment>The message displayed on the bottom of Settings window if any of settings changes requires VPN to be reconnected to take effect</comment>
</data>
<data name="Settings_ttl">
Expand Down
30 changes: 15 additions & 15 deletions src/ProtonVPN.Translations/Properties/Resources.zh-TW.resx
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@
<comment>The title of About window</comment>
</data>
<data name="Account_btn_ManageSubscription">
<value>管理訂閱</value>
<value>管理訂購授權</value>
<comment>The text on Manage subscription button in Account window (auto login to a subscription upgrade page)</comment>
</data>
<data name="Account_lbl_AccessContent">
Expand Down Expand Up @@ -470,7 +470,7 @@
<comment>The VPN status displayed in Pinging overlay of main app window</comment>
</data>
<data name="Connecting_VpnStatus_val_RetrievingConfiguration">
<value>建立VPN隧道</value>
<value>創建VPN隧道</value>
<comment>The VPN status displayed in Connecting overlay of main app window</comment>
</data>
<data name="Connecting_VpnStatus_val_Waiting">
Expand All @@ -490,7 +490,7 @@
<comment>The beginning of text for VPN server being connected to in Connecting overlay of main app window. It shall be translated as a text before imaginary placeholder {0} in the text string "Connecting to {0}". If translated text suppose to not include any text before the placeholder {0} then please leave it empty. Do not include placeholder {0} into translated text.</comment>
</data>
<data name="Connecting_lbl_ConnectingTo_1_SecureCore">
<value>建立中</value>
<value>創建中</value>
<comment>The beginning of text for Secure Core VPN server being connected to in Connecting overlay of main app window. It shall be translated as a text before imaginary placeholder {0} in the text string "Creating {0} connection". If translated text suppose to not include any text before the placeholder {0} then please leave it empty. Do not include placeholder {0} into translated text.</comment>
</data>
<data name="Connecting_lbl_ConnectingTo_2">
Expand Down Expand Up @@ -1756,15 +1756,15 @@
<comment>The text right before the subscriber benefits list in the Subscription Expired window</comment>
</data>
<data name="Dialogs_SubscriptionExpired_Reconnected_Subtitle">
<value>您的訂閱已降級,因此我們正重新連線到最快速的可用伺服器。</value>
<value>您的訂購授權已降級,因此我們正重新連線到最快速的可用伺服器。</value>
<comment>The subtitle of the Subscription Expired window when the user is reconnected</comment>
</data>
<data name="Dialogs_SubscriptionExpired_Subtitle">
<value>您的訂閱已降級。</value>
<value>您的訂購授權已降級。</value>
<comment>The subtitle of the Subscription Expired window</comment>
</data>
<data name="Dialogs_SubscriptionExpired_Title">
<value>您的 VPN 訂閱方案已到期</value>
<value>您的 VPN 訂購授權已到期</value>
<comment>The title of the Subscription Expired window</comment>
</data>
<data name="Dialogs_SubscriptionExpired_Upgrade">
Expand Down Expand Up @@ -1953,7 +1953,7 @@
<comment>The text of hyperlink in Need Help popup of Login window (opens web page with information regarding login issues)</comment>
</data>
<data name="Login_lnk_CreateAccount">
<value>建立帳號</value>
<value>創建帳號</value>
<comment>The text of hyperlink for creating account in Login window</comment>
</data>
<data name="Login_lnk_ForgotUsername">
Expand Down Expand Up @@ -2128,15 +2128,15 @@
<comment>The description of the Maximum Device Limit notification when the user can upgrade the subscription plan</comment>
</data>
<data name="Notifications_SubscriptionExpired_Description">
<value>您的訂閱已降級。再次升級以享用所有功能。</value>
<value>您的訂購授權已降級。再次升級以享用所有功能。</value>
<comment>The description of the Subscription Expired notification</comment>
</data>
<data name="Notifications_SubscriptionExpired_Reconnected_Description">
<value>您的訂閱已降級,因此我們正重新連線到最快速的可用伺服器。再次升級以享用所有功能。</value>
<value>您的訂購授權已降級,因此我們正重新連線到最快速的可用伺服器。再次升級以享用所有功能。</value>
<comment>The description of the Subscription Expired notification when the user is reconnected</comment>
</data>
<data name="Notifications_SubscriptionExpired_Title">
<value>您的 VPN 訂閱已逾期</value>
<value>您的 VPN 訂購授權已逾期</value>
<comment>The title of the Subscription Expired notification</comment>
</data>
<data name="Notifications_Update_lnk_Restart">
Expand Down Expand Up @@ -2325,7 +2325,7 @@
<comment>The message displayed in Question dialog when cancelling changes in Profile window.</comment>
</data>
<data name="Profiles_Profile_ttl_Create">
<value>建立設定檔</value>
<value>創建設定檔</value>
<comment>The title of Profile window when creating new profile</comment>
</data>
<data name="Profiles_Profile_ttl_Edit">
Expand All @@ -2337,7 +2337,7 @@
<comment>The text on Close button in Profiles window</comment>
</data>
<data name="Profiles_btn_Create">
<value>建立配置檔</value>
<value>創建配置檔</value>
<comment>The text on create profile button on Profile window (opens new profile window)</comment>
</data>
<data name="Profiles_btn_Troubleshoot">
Expand Down Expand Up @@ -3024,7 +3024,7 @@ This setting instructs the Proton VPN to start automatically when the user logs
<value>一鍵將您的網路流量路由改為經由 Tor 網路傳送。速度較慢,但更隱密。</value>
</data>
<data name="Sidebar_Profiles_btn_Create">
<value>建立設定檔</value>
<value>創建設定檔</value>
<comment>The text of button for creating new profile on Profiles tab of Sidebar section of main app window (opens new profile window)</comment>
</data>
<data name="Sidebar_Profiles_lnk_Manage">
Expand Down Expand Up @@ -3111,7 +3111,7 @@ This setting instructs the Proton VPN to start automatically when the user logs
<value>存取地理封鎖內容</value>
</data>
<data name="Upsell_Countries_ChooseAnyLocation">
<value>選擇任何地址</value>
<value>選擇任何位址</value>
</data>
<data name="Upsell_Countries_HigherVpnSpeed">
<value>甚至更快虛擬私有網速度</value>
Expand Down Expand Up @@ -3266,7 +3266,7 @@ This setting instructs the Proton VPN to start automatically when the user logs
<value>將您的流量分為 VPN 與非 VPN 通道</value>
</data>
<data name="Upsell_SplitTunneling_Bullet2">
<value>讓受信任的應用程式與 IP 地址繞過 VPN 以取得更快的速度</value>
<value>讓受信任的應用程式與 IP 位址繞過 VPN 以取得更快的速度</value>
</data>
<data name="Upsell_SplitTunneling_Bullet3">
<value>從國外瀏覽時可以存取家庭與區域內容</value>
Expand Down
17 changes: 7 additions & 10 deletions src/Tests/ProtonVPN.UI.Tests/TestsHelper/TestMonitorHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,14 @@ public static async Task ReportDurationAsync(string name, string description)

public static async Task ReportTestStatusAsync(string name, string description)
{
if (IsMonitoringState)
TestStatus status = TestContext.CurrentContext.Result.Outcome.Status;
if (status == TestStatus.Passed)
{
TestStatus status = TestContext.CurrentContext.Result.Outcome.Status;
if (status == TestStatus.Passed)
{
await IncrementMetricAsync(name, description, 0);
}
else if (status == TestStatus.Failed)
{
await IncrementMetricAsync(name, description, 1);
}
await IncrementMetricAsync(name, description, 0);
}
else if (IsMonitoringState && status == TestStatus.Failed)
{
await IncrementMetricAsync(name, description, 1);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,9 @@
*/

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Win32;
using ProtonVPN.Common.Extensions;
using ProtonVPN.Common.Helpers;
using SysPath = System.IO.Path;
Expand All @@ -34,9 +32,6 @@ namespace ProtonVPN.Update.Files.UpdatesDirectory
/// </summary>
internal class UpdatesDirectory : IUpdatesDirectory
{
private const string LOCAL_APP_DATA_REGISTRY_KEY = "Local AppData";
private const string LOCAL_APP_DATA_REGISTRY_PATH = @"HKEY_USERS\{0}\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders";

private readonly string _path;
private readonly Version _currentVersion;

Expand All @@ -60,10 +55,6 @@ public string Path
public void Cleanup()
{
PathCleanup(_path);
foreach (string localAppDataFolder in GetAllLocalAppDataPaths())
{
DeletePath(SysPath.Combine(localAppDataFolder, "ProtonVPN", "Updates"));
}
}

public void PathCleanup(string path)
Expand Down Expand Up @@ -107,54 +98,5 @@ private static Version FileVersion(string path)
? version.Normalized()
: new Version(0, 0, 0);
}

private IEnumerable<string> GetAllLocalAppDataPaths()
{
List<string> localAppDataFolders = new();
try
{
string[] systemUserIds = Registry.Users.GetSubKeyNames();
foreach (string systemUserId in systemUserIds)
{
string localAppDataFolder = GetUserLocalAppDataPath(systemUserId);
if (!string.IsNullOrWhiteSpace(localAppDataFolder))
{
localAppDataFolders.Add(localAppDataFolder);
}
}
}
catch
{
}
return localAppDataFolders;
}

private string GetUserLocalAppDataPath(string systemUserId)
{
try
{
return (string)Registry.GetValue(
string.Format(LOCAL_APP_DATA_REGISTRY_PATH, systemUserId), LOCAL_APP_DATA_REGISTRY_KEY, null);
}
catch
{
return null;
}
}

private void DeletePath(string path)
{
try
{
bool pathExists = Directory.Exists(path);
if (pathExists)
{
Directory.Delete(path, recursive: true);
}
}
catch
{
}
}
}
}