Merge branch 'dev' into feature/app-update
This commit is contained in:
commit
a71ca29b2f
685 changed files with 51300 additions and 12531 deletions
|
|
@ -8,7 +8,7 @@
|
|||
#include <QtConcurrent>
|
||||
|
||||
#include "core/controllers/vpnConfigurationController.h"
|
||||
#include "core/errorstrings.h"
|
||||
#include "core/enums/apiEnums.h"
|
||||
#include "version.h"
|
||||
|
||||
ConnectionController::ConnectionController(const QSharedPointer<ServersModel> &serversModel,
|
||||
|
|
@ -17,7 +17,6 @@ ConnectionController::ConnectionController(const QSharedPointer<ServersModel> &s
|
|||
const QSharedPointer<VpnConnection> &vpnConnection, const std::shared_ptr<Settings> &settings,
|
||||
QObject *parent)
|
||||
: QObject(parent),
|
||||
m_apiController(this),
|
||||
m_serversModel(serversModel),
|
||||
m_containersModel(containersModel),
|
||||
m_clientManagementModel(clientManagementModel),
|
||||
|
|
@ -28,9 +27,7 @@ ConnectionController::ConnectionController(const QSharedPointer<ServersModel> &s
|
|||
connect(this, &ConnectionController::connectToVpn, m_vpnConnection.get(), &VpnConnection::connectToVpn, Qt::QueuedConnection);
|
||||
connect(this, &ConnectionController::disconnectFromVpn, m_vpnConnection.get(), &VpnConnection::disconnectFromVpn, Qt::QueuedConnection);
|
||||
|
||||
connect(&m_apiController, &ApiController::configUpdated, this,
|
||||
static_cast<void (ConnectionController::*)(const bool, const QJsonObject &, const int)>(&ConnectionController::openConnection));
|
||||
connect(&m_apiController, &ApiController::errorOccurred, this, &ConnectionController::connectionErrorOccurred);
|
||||
connect(this, &ConnectionController::configFromApiUpdated, this, &ConnectionController::continueConnection);
|
||||
|
||||
m_state = Vpn::ConnectionState::Disconnected;
|
||||
}
|
||||
|
|
@ -40,21 +37,32 @@ void ConnectionController::openConnection()
|
|||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
||||
if (!Utils::processIsRunning(Utils::executable(SERVICE_NAME, false), true))
|
||||
{
|
||||
emit connectionErrorOccurred(errorString(ErrorCode::AmneziaServiceNotRunning));
|
||||
emit connectionErrorOccurred(ErrorCode::AmneziaServiceNotRunning);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
int serverIndex = m_serversModel->getDefaultServerIndex();
|
||||
QJsonObject serverConfig = m_serversModel->getServerConfig(serverIndex);
|
||||
auto configVersion = serverConfig.value(config_key::configVersion).toInt();
|
||||
|
||||
emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Preparing);
|
||||
|
||||
if (serverConfig.value(config_key::configVersion).toInt()
|
||||
if (configVersion == ApiConfigSources::Telegram
|
||||
&& !m_serversModel->data(serverIndex, ServersModel::Roles::HasInstalledContainers).toBool()) {
|
||||
m_apiController.updateServerConfigFromApi(m_settings->getInstallationUuid(true), serverIndex, serverConfig);
|
||||
emit updateApiConfigFromTelegram();
|
||||
} else if (configVersion == ApiConfigSources::AmneziaGateway
|
||||
&& !m_serversModel->data(serverIndex, ServersModel::Roles::HasInstalledContainers).toBool()) {
|
||||
emit updateApiConfigFromGateway();
|
||||
} else if (configVersion && m_serversModel->isApiKeyExpired(serverIndex)) {
|
||||
qDebug() << "attempt to update api config by end_date event";
|
||||
if (configVersion == ApiConfigSources::Telegram) {
|
||||
emit updateApiConfigFromTelegram();
|
||||
} else {
|
||||
emit updateApiConfigFromGateway();
|
||||
}
|
||||
} else {
|
||||
openConnection(false, serverConfig, serverIndex);
|
||||
continueConnection();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -63,9 +71,9 @@ void ConnectionController::closeConnection()
|
|||
emit disconnectFromVpn();
|
||||
}
|
||||
|
||||
QString ConnectionController::getLastConnectionError()
|
||||
ErrorCode ConnectionController::getLastConnectionError()
|
||||
{
|
||||
return errorString(m_vpnConnection->lastError());
|
||||
return m_vpnConnection->lastError();
|
||||
}
|
||||
|
||||
void ConnectionController::onConnectionStateChanged(Vpn::ConnectionState state)
|
||||
|
|
@ -124,7 +132,7 @@ void ConnectionController::onConnectionStateChanged(Vpn::ConnectionState state)
|
|||
void ConnectionController::onCurrentContainerUpdated()
|
||||
{
|
||||
if (m_isConnected || m_isConnectionInProgress) {
|
||||
emit reconnectWithUpdatedContainer(tr("Settings updated successfully, Reconnnection..."));
|
||||
emit reconnectWithUpdatedContainer(tr("Settings updated successfully, reconnnection..."));
|
||||
openConnection();
|
||||
} else {
|
||||
emit reconnectWithUpdatedContainer(tr("Settings updated successfully"));
|
||||
|
|
@ -186,12 +194,11 @@ bool ConnectionController::isProtocolConfigExists(const QJsonObject &containerCo
|
|||
return true;
|
||||
}
|
||||
|
||||
void ConnectionController::openConnection(const bool updateConfig, const QJsonObject &config, const int serverIndex)
|
||||
void ConnectionController::continueConnection()
|
||||
{
|
||||
// Update config for this server as it was received from API
|
||||
if (updateConfig) {
|
||||
m_serversModel->editServer(config, serverIndex);
|
||||
}
|
||||
int serverIndex = m_serversModel->getDefaultServerIndex();
|
||||
QJsonObject serverConfig = m_serversModel->getServerConfig(serverIndex);
|
||||
auto configVersion = serverConfig.value(config_key::configVersion).toInt();
|
||||
|
||||
if (!m_serversModel->data(serverIndex, ServersModel::Roles::HasInstalledContainers).toBool()) {
|
||||
emit noInstalledContainers();
|
||||
|
|
@ -218,13 +225,13 @@ void ConnectionController::openConnection(const bool updateConfig, const QJsonOb
|
|||
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
|
||||
ErrorCode errorCode = updateProtocolConfig(container, credentials, containerConfig, serverController);
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
emit connectionErrorOccurred(errorString(errorCode));
|
||||
emit connectionErrorOccurred(errorCode);
|
||||
return;
|
||||
}
|
||||
|
||||
auto dns = m_serversModel->getDnsPair(serverIndex);
|
||||
|
||||
auto vpnConfiguration = vpnConfigurationController.createVpnConfiguration(dns, config, containerConfig, container, errorCode);
|
||||
auto vpnConfiguration = vpnConfigurationController.createVpnConfiguration(dns, serverConfig, containerConfig, container, errorCode);
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
emit connectionErrorOccurred(tr("unable to create configuration"));
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
#ifndef CONNECTIONCONTROLLER_H
|
||||
#define CONNECTIONCONTROLLER_H
|
||||
|
||||
#include "core/controllers/apiController.h"
|
||||
#include "protocols/vpnprotocol.h"
|
||||
#include "ui/models/clientManagementModel.h"
|
||||
#include "ui/models/containers_model.h"
|
||||
|
|
@ -34,7 +33,7 @@ public slots:
|
|||
void openConnection();
|
||||
void closeConnection();
|
||||
|
||||
QString getLastConnectionError();
|
||||
ErrorCode getLastConnectionError();
|
||||
void onConnectionStateChanged(Vpn::ConnectionState state);
|
||||
|
||||
void onCurrentContainerUpdated();
|
||||
|
|
@ -50,6 +49,7 @@ signals:
|
|||
void connectionStateChanged();
|
||||
|
||||
void connectionErrorOccurred(const QString &errorMessage);
|
||||
void connectionErrorOccurred(ErrorCode errorCode);
|
||||
void reconnectWithUpdatedContainer(const QString &message);
|
||||
|
||||
void noInstalledContainers();
|
||||
|
|
@ -57,13 +57,15 @@ signals:
|
|||
void connectButtonClicked();
|
||||
void preparingConfig();
|
||||
|
||||
void updateApiConfigFromGateway();
|
||||
void updateApiConfigFromTelegram();
|
||||
void configFromApiUpdated();
|
||||
|
||||
private:
|
||||
Vpn::ConnectionState getCurrentConnectionState();
|
||||
bool isProtocolConfigExists(const QJsonObject &containerConfig, const DockerContainer container);
|
||||
|
||||
void openConnection(const bool updateConfig, const QJsonObject &config, const int serverIndex);
|
||||
|
||||
ApiController m_apiController;
|
||||
void continueConnection();
|
||||
|
||||
QSharedPointer<ServersModel> m_serversModel;
|
||||
QSharedPointer<ContainersModel> m_containersModel;
|
||||
|
|
|
|||
|
|
@ -9,11 +9,7 @@
|
|||
#include <QStandardPaths>
|
||||
|
||||
#include "core/controllers/vpnConfigurationController.h"
|
||||
#include "core/errorstrings.h"
|
||||
#include "systemController.h"
|
||||
#ifdef Q_OS_ANDROID
|
||||
#include "platforms/android/android_utils.h"
|
||||
#endif
|
||||
#include "qrcodegen.hpp"
|
||||
|
||||
ExportController::ExportController(const QSharedPointer<ServersModel> &serversModel, const QSharedPointer<ContainersModel> &containersModel,
|
||||
|
|
@ -25,12 +21,6 @@ ExportController::ExportController(const QSharedPointer<ServersModel> &serversMo
|
|||
m_clientManagementModel(clientManagementModel),
|
||||
m_settings(settings)
|
||||
{
|
||||
#ifdef Q_OS_ANDROID
|
||||
m_authResultNotifier.reset(new AuthResultNotifier);
|
||||
m_authResultReceiver.reset(new AuthResultReceiver(m_authResultNotifier));
|
||||
connect(m_authResultNotifier.get(), &AuthResultNotifier::authFailed, this, [this]() { emit exportErrorOccurred(tr("Access error!")); });
|
||||
connect(m_authResultNotifier.get(), &AuthResultNotifier::authSuccessful, this, &ExportController::generateFullAccessConfig);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ExportController::generateFullAccessConfig()
|
||||
|
|
@ -64,26 +54,6 @@ void ExportController::generateFullAccessConfig()
|
|||
emit exportConfigChanged();
|
||||
}
|
||||
|
||||
#if defined(Q_OS_ANDROID)
|
||||
void ExportController::generateFullAccessConfigAndroid()
|
||||
{
|
||||
/* We use builtin keyguard for ssh key export protection on Android */
|
||||
QJniObject activity = AndroidUtils::getActivity();
|
||||
auto appContext = activity.callObjectMethod("getApplicationContext", "()Landroid/content/Context;");
|
||||
if (appContext.isValid()) {
|
||||
auto intent = QJniObject::callStaticObjectMethod("org/amnezia/vpn/AuthHelper", "getAuthIntent",
|
||||
"(Landroid/content/Context;)Landroid/content/Intent;", appContext.object());
|
||||
if (intent.isValid()) {
|
||||
if (intent.object<jobject>() != nullptr) {
|
||||
QtAndroidPrivate::startActivity(intent.object<jobject>(), 1, m_authResultReceiver.get());
|
||||
}
|
||||
} else {
|
||||
generateFullAccessConfig();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void ExportController::generateConnectionConfig(const QString &clientName)
|
||||
{
|
||||
clearPreviousConfig();
|
||||
|
|
@ -101,7 +71,7 @@ void ExportController::generateConnectionConfig(const QString &clientName)
|
|||
|
||||
errorCode = m_clientManagementModel->appendClient(container, credentials, containerConfig, clientName, serverController);
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
emit exportErrorOccurred(errorString(errorCode));
|
||||
emit exportErrorOccurred(errorCode);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -134,7 +104,7 @@ ErrorCode ExportController::generateNativeConfig(const DockerContainer container
|
|||
int serverIndex = m_serversModel->getProcessedServerIndex();
|
||||
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
|
||||
auto dns = m_serversModel->getDnsPair(serverIndex);
|
||||
bool isApiConfig = qvariant_cast<bool>(m_serversModel->data(serverIndex, ServersModel::IsServerFromApiRole));
|
||||
bool isApiConfig = qvariant_cast<bool>(m_serversModel->data(serverIndex, ServersModel::IsServerFromTelegramApiRole));
|
||||
|
||||
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
|
||||
containerConfig.insert(config_key::container, ContainerProps::containerToString(container));
|
||||
|
|
@ -171,7 +141,7 @@ void ExportController::generateOpenVpnConfig(const QString &clientName)
|
|||
}
|
||||
|
||||
if (errorCode) {
|
||||
emit exportErrorOccurred(errorString(errorCode));
|
||||
emit exportErrorOccurred(errorCode);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -189,7 +159,7 @@ void ExportController::generateWireGuardConfig(const QString &clientName)
|
|||
QJsonObject nativeConfig;
|
||||
ErrorCode errorCode = generateNativeConfig(DockerContainer::WireGuard, clientName, Proto::WireGuard, nativeConfig);
|
||||
if (errorCode) {
|
||||
emit exportErrorOccurred(errorString(errorCode));
|
||||
emit exportErrorOccurred(errorCode);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -209,7 +179,7 @@ void ExportController::generateAwgConfig(const QString &clientName)
|
|||
QJsonObject nativeConfig;
|
||||
ErrorCode errorCode = generateNativeConfig(DockerContainer::Awg, clientName, Proto::Awg, nativeConfig);
|
||||
if (errorCode) {
|
||||
emit exportErrorOccurred(errorString(errorCode));
|
||||
emit exportErrorOccurred(errorCode);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -237,7 +207,7 @@ void ExportController::generateShadowSocksConfig()
|
|||
}
|
||||
|
||||
if (errorCode) {
|
||||
emit exportErrorOccurred(errorString(errorCode));
|
||||
emit exportErrorOccurred(errorCode);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -263,7 +233,7 @@ void ExportController::generateCloakConfig()
|
|||
QJsonObject nativeConfig;
|
||||
ErrorCode errorCode = generateNativeConfig(DockerContainer::Cloak, "", Proto::Cloak, nativeConfig);
|
||||
if (errorCode) {
|
||||
emit exportErrorOccurred(errorString(errorCode));
|
||||
emit exportErrorOccurred(errorCode);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -283,7 +253,7 @@ void ExportController::generateXrayConfig()
|
|||
QJsonObject nativeConfig;
|
||||
ErrorCode errorCode = generateNativeConfig(DockerContainer::Xray, "", Proto::Xray, nativeConfig);
|
||||
if (errorCode) {
|
||||
emit exportErrorOccurred(errorString(errorCode));
|
||||
emit exportErrorOccurred(errorCode);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -320,7 +290,7 @@ void ExportController::updateClientManagementModel(const DockerContainer contain
|
|||
QSharedPointer<ServerController> serverController(new ServerController(m_settings));
|
||||
ErrorCode errorCode = m_clientManagementModel->updateModel(container, credentials, serverController);
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
emit exportErrorOccurred(errorString(errorCode));
|
||||
emit exportErrorOccurred(errorCode);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -330,7 +300,7 @@ void ExportController::revokeConfig(const int row, const DockerContainer contain
|
|||
ErrorCode errorCode =
|
||||
m_clientManagementModel->revokeClient(row, container, credentials, m_serversModel->getProcessedServerIndex(), serverController);
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
emit exportErrorOccurred(errorString(errorCode));
|
||||
emit exportErrorOccurred(errorCode);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -339,7 +309,7 @@ void ExportController::renameClient(const int row, const QString &clientName, co
|
|||
QSharedPointer<ServerController> serverController(new ServerController(m_settings));
|
||||
ErrorCode errorCode = m_clientManagementModel->renameClient(row, clientName, container, credentials, serverController);
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
emit exportErrorOccurred(errorString(errorCode));
|
||||
emit exportErrorOccurred(errorCode);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,9 +6,6 @@
|
|||
#include "ui/models/clientManagementModel.h"
|
||||
#include "ui/models/containers_model.h"
|
||||
#include "ui/models/servers_model.h"
|
||||
#ifdef Q_OS_ANDROID
|
||||
#include "platforms/android/authResultReceiver.h"
|
||||
#endif
|
||||
|
||||
class ExportController : public QObject
|
||||
{
|
||||
|
|
@ -25,9 +22,6 @@ public:
|
|||
|
||||
public slots:
|
||||
void generateFullAccessConfig();
|
||||
#if defined(Q_OS_ANDROID)
|
||||
void generateFullAccessConfigAndroid();
|
||||
#endif
|
||||
void generateConnectionConfig(const QString &clientName);
|
||||
void generateOpenVpnConfig(const QString &clientName);
|
||||
void generateWireGuardConfig(const QString &clientName);
|
||||
|
|
@ -49,6 +43,7 @@ public slots:
|
|||
signals:
|
||||
void generateConfig(int type);
|
||||
void exportErrorOccurred(const QString &errorMessage);
|
||||
void exportErrorOccurred(ErrorCode errorCode);
|
||||
|
||||
void exportConfigChanged();
|
||||
|
||||
|
|
@ -73,11 +68,6 @@ private:
|
|||
QString m_config;
|
||||
QString m_nativeConfigString;
|
||||
QList<QString> m_qrCodes;
|
||||
|
||||
#ifdef Q_OS_ANDROID
|
||||
QSharedPointer<AuthResultNotifier> m_authResultNotifier;
|
||||
QSharedPointer<QAndroidActivityResultReceiver> m_authResultReceiver;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // EXPORTCONTROLLER_H
|
||||
|
|
|
|||
|
|
@ -5,8 +5,12 @@
|
|||
#include <QQuickItem>
|
||||
#include <QRandomGenerator>
|
||||
#include <QStandardPaths>
|
||||
#include <QUrlQuery>
|
||||
|
||||
#include "core/errorstrings.h"
|
||||
#include "core/serialization/serialization.h"
|
||||
#include "utilities.h"
|
||||
|
||||
#ifdef Q_OS_ANDROID
|
||||
#include "platforms/android/android_controller.h"
|
||||
#endif
|
||||
|
|
@ -35,11 +39,12 @@ namespace
|
|||
const QString amneziaConfigPatternUserName = "userName";
|
||||
const QString amneziaConfigPatternPassword = "password";
|
||||
const QString amneziaFreeConfigPattern = "api_key";
|
||||
const QString amneziaPremiumConfigPattern = "auth_data";
|
||||
const QString backupPattern = "Servers/serversList";
|
||||
|
||||
if (config.contains(backupPattern)) {
|
||||
return ConfigTypes::Backup;
|
||||
} else if (config.contains(amneziaConfigPattern) || config.contains(amneziaFreeConfigPattern)
|
||||
} else if (config.contains(amneziaConfigPattern) || config.contains(amneziaFreeConfigPattern) || config.contains(amneziaPremiumConfigPattern)
|
||||
|| (config.contains(amneziaConfigPatternHostName) && config.contains(amneziaConfigPatternUserName)
|
||||
&& config.contains(amneziaConfigPatternPassword))) {
|
||||
return ConfigTypes::Amnezia;
|
||||
|
|
@ -80,13 +85,66 @@ bool ImportController::extractConfigFromFile(const QString &fileName)
|
|||
return extractConfigFromData(data);
|
||||
}
|
||||
|
||||
emit importErrorOccurred(tr("Unable to open file"), false);
|
||||
emit importErrorOccurred(ErrorCode::ImportOpenConfigError, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ImportController::extractConfigFromData(QString data)
|
||||
{
|
||||
QString config = data;
|
||||
QString prefix;
|
||||
QString errormsg;
|
||||
|
||||
if (config.startsWith("vless://")) {
|
||||
m_configType = ConfigTypes::Xray;
|
||||
m_config = extractXrayConfig(
|
||||
Utils::JsonToString(serialization::vless::Deserialize(config, &prefix, &errormsg), QJsonDocument::JsonFormat::Compact),
|
||||
prefix);
|
||||
return m_config.empty() ? false : true;
|
||||
}
|
||||
|
||||
if (config.startsWith("vmess://") && config.contains("@")) {
|
||||
m_configType = ConfigTypes::Xray;
|
||||
m_config = extractXrayConfig(
|
||||
Utils::JsonToString(serialization::vmess_new::Deserialize(config, &prefix, &errormsg), QJsonDocument::JsonFormat::Compact),
|
||||
prefix);
|
||||
return m_config.empty() ? false : true;
|
||||
}
|
||||
|
||||
if (config.startsWith("vmess://")) {
|
||||
m_configType = ConfigTypes::Xray;
|
||||
m_config = extractXrayConfig(
|
||||
Utils::JsonToString(serialization::vmess::Deserialize(config, &prefix, &errormsg), QJsonDocument::JsonFormat::Compact),
|
||||
prefix);
|
||||
return m_config.empty() ? false : true;
|
||||
}
|
||||
|
||||
if (config.startsWith("trojan://")) {
|
||||
m_configType = ConfigTypes::Xray;
|
||||
m_config = extractXrayConfig(
|
||||
Utils::JsonToString(serialization::trojan::Deserialize(config, &prefix, &errormsg), QJsonDocument::JsonFormat::Compact),
|
||||
prefix);
|
||||
return m_config.empty() ? false : true;
|
||||
}
|
||||
|
||||
if (config.startsWith("ss://") && !config.contains("plugin=")) {
|
||||
m_configType = ConfigTypes::ShadowSocks;
|
||||
m_config = extractXrayConfig(
|
||||
Utils::JsonToString(serialization::ss::Deserialize(config, &prefix, &errormsg), QJsonDocument::JsonFormat::Compact), prefix);
|
||||
return m_config.empty() ? false : true;
|
||||
}
|
||||
|
||||
if (config.startsWith("ssd://")) {
|
||||
QStringList tmp;
|
||||
QList<std::pair<QString, QJsonObject>> servers = serialization::ssd::Deserialize(config, &prefix, &tmp);
|
||||
m_configType = ConfigTypes::ShadowSocks;
|
||||
// Took only first config from list
|
||||
if (!servers.isEmpty()) {
|
||||
m_config = extractXrayConfig(servers.first().first);
|
||||
}
|
||||
return m_config.empty() ? false : true;
|
||||
}
|
||||
|
||||
m_configType = checkConfigFormat(config);
|
||||
if (m_configType == ConfigTypes::Invalid) {
|
||||
data.replace("vpn://", "");
|
||||
|
|
@ -120,6 +178,7 @@ bool ImportController::extractConfigFromData(QString data)
|
|||
}
|
||||
case ConfigTypes::Amnezia: {
|
||||
m_config = QJsonDocument::fromJson(config.toUtf8()).object();
|
||||
processAmneziaConfig(m_config);
|
||||
if (!m_config.empty()) {
|
||||
checkForMaliciousStrings(m_config);
|
||||
return true;
|
||||
|
|
@ -130,12 +189,12 @@ bool ImportController::extractConfigFromData(QString data)
|
|||
if (!m_serversModel->getServersCount()) {
|
||||
emit restoreAppConfig(config.toUtf8());
|
||||
} else {
|
||||
emit importErrorOccurred(tr("Invalid configuration file"), false);
|
||||
emit importErrorOccurred(ErrorCode::ImportInvalidConfigError, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ConfigTypes::Invalid: {
|
||||
emit importErrorOccurred(tr("Invalid configuration file"), false);
|
||||
emit importErrorOccurred(ErrorCode::ImportInvalidConfigError, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -184,24 +243,26 @@ void ImportController::processNativeWireGuardConfig()
|
|||
auto containers = m_config.value(config_key::containers).toArray();
|
||||
if (!containers.isEmpty()) {
|
||||
auto container = containers.at(0).toObject();
|
||||
auto containerConfig = container.value(ContainerProps::containerTypeToString(DockerContainer::WireGuard)).toObject();
|
||||
auto protocolConfig = QJsonDocument::fromJson(containerConfig.value(config_key::last_config).toString().toUtf8()).object();
|
||||
auto serverProtocolConfig = container.value(ContainerProps::containerTypeToString(DockerContainer::WireGuard)).toObject();
|
||||
auto clientProtocolConfig = QJsonDocument::fromJson(serverProtocolConfig.value(config_key::last_config).toString().toUtf8()).object();
|
||||
|
||||
QString junkPacketCount = QString::number(QRandomGenerator::global()->bounded(3, 10));
|
||||
QString junkPacketMinSize = QString::number(50);
|
||||
QString junkPacketMaxSize = QString::number(1000);
|
||||
protocolConfig[config_key::junkPacketCount] = junkPacketCount;
|
||||
protocolConfig[config_key::junkPacketMinSize] = junkPacketMinSize;
|
||||
protocolConfig[config_key::junkPacketMaxSize] = junkPacketMaxSize;
|
||||
protocolConfig[config_key::initPacketJunkSize] = "0";
|
||||
protocolConfig[config_key::responsePacketJunkSize] = "0";
|
||||
protocolConfig[config_key::initPacketMagicHeader] = "1";
|
||||
protocolConfig[config_key::responsePacketMagicHeader] = "2";
|
||||
protocolConfig[config_key::underloadPacketMagicHeader] = "3";
|
||||
protocolConfig[config_key::transportPacketMagicHeader] = "4";
|
||||
QString junkPacketCount = QString::number(QRandomGenerator::global()->bounded(2, 5));
|
||||
QString junkPacketMinSize = QString::number(10);
|
||||
QString junkPacketMaxSize = QString::number(50);
|
||||
clientProtocolConfig[config_key::junkPacketCount] = junkPacketCount;
|
||||
clientProtocolConfig[config_key::junkPacketMinSize] = junkPacketMinSize;
|
||||
clientProtocolConfig[config_key::junkPacketMaxSize] = junkPacketMaxSize;
|
||||
clientProtocolConfig[config_key::initPacketJunkSize] = "0";
|
||||
clientProtocolConfig[config_key::responsePacketJunkSize] = "0";
|
||||
clientProtocolConfig[config_key::initPacketMagicHeader] = "1";
|
||||
clientProtocolConfig[config_key::responsePacketMagicHeader] = "2";
|
||||
clientProtocolConfig[config_key::underloadPacketMagicHeader] = "3";
|
||||
clientProtocolConfig[config_key::transportPacketMagicHeader] = "4";
|
||||
|
||||
containerConfig[config_key::last_config] = QString(QJsonDocument(protocolConfig).toJson());
|
||||
container["wireguard"] = containerConfig;
|
||||
clientProtocolConfig[config_key::isObfuscationEnabled] = true;
|
||||
|
||||
serverProtocolConfig[config_key::last_config] = QString(QJsonDocument(clientProtocolConfig).toJson());
|
||||
container["wireguard"] = serverProtocolConfig;
|
||||
containers.replace(0, container);
|
||||
m_config[config_key::containers] = containers;
|
||||
}
|
||||
|
|
@ -221,7 +282,7 @@ void ImportController::importConfig()
|
|||
} else if (m_config.contains(config_key::configVersion)) {
|
||||
quint16 crc = qChecksum(QJsonDocument(m_config).toJson());
|
||||
if (m_serversModel->isServerFromApiAlreadyExists(crc)) {
|
||||
emit importErrorOccurred(errorString(ErrorCode::ApiConfigAlreadyAdded), true);
|
||||
emit importErrorOccurred(ErrorCode::ApiConfigAlreadyAdded, true);
|
||||
} else {
|
||||
m_config.insert(config_key::crc, crc);
|
||||
|
||||
|
|
@ -231,7 +292,7 @@ void ImportController::importConfig()
|
|||
} else {
|
||||
qDebug() << "Failed to import profile";
|
||||
qDebug().noquote() << QJsonDocument(m_config).toJson();
|
||||
emit importErrorOccurred(errorString(ErrorCode::ImportInvalidConfigError), false);
|
||||
emit importErrorOccurred(ErrorCode::ImportInvalidConfigError, false);
|
||||
}
|
||||
|
||||
m_config = {};
|
||||
|
|
@ -300,20 +361,19 @@ QJsonObject ImportController::extractWireGuardConfig(const QString &data)
|
|||
QJsonObject lastConfig;
|
||||
lastConfig[config_key::config] = data;
|
||||
|
||||
const static QRegularExpression hostNameAndPortRegExp("Endpoint = (.*):([0-9]*)");
|
||||
QRegularExpressionMatch hostNameAndPortMatch = hostNameAndPortRegExp.match(data);
|
||||
auto url { QUrl::fromUserInput(configMap.value("Endpoint")) };
|
||||
QString hostName;
|
||||
QString port;
|
||||
if (hostNameAndPortMatch.hasCaptured(1)) {
|
||||
hostName = hostNameAndPortMatch.captured(1);
|
||||
if (!url.host().isEmpty()) {
|
||||
hostName = url.host();
|
||||
} else {
|
||||
qDebug() << "Key parameter 'Endpoint' is missing";
|
||||
emit importErrorOccurred(errorString(ErrorCode::ImportInvalidConfigError), false);
|
||||
qDebug() << "Key parameter 'Endpoint' is missing or has an invalid format";
|
||||
emit importErrorOccurred(ErrorCode::ImportInvalidConfigError, false);
|
||||
return QJsonObject();
|
||||
}
|
||||
|
||||
if (hostNameAndPortMatch.hasCaptured(2)) {
|
||||
port = hostNameAndPortMatch.captured(2);
|
||||
if (url.port() != -1) {
|
||||
port = QString::number(url.port());
|
||||
} else {
|
||||
port = protocols::wireguard::defaultPort;
|
||||
}
|
||||
|
|
@ -334,7 +394,7 @@ QJsonObject ImportController::extractWireGuardConfig(const QString &data)
|
|||
lastConfig[config_key::server_pub_key] = configMap.value("PublicKey");
|
||||
} else {
|
||||
qDebug() << "One of the key parameters is missing (PrivateKey, Address, PublicKey)";
|
||||
emit importErrorOccurred(errorString(ErrorCode::ImportInvalidConfigError), false);
|
||||
emit importErrorOccurred(ErrorCode::ImportInvalidConfigError, false);
|
||||
return QJsonObject();
|
||||
}
|
||||
|
||||
|
|
@ -342,7 +402,11 @@ QJsonObject ImportController::extractWireGuardConfig(const QString &data)
|
|||
lastConfig[config_key::mtu] = configMap.value("MTU");
|
||||
}
|
||||
|
||||
QJsonArray allowedIpsJsonArray = QJsonArray::fromStringList(configMap.value("AllowedIPs").split(","));
|
||||
if (!configMap.value("PersistentKeepalive").isEmpty()) {
|
||||
lastConfig[config_key::persistent_keep_alive] = configMap.value("PersistentKeepalive");
|
||||
}
|
||||
|
||||
QJsonArray allowedIpsJsonArray = QJsonArray::fromStringList(configMap.value("AllowedIPs").split(", "));
|
||||
|
||||
lastConfig[config_key::allowed_ips] = allowedIpsJsonArray;
|
||||
|
||||
|
|
@ -366,6 +430,12 @@ QJsonObject ImportController::extractWireGuardConfig(const QString &data)
|
|||
m_configType = ConfigTypes::Awg;
|
||||
}
|
||||
|
||||
if (!configMap.value("MTU").isEmpty()) {
|
||||
lastConfig[config_key::mtu] = configMap.value("MTU");
|
||||
} else {
|
||||
lastConfig[config_key::mtu] = protocolName == "awg" ? protocols::awg::defaultMtu : protocols::wireguard::defaultMtu;
|
||||
}
|
||||
|
||||
QJsonObject wireguardConfig;
|
||||
wireguardConfig[config_key::last_config] = QString(QJsonDocument(lastConfig).toJson());
|
||||
wireguardConfig[config_key::isThirdPartyConfig] = true;
|
||||
|
|
@ -398,7 +468,7 @@ QJsonObject ImportController::extractWireGuardConfig(const QString &data)
|
|||
return config;
|
||||
}
|
||||
|
||||
QJsonObject ImportController::extractXrayConfig(const QString &data)
|
||||
QJsonObject ImportController::extractXrayConfig(const QString &data, const QString &description)
|
||||
{
|
||||
QJsonParseError parserErr;
|
||||
QJsonDocument jsonConf = QJsonDocument::fromJson(data.toLocal8Bit(), &parserErr);
|
||||
|
|
@ -410,8 +480,13 @@ QJsonObject ImportController::extractXrayConfig(const QString &data)
|
|||
lastConfig[config_key::isThirdPartyConfig] = true;
|
||||
|
||||
QJsonObject containers;
|
||||
containers.insert(config_key::container, QJsonValue("amnezia-xray"));
|
||||
containers.insert(config_key::xray, QJsonValue(lastConfig));
|
||||
if (m_configType == ConfigTypes::ShadowSocks) {
|
||||
containers.insert(config_key::ssxray, QJsonValue(lastConfig));
|
||||
containers.insert(config_key::container, QJsonValue("amnezia-ssxray"));
|
||||
} else {
|
||||
containers.insert(config_key::container, QJsonValue("amnezia-xray"));
|
||||
containers.insert(config_key::xray, QJsonValue(lastConfig));
|
||||
}
|
||||
|
||||
QJsonArray arr;
|
||||
arr.push_back(containers);
|
||||
|
|
@ -426,9 +501,17 @@ QJsonObject ImportController::extractXrayConfig(const QString &data)
|
|||
|
||||
QJsonObject config;
|
||||
config[config_key::containers] = arr;
|
||||
config[config_key::defaultContainer] = "amnezia-xray";
|
||||
config[config_key::description] = m_settings->nextAvailableServerName();
|
||||
|
||||
if (m_configType == ConfigTypes::ShadowSocks) {
|
||||
config[config_key::defaultContainer] = "amnezia-ssxray";
|
||||
} else {
|
||||
config[config_key::defaultContainer] = "amnezia-xray";
|
||||
}
|
||||
if (description.isEmpty()) {
|
||||
config[config_key::description] = m_settings->nextAvailableServerName();
|
||||
} else {
|
||||
config[config_key::description] = description;
|
||||
}
|
||||
config[config_key::hostName] = hostName;
|
||||
|
||||
return config;
|
||||
|
|
@ -580,3 +663,28 @@ void ImportController::checkForMaliciousStrings(const QJsonObject &serverConfig)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ImportController::processAmneziaConfig(QJsonObject &config)
|
||||
{
|
||||
auto containers = config.value(config_key::containers).toArray();
|
||||
for (auto i = 0; i < containers.size(); i++) {
|
||||
auto container = containers.at(i).toObject();
|
||||
auto dockerContainer = ContainerProps::containerFromString(container.value(config_key::container).toString());
|
||||
if (dockerContainer == DockerContainer::Awg || dockerContainer == DockerContainer::WireGuard) {
|
||||
auto containerConfig = container.value(ContainerProps::containerTypeToString(dockerContainer)).toObject();
|
||||
auto protocolConfig = containerConfig.value(config_key::last_config).toString();
|
||||
if (protocolConfig.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QJsonObject jsonConfig = QJsonDocument::fromJson(protocolConfig.toUtf8()).object();
|
||||
jsonConfig[config_key::mtu] = dockerContainer == DockerContainer::Awg ? protocols::awg::defaultMtu : protocols::wireguard::defaultMtu;
|
||||
|
||||
containerConfig[config_key::last_config] = QString(QJsonDocument(jsonConfig).toJson());
|
||||
|
||||
container[ContainerProps::containerTypeToString(dockerContainer)] = containerConfig;
|
||||
containers.replace(i, container);
|
||||
config.insert(config_key::containers, containers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ namespace
|
|||
WireGuard,
|
||||
Awg,
|
||||
Xray,
|
||||
ShadowSocks,
|
||||
Backup,
|
||||
Invalid
|
||||
};
|
||||
|
|
@ -53,7 +54,7 @@ public slots:
|
|||
|
||||
signals:
|
||||
void importFinished();
|
||||
void importErrorOccurred(const QString &errorMessage, bool goToPageHome);
|
||||
void importErrorOccurred(ErrorCode errorCode, bool goToPageHome);
|
||||
|
||||
void qrDecodingFinished();
|
||||
|
||||
|
|
@ -62,10 +63,12 @@ signals:
|
|||
private:
|
||||
QJsonObject extractOpenVpnConfig(const QString &data);
|
||||
QJsonObject extractWireGuardConfig(const QString &data);
|
||||
QJsonObject extractXrayConfig(const QString &data);
|
||||
QJsonObject extractXrayConfig(const QString &data, const QString &description = "");
|
||||
|
||||
void checkForMaliciousStrings(const QJsonObject &protocolConfig);
|
||||
|
||||
void processAmneziaConfig(QJsonObject &config);
|
||||
|
||||
#if defined Q_OS_ANDROID || defined Q_OS_IOS
|
||||
void stopDecodingQr();
|
||||
#endif
|
||||
|
|
|
|||
236
client/ui/controllers/installController.cpp
Normal file → Executable file
236
client/ui/controllers/installController.cpp
Normal file → Executable file
|
|
@ -7,58 +7,46 @@
|
|||
#include <QRandomGenerator>
|
||||
#include <QStandardPaths>
|
||||
|
||||
#include "core/controllers/apiController.h"
|
||||
#include "core/controllers/serverController.h"
|
||||
#include "core/controllers/vpnConfigurationController.h"
|
||||
#include "core/errorstrings.h"
|
||||
#include "core/networkUtilities.h"
|
||||
#include "logger.h"
|
||||
#include "ui/models/protocols/awgConfigModel.h"
|
||||
#include "ui/models/protocols/wireguardConfigModel.h"
|
||||
#include "utilities.h"
|
||||
|
||||
#ifdef Q_OS_IOS
|
||||
#include <AmneziaVPN-Swift.h>
|
||||
#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
Logger logger("ServerController");
|
||||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
QString getNextDriverLetter()
|
||||
namespace configKey
|
||||
{
|
||||
QProcess drivesProc;
|
||||
drivesProc.start("wmic logicaldisk get caption");
|
||||
drivesProc.waitForFinished();
|
||||
QString drives = drivesProc.readAll();
|
||||
qDebug() << drives;
|
||||
constexpr char serviceInfo[] = "service_info";
|
||||
constexpr char serviceType[] = "service_type";
|
||||
constexpr char serviceProtocol[] = "service_protocol";
|
||||
constexpr char userCountryCode[] = "user_country_code";
|
||||
|
||||
QString letters = "CFGHIJKLMNOPQRSTUVWXYZ";
|
||||
QString letter;
|
||||
for (int i = letters.size() - 1; i > 0; i--) {
|
||||
letter = letters.at(i);
|
||||
if (!drives.contains(letter + ":"))
|
||||
break;
|
||||
}
|
||||
if (letter == "C:") {
|
||||
// set err info
|
||||
qDebug() << "Can't find free drive letter";
|
||||
return "";
|
||||
}
|
||||
return letter;
|
||||
constexpr char serverCountryCode[] = "server_country_code";
|
||||
constexpr char serverCountryName[] = "server_country_name";
|
||||
constexpr char availableCountries[] = "available_countries";
|
||||
|
||||
constexpr char apiConfig[] = "api_config";
|
||||
constexpr char authData[] = "auth_data";
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
InstallController::InstallController(const QSharedPointer<ServersModel> &serversModel, const QSharedPointer<ContainersModel> &containersModel,
|
||||
const QSharedPointer<ProtocolsModel> &protocolsModel,
|
||||
const QSharedPointer<ClientManagementModel> &clientManagementModel,
|
||||
const std::shared_ptr<Settings> &settings, QObject *parent)
|
||||
const QSharedPointer<ApiServicesModel> &apiServicesModel, const std::shared_ptr<Settings> &settings,
|
||||
QObject *parent)
|
||||
: QObject(parent),
|
||||
m_serversModel(serversModel),
|
||||
m_containersModel(containersModel),
|
||||
m_protocolModel(protocolsModel),
|
||||
m_clientManagementModel(clientManagementModel),
|
||||
m_apiServicesModel(apiServicesModel),
|
||||
m_settings(settings)
|
||||
{
|
||||
}
|
||||
|
|
@ -86,9 +74,9 @@ void InstallController::install(DockerContainer container, int port, TransportPr
|
|||
containerConfig.insert(config_key::transport_proto, ProtocolProps::transportProtoToString(transportProto, protocol));
|
||||
|
||||
if (container == DockerContainer::Awg) {
|
||||
QString junkPacketCount = QString::number(QRandomGenerator::global()->bounded(3, 10));
|
||||
QString junkPacketMinSize = QString::number(50);
|
||||
QString junkPacketMaxSize = QString::number(1000);
|
||||
QString junkPacketCount = QString::number(QRandomGenerator::global()->bounded(2, 5));
|
||||
QString junkPacketMinSize = QString::number(10);
|
||||
QString junkPacketMaxSize = QString::number(50);
|
||||
|
||||
int s1 = QRandomGenerator::global()->bounded(15, 150);
|
||||
int s2 = QRandomGenerator::global()->bounded(15, 150);
|
||||
|
|
@ -123,7 +111,10 @@ void InstallController::install(DockerContainer container, int port, TransportPr
|
|||
containerConfig[config_key::transportPacketMagicHeader] = transportPacketMagicHeader;
|
||||
} else if (container == DockerContainer::Sftp) {
|
||||
containerConfig.insert(config_key::userName, protocols::sftp::defaultUserName);
|
||||
containerConfig.insert(config_key::password, Utils::getRandomString(10));
|
||||
containerConfig.insert(config_key::password, Utils::getRandomString(16));
|
||||
} else if (container == DockerContainer::Socks5Proxy) {
|
||||
containerConfig.insert(config_key::userName, protocols::socks5Proxy::defaultUserName);
|
||||
containerConfig.insert(config_key::password, Utils::getRandomString(16));
|
||||
}
|
||||
|
||||
config.insert(config_key::container, ContainerProps::containerToString(container));
|
||||
|
|
@ -149,7 +140,7 @@ void InstallController::install(DockerContainer container, int port, TransportPr
|
|||
QMap<DockerContainer, QJsonObject> installedContainers;
|
||||
ErrorCode errorCode = getAlreadyInstalledContainers(serverCredentials, serverController, installedContainers);
|
||||
if (errorCode) {
|
||||
emit installationErrorOccurred(errorString(errorCode));
|
||||
emit installationErrorOccurred(errorCode);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -158,7 +149,7 @@ void InstallController::install(DockerContainer container, int port, TransportPr
|
|||
if (!installedContainers.contains(container)) {
|
||||
errorCode = serverController->setupContainer(serverCredentials, container, config);
|
||||
if (errorCode) {
|
||||
emit installationErrorOccurred(errorString(errorCode));
|
||||
emit installationErrorOccurred(errorCode);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -169,7 +160,7 @@ void InstallController::install(DockerContainer container, int port, TransportPr
|
|||
}
|
||||
|
||||
if (errorCode) {
|
||||
emit installationErrorOccurred(errorString(errorCode));
|
||||
emit installationErrorOccurred(errorCode);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -204,7 +195,7 @@ void InstallController::installServer(const DockerContainer container, const QMa
|
|||
auto errorCode = vpnConfigurationController.createProtocolConfigForContainer(m_processedServerCredentials, iterator.key(),
|
||||
containerConfig);
|
||||
if (errorCode) {
|
||||
emit installationErrorOccurred(errorString(errorCode));
|
||||
emit installationErrorOccurred(errorCode);
|
||||
return;
|
||||
}
|
||||
containerConfigs.append(containerConfig);
|
||||
|
|
@ -212,7 +203,7 @@ void InstallController::installServer(const DockerContainer container, const QMa
|
|||
errorCode = m_clientManagementModel->appendClient(iterator.key(), serverCredentials, containerConfig,
|
||||
QString("Admin [%1]").arg(QSysInfo::prettyProductName()), serverController);
|
||||
if (errorCode) {
|
||||
emit installationErrorOccurred(errorString(errorCode));
|
||||
emit installationErrorOccurred(errorCode);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -244,7 +235,7 @@ void InstallController::installContainer(const DockerContainer container, const
|
|||
auto errorCode =
|
||||
vpnConfigurationController.createProtocolConfigForContainer(serverCredentials, iterator.key(), containerConfig);
|
||||
if (errorCode) {
|
||||
emit installationErrorOccurred(errorString(errorCode));
|
||||
emit installationErrorOccurred(errorCode);
|
||||
return;
|
||||
}
|
||||
m_serversModel->addContainerConfig(iterator.key(), containerConfig);
|
||||
|
|
@ -252,7 +243,7 @@ void InstallController::installContainer(const DockerContainer container, const
|
|||
errorCode = m_clientManagementModel->appendClient(iterator.key(), serverCredentials, containerConfig,
|
||||
QString("Admin [%1]").arg(QSysInfo::prettyProductName()), serverController);
|
||||
if (errorCode) {
|
||||
emit installationErrorOccurred(errorString(errorCode));
|
||||
emit installationErrorOccurred(errorCode);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -310,7 +301,7 @@ void InstallController::scanServerForInstalledContainers()
|
|||
auto errorCode =
|
||||
vpnConfigurationController.createProtocolConfigForContainer(serverCredentials, container, containerConfig);
|
||||
if (errorCode) {
|
||||
emit installationErrorOccurred(errorString(errorCode));
|
||||
emit installationErrorOccurred(errorCode);
|
||||
return;
|
||||
}
|
||||
m_serversModel->addContainerConfig(container, containerConfig);
|
||||
|
|
@ -319,7 +310,7 @@ void InstallController::scanServerForInstalledContainers()
|
|||
QString("Admin [%1]").arg(QSysInfo::prettyProductName()),
|
||||
serverController);
|
||||
if (errorCode) {
|
||||
emit installationErrorOccurred(errorString(errorCode));
|
||||
emit installationErrorOccurred(errorCode);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -334,7 +325,7 @@ void InstallController::scanServerForInstalledContainers()
|
|||
return;
|
||||
}
|
||||
|
||||
emit installationErrorOccurred(errorString(errorCode));
|
||||
emit installationErrorOccurred(errorCode);
|
||||
}
|
||||
|
||||
ErrorCode InstallController::getAlreadyInstalledContainers(const ServerCredentials &credentials,
|
||||
|
|
@ -363,7 +354,7 @@ ErrorCode InstallController::getAlreadyInstalledContainers(const ServerCredentia
|
|||
if (containerInfo.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
const static QRegularExpression containerAndPortRegExp("(amnezia[-a-z]*).*?:([0-9]*)->[0-9]*/(udp|tcp).*");
|
||||
const static QRegularExpression containerAndPortRegExp("(amnezia[-a-z0-9]*).*?:([0-9]*)->[0-9]*/(udp|tcp).*");
|
||||
QRegularExpressionMatch containerAndPortMatch = containerAndPortRegExp.match(containerInfo);
|
||||
if (containerAndPortMatch.hasMatch()) {
|
||||
QString name = containerAndPortMatch.captured(1);
|
||||
|
|
@ -428,6 +419,20 @@ ErrorCode InstallController::getAlreadyInstalledContainers(const ServerCredentia
|
|||
|
||||
containerConfig.insert(config_key::userName, userName);
|
||||
containerConfig.insert(config_key::password, password);
|
||||
} else if (protocol == Proto::Socks5Proxy) {
|
||||
QString proxyConfig = serverController->getTextFileFromContainer(container, credentials,
|
||||
protocols::socks5Proxy::proxyConfigPath, errorCode);
|
||||
|
||||
const static QRegularExpression usernameAndPasswordRegExp("users (\\w+):CL:(\\w+)");
|
||||
QRegularExpressionMatch usernameAndPasswordMatch = usernameAndPasswordRegExp.match(proxyConfig);
|
||||
|
||||
if (usernameAndPasswordMatch.hasMatch()) {
|
||||
QString userName = usernameAndPasswordMatch.captured(1);
|
||||
QString password = usernameAndPasswordMatch.captured(2);
|
||||
|
||||
containerConfig.insert(config_key::userName, userName);
|
||||
containerConfig.insert(config_key::password, password);
|
||||
}
|
||||
}
|
||||
|
||||
config.insert(config_key::container, ContainerProps::containerToString(container));
|
||||
|
|
@ -515,7 +520,7 @@ void InstallController::updateContainer(QJsonObject config)
|
|||
return;
|
||||
}
|
||||
|
||||
emit installationErrorOccurred(errorString(errorCode));
|
||||
emit installationErrorOccurred(errorCode);
|
||||
}
|
||||
|
||||
void InstallController::rebootProcessedServer()
|
||||
|
|
@ -528,7 +533,7 @@ void InstallController::rebootProcessedServer()
|
|||
if (errorCode == ErrorCode::NoError) {
|
||||
emit rebootProcessedServerFinished(tr("Server '%1' was rebooted").arg(serverName));
|
||||
} else {
|
||||
emit installationErrorOccurred(errorString(errorCode));
|
||||
emit installationErrorOccurred(errorCode);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -552,7 +557,7 @@ void InstallController::removeAllContainers()
|
|||
emit removeAllContainersFinished(tr("All containers from server '%1' have been removed").arg(serverName));
|
||||
return;
|
||||
}
|
||||
emit installationErrorOccurred(errorString(errorCode));
|
||||
emit installationErrorOccurred(errorCode);
|
||||
}
|
||||
|
||||
void InstallController::removeProcessedContainer()
|
||||
|
|
@ -570,30 +575,13 @@ void InstallController::removeProcessedContainer()
|
|||
emit removeProcessedContainerFinished(tr("%1 has been removed from the server '%2'").arg(containerName, serverName));
|
||||
return;
|
||||
}
|
||||
emit installationErrorOccurred(errorString(errorCode));
|
||||
emit installationErrorOccurred(errorCode);
|
||||
}
|
||||
|
||||
void InstallController::removeApiConfig(const int serverIndex)
|
||||
{
|
||||
auto serverConfig = m_serversModel->getServerConfig(serverIndex);
|
||||
|
||||
#ifdef Q_OS_IOS
|
||||
QString vpncName = QString("%1 (%2) %3")
|
||||
.arg(serverConfig[config_key::description].toString())
|
||||
.arg(serverConfig[config_key::hostName].toString())
|
||||
.arg(serverConfig[config_key::vpnproto].toString());
|
||||
|
||||
AmneziaVPN::removeVPNC(vpncName.toStdString());
|
||||
#endif
|
||||
|
||||
serverConfig.remove(config_key::dns1);
|
||||
serverConfig.remove(config_key::dns2);
|
||||
serverConfig.remove(config_key::containers);
|
||||
serverConfig.remove(config_key::hostName);
|
||||
|
||||
serverConfig.insert(config_key::defaultContainer, ContainerProps::containerToString(DockerContainer::None));
|
||||
|
||||
m_serversModel->editServer(serverConfig, serverIndex);
|
||||
m_serversModel->removeApiConfig(serverIndex);
|
||||
emit apiConfigRemoved(tr("Api config removed"));
|
||||
}
|
||||
|
||||
void InstallController::clearCachedProfile(QSharedPointer<ServerController> serverController)
|
||||
|
|
@ -604,6 +592,10 @@ void InstallController::clearCachedProfile(QSharedPointer<ServerController> serv
|
|||
|
||||
int serverIndex = m_serversModel->getProcessedServerIndex();
|
||||
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getProcessedContainerIndex());
|
||||
if (ContainerProps::containerService(container) == ServiceType::Other) {
|
||||
return;
|
||||
}
|
||||
|
||||
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
|
||||
ServerCredentials serverCredentials =
|
||||
qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
|
||||
|
|
@ -651,7 +643,7 @@ void InstallController::mountSftpDrive(const QString &port, const QString &passw
|
|||
QString hostname = serverCredentials.hostName;
|
||||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
mountPath = getNextDriverLetter() + ":";
|
||||
mountPath = Utils::getNextDriverLetter() + ":";
|
||||
// QString cmd = QString("net use \\\\sshfs\\%1@x.x.x.x!%2 /USER:%1 %3")
|
||||
// .arg(labelTftpUserNameText())
|
||||
// .arg(labelTftpPortText())
|
||||
|
|
@ -738,7 +730,7 @@ bool InstallController::checkSshConnection(QSharedPointer<ServerController> serv
|
|||
if (errorCode == ErrorCode::NoError) {
|
||||
m_processedServerCredentials.secretData = decryptedPrivateKey;
|
||||
} else {
|
||||
emit installationErrorOccurred(errorString(errorCode));
|
||||
emit installationErrorOccurred(errorCode);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -747,12 +739,12 @@ bool InstallController::checkSshConnection(QSharedPointer<ServerController> serv
|
|||
output = serverController->checkSshConnection(m_processedServerCredentials, errorCode);
|
||||
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
emit installationErrorOccurred(errorString(errorCode));
|
||||
emit installationErrorOccurred(errorCode);
|
||||
return false;
|
||||
} else {
|
||||
if (output.contains(tr("Please login as the user"))) {
|
||||
output.replace("\n", "");
|
||||
emit installationErrorOccurred(output);
|
||||
emit wrongInstallationUser(output);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -781,6 +773,112 @@ void InstallController::addEmptyServer()
|
|||
emit installServerFinished(tr("Server added successfully"));
|
||||
}
|
||||
|
||||
bool InstallController::fillAvailableServices()
|
||||
{
|
||||
ApiController apiController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv());
|
||||
|
||||
QByteArray responseBody;
|
||||
ErrorCode errorCode = apiController.getServicesList(responseBody);
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
emit installationErrorOccurred(errorCode);
|
||||
return false;
|
||||
}
|
||||
|
||||
QJsonObject data = QJsonDocument::fromJson(responseBody).object();
|
||||
m_apiServicesModel->updateModel(data);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InstallController::installServiceFromApi()
|
||||
{
|
||||
if (m_serversModel->isServerFromApiAlreadyExists(m_apiServicesModel->getCountryCode(), m_apiServicesModel->getSelectedServiceType(),
|
||||
m_apiServicesModel->getSelectedServiceProtocol())) {
|
||||
emit installationErrorOccurred(ErrorCode::ApiConfigAlreadyAdded);
|
||||
return false;
|
||||
}
|
||||
|
||||
ApiController apiController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv());
|
||||
QJsonObject serverConfig;
|
||||
|
||||
ErrorCode errorCode = apiController.getConfigForService(m_settings->getInstallationUuid(true), m_apiServicesModel->getCountryCode(),
|
||||
m_apiServicesModel->getSelectedServiceType(),
|
||||
m_apiServicesModel->getSelectedServiceProtocol(), "", QJsonObject(), serverConfig);
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
emit installationErrorOccurred(errorCode);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto serviceInfo = m_apiServicesModel->getSelectedServiceInfo();
|
||||
QJsonObject apiConfig = serverConfig.value(configKey::apiConfig).toObject();
|
||||
apiConfig.insert(configKey::serviceInfo, serviceInfo);
|
||||
apiConfig.insert(configKey::userCountryCode, m_apiServicesModel->getCountryCode());
|
||||
apiConfig.insert(configKey::serviceType, m_apiServicesModel->getSelectedServiceType());
|
||||
apiConfig.insert(configKey::serviceProtocol, m_apiServicesModel->getSelectedServiceProtocol());
|
||||
|
||||
serverConfig.insert(configKey::apiConfig, apiConfig);
|
||||
|
||||
m_serversModel->addServer(serverConfig);
|
||||
emit installServerFromApiFinished(tr("%1 installed successfully.").arg(m_apiServicesModel->getSelectedServiceName()));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InstallController::updateServiceFromApi(const int serverIndex, const QString &newCountryCode, const QString &newCountryName,
|
||||
bool reloadServiceConfig)
|
||||
{
|
||||
ApiController apiController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv());
|
||||
|
||||
auto serverConfig = m_serversModel->getServerConfig(serverIndex);
|
||||
auto apiConfig = serverConfig.value(configKey::apiConfig).toObject();
|
||||
auto authData = serverConfig.value(configKey::authData).toObject();
|
||||
|
||||
QJsonObject newServerConfig;
|
||||
ErrorCode errorCode = apiController.getConfigForService(
|
||||
m_settings->getInstallationUuid(true), apiConfig.value(configKey::userCountryCode).toString(),
|
||||
apiConfig.value(configKey::serviceType).toString(), apiConfig.value(configKey::serviceProtocol).toString(), newCountryCode,
|
||||
authData, newServerConfig);
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
emit installationErrorOccurred(errorCode);
|
||||
return false;
|
||||
}
|
||||
|
||||
QJsonObject newApiConfig = newServerConfig.value(configKey::apiConfig).toObject();
|
||||
newApiConfig.insert(configKey::userCountryCode, apiConfig.value(configKey::userCountryCode));
|
||||
newApiConfig.insert(configKey::serviceType, apiConfig.value(configKey::serviceType));
|
||||
newApiConfig.insert(configKey::serviceProtocol, apiConfig.value(configKey::serviceProtocol));
|
||||
|
||||
newServerConfig.insert(configKey::apiConfig, newApiConfig);
|
||||
newServerConfig.insert(configKey::authData, authData);
|
||||
newServerConfig.insert(config_key::crc, serverConfig.value(config_key::crc));
|
||||
m_serversModel->editServer(newServerConfig, serverIndex);
|
||||
|
||||
if (reloadServiceConfig) {
|
||||
emit reloadServerFromApiFinished(tr("API config reloaded"));
|
||||
} else if (newCountryName.isEmpty()) {
|
||||
emit updateServerFromApiFinished();
|
||||
} else {
|
||||
emit changeApiCountryFinished(tr("Successfully changed the country of connection to %1").arg(newCountryName));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void InstallController::updateServiceFromTelegram(const int serverIndex)
|
||||
{
|
||||
ApiController *apiController = new ApiController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv());
|
||||
|
||||
auto serverConfig = m_serversModel->getServerConfig(serverIndex);
|
||||
|
||||
apiController->updateServerConfigFromApi(m_settings->getInstallationUuid(true), serverIndex, serverConfig);
|
||||
connect(apiController, &ApiController::finished, this, [this, apiController](const QJsonObject &config, const int serverIndex) {
|
||||
m_serversModel->editServer(config, serverIndex);
|
||||
emit updateServerFromApiFinished();
|
||||
apiController->deleteLater();
|
||||
});
|
||||
connect(apiController, &ApiController::errorOccurred, this, [this, apiController](ErrorCode errorCode) {
|
||||
emit installationErrorOccurred(errorCode);
|
||||
apiController->deleteLater();
|
||||
});
|
||||
}
|
||||
|
||||
bool InstallController::isUpdateDockerContainerRequired(const DockerContainer container, const QJsonObject &oldConfig,
|
||||
const QJsonObject &newConfig)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include "ui/models/containers_model.h"
|
||||
#include "ui/models/protocols_model.h"
|
||||
#include "ui/models/servers_model.h"
|
||||
#include "ui/models/apiServicesModel.h"
|
||||
|
||||
class InstallController : public QObject
|
||||
{
|
||||
|
|
@ -18,6 +19,7 @@ public:
|
|||
explicit InstallController(const QSharedPointer<ServersModel> &serversModel, const QSharedPointer<ContainersModel> &containersModel,
|
||||
const QSharedPointer<ProtocolsModel> &protocolsModel,
|
||||
const QSharedPointer<ClientManagementModel> &clientManagementModel,
|
||||
const QSharedPointer<ApiServicesModel> &apiServicesModel,
|
||||
const std::shared_ptr<Settings> &settings, QObject *parent = nullptr);
|
||||
~InstallController();
|
||||
|
||||
|
|
@ -50,11 +52,21 @@ public slots:
|
|||
|
||||
void addEmptyServer();
|
||||
|
||||
bool fillAvailableServices();
|
||||
bool installServiceFromApi();
|
||||
bool updateServiceFromApi(const int serverIndex, const QString &newCountryCode, const QString &newCountryName, bool reloadServiceConfig = false);
|
||||
|
||||
void updateServiceFromTelegram(const int serverIndex);
|
||||
|
||||
signals:
|
||||
void installContainerFinished(const QString &finishMessage, bool isServiceInstall);
|
||||
void installServerFinished(const QString &finishMessage);
|
||||
void installServerFromApiFinished(const QString &message);
|
||||
|
||||
void updateContainerFinished(const QString &message);
|
||||
void updateServerFromApiFinished();
|
||||
void changeApiCountryFinished(const QString &message);
|
||||
void reloadServerFromApiFinished(const QString &message);
|
||||
|
||||
void scanServerFinished(bool isInstalledContainerFound);
|
||||
|
||||
|
|
@ -63,7 +75,8 @@ signals:
|
|||
void removeAllContainersFinished(const QString &finishedMessage);
|
||||
void removeProcessedContainerFinished(const QString &finishedMessage);
|
||||
|
||||
void installationErrorOccurred(const QString &errorMessage);
|
||||
void installationErrorOccurred(ErrorCode errorCode);
|
||||
void wrongInstallationUser(const QString &message);
|
||||
|
||||
void serverAlreadyExists(int serverIndex);
|
||||
|
||||
|
|
@ -76,6 +89,7 @@ signals:
|
|||
void currentContainerUpdated();
|
||||
|
||||
void cachedProfileCleared(const QString &message);
|
||||
void apiConfigRemoved(const QString &message);
|
||||
|
||||
private:
|
||||
void installServer(const DockerContainer container, const QMap<DockerContainer, QJsonObject> &installedContainers,
|
||||
|
|
@ -94,6 +108,8 @@ private:
|
|||
QSharedPointer<ContainersModel> m_containersModel;
|
||||
QSharedPointer<ProtocolsModel> m_protocolModel;
|
||||
QSharedPointer<ClientManagementModel> m_clientManagementModel;
|
||||
QSharedPointer<ApiServicesModel> m_apiServicesModel;
|
||||
|
||||
std::shared_ptr<Settings> m_settings;
|
||||
|
||||
ServerCredentials m_processedServerCredentials;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
#include "pageController.h"
|
||||
#include "utils/converter.h"
|
||||
#include "core/errorstrings.h"
|
||||
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
||||
#include <QGuiApplication>
|
||||
|
|
@ -8,8 +10,6 @@
|
|||
|
||||
#ifdef Q_OS_ANDROID
|
||||
#include "platforms/android/android_controller.h"
|
||||
#include "platforms/android/android_utils.h"
|
||||
#include <QJniObject>
|
||||
#endif
|
||||
#if defined Q_OS_MAC
|
||||
#include "ui/macos_util.h"
|
||||
|
|
@ -20,38 +20,30 @@ PageController::PageController(const QSharedPointer<ServersModel> &serversModel,
|
|||
: QObject(parent), m_serversModel(serversModel), m_settings(settings)
|
||||
{
|
||||
#ifdef Q_OS_ANDROID
|
||||
// Change color of navigation and status bar's
|
||||
auto initialPageNavigationBarColor = getInitialPageNavigationBarColor();
|
||||
AndroidUtils::runOnAndroidThreadSync([&initialPageNavigationBarColor]() {
|
||||
QJniObject activity = AndroidUtils::getActivity();
|
||||
QJniObject window = activity.callObjectMethod("getWindow", "()Landroid/view/Window;");
|
||||
if (window.isValid()) {
|
||||
window.callMethod<void>("addFlags", "(I)V", 0x80000000);
|
||||
window.callMethod<void>("clearFlags", "(I)V", 0x04000000);
|
||||
window.callMethod<void>("setStatusBarColor", "(I)V", 0xFF0E0E11);
|
||||
window.callMethod<void>("setNavigationBarColor", "(I)V", initialPageNavigationBarColor);
|
||||
}
|
||||
});
|
||||
AndroidController::instance()->setNavigationBarColor(initialPageNavigationBarColor);
|
||||
#endif
|
||||
|
||||
#if defined Q_OS_MACX
|
||||
connect(this, &PageController::raiseMainWindow, []() { setDockIconVisible(true); });
|
||||
connect(this, &PageController::hideMainWindow, []() { setDockIconVisible(false); });
|
||||
#endif
|
||||
|
||||
connect(this, qOverload<ErrorCode>(&PageController::showErrorMessage), this, &PageController::onShowErrorMessage);
|
||||
|
||||
m_isTriggeredByConnectButton = false;
|
||||
}
|
||||
|
||||
QString PageController::getInitialPage()
|
||||
bool PageController::isStartPageVisible()
|
||||
{
|
||||
if (m_serversModel->getServersCount()) {
|
||||
if (m_serversModel->getDefaultServerIndex() < 0) {
|
||||
auto defaultServerIndex = m_serversModel->index(0);
|
||||
m_serversModel->setData(defaultServerIndex, true, ServersModel::Roles::IsDefaultRole);
|
||||
}
|
||||
return getPagePath(PageLoader::PageEnum::PageStart);
|
||||
return false;
|
||||
} else {
|
||||
return getPagePath(PageLoader::PageEnum::PageSetupWizardStart);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -111,14 +103,7 @@ unsigned int PageController::getInitialPageNavigationBarColor()
|
|||
void PageController::updateNavigationBarColor(const int color)
|
||||
{
|
||||
#ifdef Q_OS_ANDROID
|
||||
// Change color of navigation bar
|
||||
AndroidUtils::runOnAndroidThreadSync([&color]() {
|
||||
QJniObject activity = AndroidUtils::getActivity();
|
||||
QJniObject window = activity.callObjectMethod("getWindow", "()Landroid/view/Window;");
|
||||
if (window.isValid()) {
|
||||
window.callMethod<void>("setNavigationBarColor", "(I)V", color);
|
||||
}
|
||||
});
|
||||
AndroidController::instance()->setNavigationBarColor(color);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -127,7 +112,7 @@ void PageController::showOnStartup()
|
|||
if (!m_settings->isStartMinimized()) {
|
||||
emit raiseMainWindow();
|
||||
} else {
|
||||
#ifdef Q_OS_WIN
|
||||
#if defined(Q_OS_WIN) || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
|
||||
emit hideMainWindow();
|
||||
#elif defined Q_OS_MACX
|
||||
setDockIconVisible(false);
|
||||
|
|
@ -161,3 +146,13 @@ int PageController::getDrawerDepth()
|
|||
{
|
||||
return m_drawerDepth;
|
||||
}
|
||||
|
||||
void PageController::onShowErrorMessage(ErrorCode errorCode)
|
||||
{
|
||||
const auto fullErrorMessage = errorString(errorCode);
|
||||
const auto errorMessage = fullErrorMessage.mid(fullErrorMessage.indexOf(". ") + 1); // remove ErrorCode %1.
|
||||
const auto errorUrl = QStringLiteral("https://docs.amnezia.org/troubleshooting/error-codes/#error-%1-%2").arg(static_cast<int>(errorCode)).arg(utils::enumToString(errorCode).toLower());
|
||||
const auto fullMessage = QStringLiteral("<a href=\"%1\" style=\"color: #FBB26A;\">ErrorCode: %2</a>. %3").arg(errorUrl).arg(static_cast<int>(errorCode)).arg(errorMessage);
|
||||
|
||||
emit showErrorMessage(fullMessage);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include <QObject>
|
||||
#include <QQmlEngine>
|
||||
|
||||
#include "core/defs.h"
|
||||
#include "ui/models/servers_model.h"
|
||||
|
||||
namespace PageLoader
|
||||
|
|
@ -34,6 +35,7 @@ namespace PageLoader
|
|||
PageServiceSftpSettings,
|
||||
PageServiceTorWebsiteSettings,
|
||||
PageServiceDnsSettings,
|
||||
PageServiceSocksProxySettings,
|
||||
|
||||
PageSetupWizardStart,
|
||||
PageSetupWizardCredentials,
|
||||
|
|
@ -45,6 +47,8 @@ namespace PageLoader
|
|||
PageSetupWizardTextKey,
|
||||
PageSetupWizardViewConfig,
|
||||
PageSetupWizardQrReader,
|
||||
PageSetupWizardApiServicesList,
|
||||
PageSetupWizardApiServiceInfo,
|
||||
|
||||
PageProtocolOpenVpnSettings,
|
||||
PageProtocolShadowSocksSettings,
|
||||
|
|
@ -55,7 +59,12 @@ namespace PageLoader
|
|||
PageProtocolIKev2Settings,
|
||||
PageProtocolRaw,
|
||||
|
||||
PageShareFullAccess
|
||||
PageProtocolWireGuardClientSettings,
|
||||
PageProtocolAwgClientSettings,
|
||||
|
||||
PageShareFullAccess,
|
||||
|
||||
PageDevMenu
|
||||
};
|
||||
Q_ENUM_NS(PageEnum)
|
||||
|
||||
|
|
@ -73,7 +82,7 @@ public:
|
|||
QObject *parent = nullptr);
|
||||
|
||||
public slots:
|
||||
QString getInitialPage();
|
||||
bool isStartPageVisible();
|
||||
QString getPagePath(PageLoader::PageEnum page);
|
||||
|
||||
void closeWindow();
|
||||
|
|
@ -93,6 +102,9 @@ public slots:
|
|||
void setDrawerDepth(const int depth);
|
||||
int getDrawerDepth();
|
||||
|
||||
private slots:
|
||||
void onShowErrorMessage(amnezia::ErrorCode errorCode);
|
||||
|
||||
signals:
|
||||
void goToPage(PageLoader::PageEnum page, bool slide = true);
|
||||
void goToStartPage();
|
||||
|
|
@ -105,8 +117,8 @@ signals:
|
|||
void closePage();
|
||||
|
||||
void restorePageHomeState(bool isContainerInstalled = false);
|
||||
void replaceStartPage();
|
||||
|
||||
void showErrorMessage(amnezia::ErrorCode);
|
||||
void showErrorMessage(const QString &errorMessage);
|
||||
void showNotificationMessage(const QString &message);
|
||||
|
||||
|
|
|
|||
|
|
@ -88,7 +88,12 @@ void SettingsController::toggleLogging(bool enable)
|
|||
|
||||
void SettingsController::openLogsFolder()
|
||||
{
|
||||
Logger::openLogsFolder();
|
||||
Logger::openLogsFolder(false);
|
||||
}
|
||||
|
||||
void SettingsController::openServiceLogsFolder()
|
||||
{
|
||||
Logger::openLogsFolder(true);
|
||||
}
|
||||
|
||||
void SettingsController::exportLogsFile(const QString &fileName)
|
||||
|
|
@ -100,12 +105,21 @@ void SettingsController::exportLogsFile(const QString &fileName)
|
|||
#endif
|
||||
}
|
||||
|
||||
void SettingsController::exportServiceLogsFile(const QString &fileName)
|
||||
{
|
||||
#ifdef Q_OS_ANDROID
|
||||
AndroidController::instance()->exportLogsFile(fileName);
|
||||
#else
|
||||
SystemController::saveFile(fileName, Logger::getServiceLogFile());
|
||||
#endif
|
||||
}
|
||||
|
||||
void SettingsController::clearLogs()
|
||||
{
|
||||
#ifdef Q_OS_ANDROID
|
||||
AndroidController::instance()->clearLogs();
|
||||
#else
|
||||
Logger::clearLogs();
|
||||
Logger::clearLogs(false);
|
||||
Logger::clearServiceLogs();
|
||||
#endif
|
||||
}
|
||||
|
|
@ -252,3 +266,62 @@ void SettingsController::requestNotificationPermission()
|
|||
AndroidController::instance()->requestNotificationPermission();
|
||||
#endif
|
||||
}
|
||||
|
||||
QString SettingsController::getInstallationUuid()
|
||||
{
|
||||
return m_settings->getInstallationUuid(false);
|
||||
}
|
||||
|
||||
void SettingsController::enableDevMode()
|
||||
{
|
||||
m_isDevModeEnabled = true;
|
||||
emit devModeEnabled();
|
||||
}
|
||||
|
||||
bool SettingsController::isDevModeEnabled()
|
||||
{
|
||||
return m_isDevModeEnabled;
|
||||
}
|
||||
|
||||
void SettingsController::resetGatewayEndpoint()
|
||||
{
|
||||
m_settings->resetGatewayEndpoint();
|
||||
emit gatewayEndpointChanged(m_settings->getGatewayEndpoint());
|
||||
}
|
||||
|
||||
void SettingsController::setGatewayEndpoint(const QString &endpoint)
|
||||
{
|
||||
m_settings->setGatewayEndpoint(endpoint);
|
||||
emit gatewayEndpointChanged(endpoint);
|
||||
}
|
||||
|
||||
QString SettingsController::getGatewayEndpoint()
|
||||
{
|
||||
return m_settings->isDevGatewayEnv() ? "Dev endpoint" : m_settings->getGatewayEndpoint();
|
||||
}
|
||||
|
||||
bool SettingsController::isDevGatewayEnv()
|
||||
{
|
||||
return m_settings->isDevGatewayEnv();
|
||||
}
|
||||
|
||||
void SettingsController::toggleDevGatewayEnv(bool enabled)
|
||||
{
|
||||
m_settings->toggleDevGatewayEnv(enabled);
|
||||
if (enabled) {
|
||||
m_settings->setDevGatewayEndpoint();
|
||||
} else {
|
||||
m_settings->resetGatewayEndpoint();
|
||||
}
|
||||
emit gatewayEndpointChanged(m_settings->getGatewayEndpoint());
|
||||
emit devGatewayEnvChanged(enabled);
|
||||
}
|
||||
|
||||
bool SettingsController::isOnTv()
|
||||
{
|
||||
#ifdef Q_OS_ANDROID
|
||||
return AndroidController::instance()->isOnTv();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
|
@ -25,6 +25,10 @@ public:
|
|||
Q_PROPERTY(bool isLoggingEnabled READ isLoggingEnabled WRITE toggleLogging NOTIFY loggingStateChanged)
|
||||
Q_PROPERTY(bool isNotificationPermissionGranted READ isNotificationPermissionGranted NOTIFY onNotificationStateChanged)
|
||||
|
||||
Q_PROPERTY(bool isDevModeEnabled READ isDevModeEnabled NOTIFY devModeEnabled)
|
||||
Q_PROPERTY(QString gatewayEndpoint READ getGatewayEndpoint WRITE setGatewayEndpoint NOTIFY gatewayEndpointChanged)
|
||||
Q_PROPERTY(bool isDevGatewayEnv READ isDevGatewayEnv WRITE toggleDevGatewayEnv NOTIFY devGatewayEnvChanged)
|
||||
|
||||
public slots:
|
||||
void toggleAmneziaDns(bool enable);
|
||||
bool isAmneziaDnsEnabled();
|
||||
|
|
@ -39,7 +43,9 @@ public slots:
|
|||
void toggleLogging(bool enable);
|
||||
|
||||
void openLogsFolder();
|
||||
void openServiceLogsFolder();
|
||||
void exportLogsFile(const QString &fileName);
|
||||
void exportServiceLogsFile(const QString &fileName);
|
||||
void clearLogs();
|
||||
|
||||
void backupAppConfig(const QString &fileName);
|
||||
|
|
@ -70,6 +76,19 @@ public slots:
|
|||
bool isNotificationPermissionGranted();
|
||||
void requestNotificationPermission();
|
||||
|
||||
QString getInstallationUuid();
|
||||
|
||||
void enableDevMode();
|
||||
bool isDevModeEnabled();
|
||||
|
||||
void resetGatewayEndpoint();
|
||||
void setGatewayEndpoint(const QString &endpoint);
|
||||
QString getGatewayEndpoint();
|
||||
bool isDevGatewayEnv();
|
||||
void toggleDevGatewayEnv(bool enabled);
|
||||
|
||||
bool isOnTv();
|
||||
|
||||
signals:
|
||||
void primaryDnsChanged();
|
||||
void secondaryDnsChanged();
|
||||
|
|
@ -89,6 +108,10 @@ signals:
|
|||
|
||||
void onNotificationStateChanged();
|
||||
|
||||
void devModeEnabled();
|
||||
void gatewayEndpointChanged(const QString &endpoint);
|
||||
void devGatewayEnvChanged(bool enabled);
|
||||
|
||||
private:
|
||||
QSharedPointer<ServersModel> m_serversModel;
|
||||
QSharedPointer<ContainersModel> m_containersModel;
|
||||
|
|
@ -101,6 +124,8 @@ private:
|
|||
|
||||
QDateTime m_loggingDisableDate;
|
||||
|
||||
bool m_isDevModeEnabled = false;
|
||||
|
||||
void checkIfNeedDisableLogs();
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,14 @@ void SystemController::saveFile(QString fileName, const QString &data)
|
|||
return;
|
||||
#else
|
||||
QFileInfo fi(fileName);
|
||||
QDesktopServices::openUrl(fi.absoluteDir().absolutePath());
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
const auto url = "file://" + fi.absoluteDir().absolutePath();
|
||||
#else
|
||||
const auto url = fi.absoluteDir().absolutePath();
|
||||
#endif
|
||||
|
||||
QDesktopServices::openUrl(url);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -118,3 +125,12 @@ void SystemController::setQmlRoot(QObject *qmlRoot)
|
|||
{
|
||||
m_qmlRoot = qmlRoot;
|
||||
}
|
||||
|
||||
bool SystemController::isAuthenticated()
|
||||
{
|
||||
#ifdef Q_OS_ANDROID
|
||||
return AndroidController::instance()->requestAuthentication();
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ public slots:
|
|||
|
||||
void setQmlRoot(QObject *qmlRoot);
|
||||
|
||||
bool isAuthenticated();
|
||||
signals:
|
||||
void fileDialogClosed(const bool isAccepted);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue