diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 6c4f1ae4..784408e2 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -107,7 +107,7 @@ set(HEADERS ${HEADERS} ${CMAKE_CURRENT_LIST_DIR}/core/errorstrings.h ${CMAKE_CURRENT_LIST_DIR}/core/scripts_registry.h ${CMAKE_CURRENT_LIST_DIR}/core/server_defs.h - ${CMAKE_CURRENT_LIST_DIR}/core/servercontroller.h + ${CMAKE_CURRENT_LIST_DIR}/core/controllers/serverController.h ${CMAKE_CURRENT_LIST_DIR}/protocols/protocols_defs.h ${CMAKE_CURRENT_LIST_DIR}/protocols/qml_register_protocols.h ${CMAKE_CURRENT_LIST_DIR}/ui/notificationhandler.h @@ -146,7 +146,7 @@ set(SOURCES ${SOURCES} ${CMAKE_CURRENT_LIST_DIR}/core/errorstrings.cpp ${CMAKE_CURRENT_LIST_DIR}/core/scripts_registry.cpp ${CMAKE_CURRENT_LIST_DIR}/core/server_defs.cpp - ${CMAKE_CURRENT_LIST_DIR}/core/servercontroller.cpp + ${CMAKE_CURRENT_LIST_DIR}/core/controllers/serverController.cpp ${CMAKE_CURRENT_LIST_DIR}/protocols/protocols_defs.cpp ${CMAKE_CURRENT_LIST_DIR}/ui/notificationhandler.cpp ${CMAKE_CURRENT_LIST_DIR}/ui/qautostart.cpp diff --git a/client/amnezia_application.cpp b/client/amnezia_application.cpp index 9d629b5b..40aab515 100644 --- a/client/amnezia_application.cpp +++ b/client/amnezia_application.cpp @@ -277,19 +277,16 @@ QQmlApplicationEngine *AmneziaApplication::qmlEngine() const void AmneziaApplication::initModels() { - m_containersModel.reset(new ContainersModel(m_settings, this)); + m_containersModel.reset(new ContainersModel(this)); m_engine->rootContext()->setContextProperty("ContainersModel", m_containersModel.get()); - connect(m_configurator.get(), &VpnConfigurator::newVpnConfigCreated, m_containersModel.get(), - &ContainersModel::updateContainersConfig); m_serversModel.reset(new ServersModel(m_settings, this)); m_engine->rootContext()->setContextProperty("ServersModel", m_serversModel.get()); - connect(m_serversModel.get(), &ServersModel::currentlyProcessedServerIndexChanged, m_containersModel.get(), - &ContainersModel::setCurrentlyProcessedServerIndex); - connect(m_serversModel.get(), &ServersModel::defaultServerIndexChanged, m_containersModel.get(), - &ContainersModel::setCurrentlyProcessedServerIndex); - connect(m_containersModel.get(), &ContainersModel::containersModelUpdated, m_serversModel.get(), - &ServersModel::updateContainersConfig); + connect(m_serversModel.get(), &ServersModel::containersUpdated, m_containersModel.get(), + &ContainersModel::updateModel); + connect(m_serversModel.get(), &ServersModel::defaultContainerChanged, m_containersModel.get(), + &ContainersModel::setDefaultContainer); + m_containersModel->setDefaultContainer(m_serversModel->getDefaultContainer()); // make better? m_languageModel.reset(new LanguageModel(m_settings, this)); m_engine->rootContext()->setContextProperty("LanguageModel", m_languageModel.get()); @@ -298,7 +295,7 @@ void AmneziaApplication::initModels() m_sitesModel.reset(new SitesModel(m_settings, this)); m_engine->rootContext()->setContextProperty("SitesModel", m_sitesModel.get()); - + m_protocolsModel.reset(new ProtocolsModel(m_settings, this)); m_engine->rootContext()->setContextProperty("ProtocolsModel", m_protocolsModel.get()); @@ -327,8 +324,13 @@ void AmneziaApplication::initModels() m_clientManagementModel.reset(new ClientManagementModel(m_settings, this)); m_engine->rootContext()->setContextProperty("ClientManagementModel", m_clientManagementModel.get()); - connect(m_configurator.get(), &VpnConfigurator::newVpnConfigCreated, m_clientManagementModel.get(), - &ClientManagementModel::appendClient); + + connect(m_configurator.get(), &VpnConfigurator::newVpnConfigCreated, this, + [this](const QString &clientId, const QString &clientName, const DockerContainer container, + ServerCredentials credentials) { + m_serversModel->reloadContainerConfig(); + m_clientManagementModel->appendClient(clientId, clientName, container, credentials); + }); } void AmneziaApplication::initControllers() @@ -354,7 +356,8 @@ void AmneziaApplication::initControllers() m_importController.reset(new ImportController(m_serversModel, m_containersModel, m_settings)); m_engine->rootContext()->setContextProperty("ImportController", m_importController.get()); - m_exportController.reset(new ExportController(m_serversModel, m_containersModel, m_clientManagementModel, m_settings, m_configurator)); + m_exportController.reset(new ExportController(m_serversModel, m_containersModel, m_clientManagementModel, + m_settings, m_configurator)); m_engine->rootContext()->setContextProperty("ExportController", m_exportController.get()); m_settingsController.reset(new SettingsController(m_serversModel, m_containersModel, m_languageModel, m_settings)); @@ -362,10 +365,15 @@ void AmneziaApplication::initControllers() if (m_settingsController->isAutoConnectEnabled() && m_serversModel->getDefaultServerIndex() >= 0) { QTimer::singleShot(1000, this, [this]() { m_connectionController->openConnection(); }); } + connect(m_settingsController.get(), &SettingsController::amneziaDnsToggled , m_serversModel.get(), + &ServersModel::toggleAmneziaDns); m_sitesController.reset(new SitesController(m_settings, m_vpnConnection, m_sitesModel)); m_engine->rootContext()->setContextProperty("SitesController", m_sitesController.get()); m_systemController.reset(new SystemController(m_settings)); m_engine->rootContext()->setContextProperty("SystemController", m_systemController.get()); + + m_cloudController.reset(new ApiController(m_serversModel, m_containersModel)); + m_engine->rootContext()->setContextProperty("ApiController", m_cloudController.get()); } diff --git a/client/amnezia_application.h b/client/amnezia_application.h index 2638c66f..aff853a6 100644 --- a/client/amnezia_application.h +++ b/client/amnezia_application.h @@ -24,6 +24,7 @@ #include "ui/controllers/settingsController.h" #include "ui/controllers/sitesController.h" #include "ui/controllers/systemController.h" +#include "ui/controllers/apiController.h" #include "ui/models/containers_model.h" #include "ui/models/languageModel.h" #include "ui/models/protocols/cloakConfigModel.h" @@ -120,6 +121,7 @@ private: QScopedPointer m_settingsController; QScopedPointer m_sitesController; QScopedPointer m_systemController; + QScopedPointer m_cloudController; }; #endif // AMNEZIA_APPLICATION_H diff --git a/client/configurators/awg_configurator.cpp b/client/configurators/awg_configurator.cpp index ca6c282b..5b452755 100644 --- a/client/configurators/awg_configurator.cpp +++ b/client/configurators/awg_configurator.cpp @@ -3,7 +3,7 @@ #include #include -#include "core/servercontroller.h" +#include "core/controllers/serverController.h" AwgConfigurator::AwgConfigurator(std::shared_ptr settings, QObject *parent) : WireguardConfigurator(settings, true, parent) diff --git a/client/configurators/cloak_configurator.cpp b/client/configurators/cloak_configurator.cpp index fab378e2..9c540967 100644 --- a/client/configurators/cloak_configurator.cpp +++ b/client/configurators/cloak_configurator.cpp @@ -4,7 +4,7 @@ #include #include -#include "core/servercontroller.h" +#include "core/controllers/serverController.h" #include "containers/containers_defs.h" CloakConfigurator::CloakConfigurator(std::shared_ptr settings, QObject *parent): diff --git a/client/configurators/ikev2_configurator.cpp b/client/configurators/ikev2_configurator.cpp index 4ca0e5da..752d1750 100644 --- a/client/configurators/ikev2_configurator.cpp +++ b/client/configurators/ikev2_configurator.cpp @@ -11,7 +11,7 @@ #include "containers/containers_defs.h" #include "core/scripts_registry.h" #include "core/server_defs.h" -#include "core/servercontroller.h" +#include "core/controllers/serverController.h" #include "utilities.h" Ikev2Configurator::Ikev2Configurator(std::shared_ptr settings, QObject *parent) diff --git a/client/configurators/openvpn_configurator.cpp b/client/configurators/openvpn_configurator.cpp index 972e460c..e3362236 100644 --- a/client/configurators/openvpn_configurator.cpp +++ b/client/configurators/openvpn_configurator.cpp @@ -16,7 +16,7 @@ #include "containers/containers_defs.h" #include "core/scripts_registry.h" #include "core/server_defs.h" -#include "core/servercontroller.h" +#include "core/controllers/serverController.h" #include "settings.h" #include "utilities.h" diff --git a/client/configurators/openvpn_configurator.h b/client/configurators/openvpn_configurator.h index 6d927697..cc66d13f 100644 --- a/client/configurators/openvpn_configurator.h +++ b/client/configurators/openvpn_configurator.h @@ -32,9 +32,9 @@ public: ErrorCode signCert(DockerContainer container, const ServerCredentials &credentials, QString clientId); -private: - ConnectionData createCertRequest(); + static ConnectionData createCertRequest(); +private: ConnectionData prepareOpenVpnConfig(const ServerCredentials &credentials, DockerContainer container, ErrorCode *errorCode = nullptr); diff --git a/client/configurators/shadowsocks_configurator.cpp b/client/configurators/shadowsocks_configurator.cpp index a71064c8..99e4158c 100644 --- a/client/configurators/shadowsocks_configurator.cpp +++ b/client/configurators/shadowsocks_configurator.cpp @@ -5,7 +5,7 @@ #include #include "containers/containers_defs.h" -#include "core/servercontroller.h" +#include "core/controllers/serverController.h" ShadowSocksConfigurator::ShadowSocksConfigurator(std::shared_ptr settings, QObject *parent): ConfiguratorBase(settings, parent) diff --git a/client/configurators/wireguard_configurator.cpp b/client/configurators/wireguard_configurator.cpp index 9a6651ef..8bfd5e75 100644 --- a/client/configurators/wireguard_configurator.cpp +++ b/client/configurators/wireguard_configurator.cpp @@ -15,7 +15,7 @@ #include "containers/containers_defs.h" #include "core/scripts_registry.h" #include "core/server_defs.h" -#include "core/servercontroller.h" +#include "core/controllers/serverController.h" #include "settings.h" #include "utilities.h" diff --git a/client/containers/containers_defs.cpp b/client/containers/containers_defs.cpp index a523ef84..8bff8b72 100644 --- a/client/containers/containers_defs.cpp +++ b/client/containers/containers_defs.cpp @@ -54,7 +54,7 @@ QVector ContainerProps::protocolsForContainer(amnezia::DockerCon case DockerContainer::ShadowSocks: return { Proto::OpenVpn, Proto::ShadowSocks }; - case DockerContainer::Cloak: return { Proto::OpenVpn, Proto::ShadowSocks, Proto::Cloak }; + case DockerContainer::Cloak: return { Proto::OpenVpn, /*Proto::ShadowSocks,*/ Proto::Cloak }; case DockerContainer::Ipsec: return { Proto::Ikev2 /*, Protocol::L2tp */ }; diff --git a/client/core/servercontroller.cpp b/client/core/controllers/serverController.cpp similarity index 99% rename from client/core/servercontroller.cpp rename to client/core/controllers/serverController.cpp index e7c047db..36560e10 100644 --- a/client/core/servercontroller.cpp +++ b/client/core/controllers/serverController.cpp @@ -1,4 +1,4 @@ -#include "servercontroller.h" +#include "serverController.h" #include #include @@ -24,8 +24,8 @@ #include "containers/containers_defs.h" #include "logger.h" -#include "scripts_registry.h" -#include "server_defs.h" +#include "core/scripts_registry.h" +#include "core/server_defs.h" #include "settings.h" #include "utilities.h" diff --git a/client/core/servercontroller.h b/client/core/controllers/serverController.h similarity index 98% rename from client/core/servercontroller.h rename to client/core/controllers/serverController.h index 6883274e..175d96da 100644 --- a/client/core/servercontroller.h +++ b/client/core/controllers/serverController.h @@ -5,8 +5,8 @@ #include #include "containers/containers_defs.h" -#include "defs.h" -#include "sshclient.h" +#include "core/defs.h" +#include "core/sshclient.h" class Settings; class VpnConfigurator; diff --git a/client/core/errorstrings.cpp b/client/core/errorstrings.cpp index 2a34576d..ab23a089 100644 --- a/client/core/errorstrings.cpp +++ b/client/core/errorstrings.cpp @@ -57,7 +57,7 @@ QString errorString(ErrorCode code){ case (OpenVpnTapAdapterError): return QObject::tr("Can't setup OpenVPN TAP network adapter"); case (AddressPoolError): return QObject::tr("VPN pool error: no available addresses"); - case (ImportInvalidConfigError): return QObject::tr("The config does not contain any containers and credentiaks for connecting to the server"); + case (ImportInvalidConfigError): return QObject::tr("The config does not contain any containers and credentials for connecting to the server"); case(InternalError): default: diff --git a/client/protocols/protocols_defs.h b/client/protocols/protocols_defs.h index 4d81e952..8d7d9bfb 100644 --- a/client/protocols/protocols_defs.h +++ b/client/protocols/protocols_defs.h @@ -21,6 +21,7 @@ namespace amnezia constexpr char dns2[] = "dns2"; constexpr char description[] = "description"; + constexpr char name[] = "name"; constexpr char cert[] = "cert"; constexpr char config[] = "config"; @@ -79,6 +80,8 @@ namespace amnezia constexpr char sftp[] = "sftp"; constexpr char awg[] = "awg"; + constexpr char configVersion[] = "config_version"; + constexpr char splitTunnelSites[] = "splitTunnelSites"; constexpr char splitTunnelType[] = "splitTunnelType"; diff --git a/client/server_scripts/install_docker.sh b/client/server_scripts/install_docker.sh index e6708ddf..6f19e090 100644 --- a/client/server_scripts/install_docker.sh +++ b/client/server_scripts/install_docker.sh @@ -7,13 +7,13 @@ if [ "$dist" = "debian" ]; then export DEBIAN_FRONTEND=noninteractive; fi;\ if ! command -v sudo > /dev/null 2>&1; then $pm $check_pkgs; $pm $silent_inst sudo; fi;\ if ! command -v fuser > /dev/null 2>&1; then sudo $pm $check_pkgs; sudo $pm $silent_inst psmisc; fi;\ if ! command -v lsof > /dev/null 2>&1; then sudo $pm $check_pkgs; sudo $pm $silent_inst lsof; fi;\ -if ! command -v docker > /dev/null 2>&1; then sudo $pm $check_pkgs; sudo $pm $silent_inst $docker_pkg;\ - if [ "$dist" = "fedora" ] || [ "$dist" = "centos" ] || [ "$dist" = "debian" ]; then sudo systemctl enable docker && sudo systemctl start docker; fi;\ +if ! command -v docker > /dev/null 2>&1; then \ + sudo $pm $check_pkgs; sudo $pm $silent_inst $docker_pkg;\ + sleep 5; sudo systemctl enable --now docker; sleep 5;\ fi;\ -if [ "$dist" = "debian" ]; then \ - docker_service=$(systemctl list-units --full --all | grep docker.service | grep -v inactive | grep -v dead | grep -v failed);\ - if [ -z "$docker_service" ]; then sudo $pm $check_pkgs; sudo $pm $silent_inst curl $docker_pkg; fi;\ - sleep 3 && sudo systemctl start docker && sleep 3;\ +if [ "$(systemctl is-active docker)" != "active" ]; then \ + sudo $pm $check_pkgs; sudo $pm $silent_inst $docker_pkg;\ + sleep 5; sudo systemctl start docker; sleep 5;\ fi;\ -if ! command -v sudo > /dev/null 2>&1; then echo "Failed to install Docker"; exit 1; fi;\ +if ! command -v sudo > /dev/null 2>&1; then echo "Failed to install sudo, command not found"; exit 1; fi;\ docker --version diff --git a/client/translations/amneziavpn_ru.ts b/client/translations/amneziavpn_ru.ts index 861beec2..283bf0c2 100644 --- a/client/translations/amneziavpn_ru.ts +++ b/client/translations/amneziavpn_ru.ts @@ -27,9 +27,26 @@ VPN Подключен + + CloudController + + + Error when retrieving configuration from cloud server + + + + + CloudController + + + Error when retrieving configuration from cloud server + + + ConnectionController + VPN Protocols is not installed. Please install VPN container at first @@ -37,35 +54,35 @@ Пожалуйста, установите протокол - + Connection... Подключение... - + Connected Подключено - + Settings updated successfully, Reconnnection... Настройки успешно обновлены. Подключение... - + Reconnection... Переподключение... - - - + + + Connect Подключиться - + Disconnection... Отключение... @@ -139,7 +156,7 @@ ImportController - + Scanned %1 of %2. Отсканировано %1 из%2. @@ -147,58 +164,52 @@ InstallController - - + + %1 installed successfully. %1 успешно установлен. - - + + %1 is already installed on the server. %1 уже установлен на сервер. - - -Added containers that were already installed on the server - -В приложение добавлены обнаруженные на сервере протоклы и сервисы - - - + + Already installed containers were found on the server. All installed containers have been added to the application На сервере обнаружены установленные протоколы и сервисы, все они добавлены в приложение - + Settings updated successfully Настройки успешно обновлены - + Server '%1' was removed Сервер '%1' был удален - + All containers from server '%1' have been removed Все протоклы и сервисы были удалены с сервера '%1' - + %1 has been removed from the server '%2' %1 был удален с сервера '%2' - + Please login as the user Пожалуйста, войдите в систему от имени пользователя - + Server added successfully Сервер успешно добавлен @@ -266,12 +277,12 @@ Already installed containers were found on the server. All installed containers PageHome - + VPN protocol VPN протокол - + Servers Серверы @@ -1000,18 +1011,18 @@ Already installed containers were found on the server. All installed containers - Allow application screenshots - Разрешить скриншоты - - - Auto start - Авто-запуск + - - Launch the application every time the device is starts - Запускать приложение при каждом включении + + Launch the application every time + + + + + starts + @@ -1932,12 +1943,7 @@ and will not be shared or disclosed to the Amnezia or any third parties Доступ - - File with accessing settings to - Файл с настройками доступа к - - - + Connection to Подключение к @@ -1977,13 +1983,12 @@ and will not be shared or disclosed to the Amnezia or any third parties Поделиться доступом к VPN, без возможности управления сервером - - Share access to server management. The user with whom you share full access to the server will be able to add and remove any protocols and services to the server, as well as change settings. - Поделиться доступом к управлению сервером. Пользователь, с которым вы делитесь полным доступом к серверу, сможет добавлять и удалять любые протоколы и службы на сервере, а также изменять настройки. + + Protocols + - - + Protocol Протокол @@ -2442,7 +2447,7 @@ and will not be shared or disclosed to the Amnezia or any third parties The config does not contain any containers and credentiaks for connecting to the server - The config does not contain any containers and credentiaks for connecting to the server + @@ -2742,6 +2747,16 @@ This means that AmneziaWG keeps the fast performance of the original while addin &Randomize colors + + + WireGuard Configuration Highlighter + + + + + &Randomize colors + + SelectLanguageDrawer @@ -2813,8 +2828,8 @@ This means that AmneziaWG keeps the fast performance of the original while addin - Show connection settings - Показать настройки подключения + Show content + @@ -2909,7 +2924,7 @@ This means that AmneziaWG keeps the fast performance of the original while addin VpnConnection - + Mbps Mbps diff --git a/client/translations/amneziavpn_zh_CN.ts b/client/translations/amneziavpn_zh_CN.ts index 8833d5c6..c8422faa 100644 --- a/client/translations/amneziavpn_zh_CN.ts +++ b/client/translations/amneziavpn_zh_CN.ts @@ -27,6 +27,14 @@ VPN已连接 + + CloudController + + + Error when retrieving configuration from cloud server + + + ConnectionController @@ -2568,6 +2576,10 @@ and will not be shared or disclosed to the Amnezia or any third parties + The config does not contain any containers and credentials for connecting to the server + + + The config does not contain any containers and credentiaks for connecting to the server 该配置不包含任何用于连接到服务器的容器和凭据。 @@ -2881,6 +2893,16 @@ While it offers a blend of security, stability, and speed, it's essential t &Randomize colors + + + WireGuard Configuration Highlighter + + + + + &Randomize colors + + SelectLanguageDrawer diff --git a/client/ui/controllers/apiController.cpp b/client/ui/controllers/apiController.cpp new file mode 100644 index 00000000..14a05410 --- /dev/null +++ b/client/ui/controllers/apiController.cpp @@ -0,0 +1,129 @@ +#include "apiController.h" + +#include +#include +#include + +#include "configurators/openvpn_configurator.h" + +namespace +{ + namespace configKey + { + constexpr char cloak[] = "cloak"; + + constexpr char apiEdnpoint[] = "api_endpoint"; + constexpr char accessToken[] = "api_key"; + constexpr char certificate[] = "certificate"; + constexpr char publicKey[] = "public_key"; + constexpr char protocol[] = "protocol"; + } +} + +ApiController::ApiController(const QSharedPointer &serversModel, + const QSharedPointer &containersModel, QObject *parent) + : QObject(parent), m_serversModel(serversModel), m_containersModel(containersModel) +{ +} + +QString ApiController::genPublicKey(const QString &protocol) +{ + if (protocol == configKey::cloak) { + return "."; + } + return QString(); +} + +QString ApiController::genCertificateRequest(const QString &protocol) +{ + if (protocol == configKey::cloak) { + m_certRequest = OpenVpnConfigurator::createCertRequest(); + return m_certRequest.request; + } + return QString(); +} + +void ApiController::processCloudConfig(const QString &protocol, QString &config) +{ + if (protocol == configKey::cloak) { + config.replace("", "\n"); + config.replace("$OPENVPN_PRIV_KEY", m_certRequest.privKey); + return; + } + return; +} + +bool ApiController::updateServerConfigFromApi() +{ + auto serverConfig = m_serversModel->getDefaultServerConfig(); + + auto containerConfig = serverConfig.value(config_key::containers).toArray(); + + if (serverConfig.value(config_key::configVersion).toInt() && containerConfig.isEmpty()) { + QNetworkAccessManager manager; + + QNetworkRequest request; + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + request.setRawHeader("Authorization", + "Api-Key " + serverConfig.value(configKey::accessToken).toString().toUtf8()); + QString endpoint = serverConfig.value(configKey::apiEdnpoint).toString(); + request.setUrl(endpoint.replace("https", "http")); // todo remove + + QString protocol = serverConfig.value(configKey::protocol).toString(); + + QJsonObject obj; + + obj[configKey::publicKey] = genPublicKey(protocol); + obj[configKey::certificate] = genCertificateRequest(protocol); + + QByteArray requestBody = QJsonDocument(obj).toJson(); + qDebug() << requestBody; + + QScopedPointer reply; + reply.reset(manager.post(request, requestBody)); + + QEventLoop wait; + QObject::connect(reply.get(), &QNetworkReply::finished, &wait, &QEventLoop::quit); + wait.exec(); + + if (reply->error() == QNetworkReply::NoError) { + QString contents = QString::fromUtf8(reply->readAll()); + auto data = QJsonDocument::fromJson(contents.toUtf8()).object().value(config_key::config).toString(); + + data.replace("vpn://", ""); + QByteArray ba = QByteArray::fromBase64(data.toUtf8(), + QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals); + + QByteArray ba_uncompressed = qUncompress(ba); + if (!ba_uncompressed.isEmpty()) { + ba = ba_uncompressed; + } + + QString configStr = ba; + processCloudConfig(protocol, configStr); + + QJsonObject cloudConfig = QJsonDocument::fromJson(configStr.toUtf8()).object(); + + serverConfig.insert("cloudConfig", cloudConfig); + serverConfig.insert(config_key::dns1, cloudConfig.value(config_key::dns1)); + serverConfig.insert(config_key::dns2, cloudConfig.value(config_key::dns2)); + serverConfig.insert(config_key::containers, cloudConfig.value(config_key::containers)); + serverConfig.insert(config_key::hostName, cloudConfig.value(config_key::hostName)); + + auto defaultContainer = cloudConfig.value(config_key::defaultContainer).toString(); + serverConfig.insert(config_key::defaultContainer, defaultContainer); + m_serversModel->editServer(serverConfig); + emit m_serversModel->defaultContainerChanged(ContainerProps::containerFromString(defaultContainer)); + } else { + QString err = reply->errorString(); + qDebug() << QString::fromUtf8(reply->readAll()); //todo remove debug output + qDebug() << reply->error(); + qDebug() << err; + qDebug() << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute); + emit errorOccurred(tr("Error when retrieving configuration from cloud server")); + return false; + } + } + + return true; +} diff --git a/client/ui/controllers/apiController.h b/client/ui/controllers/apiController.h new file mode 100644 index 00000000..1ce933c6 --- /dev/null +++ b/client/ui/controllers/apiController.h @@ -0,0 +1,36 @@ +#ifndef APICONTROLLER_H +#define APICONTROLLER_H + +#include + +#include "configurators/openvpn_configurator.h" +#include "ui/models/containers_model.h" +#include "ui/models/servers_model.h" + +class ApiController : public QObject +{ + Q_OBJECT + +public: + explicit ApiController(const QSharedPointer &serversModel, + const QSharedPointer &containersModel, QObject *parent = nullptr); + +public slots: + bool updateServerConfigFromApi(); + +signals: + void errorOccurred(const QString &errorMessage); + +private: + QString genPublicKey(const QString &protocol); + QString genCertificateRequest(const QString &protocol); + + void processCloudConfig(const QString &protocol, QString &config); + + QSharedPointer m_serversModel; + QSharedPointer m_containersModel; + + OpenVpnConfigurator::ConnectionData m_certRequest; +}; + +#endif // APICONTROLLER_H diff --git a/client/ui/controllers/connectionController.cpp b/client/ui/controllers/connectionController.cpp index b8004d09..25bebfb1 100644 --- a/client/ui/controllers/connectionController.cpp +++ b/client/ui/controllers/connectionController.cpp @@ -26,13 +26,10 @@ ConnectionController::ConnectionController(const QSharedPointer &s void ConnectionController::openConnection() { int serverIndex = m_serversModel->getDefaultServerIndex(); - ServerCredentials credentials = - qvariant_cast(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole)); + ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex); DockerContainer container = m_containersModel->getDefaultContainer(); - QModelIndex containerModelIndex = m_containersModel->index(container); - const QJsonObject &containerConfig = - qvariant_cast(m_containersModel->data(containerModelIndex, ContainersModel::Roles::ConfigRole)); + const QJsonObject &containerConfig = m_containersModel->getContainerConfig(container); if (container == DockerContainer::None) { emit connectionErrorOccurred(tr("VPN Protocols is not installed.\n Please install VPN container at first")); @@ -40,6 +37,7 @@ void ConnectionController::openConnection() } qApp->processEvents(); + emit connectToVpn(serverIndex, credentials, container, containerConfig); } diff --git a/client/ui/controllers/exportController.cpp b/client/ui/controllers/exportController.cpp index 52dadba5..9930926f 100644 --- a/client/ui/controllers/exportController.cpp +++ b/client/ui/controllers/exportController.cpp @@ -84,12 +84,10 @@ void ExportController::generateConnectionConfig(const QString &clientName) clearPreviousConfig(); int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex(); - ServerCredentials credentials = m_serversModel->getCurrentlyProcessedServerCredentials(); + ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex); DockerContainer container = static_cast(m_containersModel->getCurrentlyProcessedContainerIndex()); - QModelIndex containerModelIndex = m_containersModel->index(container); - QJsonObject containerConfig = - qvariant_cast(m_containersModel->data(containerModelIndex, ContainersModel::Roles::ConfigRole)); + QJsonObject containerConfig = m_containersModel->getContainerConfig(container); containerConfig.insert(config_key::container, ContainerProps::containerToString(container)); ErrorCode errorCode = ErrorCode::NoError; @@ -142,12 +140,10 @@ void ExportController::generateOpenVpnConfig(const QString &clientName) clearPreviousConfig(); int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex(); - ServerCredentials credentials = m_serversModel->getCurrentlyProcessedServerCredentials(); + ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex); DockerContainer container = static_cast(m_containersModel->getCurrentlyProcessedContainerIndex()); - QModelIndex containerModelIndex = m_containersModel->index(container); - QJsonObject containerConfig = - qvariant_cast(m_containersModel->data(containerModelIndex, ContainersModel::Roles::ConfigRole)); + QJsonObject containerConfig = m_containersModel->getContainerConfig(container); containerConfig.insert(config_key::container, ContainerProps::containerToString(container)); ErrorCode errorCode = ErrorCode::NoError; @@ -182,12 +178,10 @@ void ExportController::generateWireGuardConfig(const QString &clientName) clearPreviousConfig(); int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex(); - ServerCredentials credentials = m_serversModel->getCurrentlyProcessedServerCredentials(); + ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex); DockerContainer container = static_cast(m_containersModel->getCurrentlyProcessedContainerIndex()); - QModelIndex containerModelIndex = m_containersModel->index(container); - QJsonObject containerConfig = - qvariant_cast(m_containersModel->data(containerModelIndex, ContainersModel::Roles::ConfigRole)); + QJsonObject containerConfig = m_containersModel->getContainerConfig(container); containerConfig.insert(config_key::container, ContainerProps::containerToString(container)); QString clientId; @@ -223,13 +217,10 @@ void ExportController::generateShadowSocksConfig() clearPreviousConfig(); int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex(); - ServerCredentials credentials = - qvariant_cast(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole)); + ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex); DockerContainer container = static_cast(m_containersModel->getCurrentlyProcessedContainerIndex()); - QModelIndex containerModelIndex = m_containersModel->index(container); - QJsonObject containerConfig = - qvariant_cast(m_containersModel->data(containerModelIndex, ContainersModel::Roles::ConfigRole)); + QJsonObject containerConfig = m_containersModel->getContainerConfig(container); containerConfig.insert(config_key::container, ContainerProps::containerToString(container)); ErrorCode errorCode = ErrorCode::NoError; @@ -262,13 +253,10 @@ void ExportController::generateCloakConfig() clearPreviousConfig(); int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex(); - ServerCredentials credentials = - qvariant_cast(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole)); + ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex); DockerContainer container = static_cast(m_containersModel->getCurrentlyProcessedContainerIndex()); - QModelIndex containerModelIndex = m_containersModel->index(container); - QJsonObject containerConfig = - qvariant_cast(m_containersModel->data(containerModelIndex, ContainersModel::Roles::ConfigRole)); + QJsonObject containerConfig = m_containersModel->getContainerConfig(container); containerConfig.insert(config_key::container, ContainerProps::containerToString(container)); ErrorCode errorCode = ErrorCode::NoError; diff --git a/client/ui/controllers/importController.cpp b/client/ui/controllers/importController.cpp index 8ae032a9..062b10a4 100644 --- a/client/ui/controllers/importController.cpp +++ b/client/ui/controllers/importController.cpp @@ -141,7 +141,9 @@ void ImportController::importConfig() credentials.userName = m_config.value(config_key::userName).toString(); credentials.secretData = m_config.value(config_key::password).toString(); - if (credentials.isValid() || m_config.contains(config_key::containers)) { + if (credentials.isValid() + || m_config.contains(config_key::containers) + || m_config.contains(config_key::configVersion)) { // todo m_serversModel->addServer(m_config); emit importFinished(); @@ -165,7 +167,9 @@ QJsonObject ImportController::extractAmneziaConfig(QString &data) ba = ba_uncompressed; } - return QJsonDocument::fromJson(ba).object(); + QJsonObject config = QJsonDocument::fromJson(ba).object(); + + return config; } QJsonObject ImportController::extractOpenVpnConfig(const QString &data) diff --git a/client/ui/controllers/installController.cpp b/client/ui/controllers/installController.cpp index 6e898a35..d4582429 100644 --- a/client/ui/controllers/installController.cpp +++ b/client/ui/controllers/installController.cpp @@ -8,7 +8,7 @@ #include #include "core/errorstrings.h" -#include "core/servercontroller.h" +#include "core/controllers/serverController.h" #include "utilities.h" namespace @@ -201,12 +201,9 @@ void InstallController::installContainer(DockerContainer container, QJsonObject if (errorCode == ErrorCode::NoError) { for (auto iterator = installedContainers.begin(); iterator != installedContainers.end(); iterator++) { - auto modelIndex = m_containersModel->index(iterator.key()); - QJsonObject containerConfig = - qvariant_cast(m_containersModel->data(modelIndex, ContainersModel::Roles::ConfigRole)); + QJsonObject containerConfig = m_containersModel->getContainerConfig(iterator.key()); if (containerConfig.isEmpty()) { - m_containersModel->setData(m_containersModel->index(iterator.key()), iterator.value(), - ContainersModel::Roles::ConfigRole); + m_serversModel->addContainerConfig(iterator.key(), iterator.value()); if (container != iterator.key()) { // skip the newly installed container isInstalledContainerAddedToGui = true; } @@ -254,12 +251,9 @@ void InstallController::scanServerForInstalledContainers() bool isInstalledContainerAddedToGui = false; for (auto iterator = installedContainers.begin(); iterator != installedContainers.end(); iterator++) { - auto modelIndex = m_containersModel->index(iterator.key()); - QJsonObject containerConfig = - qvariant_cast(m_containersModel->data(modelIndex, ContainersModel::Roles::ConfigRole)); + QJsonObject containerConfig = m_containersModel->getContainerConfig(iterator.key()); if (containerConfig.isEmpty()) { - m_containersModel->setData(m_containersModel->index(iterator.key()), iterator.value(), - ContainersModel::Roles::ConfigRole); + m_serversModel->addContainerConfig(iterator.key(), iterator.value()); isInstalledContainerAddedToGui = true; } } @@ -278,9 +272,7 @@ void InstallController::updateContainer(QJsonObject config) qvariant_cast(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole)); const DockerContainer container = ContainerProps::containerFromString(config.value(config_key::container).toString()); - auto modelIndex = m_containersModel->index(container); - QJsonObject oldContainerConfig = - qvariant_cast(m_containersModel->data(modelIndex, ContainersModel::Roles::ConfigRole)); + QJsonObject oldContainerConfig = m_containersModel->getContainerConfig(container); ServerController serverController(m_settings); connect(&serverController, &ServerController::serverIsBusy, this, &InstallController::serverIsBusy); @@ -288,7 +280,7 @@ void InstallController::updateContainer(QJsonObject config) auto errorCode = serverController.updateContainer(serverCredentials, container, oldContainerConfig, config); if (errorCode == ErrorCode::NoError) { - m_containersModel->setData(modelIndex, config, ContainersModel::Roles::ConfigRole); + m_serversModel->updateContainerConfig(container, config); m_protocolModel->updateModel(config); if ((serverIndex == m_serversModel->getDefaultServerIndex()) @@ -318,7 +310,7 @@ void InstallController::removeAllContainers() int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex(); QString serverName = m_serversModel->data(serverIndex, ServersModel::Roles::NameRole).toString(); - ErrorCode errorCode = m_containersModel->removeAllContainers(); + ErrorCode errorCode = m_serversModel->removeAllContainers(); if (errorCode == ErrorCode::NoError) { emit removeAllContainersFinished(tr("All containers from server '%1' have been removed").arg(serverName)); return; @@ -332,12 +324,12 @@ void InstallController::removeCurrentlyProcessedContainer() QString serverName = m_serversModel->data(serverIndex, ServersModel::Roles::NameRole).toString(); int container = m_containersModel->getCurrentlyProcessedContainerIndex(); - QString containerName = m_containersModel->data(container, ContainersModel::Roles::NameRole).toString(); + QString containerName = m_containersModel->getCurrentlyProcessedContainerName(); - ErrorCode errorCode = m_containersModel->removeCurrentlyProcessedContainer(); + ErrorCode errorCode = m_serversModel->removeContainer(container); if (errorCode == ErrorCode::NoError) { - emit removeCurrentlyProcessedContainerFinished(tr("%1 has been removed from the server '%2'").arg(containerName).arg(serverName)); + emit removeCurrentlyProcessedContainerFinished(tr("%1 has been removed from the server '%2'").arg(containerName, serverName)); return; } emit installationErrorOccurred(errorString(errorCode)); diff --git a/client/ui/controllers/settingsController.cpp b/client/ui/controllers/settingsController.cpp index 78d0dd67..9fa4d76b 100644 --- a/client/ui/controllers/settingsController.cpp +++ b/client/ui/controllers/settingsController.cpp @@ -42,6 +42,7 @@ SettingsController::SettingsController(const QSharedPointer &serve void SettingsController::toggleAmneziaDns(bool enable) { m_settings->setUseAmneziaDns(enable); + emit amneziaDnsToggled(enable); } bool SettingsController::isAmneziaDnsEnabled() @@ -138,7 +139,7 @@ void SettingsController::clearSettings() void SettingsController::clearCachedProfiles() { - m_containersModel->clearCachedProfiles(); + m_serversModel->clearCachedProfiles(); emit changeSettingsFinished(tr("Cached profiles cleared")); } diff --git a/client/ui/controllers/settingsController.h b/client/ui/controllers/settingsController.h index be041f3e..710d255f 100644 --- a/client/ui/controllers/settingsController.h +++ b/client/ui/controllers/settingsController.h @@ -70,6 +70,8 @@ signals: void importBackupFromOutside(QString filePath); + void amneziaDnsToggled(bool enable); + private: QSharedPointer m_serversModel; QSharedPointer m_containersModel; diff --git a/client/ui/models/clientManagementModel.cpp b/client/ui/models/clientManagementModel.cpp index bfc33eb9..8ec31d02 100644 --- a/client/ui/models/clientManagementModel.cpp +++ b/client/ui/models/clientManagementModel.cpp @@ -3,7 +3,7 @@ #include #include -#include "core/servercontroller.h" +#include "core/controllers/serverController.h" #include "logger.h" namespace diff --git a/client/ui/models/clientManagementModel.h b/client/ui/models/clientManagementModel.h index f5312db7..6b6adf68 100644 --- a/client/ui/models/clientManagementModel.h +++ b/client/ui/models/clientManagementModel.h @@ -4,7 +4,7 @@ #include #include -#include "core/servercontroller.h" +#include "core/controllers/serverController.h" #include "settings.h" class ClientManagementModel : public QAbstractListModel diff --git a/client/ui/models/containers_model.cpp b/client/ui/models/containers_model.cpp index 3fff22d4..7e73b2e9 100644 --- a/client/ui/models/containers_model.cpp +++ b/client/ui/models/containers_model.cpp @@ -1,9 +1,9 @@ #include "containers_model.h" -#include "core/servercontroller.h" +#include -ContainersModel::ContainersModel(std::shared_ptr settings, QObject *parent) - : m_settings(settings), QAbstractListModel(parent) +ContainersModel::ContainersModel(QObject *parent) + : QAbstractListModel(parent) { } @@ -13,37 +13,6 @@ int ContainersModel::rowCount(const QModelIndex &parent) const return ContainerProps::allContainers().size(); } -bool ContainersModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - if (!index.isValid() || index.row() < 0 || index.row() >= ContainerProps::allContainers().size()) { - return false; - } - - DockerContainer container = ContainerProps::allContainers().at(index.row()); - - switch (role) { - case ConfigRole: { - m_settings->setContainerConfig(m_currentlyProcessedServerIndex, container, value.toJsonObject()); - m_containers = m_settings->containers(m_currentlyProcessedServerIndex); - if (m_defaultContainerIndex != DockerContainer::None) { - break; - } else if (ContainerProps::containerService(container) == ServiceType::Other) { - break; - } - } - case IsDefaultRole: { //todo remove - m_settings->setDefaultContainer(m_currentlyProcessedServerIndex, container); - m_defaultContainerIndex = container; - emit defaultContainerChanged(); - } - default: break; - } - - emit containersModelUpdated(); - emit dataChanged(index, index); - return true; -} - QVariant ContainersModel::data(const QModelIndex &index, int role) const { if (!index.isValid() || index.row() < 0 || index.row() >= ContainerProps::allContainers().size()) { @@ -84,37 +53,32 @@ QVariant ContainersModel::data(const int index, int role) const return data(modelIndex, role); } -void ContainersModel::setCurrentlyProcessedServerIndex(const int index) +void ContainersModel::updateModel(QJsonArray &containers) { beginResetModel(); - m_currentlyProcessedServerIndex = index; - m_containers = m_settings->containers(m_currentlyProcessedServerIndex); - m_defaultContainerIndex = m_settings->defaultContainer(m_currentlyProcessedServerIndex); + m_containers.clear(); + for (const QJsonValue &val : containers) { + m_containers.insert(ContainerProps::containerFromString(val.toObject().value(config_key::container).toString()), + val.toObject()); + } endResetModel(); - emit defaultContainerChanged(); } -void ContainersModel::setCurrentlyProcessedContainerIndex(int index) +void ContainersModel::setDefaultContainer(const int containerIndex) { - m_currentlyProcessedContainerIndex = index; + m_defaultContainerIndex = static_cast(containerIndex); + emit dataChanged(index(containerIndex, 0), index(containerIndex, 0)); } + DockerContainer ContainersModel::getDefaultContainer() { return m_defaultContainerIndex; } -QString ContainersModel::getDefaultContainerName() +void ContainersModel::setCurrentlyProcessedContainerIndex(int index) { - return ContainerProps::containerHumanNames().value(m_defaultContainerIndex); -} - -void ContainersModel::setDefaultContainer(int index) -{ - auto container = static_cast(index); - m_settings->setDefaultContainer(m_currentlyProcessedServerIndex, container); - m_defaultContainerIndex = container; - emit defaultContainerChanged(); + m_currentlyProcessedContainerIndex = index; } int ContainersModel::getCurrentlyProcessedContainerIndex() @@ -127,91 +91,9 @@ QString ContainersModel::getCurrentlyProcessedContainerName() return ContainerProps::containerHumanNames().value(static_cast(m_currentlyProcessedContainerIndex)); } -QJsonObject ContainersModel::getCurrentlyProcessedContainerConfig() +QJsonObject ContainersModel::getContainerConfig(const int containerIndex) { - return qvariant_cast(data(index(m_currentlyProcessedContainerIndex), ConfigRole)); -} - -QStringList ContainersModel::getAllInstalledServicesName(const int serverIndex) -{ - QStringList servicesName; - const auto &containers = m_settings->containers(serverIndex); - for (const DockerContainer &container : containers.keys()) { - if (ContainerProps::containerService(container) == ServiceType::Other && m_containers.contains(container)) { - if (container == DockerContainer::Dns) { - servicesName.append("DNS"); - } else if (container == DockerContainer::Sftp) { - servicesName.append("SFTP"); - } else if (container == DockerContainer::TorWebSite) { - servicesName.append("TOR"); - } - } - } - servicesName.sort(); - return servicesName; -} - -ErrorCode ContainersModel::removeAllContainers() -{ - - ServerController serverController(m_settings); - ErrorCode errorCode = - serverController.removeAllContainers(m_settings->serverCredentials(m_currentlyProcessedServerIndex)); - - if (errorCode == ErrorCode::NoError) { - beginResetModel(); - - m_settings->setContainers(m_currentlyProcessedServerIndex, {}); - m_containers = m_settings->containers(m_currentlyProcessedServerIndex); - - setData(index(DockerContainer::None, 0), true, IsDefaultRole); - endResetModel(); - } - return errorCode; -} - -ErrorCode ContainersModel::removeCurrentlyProcessedContainer() -{ - ServerController serverController(m_settings); - auto credentials = m_settings->serverCredentials(m_currentlyProcessedServerIndex); - auto dockerContainer = static_cast(m_currentlyProcessedContainerIndex); - - ErrorCode errorCode = serverController.removeContainer(credentials, dockerContainer); - - if (errorCode == ErrorCode::NoError) { - beginResetModel(); - m_settings->removeContainerConfig(m_currentlyProcessedServerIndex, dockerContainer); - m_containers = m_settings->containers(m_currentlyProcessedServerIndex); - - if (m_defaultContainerIndex == m_currentlyProcessedContainerIndex) { - if (m_containers.isEmpty()) { - setData(index(DockerContainer::None, 0), true, IsDefaultRole); - } else { - setData(index(m_containers.begin().key(), 0), true, IsDefaultRole); - } - } - endResetModel(); - } - return errorCode; -} - -void ContainersModel::clearCachedProfiles() -{ - const auto &containers = m_settings->containers(m_currentlyProcessedServerIndex); - for (DockerContainer container : containers.keys()) { - m_settings->clearLastConnectionConfig(m_currentlyProcessedServerIndex, container); - } -} - -bool ContainersModel::isAmneziaDnsContainerInstalled() -{ - return m_containers.contains(DockerContainer::Dns); -} - -bool ContainersModel::isAmneziaDnsContainerInstalled(const int serverIndex) -{ - QMap containers = m_settings->containers(serverIndex); - return containers.contains(DockerContainer::Dns); + return qvariant_cast(data(index(containerIndex), ConfigRole)); } bool ContainersModel::isAnyContainerInstalled() @@ -228,11 +110,6 @@ bool ContainersModel::isAnyContainerInstalled() return false; } -void ContainersModel::updateContainersConfig() -{ - m_containers = m_settings->containers(m_currentlyProcessedServerIndex); -} - QHash ContainersModel::roleNames() const { QHash roles; diff --git a/client/ui/models/containers_model.h b/client/ui/models/containers_model.h index 8f087d87..23a91ea5 100644 --- a/client/ui/models/containers_model.h +++ b/client/ui/models/containers_model.h @@ -7,13 +7,12 @@ #include #include "containers/containers_defs.h" -#include "settings.h" class ContainersModel : public QAbstractListModel { Q_OBJECT public: - ContainersModel(std::shared_ptr settings, QObject *parent = nullptr); + ContainersModel(QObject *parent = nullptr); enum Roles { NameRole = Qt::UserRole + 1, @@ -37,37 +36,24 @@ public: int rowCount(const QModelIndex &parent = QModelIndex()) const override; - bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; QVariant data(const int index, int role) const; - Q_PROPERTY(QString defaultContainerName READ getDefaultContainerName NOTIFY defaultContainerChanged) - public slots: + void updateModel(QJsonArray &containers); + DockerContainer getDefaultContainer(); - QString getDefaultContainerName(); - void setDefaultContainer(int index); + void setDefaultContainer(const int containerIndex); - void setCurrentlyProcessedServerIndex(const int index); - - void setCurrentlyProcessedContainerIndex(int index); + void setCurrentlyProcessedContainerIndex(int containerIndex); int getCurrentlyProcessedContainerIndex(); QString getCurrentlyProcessedContainerName(); - QJsonObject getCurrentlyProcessedContainerConfig(); - QStringList getAllInstalledServicesName(const int serverIndex); - ErrorCode removeAllContainers(); - ErrorCode removeCurrentlyProcessedContainer(); - void clearCachedProfiles(); - - bool isAmneziaDnsContainerInstalled(); - bool isAmneziaDnsContainerInstalled(const int serverIndex); + QJsonObject getContainerConfig(const int containerIndex); bool isAnyContainerInstalled(); - void updateContainersConfig(); - protected: QHash roleNames() const override; @@ -78,11 +64,8 @@ signals: private: QMap m_containers; - int m_currentlyProcessedServerIndex; int m_currentlyProcessedContainerIndex; DockerContainer m_defaultContainerIndex; - - std::shared_ptr m_settings; }; #endif // CONTAINERS_MODEL_H diff --git a/client/ui/models/servers_model.cpp b/client/ui/models/servers_model.cpp index c702ca1e..ad927fce 100644 --- a/client/ui/models/servers_model.cpp +++ b/client/ui/models/servers_model.cpp @@ -1,5 +1,7 @@ #include "servers_model.h" +#include "core/controllers/serverController.h" + ServersModel::ServersModel(std::shared_ptr settings, QObject *parent) : m_settings(settings), QAbstractListModel(parent) { @@ -8,6 +10,11 @@ ServersModel::ServersModel(std::shared_ptr settings, QObject *parent) m_currentlyProcessedServerIndex = m_defaultServerIndex; connect(this, &ServersModel::defaultServerIndexChanged, this, &ServersModel::defaultServerNameChanged); + connect(this, &ServersModel::defaultContainerChanged, this, &ServersModel::defaultServerDescriptionChanged); + connect(this, &ServersModel::defaultServerIndexChanged, this, [this](const int serverIndex) { + auto defaultContainer = ContainerProps::containerFromString(m_servers.at(serverIndex).toObject().value(config_key::defaultContainer).toString()); + emit ServersModel::defaultContainerChanged(defaultContainer); + }); } int ServersModel::rowCount(const QModelIndex &parent) const @@ -50,14 +57,23 @@ QVariant ServersModel::data(const QModelIndex &index, int role) const } const QJsonObject server = m_servers.at(index.row()).toObject(); - + const auto configVersion = server.value(config_key::configVersion).toInt(); switch (role) { case NameRole: { - auto description = server.value(config_key::description).toString(); - if (description.isEmpty()) { + if (configVersion) { + return server.value(config_key::name).toString(); + } + auto name = server.value(config_key::description).toString(); + if (name.isEmpty()) { return server.value(config_key::hostName).toString(); } - return description; + return name; + } + case ServerDescriptionRole: { + if (configVersion) { + return server.value(config_key::description).toString(); + } + return server.value(config_key::hostName).toString(); } case HostNameRole: return server.value(config_key::hostName).toString(); case CredentialsRole: return QVariant::fromValue(serverCredentials(index.row())); @@ -72,6 +88,9 @@ QVariant ServersModel::data(const QModelIndex &index, int role) const QString primaryDns = server.value(config_key::dns1).toString(); return primaryDns == protocols::dns::amneziaDnsIp; } + case DefaultContainerRole: { + return ContainerProps::containerFromString(server.value(config_key::defaultContainer).toString()); + } } return QVariant(); @@ -114,6 +133,53 @@ const QString ServersModel::getDefaultServerHostName() return qvariant_cast(data(m_defaultServerIndex, HostNameRole)); } +QString ServersModel::getDefaultServerDescription(const QJsonObject &server) +{ + const auto configVersion = server.value(config_key::configVersion).toInt(); + + QString description; + + if (configVersion) { + return server.value(config_key::description).toString(); + } else if (isDefaultServerHasWriteAccess()) { + if (m_isAmneziaDnsEnabled + && isAmneziaDnsContainerInstalled(m_defaultServerIndex)) { + description += "Amnezia DNS | "; + } + } else { + if (isDefaultServerConfigContainsAmneziaDns()) { + description += "Amnezia DNS | "; + } + } + return description; +} + +const QString ServersModel::getDefaultServerDescriptionCollapsed() +{ + const QJsonObject server = m_servers.at(m_defaultServerIndex).toObject(); + const auto configVersion = server.value(config_key::configVersion).toInt(); + auto description = getDefaultServerDescription(server); + if (configVersion) { + return description; + } + + auto container = ContainerProps::containerFromString(server.value(config_key::defaultContainer).toString()); + + return description += ContainerProps::containerHumanNames().value(container) + " | " + server.value(config_key::hostName).toString(); +} + +const QString ServersModel::getDefaultServerDescriptionExpanded() +{ + const QJsonObject server = m_servers.at(m_defaultServerIndex).toObject(); + const auto configVersion = server.value(config_key::configVersion).toInt(); + auto description = getDefaultServerDescription(server); + if (configVersion) { + return description; + } + + return description += server.value(config_key::hostName).toString(); +} + const int ServersModel::getServersCount() { return m_servers.count(); @@ -132,6 +198,7 @@ bool ServersModel::hasServerWithWriteAccess() void ServersModel::setCurrentlyProcessedServerIndex(const int index) { m_currentlyProcessedServerIndex = index; + updateContainersModel(); emit currentlyProcessedServerIndexChanged(m_currentlyProcessedServerIndex); } @@ -150,6 +217,11 @@ const ServerCredentials ServersModel::getCurrentlyProcessedServerCredentials() return serverCredentials(m_currentlyProcessedServerIndex); } +const ServerCredentials ServersModel::getServerCredentials(const int index) +{ + return serverCredentials(index); +} + bool ServersModel::isDefaultServerCurrentlyProcessed() { return m_defaultServerIndex == m_currentlyProcessedServerIndex; @@ -173,6 +245,15 @@ void ServersModel::addServer(const QJsonObject &server) endResetModel(); } +void ServersModel::editServer(const QJsonObject &server) +{ + beginResetModel(); + m_settings->editServer(m_currentlyProcessedServerIndex, server); + m_servers = m_settings->serversArray(); + endResetModel(); + updateContainersModel(); +} + void ServersModel::removeServer() { beginResetModel(); @@ -198,23 +279,27 @@ bool ServersModel::isDefaultServerConfigContainsAmneziaDns() return primaryDns == protocols::dns::amneziaDnsIp; } -void ServersModel::updateContainersConfig() -{ - auto server = m_settings->server(m_currentlyProcessedServerIndex); - m_servers.replace(m_currentlyProcessedServerIndex, server); -} - QHash ServersModel::roleNames() const { QHash roles; + + roles[NameRole] = "serverName"; roles[NameRole] = "name"; + roles[ServerDescriptionRole] = "serverDescription"; + roles[HostNameRole] = "hostName"; + roles[CredentialsRole] = "credentials"; roles[CredentialsLoginRole] = "credentialsLogin"; + roles[IsDefaultRole] = "isDefault"; roles[IsCurrentlyProcessedRole] = "isCurrentlyProcessed"; + roles[HasWriteAccessRole] = "hasWriteAccess"; + roles[ContainsAmneziaDnsRole] = "containsAmneziaDns"; + + roles[DefaultContainerRole] = "defaultContainer"; return roles; } @@ -230,3 +315,206 @@ ServerCredentials ServersModel::serverCredentials(int index) const return credentials; } + +void ServersModel::updateContainersModel() +{ + auto containers = m_servers.at(m_currentlyProcessedServerIndex).toObject().value(config_key::containers).toArray(); + emit containersUpdated(containers); +} + +QJsonObject ServersModel::getDefaultServerConfig() +{ + return m_servers.at(m_defaultServerIndex).toObject(); +} + +void ServersModel::reloadContainerConfig() +{ + QJsonObject server = m_servers.at(m_currentlyProcessedServerIndex).toObject(); + auto container = ContainerProps::containerFromString(server.value(config_key::defaultContainer).toString()); + + auto containers = server.value(config_key::containers).toArray(); + + auto config = m_settings->containerConfig(m_currentlyProcessedServerIndex, container); + for (auto i = 0; i < containers.size(); i++) { + auto c = ContainerProps::containerFromString(containers.at(i).toObject().value(config_key::container).toString()); + if (c == container) { + containers.replace(i, config); + break; + } + } + + server.insert(config_key::containers, containers); + editServer(server); +} + +void ServersModel::updateContainerConfig(const int containerIndex, const QJsonObject config) +{ + auto container = static_cast(containerIndex); + QJsonObject server = m_servers.at(m_currentlyProcessedServerIndex).toObject(); + + auto containers = server.value(config_key::containers).toArray(); + for (auto i = 0; i < containers.size(); i++) { + auto c = ContainerProps::containerFromString(containers.at(i).toObject().value(config_key::container).toString()); + if (c == container) { + containers.replace(i, config); + break; + } + } + + server.insert(config_key::containers, containers); + + auto defaultContainer = server.value(config_key::defaultContainer).toString(); + if ((ContainerProps::containerFromString(defaultContainer) == DockerContainer::None || ContainerProps::containerService(container) != ServiceType::Other)) { + server.insert(config_key::defaultContainer, ContainerProps::containerToString(container)); + } + + editServer(server); +} + +void ServersModel::addContainerConfig(const int containerIndex, const QJsonObject config) +{ + auto container = static_cast(containerIndex); + QJsonObject server = m_servers.at(m_currentlyProcessedServerIndex).toObject(); + + auto containers = server.value(config_key::containers).toArray(); + containers.push_back(config); + + server.insert(config_key::containers, containers); + + bool isDefaultContainerChanged = false; + auto defaultContainer = server.value(config_key::defaultContainer).toString(); + if ((ContainerProps::containerFromString(defaultContainer) == DockerContainer::None || ContainerProps::containerService(container) != ServiceType::Other)) { + server.insert(config_key::defaultContainer, ContainerProps::containerToString(container)); + isDefaultContainerChanged = true; + } + + editServer(server); + if (isDefaultContainerChanged) { + emit defaultContainerChanged(container); + } +} + +void ServersModel::setDefaultContainer(const int containerIndex) +{ + auto container = static_cast(containerIndex); + QJsonObject s = m_servers.at(m_currentlyProcessedServerIndex).toObject(); + s.insert(config_key::defaultContainer, ContainerProps::containerToString(container)); + editServer(s); //check + emit defaultContainerChanged(container); +} + +DockerContainer ServersModel::getDefaultContainer() +{ + return qvariant_cast(data(m_currentlyProcessedServerIndex, DefaultContainerRole)); +} + +const QString ServersModel::getDefaultContainerName() +{ + auto defaultContainer = getDefaultContainer(); + return ContainerProps::containerHumanNames().value(defaultContainer); +} + +ErrorCode ServersModel::removeAllContainers() +{ + ServerController serverController(m_settings); + ErrorCode errorCode = + serverController.removeAllContainers(m_settings->serverCredentials(m_currentlyProcessedServerIndex)); + + if (errorCode == ErrorCode::NoError) { + QJsonObject s = m_servers.at(m_currentlyProcessedServerIndex).toObject(); + s.insert(config_key::containers, {}); + s.insert(config_key::defaultContainer, ContainerProps::containerToString(DockerContainer::None)); + + editServer(s); + emit defaultContainerChanged(DockerContainer::None); + } + return errorCode; +} + +ErrorCode ServersModel::removeContainer(const int containerIndex) +{ + ServerController serverController(m_settings); + auto credentials = m_settings->serverCredentials(m_currentlyProcessedServerIndex); + auto dockerContainer = static_cast(containerIndex); + + ErrorCode errorCode = serverController.removeContainer(credentials, dockerContainer); + + if (errorCode == ErrorCode::NoError) { + QJsonObject server = m_servers.at(m_currentlyProcessedServerIndex).toObject(); + + auto containers = server.value(config_key::containers).toArray(); + for (auto it = containers.begin(); it != containers.end(); it++) { + if (it->toObject().value(config_key::container).toString() == ContainerProps::containerToString(dockerContainer)) { + containers.erase(it); + break; + } + } + + server.insert(config_key::containers, containers); + + auto defaultContainer = ContainerProps::containerFromString(server.value(config_key::defaultContainer).toString()); + if (defaultContainer == containerIndex) { + if (containers.empty()) { + defaultContainer = DockerContainer::None; + } else { + defaultContainer = ContainerProps::containerFromString(containers.begin()->toObject().value(config_key::container).toString()); + } + server.insert(config_key::defaultContainer, ContainerProps::containerToString(defaultContainer)); + } + + editServer(server); + emit defaultContainerChanged(defaultContainer); + } + return errorCode; +} + +void ServersModel::clearCachedProfiles() +{ + const auto &containers = m_settings->containers(m_currentlyProcessedServerIndex); + for (DockerContainer container : containers.keys()) { + m_settings->clearLastConnectionConfig(m_currentlyProcessedServerIndex, container); + } + + m_servers.replace(m_currentlyProcessedServerIndex, m_settings->server(m_currentlyProcessedServerIndex)); + updateContainersModel(); +} + +bool ServersModel::isAmneziaDnsContainerInstalled(const int serverIndex) +{ + QJsonObject server = m_servers.at(serverIndex).toObject(); + auto containers = server.value(config_key::containers).toArray(); + for (auto it = containers.begin(); it != containers.end(); it++) { + if (it->toObject().value(config_key::container).toString() == ContainerProps::containerToString(DockerContainer::Dns)) { + return true; + } + } + return false; +} + +QStringList ServersModel::getAllInstalledServicesName(const int serverIndex) +{ + QStringList servicesName; + QJsonObject server = m_servers.at(serverIndex).toObject(); + const auto containers = server.value(config_key::containers).toArray(); + for (auto it = containers.begin(); it != containers.end(); it++) { + auto container = ContainerProps::containerFromString(it->toObject().value(config_key::container).toString()); + if (ContainerProps::containerService(container) == ServiceType::Other) { + if (container == DockerContainer::Dns) { + servicesName.append("DNS"); + } else if (container == DockerContainer::Sftp) { + servicesName.append("SFTP"); + } else if (container == DockerContainer::TorWebSite) { + servicesName.append("TOR"); + } + } + } + servicesName.sort(); + return servicesName; +} + +void ServersModel::toggleAmneziaDns(bool enabled) +{ + m_isAmneziaDnsEnabled = enabled; + emit defaultServerDescriptionChanged(); +} + diff --git a/client/ui/models/servers_model.h b/client/ui/models/servers_model.h index b2654530..901605e2 100644 --- a/client/ui/models/servers_model.h +++ b/client/ui/models/servers_model.h @@ -11,13 +11,21 @@ class ServersModel : public QAbstractListModel public: enum Roles { NameRole = Qt::UserRole + 1, + ServerDescriptionRole, + HostNameRole, + CredentialsRole, CredentialsLoginRole, + IsDefaultRole, IsCurrentlyProcessedRole, + HasWriteAccessRole, - ContainsAmneziaDnsRole + + ContainsAmneziaDnsRole, + + DefaultContainerRole }; ServersModel(std::shared_ptr settings, QObject *parent = nullptr); @@ -33,6 +41,10 @@ public: Q_PROPERTY(int defaultIndex READ getDefaultServerIndex WRITE setDefaultServerIndex NOTIFY defaultServerIndexChanged) Q_PROPERTY(QString defaultServerName READ getDefaultServerName NOTIFY defaultServerNameChanged) Q_PROPERTY(QString defaultServerHostName READ getDefaultServerHostName NOTIFY defaultServerIndexChanged) + Q_PROPERTY(QString defaultContainerName READ getDefaultContainerName NOTIFY defaultContainerChanged) + Q_PROPERTY(QString defaultServerDescriptionCollapsed READ getDefaultServerDescriptionCollapsed NOTIFY defaultServerDescriptionChanged) + Q_PROPERTY(QString defaultServerDescriptionExpanded READ getDefaultServerDescriptionExpanded NOTIFY defaultServerDescriptionChanged) + Q_PROPERTY(int currentlyProcessedIndex READ getCurrentlyProcessedServerIndex WRITE setCurrentlyProcessedServerIndex NOTIFY currentlyProcessedServerIndexChanged) @@ -41,6 +53,8 @@ public slots: const int getDefaultServerIndex(); const QString getDefaultServerName(); const QString getDefaultServerHostName(); + const QString getDefaultServerDescriptionCollapsed(); + const QString getDefaultServerDescriptionExpanded(); bool isDefaultServerCurrentlyProcessed(); bool isCurrentlyProcessedServerHasWriteAccess(); @@ -54,13 +68,33 @@ public slots: QString getCurrentlyProcessedServerHostName(); const ServerCredentials getCurrentlyProcessedServerCredentials(); + const ServerCredentials getServerCredentials(const int index); void addServer(const QJsonObject &server); + void editServer(const QJsonObject &server); void removeServer(); bool isDefaultServerConfigContainsAmneziaDns(); + bool isAmneziaDnsContainerInstalled(const int serverIndex); - void updateContainersConfig(); + QJsonObject getDefaultServerConfig(); + + void reloadContainerConfig(); + void updateContainerConfig(const int containerIndex, const QJsonObject config); + void addContainerConfig(const int containerIndex, const QJsonObject config); + + void clearCachedProfiles(); + + ErrorCode removeContainer(const int containerIndex); + ErrorCode removeAllContainers(); + + void setDefaultContainer(const int containerIndex); + DockerContainer getDefaultContainer(); + const QString getDefaultContainerName(); + + QStringList getAllInstalledServicesName(const int serverIndex); + + void toggleAmneziaDns(bool enabled); protected: QHash roleNames() const override; @@ -69,9 +103,16 @@ signals: void currentlyProcessedServerIndexChanged(const int index); void defaultServerIndexChanged(const int index); void defaultServerNameChanged(); + void defaultServerDescriptionChanged(); + + void containersUpdated(QJsonArray &containers); + void defaultContainerChanged(const int containerIndex); private: ServerCredentials serverCredentials(int index) const; + void updateContainersModel(); + + QString getDefaultServerDescription(const QJsonObject &server); QJsonArray m_servers; @@ -79,6 +120,8 @@ private: int m_defaultServerIndex; int m_currentlyProcessedServerIndex; + + bool m_isAmneziaDnsEnabled = m_settings->useAmneziaDns(); }; #endif // SERVERSMODEL_H diff --git a/client/ui/qml/Components/ConnectButton.qml b/client/ui/qml/Components/ConnectButton.qml index c2ec186d..a0a57e6a 100644 --- a/client/ui/qml/Components/ConnectButton.qml +++ b/client/ui/qml/Components/ConnectButton.qml @@ -138,6 +138,10 @@ Button { } onClicked: { + if (!ApiController.updateServerConfigFromApi()) { + return + } + if (!ContainersModel.isAnyContainerInstalled()) { PageController.setTriggeredBtConnectButton(true) diff --git a/client/ui/qml/Components/HomeContainersListView.qml b/client/ui/qml/Components/HomeContainersListView.qml index f05b90d6..78ea9330 100644 --- a/client/ui/qml/Components/HomeContainersListView.qml +++ b/client/ui/qml/Components/HomeContainersListView.qml @@ -60,9 +60,8 @@ ListView { } if (checked) { - isDefault = true + ServersModel.setDefaultContainer(proxyContainersModel.mapToSource(index)) - menuContent.currentIndex = index containersDropDown.menuVisible = false } else { if (!isSupported && isInstalled) { diff --git a/client/ui/qml/Pages2/PageHome.qml b/client/ui/qml/Pages2/PageHome.qml index 222f7764..8374dbc3 100644 --- a/client/ui/qml/Pages2/PageHome.qml +++ b/client/ui/qml/Pages2/PageHome.qml @@ -22,10 +22,6 @@ PageType { property string borderColor: "#2C2D30" - property string defaultServerName: ServersModel.defaultServerName - property string defaultServerHostName: ServersModel.defaultServerHostName - property string defaultContainerName: ContainersModel.defaultContainerName - Connections { target: PageController @@ -40,41 +36,6 @@ PageType { } } - Connections { - target: ServersModel - - function onDefaultServerIndexChanged() { - updateDescriptions() - } - } - - Connections { - target: ContainersModel - - function onDefaultContainerChanged() { - updateDescriptions() - } - } - - function updateDescriptions() { - var description = "" - if (ServersModel.isDefaultServerHasWriteAccess()) { - if (SettingsController.isAmneziaDnsEnabled() - && ContainersModel.isAmneziaDnsContainerInstalled(ServersModel.getDefaultServerIndex())) { - description += "Amnezia DNS | " - } - } else { - if (ServersModel.isDefaultServerConfigContainsAmneziaDns()) { - description += "Amnezia DNS | " - } - } - - collapsedServerMenuDescription.text = description + root.defaultContainerName + " | " + root.defaultServerHostName - expandedServersMenuDescription.text = description + root.defaultServerHostName - } - - Component.onCompleted: updateDescriptions() - MouseArea { anchors.fill: parent enabled: buttonContent.state === "expanded" @@ -267,7 +228,7 @@ PageType { maximumLineCount: 2 elide: Qt.ElideRight - text: root.defaultServerName + text: ServersModel.defaultServerName horizontalAlignment: Qt.AlignHCenter Behavior on opacity { @@ -304,6 +265,7 @@ PageType { Layout.bottomMargin: 44 Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter visible: buttonContent.collapsedVisibility + text: ServersModel.defaultServerDescriptionCollapsed } ColumnLayout { @@ -319,7 +281,7 @@ PageType { Layout.leftMargin: 16 Layout.rightMargin: 16 - text: root.defaultServerName + text: ServersModel.defaultServerName horizontalAlignment: Qt.AlignHCenter maximumLineCount: 2 elide: Qt.ElideRight @@ -331,6 +293,7 @@ PageType { Layout.fillWidth: true horizontalAlignment: Qt.AlignHCenter verticalAlignment: Qt.AlignVCenter + text: ServersModel.defaultServerDescriptionExpanded } RowLayout { @@ -349,7 +312,7 @@ PageType { rootButtonTextTopMargin: 8 rootButtonTextBottomMargin: 8 - text: root.defaultContainerName + text: ServersModel.defaultContainerName textColor: "#0E0E11" headerText: qsTr("VPN protocol") headerBackButtonImage: "qrc:/images/controls/arrow-left.svg" @@ -468,7 +431,7 @@ PageType { var description = "" if (hasWriteAccess) { if (SettingsController.isAmneziaDnsEnabled() - && ContainersModel.isAmneziaDnsContainerInstalled(index)) { + && ServersModel.isAmneziaDnsContainerInstalled(index)) { description += "Amnezia DNS | " } } else { diff --git a/client/ui/qml/Pages2/PageServiceTorWebsiteSettings.qml b/client/ui/qml/Pages2/PageServiceTorWebsiteSettings.qml index 3bfa5bb0..aca4575c 100644 --- a/client/ui/qml/Pages2/PageServiceTorWebsiteSettings.qml +++ b/client/ui/qml/Pages2/PageServiceTorWebsiteSettings.qml @@ -66,8 +66,8 @@ PageType { text: qsTr("Website address") descriptionText: { - var config = ContainersModel.getCurrentlyProcessedContainerConfig() var containerIndex = ContainersModel.getCurrentlyProcessedContainerIndex() + var config = ContainersModel.getContainerConfig(containerIndex) return config[ContainerProps.containerTypeToString(containerIndex)]["site"] } diff --git a/client/ui/qml/Pages2/PageSettingsServersList.qml b/client/ui/qml/Pages2/PageSettingsServersList.qml index 040aafc3..dca904ae 100644 --- a/client/ui/qml/Pages2/PageSettingsServersList.qml +++ b/client/ui/qml/Pages2/PageSettingsServersList.qml @@ -77,7 +77,7 @@ PageType { text: name descriptionText: { var servicesNameString = "" - var servicesName = ContainersModel.getAllInstalledServicesName(index) + var servicesName = ServersModel.getAllInstalledServicesName(index) for (var i = 0; i < servicesName.length; i++) { servicesNameString += servicesName[i] + " · " } diff --git a/client/ui/qml/Pages2/PageSetupWizardInstalling.qml b/client/ui/qml/Pages2/PageSetupWizardInstalling.qml index 391d408f..9811d87d 100644 --- a/client/ui/qml/Pages2/PageSetupWizardInstalling.qml +++ b/client/ui/qml/Pages2/PageSetupWizardInstalling.qml @@ -26,7 +26,7 @@ PageType { function onInstallContainerFinished(finishedMessage, isServiceInstall) { if (!ConnectionController.isConnected && !isServiceInstall) { - ContainersModel.setDefaultContainer(ContainersModel.getCurrentlyProcessedContainerIndex()) + ServersModel.setDefaultContainer(ContainersModel.getCurrentlyProcessedContainerIndex()) } PageController.closePage() // close installing page diff --git a/client/ui/qml/Pages2/PageShare.qml b/client/ui/qml/Pages2/PageShare.qml index 67a66931..38010b8f 100644 --- a/client/ui/qml/Pages2/PageShare.qml +++ b/client/ui/qml/Pages2/PageShare.qml @@ -31,6 +31,7 @@ PageType { ContainersModel.getCurrentlyProcessedContainerIndex(), ServersModel.getCurrentlyProcessedServerCredentials()) PageController.showBusyIndicator(false) + PageController.showNotificationMessage(qsTr("Config revoked")) } Connections { @@ -354,8 +355,6 @@ PageType { currentIndex: 0 clickedFunction: function() { - protocolSelectorListView.currentItem.y - handler() protocolSelector.menuVisible = false @@ -365,7 +364,7 @@ PageType { target: serverSelector function onSeverSelectorIndexChanged() { - protocolSelectorListView.currentIndex = proxyContainersModel.mapFromSource(ContainersModel.getDefaultContainer()) + protocolSelectorListView.currentIndex = proxyContainersModel.mapFromSource(ServersModel.getDefaultContainer()) protocolSelectorListView.triggerCurrentItem() } } diff --git a/client/vpnconnection.cpp b/client/vpnconnection.cpp index 86321e04..80163ef1 100644 --- a/client/vpnconnection.cpp +++ b/client/vpnconnection.cpp @@ -10,7 +10,7 @@ #include #include #include -#include +#include "core/controllers/serverController.h" #ifdef AMNEZIA_DESKTOP #include "core/ipcclient.h" @@ -234,8 +234,6 @@ QString VpnConnection::createVpnConfigurationForProto(int serverIndex, const Ser return ""; } - emit m_configurator->newVpnConfigCreated(clientId, "unnamed client", container, credentials); - QString configDataBeforeLocalProcessing = configData; configData = m_configurator->processConfigWithLocalSettings(serverIndex, container, proto, configData); @@ -247,6 +245,8 @@ QString VpnConnection::createVpnConfigurationForProto(int serverIndex, const Ser protoObject.insert(config_key::last_config, configDataBeforeLocalProcessing); m_settings->setProtocolConfig(serverIndex, container, proto, protoObject); } + + emit m_configurator->newVpnConfigCreated(clientId, "unnamed client", container, credentials); } return configData; @@ -261,9 +261,7 @@ QJsonObject VpnConnection::createVpnConfiguration(int serverIndex, const ServerC for (ProtocolEnumNS::Proto proto : ContainerProps::protocolsForContainer(container)) { QJsonObject vpnConfigData = QJsonDocument::fromJson(createVpnConfigurationForProto(serverIndex, credentials, container, - containerConfig, proto, errorCode) - .toUtf8()) - .object(); + containerConfig, proto, errorCode).toUtf8()).object(); if (errorCode && *errorCode) { return {};