diff --git a/client/core/controllers/coreController.cpp b/client/core/controllers/coreController.cpp index 82232c99d..b58113e51 100644 --- a/client/core/controllers/coreController.cpp +++ b/client/core/controllers/coreController.cpp @@ -141,6 +141,9 @@ void CoreController::initControllers() m_apiConfigsController.reset(new ApiConfigsController(m_serversModel, m_apiServicesModel, m_settings)); m_engine->rootContext()->setContextProperty("ApiConfigsController", m_apiConfigsController.get()); + + m_updateController.reset(new UpdateController(m_settings)); + m_engine->rootContext()->setContextProperty("UpdateController", m_updateController.get()); } void CoreController::initAndroidController() @@ -213,6 +216,7 @@ void CoreController::initSignalHandlers() initAutoConnectHandler(); initAmneziaDnsToggledHandler(); initPrepareConfigHandler(); + initUpdateFoundHandler(); } void CoreController::initNotificationHandler() @@ -339,6 +343,16 @@ void CoreController::initPrepareConfigHandler() }); } +void CoreController::initUpdateFoundHandler() +{ +#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) + connect(m_updateController.get(), &UpdateController::updateFound, this, + [this]() { QTimer::singleShot(1000, this, [this]() { m_pageController->showChangelogDrawer(); }); }); + + m_updateController->checkForUpdates(); +#endif +} + QSharedPointer CoreController::pageController() const { return m_pageController; diff --git a/client/core/controllers/coreController.h b/client/core/controllers/coreController.h index 700504af6..769c5e770 100644 --- a/client/core/controllers/coreController.h +++ b/client/core/controllers/coreController.h @@ -17,6 +17,7 @@ #include "ui/controllers/settingsController.h" #include "ui/controllers/sitesController.h" #include "ui/controllers/systemController.h" +#include "ui/controllers/updateController.h" #include "ui/models/containers_model.h" #include "ui/models/languageModel.h" @@ -80,6 +81,7 @@ class CoreController : public QObject void initAutoConnectHandler(); void initAmneziaDnsToggledHandler(); void initPrepareConfigHandler(); + void initUpdateFoundHandler(); QQmlApplicationEngine *m_engine {}; // TODO use parent child system here? std::shared_ptr m_settings; @@ -102,6 +104,7 @@ class CoreController : public QObject QScopedPointer m_sitesController; QScopedPointer m_systemController; QScopedPointer m_appSplitTunnelingController; + QScopedPointer m_updateController; QScopedPointer m_apiSettingsController; QScopedPointer m_apiConfigsController; diff --git a/client/ui/controllers/updateController.cpp b/client/ui/controllers/updateController.cpp index 770ca75cc..b7c5cdd57 100644 --- a/client/ui/controllers/updateController.cpp +++ b/client/ui/controllers/updateController.cpp @@ -18,15 +18,13 @@ namespace #ifdef Q_OS_MACOS const QString installerPath = QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/AmneziaVPN.dmg"; #elif defined Q_OS_WINDOWS - const QString installerPath = - QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/AmneziaVPN_installer.exe"; + const QString installerPath = QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/AmneziaVPN_installer.exe"; #elif defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID) const QString installerPath = QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/AmneziaVPN.tar.zip"; #endif } -UpdateController::UpdateController(const std::shared_ptr &settings, QObject *parent) - : QObject(parent), m_settings(settings) +UpdateController::UpdateController(const std::shared_ptr &settings, QObject *parent) : QObject(parent), m_settings(settings) { } @@ -37,7 +35,34 @@ QString UpdateController::getHeaderText() QString UpdateController::getChangelogText() { - return m_changelogText; + QStringList lines = m_changelogText.split("\n"); + QStringList filteredChangeLogText; + bool add = false; + QString osSection; + +#ifdef Q_OS_WINDOWS + osSection = "### Windows"; +#elif defined(Q_OS_MACOS) + osSection = "### macOS"; +#elif defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID) + osSection = "### Linux"; +#endif + + for (const QString &line : lines) { + if (line.startsWith("### General")) { + add = true; + } else if (line.startsWith("### ") && line != osSection) { + add = false; + } else if (line == osSection) { + add = true; + } + + if (add) { + filteredChangeLogText.append(line); + } + } + + return filteredChangeLogText.join("\n"); } void UpdateController::checkForUpdates() @@ -47,7 +72,7 @@ void UpdateController::checkForUpdates() QString endpoint = "https://api.github.com/repos/amnezia-vpn/amnezia-client/releases/latest"; request.setUrl(endpoint); - QNetworkReply *reply = amnApp->manager()->get(request); + QNetworkReply *reply = amnApp->networkManager()->get(request); QObject::connect(reply, &QNetworkReply::finished, [this, reply]() { if (reply->error() == QNetworkReply::NoError) { @@ -127,21 +152,19 @@ void UpdateController::runInstaller() request.setTransferTimeout(7000); request.setUrl(m_downloadUrl); - QNetworkReply *reply = amnApp->manager()->get(request); + QNetworkReply *reply = amnApp->networkManager()->get(request); QObject::connect(reply, &QNetworkReply::finished, [this, reply]() { if (reply->error() == QNetworkReply::NoError) { QFile file(installerPath); if (!file.open(QIODevice::WriteOnly)) { - logger.error() << "Failed to open installer file for writing:" << installerPath - << "Error:" << file.errorString(); + logger.error() << "Failed to open installer file for writing:" << installerPath << "Error:" << file.errorString(); reply->deleteLater(); return; } if (file.write(reply->readAll()) == -1) { - logger.error() << "Failed to write installer data to file:" << installerPath - << "Error:" << file.errorString(); + logger.error() << "Failed to write installer data to file:" << installerPath << "Error:" << file.errorString(); file.close(); reply->deleteLater(); return; @@ -149,13 +172,13 @@ void UpdateController::runInstaller() file.close(); -#if defined(Q_OS_WINDOWS) + #if defined(Q_OS_WINDOWS) runWindowsInstaller(installerPath); -#elif defined(Q_OS_MACOS) + #elif defined(Q_OS_MACOS) runMacInstaller(installerPath); -#elif defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID) + #elif defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID) runLinuxInstaller(installerPath); -#endif + #endif } else { if (reply->error() == QNetworkReply::NetworkError::OperationCanceledError || reply->error() == QNetworkReply::NetworkError::TimeoutError) { @@ -228,8 +251,8 @@ int UpdateController::runMacInstaller(const QString &installerPath) // Start detached process qint64 pid; - bool success = QProcess::startDetached( - "/bin/bash", QStringList() << scriptPath << extractDir.path() << installerPath, extractDir.path(), &pid); + bool success = + QProcess::startDetached("/bin/bash", QStringList() << scriptPath << extractDir.path() << installerPath, extractDir.path(), &pid); if (success) { logger.info() << "Installation process started with PID:" << pid; @@ -273,8 +296,8 @@ int UpdateController::runLinuxInstaller(const QString &installerPath) // Start detached process qint64 pid; - bool success = QProcess::startDetached( - "/bin/bash", QStringList() << scriptPath << extractDir.path() << installerPath, extractDir.path(), &pid); + bool success = + QProcess::startDetached("/bin/bash", QStringList() << scriptPath << extractDir.path() << installerPath, extractDir.path(), &pid); if (success) { logger.info() << "Installation process started with PID:" << pid; diff --git a/ipc/ipcserver.cpp b/ipc/ipcserver.cpp index 0d6be4719..17f344995 100644 --- a/ipc/ipcserver.cpp +++ b/ipc/ipcserver.cpp @@ -8,8 +8,8 @@ #include "logger.h" #include "router.h" -#include "../client/protocols/protocols_defs.h" #include "../core/networkUtilities.h" +#include "../client/protocols/protocols_defs.h" #ifdef Q_OS_WIN #include "../client/platforms/windows/daemon/windowsdaemon.h" #include "../client/platforms/windows/daemon/windowsfirewall.h" @@ -55,23 +55,10 @@ int IpcServer::createPrivilegedProcess() } }); - QObject::connect(pd.serverNode.data(), &QRemoteObjectHost::error, this, [pd](QRemoteObjectNode::ErrorCode errorCode) { - qDebug() << "QRemoteObjectHost::error" << errorCode; - }); + QObject::connect(pd.serverNode.data(), &QRemoteObjectHost::error, this, + [pd](QRemoteObjectNode::ErrorCode errorCode) { qDebug() << "QRemoteObjectHost::error" << errorCode; }); - QObject::connect(pd.serverNode.data(), &QRemoteObjectHost::destroyed, this, - [pd]() { qDebug() << "QRemoteObjectHost::destroyed"; }); - - // connect(pd.ipcProcess.data(), &IpcServerProcess::finished, this, [this, pid=m_localpid](int exitCode, - // QProcess::ExitStatus exitStatus){ - // qDebug() << "IpcServerProcess finished" << exitCode << exitStatus; - //// if (m_processes.contains(pid)) { - //// m_processes[pid].ipcProcess.reset(); - //// m_processes[pid].serverNode.reset(); - //// m_processes[pid].localServer.reset(); - //// m_processes.remove(pid); - //// } - // }); + QObject::connect(pd.serverNode.data(), &QRemoteObjectHost::destroyed, this, [pd]() { qDebug() << "QRemoteObjectHost::destroyed"; }); m_processes.insert(m_localpid, pd); diff --git a/ipc/ipcserver.h b/ipc/ipcserver.h index f66dae90a..9810046b9 100644 --- a/ipc/ipcserver.h +++ b/ipc/ipcserver.h @@ -1,11 +1,11 @@ #ifndef IPCSERVER_H #define IPCSERVER_H -#include "../client/daemon/interfaceconfig.h" -#include #include #include #include +#include +#include "../client/daemon/interfaceconfig.h" #include "ipc.h" #include "ipcserverprocess.h" @@ -37,15 +37,13 @@ class IpcServer : public IpcInterfaceSource virtual bool enablePeerTraffic(const QJsonObject &configStr) override; virtual bool enableKillSwitch(const QJsonObject &excludeAddr, int vpnAdapterIndex) override; virtual bool disableKillSwitch() override; - virtual bool updateResolvers(const QString &ifname, const QList &resolvers) override; + virtual bool updateResolvers(const QString& ifname, const QList& resolvers) override; private: int m_localpid = 0; - struct ProcessDescriptor - { - ProcessDescriptor(QObject *parent = nullptr) - { + struct ProcessDescriptor { + ProcessDescriptor (QObject *parent = nullptr) { serverNode = QSharedPointer(new QRemoteObjectHost(parent)); ipcProcess = QSharedPointer(new IpcServerProcess(parent)); tun2socksProcess = QSharedPointer(new IpcProcessTun2Socks(parent));