/*
* Copyright (c) 2025 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 .
*/
using ProtonVPN.Client.Logic.Auth.Contracts.Models;
using ProtonVPN.Client.Logic.Users.Contracts.Messages;
using ProtonVPN.Client.Settings.Contracts;
using ProtonVPN.Client.Settings.Contracts.Enums;
using ProtonVPN.Client.Settings.Contracts.Models;
using ProtonVPN.Client.Settings.Repositories.Contracts;
using ProtonVPN.Common.Core.Dns;
using ProtonVPN.Common.Core.Extensions;
using ProtonVPN.Common.Core.Networking;
namespace ProtonVPN.Client.Settings;
public class UserSettings : GlobalSettings, IUserSettings
{
private readonly IUserSettingsCache _userCache;
public string? Username
{
get => _userCache.GetReferenceType(SettingEncryption.Encrypted);
set => _userCache.SetReferenceType(value, SettingEncryption.Encrypted);
}
public string? UserDisplayName
{
get => _userCache.GetReferenceType(SettingEncryption.Encrypted);
set => _userCache.SetReferenceType(value, SettingEncryption.Encrypted);
}
public string? UserEmail
{
get => _userCache.GetReferenceType(SettingEncryption.Encrypted);
set => _userCache.SetReferenceType(value, SettingEncryption.Encrypted);
}
public DateTimeOffset? UserCreationDateUtc
{
get => _userCache.GetValueType(SettingEncryption.Encrypted);
set => _userCache.SetValueType(value, SettingEncryption.Encrypted);
}
public string Theme
{
get => _userCache.GetReferenceType(SettingEncryption.Unencrypted) ?? DefaultSettings.Theme;
set => _userCache.SetReferenceType(value, SettingEncryption.Unencrypted);
}
public int WindowWidth
{
get => _userCache.GetValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.WindowWidth;
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public int WindowHeight
{
get => _userCache.GetValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.WindowHeight;
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public int? WindowXPosition
{
get => _userCache.GetValueType(SettingEncryption.Unencrypted);
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public int? WindowYPosition
{
get => _userCache.GetValueType(SettingEncryption.Unencrypted);
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public bool IsWindowMaximized
{
get => _userCache.GetValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.IsWindowMaximized;
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public bool IsNavigationPaneOpened
{
get => _userCache.GetValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.IsNavigationPaneOpened;
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public int SidebarWidth
{
get => _userCache.GetValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.SidebarWidth;
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public bool IsRecentsPaneOpened
{
get => _userCache.GetValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.IsRecentsPaneOpened;
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public bool IsConnectionDetailsPaneOpened
{
get => _userCache.GetValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.IsConnectionDetailsPaneOpened;
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public bool AreProtonProtocolsEnabled
{
get => _userCache.GetValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.AreProtonProtocolsEnabled;
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public VpnProtocol VpnProtocol
{
get => _userCache.GetValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.VpnProtocol;
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public OpenVpnAdapter OpenVpnAdapter
{
get => _userCache.GetValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.OpenVpnAdapter;
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public VpnPlan VpnPlan
{
get => _userCache.GetValueType(SettingEncryption.Encrypted) ?? DefaultSettings.VpnPlan;
set => _userCache.SetValueType(value, SettingEncryption.Encrypted);
}
public int MaxDevicesAllowed
{
get => _userCache.GetValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.MaxDevicesAllowed;
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public ConnectionAsymmetricKeyPair? ConnectionKeyPair
{
get => _userCache.GetValueType(SettingEncryption.Encrypted);
set => _userCache.SetValueType(value, SettingEncryption.Encrypted);
}
public ConnectionCertificate? ConnectionCertificate
{
get => _userCache.GetValueType(SettingEncryption.Encrypted);
set => _userCache.SetValueType(value, SettingEncryption.Encrypted);
}
public NatType NatType
{
get
{
if (VpnPlan.IsPaid)
{
return _userCache.GetValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.NatType;
}
return DefaultSettings.NatType;
}
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public bool IsVpnAcceleratorEnabled
{
get
{
if (VpnPlan.IsPaid)
{
return _userCache.GetValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.IsVpnAcceleratorEnabled;
}
return DefaultSettings.IsVpnAcceleratorEnabled;
}
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public bool IsLocalAreaNetworkAccessEnabled
{
get
{
if (VpnPlan.IsPaid)
{
return _userCache.GetValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.IsLocalAreaNetworkAccessAllowed(true);
}
// Free users can't use this feature
return false;
}
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public bool IsLocalDnsEnabled
{
// Get the value from cache if it exists, otherwise set it based on the DnsBlockMode. To be removed in future versions.
get
{
bool? isLocalDnsEnabled = _userCache.GetValueType(SettingEncryption.Unencrypted);
if (isLocalDnsEnabled is null)
{
isLocalDnsEnabled = DnsBlockMode == DnsBlockMode.Callout;
_userCache.SetValueType(isLocalDnsEnabled, SettingEncryption.Unencrypted);
}
return isLocalDnsEnabled.Value;
}
// get => _userCache.GetValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.IsLocalDnsEnabled;
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public bool IsNotificationEnabled
{
get => _userCache.GetValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.IsNotificationEnabled;
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public bool IsShareStatisticsEnabled
{
get => _userCache.GetValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.IsShareStatisticsEnabled;
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public bool IsIpv6LeakProtectionEnabled
{
get => _userCache.GetValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.IsIpv6LeakProtectionEnabled;
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public bool IsIpv6Enabled
{
get => _userCache.GetValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.IsIpv6Enabled;
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public bool IsCustomDnsServersEnabled
{
get
{
if (VpnPlan.IsPaid)
{
return _userCache.GetValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.IsCustomDnsServersEnabled;
}
return DefaultSettings.IsCustomDnsServersEnabled;
}
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public List CustomDnsServersList
{
get => _userCache.GetListValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.CustomDnsServersList;
set => _userCache.SetListValueType(value, SettingEncryption.Unencrypted);
}
public bool IsAutoConnectEnabled
{
get => _userCache.GetValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.IsAutoConnectEnabled;
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public bool IsNetShieldEnabled
{
get
{
if (VpnPlan.IsPaid)
{
return _userCache.GetValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.IsNetShieldEnabled(true);
}
return DefaultSettings.IsNetShieldEnabled(false);
}
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public NetShieldMode NetShieldMode
{
get => _userCache.GetValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.NetShieldMode;
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public bool IsPortForwardingEnabled
{
get
{
if (VpnPlan.IsPaid)
{
return _userCache.GetValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.IsPortForwardingEnabled;
}
return DefaultSettings.IsPortForwardingEnabled;
}
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public bool IsPortForwardingNotificationEnabled
{
get => _userCache.GetValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.IsPortForwardingNotificationEnabled;
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public bool IsSplitTunnelingEnabled
{
get
{
if (VpnPlan.IsPaid)
{
return _userCache.GetValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.IsSplitTunnelingEnabled;
}
return DefaultSettings.IsSplitTunnelingEnabled;
}
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public bool IsSmartReconnectEnabled
{
get => _userCache.GetValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.IsSmartReconnectEnabled;
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public bool IsUserSettingsMigrationDone
{
get => _userCache.GetValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.IsUserSettingsMigrationDone;
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public SplitTunnelingMode SplitTunnelingMode
{
get => _userCache.GetValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.SplitTunnelingMode;
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public List SplitTunnelingStandardAppsList
{
get => _userCache.GetListValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.SplitTunnelingAppsList();
set => _userCache.SetListValueType(value, SettingEncryption.Unencrypted);
}
public List SplitTunnelingInverseAppsList
{
get => _userCache.GetListValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.SplitTunnelingAppsList();
set => _userCache.SetListValueType(value, SettingEncryption.Unencrypted);
}
public List SplitTunnelingStandardIpAddressesList
{
get => _userCache.GetListValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.SplitTunnelingIpAddressesList;
set => _userCache.SetListValueType(value, SettingEncryption.Unencrypted);
}
public List SplitTunnelingInverseIpAddressesList
{
get => _userCache.GetListValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.SplitTunnelingIpAddressesList;
set => _userCache.SetListValueType(value, SettingEncryption.Unencrypted);
}
public List Ipv6Fragments
{
get => _userCache.GetListReferenceType(SettingEncryption.Unencrypted) ?? DefaultSettings.Ipv6Fragments;
set => _userCache.SetListReferenceType(value, SettingEncryption.Unencrypted);
}
public string? LastLogicalsStatusId
{
get => _userCache.GetReferenceType(SettingEncryption.Unencrypted);
set => _userCache.SetReferenceType(value, SettingEncryption.Unencrypted);
}
public ChangeServerAttempts ChangeServerAttempts
{
get => _userCache.GetValueType(SettingEncryption.Encrypted) ?? DefaultSettings.ChangeServerAttempts;
set => _userCache.SetValueType(value, SettingEncryption.Encrypted);
}
public DefaultConnection DefaultConnection
{
get
{
if (VpnPlan.IsPaid)
{
return _userCache.GetValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.DefaultConnection;
}
return DefaultSettings.DefaultConnection;
}
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public bool WasWelcomeOverlayDisplayed
{
get => SkipOnboarding || (_userCache.GetValueType(SettingEncryption.Unencrypted) ?? false);
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public bool WasWelcomePlusOverlayDisplayed
{
get => SkipOnboarding || (_userCache.GetValueType(SettingEncryption.Unencrypted) ?? false);
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public bool WasWelcomeUnlimitedOverlayDisplayed
{
get => SkipOnboarding || (_userCache.GetValueType(SettingEncryption.Unencrypted) ?? false);
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public bool WasWelcomeB2BOverlayDisplayed
{
get => SkipOnboarding || (_userCache.GetValueType(SettingEncryption.Unencrypted) ?? false);
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public DateTimeOffset LogicalsLastModifiedDate
{
get => _userCache.GetValueType(SettingEncryption.Encrypted)?.Max(DateTimeOffset.UnixEpoch) ?? DefaultSettings.LogicalsLastModifiedDate;
set => _userCache.SetValueType(value.Max(DateTimeOffset.UnixEpoch), SettingEncryption.Encrypted);
}
public bool IsP2PInfoBannerDismissed
{
get => SkipOnboarding || (_userCache.GetValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.IsP2PInfoBannerDismissed);
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public bool IsSecureCoreInfoBannerDismissed
{
get => SkipOnboarding || (_userCache.GetValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.IsSecureCoreInfoBannerDismissed);
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public bool IsTorInfoBannerDismissed
{
get => SkipOnboarding || (_userCache.GetValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.IsTorInfoBannerDismissed);
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public bool IsGatewayInfoBannerDismissed
{
get => SkipOnboarding || (_userCache.GetValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.IsGatewayInfoBannerDismissed);
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public int LastSeenWhatsNewOverlayVersion
{
get
{
if (SkipOnboarding)
{
return DefaultSettings.WhatsNewOverlayVersion;
}
int? version = _userCache.GetValueType(SettingEncryption.Unencrypted);
if (version is null)
{
version = DefaultSettings.WhatsNewOverlayVersion;
_userCache.SetValueType(version.Value, SettingEncryption.Unencrypted);
}
return version.Value;
}
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public DateTimeOffset? LastSettingsHeartbeatTimeUtc
{
get => _userCache.GetValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.LastSettingsHeartbeatTimeUtc;
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public DateTimeOffset LastP2PWarningNotificationUtcDate
{
get => _userCache.GetValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.LastP2PTrafficNotificationUtcDate;
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public DateTimeOffset LastStreamingWarningNotificationUtcDate
{
get => _userCache.GetValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.LastStreamingNotificationUtcDate;
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public List ExcludedLocationsList
{
get => _userCache.GetListValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.ExcludedLocationsList;
set => _userCache.SetListValueType(value, SettingEncryption.Unencrypted);
}
public bool WasExcludedLocationsSmartDiscoveryPromptDisplayed
{
get => SkipOnboarding || (_userCache.GetValueType(SettingEncryption.Unencrypted) ?? false);
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public bool WasExcludedLocationsTeachingTipDisplayed
{
get => SkipOnboarding || (_userCache.GetValueType(SettingEncryption.Unencrypted) ?? false);
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
[Obsolete("Use IsLocalDnsEnabled instead. DnsBlockMode is maintained in order to migrate the value for existing users.")]
public DnsBlockMode DnsBlockMode
{
get => _userCache.GetValueType(SettingEncryption.Unencrypted) ?? DefaultSettings.DnsBlockMode;
set => _userCache.SetValueType(value, SettingEncryption.Unencrypted);
}
public UserSettings(IGlobalSettingsCache globalSettingsCache, IUserSettingsCache userSettingsCache)
: base(globalSettingsCache)
{
_userCache = userSettingsCache;
}
}