mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-06-30 05:56:08 +03:00
Compare commits
19 Commits
4.5.0.0
...
bugfix/hid
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dad2dc0ab0 | ||
|
|
a22c08a41d | ||
|
|
10ea9b418a | ||
|
|
e39efb1d68 | ||
|
|
7db84122f9 | ||
|
|
84ad167ab4 | ||
|
|
ed7e217a6b | ||
|
|
c1b0d4a4a7 | ||
|
|
2f84e24353 | ||
|
|
f73586185b | ||
|
|
653ffb9a68 | ||
|
|
fe8c2d157a | ||
|
|
86367a1276 | ||
|
|
b0fcf92ada | ||
|
|
283b6ebf81 | ||
|
|
d0a7fc5116 | ||
|
|
9851aacba7 | ||
|
|
51f9fb9e0a | ||
|
|
0325761f3e |
@@ -68,6 +68,7 @@ set(AMNEZIAVPN_TS_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/translations/amneziavpn_fa_IR.ts
|
||||
${CMAKE_CURRENT_LIST_DIR}/translations/amneziavpn_ar_EG.ts
|
||||
${CMAKE_CURRENT_LIST_DIR}/translations/amneziavpn_my_MM.ts
|
||||
${CMAKE_CURRENT_LIST_DIR}/translations/amneziavpn_uk_UA.ts
|
||||
)
|
||||
|
||||
file(GLOB_RECURSE AMNEZIAVPN_TS_SOURCES *.qrc *.cpp *.h *.ui)
|
||||
|
||||
@@ -406,25 +406,29 @@ class AmneziaActivity : QtActivity() {
|
||||
Log.v(TAG, "Open file with filter: $filter")
|
||||
|
||||
val mimeTypes = if (!filter.isNullOrEmpty()) {
|
||||
val extensionRegex = "\\*\\.[a-z .]+".toRegex(IGNORE_CASE)
|
||||
val extensionRegex = "\\*\\.([a-z0-9]+)".toRegex(IGNORE_CASE)
|
||||
val mime = MimeTypeMap.getSingleton()
|
||||
extensionRegex.findAll(filter).map {
|
||||
mime.getMimeTypeFromExtension(it.value.drop(2))
|
||||
}.filterNotNull().toSet()
|
||||
it.groups[1]?.value?.let { mime.getMimeTypeFromExtension(it) } ?: "*/*"
|
||||
}.toSet()
|
||||
} else emptySet()
|
||||
|
||||
Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
|
||||
addCategory(Intent.CATEGORY_OPENABLE)
|
||||
Log.v(TAG, "File mimyType filter: $mimeTypes")
|
||||
when (mimeTypes.size) {
|
||||
1 -> type = mimeTypes.first()
|
||||
if ("*/*" in mimeTypes) {
|
||||
type = "*/*"
|
||||
} else {
|
||||
when (mimeTypes.size) {
|
||||
1 -> type = mimeTypes.first()
|
||||
|
||||
in 2..Int.MAX_VALUE -> {
|
||||
type = "*/*"
|
||||
putExtra(EXTRA_MIME_TYPES, mimeTypes.toTypedArray())
|
||||
in 2..Int.MAX_VALUE -> {
|
||||
type = "*/*"
|
||||
putExtra(EXTRA_MIME_TYPES, mimeTypes.toTypedArray())
|
||||
}
|
||||
|
||||
else -> type = "*/*"
|
||||
}
|
||||
|
||||
else -> type = "*/*"
|
||||
}
|
||||
}.also {
|
||||
startActivityForResult(it, OPEN_FILE_ACTION_CODE)
|
||||
|
||||
@@ -113,11 +113,13 @@ target_sources(${PROJECT} PRIVATE
|
||||
target_sources(${PROJECT} PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/AmneziaVPNLaunchScreen.storyboard
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/Media.xcassets
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/PrivacyInfo.xcprivacy
|
||||
)
|
||||
|
||||
set_property(TARGET ${PROJECT} APPEND PROPERTY RESOURCE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/AmneziaVPNLaunchScreen.storyboard
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/Media.xcassets
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/PrivacyInfo.xcprivacy
|
||||
)
|
||||
|
||||
add_subdirectory(ios/networkextension)
|
||||
|
||||
33
client/ios/app/PrivacyInfo.xcprivacy
Normal file
33
client/ios/app/PrivacyInfo.xcprivacy
Normal file
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPITypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>C617.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>1C8F.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategorySystemBootTime</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>35F9.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -90,6 +90,14 @@ target_sources(networkextension PRIVATE
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/iosglue.mm
|
||||
)
|
||||
|
||||
target_sources(networkextension PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/PrivacyInfo.xcprivacy
|
||||
)
|
||||
|
||||
set_property(TARGET networkextension APPEND PROPERTY RESOURCE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/PrivacyInfo.xcprivacy
|
||||
)
|
||||
|
||||
## Build wireguard-go-version.h
|
||||
execute_process(
|
||||
COMMAND go list -m golang.zx2c4.com/wireguard
|
||||
|
||||
25
client/ios/networkextension/PrivacyInfo.xcprivacy
Normal file
25
client/ios/networkextension/PrivacyInfo.xcprivacy
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPITypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>1C8F.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>C617.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -424,6 +424,8 @@ bool IosController::setupCloak()
|
||||
openVPNConfig.insert(config_key::mtu, protocols::openvpn::defaultMtu);
|
||||
}
|
||||
|
||||
openVPNConfig.insert(config_key::splitTunnelType, m_rawConfig[config_key::splitTunnelType]);
|
||||
|
||||
QJsonArray splitTunnelSites = m_rawConfig[config_key::splitTunnelSites].toArray();
|
||||
|
||||
for(int index = 0; index < splitTunnelSites.count(); index++) {
|
||||
|
||||
@@ -256,6 +256,16 @@ Settings::RouteMode Settings::routeMode() const
|
||||
return static_cast<RouteMode>(value("Conf/routeMode", 0).toInt());
|
||||
}
|
||||
|
||||
bool Settings::getSitesSplitTunnelingEnabled() const
|
||||
{
|
||||
return value("Conf/sitesSplitTunnelingEnabled", false).toBool();
|
||||
}
|
||||
|
||||
void Settings::setSitesSplitTunnelingEnabled(bool enabled)
|
||||
{
|
||||
setValue("Conf/sitesSplitTunnelingEnabled", enabled);
|
||||
}
|
||||
|
||||
bool Settings::addVpnSite(RouteMode mode, const QString &site, const QString &ip)
|
||||
{
|
||||
QVariantMap sites = vpnSites(mode);
|
||||
@@ -403,6 +413,16 @@ void Settings::setVpnApps(AppsRouteMode mode, const QVector<InstalledAppInfo> &a
|
||||
m_settings.sync();
|
||||
}
|
||||
|
||||
bool Settings::getAppsSplitTunnelingEnabled() const
|
||||
{
|
||||
return value("Conf/appsSplitTunnelingEnabled", false).toBool();
|
||||
}
|
||||
|
||||
void Settings::setAppsSplitTunnelingEnabled(bool enabled)
|
||||
{
|
||||
setValue("Conf/appsSplitTunnelingEnabled", enabled);
|
||||
}
|
||||
|
||||
ServerCredentials Settings::defaultServerCredentials() const
|
||||
{
|
||||
return serverCredentials(defaultServerIndex());
|
||||
|
||||
@@ -115,6 +115,9 @@ public:
|
||||
RouteMode routeMode() const;
|
||||
void setRouteMode(RouteMode mode) { setValue("Conf/routeMode", mode); }
|
||||
|
||||
bool getSitesSplitTunnelingEnabled() const;
|
||||
void setSitesSplitTunnelingEnabled(bool enabled);
|
||||
|
||||
QVariantMap vpnSites(RouteMode mode) const
|
||||
{
|
||||
return value("Conf/" + routeModeString(mode)).toMap();
|
||||
@@ -208,6 +211,9 @@ public:
|
||||
QVector<InstalledAppInfo> getVpnApps(AppsRouteMode mode) const;
|
||||
void setVpnApps(AppsRouteMode mode, const QVector<InstalledAppInfo> &apps);
|
||||
|
||||
bool getAppsSplitTunnelingEnabled() const;
|
||||
void setAppsSplitTunnelingEnabled(bool enabled);
|
||||
|
||||
signals:
|
||||
void saveLogsChanged(bool enabled);
|
||||
void screenshotsEnabledChanged(bool enabled);
|
||||
|
||||
@@ -2906,7 +2906,7 @@ While it offers a blend of security, stability, and speed, it's essential t
|
||||
Он может быстро переключаться между сетями и устройствами, что делает его особенно адаптивным в динамичных сетевых средах.
|
||||
Несмотря на сочетание безопасности, стабильности и скорости, необходимо отметить, что IKEv2 легко обнаруживается и подвержен блокировке.
|
||||
|
||||
* Доступно в AmneziaVPN только для Windows.
|
||||
* Доступен в AmneziaVPN только для Windows
|
||||
* Низкое энергопотребление, на мобильных устройствах
|
||||
* Минимальная конфигурация
|
||||
* Распознается системами DPI-анализа
|
||||
@@ -2974,9 +2974,9 @@ It employs its unique security protocol, leveraging the strength of SSL/TLS for
|
||||
* Recognised by DPI analysis systems and therefore susceptible to blocking
|
||||
* Can operate over both TCP and UDP network protocols.</source>
|
||||
<translation>OpenVPN однин из самых популярных и проверенных временем VPN-протоколов.
|
||||
В нем используется уникальный протокол безопасности, опирающийся на протокол SSL/TLS для шифрования и обмена ключами. Кроме того, поддержка OpenVPN множества методов аутентификации делает его универсальным и адаптируемым к широкому спектру устройств и операционных систем. Благодаря открытому исходному коду OpenVPN подвергается тщательному анализу со стороны мирового сообщества, что постоянно повышает его безопасность. Благодаря оптимальному соотношению производительности, безопасности и совместимости OpenVPN остается лучшим выбором как для частных лиц, так и для компаний, заботящихся о конфиденциальности.
|
||||
В нем используется уникальный протокол безопасности, опирающийся на протокол SSL/TLS для шифрования и обмена ключами. Кроме того, OpenVPN поддерживает множество методов аутентификации, что делает его универсальным и адаптируемым к широкому спектру устройств и операционных систем. Благодаря открытому исходному коду OpenVPN подвергается тщательному анализу со стороны мирового сообщества, что постоянно повышает его безопасность. Благодаря оптимальному соотношению производительности, безопасности и совместимости OpenVPN остается лучшим выбором как для частных лиц, так и для компаний, заботящихся о конфиденциальности.
|
||||
|
||||
* Доступность AmneziaVPN для всех платформ
|
||||
* Доступен в AmneziaVPN для всех платформ
|
||||
* Нормальное энергопотребление на мобильных устройствах
|
||||
* Гибкая настройка под нужды пользователя для работы с различными операционными системами и устройствами
|
||||
* Распознается системами DPI-анализа и поэтому подвержен блокировке
|
||||
@@ -2994,7 +2994,7 @@ It employs its unique security protocol, leveraging the strength of SSL/TLS for
|
||||
* Works over TCP network protocol.</source>
|
||||
<translation>Shadowsocks, создан на основе протокола SOCKS5, защищает соединение с помощью шифра AEAD. Несмотря на то, что протокол Shadowsocks разработан таким образом, чтобы быть незаметным и сложным для идентификации, он не идентичен стандартному HTTPS-соединению. Однако некоторые системы анализа трафика все же могут обнаружить соединение Shadowsocks. В связи с ограниченной поддержкой в Amnezia рекомендуется использовать протокол AmneziaWG, или OpenVPN over Cloak.
|
||||
|
||||
* Доступен в AmneziaVPN только на ПК ноутбуках.
|
||||
* Доступен в AmneziaVPN только для ПК и ноутбуков
|
||||
* Настраиваемый протокол шифрования
|
||||
* Обнаруживается некоторыми DPI-системами
|
||||
* Работает по сетевому протоколу TCP.</translation>
|
||||
@@ -3037,19 +3037,19 @@ If there is a extreme level of Internet censorship in your region, we advise you
|
||||
* Not recognised by DPI analysis systems
|
||||
* Works over TCP network protocol, 443 port.
|
||||
</source>
|
||||
<translation type="vanished">OpenVPN over Cloak - это комбинация протокола OpenVPN и плагина Cloak, разработанного специально для защиты от блокировок.
|
||||
<translation type="vanished">OpenVPN over Cloak - это комбинация протокола OpenVPN и плагина Cloak, разработанного специально для защиты от обнаружения и блокировок.
|
||||
|
||||
OpenVPN обеспечивает безопасное VPN-соединение за счет шифрования всего интернет-трафика между клиентом и сервером.
|
||||
Протокол OpenVPN обеспечивает безопасное VPN-соединение за счет шифрования всего интернет-трафика между клиентом и сервером.
|
||||
|
||||
Cloak защищает OpenVPN от обнаружения и блокировок.
|
||||
Плагин Cloak защищает OpenVPN от обнаружения и блокировок.
|
||||
|
||||
Cloak может изменять метаданные пакетов. Он полностью маскирует VPN-трафик под обычный веб-трафик, а также защищает VPN от обнаружения с помощью Active Probing. Это делает его очень устойчивым к обнаружению
|
||||
|
||||
Сразу же после получения первого пакета данных Cloak проверяет подлинность входящего соединения. Если аутентификация не проходит, плагин маскирует сервер под поддельный сайт, и ваш VPN становится невидимым для аналитических систем.
|
||||
|
||||
Если в вашем регионе существует экстремальный уровень цензуры в Интернете, мы советуем вам при первом подключении использовать только OpenVPN через Cloak
|
||||
Если в вашем регионе экстремальный уровень цензуры в Интернете, мы советуем вам с первого подключения использовать только OpenVPN over Cloak
|
||||
|
||||
* Доступность AmneziaVPN на всех платформах
|
||||
* Доступен в AmneziaVPN для всех платформ
|
||||
* Высокое энергопотребление на мобильных устройствах
|
||||
* Гибкие настройки
|
||||
* Не распознается системами DPI-анализа
|
||||
@@ -3070,7 +3070,7 @@ WireGuard is very susceptible to blocking due to its distinct packet signatures.
|
||||
Обеспечивает стабильное VPN-соединение, высокую производительность на всех устройствах. Использует жестко заданные настройки шифрования. WireGuard по сравнению с OpenVPN имеет меньшую задержку и лучшую пропускную способность при передаче данных.
|
||||
WireGuard очень восприимчив к блокированию из-за особенностей сигнатур пакетов. В отличие от некоторых других VPN-протоколов, использующих методы обфускации, последовательные сигнатуры пакетов WireGuard легче выявляются и, соответственно, блокируются современными системами глубокой проверки пакетов (DPI) и другими средствами сетевого мониторинга.
|
||||
|
||||
* Доступность AmneziaVPN для всех платформ
|
||||
* Доступен в AmneziaVPN для всех платформ
|
||||
* Низкое энергопотребление
|
||||
* Минимальное количество настроек
|
||||
* Легко распознается системами DPI-анализа, подвержен блокировке
|
||||
@@ -3091,7 +3091,7 @@ This means that AmneziaWG keeps the fast performance of the original while addin
|
||||
Хотя WireGuard известен своей эффективностью, у него были проблемы с обнаружением из-за характерных сигнатур пакетов. AmneziaWG решает эту проблему за счет использования более совершенных методов обфускации, благодаря чему его трафик сливается с обычным интернет-трафиком.
|
||||
Таким образом, AmneziaWG сохраняет высокую производительность оригинала, добавляя при этом дополнительный уровень скрытности, что делает его отличным выбором для тех, кому нужно быстрое и незаметное VPN-соединение.
|
||||
|
||||
* Доступность AmneziaVPN на всех платформах
|
||||
* Доступен в AmneziaVPN для всех платформ
|
||||
* Низкое энергопотребление
|
||||
* Минимальное количество настроек
|
||||
* Не распознается системами DPI-анализа, устойчив к блокировке
|
||||
|
||||
3687
client/translations/amneziavpn_uk_UA.ts
Normal file
3687
client/translations/amneziavpn_uk_UA.ts
Normal file
File diff suppressed because it is too large
Load Diff
@@ -62,6 +62,11 @@ void ConnectionController::openConnection()
|
||||
DockerContainer container =
|
||||
qvariant_cast<DockerContainer>(m_serversModel->data(serverIndex, ServersModel::Roles::DefaultContainerRole));
|
||||
|
||||
if (!m_containersModel->isSupportedByCurrentPlatform(container)) {
|
||||
emit connectionErrorOccurred(tr("The selected protocol is not supported on the current platform"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (container == DockerContainer::None) {
|
||||
emit connectionErrorOccurred(tr("VPN Protocols is not installed.\n Please install VPN container at first"));
|
||||
return;
|
||||
|
||||
@@ -188,19 +188,24 @@ void InstallController::installServer(const DockerContainer container, const QMa
|
||||
VpnConfigurationsController vpnConfigurationController(m_settings);
|
||||
for (auto iterator = installedContainers.begin(); iterator != installedContainers.end(); iterator++) {
|
||||
auto containerConfig = iterator.value();
|
||||
auto errorCode =
|
||||
vpnConfigurationController.createProtocolConfigForContainer(m_processedServerCredentials, iterator.key(), containerConfig);
|
||||
if (errorCode) {
|
||||
emit installationErrorOccurred(errorString(errorCode));
|
||||
return;
|
||||
}
|
||||
containerConfigs.append(containerConfig);
|
||||
|
||||
errorCode = m_clientManagementModel->appendClient(iterator.key(), serverCredentials, containerConfig,
|
||||
QString("Admin [%1]").arg(QSysInfo::prettyProductName()));
|
||||
if (errorCode) {
|
||||
emit installationErrorOccurred(errorString(errorCode));
|
||||
return;
|
||||
if (ContainerProps::isSupportedByCurrentPlatform(container)) {
|
||||
auto errorCode =
|
||||
vpnConfigurationController.createProtocolConfigForContainer(m_processedServerCredentials, iterator.key(), containerConfig);
|
||||
if (errorCode) {
|
||||
emit installationErrorOccurred(errorString(errorCode));
|
||||
return;
|
||||
}
|
||||
containerConfigs.append(containerConfig);
|
||||
|
||||
errorCode = m_clientManagementModel->appendClient(iterator.key(), serverCredentials, containerConfig,
|
||||
QString("Admin [%1]").arg(QSysInfo::prettyProductName()));
|
||||
if (errorCode) {
|
||||
emit installationErrorOccurred(errorString(errorCode));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
containerConfigs.append(containerConfig);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,18 +227,23 @@ void InstallController::installContainer(const DockerContainer container, const
|
||||
QJsonObject containerConfig = m_containersModel->getContainerConfig(iterator.key());
|
||||
if (containerConfig.isEmpty()) {
|
||||
containerConfig = iterator.value();
|
||||
auto errorCode = vpnConfigurationController.createProtocolConfigForContainer(serverCredentials, iterator.key(), containerConfig);
|
||||
if (errorCode) {
|
||||
emit installationErrorOccurred(errorString(errorCode));
|
||||
return;
|
||||
}
|
||||
m_serversModel->addContainerConfig(iterator.key(), containerConfig);
|
||||
|
||||
errorCode = m_clientManagementModel->appendClient(iterator.key(), serverCredentials, containerConfig,
|
||||
QString("Admin [%1]").arg(QSysInfo::prettyProductName()));
|
||||
if (errorCode) {
|
||||
emit installationErrorOccurred(errorString(errorCode));
|
||||
return;
|
||||
if (ContainerProps::isSupportedByCurrentPlatform(container)) {
|
||||
auto errorCode = vpnConfigurationController.createProtocolConfigForContainer(serverCredentials, iterator.key(), containerConfig);
|
||||
if (errorCode) {
|
||||
emit installationErrorOccurred(errorString(errorCode));
|
||||
return;
|
||||
}
|
||||
m_serversModel->addContainerConfig(iterator.key(), containerConfig);
|
||||
|
||||
errorCode = m_clientManagementModel->appendClient(iterator.key(), serverCredentials, containerConfig,
|
||||
QString("Admin [%1]").arg(QSysInfo::prettyProductName()));
|
||||
if (errorCode) {
|
||||
emit installationErrorOccurred(errorString(errorCode));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
m_serversModel->addContainerConfig(iterator.key(), containerConfig);
|
||||
}
|
||||
|
||||
if (container != iterator.key()) { // skip the newly installed container
|
||||
@@ -279,22 +289,28 @@ void InstallController::scanServerForInstalledContainers()
|
||||
VpnConfigurationsController vpnConfigurationController(m_settings);
|
||||
|
||||
for (auto iterator = installedContainers.begin(); iterator != installedContainers.end(); iterator++) {
|
||||
QJsonObject containerConfig = m_containersModel->getContainerConfig(iterator.key());
|
||||
auto container = iterator.key();
|
||||
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
|
||||
if (containerConfig.isEmpty()) {
|
||||
containerConfig = iterator.value();
|
||||
auto errorCode =
|
||||
vpnConfigurationController.createProtocolConfigForContainer(serverCredentials, iterator.key(), containerConfig);
|
||||
if (errorCode) {
|
||||
emit installationErrorOccurred(errorString(errorCode));
|
||||
return;
|
||||
}
|
||||
m_serversModel->addContainerConfig(iterator.key(), containerConfig);
|
||||
|
||||
errorCode = m_clientManagementModel->appendClient(iterator.key(), serverCredentials, containerConfig,
|
||||
QString("Admin [%1]").arg(QSysInfo::prettyProductName()));
|
||||
if (errorCode) {
|
||||
emit installationErrorOccurred(errorString(errorCode));
|
||||
return;
|
||||
if (ContainerProps::isSupportedByCurrentPlatform(container)) {
|
||||
auto errorCode =
|
||||
vpnConfigurationController.createProtocolConfigForContainer(serverCredentials, container, containerConfig);
|
||||
if (errorCode) {
|
||||
emit installationErrorOccurred(errorString(errorCode));
|
||||
return;
|
||||
}
|
||||
m_serversModel->addContainerConfig(container, containerConfig);
|
||||
|
||||
errorCode = m_clientManagementModel->appendClient(container, serverCredentials, containerConfig,
|
||||
QString("Admin [%1]").arg(QSysInfo::prettyProductName()));
|
||||
if (errorCode) {
|
||||
emit installationErrorOccurred(errorString(errorCode));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
m_serversModel->addContainerConfig(container, containerConfig);
|
||||
}
|
||||
|
||||
isInstalledContainerAddedToGui = true;
|
||||
@@ -517,7 +533,8 @@ void InstallController::removeAllContainers()
|
||||
emit removeAllContainersFinished(tr("All containers from server '%1' have been removed").arg(serverName));
|
||||
return;
|
||||
}
|
||||
emit installationErrorOccurred(errorString(errorCode));
|
||||
|
||||
qDebug() << errorString(errorCode);
|
||||
}
|
||||
|
||||
void InstallController::removeProcessedContainer()
|
||||
|
||||
@@ -5,14 +5,8 @@
|
||||
AppSplitTunnelingModel::AppSplitTunnelingModel(std::shared_ptr<Settings> settings, QObject *parent)
|
||||
: QAbstractListModel(parent), m_settings(settings)
|
||||
{
|
||||
auto routeMode = m_settings->getAppsRouteMode();
|
||||
if (routeMode == Settings::AppsRouteMode::VpnAllApps) {
|
||||
m_isSplitTunnelingEnabled = false;
|
||||
m_currentRouteMode = Settings::AppsRouteMode::VpnAllExceptApps;
|
||||
} else {
|
||||
m_isSplitTunnelingEnabled = true;
|
||||
m_currentRouteMode = routeMode;
|
||||
}
|
||||
m_isSplitTunnelingEnabled = m_settings->getAppsSplitTunnelingEnabled();
|
||||
m_currentRouteMode = m_settings->getAppsRouteMode();
|
||||
m_apps = m_settings->getVpnApps(m_currentRouteMode);
|
||||
}
|
||||
|
||||
@@ -84,11 +78,7 @@ bool AppSplitTunnelingModel::isSplitTunnelingEnabled()
|
||||
|
||||
void AppSplitTunnelingModel::toggleSplitTunneling(bool enabled)
|
||||
{
|
||||
if (enabled) {
|
||||
setRouteMode(m_currentRouteMode);
|
||||
} else {
|
||||
m_settings->setAppsRouteMode(Settings::AppsRouteMode::VpnAllApps);
|
||||
}
|
||||
m_settings->setAppsSplitTunnelingEnabled(enabled);
|
||||
m_isSplitTunnelingEnabled = enabled;
|
||||
emit splitTunnelingToggled();
|
||||
}
|
||||
|
||||
@@ -83,6 +83,16 @@ QJsonObject ContainersModel::getContainerConfig(const int containerIndex)
|
||||
return qvariant_cast<QJsonObject>(data(index(containerIndex), ConfigRole));
|
||||
}
|
||||
|
||||
bool ContainersModel::isSupportedByCurrentPlatform(const int containerIndex)
|
||||
{
|
||||
return qvariant_cast<bool>(data(index(containerIndex), IsSupportedRole));
|
||||
}
|
||||
|
||||
bool ContainersModel::isServiceContainer(const int containerIndex)
|
||||
{
|
||||
return qvariant_cast<amnezia::ServiceType>(data(index(containerIndex), ServiceTypeRole) == ServiceType::Other);
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> ContainersModel::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roles;
|
||||
|
||||
@@ -49,6 +49,9 @@ public slots:
|
||||
|
||||
QJsonObject getContainerConfig(const int containerIndex);
|
||||
|
||||
bool isSupportedByCurrentPlatform(const int containerIndex);
|
||||
bool isServiceContainer(const int containerIndex);
|
||||
|
||||
protected:
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
|
||||
@@ -64,6 +64,7 @@ QVector<QPair<QString, QString>> InstalledAppsModel::getSelectedAppsInfo()
|
||||
appsInfo.push_back({ appName, packageName });
|
||||
}
|
||||
|
||||
m_selectedAppIndexes.clear();
|
||||
return appsInfo;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ QString LanguageModel::getLocalLanguageName(const LanguageSettings::AvailableLan
|
||||
switch (language) {
|
||||
case LanguageSettings::AvailableLanguageEnum::English: strLanguage = "English"; break;
|
||||
case LanguageSettings::AvailableLanguageEnum::Russian: strLanguage = "Русский"; break;
|
||||
case LanguageSettings::AvailableLanguageEnum::Ukrainian: strLanguage = "Українська"; break;
|
||||
case LanguageSettings::AvailableLanguageEnum::China_cn: strLanguage = "\347\256\200\344\275\223\344\270\255\346\226\207"; break;
|
||||
case LanguageSettings::AvailableLanguageEnum::Persian: strLanguage = "فارسی"; break;
|
||||
case LanguageSettings::AvailableLanguageEnum::Arabic: strLanguage = "العربية"; break;
|
||||
@@ -60,6 +61,7 @@ void LanguageModel::changeLanguage(const LanguageSettings::AvailableLanguageEnum
|
||||
case LanguageSettings::AvailableLanguageEnum::English: emit updateTranslations(QLocale::English); break;
|
||||
case LanguageSettings::AvailableLanguageEnum::Russian: emit updateTranslations(QLocale::Russian); break;
|
||||
case LanguageSettings::AvailableLanguageEnum::China_cn: emit updateTranslations(QLocale::Chinese); break;
|
||||
case LanguageSettings::AvailableLanguageEnum::Ukrainian: emit updateTranslations(QLocale::Ukrainian); break;
|
||||
case LanguageSettings::AvailableLanguageEnum::Persian: emit updateTranslations(QLocale::Persian); break;
|
||||
case LanguageSettings::AvailableLanguageEnum::Arabic: emit updateTranslations(QLocale::Arabic); break;
|
||||
case LanguageSettings::AvailableLanguageEnum::Burmese: emit updateTranslations(QLocale::Burmese); break;
|
||||
@@ -74,6 +76,7 @@ int LanguageModel::getCurrentLanguageIndex()
|
||||
case QLocale::English: return static_cast<int>(LanguageSettings::AvailableLanguageEnum::English); break;
|
||||
case QLocale::Russian: return static_cast<int>(LanguageSettings::AvailableLanguageEnum::Russian); break;
|
||||
case QLocale::Chinese: return static_cast<int>(LanguageSettings::AvailableLanguageEnum::China_cn); break;
|
||||
case QLocale::Ukrainian: return static_cast<int>(LanguageSettings::AvailableLanguageEnum::Ukrainian); break;
|
||||
case QLocale::Persian: return static_cast<int>(LanguageSettings::AvailableLanguageEnum::Persian); break;
|
||||
case QLocale::Arabic: return static_cast<int>(LanguageSettings::AvailableLanguageEnum::Arabic); break;
|
||||
case QLocale::Burmese: return static_cast<int>(LanguageSettings::AvailableLanguageEnum::Burmese); break;
|
||||
|
||||
@@ -13,6 +13,7 @@ namespace LanguageSettings
|
||||
English,
|
||||
Russian,
|
||||
China_cn,
|
||||
Ukrainian,
|
||||
Persian,
|
||||
Arabic,
|
||||
Burmese
|
||||
|
||||
@@ -105,12 +105,12 @@ void OpenVpnConfigModel::updateModel(const QJsonObject &config)
|
||||
m_protocolConfig.insert(config_key::hash,
|
||||
protocolConfig.value(config_key::hash).toString(protocols::openvpn::defaultHash));
|
||||
m_protocolConfig.insert(config_key::block_outside_dns,
|
||||
protocolConfig.value(config_key::tls_auth).toBool(protocols::openvpn::defaultTlsAuth));
|
||||
protocolConfig.value(config_key::block_outside_dns).toBool(protocols::openvpn::defaultBlockOutsideDns));
|
||||
m_protocolConfig.insert(config_key::port,
|
||||
protocolConfig.value(config_key::port).toString(protocols::openvpn::defaultPort));
|
||||
m_protocolConfig.insert(
|
||||
config_key::tls_auth,
|
||||
protocolConfig.value(config_key::block_outside_dns).toBool(protocols::openvpn::defaultBlockOutsideDns));
|
||||
protocolConfig.value(config_key::tls_auth).toBool(protocols::openvpn::defaultTlsAuth));
|
||||
m_protocolConfig.insert(config_key::additional_client_config,
|
||||
protocolConfig.value(config_key::additional_client_config)
|
||||
.toString(protocols::openvpn::defaultAdditionalClientConfig));
|
||||
|
||||
@@ -31,10 +31,15 @@ bool ServersModel::setData(const QModelIndex &index, const QVariant &value, int
|
||||
}
|
||||
|
||||
QJsonObject server = m_servers.at(index.row()).toObject();
|
||||
const auto configVersion = server.value(config_key::configVersion).toInt();
|
||||
|
||||
switch (role) {
|
||||
case NameRole: {
|
||||
server.insert(config_key::description, value.toString());
|
||||
if (configVersion) {
|
||||
server.insert(config_key::name, value.toString());
|
||||
} else {
|
||||
server.insert(config_key::description, value.toString());
|
||||
}
|
||||
m_settings->editServer(index.row(), server);
|
||||
m_servers.replace(index.row(), server);
|
||||
if (index.row() == m_defaultServerIndex) {
|
||||
@@ -400,8 +405,9 @@ void ServersModel::addContainerConfig(const int containerIndex, const QJsonObjec
|
||||
server.insert(config_key::containers, containers);
|
||||
|
||||
auto defaultContainer = server.value(config_key::defaultContainer).toString();
|
||||
if ((ContainerProps::containerFromString(defaultContainer) == DockerContainer::None
|
||||
|| ContainerProps::containerService(container) != ServiceType::Other)) {
|
||||
if (ContainerProps::containerFromString(defaultContainer) == DockerContainer::None
|
||||
&& ContainerProps::containerService(container) != ServiceType::Other
|
||||
&& ContainerProps::isSupportedByCurrentPlatform(container)) {
|
||||
server.insert(config_key::defaultContainer, ContainerProps::containerToString(container));
|
||||
}
|
||||
|
||||
|
||||
@@ -3,14 +3,8 @@
|
||||
SitesModel::SitesModel(std::shared_ptr<Settings> settings, QObject *parent)
|
||||
: QAbstractListModel(parent), m_settings(settings)
|
||||
{
|
||||
auto routeMode = m_settings->routeMode();
|
||||
if (routeMode == Settings::RouteMode::VpnAllSites) {
|
||||
m_isSplitTunnelingEnabled = false;
|
||||
m_currentRouteMode = Settings::RouteMode::VpnOnlyForwardSites;
|
||||
} else {
|
||||
m_isSplitTunnelingEnabled = true;
|
||||
m_currentRouteMode = routeMode;
|
||||
}
|
||||
m_isSplitTunnelingEnabled = m_settings->getSitesSplitTunnelingEnabled();
|
||||
m_currentRouteMode = m_settings->routeMode();
|
||||
fillSites();
|
||||
}
|
||||
|
||||
@@ -107,11 +101,7 @@ bool SitesModel::isSplitTunnelingEnabled()
|
||||
|
||||
void SitesModel::toggleSplitTunneling(bool enabled)
|
||||
{
|
||||
if (enabled) {
|
||||
setRouteMode(m_currentRouteMode);
|
||||
} else {
|
||||
m_settings->setRouteMode(Settings::RouteMode::VpnAllSites);
|
||||
}
|
||||
m_settings->setSitesSplitTunnelingEnabled(enabled);
|
||||
m_isSplitTunnelingEnabled = enabled;
|
||||
emit splitTunnelingToggled();
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ ListView {
|
||||
imageSource: "qrc:/images/controls/download.svg"
|
||||
showImage: !isInstalled
|
||||
|
||||
checkable: isInstalled && !ConnectionController.isConnected && isSupported
|
||||
checkable: isInstalled && !ConnectionController.isConnected
|
||||
checked: proxyDefaultServerContainersModel.mapToSource(index) === ServersModel.getDefaultServerData("defaultContainer")
|
||||
|
||||
onClicked: {
|
||||
@@ -64,11 +64,6 @@ ListView {
|
||||
containersDropDown.close()
|
||||
ServersModel.setDefaultContainer(ServersModel.defaultIndex, proxyDefaultServerContainersModel.mapToSource(index))
|
||||
} else {
|
||||
if (!isSupported && isInstalled) {
|
||||
PageController.showErrorMessage(qsTr("The selected protocol is not supported on the current platform"))
|
||||
return
|
||||
}
|
||||
|
||||
ContainersModel.setProcessedContainerIndex(proxyDefaultServerContainersModel.mapToSource(index))
|
||||
InstallController.setShouldCreateServer(false)
|
||||
PageController.goToPage(PageEnum.PageSetupWizardProtocolSettings)
|
||||
|
||||
@@ -59,8 +59,6 @@ DrawerType2 {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 16
|
||||
|
||||
enabled: !ServersModel.isDefaultServerDefaultContainerHasSplitTunneling || !ServersModel.getDefaultServerData("isServerFromApi")
|
||||
|
||||
text: qsTr("Site-based split tunneling")
|
||||
descriptionText: enabled && SitesModel.isTunnelingEnabled ? qsTr("Enabled") : qsTr("Disabled")
|
||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||
|
||||
@@ -5,6 +5,8 @@ import QtQuick.Layouts
|
||||
import "../Controls2"
|
||||
import "../Controls2/TextTypes"
|
||||
|
||||
import SortFilterProxyModel 0.2
|
||||
|
||||
import InstalledAppsModel 1.0
|
||||
|
||||
DrawerType2 {
|
||||
@@ -34,7 +36,7 @@ DrawerType2 {
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: addButton.top
|
||||
anchors.bottom: searchField.top
|
||||
anchors.topMargin: 16
|
||||
|
||||
BackButtonType {
|
||||
@@ -66,7 +68,15 @@ DrawerType2 {
|
||||
clip: true
|
||||
interactive: true
|
||||
|
||||
model: installedAppsModel
|
||||
model: SortFilterProxyModel {
|
||||
id: proxyInstalledAppsModel
|
||||
sourceModel: installedAppsModel
|
||||
filters: RegExpFilter {
|
||||
roleName: "appName"
|
||||
pattern: ".*" + searchField.textField.text + ".*"
|
||||
caseSensitivity: Qt.CaseInsensitive
|
||||
}
|
||||
}
|
||||
|
||||
ScrollBar.vertical: ScrollBar {
|
||||
id: scrollBar
|
||||
@@ -93,7 +103,7 @@ DrawerType2 {
|
||||
text: appName
|
||||
|
||||
onCheckedChanged: {
|
||||
listView.model.selectedStateChanged(index, checked)
|
||||
installedAppsModel.selectedStateChanged(proxyInstalledAppsModel.mapToSource(index), checked)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,6 +123,21 @@ DrawerType2 {
|
||||
}
|
||||
}
|
||||
|
||||
TextFieldWithHeaderType {
|
||||
id: searchField
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: addButton.top
|
||||
anchors.bottomMargin: 16
|
||||
anchors.rightMargin: 16
|
||||
anchors.leftMargin: 16
|
||||
|
||||
backgroundColor: "#2C2D30"
|
||||
|
||||
textFieldPlaceholderText: qsTr("application name")
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
id: addButton
|
||||
|
||||
@@ -127,7 +152,7 @@ DrawerType2 {
|
||||
|
||||
clickedFunc: function() {
|
||||
PageController.showBusyIndicator(true)
|
||||
AppSplitTunnelingController.addApps(listView.model.getSelectedAppsInfo())
|
||||
AppSplitTunnelingController.addApps(installedAppsModel.getSelectedAppsInfo())
|
||||
PageController.showBusyIndicator(false)
|
||||
root.close()
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ PageType {
|
||||
|
||||
Header1TextType {
|
||||
id: collapsedButtonHeader
|
||||
Layout.maximumWidth: drawer.isCollapsed ? drawer.width - 48 - 18 - 12 : drawer.width// todo
|
||||
Layout.maximumWidth: drawer.width - 48 - 18 - 12
|
||||
|
||||
maximumLineCount: 2
|
||||
elide: Qt.ElideRight
|
||||
|
||||
@@ -68,8 +68,14 @@ PageType {
|
||||
var noButtonText = qsTr("Cancel")
|
||||
|
||||
var yesButtonFunction = function() {
|
||||
PageController.goToPage(PageEnum.PageDeinstalling)
|
||||
InstallController.removeProcessedContainer()
|
||||
if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected
|
||||
&& SettingsController.isAmneziaDnsEnabled()) {
|
||||
PageController.showNotificationMessage(qsTr("Cannot remove Amnezia DNS from running server"))
|
||||
} else
|
||||
{
|
||||
PageController.goToPage(PageEnum.PageDeinstalling)
|
||||
InstallController.removeProcessedContainer()
|
||||
}
|
||||
}
|
||||
var noButtonFunction = function() {
|
||||
}
|
||||
|
||||
@@ -20,6 +20,17 @@ import "../Components"
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
property bool pageEnabled
|
||||
|
||||
Component.onCompleted: {
|
||||
if (ConnectionController.isConnected) {
|
||||
PageController.showNotificationMessage(qsTr("Cannot change split tunneling settings during active connection"))
|
||||
root.pageEnabled = false
|
||||
} else {
|
||||
root.pageEnabled = true
|
||||
}
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: routeMode
|
||||
property int allApps: 0
|
||||
@@ -70,6 +81,8 @@ PageType {
|
||||
Layout.leftMargin: 16
|
||||
|
||||
headerText: qsTr("App split tunneling")
|
||||
|
||||
enabled: root.pageEnabled
|
||||
}
|
||||
|
||||
SwitcherType {
|
||||
@@ -78,6 +91,8 @@ PageType {
|
||||
Layout.fillWidth: true
|
||||
Layout.rightMargin: 16
|
||||
|
||||
enabled: root.pageEnabled
|
||||
|
||||
checked: AppSplitTunnelingModel.isTunnelingEnabled
|
||||
onToggled: {
|
||||
AppSplitTunnelingModel.toggleSplitTunneling(checked)
|
||||
@@ -99,7 +114,7 @@ PageType {
|
||||
|
||||
headerText: qsTr("Mode")
|
||||
|
||||
enabled: Qt.platform.os === "android"
|
||||
enabled: Qt.platform.os === "android" && root.pageEnabled
|
||||
|
||||
listView: ListViewWithRadioButtonType {
|
||||
rootWidth: root.width
|
||||
@@ -139,6 +154,8 @@ PageType {
|
||||
anchors.topMargin: 16
|
||||
contentHeight: col.implicitHeight + addAppButton.implicitHeight + addAppButton.anchors.bottomMargin + addAppButton.anchors.topMargin
|
||||
|
||||
enabled: root.pageEnabled
|
||||
|
||||
Column {
|
||||
id: col
|
||||
anchors.top: parent.top
|
||||
@@ -213,6 +230,8 @@ PageType {
|
||||
RowLayout {
|
||||
id: addAppButton
|
||||
|
||||
enabled: root.pageEnabled
|
||||
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
@@ -169,8 +169,13 @@ PageType {
|
||||
var noButtonText = qsTr("Cancel")
|
||||
|
||||
var yesButtonFunction = function() {
|
||||
SettingsController.clearSettings()
|
||||
PageController.replaceStartPage()
|
||||
if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) {
|
||||
PageController.showNotificationMessage(qsTr("Cannot reset settings during active connection"))
|
||||
} else
|
||||
{
|
||||
SettingsController.clearSettings()
|
||||
PageController.replaceStartPage()
|
||||
}
|
||||
}
|
||||
var noButtonFunction = function() {
|
||||
}
|
||||
|
||||
@@ -135,9 +135,14 @@ PageType {
|
||||
var noButtonText = qsTr("Cancel")
|
||||
|
||||
var yesButtonFunction = function() {
|
||||
PageController.showBusyIndicator(true)
|
||||
SettingsController.restoreAppConfig(filePath)
|
||||
PageController.showBusyIndicator(false)
|
||||
if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) {
|
||||
PageController.showNotificationMessage(qsTr("Cannot restore backup settings during active connection"))
|
||||
} else
|
||||
{
|
||||
PageController.showBusyIndicator(true)
|
||||
SettingsController.restoreAppConfig(filePath)
|
||||
PageController.showBusyIndicator(false)
|
||||
}
|
||||
}
|
||||
var noButtonFunction = function() {
|
||||
}
|
||||
|
||||
@@ -116,12 +116,13 @@ PageType {
|
||||
var noButtonText = qsTr("Cancel")
|
||||
|
||||
var yesButtonFunction = function() {
|
||||
PageController.showBusyIndicator(true)
|
||||
if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) {
|
||||
ConnectionController.closeConnection()
|
||||
PageController.showNotificationMessage(qsTr("Cannot reboot server during active connection"))
|
||||
} else {
|
||||
PageController.showBusyIndicator(true)
|
||||
InstallController.rebootProcessedServer()
|
||||
PageController.showBusyIndicator(false)
|
||||
}
|
||||
InstallController.rebootProcessedServer()
|
||||
PageController.showBusyIndicator(false)
|
||||
}
|
||||
var noButtonFunction = function() {
|
||||
}
|
||||
@@ -147,12 +148,13 @@ PageType {
|
||||
var noButtonText = qsTr("Cancel")
|
||||
|
||||
var yesButtonFunction = function() {
|
||||
PageController.showBusyIndicator(true)
|
||||
if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) {
|
||||
ConnectionController.closeConnection()
|
||||
PageController.showNotificationMessage(qsTr("Cannot remove server during active connection"))
|
||||
} else {
|
||||
PageController.showBusyIndicator(true)
|
||||
InstallController.removeProcessedServer()
|
||||
PageController.showBusyIndicator(false)
|
||||
}
|
||||
InstallController.removeProcessedServer()
|
||||
PageController.showBusyIndicator(false)
|
||||
}
|
||||
var noButtonFunction = function() {
|
||||
}
|
||||
@@ -177,11 +179,12 @@ PageType {
|
||||
var noButtonText = qsTr("Cancel")
|
||||
|
||||
var yesButtonFunction = function() {
|
||||
PageController.goToPage(PageEnum.PageDeinstalling)
|
||||
if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) {
|
||||
ConnectionController.closeConnection()
|
||||
PageController.showNotificationMessage(qsTr("Cannot clear server from Amnezia software during active connection"))
|
||||
} else {
|
||||
PageController.goToPage(PageEnum.PageDeinstalling)
|
||||
InstallController.removeAllContainers()
|
||||
}
|
||||
InstallController.removeAllContainers()
|
||||
}
|
||||
var noButtonFunction = function() {
|
||||
}
|
||||
@@ -208,9 +211,13 @@ PageType {
|
||||
var noButtonText = qsTr("Cancel")
|
||||
|
||||
var yesButtonFunction = function() {
|
||||
PageController.showBusyIndicator(true)
|
||||
InstallController.removeApiConfig()
|
||||
PageController.showBusyIndicator(false)
|
||||
if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) {
|
||||
PageController.showNotificationMessage(qsTr("Cannot reset API config during active connection"))
|
||||
} else {
|
||||
PageController.showBusyIndicator(true)
|
||||
InstallController.removeApiConfig()
|
||||
PageController.showBusyIndicator(false)
|
||||
}
|
||||
}
|
||||
var noButtonFunction = function() {
|
||||
}
|
||||
|
||||
@@ -147,8 +147,14 @@ PageType {
|
||||
var noButtonText = qsTr("Cancel")
|
||||
|
||||
var yesButtonFunction = function() {
|
||||
PageController.goToPage(PageEnum.PageDeinstalling)
|
||||
InstallController.removeProcessedContainer()
|
||||
if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected
|
||||
&& ServersModel.getDefaultServerData("defaultContainer") === ContainersModel.getProcessedContainerIndex()) {
|
||||
PageController.showNotificationMessage(qsTr("Cannot remove active container"))
|
||||
} else
|
||||
{
|
||||
PageController.goToPage(PageEnum.PageDeinstalling)
|
||||
InstallController.removeProcessedContainer()
|
||||
}
|
||||
}
|
||||
var noButtonFunction = function() {
|
||||
}
|
||||
|
||||
@@ -24,9 +24,7 @@ PageType {
|
||||
|
||||
defaultActiveFocusItem: searchField.textField
|
||||
|
||||
property bool pageEnabled: {
|
||||
return !ConnectionController.isConnected && !isServerFromApi
|
||||
}
|
||||
property bool pageEnabled
|
||||
|
||||
Component.onCompleted: {
|
||||
if (ConnectionController.isConnected) {
|
||||
|
||||
@@ -25,8 +25,9 @@ PageType {
|
||||
target: InstallController
|
||||
|
||||
function onInstallContainerFinished(finishedMessage, isServiceInstall) {
|
||||
if (!ConnectionController.isConnected && !isServiceInstall) {
|
||||
ServersModel.setDefaultContainer(ServersModel.processedIndex, ContainersModel.getProcessedContainerIndex())
|
||||
var containerIndex = ContainersModel.getProcessedContainerIndex()
|
||||
if (!ConnectionController.isConnected && !ContainersModel.isServiceContainer(containerIndex)) {
|
||||
ServersModel.setDefaultContainer(ServersModel.processedIndex, containerIndex)
|
||||
}
|
||||
|
||||
PageController.closePage() // close installing page
|
||||
|
||||
@@ -67,7 +67,9 @@ void SystemTrayNotificationHandler::onTranslationsUpdated()
|
||||
void SystemTrayNotificationHandler::setTrayIcon(const QString &iconPath)
|
||||
{
|
||||
QIcon trayIconMask(QPixmap(iconPath).scaled(128,128));
|
||||
#ifndef Q_OS_MAC
|
||||
trayIconMask.setIsMask(true);
|
||||
#endif
|
||||
m_systemTrayIcon.setIcon(trayIconMask);
|
||||
}
|
||||
|
||||
|
||||
@@ -301,7 +301,11 @@ void VpnConnection::appendSplitTunnelingConfig()
|
||||
}
|
||||
}
|
||||
|
||||
auto routeMode = m_settings->routeMode();
|
||||
Settings::RouteMode routeMode = Settings::RouteMode::VpnAllSites;
|
||||
if (m_settings->getSitesSplitTunnelingEnabled()) {
|
||||
routeMode = m_settings->routeMode();
|
||||
}
|
||||
|
||||
auto sites = m_settings->getVpnIps(routeMode);
|
||||
|
||||
QJsonArray sitesJsonArray;
|
||||
@@ -318,7 +322,11 @@ void VpnConnection::appendSplitTunnelingConfig()
|
||||
m_vpnConfiguration.insert(config_key::splitTunnelType, routeMode);
|
||||
m_vpnConfiguration.insert(config_key::splitTunnelSites, sitesJsonArray);
|
||||
|
||||
auto appsRouteMode = m_settings->getAppsRouteMode();
|
||||
Settings::AppsRouteMode appsRouteMode = Settings::AppsRouteMode::VpnAllApps;
|
||||
if (m_settings->getAppsSplitTunnelingEnabled()) {
|
||||
appsRouteMode = m_settings->getAppsRouteMode();
|
||||
}
|
||||
|
||||
auto apps = m_settings->getVpnApps(appsRouteMode);
|
||||
|
||||
QJsonArray appsJsonArray;
|
||||
|
||||
Reference in New Issue
Block a user