mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-06-23 02:00:20 +07:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 776e7c2504 |
+1
-1
Submodule client/3rd-prebuilt updated: c969f28b84...a5901c84b7
@@ -151,6 +151,7 @@ include_directories(mozilla/models)
|
|||||||
|
|
||||||
if(NOT IOS)
|
if(NOT IOS)
|
||||||
set(HEADERS ${HEADERS}
|
set(HEADERS ${HEADERS}
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/platforms/ios/MobileUtils.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/platforms/ios/QRCodeReaderBase.h
|
${CMAKE_CURRENT_LIST_DIR}/platforms/ios/QRCodeReaderBase.h
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
@@ -192,6 +193,7 @@ endif()
|
|||||||
|
|
||||||
if(NOT IOS)
|
if(NOT IOS)
|
||||||
set(SOURCES ${SOURCES}
|
set(SOURCES ${SOURCES}
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/platforms/ios/MobileUtils.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/platforms/ios/QRCodeReaderBase.cpp
|
${CMAKE_CURRENT_LIST_DIR}/platforms/ios/QRCodeReaderBase.cpp
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -55,7 +55,6 @@ AmneziaApplication::AmneziaApplication(int &argc, char *argv[], bool allowSecond
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_settings = std::shared_ptr<Settings>(new Settings);
|
m_settings = std::shared_ptr<Settings>(new Settings);
|
||||||
m_nam = new QNetworkAccessManager(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AmneziaApplication::~AmneziaApplication()
|
AmneziaApplication::~AmneziaApplication()
|
||||||
@@ -151,7 +150,7 @@ void AmneziaApplication::init()
|
|||||||
|
|
||||||
connect(m_notificationHandler.get(), &NotificationHandler::raiseRequested, m_pageController.get(), &PageController::raiseMainWindow);
|
connect(m_notificationHandler.get(), &NotificationHandler::raiseRequested, m_pageController.get(), &PageController::raiseMainWindow);
|
||||||
connect(m_notificationHandler.get(), &NotificationHandler::connectRequested, m_connectionController.get(),
|
connect(m_notificationHandler.get(), &NotificationHandler::connectRequested, m_connectionController.get(),
|
||||||
static_cast<void (ConnectionController::*)()>(&ConnectionController::openConnection));
|
&ConnectionController::openConnection);
|
||||||
connect(m_notificationHandler.get(), &NotificationHandler::disconnectRequested, m_connectionController.get(),
|
connect(m_notificationHandler.get(), &NotificationHandler::disconnectRequested, m_connectionController.get(),
|
||||||
&ConnectionController::closeConnection);
|
&ConnectionController::closeConnection);
|
||||||
connect(this, &AmneziaApplication::translationsUpdated, m_notificationHandler.get(), &NotificationHandler::onTranslationsUpdated);
|
connect(this, &AmneziaApplication::translationsUpdated, m_notificationHandler.get(), &NotificationHandler::onTranslationsUpdated);
|
||||||
@@ -363,22 +362,16 @@ void AmneziaApplication::initControllers()
|
|||||||
new ConnectionController(m_serversModel, m_containersModel, m_clientManagementModel, m_vpnConnection, m_settings));
|
new ConnectionController(m_serversModel, m_containersModel, m_clientManagementModel, m_vpnConnection, m_settings));
|
||||||
m_engine->rootContext()->setContextProperty("ConnectionController", m_connectionController.get());
|
m_engine->rootContext()->setContextProperty("ConnectionController", m_connectionController.get());
|
||||||
|
|
||||||
connect(m_connectionController.get(), qOverload<const QString &>(&ConnectionController::connectionErrorOccurred), this, [this](const QString &errorMessage) {
|
connect(m_connectionController.get(), &ConnectionController::connectionErrorOccurred, this, [this](const QString &errorMessage) {
|
||||||
emit m_pageController->showErrorMessage(errorMessage);
|
emit m_pageController->showErrorMessage(errorMessage);
|
||||||
emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Disconnected);
|
emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Disconnected);
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(m_connectionController.get(), qOverload<ErrorCode>(&ConnectionController::connectionErrorOccurred), this, [this](ErrorCode errorCode) {
|
|
||||||
emit m_pageController->showErrorMessage(errorCode);
|
|
||||||
emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Disconnected);
|
|
||||||
});
|
|
||||||
|
|
||||||
connect(m_connectionController.get(), &ConnectionController::connectButtonClicked, m_connectionController.get(),
|
connect(m_connectionController.get(), &ConnectionController::connectButtonClicked, m_connectionController.get(),
|
||||||
&ConnectionController::toggleConnection, Qt::QueuedConnection);
|
&ConnectionController::toggleConnection, Qt::QueuedConnection);
|
||||||
|
|
||||||
connect(this, &AmneziaApplication::translationsUpdated, m_connectionController.get(), &ConnectionController::onTranslationsUpdated);
|
connect(this, &AmneziaApplication::translationsUpdated, m_connectionController.get(), &ConnectionController::onTranslationsUpdated);
|
||||||
|
|
||||||
m_pageController.reset(new PageController(m_serversModel, m_settings, m_languageModel));
|
m_pageController.reset(new PageController(m_serversModel, m_settings));
|
||||||
m_engine->rootContext()->setContextProperty("PageController", m_pageController.get());
|
m_engine->rootContext()->setContextProperty("PageController", m_pageController.get());
|
||||||
|
|
||||||
m_installController.reset(new InstallController(m_serversModel, m_containersModel, m_protocolsModel, m_clientManagementModel, m_settings));
|
m_installController.reset(new InstallController(m_serversModel, m_containersModel, m_protocolsModel, m_clientManagementModel, m_settings));
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
#define AMNEZIA_APPLICATION_H
|
#define AMNEZIA_APPLICATION_H
|
||||||
|
|
||||||
#include <QCommandLineParser>
|
#include <QCommandLineParser>
|
||||||
#include <QNetworkAccessManager>
|
|
||||||
#include <QQmlApplicationEngine>
|
#include <QQmlApplicationEngine>
|
||||||
#include <QQmlContext>
|
#include <QQmlContext>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
@@ -76,7 +75,6 @@ public:
|
|||||||
bool parseCommands();
|
bool parseCommands();
|
||||||
|
|
||||||
QQmlApplicationEngine *qmlEngine() const;
|
QQmlApplicationEngine *qmlEngine() const;
|
||||||
QNetworkAccessManager *manager() { return m_nam; }
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void translationsUpdated();
|
void translationsUpdated();
|
||||||
@@ -130,8 +128,6 @@ private:
|
|||||||
QScopedPointer<SitesController> m_sitesController;
|
QScopedPointer<SitesController> m_sitesController;
|
||||||
QScopedPointer<SystemController> m_systemController;
|
QScopedPointer<SystemController> m_systemController;
|
||||||
QScopedPointer<AppSplitTunnelingController> m_appSplitTunnelingController;
|
QScopedPointer<AppSplitTunnelingController> m_appSplitTunnelingController;
|
||||||
|
|
||||||
QNetworkAccessManager *m_nam;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // AMNEZIA_APPLICATION_H
|
#endif // AMNEZIA_APPLICATION_H
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ set(SOURCES ${SOURCES}
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/iosglue.mm
|
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/iosglue.mm
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/QRCodeReaderBase.mm
|
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/QRCodeReaderBase.mm
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/QtAppDelegate.mm
|
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/QtAppDelegate.mm
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/MobileUtils.mm
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,9 +5,7 @@
|
|||||||
#include <QNetworkReply>
|
#include <QNetworkReply>
|
||||||
#include <QtConcurrent>
|
#include <QtConcurrent>
|
||||||
|
|
||||||
#include "amnezia_application.h"
|
|
||||||
#include "configurators/wireguard_configurator.h"
|
#include "configurators/wireguard_configurator.h"
|
||||||
#include "version.h"
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@@ -21,10 +19,7 @@ namespace
|
|||||||
constexpr char certificate[] = "certificate";
|
constexpr char certificate[] = "certificate";
|
||||||
constexpr char publicKey[] = "public_key";
|
constexpr char publicKey[] = "public_key";
|
||||||
constexpr char protocol[] = "protocol";
|
constexpr char protocol[] = "protocol";
|
||||||
|
|
||||||
constexpr char uuid[] = "installation_uuid";
|
constexpr char uuid[] = "installation_uuid";
|
||||||
constexpr char osVersion[] = "os_version";
|
|
||||||
constexpr char appVersion[] = "app_version";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,7 +27,8 @@ ApiController::ApiController(QObject *parent) : QObject(parent)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApiController::processApiConfig(const QString &protocol, const ApiController::ApiPayloadData &apiPayloadData, QString &config)
|
void ApiController::processApiConfig(const QString &protocol, const ApiController::ApiPayloadData &apiPayloadData,
|
||||||
|
QString &config)
|
||||||
{
|
{
|
||||||
if (protocol == configKey::cloak) {
|
if (protocol == configKey::cloak) {
|
||||||
config.replace("<key>", "<key>\n");
|
config.replace("<key>", "<key>\n");
|
||||||
@@ -65,52 +61,53 @@ QJsonObject ApiController::fillApiPayload(const QString &protocol, const ApiCont
|
|||||||
} else if (protocol == configKey::awg) {
|
} else if (protocol == configKey::awg) {
|
||||||
obj[configKey::publicKey] = apiPayloadData.wireGuardClientPubKey;
|
obj[configKey::publicKey] = apiPayloadData.wireGuardClientPubKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
obj[configKey::osVersion] = QSysInfo::productType();
|
|
||||||
obj[configKey::appVersion] = QString(APP_VERSION);
|
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApiController::updateServerConfigFromApi(const QString &installationUuid, const int serverIndex, QJsonObject serverConfig)
|
ErrorCode ApiController::updateServerConfigFromApi(const QString &installationUuid, QJsonObject &serverConfig)
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_IOS
|
QFutureWatcher<ErrorCode> watcher;
|
||||||
IosController::Instance()->requestInetAccess();
|
|
||||||
QThread::msleep(10);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
QFuture<ErrorCode> future = QtConcurrent::run([this, &serverConfig, &installationUuid]() {
|
||||||
auto containerConfig = serverConfig.value(config_key::containers).toArray();
|
auto containerConfig = serverConfig.value(config_key::containers).toArray();
|
||||||
|
|
||||||
if (serverConfig.value(config_key::configVersion).toInt()) {
|
if (serverConfig.value(config_key::configVersion).toInt()) {
|
||||||
|
QNetworkAccessManager manager;
|
||||||
|
|
||||||
QNetworkRequest request;
|
QNetworkRequest request;
|
||||||
request.setTransferTimeout(7000);
|
request.setTransferTimeout(7000);
|
||||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||||
request.setRawHeader("Authorization", "Api-Key " + serverConfig.value(configKey::accessToken).toString().toUtf8());
|
request.setRawHeader("Authorization",
|
||||||
|
"Api-Key " + serverConfig.value(configKey::accessToken).toString().toUtf8());
|
||||||
QString endpoint = serverConfig.value(configKey::apiEdnpoint).toString();
|
QString endpoint = serverConfig.value(configKey::apiEdnpoint).toString();
|
||||||
request.setUrl(endpoint);
|
request.setUrl(endpoint);
|
||||||
|
|
||||||
QString protocol = serverConfig.value(configKey::protocol).toString();
|
QString protocol = serverConfig.value(configKey::protocol).toString();
|
||||||
|
|
||||||
ApiPayloadData apiPayloadData = generateApiPayloadData(protocol);
|
auto apiPayloadData = generateApiPayloadData(protocol);
|
||||||
|
|
||||||
QJsonObject apiPayload = fillApiPayload(protocol, apiPayloadData);
|
auto apiPayload = fillApiPayload(protocol, apiPayloadData);
|
||||||
apiPayload[configKey::uuid] = installationUuid;
|
apiPayload[configKey::uuid] = installationUuid;
|
||||||
|
|
||||||
QByteArray requestBody = QJsonDocument(apiPayload).toJson();
|
QByteArray requestBody = QJsonDocument(apiPayload).toJson();
|
||||||
|
|
||||||
QNetworkReply *reply = amnApp->manager()->post(request, requestBody); // ??
|
QScopedPointer<QNetworkReply> reply;
|
||||||
|
reply.reset(manager.post(request, requestBody));
|
||||||
|
|
||||||
|
QEventLoop wait;
|
||||||
|
QObject::connect(reply.get(), &QNetworkReply::finished, &wait, &QEventLoop::quit);
|
||||||
|
wait.exec();
|
||||||
|
|
||||||
QObject::connect(reply, &QNetworkReply::finished, [this, reply, protocol, apiPayloadData, serverIndex, serverConfig]() mutable {
|
|
||||||
if (reply->error() == QNetworkReply::NoError) {
|
if (reply->error() == QNetworkReply::NoError) {
|
||||||
QString contents = QString::fromUtf8(reply->readAll());
|
QString contents = QString::fromUtf8(reply->readAll());
|
||||||
QString data = QJsonDocument::fromJson(contents.toUtf8()).object().value(config_key::config).toString();
|
auto data = QJsonDocument::fromJson(contents.toUtf8()).object().value(config_key::config).toString();
|
||||||
|
|
||||||
data.replace("vpn://", "");
|
data.replace("vpn://", "");
|
||||||
QByteArray ba = QByteArray::fromBase64(data.toUtf8(), QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
|
QByteArray ba = QByteArray::fromBase64(data.toUtf8(),
|
||||||
|
QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
|
||||||
|
|
||||||
if (ba.isEmpty()) {
|
if (ba.isEmpty()) {
|
||||||
emit errorOccurred(ErrorCode::ApiConfigEmptyError);
|
return ErrorCode::ApiConfigDownloadError;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray ba_uncompressed = qUncompress(ba);
|
QByteArray ba_uncompressed = qUncompress(ba);
|
||||||
@@ -122,37 +119,30 @@ void ApiController::updateServerConfigFromApi(const QString &installationUuid, c
|
|||||||
processApiConfig(protocol, apiPayloadData, configStr);
|
processApiConfig(protocol, apiPayloadData, configStr);
|
||||||
|
|
||||||
QJsonObject apiConfig = QJsonDocument::fromJson(configStr.toUtf8()).object();
|
QJsonObject apiConfig = QJsonDocument::fromJson(configStr.toUtf8()).object();
|
||||||
serverConfig[config_key::dns1] = apiConfig.value(config_key::dns1);
|
|
||||||
serverConfig[config_key::dns2] = apiConfig.value(config_key::dns2);
|
serverConfig.insert(config_key::dns1, apiConfig.value(config_key::dns1));
|
||||||
serverConfig[config_key::containers] = apiConfig.value(config_key::containers);
|
serverConfig.insert(config_key::dns2, apiConfig.value(config_key::dns2));
|
||||||
serverConfig[config_key::hostName] = apiConfig.value(config_key::hostName);
|
serverConfig.insert(config_key::containers, apiConfig.value(config_key::containers));
|
||||||
|
serverConfig.insert(config_key::hostName, apiConfig.value(config_key::hostName));
|
||||||
|
|
||||||
auto defaultContainer = apiConfig.value(config_key::defaultContainer).toString();
|
auto defaultContainer = apiConfig.value(config_key::defaultContainer).toString();
|
||||||
serverConfig[config_key::defaultContainer] = defaultContainer;
|
serverConfig.insert(config_key::defaultContainer, defaultContainer);
|
||||||
|
|
||||||
emit configUpdated(true, serverConfig, serverIndex);
|
|
||||||
} else {
|
|
||||||
if (reply->error() == QNetworkReply::NetworkError::OperationCanceledError
|
|
||||||
|| reply->error() == QNetworkReply::NetworkError::TimeoutError) {
|
|
||||||
emit errorOccurred(ErrorCode::ApiConfigTimeoutError);
|
|
||||||
} else {
|
} else {
|
||||||
QString err = reply->errorString();
|
QString err = reply->errorString();
|
||||||
qDebug() << QString::fromUtf8(reply->readAll());
|
qDebug() << QString::fromUtf8(reply->readAll());
|
||||||
qDebug() << reply->error();
|
qDebug() << reply->error();
|
||||||
qDebug() << err;
|
qDebug() << err;
|
||||||
qDebug() << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
|
qDebug() << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
|
||||||
emit errorOccurred(ErrorCode::ApiConfigDownloadError);
|
return ErrorCode::ApiConfigDownloadError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return ErrorCode::NoError;
|
||||||
reply->deleteLater();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
QObject::connect(reply, &QNetworkReply::errorOccurred,
|
QEventLoop wait;
|
||||||
[this, reply](QNetworkReply::NetworkError error) { qDebug() << reply->errorString() << error; });
|
connect(&watcher, &QFutureWatcher<ErrorCode>::finished, &wait, &QEventLoop::quit);
|
||||||
connect(reply, &QNetworkReply::sslErrors, [this, reply](const QList<QSslError> &errors) {
|
watcher.setFuture(future);
|
||||||
qDebug().noquote() << errors;
|
wait.exec();
|
||||||
emit errorOccurred(ErrorCode::ApiConfigSslError);
|
|
||||||
});
|
return watcher.result();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,10 +5,6 @@
|
|||||||
|
|
||||||
#include "configurators/openvpn_configurator.h"
|
#include "configurators/openvpn_configurator.h"
|
||||||
|
|
||||||
#ifdef Q_OS_IOS
|
|
||||||
#include "platforms/ios/ios_controller.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class ApiController : public QObject
|
class ApiController : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -17,15 +13,10 @@ public:
|
|||||||
explicit ApiController(QObject *parent = nullptr);
|
explicit ApiController(QObject *parent = nullptr);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void updateServerConfigFromApi(const QString &installationUuid, const int serverIndex, QJsonObject serverConfig);
|
ErrorCode updateServerConfigFromApi(const QString &installationUuid, QJsonObject &serverConfig);
|
||||||
|
|
||||||
signals:
|
|
||||||
void errorOccurred(ErrorCode errorCode);
|
|
||||||
void configUpdated(const bool updateConfig, const QJsonObject &config, const int serverIndex);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct ApiPayloadData
|
struct ApiPayloadData {
|
||||||
{
|
|
||||||
OpenVpnConfigurator::ConnectionData certRequest;
|
OpenVpnConfigurator::ConnectionData certRequest;
|
||||||
|
|
||||||
QString wireGuardClientPrivKey;
|
QString wireGuardClientPrivKey;
|
||||||
|
|||||||
@@ -36,10 +36,6 @@ namespace amnezia
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace error_code_ns
|
|
||||||
{
|
|
||||||
Q_NAMESPACE
|
|
||||||
// TODO: change to enum class
|
|
||||||
enum ErrorCode {
|
enum ErrorCode {
|
||||||
// General error codes
|
// General error codes
|
||||||
NoError = 0,
|
NoError = 0,
|
||||||
@@ -103,9 +99,6 @@ namespace amnezia
|
|||||||
// Api errors
|
// Api errors
|
||||||
ApiConfigDownloadError = 1100,
|
ApiConfigDownloadError = 1100,
|
||||||
ApiConfigAlreadyAdded = 1101,
|
ApiConfigAlreadyAdded = 1101,
|
||||||
ApiConfigEmptyError = 1102,
|
|
||||||
ApiConfigTimeoutError = 1103,
|
|
||||||
ApiConfigSslError = 1104,
|
|
||||||
|
|
||||||
// QFile errors
|
// QFile errors
|
||||||
OpenError = 1200,
|
OpenError = 1200,
|
||||||
@@ -115,10 +108,6 @@ namespace amnezia
|
|||||||
FatalError = 1204,
|
FatalError = 1204,
|
||||||
AbortError = 1205
|
AbortError = 1205
|
||||||
};
|
};
|
||||||
Q_ENUM_NS(ErrorCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
using ErrorCode = error_code_ns::ErrorCode;
|
|
||||||
|
|
||||||
} // namespace amnezia
|
} // namespace amnezia
|
||||||
|
|
||||||
|
|||||||
@@ -8,68 +8,65 @@ QString errorString(ErrorCode code) {
|
|||||||
switch (code) {
|
switch (code) {
|
||||||
|
|
||||||
// General error codes
|
// General error codes
|
||||||
case(ErrorCode::NoError): errorMessage = QObject::tr("No error"); break;
|
case(NoError): errorMessage = QObject::tr("No error"); break;
|
||||||
case(ErrorCode::UnknownError): errorMessage = QObject::tr("Unknown Error"); break;
|
case(UnknownError): errorMessage = QObject::tr("Unknown Error"); break;
|
||||||
case(ErrorCode::NotImplementedError): errorMessage = QObject::tr("Function not implemented"); break;
|
case(NotImplementedError): errorMessage = QObject::tr("Function not implemented"); break;
|
||||||
case(ErrorCode::AmneziaServiceNotRunning): errorMessage = QObject::tr("Background service is not running"); break;
|
case(AmneziaServiceNotRunning): errorMessage = QObject::tr("Background service is not running"); break;
|
||||||
|
|
||||||
// Server errors
|
// Server errors
|
||||||
case(ErrorCode::ServerCheckFailed): errorMessage = QObject::tr("Server check failed"); break;
|
case(ServerCheckFailed): errorMessage = QObject::tr("Server check failed"); break;
|
||||||
case(ErrorCode::ServerPortAlreadyAllocatedError): errorMessage = QObject::tr("Server port already used. Check for another software"); break;
|
case(ServerPortAlreadyAllocatedError): errorMessage = QObject::tr("Server port already used. Check for another software"); break;
|
||||||
case(ErrorCode::ServerContainerMissingError): errorMessage = QObject::tr("Server error: Docker container missing"); break;
|
case(ServerContainerMissingError): errorMessage = QObject::tr("Server error: Docker container missing"); break;
|
||||||
case(ErrorCode::ServerDockerFailedError): errorMessage = QObject::tr("Server error: Docker failed"); break;
|
case(ServerDockerFailedError): errorMessage = QObject::tr("Server error: Docker failed"); break;
|
||||||
case(ErrorCode::ServerCancelInstallation): errorMessage = QObject::tr("Installation canceled by user"); break;
|
case(ServerCancelInstallation): errorMessage = QObject::tr("Installation canceled by user"); break;
|
||||||
case(ErrorCode::ServerUserNotInSudo): errorMessage = QObject::tr("The user does not have permission to use sudo"); break;
|
case(ServerUserNotInSudo): errorMessage = QObject::tr("The user does not have permission to use sudo"); break;
|
||||||
case(ErrorCode::ServerPacketManagerError): errorMessage = QObject::tr("Server error: Packet manager error"); break;
|
case(ServerPacketManagerError): errorMessage = QObject::tr("Server error: Packet manager error"); break;
|
||||||
|
|
||||||
// Libssh errors
|
// Libssh errors
|
||||||
case(ErrorCode::SshRequestDeniedError): errorMessage = QObject::tr("Ssh request was denied"); break;
|
case(SshRequestDeniedError): errorMessage = QObject::tr("Ssh request was denied"); break;
|
||||||
case(ErrorCode::SshInterruptedError): errorMessage = QObject::tr("Ssh request was interrupted"); break;
|
case(SshInterruptedError): errorMessage = QObject::tr("Ssh request was interrupted"); break;
|
||||||
case(ErrorCode::SshInternalError): errorMessage = QObject::tr("Ssh internal error"); break;
|
case(SshInternalError): errorMessage = QObject::tr("Ssh internal error"); break;
|
||||||
case(ErrorCode::SshPrivateKeyError): errorMessage = QObject::tr("Invalid private key or invalid passphrase entered"); break;
|
case(SshPrivateKeyError): errorMessage = QObject::tr("Invalid private key or invalid passphrase entered"); break;
|
||||||
case(ErrorCode::SshPrivateKeyFormatError): errorMessage = QObject::tr("The selected private key format is not supported, use openssh ED25519 key types or PEM key types"); break;
|
case(SshPrivateKeyFormatError): errorMessage = QObject::tr("The selected private key format is not supported, use openssh ED25519 key types or PEM key types"); break;
|
||||||
case(ErrorCode::SshTimeoutError): errorMessage = QObject::tr("Timeout connecting to server"); break;
|
case(SshTimeoutError): errorMessage = QObject::tr("Timeout connecting to server"); break;
|
||||||
|
|
||||||
// Ssh scp errors
|
// Ssh scp errors
|
||||||
case(ErrorCode::SshScpFailureError): errorMessage = QObject::tr("Scp error: Generic failure"); break;
|
case(SshScpFailureError): errorMessage = QObject::tr("Scp error: Generic failure"); break;
|
||||||
|
|
||||||
// Local errors
|
// Local errors
|
||||||
case (ErrorCode::OpenVpnConfigMissing): errorMessage = QObject::tr("OpenVPN config missing"); break;
|
case (OpenVpnConfigMissing): errorMessage = QObject::tr("OpenVPN config missing"); break;
|
||||||
case (ErrorCode::OpenVpnManagementServerError): errorMessage = QObject::tr("OpenVPN management server error"); break;
|
case (OpenVpnManagementServerError): errorMessage = QObject::tr("OpenVPN management server error"); break;
|
||||||
|
|
||||||
// Distro errors
|
// Distro errors
|
||||||
case (ErrorCode::OpenVpnExecutableMissing): errorMessage = QObject::tr("OpenVPN executable missing"); break;
|
case (OpenVpnExecutableMissing): errorMessage = QObject::tr("OpenVPN executable missing"); break;
|
||||||
case (ErrorCode::ShadowSocksExecutableMissing): errorMessage = QObject::tr("ShadowSocks (ss-local) executable missing"); break;
|
case (ShadowSocksExecutableMissing): errorMessage = QObject::tr("ShadowSocks (ss-local) executable missing"); break;
|
||||||
case (ErrorCode::CloakExecutableMissing): errorMessage = QObject::tr("Cloak (ck-client) executable missing"); break;
|
case (CloakExecutableMissing): errorMessage = QObject::tr("Cloak (ck-client) executable missing"); break;
|
||||||
case (ErrorCode::AmneziaServiceConnectionFailed): errorMessage = QObject::tr("Amnezia helper service error"); break;
|
case (AmneziaServiceConnectionFailed): errorMessage = QObject::tr("Amnezia helper service error"); break;
|
||||||
case (ErrorCode::OpenSslFailed): errorMessage = QObject::tr("OpenSSL failed"); break;
|
case (OpenSslFailed): errorMessage = QObject::tr("OpenSSL failed"); break;
|
||||||
|
|
||||||
// VPN errors
|
// VPN errors
|
||||||
case (ErrorCode::OpenVpnAdaptersInUseError): errorMessage = QObject::tr("Can't connect: another VPN connection is active"); break;
|
case (OpenVpnAdaptersInUseError): errorMessage = QObject::tr("Can't connect: another VPN connection is active"); break;
|
||||||
case (ErrorCode::OpenVpnTapAdapterError): errorMessage = QObject::tr("Can't setup OpenVPN TAP network adapter"); break;
|
case (OpenVpnTapAdapterError): errorMessage = QObject::tr("Can't setup OpenVPN TAP network adapter"); break;
|
||||||
case (ErrorCode::AddressPoolError): errorMessage = QObject::tr("VPN pool error: no available addresses"); break;
|
case (AddressPoolError): errorMessage = QObject::tr("VPN pool error: no available addresses"); break;
|
||||||
|
|
||||||
case (ErrorCode::ImportInvalidConfigError): errorMessage = QObject::tr("The config does not contain any containers and credentials for connecting to the server"); break;
|
case (ImportInvalidConfigError): errorMessage = QObject::tr("The config does not contain any containers and credentials for connecting to the server"); break;
|
||||||
|
|
||||||
// Android errors
|
// Android errors
|
||||||
case (ErrorCode::AndroidError): errorMessage = QObject::tr("VPN connection error"); break;
|
case (AndroidError): errorMessage = QObject::tr("VPN connection error"); break;
|
||||||
|
|
||||||
// Api errors
|
// Api errors
|
||||||
case (ErrorCode::ApiConfigDownloadError): errorMessage = QObject::tr("Error when retrieving configuration from API"); break;
|
case (ApiConfigDownloadError): errorMessage = QObject::tr("Error when retrieving configuration from API"); break;
|
||||||
case (ErrorCode::ApiConfigAlreadyAdded): errorMessage = QObject::tr("This config has already been added to the application"); break;
|
case (ApiConfigAlreadyAdded): errorMessage = QObject::tr("This config has already been added to the application"); break;
|
||||||
case (ErrorCode::ApiConfigEmptyError): errorMessage = QObject::tr("In the response from the server, an empty config was received"); break;
|
|
||||||
case (ErrorCode::ApiConfigSslError): errorMessage = QObject::tr("SSL error occurred"); break;
|
|
||||||
case (ErrorCode::ApiConfigTimeoutError): errorMessage = QObject::tr("Server response timeout on api request"); break;
|
|
||||||
|
|
||||||
// QFile errors
|
// QFile errors
|
||||||
case(ErrorCode::OpenError): errorMessage = QObject::tr("QFile error: The file could not be opened"); break;
|
case(OpenError): errorMessage = QObject::tr("QFile error: The file could not be opened"); break;
|
||||||
case(ErrorCode::ReadError): errorMessage = QObject::tr("QFile error: An error occurred when reading from the file"); break;
|
case(ReadError): errorMessage = QObject::tr("QFile error: An error occurred when reading from the file"); break;
|
||||||
case(ErrorCode::PermissionsError): errorMessage = QObject::tr("QFile error: The file could not be accessed"); break;
|
case(PermissionsError): errorMessage = QObject::tr("QFile error: The file could not be accessed"); break;
|
||||||
case(ErrorCode::UnspecifiedError): errorMessage = QObject::tr("QFile error: An unspecified error occurred"); break;
|
case(UnspecifiedError): errorMessage = QObject::tr("QFile error: An unspecified error occurred"); break;
|
||||||
case(ErrorCode::FatalError): errorMessage = QObject::tr("QFile error: A fatal error occurred"); break;
|
case(FatalError): errorMessage = QObject::tr("QFile error: A fatal error occurred"); break;
|
||||||
case(ErrorCode::AbortError): errorMessage = QObject::tr("QFile error: The operation was aborted"); break;
|
case(AbortError): errorMessage = QObject::tr("QFile error: The operation was aborted"); break;
|
||||||
|
|
||||||
case(ErrorCode::InternalError):
|
case(InternalError):
|
||||||
default:
|
default:
|
||||||
errorMessage = QObject::tr("Internal error"); break;
|
errorMessage = QObject::tr("Internal error"); break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,13 +51,6 @@
|
|||||||
<true/>
|
<true/>
|
||||||
<key>NSCameraUsageDescription</key>
|
<key>NSCameraUsageDescription</key>
|
||||||
<string>Amnezia VPN needs access to the camera for reading QR-codes.</string>
|
<string>Amnezia VPN needs access to the camera for reading QR-codes.</string>
|
||||||
<key>NSAppTransportSecurity</key>
|
|
||||||
<dict>
|
|
||||||
<key>NSAllowsArbitraryLoads</key>
|
|
||||||
<false/>
|
|
||||||
<key>NSAllowsLocalNetworking</key>
|
|
||||||
<true/>
|
|
||||||
</dict>
|
|
||||||
<key>CFBundleIcons</key>
|
<key>CFBundleIcons</key>
|
||||||
<dict/>
|
<dict/>
|
||||||
<key>CFBundleIcons~ipad</key>
|
<key>CFBundleIcons~ipad</key>
|
||||||
|
|||||||
@@ -64,7 +64,6 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
qInfo().noquote() << QString("Started %1 version %2 %3").arg(APPLICATION_NAME, APP_VERSION, GIT_COMMIT_HASH);
|
qInfo().noquote() << QString("Started %1 version %2 %3").arg(APPLICATION_NAME, APP_VERSION, GIT_COMMIT_HASH);
|
||||||
qInfo().noquote() << QString("%1 (%2)").arg(QSysInfo::prettyProductName(), QSysInfo::currentCpuArchitecture());
|
qInfo().noquote() << QString("%1 (%2)").arg(QSysInfo::prettyProductName(), QSysInfo::currentCpuArchitecture());
|
||||||
qInfo().noquote() << QString("SSL backend: %1").arg(QSslSocket::sslLibraryVersionString());
|
|
||||||
|
|
||||||
return app.exec();
|
return app.exec();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ ErrorCode AndroidController::start(const QJsonObject &vpnConfig)
|
|||||||
callActivityMethod("start", "(Ljava/lang/String;)V",
|
callActivityMethod("start", "(Ljava/lang/String;)V",
|
||||||
QJniObject::fromString(config).object<jstring>());
|
QJniObject::fromString(config).object<jstring>());
|
||||||
|
|
||||||
return ErrorCode::NoError;
|
return NoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidController::stop()
|
void AndroidController::stop()
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
#include "MobileUtils.h"
|
||||||
|
|
||||||
|
MobileUtils::MobileUtils(QObject *parent) : QObject(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MobileUtils::shareText(const QStringList &)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString MobileUtils::openFile()
|
||||||
|
{
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#ifndef MOBILEUTILS_H
|
||||||
|
#define MOBILEUTILS_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
|
class MobileUtils : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit MobileUtils(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
bool shareText(const QStringList &filesToSend);
|
||||||
|
QString openFile();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void finished();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MOBILEUTILS_H
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
#include "MobileUtils.h"
|
||||||
|
|
||||||
|
#include <UIKit/UIKit.h>
|
||||||
|
#include <Security/Security.h>
|
||||||
|
|
||||||
|
#include <QEventLoop>
|
||||||
|
|
||||||
|
static UIViewController* getViewController() {
|
||||||
|
NSArray *windows = [[UIApplication sharedApplication]windows];
|
||||||
|
for (UIWindow *window in windows) {
|
||||||
|
if (window.isKeyWindow) {
|
||||||
|
return window.rootViewController;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
MobileUtils::MobileUtils(QObject *parent) : QObject(parent) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MobileUtils::shareText(const QStringList& filesToSend) {
|
||||||
|
NSMutableArray *sharingItems = [NSMutableArray new];
|
||||||
|
|
||||||
|
for (int i = 0; i < filesToSend.size(); i++) {
|
||||||
|
NSURL *logFileUrl = [[NSURL alloc] initFileURLWithPath:filesToSend[i].toNSString()];
|
||||||
|
[sharingItems addObject:logFileUrl];
|
||||||
|
}
|
||||||
|
|
||||||
|
UIViewController *qtController = getViewController();
|
||||||
|
if (!qtController) return;
|
||||||
|
|
||||||
|
UIActivityViewController *activityController = [[UIActivityViewController alloc] initWithActivityItems:sharingItems applicationActivities:nil];
|
||||||
|
|
||||||
|
__block bool isAccepted = false;
|
||||||
|
|
||||||
|
[activityController setCompletionWithItemsHandler:^(NSString *activityType, BOOL completed, NSArray *returnedItems, NSError *activityError) {
|
||||||
|
isAccepted = completed;
|
||||||
|
emit finished();
|
||||||
|
}];
|
||||||
|
|
||||||
|
[qtController presentViewController:activityController animated:YES completion:nil];
|
||||||
|
UIPopoverPresentationController *popController = activityController.popoverPresentationController;
|
||||||
|
if (popController) {
|
||||||
|
popController.sourceView = qtController.view;
|
||||||
|
popController.sourceRect = CGRectMake(100, 100, 100, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
QEventLoop wait;
|
||||||
|
QObject::connect(this, &MobileUtils::finished, &wait, &QEventLoop::quit);
|
||||||
|
wait.exec();
|
||||||
|
|
||||||
|
return isAccepted;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef void (^DocumentPickerClosedCallback)(NSString *path);
|
||||||
|
|
||||||
|
@interface DocumentPickerDelegate : NSObject <UIDocumentPickerDelegate>
|
||||||
|
|
||||||
|
@property (nonatomic, copy) DocumentPickerClosedCallback documentPickerClosedCallback;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation DocumentPickerDelegate
|
||||||
|
|
||||||
|
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray<NSURL *> *)urls {
|
||||||
|
for (NSURL *url in urls) {
|
||||||
|
if (self.documentPickerClosedCallback) {
|
||||||
|
self.documentPickerClosedCallback([url path]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)documentPickerWasCancelled:(UIDocumentPickerViewController *)controller {
|
||||||
|
if (self.documentPickerClosedCallback) {
|
||||||
|
self.documentPickerClosedCallback(nil);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
QString MobileUtils::openFile() {
|
||||||
|
UIDocumentPickerViewController *documentPicker = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:@[@"public.item"] inMode:UIDocumentPickerModeOpen];
|
||||||
|
|
||||||
|
DocumentPickerDelegate *documentPickerDelegate = [[DocumentPickerDelegate alloc] init];
|
||||||
|
documentPicker.delegate = documentPickerDelegate;
|
||||||
|
|
||||||
|
UIViewController *qtController = getViewController();
|
||||||
|
if (!qtController) return;
|
||||||
|
|
||||||
|
[qtController presentViewController:documentPicker animated:YES completion:nil];
|
||||||
|
|
||||||
|
__block QString filePath;
|
||||||
|
|
||||||
|
documentPickerDelegate.documentPickerClosedCallback = ^(NSString *path) {
|
||||||
|
if (path) {
|
||||||
|
filePath = QString::fromUtf8(path.UTF8String);
|
||||||
|
} else {
|
||||||
|
filePath = QString();
|
||||||
|
}
|
||||||
|
emit finished();
|
||||||
|
};
|
||||||
|
|
||||||
|
QEventLoop wait;
|
||||||
|
QObject::connect(this, &MobileUtils::finished, &wait, &QEventLoop::quit);
|
||||||
|
wait.exec();
|
||||||
|
|
||||||
|
return filePath;
|
||||||
|
}
|
||||||
@@ -50,19 +50,12 @@ public:
|
|||||||
|
|
||||||
void getBackendLogs(std::function<void(const QString &)> &&callback);
|
void getBackendLogs(std::function<void(const QString &)> &&callback);
|
||||||
void checkStatus();
|
void checkStatus();
|
||||||
|
|
||||||
bool shareText(const QStringList &filesToSend);
|
|
||||||
QString openFile();
|
|
||||||
|
|
||||||
void requestInetAccess();
|
|
||||||
signals:
|
signals:
|
||||||
void connectionStateChanged(Vpn::ConnectionState state);
|
void connectionStateChanged(Vpn::ConnectionState state);
|
||||||
void bytesChanged(quint64 receivedBytes, quint64 sentBytes);
|
void bytesChanged(quint64 receivedBytes, quint64 sentBytes);
|
||||||
void importConfigFromOutside(const QString);
|
void importConfigFromOutside(const QString);
|
||||||
void importBackupFromOutside(const QString);
|
void importBackupFromOutside(const QString);
|
||||||
|
|
||||||
void finished();
|
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <QEventLoop>
|
|
||||||
|
|
||||||
#include "../protocols/vpnprotocol.h"
|
#include "../protocols/vpnprotocol.h"
|
||||||
#import "ios_controller_wrapper.h"
|
#import "ios_controller_wrapper.h"
|
||||||
@@ -27,15 +26,6 @@ const char* MessageKey::isOnDemand = "is-on-demand";
|
|||||||
const char* MessageKey::SplitTunnelType = "SplitTunnelType";
|
const char* MessageKey::SplitTunnelType = "SplitTunnelType";
|
||||||
const char* MessageKey::SplitTunnelSites = "SplitTunnelSites";
|
const char* MessageKey::SplitTunnelSites = "SplitTunnelSites";
|
||||||
|
|
||||||
static UIViewController* getViewController() {
|
|
||||||
NSArray *windows = [[UIApplication sharedApplication]windows];
|
|
||||||
for (UIWindow *window in windows) {
|
|
||||||
if (window.isKeyWindow) {
|
|
||||||
return window.rootViewController;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vpn::ConnectionState iosStatusToState(NEVPNStatus status) {
|
Vpn::ConnectionState iosStatusToState(NEVPNStatus status) {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
@@ -713,86 +703,3 @@ void IosController::sendVpnExtensionMessage(NSDictionary* message, std::function
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IosController::shareText(const QStringList& filesToSend) {
|
|
||||||
NSMutableArray *sharingItems = [NSMutableArray new];
|
|
||||||
|
|
||||||
for (int i = 0; i < filesToSend.size(); i++) {
|
|
||||||
NSURL *logFileUrl = [[NSURL alloc] initFileURLWithPath:filesToSend[i].toNSString()];
|
|
||||||
[sharingItems addObject:logFileUrl];
|
|
||||||
}
|
|
||||||
|
|
||||||
UIViewController *qtController = getViewController();
|
|
||||||
if (!qtController) return;
|
|
||||||
|
|
||||||
UIActivityViewController *activityController = [[UIActivityViewController alloc] initWithActivityItems:sharingItems applicationActivities:nil];
|
|
||||||
|
|
||||||
__block bool isAccepted = false;
|
|
||||||
|
|
||||||
[activityController setCompletionWithItemsHandler:^(NSString *activityType, BOOL completed, NSArray *returnedItems, NSError *activityError) {
|
|
||||||
isAccepted = completed;
|
|
||||||
emit finished();
|
|
||||||
}];
|
|
||||||
|
|
||||||
[qtController presentViewController:activityController animated:YES completion:nil];
|
|
||||||
UIPopoverPresentationController *popController = activityController.popoverPresentationController;
|
|
||||||
if (popController) {
|
|
||||||
popController.sourceView = qtController.view;
|
|
||||||
popController.sourceRect = CGRectMake(100, 100, 100, 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
QEventLoop wait;
|
|
||||||
QObject::connect(this, &IosController::finished, &wait, &QEventLoop::quit);
|
|
||||||
wait.exec();
|
|
||||||
|
|
||||||
return isAccepted;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString IosController::openFile() {
|
|
||||||
UIDocumentPickerViewController *documentPicker = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:@[@"public.item"] inMode:UIDocumentPickerModeOpen];
|
|
||||||
|
|
||||||
DocumentPickerDelegate *documentPickerDelegate = [[DocumentPickerDelegate alloc] init];
|
|
||||||
documentPicker.delegate = documentPickerDelegate;
|
|
||||||
|
|
||||||
UIViewController *qtController = getViewController();
|
|
||||||
if (!qtController) return;
|
|
||||||
|
|
||||||
[qtController presentViewController:documentPicker animated:YES completion:nil];
|
|
||||||
|
|
||||||
__block QString filePath;
|
|
||||||
|
|
||||||
documentPickerDelegate.documentPickerClosedCallback = ^(NSString *path) {
|
|
||||||
if (path) {
|
|
||||||
filePath = QString::fromUtf8(path.UTF8String);
|
|
||||||
} else {
|
|
||||||
filePath = QString();
|
|
||||||
}
|
|
||||||
emit finished();
|
|
||||||
};
|
|
||||||
|
|
||||||
QEventLoop wait;
|
|
||||||
QObject::connect(this, &IosController::finished, &wait, &QEventLoop::quit);
|
|
||||||
wait.exec();
|
|
||||||
|
|
||||||
return filePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
void IosController::requestInetAccess() {
|
|
||||||
NSURL *url = [NSURL URLWithString:@"http://captive.apple.com/generate_204"];
|
|
||||||
if (url) {
|
|
||||||
qDebug() << "IosController::requestInetAccess URL error";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
NSURLSession *session = [NSURLSession sharedSession];
|
|
||||||
NSURLSessionDataTask *task = [session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
|
|
||||||
if (error) {
|
|
||||||
qDebug() << "IosController::requestInetAccess error:" << error.localizedDescription;
|
|
||||||
} else {
|
|
||||||
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
|
|
||||||
QString responseBody = QString::fromUtf8((const char*)data.bytes, data.length);
|
|
||||||
qDebug() << "IosController::requestInetAccess server response:" << httpResponse.statusCode << "\n\n" <<responseBody;
|
|
||||||
}
|
|
||||||
}];
|
|
||||||
[task resume];
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
#import <NetworkExtension/NetworkExtension.h>
|
#import <NetworkExtension/NetworkExtension.h>
|
||||||
#import <NetworkExtension/NETunnelProviderSession.h>
|
#import <NetworkExtension/NETunnelProviderSession.h>
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#include <UIKit/UIKit.h>
|
|
||||||
#include <Security/Security.h>
|
|
||||||
|
|
||||||
class IosController;
|
class IosController;
|
||||||
|
|
||||||
@@ -15,11 +13,3 @@ class IosController;
|
|||||||
- (void)vpnConfigurationDidChange:(NSNotification *)notification;
|
- (void)vpnConfigurationDidChange:(NSNotification *)notification;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
typedef void (^DocumentPickerClosedCallback)(NSString *path);
|
|
||||||
|
|
||||||
@interface DocumentPickerDelegate : NSObject <UIDocumentPickerDelegate>
|
|
||||||
|
|
||||||
@property (nonatomic, copy) DocumentPickerClosedCallback documentPickerClosedCallback;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|||||||
@@ -24,22 +24,5 @@
|
|||||||
// cppController->vpnStatusDidChange(notification);
|
// cppController->vpnStatusDidChange(notification);
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation DocumentPickerDelegate
|
|
||||||
|
|
||||||
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray<NSURL *> *)urls {
|
|
||||||
for (NSURL *url in urls) {
|
|
||||||
if (self.documentPickerClosedCallback) {
|
|
||||||
self.documentPickerClosedCallback([url path]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)documentPickerWasCancelled:(UIDocumentPickerViewController *)controller {
|
|
||||||
if (self.documentPickerClosedCallback) {
|
|
||||||
self.documentPickerClosedCallback(nil);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
#define TUNNEL_NAMED_PIPE \
|
#define TUNNEL_NAMED_PIPE \
|
||||||
"\\\\." \
|
"\\\\." \
|
||||||
"\\pipe\\ProtectedPrefix\\Administrators\\WireGuard\\AmneziaVPN"
|
"\\pipe\\ProtectedPrefix\\Administrators\\AmneziaWG\\AmneziaVPN"
|
||||||
|
|
||||||
constexpr uint32_t WINDOWS_TUNNEL_MONITOR_TIMEOUT_MSEC = 2000;
|
constexpr uint32_t WINDOWS_TUNNEL_MONITOR_TIMEOUT_MSEC = 2000;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "secure_qsettings.h"
|
#include "secure_qsettings.h"
|
||||||
|
#include "platforms/ios/MobileUtils.h"
|
||||||
|
|
||||||
#include "QAead.h"
|
#include "QAead.h"
|
||||||
#include "QBlockCipher.h"
|
#include "QBlockCipher.h"
|
||||||
|
|||||||
@@ -2944,8 +2944,8 @@ For more detailed information, you can
|
|||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="115"/>
|
<location filename="../containers/containers_defs.cpp" line="115"/>
|
||||||
<source>IKEv2 - Modern stable protocol, a bit faster than others, restores connection after signal loss.</source>
|
<source>IKEv2 - Modern stable protocol, a bit faster than others, restores connection after signal loss. It has native support on the latest versions of Android and iOS.</source>
|
||||||
<translation>بروتوكول IKEv2 - بروتوكول مستقر حديث, اسرع بقليل من الباقي, يسترجع الاتصال بعد خسارة الاشارة.</translation>
|
<translation>بروتوكول IKEv2 - بروتوكول مستقر حديث, اسرع بقليل من الباقي, يسترجع الاتصال بعد خسارة الاشارة. لدية يتمتع بدعم أصلي على أحدث إصدارات Android وiOS.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="118"/>
|
<location filename="../containers/containers_defs.cpp" line="118"/>
|
||||||
|
|||||||
@@ -2850,8 +2850,8 @@ While it offers a blend of security, stability, and speed, it's essential t
|
|||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="115"/>
|
<location filename="../containers/containers_defs.cpp" line="115"/>
|
||||||
<source>IKEv2 - Modern stable protocol, a bit faster than others, restores connection after signal loss.</source>
|
<source>IKEv2 - Modern stable protocol, a bit faster than others, restores connection after signal loss. It has native support on the latest versions of Android and iOS.</source>
|
||||||
<translation>پروتکل IKEv2 پروتکلی پایدار و مدرن که مقداری سریعتر از سایر پروتکلهاست. بعد از قطع سیگنال دوباره اتصال را بازیابی میکند.</translation>
|
<translation>پروتکل IKEv2 پروتکلی پایدار و مدرن که مقداری سریعتر از سایر پروتکلهاست. بعد از قطع سیگنال دوباره اتصال را بازیابی میکند. به صورت پیشفرض بر روی آخرین نسخه دستگاههای اندروید و iOS پیشتیبانی میشود.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="118"/>
|
<location filename="../containers/containers_defs.cpp" line="118"/>
|
||||||
|
|||||||
@@ -2998,8 +2998,8 @@ For more detailed information, you can
|
|||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="124"/>
|
<location filename="../containers/containers_defs.cpp" line="124"/>
|
||||||
<source>IKEv2 - Modern stable protocol, a bit faster than others, restores connection after signal loss.</source>
|
<source>IKEv2 - Modern stable protocol, a bit faster than others, restores connection after signal loss. It has native support on the latest versions of Android and iOS.</source>
|
||||||
<translation>IKEv2 - आधुनिक स्थिर प्रोटोकॉल, दूसरों की तुलना में थोड़ा तेज़, सिग्नल हानि के बाद कनेक्शन पुनर्स्थापित करता है।</translation>
|
<translation>IKEv2 - आधुनिक स्थिर प्रोटोकॉल, दूसरों की तुलना में थोड़ा तेज़, सिग्नल हानि के बाद कनेक्शन पुनर्स्थापित करता है। इसे Android और iOS के नवीनतम संस्करणों पर मूल समर्थन प्राप्त है.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="127"/>
|
<location filename="../containers/containers_defs.cpp" line="127"/>
|
||||||
|
|||||||
@@ -2851,8 +2851,8 @@ IKEv2 သည် လုံခြုံရေး၊ တည်ငြိမ်မှ
|
|||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="115"/>
|
<location filename="../containers/containers_defs.cpp" line="115"/>
|
||||||
<source>IKEv2 - Modern stable protocol, a bit faster than others, restores connection after signal loss.</source>
|
<source>IKEv2 - Modern stable protocol, a bit faster than others, restores connection after signal loss. It has native support on the latest versions of Android and iOS.</source>
|
||||||
<translation>IKEv2 - ခေတ်မီတည်ငြိမ်သောပရိုတိုကော၊ အခြားအရာများထက်အနည်းငယ်ပိုမြန်သည်၊ signal ပျောက်ဆုံးပြီးနောက် ချိတ်ဆက်မှုကို ပြန်လည်ရယူပေးသည်.</translation>
|
<translation>IKEv2 - ခေတ်မီတည်ငြိမ်သောပရိုတိုကော၊ အခြားအရာများထက်အနည်းငယ်ပိုမြန်သည်၊ signal ပျောက်ဆုံးပြီးနောက် ချိတ်ဆက်မှုကို ပြန်လည်ရယူပေးသည်. ၎င်းသည် Android နှင့် iOS ၏နောက်ဆုံးဗားရှင်းများတွင် မူရင်းအတိုင်းထောက်ပံ့မှုရရှိသည်.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="118"/>
|
<location filename="../containers/containers_defs.cpp" line="118"/>
|
||||||
|
|||||||
@@ -2997,8 +2997,8 @@ While it offers a blend of security, stability, and speed, it's essential t
|
|||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="121"/>
|
<location filename="../containers/containers_defs.cpp" line="121"/>
|
||||||
<source>IKEv2 - Modern stable protocol, a bit faster than others, restores connection after signal loss.</source>
|
<source>IKEv2 - Modern stable protocol, a bit faster than others, restores connection after signal loss. It has native support on the latest versions of Android and iOS.</source>
|
||||||
<translation>IKEv2 Современный стабильный протокол, немного быстрее других восстанавливает соединение после потери сигнала.</translation>
|
<translation>IKEv2 Современный стабильный протокол, немного быстрее других восстанавливает соединение после потери сигнала. Имеет нативную поддержку последних версиий Android и iOS.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="124"/>
|
<location filename="../containers/containers_defs.cpp" line="124"/>
|
||||||
|
|||||||
@@ -3191,8 +3191,8 @@ While it offers a blend of security, stability, and speed, it's essential t
|
|||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="124"/>
|
<location filename="../containers/containers_defs.cpp" line="124"/>
|
||||||
<source>IKEv2 - Modern stable protocol, a bit faster than others, restores connection after signal loss.</source>
|
<source>IKEv2 - Modern stable protocol, a bit faster than others, restores connection after signal loss. It has native support on the latest versions of Android and iOS.</source>
|
||||||
<translation>IKEv2 сучасний стабільний протокол, трішки швидше за інших відновлює підключення.</translation>
|
<translation>IKEv2 сучасний стабільний протокол, трішки швидше за інших відновлює підключення. Підтримується в останніх версіях Android и iOS самими операційними системами.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="127"/>
|
<location filename="../containers/containers_defs.cpp" line="127"/>
|
||||||
|
|||||||
@@ -2947,8 +2947,8 @@ For more detailed information, you can
|
|||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="124"/>
|
<location filename="../containers/containers_defs.cpp" line="124"/>
|
||||||
<source>IKEv2 - Modern stable protocol, a bit faster than others, restores connection after signal loss.</source>
|
<source>IKEv2 - Modern stable protocol, a bit faster than others, restores connection after signal loss. It has native support on the latest versions of Android and iOS.</source>
|
||||||
<translation>IKEv2 - جدید مستحکم پروٹوکول، دوسروں کے مقابلے میں تھوڑا تیز، سگنل ضائع ہونے کے بعد کنکشن بحال کرتا ہے۔</translation>
|
<translation>IKEv2 - جدید مستحکم پروٹوکول، دوسروں کے مقابلے میں تھوڑا تیز، سگنل ضائع ہونے کے بعد کنکشن بحال کرتا ہے۔ اسے اینڈرائیڈ اور آئی او ایس کے تازہ ترین ورژنز پر مقامی حمایت حاصل ہے۔</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="127"/>
|
<location filename="../containers/containers_defs.cpp" line="127"/>
|
||||||
|
|||||||
@@ -3057,8 +3057,8 @@ WireGuard非常容易被阻挡,因为其独特的数据包签名。与一些
|
|||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="115"/>
|
<location filename="../containers/containers_defs.cpp" line="115"/>
|
||||||
<source>IKEv2 - Modern stable protocol, a bit faster than others, restores connection after signal loss.</source>
|
<source>IKEv2 - Modern stable protocol, a bit faster than others, restores connection after signal loss. It has native support on the latest versions of Android and iOS.</source>
|
||||||
<translation>IKEv2 - 现代稳定协议,相比其他协议较快一些,在信号丢失后恢复连接。</translation>
|
<translation>IKEv2 - 现代稳定协议,相比其他协议较快一些,在信号丢失后恢复连接。Android 和 iOS最新版原生支持。</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="118"/>
|
<location filename="../containers/containers_defs.cpp" line="118"/>
|
||||||
|
|||||||
@@ -7,7 +7,10 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <QtConcurrent>
|
#include <QtConcurrent>
|
||||||
|
|
||||||
|
#include "utilities.h"
|
||||||
|
#include "core/controllers/apiController.h"
|
||||||
#include "core/controllers/vpnConfigurationController.h"
|
#include "core/controllers/vpnConfigurationController.h"
|
||||||
|
#include "core/errorstrings.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
ConnectionController::ConnectionController(const QSharedPointer<ServersModel> &serversModel,
|
ConnectionController::ConnectionController(const QSharedPointer<ServersModel> &serversModel,
|
||||||
@@ -16,7 +19,6 @@ ConnectionController::ConnectionController(const QSharedPointer<ServersModel> &s
|
|||||||
const QSharedPointer<VpnConnection> &vpnConnection, const std::shared_ptr<Settings> &settings,
|
const QSharedPointer<VpnConnection> &vpnConnection, const std::shared_ptr<Settings> &settings,
|
||||||
QObject *parent)
|
QObject *parent)
|
||||||
: QObject(parent),
|
: QObject(parent),
|
||||||
m_apiController(this),
|
|
||||||
m_serversModel(serversModel),
|
m_serversModel(serversModel),
|
||||||
m_containersModel(containersModel),
|
m_containersModel(containersModel),
|
||||||
m_clientManagementModel(clientManagementModel),
|
m_clientManagementModel(clientManagementModel),
|
||||||
@@ -27,10 +29,6 @@ ConnectionController::ConnectionController(const QSharedPointer<ServersModel> &s
|
|||||||
connect(this, &ConnectionController::connectToVpn, m_vpnConnection.get(), &VpnConnection::connectToVpn, Qt::QueuedConnection);
|
connect(this, &ConnectionController::connectToVpn, m_vpnConnection.get(), &VpnConnection::connectToVpn, Qt::QueuedConnection);
|
||||||
connect(this, &ConnectionController::disconnectFromVpn, m_vpnConnection.get(), &VpnConnection::disconnectFromVpn, 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, qOverload<ErrorCode>(&ApiController::errorOccurred), this, qOverload<ErrorCode>(&ConnectionController::connectionErrorOccurred));
|
|
||||||
|
|
||||||
m_state = Vpn::ConnectionState::Disconnected;
|
m_state = Vpn::ConnectionState::Disconnected;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,22 +37,70 @@ void ConnectionController::openConnection()
|
|||||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
||||||
if (!Utils::processIsRunning(Utils::executable(SERVICE_NAME, false), true))
|
if (!Utils::processIsRunning(Utils::executable(SERVICE_NAME, false), true))
|
||||||
{
|
{
|
||||||
emit connectionErrorOccurred(ErrorCode::AmneziaServiceNotRunning);
|
emit connectionErrorOccurred(errorString(ErrorCode::AmneziaServiceNotRunning));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int serverIndex = m_serversModel->getDefaultServerIndex();
|
int serverIndex = m_serversModel->getDefaultServerIndex();
|
||||||
QJsonObject serverConfig = m_serversModel->getServerConfig(serverIndex);
|
auto serverConfig = m_serversModel->getServerConfig(serverIndex);
|
||||||
|
|
||||||
|
ErrorCode errorCode = ErrorCode::NoError;
|
||||||
|
|
||||||
emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Preparing);
|
emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Preparing);
|
||||||
|
|
||||||
if (serverConfig.value(config_key::configVersion).toInt()
|
if (serverConfig.value(config_key::configVersion).toInt()
|
||||||
&& !m_serversModel->data(serverIndex, ServersModel::Roles::HasInstalledContainers).toBool()) {
|
&& !m_serversModel->data(serverIndex, ServersModel::Roles::HasInstalledContainers).toBool()) {
|
||||||
m_apiController.updateServerConfigFromApi(m_settings->getInstallationUuid(true), serverIndex, serverConfig);
|
ApiController apiController;
|
||||||
} else {
|
errorCode = apiController.updateServerConfigFromApi(m_settings->getInstallationUuid(true), serverConfig);
|
||||||
openConnection(false, serverConfig, serverIndex);
|
if (errorCode != ErrorCode::NoError) {
|
||||||
|
emit connectionErrorOccurred(errorString(errorCode));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
m_serversModel->editServer(serverConfig, serverIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_serversModel->data(serverIndex, ServersModel::Roles::HasInstalledContainers).toBool()) {
|
||||||
|
emit noInstalledContainers();
|
||||||
|
emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Disconnected);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DockerContainer container = qvariant_cast<DockerContainer>(m_serversModel->data(serverIndex, ServersModel::Roles::DefaultContainerRole));
|
||||||
|
|
||||||
|
if (!m_containersModel->isSupportedByCurrentPlatform(container)) {
|
||||||
|
emit connectionErrorOccurred(tr("The selected protocol is not supported on the current platform"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (container == DockerContainer::None) {
|
||||||
|
emit connectionErrorOccurred(tr("VPN Protocols is not installed.\n Please install VPN container at first"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qApp->processEvents();
|
||||||
|
|
||||||
|
QSharedPointer<ServerController> serverController(new ServerController(m_settings));
|
||||||
|
VpnConfigurationsController vpnConfigurationController(m_settings, serverController);
|
||||||
|
|
||||||
|
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
|
||||||
|
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
|
||||||
|
errorCode = updateProtocolConfig(container, credentials, containerConfig, serverController);
|
||||||
|
if (errorCode != ErrorCode::NoError) {
|
||||||
|
emit connectionErrorOccurred(errorString(errorCode));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto dns = m_serversModel->getDnsPair(serverIndex);
|
||||||
|
serverConfig = m_serversModel->getServerConfig(serverIndex);
|
||||||
|
|
||||||
|
auto vpnConfiguration = vpnConfigurationController.createVpnConfiguration(dns, serverConfig, containerConfig, container, errorCode);
|
||||||
|
if (errorCode != ErrorCode::NoError) {
|
||||||
|
emit connectionErrorOccurred(tr("unable to create configuration"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
emit connectToVpn(serverIndex, credentials, container, vpnConfiguration);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionController::closeConnection()
|
void ConnectionController::closeConnection()
|
||||||
@@ -62,9 +108,9 @@ void ConnectionController::closeConnection()
|
|||||||
emit disconnectFromVpn();
|
emit disconnectFromVpn();
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ConnectionController::getLastConnectionError()
|
QString ConnectionController::getLastConnectionError()
|
||||||
{
|
{
|
||||||
return m_vpnConnection->lastError();
|
return errorString(m_vpnConnection->lastError());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionController::onConnectionStateChanged(Vpn::ConnectionState state)
|
void ConnectionController::onConnectionStateChanged(Vpn::ConnectionState state)
|
||||||
@@ -185,53 +231,6 @@ bool ConnectionController::isProtocolConfigExists(const QJsonObject &containerCo
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionController::openConnection(const bool updateConfig, const QJsonObject &config, const int serverIndex)
|
|
||||||
{
|
|
||||||
// Update config for this server as it was received from API
|
|
||||||
if (updateConfig) {
|
|
||||||
m_serversModel->editServer(config, serverIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_serversModel->data(serverIndex, ServersModel::Roles::HasInstalledContainers).toBool()) {
|
|
||||||
emit noInstalledContainers();
|
|
||||||
emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Disconnected);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DockerContainer container = qvariant_cast<DockerContainer>(m_serversModel->data(serverIndex, ServersModel::Roles::DefaultContainerRole));
|
|
||||||
|
|
||||||
if (!m_containersModel->isSupportedByCurrentPlatform(container)) {
|
|
||||||
emit connectionErrorOccurred(tr("The selected protocol is not supported on the current platform"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (container == DockerContainer::None) {
|
|
||||||
emit connectionErrorOccurred(tr("VPN Protocols is not installed.\n Please install VPN container at first"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QSharedPointer<ServerController> serverController(new ServerController(m_settings));
|
|
||||||
VpnConfigurationsController vpnConfigurationController(m_settings, serverController);
|
|
||||||
|
|
||||||
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
|
|
||||||
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
|
|
||||||
ErrorCode errorCode = updateProtocolConfig(container, credentials, containerConfig, serverController);
|
|
||||||
if (errorCode != ErrorCode::NoError) {
|
|
||||||
emit connectionErrorOccurred(errorCode);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto dns = m_serversModel->getDnsPair(serverIndex);
|
|
||||||
|
|
||||||
auto vpnConfiguration = vpnConfigurationController.createVpnConfiguration(dns, config, containerConfig, container, errorCode);
|
|
||||||
if (errorCode != ErrorCode::NoError) {
|
|
||||||
emit connectionErrorOccurred(tr("unable to create configuration"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
emit connectToVpn(serverIndex, credentials, container, vpnConfiguration);
|
|
||||||
}
|
|
||||||
|
|
||||||
ErrorCode ConnectionController::updateProtocolConfig(const DockerContainer container, const ServerCredentials &credentials,
|
ErrorCode ConnectionController::updateProtocolConfig(const DockerContainer container, const ServerCredentials &credentials,
|
||||||
QJsonObject &containerConfig, QSharedPointer<ServerController> serverController)
|
QJsonObject &containerConfig, QSharedPointer<ServerController> serverController)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#ifndef CONNECTIONCONTROLLER_H
|
#ifndef CONNECTIONCONTROLLER_H
|
||||||
#define CONNECTIONCONTROLLER_H
|
#define CONNECTIONCONTROLLER_H
|
||||||
|
|
||||||
#include "core/controllers/apiController.h"
|
|
||||||
#include "protocols/vpnprotocol.h"
|
#include "protocols/vpnprotocol.h"
|
||||||
#include "ui/models/clientManagementModel.h"
|
#include "ui/models/clientManagementModel.h"
|
||||||
#include "ui/models/containers_model.h"
|
#include "ui/models/containers_model.h"
|
||||||
@@ -34,7 +33,7 @@ public slots:
|
|||||||
void openConnection();
|
void openConnection();
|
||||||
void closeConnection();
|
void closeConnection();
|
||||||
|
|
||||||
ErrorCode getLastConnectionError();
|
QString getLastConnectionError();
|
||||||
void onConnectionStateChanged(Vpn::ConnectionState state);
|
void onConnectionStateChanged(Vpn::ConnectionState state);
|
||||||
|
|
||||||
void onCurrentContainerUpdated();
|
void onCurrentContainerUpdated();
|
||||||
@@ -50,7 +49,6 @@ signals:
|
|||||||
void connectionStateChanged();
|
void connectionStateChanged();
|
||||||
|
|
||||||
void connectionErrorOccurred(const QString &errorMessage);
|
void connectionErrorOccurred(const QString &errorMessage);
|
||||||
void connectionErrorOccurred(ErrorCode errorCode);
|
|
||||||
void reconnectWithUpdatedContainer(const QString &message);
|
void reconnectWithUpdatedContainer(const QString &message);
|
||||||
|
|
||||||
void noInstalledContainers();
|
void noInstalledContainers();
|
||||||
@@ -62,10 +60,6 @@ private:
|
|||||||
Vpn::ConnectionState getCurrentConnectionState();
|
Vpn::ConnectionState getCurrentConnectionState();
|
||||||
bool isProtocolConfigExists(const QJsonObject &containerConfig, const DockerContainer container);
|
bool isProtocolConfigExists(const QJsonObject &containerConfig, const DockerContainer container);
|
||||||
|
|
||||||
void openConnection(const bool updateConfig, const QJsonObject &config, const int serverIndex);
|
|
||||||
|
|
||||||
ApiController m_apiController;
|
|
||||||
|
|
||||||
QSharedPointer<ServersModel> m_serversModel;
|
QSharedPointer<ServersModel> m_serversModel;
|
||||||
QSharedPointer<ContainersModel> m_containersModel;
|
QSharedPointer<ContainersModel> m_containersModel;
|
||||||
QSharedPointer<ClientManagementModel> m_clientManagementModel;
|
QSharedPointer<ClientManagementModel> m_clientManagementModel;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
|
|
||||||
#include "core/controllers/vpnConfigurationController.h"
|
#include "core/controllers/vpnConfigurationController.h"
|
||||||
|
#include "core/errorstrings.h"
|
||||||
#include "systemController.h"
|
#include "systemController.h"
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
#include "platforms/android/android_utils.h"
|
#include "platforms/android/android_utils.h"
|
||||||
@@ -100,7 +101,7 @@ void ExportController::generateConnectionConfig(const QString &clientName)
|
|||||||
|
|
||||||
errorCode = m_clientManagementModel->appendClient(container, credentials, containerConfig, clientName, serverController);
|
errorCode = m_clientManagementModel->appendClient(container, credentials, containerConfig, clientName, serverController);
|
||||||
if (errorCode != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
emit exportErrorOccurred(errorCode);
|
emit exportErrorOccurred(errorString(errorCode));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,7 +171,7 @@ void ExportController::generateOpenVpnConfig(const QString &clientName)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (errorCode) {
|
if (errorCode) {
|
||||||
emit exportErrorOccurred(errorCode);
|
emit exportErrorOccurred(errorString(errorCode));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,7 +189,7 @@ void ExportController::generateWireGuardConfig(const QString &clientName)
|
|||||||
QJsonObject nativeConfig;
|
QJsonObject nativeConfig;
|
||||||
ErrorCode errorCode = generateNativeConfig(DockerContainer::WireGuard, clientName, Proto::WireGuard, nativeConfig);
|
ErrorCode errorCode = generateNativeConfig(DockerContainer::WireGuard, clientName, Proto::WireGuard, nativeConfig);
|
||||||
if (errorCode) {
|
if (errorCode) {
|
||||||
emit exportErrorOccurred(errorCode);
|
emit exportErrorOccurred(errorString(errorCode));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,7 +209,7 @@ void ExportController::generateAwgConfig(const QString &clientName)
|
|||||||
QJsonObject nativeConfig;
|
QJsonObject nativeConfig;
|
||||||
ErrorCode errorCode = generateNativeConfig(DockerContainer::Awg, clientName, Proto::Awg, nativeConfig);
|
ErrorCode errorCode = generateNativeConfig(DockerContainer::Awg, clientName, Proto::Awg, nativeConfig);
|
||||||
if (errorCode) {
|
if (errorCode) {
|
||||||
emit exportErrorOccurred(errorCode);
|
emit exportErrorOccurred(errorString(errorCode));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,7 +237,7 @@ void ExportController::generateShadowSocksConfig()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (errorCode) {
|
if (errorCode) {
|
||||||
emit exportErrorOccurred(errorCode);
|
emit exportErrorOccurred(errorString(errorCode));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,7 +263,7 @@ void ExportController::generateCloakConfig()
|
|||||||
QJsonObject nativeConfig;
|
QJsonObject nativeConfig;
|
||||||
ErrorCode errorCode = generateNativeConfig(DockerContainer::Cloak, "", Proto::Cloak, nativeConfig);
|
ErrorCode errorCode = generateNativeConfig(DockerContainer::Cloak, "", Proto::Cloak, nativeConfig);
|
||||||
if (errorCode) {
|
if (errorCode) {
|
||||||
emit exportErrorOccurred(errorCode);
|
emit exportErrorOccurred(errorString(errorCode));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,7 +283,7 @@ void ExportController::generateXrayConfig()
|
|||||||
QJsonObject nativeConfig;
|
QJsonObject nativeConfig;
|
||||||
ErrorCode errorCode = generateNativeConfig(DockerContainer::Xray, "", Proto::Xray, nativeConfig);
|
ErrorCode errorCode = generateNativeConfig(DockerContainer::Xray, "", Proto::Xray, nativeConfig);
|
||||||
if (errorCode) {
|
if (errorCode) {
|
||||||
emit exportErrorOccurred(errorCode);
|
emit exportErrorOccurred(errorString(errorCode));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -319,7 +320,7 @@ void ExportController::updateClientManagementModel(const DockerContainer contain
|
|||||||
QSharedPointer<ServerController> serverController(new ServerController(m_settings));
|
QSharedPointer<ServerController> serverController(new ServerController(m_settings));
|
||||||
ErrorCode errorCode = m_clientManagementModel->updateModel(container, credentials, serverController);
|
ErrorCode errorCode = m_clientManagementModel->updateModel(container, credentials, serverController);
|
||||||
if (errorCode != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
emit exportErrorOccurred(errorCode);
|
emit exportErrorOccurred(errorString(errorCode));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -329,7 +330,7 @@ void ExportController::revokeConfig(const int row, const DockerContainer contain
|
|||||||
ErrorCode errorCode =
|
ErrorCode errorCode =
|
||||||
m_clientManagementModel->revokeClient(row, container, credentials, m_serversModel->getProcessedServerIndex(), serverController);
|
m_clientManagementModel->revokeClient(row, container, credentials, m_serversModel->getProcessedServerIndex(), serverController);
|
||||||
if (errorCode != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
emit exportErrorOccurred(errorCode);
|
emit exportErrorOccurred(errorString(errorCode));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,7 +339,7 @@ void ExportController::renameClient(const int row, const QString &clientName, co
|
|||||||
QSharedPointer<ServerController> serverController(new ServerController(m_settings));
|
QSharedPointer<ServerController> serverController(new ServerController(m_settings));
|
||||||
ErrorCode errorCode = m_clientManagementModel->renameClient(row, clientName, container, credentials, serverController);
|
ErrorCode errorCode = m_clientManagementModel->renameClient(row, clientName, container, credentials, serverController);
|
||||||
if (errorCode != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
emit exportErrorOccurred(errorCode);
|
emit exportErrorOccurred(errorString(errorCode));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ public slots:
|
|||||||
signals:
|
signals:
|
||||||
void generateConfig(int type);
|
void generateConfig(int type);
|
||||||
void exportErrorOccurred(const QString &errorMessage);
|
void exportErrorOccurred(const QString &errorMessage);
|
||||||
void exportErrorOccurred(ErrorCode errorCode);
|
|
||||||
|
|
||||||
void exportConfigChanged();
|
void exportConfigChanged();
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include <QRandomGenerator>
|
#include <QRandomGenerator>
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
|
|
||||||
|
#include "core/errorstrings.h"
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
#include "platforms/android/android_controller.h"
|
#include "platforms/android/android_controller.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -220,7 +221,7 @@ void ImportController::importConfig()
|
|||||||
} else if (m_config.contains(config_key::configVersion)) {
|
} else if (m_config.contains(config_key::configVersion)) {
|
||||||
quint16 crc = qChecksum(QJsonDocument(m_config).toJson());
|
quint16 crc = qChecksum(QJsonDocument(m_config).toJson());
|
||||||
if (m_serversModel->isServerFromApiAlreadyExists(crc)) {
|
if (m_serversModel->isServerFromApiAlreadyExists(crc)) {
|
||||||
emit importErrorOccurred(ErrorCode::ApiConfigAlreadyAdded, true);
|
emit importErrorOccurred(errorString(ErrorCode::ApiConfigAlreadyAdded), true);
|
||||||
} else {
|
} else {
|
||||||
m_config.insert(config_key::crc, crc);
|
m_config.insert(config_key::crc, crc);
|
||||||
|
|
||||||
@@ -230,7 +231,7 @@ void ImportController::importConfig()
|
|||||||
} else {
|
} else {
|
||||||
qDebug() << "Failed to import profile";
|
qDebug() << "Failed to import profile";
|
||||||
qDebug().noquote() << QJsonDocument(m_config).toJson();
|
qDebug().noquote() << QJsonDocument(m_config).toJson();
|
||||||
emit importErrorOccurred(ErrorCode::ImportInvalidConfigError, false);
|
emit importErrorOccurred(errorString(ErrorCode::ImportInvalidConfigError), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_config = {};
|
m_config = {};
|
||||||
@@ -307,7 +308,7 @@ QJsonObject ImportController::extractWireGuardConfig(const QString &data)
|
|||||||
hostName = hostNameAndPortMatch.captured(1);
|
hostName = hostNameAndPortMatch.captured(1);
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "Key parameter 'Endpoint' is missing";
|
qDebug() << "Key parameter 'Endpoint' is missing";
|
||||||
emit importErrorOccurred(ErrorCode::ImportInvalidConfigError, false);
|
emit importErrorOccurred(errorString(ErrorCode::ImportInvalidConfigError), false);
|
||||||
return QJsonObject();
|
return QJsonObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -333,7 +334,7 @@ QJsonObject ImportController::extractWireGuardConfig(const QString &data)
|
|||||||
lastConfig[config_key::server_pub_key] = configMap.value("PublicKey");
|
lastConfig[config_key::server_pub_key] = configMap.value("PublicKey");
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "One of the key parameters is missing (PrivateKey, Address, PublicKey)";
|
qDebug() << "One of the key parameters is missing (PrivateKey, Address, PublicKey)";
|
||||||
emit importErrorOccurred(ErrorCode::ImportInvalidConfigError, false);
|
emit importErrorOccurred(errorString(ErrorCode::ImportInvalidConfigError), false);
|
||||||
return QJsonObject();
|
return QJsonObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,6 @@ public slots:
|
|||||||
signals:
|
signals:
|
||||||
void importFinished();
|
void importFinished();
|
||||||
void importErrorOccurred(const QString &errorMessage, bool goToPageHome);
|
void importErrorOccurred(const QString &errorMessage, bool goToPageHome);
|
||||||
void importErrorOccurred(ErrorCode errorCode, bool goToPageHome);
|
|
||||||
|
|
||||||
void qrDecodingFinished();
|
void qrDecodingFinished();
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include "core/controllers/serverController.h"
|
#include "core/controllers/serverController.h"
|
||||||
#include "core/controllers/vpnConfigurationController.h"
|
#include "core/controllers/vpnConfigurationController.h"
|
||||||
|
#include "core/errorstrings.h"
|
||||||
#include "core/networkUtilities.h"
|
#include "core/networkUtilities.h"
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include "ui/models/protocols/awgConfigModel.h"
|
#include "ui/models/protocols/awgConfigModel.h"
|
||||||
@@ -148,7 +149,7 @@ void InstallController::install(DockerContainer container, int port, TransportPr
|
|||||||
QMap<DockerContainer, QJsonObject> installedContainers;
|
QMap<DockerContainer, QJsonObject> installedContainers;
|
||||||
ErrorCode errorCode = getAlreadyInstalledContainers(serverCredentials, serverController, installedContainers);
|
ErrorCode errorCode = getAlreadyInstalledContainers(serverCredentials, serverController, installedContainers);
|
||||||
if (errorCode) {
|
if (errorCode) {
|
||||||
emit installationErrorOccurred(errorCode);
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,7 +158,7 @@ void InstallController::install(DockerContainer container, int port, TransportPr
|
|||||||
if (!installedContainers.contains(container)) {
|
if (!installedContainers.contains(container)) {
|
||||||
errorCode = serverController->setupContainer(serverCredentials, container, config);
|
errorCode = serverController->setupContainer(serverCredentials, container, config);
|
||||||
if (errorCode) {
|
if (errorCode) {
|
||||||
emit installationErrorOccurred(errorCode);
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,7 +169,7 @@ void InstallController::install(DockerContainer container, int port, TransportPr
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (errorCode) {
|
if (errorCode) {
|
||||||
emit installationErrorOccurred(errorCode);
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,7 +204,7 @@ void InstallController::installServer(const DockerContainer container, const QMa
|
|||||||
auto errorCode = vpnConfigurationController.createProtocolConfigForContainer(m_processedServerCredentials, iterator.key(),
|
auto errorCode = vpnConfigurationController.createProtocolConfigForContainer(m_processedServerCredentials, iterator.key(),
|
||||||
containerConfig);
|
containerConfig);
|
||||||
if (errorCode) {
|
if (errorCode) {
|
||||||
emit installationErrorOccurred(errorCode);
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
containerConfigs.append(containerConfig);
|
containerConfigs.append(containerConfig);
|
||||||
@@ -211,7 +212,7 @@ void InstallController::installServer(const DockerContainer container, const QMa
|
|||||||
errorCode = m_clientManagementModel->appendClient(iterator.key(), serverCredentials, containerConfig,
|
errorCode = m_clientManagementModel->appendClient(iterator.key(), serverCredentials, containerConfig,
|
||||||
QString("Admin [%1]").arg(QSysInfo::prettyProductName()), serverController);
|
QString("Admin [%1]").arg(QSysInfo::prettyProductName()), serverController);
|
||||||
if (errorCode) {
|
if (errorCode) {
|
||||||
emit installationErrorOccurred(errorCode);
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -243,7 +244,7 @@ void InstallController::installContainer(const DockerContainer container, const
|
|||||||
auto errorCode =
|
auto errorCode =
|
||||||
vpnConfigurationController.createProtocolConfigForContainer(serverCredentials, iterator.key(), containerConfig);
|
vpnConfigurationController.createProtocolConfigForContainer(serverCredentials, iterator.key(), containerConfig);
|
||||||
if (errorCode) {
|
if (errorCode) {
|
||||||
emit installationErrorOccurred(errorCode);
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_serversModel->addContainerConfig(iterator.key(), containerConfig);
|
m_serversModel->addContainerConfig(iterator.key(), containerConfig);
|
||||||
@@ -251,7 +252,7 @@ void InstallController::installContainer(const DockerContainer container, const
|
|||||||
errorCode = m_clientManagementModel->appendClient(iterator.key(), serverCredentials, containerConfig,
|
errorCode = m_clientManagementModel->appendClient(iterator.key(), serverCredentials, containerConfig,
|
||||||
QString("Admin [%1]").arg(QSysInfo::prettyProductName()), serverController);
|
QString("Admin [%1]").arg(QSysInfo::prettyProductName()), serverController);
|
||||||
if (errorCode) {
|
if (errorCode) {
|
||||||
emit installationErrorOccurred(errorCode);
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -309,7 +310,7 @@ void InstallController::scanServerForInstalledContainers()
|
|||||||
auto errorCode =
|
auto errorCode =
|
||||||
vpnConfigurationController.createProtocolConfigForContainer(serverCredentials, container, containerConfig);
|
vpnConfigurationController.createProtocolConfigForContainer(serverCredentials, container, containerConfig);
|
||||||
if (errorCode) {
|
if (errorCode) {
|
||||||
emit installationErrorOccurred(errorCode);
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_serversModel->addContainerConfig(container, containerConfig);
|
m_serversModel->addContainerConfig(container, containerConfig);
|
||||||
@@ -318,7 +319,7 @@ void InstallController::scanServerForInstalledContainers()
|
|||||||
QString("Admin [%1]").arg(QSysInfo::prettyProductName()),
|
QString("Admin [%1]").arg(QSysInfo::prettyProductName()),
|
||||||
serverController);
|
serverController);
|
||||||
if (errorCode) {
|
if (errorCode) {
|
||||||
emit installationErrorOccurred(errorCode);
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -333,7 +334,7 @@ void InstallController::scanServerForInstalledContainers()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
emit installationErrorOccurred(errorCode);
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode InstallController::getAlreadyInstalledContainers(const ServerCredentials &credentials,
|
ErrorCode InstallController::getAlreadyInstalledContainers(const ServerCredentials &credentials,
|
||||||
@@ -514,7 +515,7 @@ void InstallController::updateContainer(QJsonObject config)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
emit installationErrorOccurred(errorCode);
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstallController::rebootProcessedServer()
|
void InstallController::rebootProcessedServer()
|
||||||
@@ -527,7 +528,7 @@ void InstallController::rebootProcessedServer()
|
|||||||
if (errorCode == ErrorCode::NoError) {
|
if (errorCode == ErrorCode::NoError) {
|
||||||
emit rebootProcessedServerFinished(tr("Server '%1' was rebooted").arg(serverName));
|
emit rebootProcessedServerFinished(tr("Server '%1' was rebooted").arg(serverName));
|
||||||
} else {
|
} else {
|
||||||
emit installationErrorOccurred(errorCode);
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -551,7 +552,7 @@ void InstallController::removeAllContainers()
|
|||||||
emit removeAllContainersFinished(tr("All containers from server '%1' have been removed").arg(serverName));
|
emit removeAllContainersFinished(tr("All containers from server '%1' have been removed").arg(serverName));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
emit installationErrorOccurred(errorCode);
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstallController::removeProcessedContainer()
|
void InstallController::removeProcessedContainer()
|
||||||
@@ -569,7 +570,7 @@ void InstallController::removeProcessedContainer()
|
|||||||
emit removeProcessedContainerFinished(tr("%1 has been removed from the server '%2'").arg(containerName, serverName));
|
emit removeProcessedContainerFinished(tr("%1 has been removed from the server '%2'").arg(containerName, serverName));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
emit installationErrorOccurred(errorCode);
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstallController::removeApiConfig(const int serverIndex)
|
void InstallController::removeApiConfig(const int serverIndex)
|
||||||
@@ -737,7 +738,7 @@ bool InstallController::checkSshConnection(QSharedPointer<ServerController> serv
|
|||||||
if (errorCode == ErrorCode::NoError) {
|
if (errorCode == ErrorCode::NoError) {
|
||||||
m_processedServerCredentials.secretData = decryptedPrivateKey;
|
m_processedServerCredentials.secretData = decryptedPrivateKey;
|
||||||
} else {
|
} else {
|
||||||
emit installationErrorOccurred(errorCode);
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -746,7 +747,7 @@ bool InstallController::checkSshConnection(QSharedPointer<ServerController> serv
|
|||||||
output = serverController->checkSshConnection(m_processedServerCredentials, errorCode);
|
output = serverController->checkSshConnection(m_processedServerCredentials, errorCode);
|
||||||
|
|
||||||
if (errorCode != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
emit installationErrorOccurred(errorCode);
|
emit installationErrorOccurred(errorString(errorCode));
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
if (output.contains(tr("Please login as the user"))) {
|
if (output.contains(tr("Please login as the user"))) {
|
||||||
|
|||||||
@@ -64,7 +64,6 @@ signals:
|
|||||||
void removeProcessedContainerFinished(const QString &finishedMessage);
|
void removeProcessedContainerFinished(const QString &finishedMessage);
|
||||||
|
|
||||||
void installationErrorOccurred(const QString &errorMessage);
|
void installationErrorOccurred(const QString &errorMessage);
|
||||||
void installationErrorOccurred(ErrorCode errorCode);
|
|
||||||
|
|
||||||
void serverAlreadyExists(int serverIndex);
|
void serverAlreadyExists(int serverIndex);
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,4 @@
|
|||||||
#include "pageController.h"
|
#include "pageController.h"
|
||||||
#include "utils/converter.h"
|
|
||||||
#include "ui/models/servers_model.h"
|
|
||||||
#include "ui/models/languageModel.h"
|
|
||||||
#include "core/errorstrings.h"
|
|
||||||
|
|
||||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
@@ -20,10 +16,8 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
PageController::PageController(const QSharedPointer<ServersModel> &serversModel,
|
PageController::PageController(const QSharedPointer<ServersModel> &serversModel,
|
||||||
const std::shared_ptr<Settings> &settings,
|
const std::shared_ptr<Settings> &settings, QObject *parent)
|
||||||
const QSharedPointer<LanguageModel> &languageModel,
|
: QObject(parent), m_serversModel(serversModel), m_settings(settings)
|
||||||
QObject *parent)
|
|
||||||
: QObject(parent), m_serversModel(serversModel), m_settings(settings), m_languageModel(languageModel)
|
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
// Change color of navigation and status bar's
|
// Change color of navigation and status bar's
|
||||||
@@ -45,8 +39,6 @@ PageController::PageController(const QSharedPointer<ServersModel> &serversModel,
|
|||||||
connect(this, &PageController::hideMainWindow, []() { setDockIconVisible(false); });
|
connect(this, &PageController::hideMainWindow, []() { setDockIconVisible(false); });
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
connect(this, qOverload<ErrorCode>(&PageController::showErrorMessage), this, &PageController::onShowErrorMessage);
|
|
||||||
|
|
||||||
m_isTriggeredByConnectButton = false;
|
m_isTriggeredByConnectButton = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,14 +161,3 @@ int PageController::getDrawerDepth()
|
|||||||
{
|
{
|
||||||
return m_drawerDepth;
|
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 baseUrl = m_languageModel->getDocsEndpoint();
|
|
||||||
const auto errorUrl = QStringLiteral("%1/troubleshooting/error-codes/#error-%2-%3").arg(baseUrl).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,9 +4,7 @@
|
|||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QQmlEngine>
|
#include <QQmlEngine>
|
||||||
|
|
||||||
#include "core/defs.h"
|
|
||||||
#include "ui/models/servers_model.h"
|
#include "ui/models/servers_model.h"
|
||||||
#include "ui/models/languageModel.h"
|
|
||||||
|
|
||||||
namespace PageLoader
|
namespace PageLoader
|
||||||
{
|
{
|
||||||
@@ -72,7 +70,7 @@ class PageController : public QObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit PageController(const QSharedPointer<ServersModel> &serversModel, const std::shared_ptr<Settings> &settings,
|
explicit PageController(const QSharedPointer<ServersModel> &serversModel, const std::shared_ptr<Settings> &settings,
|
||||||
const QSharedPointer<LanguageModel> & languageModel,QObject *parent = nullptr);
|
QObject *parent = nullptr);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
QString getInitialPage();
|
QString getInitialPage();
|
||||||
@@ -95,9 +93,6 @@ public slots:
|
|||||||
void setDrawerDepth(const int depth);
|
void setDrawerDepth(const int depth);
|
||||||
int getDrawerDepth();
|
int getDrawerDepth();
|
||||||
|
|
||||||
private slots:
|
|
||||||
void onShowErrorMessage(amnezia::ErrorCode errorCode);
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void goToPage(PageLoader::PageEnum page, bool slide = true);
|
void goToPage(PageLoader::PageEnum page, bool slide = true);
|
||||||
void goToStartPage();
|
void goToStartPage();
|
||||||
@@ -112,7 +107,6 @@ signals:
|
|||||||
void restorePageHomeState(bool isContainerInstalled = false);
|
void restorePageHomeState(bool isContainerInstalled = false);
|
||||||
void replaceStartPage();
|
void replaceStartPage();
|
||||||
|
|
||||||
void showErrorMessage(amnezia::ErrorCode);
|
|
||||||
void showErrorMessage(const QString &errorMessage);
|
void showErrorMessage(const QString &errorMessage);
|
||||||
void showNotificationMessage(const QString &message);
|
void showNotificationMessage(const QString &message);
|
||||||
|
|
||||||
@@ -137,8 +131,6 @@ private:
|
|||||||
|
|
||||||
std::shared_ptr<Settings> m_settings;
|
std::shared_ptr<Settings> m_settings;
|
||||||
|
|
||||||
QSharedPointer<LanguageModel> m_languageModel;
|
|
||||||
|
|
||||||
bool m_isTriggeredByConnectButton;
|
bool m_isTriggeredByConnectButton;
|
||||||
|
|
||||||
int m_drawerDepth = 0;
|
int m_drawerDepth = 0;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef Q_OS_IOS
|
#ifdef Q_OS_IOS
|
||||||
#include "platforms/ios/ios_controller.h"
|
#include "platforms/ios/MobileUtils.h"
|
||||||
#include <CoreFoundation/CoreFoundation.h>
|
#include <CoreFoundation/CoreFoundation.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -46,8 +46,9 @@ void SystemController::saveFile(QString fileName, const QString &data)
|
|||||||
#ifdef Q_OS_IOS
|
#ifdef Q_OS_IOS
|
||||||
QStringList filesToSend;
|
QStringList filesToSend;
|
||||||
filesToSend.append(fileUrl.toString());
|
filesToSend.append(fileUrl.toString());
|
||||||
|
MobileUtils mobileUtils;
|
||||||
// todo check if save successful
|
// todo check if save successful
|
||||||
IosController::Instance()->shareText(filesToSend);
|
mobileUtils.shareText(filesToSend);
|
||||||
return;
|
return;
|
||||||
#else
|
#else
|
||||||
QFileInfo fi(fileName);
|
QFileInfo fi(fileName);
|
||||||
@@ -66,7 +67,8 @@ QString SystemController::getFileName(const QString &acceptLabel, const QString
|
|||||||
|
|
||||||
#ifdef Q_OS_IOS
|
#ifdef Q_OS_IOS
|
||||||
|
|
||||||
fileName = IosController::Instance()->openFile();
|
MobileUtils mobileUtils;
|
||||||
|
fileName = mobileUtils.openFile();
|
||||||
if (fileName.isEmpty()) {
|
if (fileName.isEmpty()) {
|
||||||
return fileName;
|
return fileName;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,24 +90,6 @@ int LanguageModel::getCurrentLanguageIndex()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString LanguageModel::getDocsEndpoint()
|
|
||||||
{
|
|
||||||
QString baseUrl = "https://docs.amnezia.org";
|
|
||||||
auto locale = m_settings->getAppLanguage();
|
|
||||||
switch (locale.language()) {
|
|
||||||
case QLocale::Russian:
|
|
||||||
baseUrl += "/ru";
|
|
||||||
break;
|
|
||||||
case QLocale::Ukrainian:
|
|
||||||
baseUrl += "/ru";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return baseUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
int LanguageModel::getLineHeightAppend()
|
int LanguageModel::getLineHeightAppend()
|
||||||
{
|
{
|
||||||
int langIndex = getCurrentLanguageIndex();
|
int langIndex = getCurrentLanguageIndex();
|
||||||
|
|||||||
@@ -59,7 +59,6 @@ public slots:
|
|||||||
int getCurrentLanguageIndex();
|
int getCurrentLanguageIndex();
|
||||||
int getLineHeightAppend();
|
int getLineHeightAppend();
|
||||||
QString getCurrentLanguageName();
|
QString getCurrentLanguageName();
|
||||||
QString getDocsEndpoint();
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void updateTranslations(const QLocale &locale);
|
void updateTranslations(const QLocale &locale);
|
||||||
|
|||||||
@@ -57,17 +57,7 @@ Popup {
|
|||||||
horizontalAlignment: Text.AlignLeft
|
horizontalAlignment: Text.AlignLeft
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
onLinkActivated: function(link) {
|
|
||||||
Qt.openUrlExternally(link)
|
|
||||||
}
|
|
||||||
|
|
||||||
text: root.text
|
text: root.text
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
acceptedButtons: Qt.NoButton
|
|
||||||
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
|||||||
@@ -76,9 +76,9 @@ PageType {
|
|||||||
Connections {
|
Connections {
|
||||||
target: InstallController
|
target: InstallController
|
||||||
|
|
||||||
function onInstallationErrorOccurred(error) {
|
function onInstallationErrorOccurred(errorMessage) {
|
||||||
PageController.showBusyIndicator(false)
|
PageController.showBusyIndicator(false)
|
||||||
PageController.showErrorMessage(error)
|
PageController.showErrorMessage(errorMessage)
|
||||||
|
|
||||||
var currentPageName = stackView.currentItem.objectName
|
var currentPageName = stackView.currentItem.objectName
|
||||||
|
|
||||||
@@ -97,8 +97,8 @@ PageType {
|
|||||||
PageController.showBusyIndicator(false)
|
PageController.showBusyIndicator(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
function onImportErrorOccurred(error, goToPageHome) {
|
function onImportErrorOccurred(errorMessage, goToPageHome) {
|
||||||
PageController.showErrorMessage(error)
|
PageController.showErrorMessage(errorMessage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -102,10 +102,9 @@ PageType {
|
|||||||
PageController.showBusyIndicator(false)
|
PageController.showBusyIndicator(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
function onExportErrorOccurred(error) {
|
function onExportErrorOccurred(errorMessage) {
|
||||||
shareConnectionDrawer.close()
|
shareConnectionDrawer.close()
|
||||||
|
PageController.showErrorMessage(errorMessage)
|
||||||
PageController.showErrorMessage(error)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -99,10 +99,9 @@ PageType {
|
|||||||
Connections {
|
Connections {
|
||||||
target: InstallController
|
target: InstallController
|
||||||
|
|
||||||
function onInstallationErrorOccurred(error) {
|
function onInstallationErrorOccurred(errorMessage) {
|
||||||
PageController.showBusyIndicator(false)
|
PageController.showBusyIndicator(false)
|
||||||
|
PageController.showErrorMessage(errorMessage)
|
||||||
PageController.showErrorMessage(error)
|
|
||||||
|
|
||||||
var needCloseCurrentPage = false
|
var needCloseCurrentPage = false
|
||||||
var currentPageName = tabBarStackView.currentItem.objectName
|
var currentPageName = tabBarStackView.currentItem.objectName
|
||||||
@@ -147,8 +146,8 @@ PageType {
|
|||||||
Connections {
|
Connections {
|
||||||
target: ImportController
|
target: ImportController
|
||||||
|
|
||||||
function onImportErrorOccurred(error, goToPageHome) {
|
function onImportErrorOccurred(errorMessage, goToPageHome) {
|
||||||
PageController.showErrorMessage(error)
|
PageController.showErrorMessage(errorMessage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QMetaEnum>
|
|
||||||
|
|
||||||
namespace utils
|
|
||||||
{
|
|
||||||
template<typename Enum>
|
|
||||||
QString enumToString(Enum value)
|
|
||||||
{
|
|
||||||
auto metaEnum = QMetaEnum::fromType<Enum>();
|
|
||||||
return metaEnum.valueToKey(static_cast<int>(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Enum>
|
|
||||||
Enum enumFromString(const QString &str, Enum defaultValue = {})
|
|
||||||
{
|
|
||||||
auto metaEnum = QMetaEnum::fromType<Enum>();
|
|
||||||
bool isOk;
|
|
||||||
auto value = metaEnum.keyToValue(str.toLatin1(), &isOk);
|
|
||||||
if (isOk) {
|
|
||||||
return static_cast<Enum>(value);
|
|
||||||
}
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user