Merge branch 'dev' into qt_migration

This commit is contained in:
pokamest 2022-10-15 19:46:26 +03:00
commit 442e7eb015
127 changed files with 5657 additions and 1619 deletions

View file

@ -1,6 +1,7 @@
#include "containers_model.h"
ContainersModel::ContainersModel(QObject *parent) :
ContainersModel::ContainersModel(std::shared_ptr<Settings> settings, QObject *parent) :
m_settings(settings),
QAbstractListModel(parent)
{
@ -37,13 +38,13 @@ QVariant ContainersModel::data(const QModelIndex &index, int role) const
return ContainerProps::containerDescriptions().value(c);
}
if (role == DefaultRole) {
return c == m_settings.defaultContainer(m_selectedServerIndex);
return c == m_settings->defaultContainer(m_selectedServerIndex);
}
if (role == ServiceTypeRole) {
return ContainerProps::containerService(c);
}
if (role == IsInstalledRole) {
return m_settings.containers(m_selectedServerIndex).contains(c);
return m_settings->containers(m_selectedServerIndex).contains(c);
}
return QVariant();
}

View file

@ -13,7 +13,7 @@ class ContainersModel : public QAbstractListModel
{
Q_OBJECT
public:
ContainersModel(QObject *parent = nullptr);
ContainersModel(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
public:
enum SiteRoles {
NameRole = Qt::UserRole + 1,
@ -33,7 +33,7 @@ protected:
private:
int m_selectedServerIndex;
Settings m_settings;
std::shared_ptr<Settings> m_settings;
};
#endif // CONTAINERS_MODEL_H

View file

@ -1,6 +1,7 @@
#include "protocols_model.h"
ProtocolsModel::ProtocolsModel(QObject *parent) :
ProtocolsModel::ProtocolsModel(std::shared_ptr<Settings> settings, QObject *parent) :
m_settings(settings),
QAbstractListModel(parent)
{

View file

@ -13,7 +13,7 @@ class ProtocolsModel : public QAbstractListModel
{
Q_OBJECT
public:
ProtocolsModel(QObject *parent = nullptr);
ProtocolsModel(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
public:
enum SiteRoles {
NameRole = Qt::UserRole + 1,
@ -34,7 +34,7 @@ protected:
private:
int m_selectedServerIndex;
DockerContainer m_selectedDockerContainer;
Settings m_settings;
std::shared_ptr<Settings> m_settings;
};
#endif // PROTOCOLS_MODEL_H

View file

@ -1,7 +1,8 @@
#include "sites_model.h"
SitesModel::SitesModel(Settings::RouteMode mode, QObject *parent)
SitesModel::SitesModel(std::shared_ptr<Settings> settings, Settings::RouteMode mode, QObject *parent)
: QAbstractListModel(parent),
m_settings(settings),
m_mode(mode)
{
}
@ -68,7 +69,7 @@ void SitesModel::genCache() const
qDebug() << "SitesModel::genCache";
m_ipsCache.clear();
const QVariantMap &sites = m_settings.vpnSites(m_mode);
const QVariantMap &sites = m_settings->vpnSites(m_mode);
auto i = sites.constBegin();
while (i != sites.constEnd()) {
m_ipsCache.append(qMakePair(i.key(), i.value().toString()));

View file

@ -15,7 +15,7 @@ public:
IpRole
};
explicit SitesModel(Settings::RouteMode mode, QObject *parent = nullptr);
explicit SitesModel(std::shared_ptr<Settings> settings, Settings::RouteMode mode, QObject *parent = nullptr);
void resetCache();
// Basic functionality:
@ -32,7 +32,7 @@ private:
private:
Settings::RouteMode m_mode;
Settings m_settings;
std::shared_ptr<Settings> m_settings;
mutable QVector<QPair<QString, QString>> m_ipsCache;
mutable bool m_cacheReady = false;

View file

@ -24,7 +24,7 @@ enum class Page {Start = 0, NewServer, NewServerProtocols, Vpn,
Wizard, WizardLow, WizardMedium, WizardHigh, WizardVpnMode, ServerConfiguringProgress,
GeneralSettings, AppSettings, NetworkSettings, ServerSettings,
ServerContainers, ServersList, ShareConnection, Sites,
ProtocolSettings, ProtocolShare, QrDecoder, QrDecoderIos, About};
ProtocolSettings, ProtocolShare, QrDecoder, QrDecoderIos, About, ViewConfig};
Q_ENUM_NS(Page)
static void declareQmlPageEnum() {

View file

@ -7,6 +7,7 @@
#include <QDesktopServices>
#include <QFileDialog>
#include <QMessageBox>
#include <QStandardPaths>
using namespace amnezia;
@ -25,9 +26,9 @@ AppSettingsLogic::AppSettingsLogic(UiLogic *logic, QObject *parent):
void AppSettingsLogic::onUpdatePage()
{
set_checkBoxAutostartChecked(Autostart::isAutostart());
set_checkBoxAutoConnectChecked(m_settings.isAutoConnect());
set_checkBoxStartMinimizedChecked(m_settings.isStartMinimized());
set_checkBoxSaveLogsChecked(m_settings.isSaveLogs());
set_checkBoxAutoConnectChecked(m_settings->isAutoConnect());
set_checkBoxStartMinimizedChecked(m_settings->isStartMinimized());
set_checkBoxSaveLogsChecked(m_settings->isSaveLogs());
QString ver = QString("%1: %2 (%3)")
.arg(tr("Software version"))
@ -46,17 +47,17 @@ void AppSettingsLogic::onCheckBoxAutostartToggled(bool checked)
void AppSettingsLogic::onCheckBoxAutoconnectToggled(bool checked)
{
m_settings.setAutoConnect(checked);
m_settings->setAutoConnect(checked);
}
void AppSettingsLogic::onCheckBoxStartMinimizedToggled(bool checked)
{
m_settings.setStartMinimized(checked);
m_settings->setStartMinimized(checked);
}
void AppSettingsLogic::onCheckBoxSaveLogsCheckedToggled(bool checked)
{
m_settings.setSaveLogs(checked);
m_settings->setSaveLogs(checked);
}
void AppSettingsLogic::onPushButtonOpenLogsClicked()
@ -74,3 +75,32 @@ void AppSettingsLogic::onPushButtonClearLogsClicked()
Debug::clearLogs();
Debug::clearServiceLogs();
}
void AppSettingsLogic::onPushButtonBackupAppConfigClicked()
{
uiLogic()->saveTextFile("Backup application config", "AmneziaVPN.backup", ".backup", m_settings->backupAppConfig());
}
void AppSettingsLogic::onPushButtonRestoreAppConfigClicked()
{
QString fileName = QFileDialog::getOpenFileName(nullptr, tr("Open backup"),
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation), "*.backup");
if (fileName.isEmpty()) return;
QFile file(fileName);
file.open(QIODevice::ReadOnly);
QByteArray data = file.readAll();
bool ok = m_settings->restoreAppConfig(data);
if (ok) {
emit uiLogic()->goToPage(Page::Vpn);
emit uiLogic()->setStartPage(Page::Vpn);
}
else {
QMessageBox::warning(nullptr, APPLICATION_NAME,
tr("Can't import config, file is corrupted."));
}
}

View file

@ -25,6 +25,10 @@ public:
Q_INVOKABLE void onPushButtonExportLogsClicked();
Q_INVOKABLE void onPushButtonClearLogsClicked();
Q_INVOKABLE void onPushButtonBackupAppConfigClicked();
Q_INVOKABLE void onPushButtonRestoreAppConfigClicked();
public:
explicit AppSettingsLogic(UiLogic *uiLogic, QObject *parent = nullptr);
~AppSettingsLogic() = default;

View file

@ -12,28 +12,28 @@ GeneralSettingsLogic::GeneralSettingsLogic(UiLogic *logic, QObject *parent):
void GeneralSettingsLogic::onUpdatePage()
{
uiLogic()->selectedServerIndex = m_settings.defaultServerIndex();
uiLogic()->selectedDockerContainer = m_settings.defaultContainer(m_settings.defaultServerIndex());
uiLogic()->selectedServerIndex = m_settings->defaultServerIndex();
uiLogic()->selectedDockerContainer = m_settings->defaultContainer(m_settings->defaultServerIndex());
set_pushButtonGeneralSettingsShareConnectionEnable(m_settings.haveAuthData(m_settings.defaultServerIndex()));
set_pushButtonGeneralSettingsShareConnectionEnable(m_settings->haveAuthData(m_settings->defaultServerIndex()));
}
void GeneralSettingsLogic::onPushButtonGeneralSettingsServerSettingsClicked()
{
uiLogic()->selectedServerIndex = m_settings.defaultServerIndex();
uiLogic()->selectedDockerContainer = m_settings.defaultContainer(m_settings.defaultServerIndex());
uiLogic()->selectedServerIndex = m_settings->defaultServerIndex();
uiLogic()->selectedDockerContainer = m_settings->defaultContainer(m_settings->defaultServerIndex());
emit uiLogic()->goToPage(Page::ServerSettings);
}
void GeneralSettingsLogic::onPushButtonGeneralSettingsShareConnectionClicked()
{
uiLogic()->selectedServerIndex = m_settings.defaultServerIndex();
uiLogic()->selectedDockerContainer = m_settings.defaultContainer(uiLogic()->selectedServerIndex);
uiLogic()->selectedServerIndex = m_settings->defaultServerIndex();
uiLogic()->selectedDockerContainer = m_settings->defaultContainer(uiLogic()->selectedServerIndex);
qobject_cast<ProtocolsModel *>(uiLogic()->protocolsModel())->setSelectedServerIndex(uiLogic()->selectedServerIndex);
qobject_cast<ProtocolsModel *>(uiLogic()->protocolsModel())->setSelectedDockerContainer(uiLogic()->selectedDockerContainer);
uiLogic()->shareConnectionLogic()->updateSharingPage(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
uiLogic()->pageLogic<ShareConnectionLogic>()->updateSharingPage(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
emit uiLogic()->goToPage(Page::ShareConnection);
}

View file

@ -2,6 +2,7 @@
#include "defines.h"
#include "utilities.h"
#include "settings.h"
NetworkSettingsLogic::NetworkSettingsLogic(UiLogic *logic, QObject *parent):
PageLogicBase(logic, parent),
@ -13,39 +14,39 @@ NetworkSettingsLogic::NetworkSettingsLogic(UiLogic *logic, QObject *parent):
void NetworkSettingsLogic::onUpdatePage()
{
set_checkBoxUseAmneziaDnsChecked(m_settings.useAmneziaDns());
set_checkBoxUseAmneziaDnsChecked(m_settings->useAmneziaDns());
set_lineEditDns1Text(m_settings.primaryDns());
set_lineEditDns2Text(m_settings.secondaryDns());
set_lineEditDns1Text(m_settings->primaryDns());
set_lineEditDns2Text(m_settings->secondaryDns());
}
void NetworkSettingsLogic::onLineEditDns1EditFinished(const QString &text)
{
if (ipAddressRegex().match(text).hasMatch()) {
m_settings.setPrimaryDns(text);
m_settings->setPrimaryDns(text);
}
}
void NetworkSettingsLogic::onLineEditDns2EditFinished(const QString &text)
{
if (ipAddressRegex().match(text).hasMatch()) {
m_settings.setSecondaryDns(text);
m_settings->setSecondaryDns(text);
}
}
void NetworkSettingsLogic::onPushButtonResetDns1Clicked()
{
m_settings.setPrimaryDns(m_settings.cloudFlareNs1);
m_settings->setPrimaryDns(m_settings->cloudFlareNs1);
onUpdatePage();
}
void NetworkSettingsLogic::onPushButtonResetDns2Clicked()
{
m_settings.setSecondaryDns(m_settings.cloudFlareNs2);
m_settings->setSecondaryDns(m_settings->cloudFlareNs2);
onUpdatePage();
}
void NetworkSettingsLogic::onCheckBoxUseAmneziaDnsToggled(bool checked)
{
m_settings.setUseAmneziaDns(checked);
m_settings->setUseAmneziaDns(checked);
}

View file

@ -3,6 +3,8 @@
#include "PageLogicBase.h"
#include <QRegularExpression>
class UiLogic;
class NetworkSettingsLogic : public PageLogicBase

View file

@ -2,6 +2,7 @@
#define NEW_SERVER_PROTOCOLS_LOGIC_H
#include "PageLogicBase.h"
#include "containers/containers_defs.h"
class UiLogic;

View file

@ -1,11 +1,17 @@
#include "PageLogicBase.h"
#include "ui/uilogic.h"
#include "settings.h"
#include "configurators/vpn_configurator.h"
PageLogicBase::PageLogicBase(UiLogic *logic, QObject *parent):
QObject(parent),
m_pageEnabled{true},
m_uiLogic(logic)
{
m_settings = logic->m_settings;
m_configurator = logic->m_configurator;
m_serverController = logic->m_serverController;
}

View file

@ -1,14 +1,15 @@
#ifndef PAGE_LOGIC_BASE_H
#define PAGE_LOGIC_BASE_H
#include "settings.h"
#include "../pages.h"
#include "../property_helper.h"
using namespace amnezia;
using namespace PageEnumNS;
class UiLogic;
class Settings;
class VpnConfigurator;
class ServerController;
class PageLogicBase : public QObject
{
@ -22,10 +23,12 @@ public:
Q_INVOKABLE virtual void onUpdatePage() {}
protected:
UiLogic *m_uiLogic;
UiLogic *uiLogic() const { return m_uiLogic; }
Settings m_settings;
UiLogic *m_uiLogic;
std::shared_ptr<Settings> m_settings;
std::shared_ptr<VpnConfigurator> m_configurator;
std::shared_ptr<ServerController> m_serverController;
signals:
void updatePage();

View file

@ -54,7 +54,7 @@ void QrDecoderLogic::onDetectedQrCode(const QString &code)
data.append(m_chunks.value(i));
}
bool ok = uiLogic()->startPageLogic()->importConnectionFromQr(data);
bool ok = uiLogic()->pageLogic<StartPageLogic>()->importConnectionFromQr(data);
if (ok) {
set_detectingEnabled(false);
emit stopDecode();
@ -67,7 +67,7 @@ void QrDecoderLogic::onDetectedQrCode(const QString &code)
}
}
else {
bool ok = uiLogic()->startPageLogic()->importConnectionFromQr(ba);
bool ok = uiLogic()->pageLogic<StartPageLogic>()->importConnectionFromQr(ba);
if (ok) {
set_detectingEnabled(false);
emit stopDecode();

View file

@ -3,6 +3,9 @@
#include <functional>
#include "PageLogicBase.h"
#include "core/defs.h"
using namespace amnezia;
class UiLogic;

View file

@ -36,64 +36,64 @@ void ServerContainersLogic::onPushButtonProtoSettingsClicked(DockerContainer c,
{
qDebug()<< "ServerContainersLogic::onPushButtonProtoSettingsClicked" << c << p;
uiLogic()->selectedDockerContainer = c;
uiLogic()->protocolLogic(p)->updateProtocolPage(m_settings.protocolConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, p),
uiLogic()->protocolLogic(p)->updateProtocolPage(m_settings->protocolConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, p),
uiLogic()->selectedDockerContainer,
m_settings.haveAuthData(uiLogic()->selectedServerIndex));
m_settings->haveAuthData(uiLogic()->selectedServerIndex));
emit uiLogic()->goToProtocolPage(p);
}
void ServerContainersLogic::onPushButtonDefaultClicked(DockerContainer c)
{
if (m_settings.defaultContainer(uiLogic()->selectedServerIndex) == c) return;
if (m_settings->defaultContainer(uiLogic()->selectedServerIndex) == c) return;
m_settings.setDefaultContainer(uiLogic()->selectedServerIndex, c);
m_settings->setDefaultContainer(uiLogic()->selectedServerIndex, c);
uiLogic()->onUpdateAllPages();
if (uiLogic()->selectedServerIndex != m_settings.defaultServerIndex()) return;
if (uiLogic()->selectedServerIndex != m_settings->defaultServerIndex()) return;
if (!uiLogic()->m_vpnConnection) return;
if (!uiLogic()->m_vpnConnection->isConnected()) return;
uiLogic()->vpnLogic()->onDisconnect();
uiLogic()->vpnLogic()->onConnect();
uiLogic()->pageLogic<VpnLogic>()->onDisconnect();
uiLogic()->pageLogic<VpnLogic>()->onConnect();
}
void ServerContainersLogic::onPushButtonShareClicked(DockerContainer c)
{
uiLogic()->shareConnectionLogic()->updateSharingPage(uiLogic()->selectedServerIndex, c);
uiLogic()->pageLogic<ShareConnectionLogic>()->updateSharingPage(uiLogic()->selectedServerIndex, c);
emit uiLogic()->goToPage(Page::ShareConnection);
}
void ServerContainersLogic::onPushButtonRemoveClicked(DockerContainer container)
{
//buttonSetEnabledFunc(false);
ErrorCode e = ServerController::removeContainer(m_settings.serverCredentials(uiLogic()->selectedServerIndex), container);
m_settings.removeContainerConfig(uiLogic()->selectedServerIndex, container);
ErrorCode e = m_serverController->removeContainer(m_settings->serverCredentials(uiLogic()->selectedServerIndex), container);
m_settings->removeContainerConfig(uiLogic()->selectedServerIndex, container);
//buttonSetEnabledFunc(true);
if (m_settings.defaultContainer(uiLogic()->selectedServerIndex) == container) {
const auto &c = m_settings.containers(uiLogic()->selectedServerIndex);
if (c.isEmpty()) m_settings.setDefaultContainer(uiLogic()->selectedServerIndex, DockerContainer::None);
else m_settings.setDefaultContainer(uiLogic()->selectedServerIndex, c.keys().first());
if (m_settings->defaultContainer(uiLogic()->selectedServerIndex) == container) {
const auto &c = m_settings->containers(uiLogic()->selectedServerIndex);
if (c.isEmpty()) m_settings->setDefaultContainer(uiLogic()->selectedServerIndex, DockerContainer::None);
else m_settings->setDefaultContainer(uiLogic()->selectedServerIndex, c.keys().first());
}
uiLogic()->onUpdateAllPages();
}
void ServerContainersLogic::onPushButtonContinueClicked(DockerContainer c, int port, TransportProto tp)
{
QJsonObject config = ServerController::createContainerInitialConfig(c, port, tp);
QJsonObject config = m_serverController->createContainerInitialConfig(c, port, tp);
emit uiLogic()->goToPage(Page::ServerConfiguringProgress);
qApp->processEvents();
ErrorCode e = uiLogic()->serverConfiguringProgressLogic()->doInstallAction([this, c, &config](){
return ServerController::setupContainer(m_settings.serverCredentials(uiLogic()->selectedServerIndex), c, config);
ErrorCode e = uiLogic()->pageLogic<ServerConfiguringProgressLogic>()->doInstallAction([this, c, &config](){
return m_serverController->setupContainer(m_settings->serverCredentials(uiLogic()->selectedServerIndex), c, config);
});
if (!e) {
m_settings.setContainerConfig(uiLogic()->selectedServerIndex, c, config);
m_settings->setContainerConfig(uiLogic()->selectedServerIndex, c, config);
if (ContainerProps::containerService(c) == ServiceType::Vpn) {
m_settings.setDefaultContainer(uiLogic()->selectedServerIndex, c);
m_settings->setDefaultContainer(uiLogic()->selectedServerIndex, c);
}
}

View file

@ -2,6 +2,7 @@
#define SERVER_CONTAINERS_LOGIC_H
#include "PageLogicBase.h"
#include "containers/containers_defs.h"
class UiLogic;

View file

@ -13,7 +13,7 @@ ServerListLogic::ServerListLogic(UiLogic *logic, QObject *parent):
void ServerListLogic::onServerListPushbuttonDefaultClicked(int index)
{
m_settings.setDefaultServer(index);
m_settings->setDefaultServer(index);
uiLogic()->onUpdateAllPages();
}
@ -25,8 +25,8 @@ void ServerListLogic::onServerListPushbuttonSettingsClicked(int index)
void ServerListLogic::onUpdatePage()
{
const QJsonArray &servers = m_settings.serversArray();
int defaultServer = m_settings.defaultServerIndex();
const QJsonArray &servers = m_settings->serversArray();
int defaultServer = m_settings->defaultServerIndex();
std::vector<ServerModelContent> serverListContent;
for(int i = 0; i < servers.size(); i++) {
ServerModelContent c;

View file

@ -10,6 +10,12 @@
#include <core/servercontroller.h>
#include <QTimer>
#if defined(Q_OS_ANDROID)
#include <QAndroidJniObject>
#include <QAndroidJniEnvironment>
#include <QtAndroid>
#endif
ServerSettingsLogic::ServerSettingsLogic(UiLogic *logic, QObject *parent):
PageLogicBase(logic, parent),
m_labelWaitInfoVisible{true},
@ -26,10 +32,10 @@ void ServerSettingsLogic::onUpdatePage()
{
set_labelWaitInfoVisible(false);
set_labelWaitInfoText("");
set_pushButtonClearVisible(m_settings.haveAuthData(uiLogic()->selectedServerIndex));
set_pushButtonClearClientCacheVisible(m_settings.haveAuthData(uiLogic()->selectedServerIndex));
set_pushButtonShareFullVisible(m_settings.haveAuthData(uiLogic()->selectedServerIndex));
const QJsonObject &server = m_settings.server(uiLogic()->selectedServerIndex);
set_pushButtonClearVisible(m_settings->haveAuthData(uiLogic()->selectedServerIndex));
set_pushButtonClearClientCacheVisible(m_settings->haveAuthData(uiLogic()->selectedServerIndex));
set_pushButtonShareFullVisible(m_settings->haveAuthData(uiLogic()->selectedServerIndex));
const QJsonObject &server = m_settings->server(uiLogic()->selectedServerIndex);
const QString &port = server.value(config_key::port).toString();
set_labelServerText(QString("%1@%2%3%4")
.arg(server.value(config_key::userName).toString())
@ -38,7 +44,7 @@ void ServerSettingsLogic::onUpdatePage()
.arg(port));
set_lineEditDescriptionText(server.value(config_key::description).toString());
DockerContainer selectedContainer = m_settings.defaultContainer(uiLogic()->selectedServerIndex);
DockerContainer selectedContainer = m_settings->defaultContainer(uiLogic()->selectedServerIndex);
QString selectedContainerName = ContainerProps::containerHumanNames().value(selectedContainer);
set_labelCurrentVpnProtocolText(tr("Service: ") + selectedContainerName);
}
@ -48,14 +54,14 @@ void ServerSettingsLogic::onPushButtonClearServer()
set_pageEnabled(false);
set_pushButtonClearText(tr("Uninstalling Amnezia software..."));
if (m_settings.defaultServerIndex() == uiLogic()->selectedServerIndex) {
uiLogic()->vpnLogic()->onDisconnect();
if (m_settings->defaultServerIndex() == uiLogic()->selectedServerIndex) {
uiLogic()->pageLogic<VpnLogic>()->onDisconnect();
}
ErrorCode e = ServerController::removeAllContainers(m_settings.serverCredentials(uiLogic()->selectedServerIndex));
ServerController::disconnectFromHost(m_settings.serverCredentials(uiLogic()->selectedServerIndex));
ErrorCode e = m_serverController->removeAllContainers(m_settings->serverCredentials(uiLogic()->selectedServerIndex));
m_serverController->disconnectFromHost(m_settings->serverCredentials(uiLogic()->selectedServerIndex));
if (e) {
uiLogic()->setDialogConnectErrorText(
uiLogic()->set_dialogConnectErrorText(
tr("Error occurred while configuring server.") + "\n" +
errorString(e) + "\n" +
tr("See logs for details."));
@ -66,8 +72,8 @@ void ServerSettingsLogic::onPushButtonClearServer()
set_labelWaitInfoText(tr("Amnezia server successfully uninstalled"));
}
m_settings.setContainers(uiLogic()->selectedServerIndex, {});
m_settings.setDefaultContainer(uiLogic()->selectedServerIndex, DockerContainer::None);
m_settings->setContainers(uiLogic()->selectedServerIndex, {});
m_settings->setDefaultContainer(uiLogic()->selectedServerIndex, DockerContainer::None);
set_pageEnabled(true);
set_pushButtonClearText(tr("Clear server from Amnezia software"));
@ -75,27 +81,27 @@ void ServerSettingsLogic::onPushButtonClearServer()
void ServerSettingsLogic::onPushButtonForgetServer()
{
if (m_settings.defaultServerIndex() == uiLogic()->selectedServerIndex && uiLogic()->m_vpnConnection->isConnected()) {
uiLogic()->vpnLogic()->onDisconnect();
if (m_settings->defaultServerIndex() == uiLogic()->selectedServerIndex && uiLogic()->m_vpnConnection->isConnected()) {
uiLogic()->pageLogic<VpnLogic>()->onDisconnect();
}
m_settings.removeServer(uiLogic()->selectedServerIndex);
m_settings->removeServer(uiLogic()->selectedServerIndex);
if (m_settings.defaultServerIndex() == uiLogic()->selectedServerIndex) {
m_settings.setDefaultServer(0);
if (m_settings->defaultServerIndex() == uiLogic()->selectedServerIndex) {
m_settings->setDefaultServer(0);
}
else if (m_settings.defaultServerIndex() > uiLogic()->selectedServerIndex) {
m_settings.setDefaultServer(m_settings.defaultServerIndex() - 1);
else if (m_settings->defaultServerIndex() > uiLogic()->selectedServerIndex) {
m_settings->setDefaultServer(m_settings->defaultServerIndex() - 1);
}
if (m_settings.serversCount() == 0) {
m_settings.setDefaultServer(-1);
if (m_settings->serversCount() == 0) {
m_settings->setDefaultServer(-1);
}
uiLogic()->selectedServerIndex = -1;
uiLogic()->onUpdateAllPages();
if (m_settings.serversCount() == 0) {
if (m_settings->serversCount() == 0) {
uiLogic()->setStartPage(Page::Start);
}
else {
@ -107,9 +113,9 @@ void ServerSettingsLogic::onPushButtonClearClientCacheClicked()
{
set_pushButtonClearClientCacheText(tr("Cache cleared"));
const auto &containers = m_settings.containers(uiLogic()->selectedServerIndex);
const auto &containers = m_settings->containers(uiLogic()->selectedServerIndex);
for (DockerContainer container: containers.keys()) {
m_settings.clearLastConnectionConfig(uiLogic()->selectedServerIndex, container);
m_settings->clearLastConnectionConfig(uiLogic()->selectedServerIndex, container);
}
QTimer::singleShot(3000, this, [this]() {
@ -120,14 +126,47 @@ void ServerSettingsLogic::onPushButtonClearClientCacheClicked()
void ServerSettingsLogic::onLineEditDescriptionEditingFinished()
{
const QString &newText = lineEditDescriptionText();
QJsonObject server = m_settings.server(uiLogic()->selectedServerIndex);
QJsonObject server = m_settings->server(uiLogic()->selectedServerIndex);
server.insert(config_key::description, newText);
m_settings.editServer(uiLogic()->selectedServerIndex, server);
m_settings->editServer(uiLogic()->selectedServerIndex, server);
uiLogic()->onUpdateAllPages();
}
#if defined(Q_OS_ANDROID)
/* Auth result handler for Android */
void authResultReceiver::handleActivityResult(int receiverRequestCode, int resultCode, const QAndroidJniObject &data)
{
qDebug() << "receiverRequestCode" << receiverRequestCode << "resultCode" << resultCode;
if (resultCode == -1) { //ResultOK
uiLogic()->pageLogic<ShareConnectionLogic>()->updateSharingPage(m_serverIndex, DockerContainer::None);
emit uiLogic()->goToShareProtocolPage(Proto::Any);
}
}
#endif
void ServerSettingsLogic::onPushButtonShareFullClicked()
{
uiLogic()->shareConnectionLogic()->updateSharingPage(uiLogic()->selectedServerIndex, DockerContainer::None);
#if defined(Q_OS_ANDROID)
/* We use builtin keyguard for ssh key export protection on Android */
auto appContext = QtAndroid::androidActivity().callObjectMethod(
"getApplicationContext", "()Landroid/content/Context;");
if (appContext.isValid()) {
QAndroidActivityResultReceiver *receiver = new authResultReceiver(uiLogic(), uiLogic()->selectedServerIndex);
auto intent = QAndroidJniObject::callStaticObjectMethod(
"org/amnezia/vpn/AuthHelper", "getAuthIntent",
"(Landroid/content/Context;)Landroid/content/Intent;", appContext.object());
if (intent.isValid()) {
if (intent.object<jobject>() != nullptr) {
QtAndroid::startActivity(intent.object<jobject>(), 1, receiver);
}
} else {
uiLogic()->pageLogic<ShareConnectionLogic>()->updateSharingPage(uiLogic()->selectedServerIndex, DockerContainer::None);
emit uiLogic()->goToShareProtocolPage(Proto::Any);
}
}
#else
uiLogic()->pageLogic<ShareConnectionLogic>()->updateSharingPage(uiLogic()->selectedServerIndex, DockerContainer::None);
emit uiLogic()->goToShareProtocolPage(Proto::Any);
#endif
}

View file

@ -3,6 +3,10 @@
#include "PageLogicBase.h"
#if defined(Q_OS_ANDROID)
#include <QAndroidActivityResultReceiver>
#endif
class UiLogic;
class ServerSettingsLogic : public PageLogicBase
@ -34,4 +38,25 @@ public:
~ServerSettingsLogic() = default;
};
#if defined(Q_OS_ANDROID)
/* Auth result handler for Android */
class authResultReceiver final : public PageLogicBase, public QAndroidActivityResultReceiver
{
Q_OBJECT
public:
authResultReceiver(UiLogic *uiLogic, int serverIndex , QObject *parent = nullptr) : PageLogicBase(uiLogic, parent) {
m_serverIndex = serverIndex;
}
~authResultReceiver() {}
public:
void handleActivityResult(int receiverRequestCode, int resultCode, const QAndroidJniObject &data) override;
private:
int m_serverIndex;
};
#endif
#endif // SERVER_SETTINGS_LOGIC_H

View file

@ -1,12 +1,10 @@
#include <QBuffer>
#include <QImage>
#include <QDataStream>
//#include <QZXing>
#include <QMessageBox>
#include "QZXing.h"
#include "QZXingImageProvider.h"
//#include "QZXingFilter.h"
#include "qrcodegen.hpp"
#include "ShareConnectionLogic.h"
@ -21,6 +19,7 @@
#include "defines.h"
#include "core/defs.h"
#include "core/errorstrings.h"
#include "core/servercontroller.h"
#include <functional>
#include "../uilogic.h"
@ -29,6 +28,8 @@
#include <math.h>
#endif
using namespace qrcodegen;
ShareConnectionLogic::ShareConnectionLogic(UiLogic *logic, QObject *parent):
PageLogicBase(logic, parent),
m_textEditShareOpenVpnCodeText{},
@ -73,19 +74,19 @@ void ShareConnectionLogic::onPushButtonShareAmneziaGenerateClicked()
// Full access
if (shareFullAccess()) {
serverConfig = m_settings.server(serverIndex);
serverConfig = m_settings->server(serverIndex);
}
// Container share
else {
ServerCredentials credentials = m_settings.serverCredentials(serverIndex);
QJsonObject containerConfig = m_settings.containerConfig(serverIndex, container);
ServerCredentials credentials = m_settings->serverCredentials(serverIndex);
QJsonObject containerConfig = m_settings->containerConfig(serverIndex, container);
containerConfig.insert(config_key::container, ContainerProps::containerToString(container));
ErrorCode e = ErrorCode::NoError;
for (Proto p: ContainerProps::protocolsForContainer(container)) {
QJsonObject protoConfig = m_settings.protocolConfig(serverIndex, container, p);
QJsonObject protoConfig = m_settings->protocolConfig(serverIndex, container, p);
QString cfg = VpnConfigurator::genVpnProtocolConfig(credentials, container, containerConfig, p, &e);
QString cfg = m_configurator->genVpnProtocolConfig(credentials, container, containerConfig, p, &e);
if (e) {
cfg = "Error generating config";
break;
@ -96,14 +97,14 @@ void ShareConnectionLogic::onPushButtonShareAmneziaGenerateClicked()
QByteArray ba;
if (!e) {
serverConfig = m_settings.server(serverIndex);
serverConfig = m_settings->server(serverIndex);
serverConfig.remove(config_key::userName);
serverConfig.remove(config_key::password);
serverConfig.remove(config_key::port);
serverConfig.insert(config_key::containers, QJsonArray {containerConfig});
serverConfig.insert(config_key::defaultContainer, ContainerProps::containerToString(container));
auto dns = VpnConfigurator::getDnsForConfig(serverIndex);
auto dns = m_configurator->getDnsForConfig(serverIndex);
serverConfig.insert(config_key::dns1, dns.first);
serverConfig.insert(config_key::dns2, dns.second);
@ -129,13 +130,13 @@ void ShareConnectionLogic::onPushButtonShareOpenVpnGenerateClicked()
{
int serverIndex = uiLogic()->selectedServerIndex;
DockerContainer container = uiLogic()->selectedDockerContainer;
ServerCredentials credentials = m_settings.serverCredentials(serverIndex);
ServerCredentials credentials = m_settings->serverCredentials(serverIndex);
const QJsonObject &containerConfig = m_settings.containerConfig(serverIndex, container);
const QJsonObject &containerConfig = m_settings->containerConfig(serverIndex, container);
ErrorCode e = ErrorCode::NoError;
QString cfg = OpenVpnConfigurator::genOpenVpnConfig(credentials, container, containerConfig, &e);
cfg = VpnConfigurator::processConfigWithExportSettings(serverIndex, container, Proto::OpenVpn, cfg);
QString cfg = m_configurator->openVpnConfigurator->genOpenVpnConfig(credentials, container, containerConfig, &e);
cfg = m_configurator->processConfigWithExportSettings(serverIndex, container, Proto::OpenVpn, cfg);
set_textEditShareOpenVpnCodeText(QJsonDocument::fromJson(cfg.toUtf8()).object()[config_key::config].toString());
}
@ -144,16 +145,16 @@ void ShareConnectionLogic::onPushButtonShareShadowSocksGenerateClicked()
{
int serverIndex = uiLogic()->selectedServerIndex;
DockerContainer container = uiLogic()->selectedDockerContainer;
ServerCredentials credentials = m_settings.serverCredentials(serverIndex);
ServerCredentials credentials = m_settings->serverCredentials(serverIndex);
QJsonObject protoConfig = m_settings.protocolConfig(serverIndex, container, Proto::ShadowSocks);
QJsonObject protoConfig = m_settings->protocolConfig(serverIndex, container, Proto::ShadowSocks);
QString cfg = protoConfig.value(config_key::last_config).toString();
if (cfg.isEmpty()) {
const QJsonObject &containerConfig = m_settings.containerConfig(serverIndex, container);
const QJsonObject &containerConfig = m_settings->containerConfig(serverIndex, container);
ErrorCode e = ErrorCode::NoError;
cfg = ShadowSocksConfigurator::genShadowSocksConfig(credentials, container, containerConfig, &e);
cfg = m_configurator->shadowSocksConfigurator->genShadowSocksConfig(credentials, container, containerConfig, &e);
}
QJsonObject ssConfig = QJsonDocument::fromJson(cfg.toUtf8()).object();
@ -167,8 +168,10 @@ void ShareConnectionLogic::onPushButtonShareShadowSocksGenerateClicked()
ssString = "ss://" + ssString.toUtf8().toBase64();
set_lineEditShareShadowSocksStringText(ssString);
QImage qr = QZXing::encodeData(ssString.toUtf8(), QZXing::EncoderFormat_QR_CODE, QSize(512,512), QZXing::EncodeErrorCorrectionLevel_L);
set_shareShadowSocksQrCodeText(imageToBase64(qr));
QrCode qr = QrCode::encodeText(ssString.toUtf8(), QrCode::Ecc::LOW);
QString svg = QString::fromStdString(toSvgString(qr, 0));
set_shareShadowSocksQrCodeText(svgToBase64(svg));
QString humanString = QString("Server: %3\n"
"Port: %4\n"
@ -186,16 +189,16 @@ void ShareConnectionLogic::onPushButtonShareCloakGenerateClicked()
{
int serverIndex = uiLogic()->selectedServerIndex;
DockerContainer container = uiLogic()->selectedDockerContainer;
ServerCredentials credentials = m_settings.serverCredentials(serverIndex);
ServerCredentials credentials = m_settings->serverCredentials(serverIndex);
QJsonObject protoConfig = m_settings.protocolConfig(serverIndex, container, Proto::Cloak);
QJsonObject protoConfig = m_settings->protocolConfig(serverIndex, container, Proto::Cloak);
QString cfg = protoConfig.value(config_key::last_config).toString();
if (cfg.isEmpty()) {
const QJsonObject &containerConfig = m_settings.containerConfig(serverIndex, container);
const QJsonObject &containerConfig = m_settings->containerConfig(serverIndex, container);
ErrorCode e = ErrorCode::NoError;
cfg = CloakConfigurator::genCloakConfig(credentials, container, containerConfig, &e);
cfg = m_configurator->cloakConfigurator->genCloakConfig(credentials, container, containerConfig, &e);
}
QJsonObject cloakConfig = QJsonDocument::fromJson(cfg.toUtf8()).object();
@ -209,48 +212,47 @@ void ShareConnectionLogic::onPushButtonShareWireGuardGenerateClicked()
{
int serverIndex = uiLogic()->selectedServerIndex;
DockerContainer container = uiLogic()->selectedDockerContainer;
ServerCredentials credentials = m_settings.serverCredentials(serverIndex);
ServerCredentials credentials = m_settings->serverCredentials(serverIndex);
const QJsonObject &containerConfig = m_settings.containerConfig(serverIndex, container);
const QJsonObject &containerConfig = m_settings->containerConfig(serverIndex, container);
ErrorCode e = ErrorCode::NoError;
QString cfg = WireguardConfigurator::genWireguardConfig(credentials, container, containerConfig, &e);
QString cfg = m_configurator->wireguardConfigurator->genWireguardConfig(credentials, container, containerConfig, &e);
if (e) {
QMessageBox::warning(nullptr, APPLICATION_NAME,
tr("Error occurred while configuring server.") + "\n" +
errorString(e));
return;
}
cfg = VpnConfigurator::processConfigWithExportSettings(serverIndex, container, Proto::WireGuard, cfg);
cfg = m_configurator->processConfigWithExportSettings(serverIndex, container, Proto::WireGuard, cfg);
cfg = QJsonDocument::fromJson(cfg.toUtf8()).object()[config_key::config].toString();
set_textEditShareWireGuardCodeText(cfg);
QImage qr = QZXing::encodeData(cfg.toUtf8(), QZXing::EncoderFormat_QR_CODE, QSize(512,512), QZXing::EncodeErrorCorrectionLevel_L);
QrCode qr = QrCode::encodeText(cfg.toUtf8(), QrCode::Ecc::LOW);
QString svg = QString::fromStdString(toSvgString(qr, 0));
set_shareWireGuardQrCodeText(imageToBase64(qr));
set_shareWireGuardQrCodeText(svgToBase64(svg));
}
void ShareConnectionLogic::onPushButtonShareIkev2GenerateClicked()
{
int serverIndex = uiLogic()->selectedServerIndex;
DockerContainer container = uiLogic()->selectedDockerContainer;
ServerCredentials credentials = m_settings.serverCredentials(serverIndex);
ServerCredentials credentials = m_settings->serverCredentials(serverIndex);
//const QJsonObject &containerConfig = m_settings.containerConfig(serverIndex, container);
Ikev2Configurator::ConnectionData connData = m_configurator->ikev2Configurator->prepareIkev2Config(credentials, container);
Ikev2Configurator::ConnectionData connData = Ikev2Configurator::prepareIkev2Config(credentials, container);
QString cfg = Ikev2Configurator::genIkev2Config(connData);
cfg = VpnConfigurator::processConfigWithExportSettings(serverIndex, container, Proto::Ikev2, cfg);
QString cfg = m_configurator->ikev2Configurator->genIkev2Config(connData);
cfg = m_configurator->processConfigWithExportSettings(serverIndex, container, Proto::Ikev2, cfg);
cfg = QJsonDocument::fromJson(cfg.toUtf8()).object()[config_key::cert].toString();
set_textEditShareIkev2CertText(cfg);
QString mobileCfg = Ikev2Configurator::genMobileConfig(connData);
QString mobileCfg = m_configurator->ikev2Configurator->genMobileConfig(connData);
set_textEditShareIkev2MobileConfigText(mobileCfg);
QString strongSwanCfg = Ikev2Configurator::genStrongSwanConfig(connData);
QString strongSwanCfg = m_configurator->ikev2Configurator->genStrongSwanConfig(connData);
set_textEditShareIkev2StrongSwanConfigText(strongSwanCfg);
}
@ -268,7 +270,7 @@ void ShareConnectionLogic::updateSharingPage(int serverIndex, DockerContainer co
QList<QString> ShareConnectionLogic::genQrCodeImageSeries(const QByteArray &data)
{
double k = 1500;
double k = 850;
quint8 chunksCount = std::ceil(data.size() / k);
QList<QString> chunks;
@ -279,18 +281,15 @@ QList<QString> ShareConnectionLogic::genQrCodeImageSeries(const QByteArray &data
QByteArray ba = chunk.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
QImage qr = QZXing::encodeData(ba, QZXing::EncoderFormat_QR_CODE, QSize(512,512), QZXing::EncodeErrorCorrectionLevel_L);
chunks.append(imageToBase64(qr));
QrCode qr = QrCode::encodeText(ba, QrCode::Ecc::LOW);
QString svg = QString::fromStdString(toSvgString(qr, 0));
chunks.append(svgToBase64(svg));
}
return chunks;
}
QString ShareConnectionLogic::imageToBase64(const QImage &image)
QString ShareConnectionLogic::svgToBase64(const QString &image)
{
QByteArray ba;
QBuffer bu(&ba);
bu.open(QIODevice::WriteOnly);
image.save(&bu, "PNG");
return "data:image/png;base64," + QString::fromLatin1(ba.toBase64().data());
return "data:image/svg;base64," + QString::fromLatin1(image.toUtf8().toBase64().data());
}

View file

@ -2,6 +2,7 @@
#define SHARE_CONNECTION_LOGIC_H
#include "PageLogicBase.h"
#include "containers/containers_defs.h"
class UiLogic;
@ -48,8 +49,7 @@ public:
void updateSharingPage(int serverIndex, DockerContainer container);
QList<QString> genQrCodeImageSeries(const QByteArray &data);
QString imageToBase64(const QImage &image);
QString svgToBase64(const QString &image);
};
#endif // SHARE_CONNECTION_LOGIC_H

View file

@ -18,13 +18,13 @@ SitesLogic::SitesLogic(UiLogic *logic, QObject *parent):
m_tableViewSitesModel{nullptr},
m_lineEditSitesAddCustomText{}
{
sitesModels.insert(Settings::VpnOnlyForwardSites, new SitesModel(Settings::VpnOnlyForwardSites));
sitesModels.insert(Settings::VpnAllExceptSites, new SitesModel(Settings::VpnAllExceptSites));
sitesModels.insert(Settings::VpnOnlyForwardSites, new SitesModel(m_settings, Settings::VpnOnlyForwardSites));
sitesModels.insert(Settings::VpnAllExceptSites, new SitesModel(m_settings, Settings::VpnAllExceptSites));
}
void SitesLogic::onUpdatePage()
{
Settings::RouteMode m = m_settings.routeMode();
Settings::RouteMode m = m_settings->routeMode();
if (m == Settings::VpnAllSites) return;
if (m == Settings::VpnOnlyForwardSites) {
@ -40,10 +40,10 @@ void SitesLogic::onUpdatePage()
void SitesLogic::onPushButtonAddCustomSitesClicked()
{
if (uiLogic()->vpnLogic()->radioButtonVpnModeAllSitesChecked()) {
if (uiLogic()->pageLogic<VpnLogic>()->radioButtonVpnModeAllSitesChecked()) {
return;
}
Settings::RouteMode mode = m_settings.routeMode();
Settings::RouteMode mode = m_settings->routeMode();
QString newSite = lineEditSitesAddCustomText();
@ -60,7 +60,7 @@ void SitesLogic::onPushButtonAddCustomSitesClicked()
}
const auto &cbProcess = [this, mode](const QString &newSite, const QString &ip) {
m_settings.addVpnSite(mode, newSite, ip);
m_settings->addVpnSite(mode, newSite, ip);
if (!ip.isEmpty()) {
uiLogic()->m_vpnConnection->addRoutes(QStringList() << ip);
@ -100,7 +100,7 @@ void SitesLogic::onPushButtonAddCustomSitesClicked()
void SitesLogic::onPushButtonSitesDeleteClicked(QStringList items)
{
Settings::RouteMode mode = m_settings.routeMode();
Settings::RouteMode mode = m_settings->routeMode();
auto siteModel = qobject_cast<SitesModel*> (tableViewSitesModel());
if (!siteModel || items.isEmpty()) {
@ -121,7 +121,7 @@ void SitesLogic::onPushButtonSitesDeleteClicked(QStringList items)
}
}
m_settings.removeVpnSites(mode, sites);
m_settings->removeVpnSites(mode, sites);
if (uiLogic()->m_vpnConnection->connectionState() == VpnProtocol::Connected) {
uiLogic()->m_vpnConnection->deleteRoutes(ips);
@ -139,7 +139,7 @@ void SitesLogic::onPushButtonSitesImportClicked(const QString& fileName)
return;
}
Settings::RouteMode mode = m_settings.routeMode();
Settings::RouteMode mode = m_settings->routeMode();
QStringList ips;
QMap<QString, QString> sites;
@ -187,8 +187,8 @@ void SitesLogic::onPushButtonSitesImportClicked(const QString& fileName)
}
m_settings.addVpnIps(mode, ips);
m_settings.addVpnSites(mode, sites);
m_settings->addVpnIps(mode, ips);
m_settings->addVpnSites(mode, sites);
uiLogic()->m_vpnConnection->addRoutes(QStringList() << ips);
uiLogic()->m_vpnConnection->flushDns();
@ -198,9 +198,9 @@ void SitesLogic::onPushButtonSitesImportClicked(const QString& fileName)
void SitesLogic::onPushButtonSitesExportClicked()
{
Settings::RouteMode mode = m_settings.routeMode();
Settings::RouteMode mode = m_settings->routeMode();
QVariantMap sites = m_settings.vpnSites(mode);
QVariantMap sites = m_settings->vpnSites(mode);
QString data;
for (auto s : sites.keys()) {

View file

@ -2,6 +2,7 @@
#define SITES_LOGIC_H
#include "PageLogicBase.h"
#include "settings.h"
class UiLogic;
class SitesModel;

View file

@ -1,6 +1,9 @@
#include "StartPageLogic.h"
#include "ViewConfigLogic.h"
#include "core/errorstrings.h"
#include "configurators/ssh_configurator.h"
#include "configurators/vpn_configurator.h"
#include "../uilogic.h"
#include "utilities.h"
@ -8,6 +11,7 @@
#include <QStandardPaths>
#ifdef Q_OS_ANDROID
#include <QtAndroid>
#include "platforms/android/android_controller.h"
#endif
@ -16,18 +20,20 @@ StartPageLogic::StartPageLogic(UiLogic *logic, QObject *parent):
m_pushButtonConnectEnabled{true},
m_pushButtonConnectText{tr("Connect")},
m_pushButtonConnectKeyChecked{false},
m_lineEditStartExistingCodeText{},
m_textEditSshKeyText{},
m_lineEditIpText{},
m_lineEditPasswordText{},
m_lineEditLoginText{},
m_labelWaitInfoVisible{true},
m_labelWaitInfoText{},
m_pushButtonBackFromStartVisible{true},
m_pushButtonConnectVisible{true},
m_ipAddressPortRegex{Utils::ipAddressPortRegExp()}
{
#ifdef Q_OS_ANDROID
// Set security screen for Android app
QtAndroid::runOnAndroidThread([]() {
QAndroidJniObject window = QtAndroid::androidActivity().callObjectMethod("getWindow", "()Landroid/view/Window;");
if (window.isValid()){
const int FLAG_SECURE = 8192;
window.callMethod<void>("addFlags", "(I)V", FLAG_SECURE);
}
});
#endif
}
void StartPageLogic::onUpdatePage()
@ -41,7 +47,6 @@ void StartPageLogic::onUpdatePage()
set_labelWaitInfoVisible(false);
set_labelWaitInfoText("");
set_pushButtonConnectVisible(true);
set_pushButtonConnectKeyChecked(false);
@ -50,8 +55,6 @@ void StartPageLogic::onUpdatePage()
void StartPageLogic::onPushButtonConnect()
{
// uiLogic()->goToPage(Page::NewServer);
// return;
if (pushButtonConnectKeyChecked()){
if (lineEditIpText().isEmpty() ||
lineEditLoginText().isEmpty() ||
@ -68,7 +71,6 @@ void StartPageLogic::onPushButtonConnect()
return;
}
}
qDebug() << "UiLogic::onPushButtonConnect checking new server";
ServerCredentials serverCredentials;
serverCredentials.hostName = lineEditIpText();
@ -85,7 +87,7 @@ void StartPageLogic::onPushButtonConnect()
}
if (key.contains("OPENSSH") && key.contains("BEGIN") && key.contains("PRIVATE KEY")) {
key = SshConfigurator::convertOpenSShKey(key);
key = m_configurator->sshConfigurator->convertOpenSShKey(key);
}
serverCredentials.password = key;
@ -99,7 +101,7 @@ void StartPageLogic::onPushButtonConnect()
ErrorCode e = ErrorCode::NoError;
#ifdef Q_DEBUG
//QString output = ServerController::checkSshConnection(serverCredentials, &e);
//QString output = m_serverController->checkSshConnection(serverCredentials, &e);
#else
QString output;
#endif
@ -153,19 +155,10 @@ bool StartPageLogic::importConnection(const QJsonObject &profile)
credentials.userName = profile.value(config_key::userName).toString();
credentials.password = profile.value(config_key::password).toString();
// qDebug() << QString("Added server %3@%1:%2").
// arg(credentials.hostName).
// arg(credentials.port).
// arg(credentials.userName);
//qDebug() << QString("Password") << credentials.password;
if (credentials.isValid() || profile.contains(config_key::containers)) {
m_settings.addServer(profile);
m_settings.setDefaultServer(m_settings.serversCount() - 1);
emit uiLogic()->goToPage(Page::Vpn);
emit uiLogic()->setStartPage(Page::Vpn);
// check config
uiLogic()->pageLogic<ViewConfigLogic>()->set_configJson(profile);
emit uiLogic()->goToPage(Page::ViewConfig);
}
else {
qDebug() << "Failed to import profile";
@ -174,8 +167,8 @@ bool StartPageLogic::importConnection(const QJsonObject &profile)
}
if (!profile.contains(config_key::containers)) {
uiLogic()->selectedServerIndex = m_settings.defaultServerIndex();
uiLogic()->selectedDockerContainer = m_settings.defaultContainer(uiLogic()->selectedServerIndex);
uiLogic()->selectedServerIndex = m_settings->defaultServerIndex();
uiLogic()->selectedDockerContainer = m_settings->defaultContainer(uiLogic()->selectedServerIndex);
uiLogic()->onUpdateAllPages();
emit uiLogic()->goToPage(Page::ServerContainers);
@ -209,7 +202,6 @@ bool StartPageLogic::importConnectionFromCode(QString code)
bool StartPageLogic::importConnectionFromQr(const QByteArray &data)
{
qDebug() << "StartPageLogic::importConnectionFromQr" << data;
QJsonObject dataObj = QJsonDocument::fromJson(data).object();
if (!dataObj.isEmpty()) {
return importConnection(dataObj);

View file

@ -3,7 +3,7 @@
#include "PageLogicBase.h"
#include <QRegExp>
#include <QRegularExpression>
class UiLogic;
@ -22,7 +22,6 @@ class StartPageLogic : public PageLogicBase
AUTO_PROPERTY(bool, labelWaitInfoVisible)
AUTO_PROPERTY(QString, labelWaitInfoText)
AUTO_PROPERTY(bool, pushButtonBackFromStartVisible)
AUTO_PROPERTY(bool, pushButtonConnectVisible)
READONLY_PROPERTY(QRegularExpression, ipAddressPortRegex)
public:

View file

@ -0,0 +1,67 @@
#include "ViewConfigLogic.h"
#include "core/errorstrings.h"
#include "../uilogic.h"
ViewConfigLogic::ViewConfigLogic(UiLogic *logic, QObject *parent):
PageLogicBase(logic, parent)
{
}
void ViewConfigLogic::onUpdatePage()
{
set_configText(QJsonDocument(configJson()).toJson());
m_openVpnLastConfigs = m_openVpnMalStrings =
"<style> \
div { line-height: 0.5; } \
</style><div>";
m_warningStringNumber = 3;
m_warningActive = false;
const QJsonArray &containers = configJson()[config_key::containers].toArray();
int i = 0;
for (const QJsonValue &v: containers) {
QString cfg_json = v.toObject()[ProtocolProps::protoToString(Proto::OpenVpn)]
.toObject()[config_key::last_config].toString();
QString openvpn_cfg = QJsonDocument::fromJson(cfg_json.toUtf8()).object()[config_key::config]
.toString();
openvpn_cfg.replace("\r", "");
QStringList lines = openvpn_cfg.split("\n");
for (const QString &l: lines) {
i++;
QRegularExpressionMatch match = m_re.match(l);
if (dangerousTags.contains(match.captured(0))) {
QString t = QString("<p><font color=\"red\">%1</font>").arg(l);
m_openVpnLastConfigs.append(t + "\n");
m_openVpnMalStrings.append(t);
if (m_warningStringNumber == 3) m_warningStringNumber = i - 3;
m_warningActive = true;
qDebug() << "ViewConfigLogic : malicious scripts warning:" << l;
}
else {
m_openVpnLastConfigs.append("<p>" + l + "&nbsp;\n");
}
}
}
emit openVpnLastConfigsChanged(m_openVpnLastConfigs);
emit openVpnMalStringsChanged(m_openVpnMalStrings);
emit warningStringNumberChanged(m_warningStringNumber);
emit warningActiveChanged(m_warningActive);
}
void ViewConfigLogic::importConfig()
{
m_settings->addServer(configJson());
m_settings->setDefaultServer(m_settings->serversCount() - 1);
emit uiLogic()->goToPage(Page::Vpn);
emit uiLogic()->setStartPage(Page::Vpn);
}

View file

@ -0,0 +1,47 @@
#ifndef VIEW_CONFIG_LOGIC_H
#define VIEW_CONFIG_LOGIC_H
#include "PageLogicBase.h"
#include <QJsonObject>
class UiLogic;
class ViewConfigLogic : public PageLogicBase
{
Q_OBJECT
AUTO_PROPERTY(QString, configText)
AUTO_PROPERTY(QString, openVpnLastConfigs)
AUTO_PROPERTY(QString, openVpnMalStrings)
AUTO_PROPERTY(QJsonObject, configJson)
AUTO_PROPERTY(int, warningStringNumber)
AUTO_PROPERTY(bool, warningActive)
public:
Q_INVOKABLE void onUpdatePage() override;
Q_INVOKABLE void importConfig();
public:
explicit ViewConfigLogic(UiLogic *uiLogic, QObject *parent = nullptr);
~ViewConfigLogic() = default;
private:
QRegularExpression m_re {"(\\w+-\\w+|\\w+)"};
// https://github.com/OpenVPN/openvpn/blob/master/doc/man-sections/script-options.rst
QStringList dangerousTags {
"up",
"tls-verify",
"ipchange",
"client-connect",
"route-up",
"route-pre-down",
"client-disconnect",
"down",
"learn-address",
"auth-user-pass-verify"
};
};
#endif // VIEW_CONFIG_LOGIC_H

View file

@ -33,7 +33,7 @@ VpnLogic::VpnLogic(UiLogic *logic, QObject *parent):
connect(this, &VpnLogic::connectToVpn, uiLogic()->m_vpnConnection, &VpnConnection::connectToVpn, Qt::QueuedConnection);
connect(this, &VpnLogic::disconnectFromVpn, uiLogic()->m_vpnConnection, &VpnConnection::disconnectFromVpn, Qt::QueuedConnection);
if (m_settings.isAutoConnect() && m_settings.defaultServerIndex() >= 0) {
if (m_settings->isAutoConnect() && m_settings->defaultServerIndex() >= 0) {
QTimer::singleShot(1000, this, [this](){
set_pushButtonConnectEnabled(false);
onConnect();
@ -47,20 +47,20 @@ VpnLogic::VpnLogic(UiLogic *logic, QObject *parent):
void VpnLogic::onUpdatePage()
{
Settings::RouteMode mode = m_settings.routeMode();
DockerContainer selectedContainer = m_settings.defaultContainer(m_settings.defaultServerIndex());
Settings::RouteMode mode = m_settings->routeMode();
DockerContainer selectedContainer = m_settings->defaultContainer(m_settings->defaultServerIndex());
set_isCustomRoutesSupported (selectedContainer == DockerContainer::OpenVpn ||
selectedContainer == DockerContainer::ShadowSocks||
selectedContainer == DockerContainer::Cloak);
set_isContainerHaveAuthData(m_settings.haveAuthData(m_settings.defaultServerIndex()));
set_isContainerHaveAuthData(m_settings->haveAuthData(m_settings->defaultServerIndex()));
set_radioButtonVpnModeAllSitesChecked(mode == Settings::VpnAllSites || !isCustomRoutesSupported());
set_radioButtonVpnModeForwardSitesChecked(mode == Settings::VpnOnlyForwardSites && isCustomRoutesSupported());
set_radioButtonVpnModeExceptSitesChecked(mode == Settings::VpnAllExceptSites && isCustomRoutesSupported());
const QJsonObject &server = uiLogic()->m_settings.defaultServer();
const QJsonObject &server = uiLogic()->m_settings->defaultServer();
QString serverString = QString("%2 (%3)")
.arg(server.value(config_key::description).toString())
.arg(server.value(config_key::hostName).toString());
@ -69,7 +69,7 @@ void VpnLogic::onUpdatePage()
QString selectedContainerName = ContainerProps::containerHumanNames().value(selectedContainer);
set_labelCurrentService(selectedContainerName);
auto dns = VpnConfigurator::getDnsForConfig(m_settings.defaultServerIndex());
auto dns = m_configurator->getDnsForConfig(m_settings->defaultServerIndex());
set_amneziaDnsEnabled(dns.first == protocols::dns::amneziaDnsIp);
if (dns.first == protocols::dns::amneziaDnsIp) {
set_labelCurrentDns("On your server");
@ -93,19 +93,19 @@ void VpnLogic::onUpdatePage()
void VpnLogic::onRadioButtonVpnModeAllSitesClicked()
{
m_settings.setRouteMode(Settings::VpnAllSites);
m_settings->setRouteMode(Settings::VpnAllSites);
onUpdatePage();
}
void VpnLogic::onRadioButtonVpnModeForwardSitesClicked()
{
m_settings.setRouteMode(Settings::VpnOnlyForwardSites);
m_settings->setRouteMode(Settings::VpnOnlyForwardSites);
onUpdatePage();
}
void VpnLogic::onRadioButtonVpnModeExceptSitesClicked()
{
m_settings.setRouteMode(Settings::VpnAllExceptSites);
m_settings->setRouteMode(Settings::VpnAllExceptSites);
onUpdatePage();
}
@ -203,11 +203,11 @@ void VpnLogic::onPushButtonConnectClicked()
void VpnLogic::onConnect()
{
int serverIndex = m_settings.defaultServerIndex();
ServerCredentials credentials = m_settings.serverCredentials(serverIndex);
DockerContainer container = m_settings.defaultContainer(serverIndex);
int serverIndex = m_settings->defaultServerIndex();
ServerCredentials credentials = m_settings->serverCredentials(serverIndex);
DockerContainer container = m_settings->defaultContainer(serverIndex);
if (m_settings.containers(serverIndex).isEmpty()) {
if (m_settings->containers(serverIndex).isEmpty()) {
set_labelErrorText(tr("VPN Protocols is not installed.\n Please install VPN container at first"));
set_pushButtonConnectChecked(false);
return;
@ -220,7 +220,7 @@ void VpnLogic::onConnect()
}
const QJsonObject &containerConfig = m_settings.containerConfig(serverIndex, container);
const QJsonObject &containerConfig = m_settings->containerConfig(serverIndex, container);
onConnectWorker(serverIndex, credentials, container, containerConfig);
}
@ -233,14 +233,6 @@ void VpnLogic::onConnectWorker(int serverIndex, const ServerCredentials &credent
qApp->processEvents();
emit connectToVpn(serverIndex, credentials, container, containerConfig);
// if (errorCode) {
// //ui->pushButton_connect->setChecked(false);
// uiLogic()->setDialogConnectErrorText(errorString(errorCode));
// emit uiLogic()->showConnectErrorDialog();
// return;
// }
}
void VpnLogic::onDisconnect()

View file

@ -55,9 +55,9 @@ void WizardLogic::onPushButtonVpnModeFinishClicked()
auto containers = getInstallConfigsFromWizardPage();
uiLogic()->installServer(containers);
if (checkBoxVpnModeChecked()) {
m_settings.setRouteMode(Settings::VpnOnlyForwardSites);
m_settings->setRouteMode(Settings::VpnOnlyForwardSites);
} else {
m_settings.setRouteMode(Settings::VpnAllSites);
m_settings->setRouteMode(Settings::VpnAllSites);
}
}

View file

@ -2,6 +2,7 @@
#define WIZARD_LOGIC_H
#include "PageLogicBase.h"
#include "containers/containers_defs.h"
class UiLogic;

View file

@ -52,10 +52,10 @@ QJsonObject CloakLogic::getProtocolConfigFromPage(QJsonObject oldConfig)
void CloakLogic::onPushButtonSaveClicked()
{
QJsonObject protocolConfig = m_settings.protocolConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, Proto::Cloak);
QJsonObject protocolConfig = m_settings->protocolConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, Proto::Cloak);
protocolConfig = getProtocolConfigFromPage(protocolConfig);
QJsonObject containerConfig = m_settings.containerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
QJsonObject containerConfig = m_settings->containerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
QJsonObject newContainerConfig = containerConfig;
newContainerConfig.insert(ProtocolProps::protoToString(Proto::Cloak), protocolConfig);
@ -89,14 +89,14 @@ void CloakLogic::onPushButtonSaveClicked()
};
ErrorCode e = uiLogic()->doInstallAction([this, containerConfig, &newContainerConfig](){
return ServerController::updateContainer(m_settings.serverCredentials(uiLogic()->selectedServerIndex), uiLogic()->selectedDockerContainer, containerConfig, newContainerConfig);
return m_serverController->updateContainer(m_settings->serverCredentials(uiLogic()->selectedServerIndex), uiLogic()->selectedDockerContainer, containerConfig, newContainerConfig);
},
page_func, progressBar_reset,
pushButton_save_func, label_info_func);
if (!e) {
m_settings.setContainerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, newContainerConfig);
m_settings.clearLastConnectionConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
m_settings->setContainerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, newContainerConfig);
m_settings->clearLastConnectionConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
}
qDebug() << "Protocol saved with code:" << e << "for" << uiLogic()->selectedServerIndex << uiLogic()->selectedDockerContainer;

View file

@ -32,7 +32,6 @@ public:
QJsonObject getProtocolConfigFromPage(QJsonObject oldConfig) override;
private:
Settings m_settings;
UiLogic *m_uiLogic;
};

View file

@ -81,10 +81,10 @@ void OpenVpnLogic::updateProtocolPage(const QJsonObject &openvpnConfig, DockerCo
void OpenVpnLogic::onPushButtonProtoOpenVpnSaveClicked()
{
QJsonObject protocolConfig = m_settings.protocolConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, Proto::OpenVpn);
QJsonObject protocolConfig = m_settings->protocolConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, Proto::OpenVpn);
protocolConfig = getProtocolConfigFromPage(protocolConfig);
QJsonObject containerConfig = m_settings.containerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
QJsonObject containerConfig = m_settings->containerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
QJsonObject newContainerConfig = containerConfig;
newContainerConfig.insert(ProtocolProps::protoToString(Proto::OpenVpn), protocolConfig);
@ -118,14 +118,14 @@ void OpenVpnLogic::onPushButtonProtoOpenVpnSaveClicked()
};
ErrorCode e = uiLogic()->doInstallAction([this, containerConfig, &newContainerConfig](){
return ServerController::updateContainer(m_settings.serverCredentials(uiLogic()->selectedServerIndex), uiLogic()->selectedDockerContainer, containerConfig, newContainerConfig);
return m_serverController->updateContainer(m_settings->serverCredentials(uiLogic()->selectedServerIndex), uiLogic()->selectedDockerContainer, containerConfig, newContainerConfig);
},
page_proto_openvpn, progressBar_proto_openvpn_reset,
pushButton_proto_openvpn_save, label_proto_openvpn_info);
if (!e) {
m_settings.setContainerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, newContainerConfig);
m_settings.clearLastConnectionConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
m_settings->setContainerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, newContainerConfig);
m_settings->clearLastConnectionConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
}
qDebug() << "Protocol saved with code:" << e << "for" << uiLogic()->selectedServerIndex << uiLogic()->selectedDockerContainer;
}

View file

@ -44,7 +44,6 @@ public:
QJsonObject getProtocolConfigFromPage(QJsonObject oldConfig) override;
private:
Settings m_settings;
UiLogic *m_uiLogic;
};

View file

@ -5,7 +5,6 @@
#include <QStandardPaths>
#include "OtherProtocolsLogic.h"
#include "core/servercontroller.h"
#include <functional>
#include "../../uilogic.h"
#include "utilities.h"
@ -82,7 +81,7 @@ void OtherProtocolsLogic::onPushButtonSftpMountDriveClicked()
{
QString mountPath;
QString cmd;
QString host = m_settings.serverCredentials(uiLogic()->selectedServerIndex).hostName;
QString host = m_settings->serverCredentials(uiLogic()->selectedServerIndex).hostName;
#ifdef Q_OS_WINDOWS

View file

@ -31,7 +31,6 @@ public:
//QJsonObject getProtocolConfigFromPage(QJsonObject oldConfig) override;
private:
Settings m_settings;
UiLogic *m_uiLogic;
#ifdef AMNEZIA_DESKTOP

View file

@ -46,10 +46,9 @@ QJsonObject ShadowSocksLogic::getProtocolConfigFromPage(QJsonObject oldConfig)
void ShadowSocksLogic::onPushButtonSaveClicked()
{
QJsonObject protocolConfig = m_settings.protocolConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, Proto::ShadowSocks);
//protocolConfig = getShadowSocksConfigFromPage(protocolConfig);
QJsonObject protocolConfig = m_settings->protocolConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, Proto::ShadowSocks);
QJsonObject containerConfig = m_settings.containerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
QJsonObject containerConfig = m_settings->containerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
QJsonObject newContainerConfig = containerConfig;
newContainerConfig.insert(ProtocolProps::protoToString(Proto::ShadowSocks), protocolConfig);
UiLogic::PageFunc page_proto_shadowsocks;
@ -82,14 +81,14 @@ void ShadowSocksLogic::onPushButtonSaveClicked()
};
ErrorCode e = uiLogic()->doInstallAction([this, containerConfig, &newContainerConfig](){
return ServerController::updateContainer(m_settings.serverCredentials(uiLogic()->selectedServerIndex), uiLogic()->selectedDockerContainer, containerConfig, newContainerConfig);
return m_serverController->updateContainer(m_settings->serverCredentials(uiLogic()->selectedServerIndex), uiLogic()->selectedDockerContainer, containerConfig, newContainerConfig);
},
page_proto_shadowsocks, progressBar_reset,
pushButton_proto_shadowsocks_save, label_proto_shadowsocks_info);
if (!e) {
m_settings.setContainerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, newContainerConfig);
m_settings.clearLastConnectionConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
m_settings->setContainerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, newContainerConfig);
m_settings->clearLastConnectionConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
}
qDebug() << "Protocol saved with code:" << e << "for" << uiLogic()->selectedServerIndex << uiLogic()->selectedDockerContainer;
}

View file

@ -30,7 +30,6 @@ public:
QJsonObject getProtocolConfigFromPage(QJsonObject oldConfig) override;
private:
Settings m_settings;
UiLogic *m_uiLogic;
};

View file

@ -14,7 +14,7 @@
} \
Q_SIGNAL void NAME ## Changed(TYPE value);\
private: \
TYPE m_ ## NAME;
TYPE m_ ## NAME{};
#define READONLY_PROPERTY(TYPE, NAME) \
Q_PROPERTY(TYPE NAME READ NAME CONSTANT ) \
@ -22,6 +22,6 @@
TYPE NAME() const { return m_ ## NAME ; } \
private: \
void NAME(TYPE value) {m_ ## NAME = value; } \
TYPE m_ ## NAME;
TYPE m_ ## NAME{};
#endif // PROPERTY_HELPER_H

View file

@ -107,7 +107,7 @@ PageBase {
BlueButtonType {
Layout.fillWidth: true
Layout.topMargin: 15
Layout.topMargin: 10
Layout.preferredHeight: 41
text: qsTr("Export logs")
onClicked: {
@ -117,7 +117,7 @@ PageBase {
BlueButtonType {
Layout.fillWidth: true
Layout.topMargin: 15
Layout.topMargin: 10
Layout.preferredHeight: 41
property string start_text: qsTr("Clear logs")
@ -135,6 +135,31 @@ PageBase {
AppSettingsLogic.onPushButtonClearLogsClicked()
}
}
LabelType {
Layout.fillWidth: true
Layout.topMargin: 30
text: qsTr("Backup and restore configuration")
}
BlueButtonType {
Layout.fillWidth: true
Layout.topMargin: 10
Layout.preferredHeight: 41
text: qsTr("Backup app config")
onClicked: {
AppSettingsLogic.onPushButtonBackupAppConfigClicked()
}
}
BlueButtonType {
Layout.fillWidth: true
Layout.topMargin: 10
Layout.preferredHeight: 41
text: qsTr("Restore app config")
onClicked: {
AppSettingsLogic.onPushButtonRestoreAppConfigClicked()
}
}
}
}

View file

@ -87,7 +87,7 @@ If AmneziaDNS service is not installed on the same server, or this option is unc
anchors.topMargin: 20
width: parent.width - 60
height: 21
text: qsTr("Secondray DNS server")
text: qsTr("Secondary DNS server")
}
TextFieldType {
id: dns2

View file

@ -1,462 +1,439 @@
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Dialogs 1.1
import QtQuick.Layouts 1.15
import SortFilterProxyModel 0.2
import ContainerProps 1.0
import ProtocolProps 1.0
import PageEnum 1.0
import ProtocolEnum 1.0
import "./"
import "../Controls"
import "../Config"
import "InstallSettings"
PageBase {
id: root
page: PageEnum.ServerContainers
logic: ServerContainersLogic
enabled: ServerContainersLogic.pageEnabled
function resetPage() {
container_selector.selectedIndex = -1
}
Connections {
target: logic
function onUpdatePage() {
root.resetPage()
}
}
BackButton {
id: back
}
Caption {
id: caption
text: container_selector.selectedIndex > 0 ? qsTr("Install new service") : qsTr("Installed services")
}
SelectContainer {
id: container_selector
onAboutToHide: {
pageLoader.focus = true
}
onContainerSelected: {
var containerProto = ContainerProps.defaultProtocol(c_index)
if (ProtocolProps.defaultPort(containerProto) < 0) {
tf_port_num.enabled = false
tf_port_num.text = qsTr("Default")
}
else tf_port_num.text = ProtocolProps.defaultPort(containerProto)
cb_port_proto.currentIndex = ProtocolProps.defaultTransportProto(containerProto)
tf_port_num.enabled = ProtocolProps.defaultPortChangeable(containerProto)
cb_port_proto.enabled = ProtocolProps.defaultTransportProtoChangeable(containerProto)
}
}
Column {
id: c1
visible: container_selector.selectedIndex > 0
width: parent.width
anchors.top: caption.bottom
anchors.topMargin: 10
Caption {
font.pixelSize: 22
text: UiLogic.containerName(container_selector.selectedIndex)
}
Text {
width: parent.width
anchors.topMargin: 10
padding: 10
font.family: "Lato"
font.styleName: "normal"
font.pixelSize: 16
color: "#181922"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
wrapMode: Text.Wrap
text: UiLogic.containerDesc(container_selector.selectedIndex)
}
}
Rectangle {
id: frame_settings
visible: container_selector.selectedIndex > 0
width: parent.width
anchors.top: c1.bottom
anchors.topMargin: 10
border.width: 1
border.color: "lightgray"
anchors.bottomMargin: 5
anchors.horizontalCenter: parent.horizontalCenter
radius: 2
Grid {
id: grid
visible: container_selector.selectedIndex > 0
anchors.fill: parent
columns: 2
horizontalItemAlignment: Grid.AlignHCenter
verticalItemAlignment: Grid.AlignVCenter
topPadding: 5
leftPadding: 10
spacing: 5
LabelType {
width: 130
text: qsTr("Port")
}
TextFieldType {
id: tf_port_num
width: parent.width - 130 - parent.spacing - parent.leftPadding * 2
}
LabelType {
width: 130
text: qsTr("Network Protocol")
}
ComboBoxType {
id: cb_port_proto
width: parent.width - 130 - parent.spacing - parent.leftPadding * 2
model: [
qsTr("udp"),
qsTr("tcp"),
]
}
}
}
BlueButtonType {
id: pb_cancel_add
visible: container_selector.selectedIndex > 0
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: pb_continue_add.top
anchors.bottomMargin: 20
width: parent.width - 40
height: 40
text: qsTr("Cancel")
font.pixelSize: 16
onClicked: container_selector.selectedIndex = -1
}
BlueButtonType {
id: pb_continue_add
visible: container_selector.selectedIndex > 0
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: 20
width: parent.width - 40
height: 40
text: qsTr("Continue")
font.pixelSize: 16
onClicked: {
let cont = container_selector.selectedIndex
let tp = ProtocolProps.transportProtoFromString(cb_port_proto.currentText)
let port = tf_port_num.text
ServerContainersLogic.onPushButtonContinueClicked(cont, port, tp)
}
}
Flickable {
visible: container_selector.selectedIndex <= 0
clip: true
width: parent.width
anchors.top: caption.bottom
anchors.bottom: pb_add_container.top
contentHeight: col.height
Column {
visible: container_selector.selectedIndex <= 0
id: col
anchors {
left: parent.left;
right: parent.right;
}
topPadding: 20
spacing: 10
Caption {
id: cap1
text: qsTr("Installed Protocols and Services")
font.pixelSize: 20
}
SortFilterProxyModel {
id: proxyContainersModel
sourceModel: UiLogic.containersModel
filters: ValueFilter {
roleName: "is_installed_role"
value: true
}
}
SortFilterProxyModel {
id: proxyProtocolsModel
sourceModel: UiLogic.protocolsModel
filters: ValueFilter {
roleName: "is_installed_role"
value: true
}
}
ListView {
id: tb_c
x: 10
width: parent.width - 10
height: tb_c.contentItem.height
currentIndex: -1
spacing: 5
clip: true
interactive: false
model: proxyContainersModel
delegate: Item {
implicitWidth: tb_c.width - 10
implicitHeight: c_item.height
Item {
id: c_item
width: parent.width
height: row_container.height + tb_p.height
anchors.left: parent.left
Rectangle {
anchors.top: parent.top
width: parent.width
height: 1
color: "lightgray"
visible: index !== tb_c.currentIndex
}
Rectangle {
anchors.top: row_container.top
anchors.bottom: row_container.bottom
anchors.left: parent.left
anchors.right: parent.right
color: "#63B4FB"
visible: index === tb_c.currentIndex
}
RowLayout {
id: row_container
//width: parent.width
anchors.left: parent.left
anchors.right: parent.right
// anchors.top: lb_container_name.top
// anchors.bottom: lb_container_name.bottom
Text {
id: lb_container_name
text: name_role
font.pixelSize: 17
//font.bold: true
color: "#100A44"
topPadding: 5
bottomPadding: 5
leftPadding: 10
verticalAlignment: Text.AlignVCenter
wrapMode: Text.WordWrap
Layout.fillWidth: true
MouseArea {
enabled: col.visible
anchors.top: lb_container_name.top
anchors.bottom: lb_container_name.bottom
anchors.left: parent.left
anchors.right: parent.right
propagateComposedEvents: true
onClicked: {
if (tb_c.currentIndex === index) tb_c.currentIndex = -1
else tb_c.currentIndex = index
UiLogic.protocolsModel.setSelectedDockerContainer(proxyContainersModel.mapToSource(index))
}
}
}
ImageButtonType {
id: button_remove
visible: index === tb_c.currentIndex
Layout.alignment: Qt.AlignRight
checkable: true
icon.source: "qrc:/images/delete.png"
implicitWidth: 30
implicitHeight: 30
checked: default_role
MessageDialog {
id: dialogRemove
standardButtons: StandardButton.Yes | StandardButton.Cancel
title: "AmneziaVPN"
text: qsTr("Remove container") + " " + name_role + "?" + "\n" + qsTr("This action will erase all data of this container on the server.")
onAccepted: {
tb_c.currentIndex = -1
ServerContainersLogic.onPushButtonRemoveClicked(proxyContainersModel.mapToSource(index))
}
}
onClicked: dialogRemove.open()
VisibleBehavior on visible { }
}
ImageButtonType {
id: button_share
visible: index === tb_c.currentIndex
Layout.alignment: Qt.AlignRight
icon.source: "qrc:/images/share.png"
implicitWidth: 30
implicitHeight: 30
onClicked: {
ServerContainersLogic.onPushButtonShareClicked(proxyContainersModel.mapToSource(index))
}
VisibleBehavior on visible { }
}
ImageButtonType {
id: button_default
visible: service_type_role == ProtocolEnum.Vpn
Layout.alignment: Qt.AlignRight
checkable: true
img.source: checked ? "qrc:/images/check.png" : "qrc:/images/uncheck.png"
implicitWidth: 30
implicitHeight: 30
checked: default_role
onClicked: {
ServerContainersLogic.onPushButtonDefaultClicked(proxyContainersModel.mapToSource(index))
}
}
}
ListView {
id: tb_p
currentIndex: -1
visible: index === tb_c.currentIndex
x: 10
anchors.top: row_container.bottom
width: parent.width - 40
height: visible ? tb_p.contentItem.height : 0
spacing: 0
clip: true
interactive: false
model: proxyProtocolsModel
VisibleBehavior on visible { }
delegate: Item {
id: dp_item
implicitWidth: tb_p.width - 10
implicitHeight: p_item.height
Item {
id: p_item
width: parent.width
height: lb_protocol_name.height
anchors.left: parent.left
Rectangle {
anchors.top: parent.top
width: parent.width
height: 1
color: "lightgray"
visible: index !== tb_p.currentIndex
}
// Rectangle {
// anchors.top: lb_protocol_name.top
// anchors.bottom: lb_protocol_name.bottom
// width: parent.width
// color: "#63B4FB"
// visible: index === tb_p.currentIndex
// }
// Text {
// id: lb_protocol_name
// text: name_role
// font.pixelSize: 16
// topPadding: 5
// bottomPadding: 5
// leftPadding: 10
// verticalAlignment: Text.AlignVCenter
// wrapMode: Text.WordWrap
// }
SettingButtonType {
id: lb_protocol_name
// anchors.top: lb_protocol_name.top
// anchors.bottom: lb_protocol_name.bottom
topPadding: 10
bottomPadding: 10
leftPadding: 10
anchors.left: parent.left
width: parent.width
height: 30
text: qsTr(name_role + " settings")
textItem.font.pixelSize: 16
icon.source: "qrc:/images/settings.png"
onClicked: {
tb_p.currentIndex = index
ServerContainersLogic.onPushButtonProtoSettingsClicked(
proxyContainersModel.mapToSource(tb_c.currentIndex),
proxyProtocolsModel.mapToSource(tb_p.currentIndex))
}
}
}
}
}
}
}
}
}
}
BlueButtonType {
id: pb_add_container
visible: container_selector.selectedIndex < 0
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.topMargin: 10
anchors.bottomMargin: 20
width: parent.width - 40
height: 40
text: qsTr("Install new protocols container")
font.pixelSize: 16
onClicked: container_selector.visible ? container_selector.close() : container_selector.open()
}
}
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Dialogs 1.1
import QtQuick.Layouts 1.15
import SortFilterProxyModel 0.2
import ContainerProps 1.0
import ProtocolProps 1.0
import PageEnum 1.0
import ProtocolEnum 1.0
import "./"
import "../Controls"
import "../Config"
import "InstallSettings"
PageBase {
id: root
page: PageEnum.ServerContainers
logic: ServerContainersLogic
enabled: ServerContainersLogic.pageEnabled
function resetPage() {
container_selector.selectedIndex = -1
}
Connections {
target: logic
function onUpdatePage() {
root.resetPage()
}
}
BackButton {
id: back
}
Caption {
id: caption
text: container_selector.selectedIndex > 0 ? qsTr("Install new service") : qsTr("Installed services")
}
SelectContainer {
id: container_selector
onAboutToHide: {
pageLoader.focus = true
}
onContainerSelected: {
var containerProto = ContainerProps.defaultProtocol(c_index)
if (ProtocolProps.defaultPort(containerProto) < 0) {
tf_port_num.enabled = false
tf_port_num.text = qsTr("Default")
}
else tf_port_num.text = ProtocolProps.defaultPort(containerProto)
cb_port_proto.currentIndex = ProtocolProps.defaultTransportProto(containerProto)
tf_port_num.enabled = ProtocolProps.defaultPortChangeable(containerProto)
cb_port_proto.enabled = ProtocolProps.defaultTransportProtoChangeable(containerProto)
}
}
Column {
id: c1
visible: container_selector.selectedIndex > 0
width: parent.width
anchors.top: caption.bottom
anchors.topMargin: 10
Caption {
font.pixelSize: 22
text: UiLogic.containerName(container_selector.selectedIndex)
}
Text {
width: parent.width
anchors.topMargin: 10
padding: 10
font.family: "Lato"
font.styleName: "normal"
font.pixelSize: 16
color: "#181922"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
wrapMode: Text.Wrap
text: UiLogic.containerDesc(container_selector.selectedIndex)
}
}
Rectangle {
id: frame_settings
visible: container_selector.selectedIndex > 0
width: parent.width
anchors.top: c1.bottom
anchors.topMargin: 10
border.width: 1
border.color: "lightgray"
anchors.bottomMargin: 5
anchors.horizontalCenter: parent.horizontalCenter
radius: 2
Grid {
id: grid
visible: container_selector.selectedIndex > 0
anchors.fill: parent
columns: 2
horizontalItemAlignment: Grid.AlignHCenter
verticalItemAlignment: Grid.AlignVCenter
topPadding: 5
leftPadding: 10
spacing: 5
LabelType {
width: 130
text: qsTr("Port")
}
TextFieldType {
id: tf_port_num
width: parent.width - 130 - parent.spacing - parent.leftPadding * 2
}
LabelType {
width: 130
text: qsTr("Network Protocol")
}
ComboBoxType {
id: cb_port_proto
width: parent.width - 130 - parent.spacing - parent.leftPadding * 2
model: [
qsTr("udp"),
qsTr("tcp"),
]
}
}
}
BlueButtonType {
id: pb_cancel_add
visible: container_selector.selectedIndex > 0
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: pb_continue_add.top
anchors.bottomMargin: 20
width: parent.width - 40
height: 40
text: qsTr("Cancel")
font.pixelSize: 16
onClicked: container_selector.selectedIndex = -1
}
BlueButtonType {
id: pb_continue_add
visible: container_selector.selectedIndex > 0
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: 20
width: parent.width - 40
height: 40
text: qsTr("Continue")
font.pixelSize: 16
onClicked: {
let cont = container_selector.selectedIndex
let tp = ProtocolProps.transportProtoFromString(cb_port_proto.currentText)
let port = tf_port_num.text
ServerContainersLogic.onPushButtonContinueClicked(cont, port, tp)
}
}
Flickable {
visible: container_selector.selectedIndex <= 0
clip: true
width: parent.width
anchors.top: caption.bottom
anchors.bottom: pb_add_container.top
contentHeight: col.height
Column {
visible: container_selector.selectedIndex <= 0
id: col
anchors {
left: parent.left;
right: parent.right;
}
topPadding: 20
spacing: 10
Caption {
id: cap1
text: qsTr("Installed Protocols and Services")
font.pixelSize: 20
}
SortFilterProxyModel {
id: proxyContainersModel
sourceModel: UiLogic.containersModel
filters: ValueFilter {
roleName: "is_installed_role"
value: true
}
}
SortFilterProxyModel {
id: proxyProtocolsModel
sourceModel: UiLogic.protocolsModel
filters: ValueFilter {
roleName: "is_installed_role"
value: true
}
}
ListView {
id: tb_c
x: 10
width: parent.width - 10
height: tb_c.contentItem.height
currentIndex: -1
spacing: 5
clip: true
interactive: false
model: proxyContainersModel
delegate: Item {
implicitWidth: tb_c.width - 10
implicitHeight: c_item.height
Item {
id: c_item
width: parent.width
height: row_container.height + tb_p.height
anchors.left: parent.left
Rectangle {
anchors.top: parent.top
width: parent.width
height: 1
color: "lightgray"
visible: index !== tb_c.currentIndex
}
Rectangle {
anchors.top: row_container.top
anchors.bottom: row_container.bottom
anchors.left: parent.left
anchors.right: parent.right
color: "#63B4FB"
visible: index === tb_c.currentIndex
}
RowLayout {
id: row_container
anchors.left: parent.left
anchors.right: parent.right
Text {
id: lb_container_name
text: name_role
font.pixelSize: 17
color: "#100A44"
topPadding: 16
bottomPadding: 12
leftPadding: 10
verticalAlignment: Text.AlignVCenter
wrapMode: Text.WordWrap
Layout.fillWidth: true
MouseArea {
enabled: col.visible
anchors.top: lb_container_name.top
anchors.bottom: lb_container_name.bottom
anchors.left: parent.left
anchors.right: parent.right
propagateComposedEvents: true
onClicked: {
if (tb_c.currentIndex === index) tb_c.currentIndex = -1
else tb_c.currentIndex = index
UiLogic.protocolsModel.setSelectedDockerContainer(proxyContainersModel.mapToSource(index))
}
}
}
ImageButtonType {
id: button_remove
visible: index === tb_c.currentIndex
Layout.alignment: Qt.AlignRight
checkable: true
icon.source: "qrc:/images/delete.png"
implicitWidth: 30
implicitHeight: 30
checked: default_role
MessageDialog {
id: dialogRemove
standardButtons: StandardButton.Yes | StandardButton.Cancel
title: "AmneziaVPN"
text: qsTr("Remove container") + " " + name_role + "?" + "\n" + qsTr("This action will erase all data of this container on the server.")
onAccepted: {
tb_c.currentIndex = -1
ServerContainersLogic.onPushButtonRemoveClicked(proxyContainersModel.mapToSource(index))
}
}
onClicked: dialogRemove.open()
VisibleBehavior on visible { }
}
ImageButtonType {
id: button_share
visible: index === tb_c.currentIndex
Layout.alignment: Qt.AlignRight
icon.source: "qrc:/images/share.png"
implicitWidth: 30
implicitHeight: 30
onClicked: {
ServerContainersLogic.onPushButtonShareClicked(proxyContainersModel.mapToSource(index))
}
VisibleBehavior on visible { }
}
ImageButtonType {
id: button_default
visible: service_type_role == ProtocolEnum.Vpn
Layout.alignment: Qt.AlignRight
checkable: true
img.source: checked ? "qrc:/images/check.png" : "qrc:/images/uncheck.png"
implicitWidth: 30
implicitHeight: 30
checked: default_role
onClicked: {
ServerContainersLogic.onPushButtonDefaultClicked(proxyContainersModel.mapToSource(index))
}
}
}
ListView {
id: tb_p
currentIndex: -1
x: 10
anchors.top: row_container.bottom
width: parent.width - 40
height: index === tb_c.currentIndex ? tb_p.contentItem.height : 0
implicitHeight: height
spacing: 0
clip: true
interactive: false
model: proxyProtocolsModel
Behavior on height {
NumberAnimation {
duration: 200
}
}
delegate: Item {
id: dp_item
implicitWidth: tb_p.width - 10
implicitHeight: p_item.height
Item {
id: p_item
width: parent.width
height: lb_protocol_name.height
anchors.left: parent.left
Rectangle {
anchors.top: parent.top
width: parent.width
height: 1
color: "lightgray"
visible: index > 0
}
SettingButtonType {
id: lb_protocol_name
topPadding: 10
bottomPadding: 10
anchors.left: parent.left
anchors.leftMargin: 10
width: parent.width
height: 45
text: qsTr(name_role + " settings")
textItem.font.pixelSize: 16
icon.source: "qrc:/images/settings.png"
onClicked: {
tb_p.currentIndex = index
ServerContainersLogic.onPushButtonProtoSettingsClicked(
proxyContainersModel.mapToSource(tb_c.currentIndex),
proxyProtocolsModel.mapToSource(tb_p.currentIndex))
}
}
}
}
}
}
}
}
}
}
BlueButtonType {
id: pb_add_container
visible: container_selector.selectedIndex < 0
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.topMargin: 10
anchors.bottomMargin: 20
width: parent.width - 40
height: 40
text: qsTr("Install new protocols container")
font.pixelSize: 16
onClicked: container_selector.visible ? container_selector.close() : container_selector.open()
}
}

View file

@ -59,7 +59,7 @@ PageBase {
text: qsTr("Share for Amnezia")
height: 40
width: tb_c.width - 10
onClicked: UiLogic.onGotoShareProtocolPage(ProtocolEnum.Any)
onClicked: UiLogic.goToShareProtocolPage(ProtocolEnum.Any)
}
ListView {
@ -82,7 +82,7 @@ PageBase {
text: qsTr("Share for ") + name_role
height: 40
width: tb_c.width - 10
onClicked: UiLogic.onGotoShareProtocolPage(proxyProtocolsModel.mapToSource(index))
onClicked: UiLogic.goToShareProtocolPage(proxyProtocolsModel.mapToSource(index))
}
}
}

View file

@ -119,7 +119,6 @@ PageBase {
anchors.topMargin: 40
text: qsTr("Open file")
visible: StartPageLogic.pushButtonConnectVisible
onClicked: {
StartPageLogic.onPushButtonImportOpenFile()
}
@ -128,12 +127,12 @@ PageBase {
BlueButtonType {
id: qr_code_import
visible: GC.isMobile()
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: qr_code_import_open.bottom
anchors.topMargin: 10
text: qsTr("Scan QR code")
visible: StartPageLogic.pushButtonConnectVisible
onClicked: {
if (Qt.platform.os == "ios") {
UiLogic.goToPage(PageEnum.QrDecoderIos)
@ -144,7 +143,19 @@ PageBase {
enabled: StartPageLogic.pushButtonConnectEnabled
}
BlueButtonType {
id: btn_restore_cfg
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: qr_code_import.bottom
anchors.topMargin: 30
visible: UiLogic.pagesStackDepth == 1
enabled: StartPageLogic.pushButtonConnectEnabled
text: qsTr("Restore app config")
onClicked: {
AppSettingsLogic.onPushButtonRestoreAppConfigClicked()
}
}
}
@ -270,7 +281,6 @@ PageBase {
anchors.topMargin: 10
text: StartPageLogic.pushButtonConnectText
visible: StartPageLogic.pushButtonConnectVisible
onClicked: {
StartPageLogic.onPushButtonConnect()
}

View file

@ -0,0 +1,148 @@
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.15
import PageEnum 1.0
import "./"
import "../Controls"
import "../Config"
PageBase {
id: root
page: PageEnum.ViewConfig
logic: ViewConfigLogic
readonly property double rowHeight: ta_last_config.contentHeight / ta_last_config.textArea.lineCount
BackButton {}
Caption {
id: caption
text: qsTr("Check config")
}
Flickable {
id: fl
width: root.width
anchors.top: caption.bottom
anchors.topMargin: 20
anchors.bottom: root.bottom
anchors.bottomMargin: 20
anchors.left: root.left
anchors.leftMargin: 30
anchors.right: root.right
anchors.rightMargin: 30
contentHeight: content.height
clip: true
ColumnLayout {
id: content
enabled: logic.pageEnabled
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
TextAreaType {
id: ta_config
Layout.topMargin: 5
Layout.bottomMargin: 20
Layout.fillWidth: true
Layout.leftMargin: 1
Layout.rightMargin: 1
Layout.preferredHeight: ViewConfigLogic.warningActive ? 250 : fl.height - 70
flickableDirection: Flickable.AutoFlickIfNeeded
textArea.readOnly: true
textArea.text: logic.configText
}
LabelType {
id: lb_att
visible: ViewConfigLogic.warningActive
text: qsTr("Attention!
The config above contains cached OpenVPN connection profile.
AmneziaVPN detected this profile may contain malicious scripts. Please, carefully review the config and import this config only if you completely trust it.")
Layout.fillWidth: true
}
LabelType {
visible: ViewConfigLogic.warningActive
text: qsTr("Suspicious string:")
Layout.fillWidth: true
}
TextAreaType {
id: ta_mal
visible: ViewConfigLogic.warningActive
Layout.topMargin: 5
Layout.bottomMargin: 20
Layout.fillWidth: true
Layout.leftMargin: 1
Layout.rightMargin: 1
Layout.preferredHeight: 60
flickableDirection: Flickable.AutoFlickIfNeeded
textArea.readOnly: true
textArea.text: logic.openVpnMalStrings
textArea.textFormat: TextEdit.RichText
}
LabelType {
visible: ViewConfigLogic.warningActive
text: qsTr("Cached connection profile:")
Layout.fillWidth: true
}
TextAreaType {
id: ta_last_config
visible: ViewConfigLogic.warningActive
Layout.topMargin: 5
Layout.bottomMargin: 20
Layout.fillWidth: true
Layout.leftMargin: 1
Layout.rightMargin: 1
Layout.preferredHeight: 350
flickableDirection: Flickable.AutoFlickIfNeeded
textArea.readOnly: true
textArea.text: logic.openVpnLastConfigs
textArea.textFormat: TextEdit.RichText
Connections {
target: logic
function onWarningStringNumberChanged(n) {
ta_last_config.contentY = rowHeight * n - ta_last_config.height / 2
}
}
}
RowLayout {
id: btns_row
BasicButtonType {
Layout.preferredWidth: (content.width - parent.spacing) /2
Layout.preferredHeight: 41
font.pixelSize: btn_import.font.pixelSize
text: qsTr("Cancel")
onClicked: {
UiLogic.closePage()
}
}
BlueButtonType {
id: btn_import
Layout.preferredWidth: (content.width - parent.spacing) /2
Layout.preferredHeight: 41
text: qsTr("Import config")
onClicked: {
logic.importConfig()
}
}
}
}
}
}

View file

@ -75,7 +75,6 @@ void SystemTrayNotificationHandler::onTrayActivated(QSystemTrayIcon::ActivationR
void SystemTrayNotificationHandler::setTrayState(VpnProtocol::VpnConnectionState state)
{
qDebug() << "SystemTrayNotificationHandler::setTrayState" << state;
QString resourcesPath = ":/images/tray/%1";
switch (state) {

View file

@ -4,7 +4,6 @@
#include <QDesktopServices>
#include <QFile>
#include <QFileDialog>
#include <QHBoxLayout>
#include <QHostInfo>
#include <QItemSelectionModel>
#include <QJsonDocument>
@ -16,9 +15,11 @@
#include <QSysInfo>
#include <QThread>
#include <QTimer>
#include <QRegularExpression>
#include <QQmlFile>
#include <QStandardPaths>
#include <QMetaObject>
#include "amnezia_application.h"
#include "configurators/cloak_configurator.h"
#include "configurators/vpn_configurator.h"
#include "configurators/openvpn_configurator.h"
@ -62,6 +63,7 @@
#include "pages_logic/ShareConnectionLogic.h"
#include "pages_logic/SitesLogic.h"
#include "pages_logic/StartPageLogic.h"
#include "pages_logic/ViewConfigLogic.h"
#include "pages_logic/VpnLogic.h"
#include "pages_logic/WizardLogic.h"
@ -74,30 +76,20 @@
using namespace amnezia;
using namespace PageEnumNS;
UiLogic::UiLogic(QObject *parent) :
UiLogic::UiLogic(std::shared_ptr<Settings> settings, std::shared_ptr<VpnConfigurator> configurator,
std::shared_ptr<ServerController> serverController,
QObject *parent) :
QObject(parent),
m_dialogConnectErrorText{}
m_settings(settings),
m_configurator(configurator),
m_serverController(serverController)
{
m_containersModel = new ContainersModel(this);
m_protocolsModel = new ProtocolsModel(this);
m_vpnConnection = new VpnConnection();
m_containersModel = new ContainersModel(settings, this);
m_protocolsModel = new ProtocolsModel(settings, this);
m_vpnConnection = new VpnConnection(settings, configurator, serverController);
m_vpnConnection->moveToThread(&m_vpnConnectionThread);
m_vpnConnectionThread.start();
m_appSettingsLogic = new AppSettingsLogic(this);
m_generalSettingsLogic = new GeneralSettingsLogic(this);
m_networkSettingsLogic = new NetworkSettingsLogic(this);
m_newServerProtocolsLogic = new NewServerProtocolsLogic(this);
m_qrDecoderLogic = new QrDecoderLogic(this);
m_serverConfiguringProgressLogic = new ServerConfiguringProgressLogic(this);
m_serverListLogic = new ServerListLogic(this);
m_serverSettingsLogic = new ServerSettingsLogic(this);
m_serverprotocolsLogic = new ServerContainersLogic(this);
m_shareConnectionLogic = new ShareConnectionLogic(this);
m_sitesLogic = new SitesLogic(this);
m_startPageLogic = new StartPageLogic(this);
m_vpnLogic = new VpnLogic(this);
m_wizardLogic = new WizardLogic(this);
m_protocolLogicMap.insert(Proto::OpenVpn, new OpenVpnLogic(this));
m_protocolLogicMap.insert(Proto::ShadowSocks, new ShadowSocksLogic(this));
@ -139,55 +131,40 @@ void UiLogic::initalizeUiLogic()
#ifdef Q_OS_ANDROID
connect(AndroidController::instance(), &AndroidController::initialized, [this](bool status, bool connected, const QDateTime& connectionDate) {
if (connected) {
vpnLogic()->onConnectionStateChanged(VpnProtocol::Connected);
pageLogic<VpnLogic>()->onConnectionStateChanged(VpnProtocol::Connected);
}
});
if (!AndroidController::instance()->initialize()) {
qDebug() << QString("Init failed") ;
qCritical() << QString("Init failed") ;
emit VpnProtocol::Error;
return;
}
#endif
qDebug() << "UiLogic::initalizeUiLogic()";
m_notificationHandler = NotificationHandler::create(qmlRoot());
connect(m_vpnConnection, &VpnConnection::connectionStateChanged, m_notificationHandler, &NotificationHandler::setConnectionState);
connect(m_notificationHandler, &NotificationHandler::raiseRequested, this, &UiLogic::raise);
connect(m_notificationHandler, &NotificationHandler::connectRequested, vpnLogic(), &VpnLogic::onConnect);
connect(m_notificationHandler, &NotificationHandler::disconnectRequested, vpnLogic(), &VpnLogic::onDisconnect);
connect(m_notificationHandler, &NotificationHandler::connectRequested, pageLogic<VpnLogic>(), &VpnLogic::onConnect);
connect(m_notificationHandler, &NotificationHandler::disconnectRequested, pageLogic<VpnLogic>(), &VpnLogic::onDisconnect);
if (m_settings.serversCount() > 0) {
if (m_settings.defaultServerIndex() < 0) m_settings.setDefaultServer(0);
if (m_settings->serversCount() > 0) {
if (m_settings->defaultServerIndex() < 0) m_settings->setDefaultServer(0);
emit goToPage(Page::Vpn, true, false);
}
else {
emit goToPage(Page::Start, true, false);
}
selectedServerIndex = m_settings.defaultServerIndex();
selectedServerIndex = m_settings->defaultServerIndex();
qInfo().noquote() << QString("Started %1 version %2").arg(APPLICATION_NAME).arg(APP_VERSION);
qInfo().noquote() << QString("%1 (%2)").arg(QSysInfo::prettyProductName()).arg(QSysInfo::currentCpuArchitecture());
}
QString UiLogic::getDialogConnectErrorText() const
{
return m_dialogConnectErrorText;
}
void UiLogic::setDialogConnectErrorText(const QString &dialogConnectErrorText)
{
if (m_dialogConnectErrorText != dialogConnectErrorText) {
m_dialogConnectErrorText = dialogConnectErrorText;
emit dialogConnectErrorTextChanged();
}
}
void UiLogic::showOnStartup()
{
if (! m_settings.isStartMinimized()) {
if (! m_settings->isStartMinimized()) {
emit show();
}
else {
@ -201,21 +178,7 @@ void UiLogic::showOnStartup()
void UiLogic::onUpdateAllPages()
{
for (PageLogicBase *logic : {
(PageLogicBase *) m_appSettingsLogic,
(PageLogicBase *) m_generalSettingsLogic,
(PageLogicBase *) m_networkSettingsLogic,
(PageLogicBase *) m_serverConfiguringProgressLogic,
(PageLogicBase *) m_newServerProtocolsLogic,
(PageLogicBase *) m_serverListLogic,
(PageLogicBase *) m_serverSettingsLogic,
(PageLogicBase *) m_serverprotocolsLogic,
(PageLogicBase *) m_shareConnectionLogic,
(PageLogicBase *) m_sitesLogic,
(PageLogicBase *) m_startPageLogic,
(PageLogicBase *) m_vpnLogic,
(PageLogicBase *) m_wizardLogic
}) {
for (auto logic : m_logicMap) {
logic->onUpdatePage();
}
}
@ -235,30 +198,29 @@ void UiLogic::keyPressEvent(Qt::Key key)
qApp->quit();
break;
case Qt::Key_H:
selectedServerIndex = m_settings.defaultServerIndex();
selectedDockerContainer = m_settings.defaultContainer(selectedServerIndex);
selectedServerIndex = m_settings->defaultServerIndex();
selectedDockerContainer = m_settings->defaultContainer(selectedServerIndex);
//updateSharingPage(selectedServerIndex, m_settings.serverCredentials(selectedServerIndex), selectedDockerContainer);
//updateSharingPage(selectedServerIndex, m_settings->serverCredentials(selectedServerIndex), selectedDockerContainer);
emit goToPage(Page::ShareConnection);
break;
#endif
case Qt::Key_C:
qDebug().noquote() << "Def server" << m_settings.defaultServerIndex() << m_settings.defaultContainerName(m_settings.defaultServerIndex());
//qDebug().noquote() << QJsonDocument(m_settings.containerConfig(m_settings.defaultServerIndex(), m_settings.defaultContainer(m_settings.defaultServerIndex()))).toJson();
qDebug().noquote() << QJsonDocument(m_settings.defaultServer()).toJson();
qDebug().noquote() << "Def server" << m_settings->defaultServerIndex() << m_settings->defaultContainerName(m_settings->defaultServerIndex());
qDebug().noquote() << QJsonDocument(m_settings->defaultServer()).toJson();
break;
case Qt::Key_A:
emit goToPage(Page::Start);
break;
case Qt::Key_S:
selectedServerIndex = m_settings.defaultServerIndex();
selectedServerIndex = m_settings->defaultServerIndex();
emit goToPage(Page::ServerSettings);
break;
case Qt::Key_P:
onGotoCurrentProtocolsPage();
break;
case Qt::Key_T:
SshConfigurator::openSshTerminal(m_settings.serverCredentials(m_settings.defaultServerIndex()));
m_configurator->sshConfigurator->openSshTerminal(m_settings->serverCredentials(m_settings->defaultServerIndex()));
break;
case Qt::Key_Escape:
case Qt::Key_Back:
@ -280,7 +242,7 @@ void UiLogic::keyPressEvent(Qt::Key key)
void UiLogic::onCloseWindow()
{
if (m_settings.serversCount() == 0) qApp->quit();
if (m_settings->serversCount() == 0) qApp->quit();
else {
hide();
}
@ -299,8 +261,8 @@ QString UiLogic::containerDesc(int container)
void UiLogic::onGotoCurrentProtocolsPage()
{
selectedServerIndex = m_settings.defaultServerIndex();
selectedDockerContainer = m_settings.defaultContainer(selectedServerIndex);
selectedServerIndex = m_settings->defaultServerIndex();
selectedDockerContainer = m_settings->defaultContainer(selectedServerIndex);
emit goToPage(Page::ServerContainers);
}
@ -344,34 +306,34 @@ void UiLogic::installServer(QMap<DockerContainer, QJsonObject> &containers)
PageFunc page_new_server_configuring;
page_new_server_configuring.setEnabledFunc = [this] (bool enabled) -> void {
serverConfiguringProgressLogic()->set_pageEnabled(enabled);
pageLogic<ServerConfiguringProgressLogic>()->set_pageEnabled(enabled);
};
ButtonFunc no_button;
LabelFunc label_new_server_configuring_wait_info;
label_new_server_configuring_wait_info.setTextFunc = [this] (const QString& text) -> void {
serverConfiguringProgressLogic()->set_labelWaitInfoText(text);
pageLogic<ServerConfiguringProgressLogic>()->set_labelWaitInfoText(text);
};
label_new_server_configuring_wait_info.setVisibleFunc = [this] (bool visible) ->void {
serverConfiguringProgressLogic()->set_labelWaitInfoVisible(visible);
pageLogic<ServerConfiguringProgressLogic>()->set_labelWaitInfoVisible(visible);
};
ProgressFunc progressBar_new_server_configuring;
progressBar_new_server_configuring.setVisibleFunc = [this] (bool visible) ->void {
serverConfiguringProgressLogic()->set_progressBarVisible(visible);
pageLogic<ServerConfiguringProgressLogic>()->set_progressBarVisible(visible);
};
progressBar_new_server_configuring.setValueFunc = [this] (int value) ->void {
serverConfiguringProgressLogic()->set_progressBarValue(value);
pageLogic<ServerConfiguringProgressLogic>()->set_progressBarValue(value);
};
progressBar_new_server_configuring.getValueFunc = [this] (void) -> int {
return serverConfiguringProgressLogic()->progressBarValue();
return pageLogic<ServerConfiguringProgressLogic>()->progressBarValue();
};
progressBar_new_server_configuring.getMaximiumFunc = [this] (void) -> int {
return serverConfiguringProgressLogic()->progressBarMaximium();
return pageLogic<ServerConfiguringProgressLogic>()->progressBarMaximium();
};
progressBar_new_server_configuring.setTextVisibleFunc = [this] (bool visible) ->void {
serverConfiguringProgressLogic()->set_progressBarTextVisible(visible);
pageLogic<ServerConfiguringProgressLogic>()->set_progressBarTextVisible(visible);
};
progressBar_new_server_configuring.setTextFunc = [this] (const QString& text) ->void {
serverConfiguringProgressLogic()->set_progressBarText(text);
pageLogic<ServerConfiguringProgressLogic>()->set_progressBarText(text);
};
bool ok = installContainers(installCredentials, containers,
page_new_server_configuring,
@ -385,7 +347,7 @@ void UiLogic::installServer(QMap<DockerContainer, QJsonObject> &containers)
server.insert(config_key::userName, installCredentials.userName);
server.insert(config_key::password, installCredentials.password);
server.insert(config_key::port, installCredentials.port);
server.insert(config_key::description, m_settings.nextAvailableServerName());
server.insert(config_key::description, m_settings->nextAvailableServerName());
QJsonArray containerConfigs;
for (const QJsonObject &cfg : containers) {
@ -394,8 +356,8 @@ void UiLogic::installServer(QMap<DockerContainer, QJsonObject> &containers)
server.insert(config_key::containers, containerConfigs);
server.insert(config_key::defaultContainer, ContainerProps::containerToString(containers.firstKey()));
m_settings.addServer(server);
m_settings.setDefaultServer(m_settings.serversCount() - 1);
m_settings->addServer(server);
m_settings->setDefaultServer(m_settings->serversCount() - 1);
onUpdateAllPages();
emit setStartPage(Page::Vpn);
@ -442,9 +404,9 @@ bool UiLogic::installContainers(ServerCredentials credentials,
progress.setTextVisibleFunc(true);
progress.setTextFunc(QString("Installing %1 %2 %3").arg(cnt+1).arg(tr("of")).arg(containers.size()));
ErrorCode e = ServerController::setupContainer(credentials, i.key(), i.value());
ErrorCode e = m_serverController->setupContainer(credentials, i.key(), i.value());
qDebug() << "Setup server finished with code" << e;
ServerController::disconnectFromHost(credentials);
m_serverController->disconnectFromHost(credentials);
if (e) {
if (page.setEnabledFunc) {
@ -587,7 +549,7 @@ PageProtocolLogicBase *UiLogic::protocolLogic(Proto p)
PageProtocolLogicBase *logic = m_protocolLogicMap.value(p);
if (logic) return logic;
else {
qDebug() << "UiLogic::protocolLogic Warning: logic missing for" << p;
qCritical() << "UiLogic::protocolLogic Warning: logic missing for" << p;
return new PageProtocolLogicBase(this);
}
}
@ -607,6 +569,11 @@ NotificationHandler *UiLogic::notificationHandler() const
return m_notificationHandler;
}
void UiLogic::setQmlContextProperty(PageLogicBase *logic)
{
amnApp->qmlEngine()->rootContext()->setContextProperty(logic->metaObject()->className(), logic);
}
PageEnumNS::Page UiLogic::currentPage()
{
return static_cast<PageEnumNS::Page>(currentPageValue());
@ -632,13 +599,11 @@ void UiLogic::saveTextFile(const QString& desc, const QString& suggestedName, QS
QUrl::fromLocalFile(docDir), "*" + ext);
#endif
qDebug() << "UiLogic::saveTextFile" << fileName;
if (fileName.isEmpty()) return;
#ifdef AMNEZIA_DESKTOP
QFile save(fileName.toLocalFile());
#else
qDebug() << "UiLogic::saveTextFile" << QQmlFile::urlToLocalFileOrQrc(fileName);
QFile save(QQmlFile::urlToLocalFileOrQrc(fileName));
#endif
@ -681,7 +646,6 @@ void UiLogic::shareTempFile(const QString &suggestedName, QString ext, const QSt
if (!fileName.endsWith(ext)) fileName.append(ext);
QFile::remove(fileName);
qDebug() << "UiLogic::shareTempFile" << fileName;
QFile save(fileName);
save.open(QIODevice::WriteOnly);
@ -692,3 +656,24 @@ void UiLogic::shareTempFile(const QString &suggestedName, QString ext, const QSt
filesToSend.append(fileName);
MobileUtils::shareText(filesToSend);
}
void UiLogic::registerPagesLogic()
{
amnApp->qmlEngine()->rootContext()->setContextProperty("UiLogic", this);
registerPageLogic<AppSettingsLogic>();
registerPageLogic<GeneralSettingsLogic>();
registerPageLogic<NetworkSettingsLogic>();
registerPageLogic<NewServerProtocolsLogic>();
registerPageLogic<QrDecoderLogic>();
registerPageLogic<ServerConfiguringProgressLogic>();
registerPageLogic<ServerListLogic>();
registerPageLogic<ServerSettingsLogic>();
registerPageLogic<ServerContainersLogic>();
registerPageLogic<ShareConnectionLogic>();
registerPageLogic<SitesLogic>();
registerPageLogic<StartPageLogic>();
registerPageLogic<ViewConfigLogic>();
registerPageLogic<VpnLogic>();
registerPageLogic<WizardLogic>();
}

View file

@ -7,6 +7,10 @@
#include <QKeyEvent>
#include <QThread>
#include <typeindex>
#include <typeinfo>
#include <unordered_map>
#include "property_helper.h"
#include "pages.h"
#include "protocols/vpnprotocol.h"
@ -16,7 +20,12 @@
#include "models/protocols_model.h"
#include "notificationhandler.h"
#include "settings.h"
class Settings;
class VpnConfigurator;
class ServerController;
class PageLogicBase;
class AppSettingsLogic;
class GeneralSettingsLogic;
@ -30,6 +39,7 @@ class ServerContainersLogic;
class ShareConnectionLogic;
class SitesLogic;
class StartPageLogic;
class ViewConfigLogic;
class VpnLogic;
class WizardLogic;
@ -50,18 +60,19 @@ class UiLogic : public QObject
AUTO_PROPERTY(bool, pageEnabled)
AUTO_PROPERTY(int, pagesStackDepth)
AUTO_PROPERTY(int, currentPageValue)
AUTO_PROPERTY(QString, dialogConnectErrorText)
READONLY_PROPERTY(QObject *, containersModel)
READONLY_PROPERTY(QObject *, protocolsModel)
// TODO: review
Q_PROPERTY(QString dialogConnectErrorText READ getDialogConnectErrorText WRITE setDialogConnectErrorText NOTIFY dialogConnectErrorTextChanged)
public:
explicit UiLogic(QObject *parent = nullptr);
explicit UiLogic(std::shared_ptr<Settings> settings, std::shared_ptr<VpnConfigurator> configurator,
std::shared_ptr<ServerController> serverController, QObject *parent = nullptr);
~UiLogic();
void showOnStartup();
friend class PageLogicBase;
friend class AppSettingsLogic;
friend class GeneralSettingsLogic;
friend class NetworkSettingsLogic;
@ -73,6 +84,7 @@ public:
friend class ShareConnectionLogic;
friend class SitesLogic;
friend class StartPageLogic;
friend class ViewConfigLogic;
friend class VpnLogic;
friend class WizardLogic;
@ -92,10 +104,6 @@ public:
Q_INVOKABLE QString containerName(int container);
Q_INVOKABLE QString containerDesc(int container);
Q_INVOKABLE void onGotoPage(PageEnumNS::Page p, bool reset = true, bool slide = true) { emit goToPage(p, reset, slide); }
Q_INVOKABLE void onGotoProtocolPage(Proto p, bool reset = true, bool slide = true) { emit goToProtocolPage(p, reset, slide); }
Q_INVOKABLE void onGotoShareProtocolPage(Proto p, bool reset = true, bool slide = true) { emit goToShareProtocolPage(p, reset, slide); }
Q_INVOKABLE void onGotoCurrentProtocolsPage();
Q_INVOKABLE void keyPressEvent(Qt::Key key);
@ -106,9 +114,6 @@ public:
void shareTempFile(const QString &suggestedName, QString ext, const QString& data);
QString getDialogConnectErrorText() const;
void setDialogConnectErrorText(const QString &dialogConnectErrorText);
signals:
void dialogConnectErrorTextChanged();
@ -125,9 +130,6 @@ signals:
void raise();
void toggleLogPanel();
private:
QString m_dialogConnectErrorText;
private slots:
// containers - INOUT arg
void installServer(QMap<DockerContainer, QJsonObject> &containers);
@ -168,21 +170,6 @@ private:
public:
AppSettingsLogic *appSettingsLogic() { return m_appSettingsLogic; }
GeneralSettingsLogic *generalSettingsLogic() { return m_generalSettingsLogic; }
NetworkSettingsLogic *networkSettingsLogic() { return m_networkSettingsLogic; }
NewServerProtocolsLogic *newServerProtocolsLogic() { return m_newServerProtocolsLogic; }
QrDecoderLogic *qrDecoderLogic() { return m_qrDecoderLogic; }
ServerConfiguringProgressLogic *serverConfiguringProgressLogic() { return m_serverConfiguringProgressLogic; }
ServerListLogic *serverListLogic() { return m_serverListLogic; }
ServerSettingsLogic *serverSettingsLogic() { return m_serverSettingsLogic; }
ServerContainersLogic *serverprotocolsLogic() { return m_serverprotocolsLogic; }
ShareConnectionLogic *shareConnectionLogic() { return m_shareConnectionLogic; }
SitesLogic *sitesLogic() { return m_sitesLogic; }
StartPageLogic *startPageLogic() { return m_startPageLogic; }
VpnLogic *vpnLogic() { return m_vpnLogic; }
WizardLogic *wizardLogic() { return m_wizardLogic; }
Q_INVOKABLE PageProtocolLogicBase *protocolLogic(Proto p);
QObject *qmlRoot() const;
@ -190,29 +177,36 @@ public:
NotificationHandler *notificationHandler() const;
void setQmlContextProperty(PageLogicBase *logic);
void registerPagesLogic();
template<typename T>
void registerPageLogic()
{
T* logic = new T(this);
m_logicMap[std::type_index(typeid(T))] = logic;
setQmlContextProperty(logic);
}
template<typename T>
T* pageLogic()
{
return static_cast<T *>(m_logicMap.value(std::type_index(typeid(T))));
}
private:
QObject *m_qmlRoot{nullptr};
AppSettingsLogic *m_appSettingsLogic;
GeneralSettingsLogic *m_generalSettingsLogic;
NetworkSettingsLogic *m_networkSettingsLogic;
NewServerProtocolsLogic *m_newServerProtocolsLogic;
QrDecoderLogic *m_qrDecoderLogic;
ServerConfiguringProgressLogic *m_serverConfiguringProgressLogic;
ServerListLogic *m_serverListLogic;
ServerSettingsLogic *m_serverSettingsLogic;
ServerContainersLogic *m_serverprotocolsLogic;
ShareConnectionLogic *m_shareConnectionLogic;
SitesLogic *m_sitesLogic;
StartPageLogic *m_startPageLogic;
VpnLogic *m_vpnLogic;
WizardLogic *m_wizardLogic;
QMap<std::type_index, PageLogicBase*> m_logicMap;
QMap<Proto, PageProtocolLogicBase *> m_protocolLogicMap;
VpnConnection* m_vpnConnection;
QThread m_vpnConnectionThread;
Settings m_settings;
std::shared_ptr<Settings> m_settings;
std::shared_ptr<VpnConfigurator> m_configurator;
std::shared_ptr<ServerController> m_serverController;
NotificationHandler* m_notificationHandler;