Compare commits

...

26 Commits

Author SHA1 Message Date
pokamest 517b5e5ca6 Merge pull request #1413 from amnezia-vpn/Change-links-readme
Update README_RU.md
2025-02-18 08:42:57 +00:00
pokamest cfeb6cbffd Merge pull request #1412 from amnezia-vpn/Change-link-readme
Update README.md
2025-02-18 08:42:18 +00:00
Nethius ec132ac96c Merge pull request #1416 from amnezia-vpn/bugfix/android-crush
bugfix: fixed ssl errors handling
2025-02-14 00:27:00 +07:00
vladimir.kuznetsov 101838404e bugfix: fixed possible crush on android 2025-02-14 00:13:57 +07:00
KsZnak 5a7b5d34fb Update README.md
fix link
2025-02-11 19:54:58 +02:00
KsZnak 9420333c76 Update README_RU.md 2025-02-11 14:14:30 +02:00
KsZnak f6403fe82e Update README.md 2025-02-11 14:10:03 +02:00
Nethius c55b025eee Merge pull request #1410 from amnezia-vpn/openvpnadapter-replacement
Openvpnadapter replacement
2025-02-11 09:27:15 +07:00
Yaroslav Yashin fc6fc26148 feat: remove ios openvpn script and associated cmake configuration 2025-02-10 19:40:14 +01:00
Yaroslav Yashin 48b43ee102 feat: remove OpenVPNAdapter submodule 2025-02-10 19:40:14 +01:00
Yaroslav Yashin e091020692 refactor: update ios build configuration to use automatic code signing and prebuilt OpenVPNAdapter framework 2025-02-10 19:39:30 +01:00
pokamest 703b9137e0 Merge pull request #1382 from amnezia-vpn/bugfix/ipsec-pfs
Enable PFS for Windows IKEv2
2025-02-06 16:16:38 +01:00
Pokamest Nikak f163f0fc1d Update VPN description texts 2025-02-05 23:11:21 +00:00
Pokamest Nikak 3b49d5ca59 Update VPN protocol descriptions 2025-02-04 15:53:40 +00:00
Nethius 236e5ca2e3 Merge pull request #1388 from amnezia-vpn/bugfix/pre-release-hotfixes
chore: returned links for mobile platforms
2025-02-01 00:13:52 +07:00
vladimir.kuznetsov 2f6e28b980 chore: returned links for mobile platforms 2025-02-01 00:10:57 +07:00
Nethius 46d96a8887 Merge pull request #1387 from amnezia-vpn/bugfix/pre-release-hotfixes
bugfix: fixed storeEndpoint parsing
2025-01-31 23:07:33 +07:00
vladimir.kuznetsov 56221881da bugfix: fixed storeEndpoint parsing 2025-01-31 23:01:53 +07:00
Nethius da5fe1d766 Merge pull request #1378 from amnezia-vpn/bugfix/pre-release-hotfixes
bugfix/pre-release-hotfixes
2025-01-28 19:22:36 +07:00
vladimir.kuznetsov a15ea0e8a1 chore: returned the backup page for androidTV 2025-01-28 14:55:08 +07:00
vladimir.kuznetsov f79bfa9d2e chore: bump version 2025-01-27 12:14:50 +07:00
vladimir.kuznetsov 3011a0e306 chore: fixed again log output with split tunneling info 2025-01-27 11:59:56 +07:00
vladimir.kuznetsov 76640311ab chore: hide "open logs folder" button for mobule platforms 2025-01-26 14:56:46 +07:00
vladimir.kuznetsov e707471b04 chore: fixed log output with split tunneling info 2025-01-26 14:56:27 +07:00
vladimir.kuznetsov 36045c6694 bugfix: fixed scrolling by keys on PageSettingsApiServerInfo 2025-01-26 14:13:30 +07:00
vladimir.kuznetsov 52ecd6899b bugfix: fixed textFields on PageSetupWizardCredentials 2025-01-24 23:27:01 +07:00
45 changed files with 451 additions and 489 deletions
-3
View File
@@ -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
View File
@@ -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")
+3 -3
View File
@@ -13,13 +13,13 @@
[![Image](https://github.com/amnezia-vpn/amnezia-client/blob/dev/metadata/img-readme/uipic4.png)](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
View File
@@ -10,12 +10,12 @@
[![Image](https://github.com/amnezia-vpn/amnezia-client/blob/dev/metadata/img-readme/uipic4.png)](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)
-5
View File
@@ -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")
+11 -8
View File
@@ -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());
});
+4 -8
View File
@@ -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")
+43 -56
View File
@@ -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();
}
+4 -4
View File
@@ -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; });
}
}
+1 -6
View File
@@ -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
-19
View File
@@ -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 {
+64 -72
View File
@@ -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();
}
+6 -4
View File
@@ -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
+7 -15
View File
@@ -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();
+1 -1
View File
@@ -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")
}
}
+5 -5
View File
@@ -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()
}
}
+1 -4
View File
@@ -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
+8 -8
View File
@@ -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
}
}
+3 -2
View File
@@ -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)
}
}
+14 -14
View File
@@ -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)
+3 -3
View File
@@ -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)
}
}
}
+14 -8
View File
@@ -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