chore/minor fixes (#1610)

* bugfix: fixed the migration form appearing on app start

* feature: added app version to api requests payload

* chore: remove unused file

* feature: extended logging in service part

* chore: bump version

* chore: update ru translation file
This commit is contained in:
Nethius 2025-05-23 14:53:55 +08:00 committed by GitHub
parent c2f9340db6
commit 48a5452a65
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 78 additions and 88 deletions

View file

@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.25.0 FATAL_ERROR)
set(PROJECT AmneziaVPN) set(PROJECT AmneziaVPN)
project(${PROJECT} VERSION 4.8.7.1 project(${PROJECT} VERSION 4.8.7.2
DESCRIPTION "AmneziaVPN" DESCRIPTION "AmneziaVPN"
HOMEPAGE_URL "https://amnezia.org/" HOMEPAGE_URL "https://amnezia.org/"
) )
@ -11,7 +11,7 @@ string(TIMESTAMP CURRENT_DATE "%Y-%m-%d")
set(RELEASE_DATE "${CURRENT_DATE}") set(RELEASE_DATE "${CURRENT_DATE}")
set(APP_MAJOR_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH}) set(APP_MAJOR_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH})
set(APP_ANDROID_VERSION_CODE 2085) set(APP_ANDROID_VERSION_CODE 2086)
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
set(MZ_PLATFORM_NAME "linux") set(MZ_PLATFORM_NAME "linux")

View file

@ -31,6 +31,7 @@ namespace apiDefs
constexpr QLatin1String apiConfig("api_config"); constexpr QLatin1String apiConfig("api_config");
constexpr QLatin1String stackType("stack_type"); constexpr QLatin1String stackType("stack_type");
constexpr QLatin1String serviceType("service_type"); constexpr QLatin1String serviceType("service_type");
constexpr QLatin1String cliVersion("cli_version");
constexpr QLatin1String vpnKey("vpn_key"); constexpr QLatin1String vpnKey("vpn_key");
constexpr QLatin1String config("config"); constexpr QLatin1String config("config");

View file

@ -41,32 +41,34 @@ bool apiUtils::isServerFromApi(const QJsonObject &serverConfigObject)
apiDefs::ConfigType apiUtils::getConfigType(const QJsonObject &serverConfigObject) apiDefs::ConfigType apiUtils::getConfigType(const QJsonObject &serverConfigObject)
{ {
auto configVersion = serverConfigObject.value(apiDefs::key::configVersion).toInt(); auto configVersion = serverConfigObject.value(apiDefs::key::configVersion).toInt();
switch (configVersion) { switch (configVersion) {
case apiDefs::ConfigSource::Telegram: { case apiDefs::ConfigSource::Telegram: {
constexpr QLatin1String freeV2Endpoint(FREE_V2_ENDPOINT);
constexpr QLatin1String premiumV1Endpoint(PREM_V1_ENDPOINT);
auto apiEndpoint = serverConfigObject.value(apiDefs::key::apiEndpoint).toString();
if (apiEndpoint.contains(premiumV1Endpoint)) {
return apiDefs::ConfigType::AmneziaPremiumV1;
} else if (apiEndpoint.contains(freeV2Endpoint)) {
return apiDefs::ConfigType::AmneziaFreeV2;
}
}; };
case apiDefs::ConfigSource::AmneziaGateway: { case apiDefs::ConfigSource::AmneziaGateway: {
constexpr QLatin1String servicePremium("amnezia-premium"); constexpr QLatin1String servicePremium("amnezia-premium");
constexpr QLatin1String serviceFree("amnezia-free"); constexpr QLatin1String serviceFree("amnezia-free");
constexpr QLatin1String serviceExternalPremium("external-premium"); constexpr QLatin1String serviceExternalPremium("external-premium");
constexpr QLatin1String freeV2Endpoint(FREE_V2_ENDPOINT);
constexpr QLatin1String premiumV1Endpoint(PREM_V1_ENDPOINT);
auto apiConfigObject = serverConfigObject.value(apiDefs::key::apiConfig).toObject(); auto apiConfigObject = serverConfigObject.value(apiDefs::key::apiConfig).toObject();
auto serviceType = apiConfigObject.value(apiDefs::key::serviceType).toString(); auto serviceType = apiConfigObject.value(apiDefs::key::serviceType).toString();
auto apiEndpoint = serverConfigObject.value(apiDefs::key::apiEndpoint).toString();
if (serviceType == servicePremium) { if (serviceType == servicePremium) {
return apiDefs::ConfigType::AmneziaPremiumV2; return apiDefs::ConfigType::AmneziaPremiumV2;
} else if (serviceType == serviceFree) { } else if (serviceType == serviceFree) {
return apiDefs::ConfigType::AmneziaFreeV3; return apiDefs::ConfigType::AmneziaFreeV3;
} else if (serviceType == serviceExternalPremium) { } else if (serviceType == serviceExternalPremium) {
return apiDefs::ConfigType::ExternalPremium; return apiDefs::ConfigType::ExternalPremium;
} else if (apiEndpoint.contains(premiumV1Endpoint)) {
return apiDefs::ConfigType::AmneziaPremiumV1;
} else if (apiEndpoint.contains(freeV2Endpoint)) {
return apiDefs::ConfigType::AmneziaFreeV2;
} }
} }
default: { default: {
@ -94,6 +96,9 @@ amnezia::ErrorCode apiUtils::checkNetworkReplyErrors(const QList<QSslError> &ssl
|| reply->error() == QNetworkReply::NetworkError::TimeoutError) { || reply->error() == QNetworkReply::NetworkError::TimeoutError) {
qDebug() << reply->error(); qDebug() << reply->error();
return amnezia::ErrorCode::ApiConfigTimeoutError; return amnezia::ErrorCode::ApiConfigTimeoutError;
} else if (reply->error() == QNetworkReply::NetworkError::OperationNotImplementedError) {
qDebug() << reply->error();
return amnezia::ErrorCode::ApiUpdateRequestError;
} else { } else {
QString err = reply->errorString(); QString err = reply->errorString();
int httpStatusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); int httpStatusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();

View file

@ -36,6 +36,8 @@ namespace
constexpr QLatin1String errorResponsePattern1("No active configuration found for"); constexpr QLatin1String errorResponsePattern1("No active configuration found for");
constexpr QLatin1String errorResponsePattern2("No non-revoked public key found for"); constexpr QLatin1String errorResponsePattern2("No non-revoked public key found for");
constexpr QLatin1String errorResponsePattern3("Account not found."); constexpr QLatin1String errorResponsePattern3("Account not found.");
constexpr QLatin1String updateRequestResponsePattern("client version update is required");
} }
GatewayController::GatewayController(const QString &gatewayEndpoint, const bool isDevEnvironment, const int requestTimeoutMsecs, GatewayController::GatewayController(const QString &gatewayEndpoint, const bool isDevEnvironment, const int requestTimeoutMsecs,
@ -311,6 +313,13 @@ bool GatewayController::shouldBypassProxy(QNetworkReply *reply, const QByteArray
qDebug() << reply->error(); qDebug() << reply->error();
return true; return true;
} }
} else if (reply->error() == QNetworkReply::NetworkError::OperationNotImplementedError) {
if (responseBody.contains(updateRequestResponsePattern)) {
return false;
} else {
qDebug() << reply->error();
return true;
}
} else if (reply->error() != QNetworkReply::NetworkError::NoError) { } else if (reply->error() != QNetworkReply::NetworkError::NoError) {
qDebug() << reply->error(); qDebug() << reply->error();
return true; return true;

View file

@ -118,6 +118,7 @@ namespace amnezia
ApiConfigLimitError = 1108, ApiConfigLimitError = 1108,
ApiNotFoundError = 1109, ApiNotFoundError = 1109,
ApiMigrationError = 1110, ApiMigrationError = 1110,
ApiUpdateRequestError = 1111,
// QFile errors // QFile errors
OpenError = 1200, OpenError = 1200,

View file

@ -75,6 +75,7 @@ QString errorString(ErrorCode code) {
case (ErrorCode::ApiConfigLimitError): errorMessage = QObject::tr("The limit of allowed configurations per subscription has been exceeded"); break; case (ErrorCode::ApiConfigLimitError): errorMessage = QObject::tr("The limit of allowed configurations per subscription has been exceeded"); break;
case (ErrorCode::ApiNotFoundError): errorMessage = QObject::tr("Error when retrieving configuration from API"); break; case (ErrorCode::ApiNotFoundError): errorMessage = QObject::tr("Error when retrieving configuration from API"); break;
case (ErrorCode::ApiMigrationError): errorMessage = QObject::tr("A migration error has occurred. Please contact our technical support"); break; case (ErrorCode::ApiMigrationError): errorMessage = QObject::tr("A migration error has occurred. Please contact our technical support"); break;
case (ErrorCode::ApiUpdateRequestError): errorMessage = QObject::tr("Please update the application to use this feature"); break;
// QFile errors // QFile errors
case(ErrorCode::OpenError): errorMessage = QObject::tr("QFile error: The file could not be opened"); break; case(ErrorCode::OpenError): errorMessage = QObject::tr("QFile error: The file could not be opened"); break;

View file

@ -149,8 +149,7 @@ bool Daemon::activate(const InterfaceConfig& config) {
// set routing // set routing
for (const IPAddress& ip : config.m_allowedIPAddressRanges) { for (const IPAddress& ip : config.m_allowedIPAddressRanges) {
if (!wgutils()->updateRoutePrefix(ip)) { if (!wgutils()->updateRoutePrefix(ip)) {
logger.debug() << "Routing configuration failed for" logger.debug() << "Routing configuration failed for" << ip.toString();
<< logger.sensitive(ip.toString());
return false; return false;
} }
} }

View file

@ -97,7 +97,7 @@ bool IPUtilsLinux::addIP4AddressToDevice(const InterfaceConfig& config) {
// Set ifr to interface // Set ifr to interface
int ret = ioctl(sockfd, SIOCSIFADDR, &ifr); int ret = ioctl(sockfd, SIOCSIFADDR, &ifr);
if (ret) { if (ret) {
logger.error() << "Failed to set IPv4: " << logger.sensitive(deviceAddr) logger.error() << "Failed to set IPv4: " << deviceAddr
<< "error:" << strerror(errno); << "error:" << strerror(errno);
return false; return false;
} }
@ -138,7 +138,7 @@ bool IPUtilsLinux::addIP6AddressToDevice(const InterfaceConfig& config) {
// Set ifr6 to the interface // Set ifr6 to the interface
ret = ioctl(sockfd, SIOCSIFADDR, &ifr6); ret = ioctl(sockfd, SIOCSIFADDR, &ifr6);
if (ret && (errno != EEXIST)) { if (ret && (errno != EEXIST)) {
logger.error() << "Failed to set IPv6: " << logger.sensitive(deviceAddr) logger.error() << "Failed to set IPv6: " << deviceAddr
<< "error:" << strerror(errno); << "error:" << strerror(errno);
return false; return false;
} }

View file

@ -122,7 +122,7 @@ bool IPUtilsMacos::addIP4AddressToDevice(const InterfaceConfig& config) {
// Set ifr to interface // Set ifr to interface
int ret = ioctl(sockfd, SIOCAIFADDR, &ifr); int ret = ioctl(sockfd, SIOCAIFADDR, &ifr);
if (ret) { if (ret) {
logger.error() << "Failed to set IPv4: " << logger.sensitive(deviceAddr) logger.error() << "Failed to set IPv4: " << deviceAddr
<< "error:" << strerror(errno); << "error:" << strerror(errno);
return false; return false;
} }
@ -162,7 +162,7 @@ bool IPUtilsMacos::addIP6AddressToDevice(const InterfaceConfig& config) {
// Set ifr to interface // Set ifr to interface
int ret = ioctl(sockfd, SIOCAIFADDR_IN6, &ifr6); int ret = ioctl(sockfd, SIOCAIFADDR_IN6, &ifr6);
if (ret) { if (ret) {
logger.error() << "Failed to set IPv6: " << logger.sensitive(deviceAddr) logger.error() << "Failed to set IPv6: " << deviceAddr
<< "error:" << strerror(errno); << "error:" << strerror(errno);
return false; return false;
} }

View file

@ -144,7 +144,7 @@ void MacosRouteMonitor::handleRtmDelete(const struct rt_msghdr* rtm,
for (const IPAddress& prefix : m_exclusionRoutes) { for (const IPAddress& prefix : m_exclusionRoutes) {
if (prefix.address().protocol() == protocol) { if (prefix.address().protocol() == protocol) {
logger.debug() << "Removing exclusion route to" logger.debug() << "Removing exclusion route to"
<< logger.sensitive(prefix.toString()); << prefix.toString();
rtmSendRoute(RTM_DELETE, prefix, rtm->rtm_index, nullptr); rtmSendRoute(RTM_DELETE, prefix, rtm->rtm_index, nullptr);
} }
} }
@ -259,7 +259,7 @@ void MacosRouteMonitor::handleRtmUpdate(const struct rt_msghdr* rtm,
for (const IPAddress& prefix : m_exclusionRoutes) { for (const IPAddress& prefix : m_exclusionRoutes) {
if (prefix.address().protocol() == protocol) { if (prefix.address().protocol() == protocol) {
logger.debug() << "Updating exclusion route to" logger.debug() << "Updating exclusion route to"
<< logger.sensitive(prefix.toString()); << prefix.toString();
rtmSendRoute(rtm_type, prefix, ifindex, addrlist[1].constData()); rtmSendRoute(rtm_type, prefix, ifindex, addrlist[1].constData());
} }
} }
@ -510,8 +510,7 @@ bool MacosRouteMonitor::deleteRoute(const IPAddress& prefix, int flags) {
} }
bool MacosRouteMonitor::addExclusionRoute(const IPAddress& prefix) { bool MacosRouteMonitor::addExclusionRoute(const IPAddress& prefix) {
logger.debug() << "Adding exclusion route for" logger.debug() << "Adding exclusion route for" << prefix.toString();
<< logger.sensitive(prefix.toString());
if (m_exclusionRoutes.contains(prefix)) { if (m_exclusionRoutes.contains(prefix)) {
logger.warning() << "Exclusion route already exists"; logger.warning() << "Exclusion route already exists";
@ -536,8 +535,7 @@ bool MacosRouteMonitor::addExclusionRoute(const IPAddress& prefix) {
} }
bool MacosRouteMonitor::deleteExclusionRoute(const IPAddress& prefix) { bool MacosRouteMonitor::deleteExclusionRoute(const IPAddress& prefix) {
logger.debug() << "Deleting exclusion route for" logger.debug() << "Deleting exclusion route for" << prefix.toString();
<< logger.sensitive(prefix.toString());
m_exclusionRoutes.removeAll(prefix); m_exclusionRoutes.removeAll(prefix);
if (prefix.address().protocol() == QAbstractSocket::IPv4Protocol) { if (prefix.address().protocol() == QAbstractSocket::IPv4Protocol) {

View file

@ -303,8 +303,7 @@ void WindowsRouteMonitor::updateCapturedRoutes(int family, void* ptable) {
data->Age++; data->Age++;
continue; continue;
} }
logger.debug() << "Capturing route to" logger.debug() << "Capturing route to" << prefix.toString();
<< logger.sensitive(prefix.toString());
// Clone the route and direct it into the VPN tunnel. // Clone the route and direct it into the VPN tunnel.
data = new MIB_IPFORWARD_ROW2; data = new MIB_IPFORWARD_ROW2;
@ -354,8 +353,7 @@ void WindowsRouteMonitor::updateCapturedRoutes(int family, void* ptable) {
continue; continue;
} }
logger.debug() << "Removing route capture for" logger.debug() << "Removing route capture for" << i.key().toString();
<< logger.sensitive(i.key().toString());
// Otherwise, this route is no longer in use. // Otherwise, this route is no longer in use.
DWORD result = DeleteIpForwardEntry2(data); DWORD result = DeleteIpForwardEntry2(data);
@ -368,8 +366,7 @@ void WindowsRouteMonitor::updateCapturedRoutes(int family, void* ptable) {
} }
bool WindowsRouteMonitor::addExclusionRoute(const IPAddress& prefix) { bool WindowsRouteMonitor::addExclusionRoute(const IPAddress& prefix) {
logger.debug() << "Adding exclusion route for" logger.debug() << "Adding exclusion route for" << prefix.toString();
<< logger.sensitive(prefix.toString());
// Silently ignore non-routeable addresses. // Silently ignore non-routeable addresses.
QHostAddress addr = prefix.address(); QHostAddress addr = prefix.address();
@ -437,7 +434,7 @@ bool WindowsRouteMonitor::addExclusionRoute(const IPAddress& prefix) {
bool WindowsRouteMonitor::deleteExclusionRoute(const IPAddress& prefix) { bool WindowsRouteMonitor::deleteExclusionRoute(const IPAddress& prefix) {
logger.debug() << "Deleting exclusion route for" logger.debug() << "Deleting exclusion route for"
<< logger.sensitive(prefix.address().toString()); << prefix.address().toString();
MIB_IPFORWARD_ROW2* data = m_exclusionRoutes.take(prefix); MIB_IPFORWARD_ROW2* data = m_exclusionRoutes.take(prefix);
if (data == nullptr) { if (data == nullptr) {
@ -447,7 +444,7 @@ bool WindowsRouteMonitor::deleteExclusionRoute(const IPAddress& prefix) {
DWORD result = DeleteIpForwardEntry2(data); DWORD result = DeleteIpForwardEntry2(data);
if ((result != ERROR_NOT_FOUND) && (result != NO_ERROR)) { if ((result != ERROR_NOT_FOUND) && (result != NO_ERROR)) {
logger.error() << "Failed to delete route to" logger.error() << "Failed to delete route to"
<< logger.sensitive(prefix.toString()) << prefix.toString()
<< "result:" << result; << "result:" << result;
} }
@ -465,7 +462,7 @@ void WindowsRouteMonitor::flushRouteTable(
DWORD result = DeleteIpForwardEntry2(data); DWORD result = DeleteIpForwardEntry2(data);
if ((result != ERROR_NOT_FOUND) && (result != NO_ERROR)) { if ((result != ERROR_NOT_FOUND) && (result != NO_ERROR)) {
logger.error() << "Failed to delete route to" logger.error() << "Failed to delete route to"
<< logger.sensitive(i.key().toString()) << i.key().toString()
<< "result:" << result; << "result:" << result;
} }
delete data; delete data;

View file

@ -89,17 +89,17 @@
<context> <context>
<name>ApiConfigsController</name> <name>ApiConfigsController</name>
<message> <message>
<location filename="../ui/controllers/api/apiConfigsController.cpp" line="207"/> <location filename="../ui/controllers/api/apiConfigsController.cpp" line="210"/>
<source>%1 installed successfully.</source> <source>%1 installed successfully.</source>
<translation>%1 успешно установлен.</translation> <translation>%1 успешно установлен.</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/api/apiConfigsController.cpp" line="262"/> <location filename="../ui/controllers/api/apiConfigsController.cpp" line="266"/>
<source>API config reloaded</source> <source>API config reloaded</source>
<translation>Конфигурация API перезагружена</translation> <translation>Конфигурация API перезагружена</translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/api/apiConfigsController.cpp" line="266"/> <location filename="../ui/controllers/api/apiConfigsController.cpp" line="270"/>
<source>Successfully changed the country of connection to %1</source> <source>Successfully changed the country of connection to %1</source>
<translation>Страна подключения изменена на %1</translation> <translation>Страна подключения изменена на %1</translation>
</message> </message>
@ -358,7 +358,7 @@
<context> <context>
<name>ContextMenuType</name> <name>ContextMenuType</name>
<message> <message>
<location filename="../ui/qml/Controls2/ContextMenuType.qml" line="9"/> <location filename="../ui/qml/Controls2/ContextMenuType.qml" line="10"/>
<source>C&amp;ut</source> <source>C&amp;ut</source>
<translation>Вырезать</translation> <translation>Вырезать</translation>
</message> </message>
@ -368,12 +368,12 @@
<translation>Копировать</translation> <translation>Копировать</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Controls2/ContextMenuType.qml" line="21"/> <location filename="../ui/qml/Controls2/ContextMenuType.qml" line="20"/>
<source>&amp;Paste</source> <source>&amp;Paste</source>
<translation>Вставить</translation> <translation>Вставить</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Controls2/ContextMenuType.qml" line="29"/> <location filename="../ui/qml/Controls2/ContextMenuType.qml" line="27"/>
<source>&amp;SelectAll</source> <source>&amp;SelectAll</source>
<translation>Выбрать всё</translation> <translation>Выбрать всё</translation>
</message> </message>
@ -2412,42 +2412,42 @@ Thank you for staying with us!</source>
<translation>Доступ в интернет блокируется при разрыве VPN-соединения</translation> <translation>Доступ в интернет блокируется при разрыве VPN-соединения</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsKillSwitch.qml" line="87"/> <location filename="../ui/qml/Pages2/PageSettingsKillSwitch.qml" line="88"/>
<source>Strict KillSwitch</source> <source>Strict KillSwitch</source>
<translation>Strict KillSwitch</translation> <translation>Strict KillSwitch</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsKillSwitch.qml" line="88"/> <location filename="../ui/qml/Pages2/PageSettingsKillSwitch.qml" line="89"/>
<source>Internet connection is blocked even when VPN is turned off manually or hasn&apos;t started</source> <source>Internet connection is blocked even when VPN is turned off manually or hasn&apos;t started</source>
<translation>Доступ в интернет блокируется, даже если VPN отключен вручную или не был запущен</translation> <translation>Доступ в интернет блокируется, даже если VPN отключен вручную или не был запущен</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsKillSwitch.qml" line="91"/> <location filename="../ui/qml/Pages2/PageSettingsKillSwitch.qml" line="92"/>
<source>Just a little heads-up</source> <source>Just a little heads-up</source>
<translation>Небольшое предупреждение</translation> <translation>Небольшое предупреждение</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsKillSwitch.qml" line="92"/> <location filename="../ui/qml/Pages2/PageSettingsKillSwitch.qml" line="93"/>
<source>If the VPN disconnects or drops while Strict KillSwitch is enabled, internet access will be blocked. To restore access, reconnect VPN or disable/change the KillSwitch.</source> <source>If the VPN disconnects or drops while Strict KillSwitch is enabled, internet access will be blocked. To restore access, reconnect VPN or disable/change the KillSwitch.</source>
<translation>Если VPN отключится или соединение прервётся при включённом Strict KillSwitch, доступ в интернет будет заблокирован. Чтобы восстановить доступ, снова подключитесь к VPN или отключите (измените) режим KillSwitch.</translation> <translation>Если VPN отключится или соединение прервётся при включённом Strict KillSwitch, доступ в интернет будет заблокирован. Чтобы восстановить доступ, снова подключитесь к VPN или отключите (измените) режим KillSwitch.</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsKillSwitch.qml" line="93"/> <location filename="../ui/qml/Pages2/PageSettingsKillSwitch.qml" line="94"/>
<source>Continue</source> <source>Continue</source>
<translation>Продолжить</translation> <translation>Продолжить</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsKillSwitch.qml" line="94"/> <location filename="../ui/qml/Pages2/PageSettingsKillSwitch.qml" line="95"/>
<source>Cancel</source> <source>Cancel</source>
<translation>Отменить</translation> <translation>Отменить</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsKillSwitch.qml" line="113"/> <location filename="../ui/qml/Pages2/PageSettingsKillSwitch.qml" line="116"/>
<source>DNS Exceptions</source> <source>DNS Exceptions</source>
<translation>Исключения для DNS</translation> <translation>Исключения для DNS</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsKillSwitch.qml" line="114"/> <location filename="../ui/qml/Pages2/PageSettingsKillSwitch.qml" line="117"/>
<source>DNS servers listed here will remain accessible when KillSwitch is active.</source> <source>DNS servers listed here will remain accessible when KillSwitch is active.</source>
<translation>DNS-серверы из этого списка останутся доступными при активном KillSwitch.</translation> <translation>DNS-серверы из этого списка останутся доступными при активном KillSwitch.</translation>
</message> </message>
@ -4085,7 +4085,12 @@ Thank you for staying with us!</source>
<translation>Произошла ошибка миграции. Обратитесь в нашу техническую поддержку</translation> <translation>Произошла ошибка миграции. Обратитесь в нашу техническую поддержку</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="92"/> <location filename="../core/errorstrings.cpp" line="78"/>
<source>Please update the application to use this feature</source>
<translation>Пожалуйста, обновите приложение, чтобы использовать эту функцию</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="93"/>
<source>ErrorCode: %1. </source> <source>ErrorCode: %1. </source>
<translation>Код ошибки: %1. </translation> <translation>Код ошибки: %1. </translation>
</message> </message>
@ -4196,37 +4201,37 @@ Thank you for staying with us!</source>
<translation type="vanished">Произошла ошибка миграции. Обратитесь в нашу техническую поддержку</translation> <translation type="vanished">Произошла ошибка миграции. Обратитесь в нашу техническую поддержку</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="80"/> <location filename="../core/errorstrings.cpp" line="81"/>
<source>QFile error: The file could not be opened</source> <source>QFile error: The file could not be opened</source>
<translation>Ошибка QFile: не удалось открыть файл</translation> <translation>Ошибка QFile: не удалось открыть файл</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="81"/> <location filename="../core/errorstrings.cpp" line="82"/>
<source>QFile error: An error occurred when reading from the file</source> <source>QFile error: An error occurred when reading from the file</source>
<translation>Ошибка QFile: произошла ошибка при чтении из файла</translation> <translation>Ошибка QFile: произошла ошибка при чтении из файла</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="82"/> <location filename="../core/errorstrings.cpp" line="83"/>
<source>QFile error: The file could not be accessed</source> <source>QFile error: The file could not be accessed</source>
<translation>Ошибка QFile: не удалось получить доступ к файлу</translation> <translation>Ошибка QFile: не удалось получить доступ к файлу</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="83"/> <location filename="../core/errorstrings.cpp" line="84"/>
<source>QFile error: An unspecified error occurred</source> <source>QFile error: An unspecified error occurred</source>
<translation>Ошибка QFile: произошла неизвестная ошибка</translation> <translation>Ошибка QFile: произошла неизвестная ошибка</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="84"/> <location filename="../core/errorstrings.cpp" line="85"/>
<source>QFile error: A fatal error occurred</source> <source>QFile error: A fatal error occurred</source>
<translation>Ошибка QFile: произошла фатальная ошибка</translation> <translation>Ошибка QFile: произошла фатальная ошибка</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="85"/> <location filename="../core/errorstrings.cpp" line="86"/>
<source>QFile error: The operation was aborted</source> <source>QFile error: The operation was aborted</source>
<translation>Ошибка QFile: операция была прервана</translation> <translation>Ошибка QFile: операция была прервана</translation>
</message> </message>
<message> <message>
<location filename="../core/errorstrings.cpp" line="89"/> <location filename="../core/errorstrings.cpp" line="90"/>
<source>Internal error</source> <source>Internal error</source>
<translation>Внутренняя ошибка</translation> <translation>Внутренняя ошибка</translation>
</message> </message>

View file

@ -1,34 +0,0 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
TextArea {
id: root
width: parent.width
topPadding: 16
leftPadding: 16
color: "#D7D8DB"
selectionColor: "#412102"
selectedTextColor: "#D7D8DB"
placeholderTextColor: "#878B91"
font.pixelSize: 16
font.weight: Font.Medium
font.family: "PT Root UI VF"
wrapMode: Text.Wrap
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.RightButton
onClicked: contextMenu.open()
}
ContextMenuType {
id: contextMenu
textObj: textField
}
}

View file

@ -77,6 +77,7 @@ bool ApiConfigsController::exportNativeConfig(const QString &serverCountryCode,
apiPayload[configKey::serverCountryCode] = serverCountryCode; apiPayload[configKey::serverCountryCode] = serverCountryCode;
apiPayload[configKey::serviceType] = apiConfigObject.value(configKey::serviceType); apiPayload[configKey::serviceType] = apiConfigObject.value(configKey::serviceType);
apiPayload[configKey::authData] = serverConfigObject.value(configKey::authData); apiPayload[configKey::authData] = serverConfigObject.value(configKey::authData);
apiPayload[apiDefs::key::cliVersion] = QString(APP_VERSION);
QByteArray responseBody; QByteArray responseBody;
ErrorCode errorCode = gatewayController.post(QString("%1v1/native_config"), apiPayload, responseBody); ErrorCode errorCode = gatewayController.post(QString("%1v1/native_config"), apiPayload, responseBody);
@ -109,6 +110,7 @@ bool ApiConfigsController::revokeNativeConfig(const QString &serverCountryCode)
apiPayload[configKey::serverCountryCode] = serverCountryCode; apiPayload[configKey::serverCountryCode] = serverCountryCode;
apiPayload[configKey::serviceType] = apiConfigObject.value(configKey::serviceType); apiPayload[configKey::serviceType] = apiConfigObject.value(configKey::serviceType);
apiPayload[configKey::authData] = serverConfigObject.value(configKey::authData); apiPayload[configKey::authData] = serverConfigObject.value(configKey::authData);
apiPayload[apiDefs::key::cliVersion] = QString(APP_VERSION);
QByteArray responseBody; QByteArray responseBody;
ErrorCode errorCode = gatewayController.post(QString("%1v1/revoke_native_config"), apiPayload, responseBody); ErrorCode errorCode = gatewayController.post(QString("%1v1/revoke_native_config"), apiPayload, responseBody);
@ -188,6 +190,7 @@ bool ApiConfigsController::importServiceFromGateway()
apiPayload[configKey::userCountryCode] = userCountryCode; apiPayload[configKey::userCountryCode] = userCountryCode;
apiPayload[configKey::serviceType] = serviceType; apiPayload[configKey::serviceType] = serviceType;
apiPayload[configKey::uuid] = installationUuid; apiPayload[configKey::uuid] = installationUuid;
apiPayload[apiDefs::key::cliVersion] = QString(APP_VERSION);
QByteArray responseBody; QByteArray responseBody;
ErrorCode errorCode = gatewayController.post(QString("%1v1/config"), apiPayload, responseBody); ErrorCode errorCode = gatewayController.post(QString("%1v1/config"), apiPayload, responseBody);
@ -233,6 +236,7 @@ bool ApiConfigsController::updateServiceFromGateway(const int serverIndex, const
apiPayload[configKey::userCountryCode] = userCountryCode; apiPayload[configKey::userCountryCode] = userCountryCode;
apiPayload[configKey::serviceType] = serviceType; apiPayload[configKey::serviceType] = serviceType;
apiPayload[configKey::uuid] = installationUuid; apiPayload[configKey::uuid] = installationUuid;
apiPayload[apiDefs::key::cliVersion] = QString(APP_VERSION);
if (!newCountryCode.isEmpty()) { if (!newCountryCode.isEmpty()) {
apiPayload[configKey::serverCountryCode] = newCountryCode; apiPayload[configKey::serverCountryCode] = newCountryCode;
@ -330,6 +334,7 @@ bool ApiConfigsController::deactivateDevice()
apiPayload[configKey::serviceType] = apiConfigObject.value(configKey::serviceType); apiPayload[configKey::serviceType] = apiConfigObject.value(configKey::serviceType);
apiPayload[configKey::authData] = serverConfigObject.value(configKey::authData); apiPayload[configKey::authData] = serverConfigObject.value(configKey::authData);
apiPayload[configKey::uuid] = m_settings->getInstallationUuid(true); apiPayload[configKey::uuid] = m_settings->getInstallationUuid(true);
apiPayload[apiDefs::key::cliVersion] = QString(APP_VERSION);
QByteArray responseBody; QByteArray responseBody;
ErrorCode errorCode = gatewayController.post(QString("%1v1/revoke_config"), apiPayload, responseBody); ErrorCode errorCode = gatewayController.post(QString("%1v1/revoke_config"), apiPayload, responseBody);
@ -366,6 +371,7 @@ bool ApiConfigsController::deactivateExternalDevice(const QString &uuid, const Q
apiPayload[configKey::serviceType] = apiConfigObject.value(configKey::serviceType); apiPayload[configKey::serviceType] = apiConfigObject.value(configKey::serviceType);
apiPayload[configKey::authData] = serverConfigObject.value(configKey::authData); apiPayload[configKey::authData] = serverConfigObject.value(configKey::authData);
apiPayload[configKey::uuid] = uuid; apiPayload[configKey::uuid] = uuid;
apiPayload[apiDefs::key::cliVersion] = QString(APP_VERSION);
QByteArray responseBody; QByteArray responseBody;
ErrorCode errorCode = gatewayController.post(QString("%1v1/revoke_config"), apiPayload, responseBody); ErrorCode errorCode = gatewayController.post(QString("%1v1/revoke_config"), apiPayload, responseBody);

View file

@ -5,6 +5,7 @@
#include "core/api/apiUtils.h" #include "core/api/apiUtils.h"
#include "core/controllers/gatewayController.h" #include "core/controllers/gatewayController.h"
#include "version.h"
namespace namespace
{ {
@ -60,6 +61,7 @@ bool ApiSettingsController::getAccountInfo(bool reload)
apiPayload[configKey::userCountryCode] = apiConfig.value(configKey::userCountryCode).toString(); apiPayload[configKey::userCountryCode] = apiConfig.value(configKey::userCountryCode).toString();
apiPayload[configKey::serviceType] = apiConfig.value(configKey::serviceType).toString(); apiPayload[configKey::serviceType] = apiConfig.value(configKey::serviceType).toString();
apiPayload[configKey::authData] = authData; apiPayload[configKey::authData] = authData;
apiPayload[apiDefs::key::cliVersion] = QString(APP_VERSION);
QByteArray responseBody; QByteArray responseBody;