mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-06-02 08:33:38 +02:00
Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 517b5e5ca6 | |||
| cfeb6cbffd | |||
| ec132ac96c | |||
| 101838404e | |||
| 5a7b5d34fb | |||
| 9420333c76 | |||
| f6403fe82e | |||
| c55b025eee | |||
| fc6fc26148 | |||
| 48b43ee102 | |||
| e091020692 | |||
| 703b9137e0 | |||
| f163f0fc1d | |||
| 3b49d5ca59 | |||
| 236e5ca2e3 | |||
| 2f6e28b980 | |||
| 46d96a8887 | |||
| 56221881da | |||
| da5fe1d766 | |||
| a15ea0e8a1 | |||
| f79bfa9d2e | |||
| 3011a0e306 | |||
| 76640311ab | |||
| e707471b04 | |||
| 36045c6694 | |||
| 52ecd6899b |
@@ -1,6 +1,3 @@
|
||||
[submodule "client/3rd/OpenVPNAdapter"]
|
||||
path = client/3rd/OpenVPNAdapter
|
||||
url = https://github.com/amnezia-vpn/OpenVPNAdapter.git
|
||||
[submodule "client/3rd/qtkeychain"]
|
||||
path = client/3rd/qtkeychain
|
||||
url = https://github.com/frankosterfeld/qtkeychain.git
|
||||
|
||||
+2
-2
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.25.0 FATAL_ERROR)
|
||||
|
||||
set(PROJECT AmneziaVPN)
|
||||
|
||||
project(${PROJECT} VERSION 4.8.3.1
|
||||
project(${PROJECT} VERSION 4.8.3.3
|
||||
DESCRIPTION "AmneziaVPN"
|
||||
HOMEPAGE_URL "https://amnezia.org/"
|
||||
)
|
||||
@@ -11,7 +11,7 @@ string(TIMESTAMP CURRENT_DATE "%Y-%m-%d")
|
||||
set(RELEASE_DATE "${CURRENT_DATE}")
|
||||
|
||||
set(APP_MAJOR_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH})
|
||||
set(APP_ANDROID_VERSION_CODE 2074)
|
||||
set(APP_ANDROID_VERSION_CODE 2076)
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
||||
set(MZ_PLATFORM_NAME "linux")
|
||||
|
||||
@@ -13,13 +13,13 @@
|
||||
|
||||
[](https://amnezia.org)
|
||||
|
||||
### [Website](https://amnezia.org) | [Alt website link](https://storage.googleapis.com/kldscp/amnezia.org) | [Documentation](https://docs.amnezia.org) | [Troubleshooting](https://docs.amnezia.org/troubleshooting)
|
||||
### [Website](https://amnezia.org) | [Alt website link](https://storage.googleapis.com/amnezia/amnezia.org) | [Documentation](https://docs.amnezia.org) | [Troubleshooting](https://docs.amnezia.org/troubleshooting)
|
||||
|
||||
> [!TIP]
|
||||
> If the [Amnezia website](https://amnezia.org) is blocked in your region, you can use an [Alternative website link](https://storage.googleapis.com/kldscp/amnezia.org).
|
||||
> If the [Amnezia website](https://amnezia.org) is blocked in your region, you can use an [Alternative website link](https://storage.googleapis.com/amnezia/amnezia.org ).
|
||||
|
||||
<a href="https://amnezia.org/downloads"><img src="https://github.com/amnezia-vpn/amnezia-client/blob/dev/metadata/img-readme/download-website.svg" width="150" style="max-width: 100%; margin-right: 10px"></a>
|
||||
<a href="https://storage.googleapis.com/kldscp/amnezia.org/downloads"><img src="https://github.com/amnezia-vpn/amnezia-client/blob/dev/metadata/img-readme/download-alt.svg" width="150" style="max-width: 100%;"></a>
|
||||
<a href="https://storage.googleapis.com/amnezia/q9p19109"><img src="https://github.com/amnezia-vpn/amnezia-client/blob/dev/metadata/img-readme/download-alt.svg" width="150" style="max-width: 100%;"></a>
|
||||
|
||||
[All releases](https://github.com/amnezia-vpn/amnezia-client/releases)
|
||||
|
||||
|
||||
+3
-3
@@ -10,12 +10,12 @@
|
||||
|
||||
[](https://amnezia.org)
|
||||
|
||||
### [Сайт](https://amnezia.org) | [Зеркало на сайт](https://storage.googleapis.com/kldscp/amnezia.org) | [Документация](https://docs.amnezia.org) | [Решение проблем](https://docs.amnezia.org/troubleshooting)
|
||||
### [Сайт](https://amnezia.org) | [Зеркало на сайт](https://storage.googleapis.com/amnezia/amnezia.org) | [Документация](https://docs.amnezia.org) | [Решение проблем](https://docs.amnezia.org/troubleshooting)
|
||||
|
||||
> [!TIP]
|
||||
> Если [сайт Amnezia](https://amnezia.org) заблокирован в вашем регионе, вы можете воспользоваться [ссылкой на зеркало](https://storage.googleapis.com/kldscp/amnezia.org).
|
||||
> Если [сайт Amnezia](https://amnezia.org) заблокирован в вашем регионе, вы можете воспользоваться [ссылкой на зеркало](https://storage.googleapis.com/amnezia/amnezia.org).
|
||||
|
||||
<a href="https://storage.googleapis.com/kldscp/amnezia.org/downloads"><img src="https://github.com/amnezia-vpn/amnezia-client/blob/dev/metadata/img-readme/download-website-ru.svg" width="150" style="max-width: 100%; margin-right: 10px"></a>
|
||||
<a href="https://storage.googleapis.com/amnezia/q9p19109"><img src="https://github.com/amnezia-vpn/amnezia-client/blob/dev/metadata/img-readme/download-website-ru.svg" width="150" style="max-width: 100%; margin-right: 10px"></a>
|
||||
|
||||
|
||||
[Все релизы](https://github.com/amnezia-vpn/amnezia-client/releases)
|
||||
|
||||
+1
-1
Submodule client/3rd-prebuilt updated: ba580dc5bd...b714700add
Vendored
-1
Submodule client/3rd/OpenVPNAdapter deleted from 7c821a8d5c
@@ -96,11 +96,6 @@ configure_file(${CMAKE_CURRENT_LIST_DIR}/translations/translations.qrc.in ${CMAK
|
||||
qt6_add_resources(QRC ${I18NQRC} ${CMAKE_CURRENT_BINARY_DIR}/translations.qrc)
|
||||
# -- i18n end
|
||||
|
||||
if(IOS)
|
||||
execute_process(COMMAND bash ${CMAKE_CURRENT_LIST_DIR}/ios/scripts/openvpn.sh args
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})
|
||||
endif()
|
||||
|
||||
set(IS_CI ${CI})
|
||||
if(IS_CI)
|
||||
message("Detected CI env")
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#include <QClipboard>
|
||||
#include <QFontDatabase>
|
||||
#include <QLocalServer>
|
||||
#include <QLocalSocket>
|
||||
#include <QMimeData>
|
||||
#include <QQuickItem>
|
||||
#include <QQuickStyle>
|
||||
@@ -10,8 +12,6 @@
|
||||
#include <QTextDocument>
|
||||
#include <QTimer>
|
||||
#include <QTranslator>
|
||||
#include <QLocalSocket>
|
||||
#include <QLocalServer>
|
||||
|
||||
#include "logger.h"
|
||||
#include "ui/models/installedAppsModel.h"
|
||||
@@ -282,16 +282,17 @@ bool AmneziaApplication::parseCommands()
|
||||
}
|
||||
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
||||
void AmneziaApplication::startLocalServer() {
|
||||
void AmneziaApplication::startLocalServer()
|
||||
{
|
||||
const QString serverName("AmneziaVPNInstance");
|
||||
QLocalServer::removeServer(serverName);
|
||||
|
||||
QLocalServer* server = new QLocalServer(this);
|
||||
QLocalServer *server = new QLocalServer(this);
|
||||
server->listen(serverName);
|
||||
|
||||
QObject::connect(server, &QLocalServer::newConnection, this, [server, this]() {
|
||||
if (server) {
|
||||
QLocalSocket* clientConnection = server->nextPendingConnection();
|
||||
QLocalSocket *clientConnection = server->nextPendingConnection();
|
||||
clientConnection->deleteLater();
|
||||
}
|
||||
emit m_pageController->raiseMainWindow();
|
||||
@@ -418,7 +419,9 @@ void AmneziaApplication::initControllers()
|
||||
&ConnectionController::onCurrentContainerUpdated);
|
||||
|
||||
connect(m_installController.get(), &InstallController::updateServerFromApiFinished, this, [this]() {
|
||||
disconnect(m_reloadConfigErrorOccurredConnection);
|
||||
if (m_reloadConfigErrorOccurredConnection) {
|
||||
disconnect(m_reloadConfigErrorOccurredConnection);
|
||||
}
|
||||
emit m_connectionController->configFromApiUpdated();
|
||||
});
|
||||
|
||||
@@ -426,7 +429,7 @@ void AmneziaApplication::initControllers()
|
||||
m_reloadConfigErrorOccurredConnection = connect(
|
||||
m_installController.get(), qOverload<ErrorCode>(&InstallController::installationErrorOccurred), this,
|
||||
[this]() { emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Disconnected); },
|
||||
static_cast<Qt::ConnectionType>(Qt::AutoConnection || Qt::SingleShotConnection));
|
||||
static_cast<Qt::ConnectionType>(Qt::AutoConnection | Qt::SingleShotConnection));
|
||||
m_installController->updateServiceFromApi(m_serversModel->getDefaultServerIndex(), "", "");
|
||||
});
|
||||
|
||||
@@ -434,7 +437,7 @@ void AmneziaApplication::initControllers()
|
||||
m_reloadConfigErrorOccurredConnection = connect(
|
||||
m_installController.get(), qOverload<ErrorCode>(&InstallController::installationErrorOccurred), this,
|
||||
[this]() { emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Disconnected); },
|
||||
static_cast<Qt::ConnectionType>(Qt::AutoConnection || Qt::SingleShotConnection));
|
||||
static_cast<Qt::ConnectionType>(Qt::AutoConnection | Qt::SingleShotConnection));
|
||||
m_serversModel->removeApiConfig(m_serversModel->getDefaultServerIndex());
|
||||
m_installController->updateServiceFromTelegram(m_serversModel->getDefaultServerIndex());
|
||||
});
|
||||
|
||||
@@ -76,11 +76,7 @@ set_target_properties(${PROJECT} PROPERTIES
|
||||
XCODE_LINK_BUILD_PHASE_MODE KNOWN_LOCATION
|
||||
XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/Frameworks"
|
||||
XCODE_EMBED_APP_EXTENSIONS networkextension
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Apple Distribution"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY[variant=Debug] "Apple Development"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_STYLE Manual
|
||||
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER "match AppStore org.amnezia.AmneziaVPN"
|
||||
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER[variant=Debug] "match Development org.amnezia.AmneziaVPN"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_STYLE Automatic
|
||||
)
|
||||
set_target_properties(${PROJECT} PROPERTIES
|
||||
XCODE_ATTRIBUTE_SWIFT_VERSION "5.0"
|
||||
@@ -126,9 +122,9 @@ add_subdirectory(ios/networkextension)
|
||||
add_dependencies(${PROJECT} networkextension)
|
||||
|
||||
set_property(TARGET ${PROJECT} PROPERTY XCODE_EMBED_FRAMEWORKS
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/3rd/OpenVPNAdapter/build/Release-iphoneos/OpenVPNAdapter.framework"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/apple/OpenVPNAdapter-ios/OpenVPNAdapter.framework"
|
||||
)
|
||||
|
||||
set(CMAKE_XCODE_ATTRIBUTE_FRAMEWORK_SEARCH_PATHS ${CMAKE_CURRENT_SOURCE_DIR}/3rd/OpenVPNAdapter/build/Release-iphoneos)
|
||||
target_link_libraries("networkextension" PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/3rd/OpenVPNAdapter/build/Release-iphoneos/OpenVPNAdapter.framework")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_FRAMEWORK_SEARCH_PATHS ${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/apple/OpenVPNAdapter-ios/)
|
||||
target_link_libraries("networkextension" PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/apple/OpenVPNAdapter-ios/OpenVPNAdapter.framework")
|
||||
|
||||
|
||||
@@ -110,22 +110,19 @@ QMap<DockerContainer, QString> ContainerProps::containerDescriptions()
|
||||
QObject::tr("OpenVPN is the most popular VPN protocol, with flexible configuration options. It uses its "
|
||||
"own security protocol with SSL/TLS for key exchange.") },
|
||||
{ DockerContainer::ShadowSocks,
|
||||
QObject::tr("Shadowsocks - masks VPN traffic, making it similar to normal web traffic, but it "
|
||||
"may be recognized by analysis systems in some highly censored regions.") },
|
||||
QObject::tr("Shadowsocks masks VPN traffic, making it resemble normal web traffic, but it may still be detected by certain analysis systems.") },
|
||||
{ DockerContainer::Cloak,
|
||||
QObject::tr("OpenVPN over Cloak - OpenVPN with VPN masquerading as web traffic and protection against "
|
||||
"active-probing detection. Ideal for bypassing blocking in regions with the highest levels "
|
||||
"of censorship.") },
|
||||
"active-probing detection. It is very resistant to detection, but offers low speed.") },
|
||||
{ DockerContainer::WireGuard,
|
||||
QObject::tr("WireGuard - New popular VPN protocol with high performance, high speed and low power "
|
||||
"consumption. Recommended for regions with low levels of censorship.") },
|
||||
QObject::tr("WireGuard - popular VPN protocol with high performance, high speed and low power "
|
||||
"consumption.") },
|
||||
{ DockerContainer::Awg,
|
||||
QObject::tr("AmneziaWG - Special protocol from Amnezia, based on WireGuard. It's fast like WireGuard, "
|
||||
"but very resistant to blockages. "
|
||||
"Recommended for regions with high levels of censorship.") },
|
||||
QObject::tr("AmneziaWG is a special protocol from Amnezia based on WireGuard. "
|
||||
"It provides high connection speed and ensures stable operation even in the most challenging network conditions.") },
|
||||
{ DockerContainer::Xray,
|
||||
QObject::tr("XRay with REALITY - Suitable for countries with the highest level of internet censorship. "
|
||||
"Traffic masking as web traffic at the TLS level, and protection against detection by active probing methods.") },
|
||||
QObject::tr("XRay with REALITY masks VPN traffic as web traffic and protects against active probing. "
|
||||
"It is highly resistant to detection and offers high speed.") },
|
||||
{ DockerContainer::Ipsec,
|
||||
QObject::tr("IKEv2/IPsec - Modern stable protocol, a bit faster than others, restores connection after "
|
||||
"signal loss. It has native support on the latest versions of Android and iOS.") },
|
||||
@@ -144,20 +141,20 @@ QMap<DockerContainer, QString> ContainerProps::containerDetailedDescriptions()
|
||||
return {
|
||||
{ DockerContainer::OpenVpn,
|
||||
QObject::tr(
|
||||
"OpenVPN stands as one of the most popular and time-tested VPN protocols available.\n"
|
||||
"It employs its unique security protocol, "
|
||||
"leveraging the strength of SSL/TLS for encryption and key exchange. "
|
||||
"Furthermore, OpenVPN's support for a multitude of authentication methods makes it versatile and adaptable, "
|
||||
"catering to a wide range of devices and operating systems. "
|
||||
"Due to its open-source nature, OpenVPN benefits from extensive scrutiny by the global community, "
|
||||
"which continually reinforces its security. "
|
||||
"With a strong balance of performance, security, and compatibility, "
|
||||
"OpenVPN remains a top choice for privacy-conscious individuals and businesses alike.\n\n"
|
||||
"* Available in the AmneziaVPN across all platforms\n"
|
||||
"* Normal power consumption on mobile devices\n"
|
||||
"* Flexible customisation to suit user needs to work with different operating systems and devices\n"
|
||||
"* Recognised by DPI analysis systems and therefore susceptible to blocking\n"
|
||||
"* Can operate over both TCP and UDP network protocols.") },
|
||||
"OpenVPN stands as one of the most popular and time-tested VPN protocols available.\n"
|
||||
"It employs its unique security protocol, "
|
||||
"leveraging the strength of SSL/TLS for encryption and key exchange. "
|
||||
"Furthermore, OpenVPN's support for a multitude of authentication methods makes it versatile and adaptable, "
|
||||
"catering to a wide range of devices and operating systems. "
|
||||
"Due to its open-source nature, OpenVPN benefits from extensive scrutiny by the global community, "
|
||||
"which continually reinforces its security. "
|
||||
"With a strong balance of performance, security, and compatibility, "
|
||||
"OpenVPN remains a top choice for privacy-conscious individuals and businesses alike.\n\n"
|
||||
"* Available in the AmneziaVPN across all platforms\n"
|
||||
"* Normal power consumption on mobile devices\n"
|
||||
"* Flexible customisation to suit user needs to work with different operating systems and devices\n"
|
||||
"* Recognised by DPI systems and therefore susceptible to blocking\n"
|
||||
"* Can operate over both TCP and UDP network protocols.") },
|
||||
{ DockerContainer::ShadowSocks,
|
||||
QObject::tr("Shadowsocks, inspired by the SOCKS5 protocol, safeguards the connection using the AEAD cipher. "
|
||||
"Although Shadowsocks is designed to be discreet and challenging to identify, it isn't identical to a standard HTTPS connection."
|
||||
@@ -169,28 +166,26 @@ QMap<DockerContainer, QString> ContainerProps::containerDetailedDescriptions()
|
||||
"* Works over TCP network protocol.") },
|
||||
{ DockerContainer::Cloak,
|
||||
QObject::tr("This is a combination of the OpenVPN protocol and the Cloak plugin designed specifically for "
|
||||
"protecting against blocking.\n\n"
|
||||
"protecting against detection.\n\n"
|
||||
"OpenVPN provides a secure VPN connection by encrypting all internet traffic between the client "
|
||||
"and the server.\n\n"
|
||||
"Cloak protects OpenVPN from detection and blocking. \n\n"
|
||||
"Cloak protects OpenVPN from detection. \n\n"
|
||||
"Cloak can modify packet metadata so that it completely masks VPN traffic as normal web traffic, "
|
||||
"and also protects the VPN from detection by Active Probing. This makes it very resistant to "
|
||||
"being detected\n\n"
|
||||
"Immediately after receiving the first data packet, Cloak authenticates the incoming connection. "
|
||||
"If authentication fails, the plugin masks the server as a fake website and your VPN becomes "
|
||||
"invisible to analysis systems.\n\n"
|
||||
"If there is a extreme level of Internet censorship in your region, we advise you to use only "
|
||||
"OpenVPN over Cloak from the first connection\n\n"
|
||||
"* Available in the AmneziaVPN across all platforms\n"
|
||||
"* High power consumption on mobile devices\n"
|
||||
"* Flexible settings\n"
|
||||
"* Not recognised by DPI analysis systems\n"
|
||||
"* Not recognised by detection systems\n"
|
||||
"* Works over TCP network protocol, 443 port.\n") },
|
||||
{ DockerContainer::WireGuard,
|
||||
QObject::tr("A relatively new popular VPN protocol with a simplified architecture.\n"
|
||||
"WireGuard provides stable VPN connection and high performance on all devices. It uses hard-coded encryption "
|
||||
"settings. WireGuard compared to OpenVPN has lower latency and better data transfer throughput.\n"
|
||||
"WireGuard is very susceptible to blocking due to its distinct packet signatures. "
|
||||
"WireGuard is very susceptible to detection and blocking due to its distinct packet signatures. "
|
||||
"Unlike some other VPN protocols that employ obfuscation techniques, "
|
||||
"the consistent signature patterns of WireGuard packets can be more easily identified and "
|
||||
"thus blocked by advanced Deep Packet Inspection (DPI) systems and other network monitoring tools.\n\n"
|
||||
@@ -213,18 +208,18 @@ QMap<DockerContainer, QString> ContainerProps::containerDetailedDescriptions()
|
||||
"* Available in the AmneziaVPN across all platforms\n"
|
||||
"* Low power consumption\n"
|
||||
"* Minimum number of settings\n"
|
||||
"* Not recognised by DPI analysis systems, resistant to blocking\n"
|
||||
"* Not recognised by traffic analysis systems\n"
|
||||
"* Works over UDP network protocol.") },
|
||||
{ DockerContainer::Xray,
|
||||
QObject::tr("The REALITY protocol, a pioneering development by the creators of XRay, "
|
||||
"is specifically designed to counteract the highest levels of internet censorship through its novel approach to evasion.\n"
|
||||
"It uniquely identifies censors during the TLS handshake phase, seamlessly operating as a proxy for legitimate clients while diverting censors to genuine websites like google.com, "
|
||||
"thus presenting an authentic TLS certificate and data. \n"
|
||||
"This advanced capability differentiates REALITY from similar technologies by its ability to disguise web traffic as coming from random, "
|
||||
"legitimate sites without the need for specific configurations. \n"
|
||||
"Unlike older protocols such as VMess, VLESS, and the XTLS-Vision transport, "
|
||||
"REALITY's innovative \"friend or foe\" recognition at the TLS handshake enhances security and circumvents detection by sophisticated DPI systems employing active probing techniques. "
|
||||
"This makes REALITY a robust solution for maintaining internet freedom in environments with stringent censorship.")
|
||||
QObject::tr("The REALITY protocol, a pioneering development by the creators of XRay, "
|
||||
"is designed to provide the highest level of protection against detection through its innovative approach to security and privacy.\n"
|
||||
"It uniquely identifies attackers during the TLS handshake phase, seamlessly operating as a proxy for legitimate clients while diverting attackers to genuine websites, "
|
||||
"thus presenting an authentic TLS certificate and data. \n"
|
||||
"This advanced capability differentiates REALITY from similar technologies by its ability to disguise web traffic as coming from random, "
|
||||
"legitimate sites without the need for specific configurations. \n"
|
||||
"Unlike older protocols such as VMess, VLESS, and the XTLS-Vision transport, "
|
||||
"REALITY's innovative \"friend or foe\" recognition at the TLS handshake enhances security. "
|
||||
"This makes REALITY a robust solution for maintaining internet freedom.")
|
||||
},
|
||||
{ DockerContainer::Ipsec,
|
||||
QObject::tr("IKEv2, paired with the IPSec encryption layer, stands as a modern and stable VPN protocol.\n"
|
||||
@@ -332,9 +327,7 @@ QStringList ContainerProps::fixedPortsForContainer(DockerContainer c)
|
||||
bool ContainerProps::isEasySetupContainer(DockerContainer container)
|
||||
{
|
||||
switch (container) {
|
||||
case DockerContainer::WireGuard: return true;
|
||||
case DockerContainer::Awg: return true;
|
||||
// case DockerContainer::Cloak: return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
@@ -342,9 +335,7 @@ bool ContainerProps::isEasySetupContainer(DockerContainer container)
|
||||
QString ContainerProps::easySetupHeader(DockerContainer container)
|
||||
{
|
||||
switch (container) {
|
||||
case DockerContainer::WireGuard: return tr("Low");
|
||||
case DockerContainer::Awg: return tr("High");
|
||||
// case DockerContainer::Cloak: return tr("Extreme");
|
||||
case DockerContainer::Awg: return tr("Automatic");
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
@@ -352,10 +343,8 @@ QString ContainerProps::easySetupHeader(DockerContainer container)
|
||||
QString ContainerProps::easySetupDescription(DockerContainer container)
|
||||
{
|
||||
switch (container) {
|
||||
case DockerContainer::WireGuard: return tr("I just want to increase the level of my privacy.");
|
||||
case DockerContainer::Awg: return tr("I want to bypass censorship. This option recommended in most cases.");
|
||||
// case DockerContainer::Cloak:
|
||||
// return tr("Most VPN protocols are blocked. Recommended if other options are not working.");
|
||||
case DockerContainer::Awg: return tr("AmneziaWG protocol will be installed. "
|
||||
"It provides high connection speed and ensures stable operation even in the most challenging network conditions.");
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
@@ -363,9 +352,7 @@ QString ContainerProps::easySetupDescription(DockerContainer container)
|
||||
int ContainerProps::easySetupOrder(DockerContainer container)
|
||||
{
|
||||
switch (container) {
|
||||
case DockerContainer::WireGuard: return 3;
|
||||
case DockerContainer::Awg: return 2;
|
||||
// case DockerContainer::Cloak: return 1;
|
||||
case DockerContainer::Awg: return 1;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
@@ -384,9 +371,9 @@ bool ContainerProps::isShareable(DockerContainer container)
|
||||
QJsonObject ContainerProps::getProtocolConfigFromContainer(const Proto protocol, const QJsonObject &containerConfig)
|
||||
{
|
||||
QString protocolConfigString = containerConfig.value(ProtocolProps::protoToString(protocol))
|
||||
.toObject()
|
||||
.value(config_key::last_config)
|
||||
.toString();
|
||||
.toObject()
|
||||
.value(config_key::last_config)
|
||||
.toString();
|
||||
|
||||
return QJsonDocument::fromJson(protocolConfigString.toUtf8()).object();
|
||||
}
|
||||
|
||||
@@ -308,6 +308,8 @@ void ApiController::updateServerConfigFromApi(const QString &installationUuid, c
|
||||
if (reply->error() == QNetworkReply::NetworkError::OperationCanceledError
|
||||
|| reply->error() == QNetworkReply::NetworkError::TimeoutError) {
|
||||
emit errorOccurred(ErrorCode::ApiConfigTimeoutError);
|
||||
} else if (reply->error() == QNetworkReply::NetworkError::SslHandshakeFailedError) {
|
||||
emit errorOccurred(ErrorCode::ApiConfigSslError);
|
||||
} else {
|
||||
QString err = reply->errorString();
|
||||
qDebug() << QString::fromUtf8(reply->readAll());
|
||||
@@ -323,10 +325,8 @@ void ApiController::updateServerConfigFromApi(const QString &installationUuid, c
|
||||
|
||||
QObject::connect(reply, &QNetworkReply::errorOccurred,
|
||||
[this, reply](QNetworkReply::NetworkError error) { qDebug() << reply->errorString() << error; });
|
||||
connect(reply, &QNetworkReply::sslErrors, [this, reply](const QList<QSslError> &errors) {
|
||||
qDebug().noquote() << errors;
|
||||
emit errorOccurred(ErrorCode::ApiConfigSslError);
|
||||
});
|
||||
|
||||
connect(reply, &QNetworkReply::sslErrors, [this, reply](const QList<QSslError> &errors) { qDebug().noquote() << errors; });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,12 +27,7 @@ set_target_properties(networkextension PROPERTIES
|
||||
|
||||
XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/../../Frameworks"
|
||||
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Apple Distribution"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY[variant=Debug] "Apple Development"
|
||||
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_STYLE Manual
|
||||
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER "match AppStore org.amnezia.AmneziaVPN.network-extension"
|
||||
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER[variant=Debug] "match Development org.amnezia.AmneziaVPN.network-extension"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_STYLE Automatic
|
||||
)
|
||||
|
||||
set_target_properties(networkextension PROPERTIES
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
XCODEBUILD="/usr/bin/xcodebuild"
|
||||
WORKINGDIR=`pwd`
|
||||
PATCH="/usr/bin/patch"
|
||||
|
||||
cat $WORKINGDIR/3rd/OpenVPNAdapter/Configuration/Project.xcconfig > $WORKINGDIR/3rd/OpenVPNAdapter/Configuration/amnezia.xcconfig
|
||||
cat << EOF >> $WORKINGDIR/3rd/OpenVPNAdapter/Configuration/amnezia.xcconfig
|
||||
PROJECT_TEMP_DIR = $WORKINGDIR/3rd/OpenVPNAdapter/build/OpenVPNAdapter.build
|
||||
CONFIGURATION_BUILD_DIR = $WORKINGDIR/3rd/OpenVPNAdapter/build/Release-iphoneos
|
||||
BUILT_PRODUCTS_DIR = $WORKINGDIR/3rd/OpenVPNAdapter/build/Release-iphoneos
|
||||
EOF
|
||||
|
||||
|
||||
cd 3rd/OpenVPNAdapter
|
||||
if $XCODEBUILD -scheme OpenVPNAdapter -configuration Release -xcconfig Configuration/amnezia.xcconfig -sdk iphoneos -destination 'generic/platform=iOS' -project OpenVPNAdapter.xcodeproj ; then
|
||||
echo "OpenVPNAdapter built successfully"
|
||||
else
|
||||
echo "OpenVPNAdapter build failed"
|
||||
fi
|
||||
cd ../../
|
||||
@@ -1,4 +1,5 @@
|
||||
import HevSocks5Tunnel
|
||||
import NetworkExtension
|
||||
|
||||
public enum Socks5Tunnel {
|
||||
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
#include "xrayprotocol.h"
|
||||
|
||||
#include "utilities.h"
|
||||
#include "core/networkUtilities.h"
|
||||
|
||||
#include <QCryptographicHash>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QNetworkInterface>
|
||||
|
||||
#include "core/networkUtilities.h"
|
||||
#include "utilities.h"
|
||||
|
||||
XrayProtocol::XrayProtocol(const QJsonObject &configuration, QObject *parent):
|
||||
VpnProtocol(configuration, parent)
|
||||
XrayProtocol::XrayProtocol(const QJsonObject &configuration, QObject *parent) : VpnProtocol(configuration, parent)
|
||||
{
|
||||
readXrayConfiguration(configuration);
|
||||
m_routeGateway = NetworkUtilities::getGatewayAndIface();
|
||||
@@ -45,10 +43,7 @@ ErrorCode XrayProtocol::start()
|
||||
|
||||
QStringList args = QStringList() << "-c" << m_xrayCfgFile.fileName() << "-format=json";
|
||||
|
||||
qDebug().noquote() << "XrayProtocol::start()"
|
||||
<< xrayExecPath() << args.join(" ");
|
||||
|
||||
|
||||
qDebug().noquote() << "XrayProtocol::start()" << xrayExecPath() << args.join(" ");
|
||||
|
||||
m_xrayProcess.setProcessChannelMode(QProcess::MergedChannels);
|
||||
m_xrayProcess.setProgram(xrayExecPath());
|
||||
@@ -66,14 +61,15 @@ ErrorCode XrayProtocol::start()
|
||||
#endif
|
||||
});
|
||||
|
||||
connect(&m_xrayProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, [this](int exitCode, QProcess::ExitStatus exitStatus) {
|
||||
qDebug().noquote() << "XrayProtocol finished, exitCode, exitStatus" << exitCode << exitStatus;
|
||||
setConnectionState(Vpn::ConnectionState::Disconnected);
|
||||
if ((exitStatus != QProcess::NormalExit) || (exitCode != 0)) {
|
||||
emit protocolError(amnezia::ErrorCode::XrayExecutableCrashed);
|
||||
emit setConnectionState(Vpn::ConnectionState::Error);
|
||||
}
|
||||
});
|
||||
connect(&m_xrayProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this,
|
||||
[this](int exitCode, QProcess::ExitStatus exitStatus) {
|
||||
qDebug().noquote() << "XrayProtocol finished, exitCode, exitStatus" << exitCode << exitStatus;
|
||||
setConnectionState(Vpn::ConnectionState::Disconnected);
|
||||
if ((exitStatus != QProcess::NormalExit) || (exitCode != 0)) {
|
||||
emit protocolError(amnezia::ErrorCode::XrayExecutableCrashed);
|
||||
emit setConnectionState(Vpn::ConnectionState::Error);
|
||||
}
|
||||
});
|
||||
|
||||
m_xrayProcess.start();
|
||||
m_xrayProcess.waitForStarted();
|
||||
@@ -82,11 +78,10 @@ ErrorCode XrayProtocol::start()
|
||||
setConnectionState(Vpn::ConnectionState::Connecting);
|
||||
QThread::msleep(1000);
|
||||
return startTun2Sock();
|
||||
}
|
||||
else return ErrorCode::XrayExecutableMissing;
|
||||
} else
|
||||
return ErrorCode::XrayExecutableMissing;
|
||||
}
|
||||
|
||||
|
||||
ErrorCode XrayProtocol::startTun2Sock()
|
||||
{
|
||||
m_t2sProcess->start();
|
||||
@@ -98,71 +93,68 @@ ErrorCode XrayProtocol::startTun2Sock()
|
||||
connect(m_t2sProcess.data(), &IpcProcessTun2SocksReplica::stateChanged, this,
|
||||
[&](QProcess::ProcessState newState) { qDebug() << "PrivilegedProcess stateChanged" << newState; });
|
||||
|
||||
connect(m_t2sProcess.data(), &IpcProcessTun2SocksReplica::setConnectionState, this,
|
||||
[&](int vpnState) {
|
||||
qDebug() << "PrivilegedProcess setConnectionState " << vpnState;
|
||||
if (vpnState == Vpn::ConnectionState::Connected)
|
||||
{
|
||||
setConnectionState(Vpn::ConnectionState::Connecting);
|
||||
QList<QHostAddress> dnsAddr;
|
||||
dnsAddr.push_back(QHostAddress(m_configData.value(config_key::dns1).toString()));
|
||||
dnsAddr.push_back(QHostAddress(m_configData.value(config_key::dns2).toString()));
|
||||
connect(m_t2sProcess.data(), &IpcProcessTun2SocksReplica::setConnectionState, this, [&](int vpnState) {
|
||||
qDebug() << "PrivilegedProcess setConnectionState " << vpnState;
|
||||
if (vpnState == Vpn::ConnectionState::Connected) {
|
||||
setConnectionState(Vpn::ConnectionState::Connecting);
|
||||
QList<QHostAddress> dnsAddr;
|
||||
dnsAddr.push_back(QHostAddress(m_configData.value(config_key::dns1).toString()));
|
||||
dnsAddr.push_back(QHostAddress(m_configData.value(config_key::dns2).toString()));
|
||||
#ifdef Q_OS_WIN
|
||||
QThread::msleep(8000);
|
||||
QThread::msleep(8000);
|
||||
#endif
|
||||
#ifdef Q_OS_MACOS
|
||||
QThread::msleep(5000);
|
||||
IpcClient::Interface()->createTun("utun22", amnezia::protocols::xray::defaultLocalAddr);
|
||||
IpcClient::Interface()->updateResolvers("utun22", dnsAddr);
|
||||
QThread::msleep(5000);
|
||||
IpcClient::Interface()->createTun("utun22", amnezia::protocols::xray::defaultLocalAddr);
|
||||
IpcClient::Interface()->updateResolvers("utun22", dnsAddr);
|
||||
#endif
|
||||
#ifdef Q_OS_LINUX
|
||||
QThread::msleep(1000);
|
||||
IpcClient::Interface()->createTun("tun2", amnezia::protocols::xray::defaultLocalAddr);
|
||||
IpcClient::Interface()->updateResolvers("tun2", dnsAddr);
|
||||
QThread::msleep(1000);
|
||||
IpcClient::Interface()->createTun("tun2", amnezia::protocols::xray::defaultLocalAddr);
|
||||
IpcClient::Interface()->updateResolvers("tun2", dnsAddr);
|
||||
#endif
|
||||
#if defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
|
||||
// killSwitch toggle
|
||||
if (QVariant(m_configData.value(config_key::killSwitchOption).toString()).toBool()) {
|
||||
m_configData.insert("vpnServer", m_remoteAddress);
|
||||
IpcClient::Interface()->enableKillSwitch(m_configData, 0);
|
||||
}
|
||||
// killSwitch toggle
|
||||
if (QVariant(m_configData.value(config_key::killSwitchOption).toString()).toBool()) {
|
||||
m_configData.insert("vpnServer", m_remoteAddress);
|
||||
IpcClient::Interface()->enableKillSwitch(m_configData, 0);
|
||||
}
|
||||
#endif
|
||||
if (m_routeMode == 0) {
|
||||
IpcClient::Interface()->routeAddList(m_vpnGateway, QStringList() << "0.0.0.0/1");
|
||||
IpcClient::Interface()->routeAddList(m_vpnGateway, QStringList() << "128.0.0.0/1");
|
||||
IpcClient::Interface()->routeAddList(m_routeGateway, QStringList() << m_remoteAddress);
|
||||
}
|
||||
IpcClient::Interface()->StopRoutingIpv6();
|
||||
if (m_routeMode == Settings::RouteMode::VpnAllSites) {
|
||||
IpcClient::Interface()->routeAddList(m_vpnGateway, QStringList() << "0.0.0.0/1");
|
||||
IpcClient::Interface()->routeAddList(m_vpnGateway, QStringList() << "128.0.0.0/1");
|
||||
IpcClient::Interface()->routeAddList(m_routeGateway, QStringList() << m_remoteAddress);
|
||||
}
|
||||
IpcClient::Interface()->StopRoutingIpv6();
|
||||
#ifdef Q_OS_WIN
|
||||
IpcClient::Interface()->updateResolvers("tun2", dnsAddr);
|
||||
QList<QNetworkInterface> netInterfaces = QNetworkInterface::allInterfaces();
|
||||
for (int i = 0; i < netInterfaces.size(); i++) {
|
||||
for (int j = 0; j < netInterfaces.at(i).addressEntries().size(); j++)
|
||||
{
|
||||
// killSwitch toggle
|
||||
if (m_vpnLocalAddress == netInterfaces.at(i).addressEntries().at(j).ip().toString()) {
|
||||
if (QVariant(m_configData.value(config_key::killSwitchOption).toString()).toBool()) {
|
||||
IpcClient::Interface()->enableKillSwitch(QJsonObject(), netInterfaces.at(i).index());
|
||||
}
|
||||
m_configData.insert("vpnAdapterIndex", netInterfaces.at(i).index());
|
||||
m_configData.insert("vpnGateway", m_vpnGateway);
|
||||
m_configData.insert("vpnServer", m_remoteAddress);
|
||||
IpcClient::Interface()->enablePeerTraffic(m_configData);
|
||||
}
|
||||
IpcClient::Interface()->updateResolvers("tun2", dnsAddr);
|
||||
QList<QNetworkInterface> netInterfaces = QNetworkInterface::allInterfaces();
|
||||
for (int i = 0; i < netInterfaces.size(); i++) {
|
||||
for (int j = 0; j < netInterfaces.at(i).addressEntries().size(); j++) {
|
||||
// killSwitch toggle
|
||||
if (m_vpnLocalAddress == netInterfaces.at(i).addressEntries().at(j).ip().toString()) {
|
||||
if (QVariant(m_configData.value(config_key::killSwitchOption).toString()).toBool()) {
|
||||
IpcClient::Interface()->enableKillSwitch(QJsonObject(), netInterfaces.at(i).index());
|
||||
}
|
||||
m_configData.insert("vpnAdapterIndex", netInterfaces.at(i).index());
|
||||
m_configData.insert("vpnGateway", m_vpnGateway);
|
||||
m_configData.insert("vpnServer", m_remoteAddress);
|
||||
IpcClient::Interface()->enablePeerTraffic(m_configData);
|
||||
}
|
||||
#endif
|
||||
setConnectionState(Vpn::ConnectionState::Connected);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
setConnectionState(Vpn::ConnectionState::Connected);
|
||||
}
|
||||
#if !defined(Q_OS_MACOS)
|
||||
if (vpnState == Vpn::ConnectionState::Disconnected) {
|
||||
setConnectionState(Vpn::ConnectionState::Disconnected);
|
||||
IpcClient::Interface()->deleteTun("tun2");
|
||||
IpcClient::Interface()->StartRoutingIpv6();
|
||||
IpcClient::Interface()->clearSavedRoutes();
|
||||
}
|
||||
if (vpnState == Vpn::ConnectionState::Disconnected) {
|
||||
setConnectionState(Vpn::ConnectionState::Disconnected);
|
||||
IpcClient::Interface()->deleteTun("tun2");
|
||||
IpcClient::Interface()->StartRoutingIpv6();
|
||||
IpcClient::Interface()->clearSavedRoutes();
|
||||
}
|
||||
#endif
|
||||
});
|
||||
});
|
||||
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
@@ -204,7 +196,7 @@ void XrayProtocol::readXrayConfiguration(const QJsonObject &configuration)
|
||||
m_localPort = QString(amnezia::protocols::xray::defaultLocalProxyPort).toInt();
|
||||
m_remoteHost = configuration.value(amnezia::config_key::hostName).toString();
|
||||
m_remoteAddress = NetworkUtilities::getIPAddress(m_remoteHost);
|
||||
m_routeMode = configuration.value(amnezia::config_key::splitTunnelType).toInt();
|
||||
m_routeMode = static_cast<Settings::RouteMode>(configuration.value(amnezia::config_key::splitTunnelType).toInt());
|
||||
m_primaryDNS = configuration.value(amnezia::config_key::dns1).toString();
|
||||
m_secondaryDNS = configuration.value(amnezia::config_key::dns2).toString();
|
||||
}
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
#ifndef XRAYPROTOCOL_H
|
||||
#define XRAYPROTOCOL_H
|
||||
|
||||
#include "openvpnprotocol.h"
|
||||
#include "QProcess"
|
||||
|
||||
#include "containers/containers_defs.h"
|
||||
#include "openvpnprotocol.h"
|
||||
#include "settings.h"
|
||||
|
||||
class XrayProtocol : public VpnProtocol
|
||||
{
|
||||
public:
|
||||
XrayProtocol(const QJsonObject& configuration, QObject* parent = nullptr);
|
||||
XrayProtocol(const QJsonObject &configuration, QObject *parent = nullptr);
|
||||
virtual ~XrayProtocol() override;
|
||||
|
||||
ErrorCode start() override;
|
||||
@@ -24,11 +26,12 @@ protected:
|
||||
private:
|
||||
static QString xrayExecPath();
|
||||
static QString tun2SocksExecPath();
|
||||
|
||||
private:
|
||||
int m_localPort;
|
||||
QString m_remoteHost;
|
||||
QString m_remoteAddress;
|
||||
int m_routeMode;
|
||||
Settings::RouteMode m_routeMode;
|
||||
QJsonObject m_configData;
|
||||
QString m_primaryDNS;
|
||||
QString m_secondaryDNS;
|
||||
@@ -37,7 +40,6 @@ private:
|
||||
QSharedPointer<IpcProcessTun2SocksReplica> m_t2sProcess;
|
||||
#endif
|
||||
QTemporaryFile m_xrayCfgFile;
|
||||
|
||||
};
|
||||
|
||||
#endif // XRAYPROTOCOL_H
|
||||
|
||||
@@ -65,11 +65,11 @@ QVariant ApiServicesModel::data(const QModelIndex &index, int role) const
|
||||
case CardDescriptionRole: {
|
||||
auto speed = apiServiceData.serviceInfo.speed;
|
||||
if (serviceType == serviceType::amneziaPremium) {
|
||||
return tr("Classic VPN for comfortable work, downloading large files and watching videos. "
|
||||
"Works for any sites. Speed up to %1 MBit/s")
|
||||
return tr("Amnezia Premium is VPN for comfortable work, downloading large files and watching videos in 8K resolution. "
|
||||
"Works for any sites with no restrictions. Speed up to %1 MBit/s. Unlimited traffic.")
|
||||
.arg(speed);
|
||||
} else if (serviceType == serviceType::amneziaFree) {
|
||||
QString description = tr("VPN to access blocked sites in regions with high levels of Internet censorship. ");
|
||||
QString description = tr("AmneziaFree provides free unlimited access to a basic set of web sites, such as Facebook, Instagram, Twitter (X), Discord, Telegram, and others. YouTube is not included in the free plan.");
|
||||
if (!isServiceAvailable) {
|
||||
description += tr("<p><a style=\"color: #EB5757;\">Not available in your region. If you have VPN enabled, disable it, "
|
||||
"return to the previous screen, and try again.</a>");
|
||||
@@ -79,11 +79,10 @@ QVariant ApiServicesModel::data(const QModelIndex &index, int role) const
|
||||
}
|
||||
case ServiceDescriptionRole: {
|
||||
if (serviceType == serviceType::amneziaPremium) {
|
||||
return tr("Amnezia Premium - A classic VPN for comfortable work, downloading large files, and watching videos in high "
|
||||
"resolution. "
|
||||
"It works for all websites, even in countries with the highest level of internet censorship.");
|
||||
return tr("Amnezia Premium is VPN for comfortable work, downloading large files and watching videos in 8K resolution. "
|
||||
"Works for any sites with no restrictions.");
|
||||
} else {
|
||||
return tr("Amnezia Free is a free VPN to bypass blocking in countries with high levels of internet censorship");
|
||||
return tr("AmneziaFree provides free unlimited access to a basic set of web sites, such as Facebook, Instagram, Twitter (X), Discord, Telegram, and others. YouTube is not included in the free plan.");
|
||||
}
|
||||
}
|
||||
case IsServiceAvailableRole: {
|
||||
@@ -146,13 +145,6 @@ void ApiServicesModel::updateModel(const QJsonObject &data)
|
||||
} else {
|
||||
for (const auto &service : services) {
|
||||
auto serviceObject = service.toObject();
|
||||
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
||||
if (serviceObject.value(configKey::serviceType).toString() == serviceType::amneziaPremium) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
m_services.push_back(getApiServicesData(serviceObject));
|
||||
}
|
||||
}
|
||||
@@ -255,7 +247,7 @@ ApiServicesModel::ApiServicesData ApiServicesModel::getApiServicesData(const QJs
|
||||
serviceData.type = serviceType;
|
||||
serviceData.protocol = serviceProtocol;
|
||||
|
||||
serviceData.storeEndpoint = serviceInfo.value(configKey::storeEndpoint).toString();
|
||||
serviceData.storeEndpoint = data.value(configKey::storeEndpoint).toString();
|
||||
|
||||
if (data.value(configKey::isAvailable).isBool()) {
|
||||
serviceData.isServiceAvailable = data.value(configKey::isAvailable).toBool();
|
||||
|
||||
@@ -108,7 +108,7 @@ QString LanguageModel::getCurrentSiteUrl()
|
||||
{
|
||||
auto language = static_cast<LanguageSettings::AvailableLanguageEnum>(getCurrentLanguageIndex());
|
||||
switch (language) {
|
||||
case LanguageSettings::AvailableLanguageEnum::Russian: return "https://storage.googleapis.com/kldscp/amnezia.org";
|
||||
case LanguageSettings::AvailableLanguageEnum::Russian: return "https://storage.googleapis.com/amnezia/amnezia.org";
|
||||
default: return "https://amnezia.org";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ DrawerType2 {
|
||||
|
||||
backgroundColor: AmneziaStyle.color.slateGray
|
||||
|
||||
textFieldPlaceholderText: qsTr("application name")
|
||||
textField.placeholderText: qsTr("application name")
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
|
||||
@@ -22,11 +22,9 @@ Item {
|
||||
property var clickedFunc
|
||||
|
||||
property alias textField: textField
|
||||
property alias textFieldText: textField.text
|
||||
property string textFieldTextColor: AmneziaStyle.color.paleGray
|
||||
property string textFieldTextDisabledColor: AmneziaStyle.color.mutedGray
|
||||
|
||||
property string textFieldPlaceholderText
|
||||
property bool textFieldEditable: true
|
||||
|
||||
property string borderColor: AmneziaStyle.color.slateGray
|
||||
@@ -101,7 +99,6 @@ Item {
|
||||
|
||||
inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhSensitiveData | Qt.ImhNoPredictiveText
|
||||
|
||||
placeholderText: root.textFieldPlaceholderText
|
||||
placeholderTextColor: AmneziaStyle.color.charcoalGray
|
||||
|
||||
selectionColor: AmneziaStyle.color.richBrown
|
||||
@@ -129,8 +126,8 @@ Item {
|
||||
}
|
||||
|
||||
onActiveFocusChanged: {
|
||||
if (checkEmptyText && textFieldText === "") {
|
||||
errorText = qsTr("The field can't be empty")
|
||||
if (root.checkEmptyText && text === "") {
|
||||
root.errorText = qsTr("The field can't be empty")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -66,18 +66,18 @@ PageType {
|
||||
Layout.leftMargin: 16
|
||||
|
||||
headerText: qsTr("Gateway endpoint")
|
||||
textFieldText: SettingsController.gatewayEndpoint
|
||||
textField.text: SettingsController.gatewayEndpoint
|
||||
|
||||
buttonImageSource: textFieldText !== "" ? "qrc:/images/controls/refresh-cw.svg" : ""
|
||||
buttonImageSource: textField.text !== "" ? "qrc:/images/controls/refresh-cw.svg" : ""
|
||||
|
||||
clickedFunc: function() {
|
||||
SettingsController.resetGatewayEndpoint()
|
||||
}
|
||||
|
||||
textField.onEditingFinished: {
|
||||
textFieldText = textField.text.replace(/^\s+|\s+$/g, '')
|
||||
if (textFieldText !== SettingsController.gatewayEndpoint) {
|
||||
SettingsController.gatewayEndpoint = textFieldText
|
||||
textField.text = textField.text.replace(/^\s+|\s+$/g, '')
|
||||
if (textField.text !== SettingsController.gatewayEndpoint) {
|
||||
SettingsController.gatewayEndpoint = textField.text
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,12 +103,12 @@ PageType {
|
||||
Layout.topMargin: 40
|
||||
|
||||
headerText: qsTr("MTU")
|
||||
textFieldText: clientMtu
|
||||
textField.text: clientMtu
|
||||
textField.validator: IntValidator { bottom: 576; top: 65535 }
|
||||
|
||||
textField.onEditingFinished: {
|
||||
if (textFieldText !== clientMtu) {
|
||||
clientMtu = textFieldText
|
||||
if (textField.text !== clientMtu) {
|
||||
clientMtu = textField.text
|
||||
}
|
||||
}
|
||||
checkEmptyText: true
|
||||
@@ -121,12 +121,12 @@ PageType {
|
||||
Layout.topMargin: 16
|
||||
|
||||
headerText: "Jc - Junk packet count"
|
||||
textFieldText: clientJunkPacketCount
|
||||
textField.text: clientJunkPacketCount
|
||||
textField.validator: IntValidator { bottom: 0 }
|
||||
|
||||
textField.onEditingFinished: {
|
||||
if (textFieldText !== clientJunkPacketCount) {
|
||||
clientJunkPacketCount = textFieldText
|
||||
if (textField.text !== clientJunkPacketCount) {
|
||||
clientJunkPacketCount = textField.text
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,12 +141,12 @@ PageType {
|
||||
Layout.topMargin: 16
|
||||
|
||||
headerText: "Jmin - Junk packet minimum size"
|
||||
textFieldText: clientJunkPacketMinSize
|
||||
textField.text: clientJunkPacketMinSize
|
||||
textField.validator: IntValidator { bottom: 0 }
|
||||
|
||||
textField.onEditingFinished: {
|
||||
if (textFieldText !== clientJunkPacketMinSize) {
|
||||
clientJunkPacketMinSize = textFieldText
|
||||
if (textField.text !== clientJunkPacketMinSize) {
|
||||
clientJunkPacketMinSize = textField.text
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,12 +161,12 @@ PageType {
|
||||
Layout.topMargin: 16
|
||||
|
||||
headerText: "Jmax - Junk packet maximum size"
|
||||
textFieldText: clientJunkPacketMaxSize
|
||||
textField.text: clientJunkPacketMaxSize
|
||||
textField.validator: IntValidator { bottom: 0 }
|
||||
|
||||
textField.onEditingFinished: {
|
||||
if (textFieldText !== clientJunkPacketMaxSize) {
|
||||
clientJunkPacketMaxSize = textFieldText
|
||||
if (textField.text !== clientJunkPacketMaxSize) {
|
||||
clientJunkPacketMaxSize = textField.text
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ PageType {
|
||||
enabled: false
|
||||
|
||||
headerText: qsTr("Port")
|
||||
textFieldText: port
|
||||
textField.text: port
|
||||
}
|
||||
|
||||
TextFieldWithHeaderType {
|
||||
@@ -200,7 +200,7 @@ PageType {
|
||||
enabled: false
|
||||
|
||||
headerText: "S1 - Init packet junk size"
|
||||
textFieldText: serverInitPacketJunkSize
|
||||
textField.text: serverInitPacketJunkSize
|
||||
}
|
||||
|
||||
TextFieldWithHeaderType {
|
||||
@@ -211,7 +211,7 @@ PageType {
|
||||
enabled: false
|
||||
|
||||
headerText: "S2 - Response packet junk size"
|
||||
textFieldText: serverResponsePacketJunkSize
|
||||
textField.text: serverResponsePacketJunkSize
|
||||
}
|
||||
|
||||
TextFieldWithHeaderType {
|
||||
@@ -222,7 +222,7 @@ PageType {
|
||||
enabled: false
|
||||
|
||||
headerText: "H1 - Init packet magic header"
|
||||
textFieldText: serverInitPacketMagicHeader
|
||||
textField.text: serverInitPacketMagicHeader
|
||||
}
|
||||
|
||||
TextFieldWithHeaderType {
|
||||
@@ -233,7 +233,7 @@ PageType {
|
||||
enabled: false
|
||||
|
||||
headerText: "H2 - Response packet magic header"
|
||||
textFieldText: serverResponsePacketMagicHeader
|
||||
textField.text: serverResponsePacketMagicHeader
|
||||
}
|
||||
|
||||
TextFieldWithHeaderType {
|
||||
@@ -244,7 +244,7 @@ PageType {
|
||||
enabled: false
|
||||
|
||||
headerText: "H3 - Underload packet magic header"
|
||||
textFieldText: serverUnderloadPacketMagicHeader
|
||||
textField.text: serverUnderloadPacketMagicHeader
|
||||
}
|
||||
|
||||
TextFieldWithHeaderType {
|
||||
@@ -255,7 +255,7 @@ PageType {
|
||||
enabled: false
|
||||
|
||||
headerText: "H4 - Transport packet magic header"
|
||||
textFieldText: serverTransportPacketMagicHeader
|
||||
textField.text: serverTransportPacketMagicHeader
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,11 +106,11 @@ PageType {
|
||||
enabled: delegateItem.isEnabled
|
||||
|
||||
headerText: qsTr("VPN address subnet")
|
||||
textFieldText: subnetAddress
|
||||
textField.text: subnetAddress
|
||||
|
||||
textField.onEditingFinished: {
|
||||
if (textFieldText !== subnetAddress) {
|
||||
subnetAddress = textFieldText
|
||||
if (textField.text !== subnetAddress) {
|
||||
subnetAddress = textField.text
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,13 +125,13 @@ PageType {
|
||||
enabled: delegateItem.isEnabled
|
||||
|
||||
headerText: qsTr("Port")
|
||||
textFieldText: port
|
||||
textField.text: port
|
||||
textField.maximumLength: 5
|
||||
textField.validator: IntValidator { bottom: 1; top: 65535 }
|
||||
|
||||
textField.onEditingFinished: {
|
||||
if (textFieldText !== port) {
|
||||
port = textFieldText
|
||||
if (textField.text !== port) {
|
||||
port = textField.text
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,16 +144,16 @@ PageType {
|
||||
Layout.topMargin: 16
|
||||
|
||||
headerText: qsTr("Jc - Junk packet count")
|
||||
textFieldText: serverJunkPacketCount
|
||||
textField.text: serverJunkPacketCount
|
||||
textField.validator: IntValidator { bottom: 0 }
|
||||
|
||||
textField.onEditingFinished: {
|
||||
if (textFieldText === "") {
|
||||
textFieldText = "0"
|
||||
if (textField.text === "") {
|
||||
textField.text = "0"
|
||||
}
|
||||
|
||||
if (textFieldText !== serverJunkPacketCount) {
|
||||
serverJunkPacketCount = textFieldText
|
||||
if (textField.text !== serverJunkPacketCount) {
|
||||
serverJunkPacketCount = textField.text
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,12 +166,12 @@ PageType {
|
||||
Layout.topMargin: 16
|
||||
|
||||
headerText: qsTr("Jmin - Junk packet minimum size")
|
||||
textFieldText: serverJunkPacketMinSize
|
||||
textField.text: serverJunkPacketMinSize
|
||||
textField.validator: IntValidator { bottom: 0 }
|
||||
|
||||
textField.onEditingFinished: {
|
||||
if (textFieldText !== serverJunkPacketMinSize) {
|
||||
serverJunkPacketMinSize = textFieldText
|
||||
if (textField.text !== serverJunkPacketMinSize) {
|
||||
serverJunkPacketMinSize = textField.text
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,12 +184,12 @@ PageType {
|
||||
Layout.topMargin: 16
|
||||
|
||||
headerText: qsTr("Jmax - Junk packet maximum size")
|
||||
textFieldText: serverJunkPacketMaxSize
|
||||
textField.text: serverJunkPacketMaxSize
|
||||
textField.validator: IntValidator { bottom: 0 }
|
||||
|
||||
textField.onEditingFinished: {
|
||||
if (textFieldText !== serverJunkPacketMaxSize) {
|
||||
serverJunkPacketMaxSize = textFieldText
|
||||
if (textField.text !== serverJunkPacketMaxSize) {
|
||||
serverJunkPacketMaxSize = textField.text
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,12 +202,12 @@ PageType {
|
||||
Layout.topMargin: 16
|
||||
|
||||
headerText: qsTr("S1 - Init packet junk size")
|
||||
textFieldText: serverInitPacketJunkSize
|
||||
textField.text: serverInitPacketJunkSize
|
||||
textField.validator: IntValidator { bottom: 0 }
|
||||
|
||||
textField.onEditingFinished: {
|
||||
if (textFieldText !== serverInitPacketJunkSize) {
|
||||
serverInitPacketJunkSize = textFieldText
|
||||
if (textField.text !== serverInitPacketJunkSize) {
|
||||
serverInitPacketJunkSize = textField.text
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,12 +226,12 @@ PageType {
|
||||
Layout.topMargin: 16
|
||||
|
||||
headerText: qsTr("S2 - Response packet junk size")
|
||||
textFieldText: serverResponsePacketJunkSize
|
||||
textField.text: serverResponsePacketJunkSize
|
||||
textField.validator: IntValidator { bottom: 0 }
|
||||
|
||||
textField.onEditingFinished: {
|
||||
if (textFieldText !== serverResponsePacketJunkSize) {
|
||||
serverResponsePacketJunkSize = textFieldText
|
||||
if (textField.text !== serverResponsePacketJunkSize) {
|
||||
serverResponsePacketJunkSize = textField.text
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,12 +250,12 @@ PageType {
|
||||
Layout.topMargin: 16
|
||||
|
||||
headerText: qsTr("H1 - Init packet magic header")
|
||||
textFieldText: serverInitPacketMagicHeader
|
||||
textField.text: serverInitPacketMagicHeader
|
||||
textField.validator: IntValidator { bottom: 0 }
|
||||
|
||||
textField.onEditingFinished: {
|
||||
if (textFieldText !== serverInitPacketMagicHeader) {
|
||||
serverInitPacketMagicHeader = textFieldText
|
||||
if (textField.text !== serverInitPacketMagicHeader) {
|
||||
serverInitPacketMagicHeader = textField.text
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,12 +268,12 @@ PageType {
|
||||
Layout.topMargin: 16
|
||||
|
||||
headerText: qsTr("H2 - Response packet magic header")
|
||||
textFieldText: serverResponsePacketMagicHeader
|
||||
textField.text: serverResponsePacketMagicHeader
|
||||
textField.validator: IntValidator { bottom: 0 }
|
||||
|
||||
textField.onEditingFinished: {
|
||||
if (textFieldText !== serverResponsePacketMagicHeader) {
|
||||
serverResponsePacketMagicHeader = textFieldText
|
||||
if (textField.text !== serverResponsePacketMagicHeader) {
|
||||
serverResponsePacketMagicHeader = textField.text
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,12 +286,12 @@ PageType {
|
||||
Layout.topMargin: 16
|
||||
|
||||
headerText: qsTr("H4 - Transport packet magic header")
|
||||
textFieldText: serverTransportPacketMagicHeader
|
||||
textField.text: serverTransportPacketMagicHeader
|
||||
textField.validator: IntValidator { bottom: 0 }
|
||||
|
||||
textField.onEditingFinished: {
|
||||
if (textFieldText !== serverTransportPacketMagicHeader) {
|
||||
serverTransportPacketMagicHeader = textFieldText
|
||||
if (textField.text !== serverTransportPacketMagicHeader) {
|
||||
serverTransportPacketMagicHeader = textField.text
|
||||
}
|
||||
}
|
||||
|
||||
@@ -304,12 +304,12 @@ PageType {
|
||||
Layout.topMargin: 16
|
||||
|
||||
headerText: qsTr("H3 - Underload packet magic header")
|
||||
textFieldText: serverUnderloadPacketMagicHeader
|
||||
textField.text: serverUnderloadPacketMagicHeader
|
||||
textField.validator: IntValidator { bottom: 0 }
|
||||
|
||||
textField.onEditingFinished: {
|
||||
if (textFieldText !== serverUnderloadPacketMagicHeader) {
|
||||
serverUnderloadPacketMagicHeader = textFieldText
|
||||
if (textField.text !== serverUnderloadPacketMagicHeader) {
|
||||
serverUnderloadPacketMagicHeader = textField.text
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -89,18 +89,18 @@ PageType {
|
||||
Layout.topMargin: 32
|
||||
|
||||
headerText: qsTr("Disguised as traffic from")
|
||||
textFieldText: site
|
||||
textField.text: site
|
||||
|
||||
textField.onEditingFinished: {
|
||||
if (textFieldText !== site) {
|
||||
var tmpText = textFieldText
|
||||
if (textField.text !== site) {
|
||||
var tmpText = textField.text
|
||||
tmpText = tmpText.toLocaleLowerCase()
|
||||
|
||||
var indexHttps = tmpText.indexOf("https://")
|
||||
if (indexHttps === 0) {
|
||||
tmpText = textFieldText.substring(8)
|
||||
tmpText = textField.text.substring(8)
|
||||
} else {
|
||||
site = textFieldText
|
||||
site = textField.text
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -113,13 +113,13 @@ PageType {
|
||||
Layout.topMargin: 16
|
||||
|
||||
headerText: qsTr("Port")
|
||||
textFieldText: port
|
||||
textField.text: port
|
||||
textField.maximumLength: 5
|
||||
textField.validator: IntValidator { bottom: 1; top: 65535 }
|
||||
|
||||
textField.onEditingFinished: {
|
||||
if (textFieldText !== port) {
|
||||
port = textFieldText
|
||||
if (textField.text !== port) {
|
||||
port = textField.text
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,13 +88,13 @@ PageType {
|
||||
Layout.topMargin: 32
|
||||
|
||||
headerText: qsTr("VPN address subnet")
|
||||
textFieldText: subnetAddress
|
||||
textField.text: subnetAddress
|
||||
|
||||
parentFlickable: fl
|
||||
|
||||
textField.onEditingFinished: {
|
||||
if (textFieldText !== subnetAddress) {
|
||||
subnetAddress = textFieldText
|
||||
if (textField.text !== subnetAddress) {
|
||||
subnetAddress = textField.text
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -137,13 +137,13 @@ PageType {
|
||||
enabled: isPortEditable
|
||||
|
||||
headerText: qsTr("Port")
|
||||
textFieldText: port
|
||||
textField.text: port
|
||||
textField.maximumLength: 5
|
||||
textField.validator: IntValidator { bottom: 1; top: 65535 }
|
||||
|
||||
textField.onEditingFinished: {
|
||||
if (textFieldText !== port) {
|
||||
port = textFieldText
|
||||
if (textField.text !== port) {
|
||||
port = textField.text
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,13 +93,13 @@ PageType {
|
||||
enabled: isPortEditable
|
||||
|
||||
headerText: qsTr("Port")
|
||||
textFieldText: port
|
||||
textField.text: port
|
||||
textField.maximumLength: 5
|
||||
textField.validator: IntValidator { bottom: 1; top: 65535 }
|
||||
|
||||
textField.onEditingFinished: {
|
||||
if (textFieldText !== port) {
|
||||
port = textFieldText
|
||||
if (textField.text !== port) {
|
||||
port = textField.text
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,12 +97,12 @@ PageType {
|
||||
Layout.topMargin: 40
|
||||
|
||||
headerText: qsTr("MTU")
|
||||
textFieldText: clientMtu
|
||||
textField.text: clientMtu
|
||||
textField.validator: IntValidator { bottom: 576; top: 65535 }
|
||||
|
||||
textField.onEditingFinished: {
|
||||
if (textFieldText !== clientMtu) {
|
||||
clientMtu = textFieldText
|
||||
if (textField.text !== clientMtu) {
|
||||
clientMtu = textField.text
|
||||
}
|
||||
}
|
||||
checkEmptyText: true
|
||||
@@ -124,7 +124,7 @@ PageType {
|
||||
enabled: false
|
||||
|
||||
headerText: qsTr("Port")
|
||||
textFieldText: port
|
||||
textField.text: port
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,11 +90,11 @@ PageType {
|
||||
enabled: delegateItem.isEnabled
|
||||
|
||||
headerText: qsTr("VPN address subnet")
|
||||
textFieldText: subnetAddress
|
||||
textField.text: subnetAddress
|
||||
|
||||
textField.onEditingFinished: {
|
||||
if (textFieldText !== subnetAddress) {
|
||||
subnetAddress = textFieldText
|
||||
if (textField.text !== subnetAddress) {
|
||||
subnetAddress = textField.text
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,13 +109,13 @@ PageType {
|
||||
enabled: delegateItem.isEnabled
|
||||
|
||||
headerText: qsTr("Port")
|
||||
textFieldText: port
|
||||
textField.text: port
|
||||
textField.maximumLength: 5
|
||||
textField.validator: IntValidator { bottom: 1; top: 65535 }
|
||||
|
||||
textField.onEditingFinished: {
|
||||
if (textFieldText !== port) {
|
||||
port = textFieldText
|
||||
if (textField.text !== port) {
|
||||
port = textField.text
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -86,18 +86,18 @@ PageType {
|
||||
Layout.topMargin: 32
|
||||
|
||||
headerText: qsTr("Disguised as traffic from")
|
||||
textFieldText: site
|
||||
textField.text: site
|
||||
|
||||
textField.onEditingFinished: {
|
||||
if (textFieldText !== site) {
|
||||
var tmpText = textFieldText
|
||||
if (textField.text !== site) {
|
||||
var tmpText = textField.text
|
||||
tmpText = tmpText.toLocaleLowerCase()
|
||||
|
||||
var indexHttps = tmpText.indexOf("https://")
|
||||
if (indexHttps === 0) {
|
||||
tmpText = textFieldText.substring(8)
|
||||
tmpText = textField.text.substring(8)
|
||||
} else {
|
||||
site = textFieldText
|
||||
site = textField.text
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,9 +211,9 @@ PageType {
|
||||
port = tempPort
|
||||
username = tempUsername
|
||||
password = tempPassword
|
||||
portTextField.textFieldText = port
|
||||
usernameTextField.textFieldText = username
|
||||
passwordTextField.textFieldText = password
|
||||
portTextField.textField.text = port
|
||||
usernameTextField.textField.text = username
|
||||
passwordTextField.textField.text = password
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,14 +231,14 @@ PageType {
|
||||
parentFlickable: fl
|
||||
|
||||
headerText: qsTr("Port")
|
||||
textFieldText: port
|
||||
textField.text: port
|
||||
textField.maximumLength: 5
|
||||
textField.validator: IntValidator { bottom: 1; top: 65535 }
|
||||
|
||||
textField.onEditingFinished: {
|
||||
textFieldText = textField.text.replace(/^\s+|\s+$/g, '')
|
||||
if (textFieldText !== port) {
|
||||
port = textFieldText
|
||||
textField.text = textField.text.replace(/^\s+|\s+$/g, '')
|
||||
if (textField.text !== port) {
|
||||
port = textField.text
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -251,14 +251,14 @@ PageType {
|
||||
parentFlickable: fl
|
||||
|
||||
headerText: qsTr("Username")
|
||||
textFieldPlaceholderText: "username"
|
||||
textFieldText: username
|
||||
textField.placeholderText: "username"
|
||||
textField.text: username
|
||||
textField.maximumLength: 32
|
||||
|
||||
textField.onEditingFinished: {
|
||||
textFieldText = textField.text.replace(/^\s+|\s+$/g, '')
|
||||
if (textFieldText !== username) {
|
||||
username = textFieldText
|
||||
textField.text = textField.text.replace(/^\s+|\s+$/g, '')
|
||||
if (textField.text !== username) {
|
||||
username = textField.text
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -273,12 +273,12 @@ PageType {
|
||||
parentFlickable: fl
|
||||
|
||||
headerText: qsTr("Password")
|
||||
textFieldPlaceholderText: "password"
|
||||
textFieldText: password
|
||||
textField.placeholderText: "password"
|
||||
textField.text: password
|
||||
textField.maximumLength: 32
|
||||
|
||||
textField.echoMode: hidePassword ? TextInput.Password : TextInput.Normal
|
||||
buttonImageSource: textFieldText !== "" ? (hidePassword ? "qrc:/images/controls/eye.svg" : "qrc:/images/controls/eye-off.svg")
|
||||
buttonImageSource: textField.text !== "" ? (hidePassword ? "qrc:/images/controls/eye.svg" : "qrc:/images/controls/eye-off.svg")
|
||||
: ""
|
||||
|
||||
clickedFunc: function() {
|
||||
@@ -286,9 +286,9 @@ PageType {
|
||||
}
|
||||
|
||||
textField.onFocusChanged: {
|
||||
textFieldText = textField.text.replace(/^\s+|\s+$/g, '')
|
||||
if (textFieldText !== password) {
|
||||
password = textFieldText
|
||||
textField.text = textField.text.replace(/^\s+|\s+$/g, '')
|
||||
if (textField.text !== password) {
|
||||
password = textField.text
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -309,19 +309,19 @@ PageType {
|
||||
portTextField.errorText = qsTr("The port must be in the range of 1 to 65535")
|
||||
return
|
||||
}
|
||||
if (usernameTextField.textFieldText && passwordTextField.textFieldText === "") {
|
||||
if (usernameTextField.textField.text && passwordTextField.textField.text === "") {
|
||||
passwordTextField.errorText = qsTr("Password cannot be empty")
|
||||
return
|
||||
} else if (usernameTextField.textFieldText === "" && passwordTextField.textFieldText) {
|
||||
} else if (usernameTextField.textField.text === "" && passwordTextField.textField.text) {
|
||||
usernameTextField.errorText = qsTr("Username cannot be empty")
|
||||
return
|
||||
}
|
||||
|
||||
PageController.goToPage(PageEnum.PageSetupWizardInstalling)
|
||||
InstallController.updateContainer(Socks5ProxyConfigModel.getConfig())
|
||||
tempPort = portTextField.textFieldText
|
||||
tempUsername = usernameTextField.textFieldText
|
||||
tempPassword = passwordTextField.textFieldText
|
||||
tempPort = portTextField.textField.text
|
||||
tempUsername = usernameTextField.textField.text
|
||||
tempPassword = passwordTextField.textField.text
|
||||
changeSettingsDrawer.closeTriggered()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +87,6 @@ PageType {
|
||||
|
||||
LabelWithButtonType {
|
||||
id: backup
|
||||
visible: !SettingsController.isOnTv()
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: qsTr("Backup")
|
||||
@@ -99,9 +98,7 @@ PageType {
|
||||
}
|
||||
}
|
||||
|
||||
DividerType {
|
||||
visible: !SettingsController.isOnTv()
|
||||
}
|
||||
DividerType {}
|
||||
|
||||
LabelWithButtonType {
|
||||
id: about
|
||||
|
||||
@@ -15,61 +15,100 @@ import "../Components"
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
FlickableType {
|
||||
id: fl
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
contentHeight: content.height
|
||||
property list<QtObject> labelsModel: [
|
||||
regionObject,
|
||||
priceObject,
|
||||
endDateObject,
|
||||
speedObject
|
||||
]
|
||||
|
||||
ColumnLayout {
|
||||
id: content
|
||||
QtObject {
|
||||
id: regionObject
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
readonly property string title: qsTr("For the region")
|
||||
readonly property string contentKey: "region"
|
||||
readonly property string objectImageSource: "qrc:/images/controls/map-pin.svg"
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: priceObject
|
||||
|
||||
readonly property string title: qsTr("Price")
|
||||
readonly property string contentKey: "price"
|
||||
readonly property string objectImageSource: "qrc:/images/controls/tag.svg"
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: endDateObject
|
||||
|
||||
readonly property string title: qsTr("Valid until")
|
||||
readonly property string contentKey: "endDate"
|
||||
readonly property string objectImageSource: "qrc:/images/controls/history.svg"
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: speedObject
|
||||
|
||||
readonly property string title: qsTr("Speed")
|
||||
readonly property string contentKey: "speed"
|
||||
readonly property string objectImageSource: "qrc:/images/controls/gauge.svg"
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: listView
|
||||
anchors.fill: parent
|
||||
|
||||
property bool isFocusable: true
|
||||
|
||||
Keys.onTabPressed: {
|
||||
FocusController.nextKeyTabItem()
|
||||
}
|
||||
|
||||
Keys.onBacktabPressed: {
|
||||
FocusController.previousKeyTabItem()
|
||||
}
|
||||
|
||||
Keys.onUpPressed: {
|
||||
FocusController.nextKeyUpItem()
|
||||
}
|
||||
|
||||
Keys.onDownPressed: {
|
||||
FocusController.nextKeyDownItem()
|
||||
}
|
||||
|
||||
Keys.onLeftPressed: {
|
||||
FocusController.nextKeyLeftItem()
|
||||
}
|
||||
|
||||
Keys.onRightPressed: {
|
||||
FocusController.nextKeyRightItem()
|
||||
}
|
||||
|
||||
ScrollBar.vertical: ScrollBarType {}
|
||||
|
||||
model: labelsModel
|
||||
clip: true
|
||||
reuseItems: true
|
||||
|
||||
delegate: ColumnLayout {
|
||||
width: listView.width
|
||||
spacing: 0
|
||||
|
||||
LabelWithImageType {
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: 16
|
||||
|
||||
imageSource: "qrc:/images/controls/map-pin.svg"
|
||||
leftText: qsTr("For the region")
|
||||
rightText: ApiServicesModel.getSelectedServiceData("region")
|
||||
}
|
||||
|
||||
LabelWithImageType {
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: 16
|
||||
|
||||
imageSource: "qrc:/images/controls/tag.svg"
|
||||
leftText: qsTr("Price")
|
||||
rightText: ApiServicesModel.getSelectedServiceData("price")
|
||||
}
|
||||
|
||||
LabelWithImageType {
|
||||
property bool showSubscriptionEndDate: ServersModel.getProcessedServerData("isCountrySelectionAvailable")
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: 16
|
||||
|
||||
imageSource: "qrc:/images/controls/history.svg"
|
||||
leftText: showSubscriptionEndDate ? qsTr("Valid until") : qsTr("Work period")
|
||||
rightText: showSubscriptionEndDate ? ApiServicesModel.getSelectedServiceData("endDate")
|
||||
: ApiServicesModel.getSelectedServiceData("workPeriod")
|
||||
imageSource: objectImageSource
|
||||
leftText: title
|
||||
rightText: ApiServicesModel.getSelectedServiceData(contentKey)
|
||||
|
||||
visible: rightText !== ""
|
||||
}
|
||||
}
|
||||
|
||||
LabelWithImageType {
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: 16
|
||||
|
||||
imageSource: "qrc:/images/controls/gauge.svg"
|
||||
leftText: qsTr("Speed")
|
||||
rightText: ApiServicesModel.getSelectedServiceData("speed")
|
||||
}
|
||||
footer: ColumnLayout {
|
||||
width: listView.width
|
||||
spacing: 0
|
||||
|
||||
ParagraphTextType {
|
||||
Layout.fillWidth: true
|
||||
@@ -88,6 +127,8 @@ PageType {
|
||||
return text.replace("%1", LanguageModel.getCurrentSiteUrl())
|
||||
}
|
||||
|
||||
visible: text !== ""
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.NoButton
|
||||
|
||||
@@ -252,7 +252,7 @@ PageType {
|
||||
|
||||
Layout.fillWidth: true
|
||||
|
||||
textFieldPlaceholderText: qsTr("application name")
|
||||
textField.placeholderText: qsTr("application name")
|
||||
buttonImageSource: "qrc:/images/controls/plus.svg"
|
||||
|
||||
rightButtonClickedOnEnter: true
|
||||
|
||||
@@ -67,7 +67,7 @@ PageType {
|
||||
Layout.fillWidth: true
|
||||
headerText: qsTr("Primary DNS")
|
||||
|
||||
textFieldText: SettingsController.primaryDns
|
||||
textField.text: SettingsController.primaryDns
|
||||
textField.validator: RegularExpressionValidator {
|
||||
regularExpression: InstallController.ipAddressRegExp()
|
||||
}
|
||||
@@ -79,7 +79,7 @@ PageType {
|
||||
Layout.fillWidth: true
|
||||
headerText: qsTr("Secondary DNS")
|
||||
|
||||
textFieldText: SettingsController.secondaryDns
|
||||
textField.text: SettingsController.secondaryDns
|
||||
textField.validator: RegularExpressionValidator {
|
||||
regularExpression: InstallController.ipAddressRegExp()
|
||||
}
|
||||
@@ -105,9 +105,9 @@ PageType {
|
||||
|
||||
var yesButtonFunction = function() {
|
||||
SettingsController.primaryDns = "1.1.1.1"
|
||||
primaryDns.textFieldText = SettingsController.primaryDns
|
||||
primaryDns.textField.text = SettingsController.primaryDns
|
||||
SettingsController.secondaryDns = "1.0.0.1"
|
||||
secondaryDns.textFieldText = SettingsController.secondaryDns
|
||||
secondaryDns.textField.text = SettingsController.secondaryDns
|
||||
PageController.showNotificationMessage(qsTr("Settings have been reset"))
|
||||
}
|
||||
var noButtonFunction = function() {
|
||||
@@ -125,11 +125,11 @@ PageType {
|
||||
text: qsTr("Save")
|
||||
|
||||
clickedFunc: function() {
|
||||
if (primaryDns.textFieldText !== SettingsController.primaryDns) {
|
||||
SettingsController.primaryDns = primaryDns.textFieldText
|
||||
if (primaryDns.textField.text !== SettingsController.primaryDns) {
|
||||
SettingsController.primaryDns = primaryDns.textField.text
|
||||
}
|
||||
if (secondaryDns.textFieldText !== SettingsController.secondaryDns) {
|
||||
SettingsController.secondaryDns = secondaryDns.textFieldText
|
||||
if (secondaryDns.textField.text !== SettingsController.secondaryDns) {
|
||||
SettingsController.secondaryDns = secondaryDns.textField.text
|
||||
}
|
||||
PageController.showNotificationMessage(qsTr("Settings saved"))
|
||||
}
|
||||
|
||||
@@ -137,6 +137,8 @@ PageType {
|
||||
Layout.topMargin: -8
|
||||
Layout.bottomMargin: -8
|
||||
|
||||
visible: !GC.isMobile()
|
||||
|
||||
text: qsTr("Open logs folder")
|
||||
leftImageSource: "qrc:/images/controls/folder-open.svg"
|
||||
isSmallLeftImage: true
|
||||
|
||||
@@ -142,7 +142,7 @@ PageType {
|
||||
|
||||
Layout.fillWidth: true
|
||||
headerText: qsTr("Server name")
|
||||
textFieldText: root.processedServer.name
|
||||
textField.text: root.processedServer.name
|
||||
textField.maximumLength: 30
|
||||
checkEmptyText: true
|
||||
}
|
||||
@@ -155,12 +155,12 @@ PageType {
|
||||
text: qsTr("Save")
|
||||
|
||||
clickedFunc: function() {
|
||||
if (serverName.textFieldText === "") {
|
||||
if (serverName.textField.text === "") {
|
||||
return
|
||||
}
|
||||
|
||||
if (serverName.textFieldText !== root.processedServer.name) {
|
||||
ServersModel.setProcessedServerData("name", serverName.textFieldText);
|
||||
if (serverName.textField.text !== root.processedServer.name) {
|
||||
ServersModel.setProcessedServerData("name", serverName.textField.text);
|
||||
}
|
||||
serverNameEditDrawer.closeTriggered()
|
||||
}
|
||||
|
||||
@@ -274,13 +274,13 @@ PageType {
|
||||
Layout.fillWidth: true
|
||||
rightButtonClickedOnEnter: true
|
||||
|
||||
textFieldPlaceholderText: qsTr("website or IP")
|
||||
textField.placeholderText: qsTr("website or IP")
|
||||
buttonImageSource: "qrc:/images/controls/plus.svg"
|
||||
|
||||
clickedFunc: function() {
|
||||
PageController.showBusyIndicator(true)
|
||||
SitesController.addSite(textFieldText)
|
||||
textFieldText = ""
|
||||
SitesController.addSite(textField.text)
|
||||
textField.text = ""
|
||||
PageController.showBusyIndicator(false)
|
||||
}
|
||||
}
|
||||
@@ -338,7 +338,6 @@ PageType {
|
||||
|
||||
LabelWithButtonType {
|
||||
id: exportSitesButton
|
||||
enabled: !SettingsController.isOnTv()
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Save site list")
|
||||
|
||||
@@ -362,9 +361,7 @@ PageType {
|
||||
}
|
||||
}
|
||||
|
||||
DividerType {
|
||||
enabled: !SettingsController.isOnTv()
|
||||
}
|
||||
DividerType {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -163,12 +163,12 @@ PageType {
|
||||
Layout.rightMargin: 16
|
||||
Layout.leftMargin: 16
|
||||
|
||||
visible: textKey.textFieldText !== ""
|
||||
visible: textKey.textField.text !== ""
|
||||
|
||||
text: qsTr("Continue")
|
||||
|
||||
clickedFunc: function() {
|
||||
if (ImportController.extractConfigFromData(textKey.textFieldText)) {
|
||||
if (ImportController.extractConfigFromData(textKey.textField.text)) {
|
||||
PageController.goToPage(PageEnum.PageSetupWizardViewConfig)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,24 +82,19 @@ PageType {
|
||||
reuseItems: true
|
||||
|
||||
delegate: ColumnLayout {
|
||||
property alias textField: _textField.textField
|
||||
|
||||
width: listView.width
|
||||
|
||||
TextFieldWithHeaderType {
|
||||
id: _textField
|
||||
id: delegate
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: 16
|
||||
Layout.rightMargin: 16
|
||||
|
||||
property bool hidePassword: hideText
|
||||
|
||||
headerText: title
|
||||
textField.echoMode: hideText ? TextInput.Password : TextInput.Normal
|
||||
buttonImageSource: imageSource
|
||||
textFieldPlaceholderText: placeholderText
|
||||
textField.text: textFieldText
|
||||
textField.echoMode: hideContent ? TextInput.Password : TextInput.Normal
|
||||
textField.placeholderText: placeholderContent
|
||||
textField.text: textField.text
|
||||
|
||||
rightButtonClickedOnEnter: true
|
||||
|
||||
@@ -108,17 +103,12 @@ PageType {
|
||||
}
|
||||
|
||||
textField.onFocusChanged: {
|
||||
var _currentIndex = listView.currentIndex
|
||||
var _currentItem = listView.itemAtIndex(_currentIndex).children[0]
|
||||
listView.model[_currentIndex].textFieldText = _currentItem.textFieldText.replace(/^\s+|\s+$/g, '')
|
||||
textField.text = textField.text.replace(/^\s+|\s+$/g, '')
|
||||
}
|
||||
|
||||
textField.onTextChanged: {
|
||||
var _currentIndex = listView.currentIndex
|
||||
textFieldText = textField.text
|
||||
|
||||
if (_currentIndex === vars.secretDataIndex) {
|
||||
buttonImageSource = textFieldText !== "" ? (hideText ? "qrc:/images/controls/eye.svg" : "qrc:/images/controls/eye-off.svg") : ""
|
||||
if (hideContent) {
|
||||
buttonImageSource = textField.text !== "" ? (hideContent ? "qrc:/images/controls/eye.svg" : "qrc:/images/controls/eye-off.svg") : ""
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -143,9 +133,9 @@ PageType {
|
||||
}
|
||||
|
||||
InstallController.setShouldCreateServer(true)
|
||||
var _hostname = listView.itemAtIndex(vars.hostnameIndex).children[0].textFieldText
|
||||
var _username = listView.itemAtIndex(vars.usernameIndex).children[0].textFieldText
|
||||
var _secretData = listView.itemAtIndex(vars.secretDataIndex).children[0].textFieldText
|
||||
var _hostname = listView.itemAtIndex(vars.hostnameIndex).children[0].textField.text
|
||||
var _username = listView.itemAtIndex(vars.usernameIndex).children[0].textField.text
|
||||
var _secretData = listView.itemAtIndex(vars.secretDataIndex).children[0].textField.text
|
||||
|
||||
InstallController.setProcessedServerCredentials(_hostname, _username, _secretData)
|
||||
|
||||
@@ -194,23 +184,23 @@ PageType {
|
||||
function isCredentialsFilled() {
|
||||
var hasEmptyField = false
|
||||
|
||||
var _hostname = listView.itemAtIndex(vars.hostnameIndex).children[0]
|
||||
if (_hostname.textFieldText === "") {
|
||||
_hostname.errorText = qsTr("Ip address cannot be empty")
|
||||
var hostnameItem = listView.itemAtIndex(vars.hostnameIndex).children[0]
|
||||
if (hostnameItem.textField.text === "") {
|
||||
hostnameItem.errorText = qsTr("Ip address cannot be empty")
|
||||
hasEmptyField = true
|
||||
} else if (!_hostname.textField.acceptableInput) {
|
||||
_hostname.errorText = qsTr("Enter the address in the format 255.255.255.255:88")
|
||||
} else if (!hostnameItem.textField.acceptableInput) {
|
||||
hostnameItem.errorText = qsTr("Enter the address in the format 255.255.255.255:88")
|
||||
}
|
||||
|
||||
var _username = listView.itemAtIndex(vars.usernameIndex).children[0]
|
||||
if (_username.textFieldText === "") {
|
||||
_username.errorText = qsTr("Login cannot be empty")
|
||||
var usernameItem = listView.itemAtIndex(vars.usernameIndex).children[0]
|
||||
if (usernameItem.textField.text === "") {
|
||||
usernameItem.errorText = qsTr("Login cannot be empty")
|
||||
hasEmptyField = true
|
||||
}
|
||||
|
||||
var _secretData = listView.itemAtIndex(vars.secretDataIndex).children[0]
|
||||
if (_secretData.textFieldText === "") {
|
||||
_secretData.errorText = qsTr("Password/private key cannot be empty")
|
||||
var secretDataItem = listView.itemAtIndex(vars.secretDataIndex).children[0]
|
||||
if (secretDataItem.textField.text === "") {
|
||||
secretDataItem.errorText = qsTr("Password/private key cannot be empty")
|
||||
hasEmptyField = true
|
||||
}
|
||||
|
||||
@@ -218,46 +208,37 @@ PageType {
|
||||
}
|
||||
|
||||
property list<QtObject> inputFields: [
|
||||
hostname,
|
||||
username,
|
||||
secretData
|
||||
hostnameObject,
|
||||
usernameObject,
|
||||
secretDataObject
|
||||
]
|
||||
|
||||
QtObject {
|
||||
id: hostname
|
||||
id: hostnameObject
|
||||
|
||||
property string title: qsTr("Server IP address [:port]")
|
||||
readonly property string placeholderText: qsTr("255.255.255.255:22")
|
||||
property string textFieldText: ""
|
||||
property bool hideText: false
|
||||
property string imageSource: ""
|
||||
readonly property var clickedHandler: function() {
|
||||
console.debug(">>> Server IP address text field was clicked!!!")
|
||||
clicked()
|
||||
}
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: username
|
||||
|
||||
property string title: qsTr("SSH Username")
|
||||
readonly property string placeholderText: "root"
|
||||
property string textFieldText: ""
|
||||
property bool hideText: false
|
||||
property string imageSource: ""
|
||||
readonly property string placeholderContent: qsTr("255.255.255.255:22")
|
||||
property bool hideContent: false
|
||||
readonly property var clickedHandler: undefined
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: secretData
|
||||
id: usernameObject
|
||||
|
||||
property string title: qsTr("SSH Username")
|
||||
readonly property string placeholderContent: "root"
|
||||
property bool hideContent: false
|
||||
readonly property var clickedHandler: undefined
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: secretDataObject
|
||||
|
||||
property string title: qsTr("Password or SSH private key")
|
||||
readonly property string placeholderText: ""
|
||||
property string textFieldText: ""
|
||||
property bool hideText: true
|
||||
property string imageSource: textFieldText !== "" ? (hideText ? "qrc:/images/controls/eye.svg" : "qrc:/images/controls/eye-off.svg") : ""
|
||||
readonly property string placeholderContent: ""
|
||||
property bool hideContent: true
|
||||
readonly property var clickedHandler: function() {
|
||||
hideText = !hideText
|
||||
hideContent = !hideContent
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ PageType {
|
||||
implicitWidth: parent.width
|
||||
headerTextMaximumLineCount: 10
|
||||
|
||||
headerText: qsTr("What is the level of internet control in your region?")
|
||||
headerText: qsTr("Choose Installation Type")
|
||||
}
|
||||
|
||||
ButtonGroup {
|
||||
@@ -139,7 +139,8 @@ PageType {
|
||||
CardType {
|
||||
implicitWidth: parent.width
|
||||
|
||||
headerText: qsTr("Choose a VPN protocol")
|
||||
headerText: qsTr("Manual")
|
||||
bodyText: qsTr("Choose a VPN protocol")
|
||||
|
||||
ButtonGroup.group: buttonGroup
|
||||
|
||||
|
||||
@@ -257,7 +257,7 @@ PageType {
|
||||
}
|
||||
|
||||
PageController.goToPage(PageEnum.PageSetupWizardInstalling);
|
||||
InstallController.install(dockerContainer, port.textFieldText, transportProtoSelector.currentIndex)
|
||||
InstallController.install(dockerContainer, port.textField.text, transportProtoSelector.currentIndex)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -267,7 +267,7 @@ PageType {
|
||||
if (ProtocolProps.defaultPort(defaultContainerProto) < 0) {
|
||||
port.visible = false
|
||||
} else {
|
||||
port.textFieldText = ProtocolProps.getPortForInstall(defaultContainerProto)
|
||||
port.textField.text = ProtocolProps.getPortForInstall(defaultContainerProto)
|
||||
}
|
||||
transportProtoSelector.currentIndex = ProtocolProps.defaultTransportProto(defaultContainerProto)
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ PageType {
|
||||
Layout.leftMargin: 16
|
||||
|
||||
headerText: qsTr("Key")
|
||||
textFieldPlaceholderText: "vpn://"
|
||||
textField.placeholderText: "vpn://"
|
||||
buttonText: qsTr("Insert")
|
||||
|
||||
clickedFunc: function() {
|
||||
@@ -75,7 +75,7 @@ PageType {
|
||||
text: qsTr("Continue")
|
||||
|
||||
clickedFunc: function() {
|
||||
if (ImportController.extractConfigFromData(textKey.textFieldText)) {
|
||||
if (ImportController.extractConfigFromData(textKey.textField.text)) {
|
||||
PageController.goToPage(PageEnum.PageSetupWizardViewConfig)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,25 +51,25 @@ PageType {
|
||||
|
||||
switch (type) {
|
||||
case PageShare.ConfigType.AmneziaConnection: {
|
||||
ExportController.generateConnectionConfig(clientNameTextField.textFieldText);
|
||||
ExportController.generateConnectionConfig(clientNameTextField.textField.text);
|
||||
break;
|
||||
}
|
||||
case PageShare.ConfigType.OpenVpn: {
|
||||
ExportController.generateOpenVpnConfig(clientNameTextField.textFieldText)
|
||||
ExportController.generateOpenVpnConfig(clientNameTextField.textField.text)
|
||||
shareConnectionDrawer.configCaption = qsTr("Save OpenVPN config")
|
||||
shareConnectionDrawer.configExtension = ".ovpn"
|
||||
shareConnectionDrawer.configFileName = "amnezia_for_openvpn"
|
||||
break
|
||||
}
|
||||
case PageShare.ConfigType.WireGuard: {
|
||||
ExportController.generateWireGuardConfig(clientNameTextField.textFieldText)
|
||||
ExportController.generateWireGuardConfig(clientNameTextField.textField.text)
|
||||
shareConnectionDrawer.configCaption = qsTr("Save WireGuard config")
|
||||
shareConnectionDrawer.configExtension = ".conf"
|
||||
shareConnectionDrawer.configFileName = "amnezia_for_wireguard"
|
||||
break
|
||||
}
|
||||
case PageShare.ConfigType.Awg: {
|
||||
ExportController.generateAwgConfig(clientNameTextField.textFieldText)
|
||||
ExportController.generateAwgConfig(clientNameTextField.textField.text)
|
||||
shareConnectionDrawer.configCaption = qsTr("Save AmneziaWG config")
|
||||
shareConnectionDrawer.configExtension = ".conf"
|
||||
shareConnectionDrawer.configFileName = "amnezia_for_awg"
|
||||
@@ -90,7 +90,7 @@ PageType {
|
||||
break
|
||||
}
|
||||
case PageShare.ConfigType.Xray: {
|
||||
ExportController.generateXrayConfig(clientNameTextField.textFieldText)
|
||||
ExportController.generateXrayConfig(clientNameTextField.textField.text)
|
||||
shareConnectionDrawer.configCaption = qsTr("Save XRay config")
|
||||
shareConnectionDrawer.configExtension = ".json"
|
||||
shareConnectionDrawer.configFileName = "amnezia_for_xray"
|
||||
@@ -296,7 +296,7 @@ PageType {
|
||||
visible: accessTypeSelector.currentIndex === 0
|
||||
|
||||
headerText: qsTr("User name")
|
||||
textFieldText: "New client"
|
||||
textField.text: "New client"
|
||||
textField.maximumLength: 20
|
||||
|
||||
checkEmptyText: true
|
||||
@@ -525,7 +525,7 @@ PageType {
|
||||
parentFlickable: a
|
||||
|
||||
clickedFunc: function(){
|
||||
if (clientNameTextField.textFieldText !== "") {
|
||||
if (clientNameTextField.textField.text !== "") {
|
||||
ExportController.generateConfig(root.connectionTypesModel[exportTypeSelector.currentIndex].type)
|
||||
}
|
||||
}
|
||||
@@ -555,14 +555,14 @@ PageType {
|
||||
id: searchTextField
|
||||
Layout.fillWidth: true
|
||||
|
||||
textFieldPlaceholderText: qsTr("Search")
|
||||
textField.placeholderText: qsTr("Search")
|
||||
|
||||
Keys.onEscapePressed: {
|
||||
root.isSearchBarVisible = false
|
||||
}
|
||||
|
||||
function navigateTo() {
|
||||
if (searchTextField.textFieldText === "") {
|
||||
if (searchTextField.textField.text === "") {
|
||||
root.isSearchBarVisible = false
|
||||
}
|
||||
}
|
||||
@@ -601,7 +601,7 @@ PageType {
|
||||
sourceModel: ClientManagementModel
|
||||
filters: RegExpFilter {
|
||||
roleName: "clientName"
|
||||
pattern: ".*" + searchTextField.textFieldText + ".*"
|
||||
pattern: ".*" + searchTextField.textField.text + ".*"
|
||||
caseSensitivity: Qt.CaseInsensitive
|
||||
}
|
||||
}
|
||||
@@ -765,7 +765,7 @@ PageType {
|
||||
id: clientNameEditor
|
||||
Layout.fillWidth: true
|
||||
headerText: qsTr("Client name")
|
||||
textFieldText: clientName
|
||||
textField.text: clientName
|
||||
textField.maximumLength: 20
|
||||
checkEmptyText: true
|
||||
}
|
||||
@@ -778,14 +778,14 @@ PageType {
|
||||
text: qsTr("Save")
|
||||
|
||||
clickedFunc: function() {
|
||||
if (clientNameEditor.textFieldText === "") {
|
||||
if (clientNameEditor.textField.text === "") {
|
||||
return
|
||||
}
|
||||
|
||||
if (clientNameEditor.textFieldText !== clientName) {
|
||||
if (clientNameEditor.textField.text !== clientName) {
|
||||
PageController.showBusyIndicator(true)
|
||||
ExportController.renameClient(index,
|
||||
clientNameEditor.textFieldText,
|
||||
clientNameEditor.textField.text,
|
||||
ContainersModel.getProcessedContainerIndex(),
|
||||
ServersModel.getProcessedServerCredentials())
|
||||
PageController.showBusyIndicator(false)
|
||||
|
||||
@@ -176,12 +176,12 @@ Window {
|
||||
Connections {
|
||||
target: privateKeyPassphraseDrawer
|
||||
function onOpened() {
|
||||
passphrase.textFieldText = ""
|
||||
passphrase.textField.text = ""
|
||||
passphrase.textField.forceActiveFocus()
|
||||
}
|
||||
|
||||
function onAboutToHide() {
|
||||
if (passphrase.textFieldText !== "") {
|
||||
if (passphrase.textField.text !== "") {
|
||||
PageController.showBusyIndicator(true)
|
||||
}
|
||||
}
|
||||
@@ -222,7 +222,7 @@ Window {
|
||||
|
||||
clickedFunc: function() {
|
||||
privateKeyPassphraseDrawer.closeTriggered()
|
||||
PageController.passphraseRequestDrawerClosed(passphrase.textFieldText)
|
||||
PageController.passphraseRequestDrawerClosed(passphrase.textField.text)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,10 +215,9 @@ ErrorCode VpnConnection::lastError() const
|
||||
void VpnConnection::connectToVpn(int serverIndex, const ServerCredentials &credentials, DockerContainer container,
|
||||
const QJsonObject &vpnConfiguration)
|
||||
{
|
||||
qDebug() << QString("ConnectToVpn, Server index is %1, container is %2, route mode is")
|
||||
qDebug() << QString("Trying to connect to VPN, server index is %1, container is %2")
|
||||
.arg(serverIndex)
|
||||
.arg(ContainerProps::containerToString(container))
|
||||
<< m_settings->routeMode();
|
||||
.arg(ContainerProps::containerToString(container));
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
||||
if (!m_IpcClient) {
|
||||
m_IpcClient = new IpcClient(this);
|
||||
@@ -341,26 +340,26 @@ void VpnConnection::appendSplitTunnelingConfig()
|
||||
}
|
||||
}
|
||||
|
||||
Settings::RouteMode routeMode = Settings::RouteMode::VpnAllSites;
|
||||
Settings::RouteMode sitesRouteMode = Settings::RouteMode::VpnAllSites;
|
||||
QJsonArray sitesJsonArray;
|
||||
if (m_settings->isSitesSplitTunnelingEnabled()) {
|
||||
routeMode = m_settings->routeMode();
|
||||
sitesRouteMode = m_settings->routeMode();
|
||||
|
||||
if (allowSiteBasedSplitTunneling) {
|
||||
auto sites = m_settings->getVpnIps(routeMode);
|
||||
auto sites = m_settings->getVpnIps(sitesRouteMode);
|
||||
for (const auto &site : sites) {
|
||||
sitesJsonArray.append(site);
|
||||
}
|
||||
|
||||
// Allow traffic to Amnezia DNS
|
||||
if (routeMode == Settings::VpnOnlyForwardSites) {
|
||||
if (sitesRouteMode == Settings::VpnOnlyForwardSites) {
|
||||
sitesJsonArray.append(m_vpnConfiguration.value(config_key::dns1).toString());
|
||||
sitesJsonArray.append(m_vpnConfiguration.value(config_key::dns2).toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_vpnConfiguration.insert(config_key::splitTunnelType, routeMode);
|
||||
m_vpnConfiguration.insert(config_key::splitTunnelType, sitesRouteMode);
|
||||
m_vpnConfiguration.insert(config_key::splitTunnelSites, sitesJsonArray);
|
||||
|
||||
Settings::AppsRouteMode appsRouteMode = Settings::AppsRouteMode::VpnAllApps;
|
||||
@@ -376,6 +375,13 @@ void VpnConnection::appendSplitTunnelingConfig()
|
||||
|
||||
m_vpnConfiguration.insert(config_key::appSplitTunnelType, appsRouteMode);
|
||||
m_vpnConfiguration.insert(config_key::splitTunnelApps, appsJsonArray);
|
||||
|
||||
qDebug() << QString("Site split tunneling is %1, route mode is %2")
|
||||
.arg(m_settings->isSitesSplitTunnelingEnabled() ? "enabled" : "disabled")
|
||||
.arg(sitesRouteMode);
|
||||
qDebug() << QString("App split tunneling is %1, route mode is %2")
|
||||
.arg(m_settings->isAppsSplitTunnelingEnabled() ? "enabled" : "disabled")
|
||||
.arg(appsRouteMode);
|
||||
}
|
||||
|
||||
#ifdef Q_OS_ANDROID
|
||||
|
||||
Reference in New Issue
Block a user