chore: minor ui fixes (#1446)
* chore: minor ui fixes * chore: update ru translation file * bugfix: fixed config update by ttl for gateway configs * bugfix: fixed proxy bypassing * chore: minor ui fixes * chore: update ru translation file * chore: bump version
This commit is contained in:
parent
728b48044c
commit
678bfffe49
11 changed files with 963 additions and 401 deletions
|
@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.25.0 FATAL_ERROR)
|
|||
|
||||
set(PROJECT AmneziaVPN)
|
||||
|
||||
project(${PROJECT} VERSION 4.8.4.2
|
||||
project(${PROJECT} VERSION 4.8.4.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 2079)
|
||||
set(APP_ANDROID_VERSION_CODE 2080)
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
||||
set(MZ_PLATFORM_NAME "linux")
|
||||
|
|
|
@ -157,12 +157,12 @@ ErrorCode GatewayController::post(const QString &endpoint, const QJsonObject api
|
|||
auto replyProcessingFunction = [&encryptedResponseBody, &reply, &sslErrors, &key, &iv, &salt,
|
||||
this](QNetworkReply *nestedReply, const QList<QSslError> &nestedSslErrors) {
|
||||
encryptedResponseBody = nestedReply->readAll();
|
||||
if (!sslErrors.isEmpty() || !shouldBypassProxy(nestedReply, encryptedResponseBody, true, key, iv, salt)) {
|
||||
reply = nestedReply;
|
||||
if (!sslErrors.isEmpty() || shouldBypassProxy(nestedReply, encryptedResponseBody, true, key, iv, salt)) {
|
||||
sslErrors = nestedSslErrors;
|
||||
reply = nestedReply;
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
return true;
|
||||
};
|
||||
|
||||
bypassProxy(endpoint, reply, requestFunction, replyProcessingFunction);
|
||||
|
@ -212,45 +212,45 @@ QStringList GatewayController::getProxyUrls()
|
|||
wait.exec();
|
||||
|
||||
if (reply->error() == QNetworkReply::NetworkError::NoError) {
|
||||
break;
|
||||
}
|
||||
reply->deleteLater();
|
||||
}
|
||||
auto encryptedResponseBody = reply->readAll();
|
||||
reply->deleteLater();
|
||||
|
||||
auto encryptedResponseBody = reply->readAll();
|
||||
reply->deleteLater();
|
||||
EVP_PKEY *privateKey = nullptr;
|
||||
QByteArray responseBody;
|
||||
try {
|
||||
if (!m_isDevEnvironment) {
|
||||
QCryptographicHash hash(QCryptographicHash::Sha512);
|
||||
hash.addData(key);
|
||||
QByteArray hashResult = hash.result().toHex();
|
||||
|
||||
EVP_PKEY *privateKey = nullptr;
|
||||
QByteArray responseBody;
|
||||
try {
|
||||
if (!m_isDevEnvironment) {
|
||||
QCryptographicHash hash(QCryptographicHash::Sha512);
|
||||
hash.addData(key);
|
||||
QByteArray hashResult = hash.result().toHex();
|
||||
QByteArray key = QByteArray::fromHex(hashResult.left(64));
|
||||
QByteArray iv = QByteArray::fromHex(hashResult.mid(64, 32));
|
||||
|
||||
QByteArray key = QByteArray::fromHex(hashResult.left(64));
|
||||
QByteArray iv = QByteArray::fromHex(hashResult.mid(64, 32));
|
||||
QByteArray ba = QByteArray::fromBase64(encryptedResponseBody);
|
||||
|
||||
QByteArray ba = QByteArray::fromBase64(encryptedResponseBody);
|
||||
QSimpleCrypto::QBlockCipher blockCipher;
|
||||
responseBody = blockCipher.decryptAesBlockCipher(ba, key, iv);
|
||||
} else {
|
||||
responseBody = encryptedResponseBody;
|
||||
}
|
||||
} catch (...) {
|
||||
Utils::logException();
|
||||
qCritical() << "error loading private key from environment variables or decrypting payload" << encryptedResponseBody;
|
||||
continue;
|
||||
}
|
||||
|
||||
QSimpleCrypto::QBlockCipher blockCipher;
|
||||
responseBody = blockCipher.decryptAesBlockCipher(ba, key, iv);
|
||||
auto endpointsArray = QJsonDocument::fromJson(responseBody).array();
|
||||
|
||||
QStringList endpoints;
|
||||
for (const auto &endpoint : endpointsArray) {
|
||||
endpoints.push_back(endpoint.toString());
|
||||
}
|
||||
return endpoints;
|
||||
} else {
|
||||
responseBody = encryptedResponseBody;
|
||||
reply->deleteLater();
|
||||
}
|
||||
} catch (...) {
|
||||
Utils::logException();
|
||||
qCritical() << "error loading private key from environment variables or decrypting payload" << encryptedResponseBody;
|
||||
return {};
|
||||
}
|
||||
|
||||
auto endpointsArray = QJsonDocument::fromJson(responseBody).array();
|
||||
|
||||
QStringList endpoints;
|
||||
for (const auto &endpoint : endpointsArray) {
|
||||
endpoints.push_back(endpoint.toString());
|
||||
}
|
||||
return endpoints;
|
||||
return {};
|
||||
}
|
||||
|
||||
bool GatewayController::shouldBypassProxy(QNetworkReply *reply, const QByteArray &responseBody, bool checkEncryption, const QByteArray &key,
|
||||
|
@ -262,7 +262,7 @@ bool GatewayController::shouldBypassProxy(QNetworkReply *reply, const QByteArray
|
|||
} else if (responseBody.contains("html")) {
|
||||
qDebug() << "The response contains an html tag";
|
||||
return true;
|
||||
} else if (checkEncryption) {
|
||||
} else if (reply->error() == QNetworkReply::NetworkError::NoError && checkEncryption) {
|
||||
try {
|
||||
QSimpleCrypto::QBlockCipher blockCipher;
|
||||
static_cast<void>(blockCipher.decryptAesBlockCipher(responseBody, key, iv, "", salt));
|
||||
|
@ -296,7 +296,7 @@ void GatewayController::bypassProxy(const QString &endpoint, QNetworkReply *repl
|
|||
connect(reply, &QNetworkReply::sslErrors, [this, &sslErrors](const QList<QSslError> &errors) { sslErrors = errors; });
|
||||
wait.exec();
|
||||
|
||||
if (!replyProcessingFunction(reply, sslErrors)) {
|
||||
if (replyProcessingFunction(reply, sslErrors)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -407,7 +407,7 @@ bool ApiConfigsController::isConfigValid()
|
|||
return updateServiceFromGateway(serverIndex, "", "");
|
||||
} else if (configSource && m_serversModel->isApiKeyExpired(serverIndex)) {
|
||||
qDebug() << "attempt to update api config by expires_at event";
|
||||
if (configSource == apiDefs::ConfigSource::Telegram) {
|
||||
if (configSource == apiDefs::ConfigSource::AmneziaGateway) {
|
||||
return updateServiceFromGateway(serverIndex, "", "");
|
||||
} else {
|
||||
m_serversModel->removeApiConfig(serverIndex);
|
||||
|
|
|
@ -48,8 +48,8 @@ QVariant ApiAccountInfoModel::data(const QModelIndex &index, int role) const
|
|||
}
|
||||
case ServiceDescriptionRole: {
|
||||
if (m_accountInfoData.configType == apiDefs::ConfigType::AmneziaPremiumV2) {
|
||||
return tr("Classic VPN for comfortable work, downloading large files and watching videos. Works for any sites. Speed up to 200 "
|
||||
"Mb/s");
|
||||
return tr("Classic VPN for seamless work, downloading large files, and watching videos. Access all websites and online resources. "
|
||||
"Speeds up to 200 Mbps");
|
||||
} else if (m_accountInfoData.configType == apiDefs::ConfigType::AmneziaFreeV3) {
|
||||
return tr("Free unlimited access to a basic set of websites such as Facebook, Instagram, Twitter (X), Discord, Telegram and "
|
||||
"more. YouTube is not included in the free plan.");
|
||||
|
|
|
@ -81,7 +81,7 @@ PageType {
|
|||
actionButtonImage: "qrc:/images/controls/settings.svg"
|
||||
|
||||
headerText: root.processedServer.name
|
||||
descriptionText: qsTr("Locations for connection")
|
||||
descriptionText: qsTr("Location for connection")
|
||||
|
||||
actionButtonFunction: function() {
|
||||
PageController.showBusyIndicator(true)
|
||||
|
|
|
@ -42,8 +42,8 @@ PageType {
|
|||
Layout.rightMargin: 16
|
||||
Layout.leftMargin: 16
|
||||
|
||||
headerText: qsTr("Connected devices")
|
||||
descriptionText: qsTr("To manage connected devices")
|
||||
headerText: qsTr("Active devices")
|
||||
descriptionText: qsTr("Manage currently connected devices")
|
||||
}
|
||||
|
||||
WarningType {
|
||||
|
@ -71,8 +71,13 @@ PageType {
|
|||
rightImageSource: "qrc:/images/controls/trash.svg"
|
||||
|
||||
clickedFunction: function() {
|
||||
var headerText = qsTr("Deactivate the subscription on selected device")
|
||||
var descriptionText = qsTr("The next time the “Connect” button is pressed, the device will be activated again")
|
||||
if (isCurrentDevice && ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) {
|
||||
PageController.showNotificationMessage(qsTr("Cannot unlink device during active connection"))
|
||||
return
|
||||
}
|
||||
|
||||
var headerText = qsTr("Are you sure you want to unlink this device?")
|
||||
var descriptionText = qsTr("This will unlink the device from your subscription. You can reconnect it anytime by pressing Connect.")
|
||||
var yesButtonText = qsTr("Continue")
|
||||
var noButtonText = qsTr("Cancel")
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ PageType {
|
|||
Layout.leftMargin: 16
|
||||
|
||||
headerText: qsTr("How to connect on another device")
|
||||
descriptionText: qsTr("Instructions on the Amnezia website")
|
||||
descriptionText: qsTr("Setup guides on the Amnezia website")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ PageType {
|
|||
Layout.leftMargin: 16
|
||||
|
||||
headerText: qsTr("Configuration files")
|
||||
descriptionText: qsTr("To connect a router or AmneziaWG application")
|
||||
descriptionText: qsTr("For router setup or the AmneziaWG app")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -123,13 +123,13 @@ PageType {
|
|||
Layout.fillWidth: true
|
||||
Layout.margins: 16
|
||||
|
||||
headerText: qsTr("Configuration file ") + moreOptionsDrawer.countryName
|
||||
headerText: moreOptionsDrawer.countryName + qsTr(" configuration file")
|
||||
}
|
||||
|
||||
LabelWithButtonType {
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: qsTr("Create a new")
|
||||
text: qsTr("Generate a new configuration file")
|
||||
descriptionText: qsTr("The previously created one will stop working")
|
||||
|
||||
clickedFunction: function() {
|
||||
|
@ -193,9 +193,15 @@ PageType {
|
|||
}
|
||||
|
||||
function showQuestion(isConfigIssue, countryCode, countryName) {
|
||||
var headerText = qsTr("Revoke the actual %1 configuration file?").arg(countryName)
|
||||
var descriptionText = qsTr("The previously created file will no longer be valid. It will not be possible to connect using it.")
|
||||
var yesButtonText = qsTr("Continue")
|
||||
var headerText
|
||||
if (isConfigIssue) {
|
||||
headerText = qsTr("Generate a new %1 configuration file?").arg(countryName)
|
||||
} else {
|
||||
headerText = qsTr("Revoke the current %1 configuration file?").arg(countryName)
|
||||
}
|
||||
|
||||
var descriptionText = qsTr("Your previous configuration file will no longer work, and it will not be possible to connect using it")
|
||||
var yesButtonText = isConfigIssue ? qsTr("Download") : qsTr("Continue")
|
||||
var noButtonText = qsTr("Cancel")
|
||||
|
||||
var yesButtonFunction = function() {
|
||||
|
|
|
@ -42,7 +42,7 @@ PageType {
|
|||
QtObject {
|
||||
id: deviceCountObject
|
||||
|
||||
readonly property string title: qsTr("Connected devices")
|
||||
readonly property string title: qsTr("Active connections")
|
||||
readonly property string contentKey: "connectedDevices"
|
||||
readonly property string objectImageSource: "qrc:/images/controls/monitor.svg"
|
||||
}
|
||||
|
@ -215,7 +215,7 @@ PageType {
|
|||
|
||||
text: qsTr("Configuration files")
|
||||
|
||||
descriptionText: qsTr("To connect a router or AmneziaWG application")
|
||||
descriptionText: qsTr("Manage configuration files")
|
||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||
|
||||
clickedFunction: function() {
|
||||
|
@ -233,9 +233,9 @@ PageType {
|
|||
|
||||
visible: footer.isVisibleForAmneziaFree
|
||||
|
||||
text: qsTr("Connected devices")
|
||||
text: qsTr("Active devices")
|
||||
|
||||
descriptionText: qsTr("To manage connected devices")
|
||||
descriptionText: qsTr("Manage currently connected devices")
|
||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||
|
||||
clickedFunction: function() {
|
||||
|
@ -265,6 +265,8 @@ PageType {
|
|||
LabelWithButtonType {
|
||||
Layout.fillWidth: true
|
||||
|
||||
visible: footer.isVisibleForAmneziaFree
|
||||
|
||||
text: qsTr("How to connect on another device")
|
||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||
|
||||
|
@ -273,7 +275,9 @@ PageType {
|
|||
}
|
||||
}
|
||||
|
||||
DividerType {}
|
||||
DividerType {
|
||||
visible: footer.isVisibleForAmneziaFree
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
id: resetButton
|
||||
|
@ -325,17 +329,17 @@ PageType {
|
|||
pressedColor: AmneziaStyle.color.sheerWhite
|
||||
textColor: AmneziaStyle.color.vibrantRed
|
||||
|
||||
text: qsTr("Deactivate the subscription on this device")
|
||||
text: qsTr("Unlink this device")
|
||||
|
||||
clickedFunc: function() {
|
||||
var headerText = qsTr("Deactivate the subscription on this device?")
|
||||
var descriptionText = qsTr("The next time the “Connect” button is pressed, the device will be activated again")
|
||||
var headerText = qsTr("Are you sure you want to unlink this device?")
|
||||
var descriptionText = qsTr("This will unlink the device from your subscription. You can reconnect it anytime by pressing Connect.")
|
||||
var yesButtonText = qsTr("Continue")
|
||||
var noButtonText = qsTr("Cancel")
|
||||
|
||||
var yesButtonFunction = function() {
|
||||
if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) {
|
||||
PageController.showNotificationMessage(qsTr("Cannot deactivate subscription during active connection"))
|
||||
PageController.showNotificationMessage(qsTr("Cannot unlink device during active connection"))
|
||||
} else {
|
||||
PageController.showBusyIndicator(true)
|
||||
if (ApiConfigsController.deactivateDevice()) {
|
||||
|
|
|
@ -27,7 +27,7 @@ PageType {
|
|||
QtObject {
|
||||
id: techSupport
|
||||
|
||||
readonly property string title: qsTr("For technical support")
|
||||
readonly property string title: qsTr("Email Support")
|
||||
readonly property string description: qsTr("support@amnezia.org")
|
||||
readonly property string link: "mailto:support@amnezia.org"
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ PageType {
|
|||
QtObject {
|
||||
id: paymentSupport
|
||||
|
||||
readonly property string title: qsTr("For payment issues")
|
||||
readonly property string title: qsTr("Email Billing & Orders")
|
||||
readonly property string description: qsTr("help@vpnpay.io")
|
||||
readonly property string link: "mailto:help@vpnpay.io"
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ PageType {
|
|||
QtObject {
|
||||
id: site
|
||||
|
||||
readonly property string title: qsTr("Site")
|
||||
readonly property string title: qsTr("Website")
|
||||
readonly property string description: qsTr("amnezia.org")
|
||||
readonly property string link: LanguageModel.getCurrentSiteUrl()
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ PageType {
|
|||
Layout.leftMargin: 16
|
||||
|
||||
headerText: qsTr("Support")
|
||||
descriptionText: qsTr("Our technical support specialists are ready to help you at any time")
|
||||
descriptionText: qsTr("Our technical support specialists are available to assist you at any time")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue