moved the platform-specific android code for the new ui
This commit is contained in:
parent
5b8a0881b7
commit
0a1359ed16
31 changed files with 854 additions and 764 deletions
|
@ -293,6 +293,7 @@ if(ANDROID)
|
||||||
${CMAKE_CURRENT_LIST_DIR}/platforms/android/android_notificationhandler.h
|
${CMAKE_CURRENT_LIST_DIR}/platforms/android/android_notificationhandler.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/platforms/android/androidutils.h
|
${CMAKE_CURRENT_LIST_DIR}/platforms/android/androidutils.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/platforms/android/androidvpnactivity.h
|
${CMAKE_CURRENT_LIST_DIR}/platforms/android/androidvpnactivity.h
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/platforms/android/authResultReceiver.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/android_vpnprotocol.h
|
${CMAKE_CURRENT_LIST_DIR}/protocols/android_vpnprotocol.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -301,6 +302,7 @@ if(ANDROID)
|
||||||
${CMAKE_CURRENT_LIST_DIR}/platforms/android/android_notificationhandler.cpp
|
${CMAKE_CURRENT_LIST_DIR}/platforms/android/android_notificationhandler.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/platforms/android/androidutils.cpp
|
${CMAKE_CURRENT_LIST_DIR}/platforms/android/androidutils.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/platforms/android/androidvpnactivity.cpp
|
${CMAKE_CURRENT_LIST_DIR}/platforms/android/androidvpnactivity.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/platforms/android/authResultReceiver.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/android_vpnprotocol.cpp
|
${CMAKE_CURRENT_LIST_DIR}/protocols/android_vpnprotocol.cpp
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <QFontDatabase>
|
#include <QFontDatabase>
|
||||||
#include <QMimeData>
|
#include <QMimeData>
|
||||||
#include <QQuickStyle>
|
#include <QQuickStyle>
|
||||||
|
#include <QResource>
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
#include <QTextDocument>
|
#include <QTextDocument>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
@ -14,9 +15,12 @@
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
#include "platforms/ios/QRCodeReaderBase.h"
|
#include "platforms/ios/QRCodeReaderBase.h"
|
||||||
|
#if defined(Q_OS_ANDROID)
|
||||||
|
#include "platforms/android/android_controller.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "ui/pages.h"
|
|
||||||
#include "protocols/qml_register_protocols.h"
|
#include "protocols/qml_register_protocols.h"
|
||||||
|
#include "ui/pages.h"
|
||||||
|
|
||||||
#if defined(Q_OS_IOS)
|
#if defined(Q_OS_IOS)
|
||||||
#include "platforms/ios/QtAppDelegate-C-Interface.h"
|
#include "platforms/ios/QtAppDelegate-C-Interface.h"
|
||||||
|
@ -33,7 +37,7 @@ AmneziaApplication::AmneziaApplication(int &argc, char *argv[], bool allowSecond
|
||||||
setQuitOnLastWindowClosed(false);
|
setQuitOnLastWindowClosed(false);
|
||||||
|
|
||||||
// Fix config file permissions
|
// Fix config file permissions
|
||||||
#ifdef Q_OS_LINUX && !defined(Q_OS_ANDROID)
|
#if defined Q_OS_LINUX && !defined(Q_OS_ANDROID)
|
||||||
{
|
{
|
||||||
QSettings s(ORGANIZATION_NAME, APPLICATION_NAME);
|
QSettings s(ORGANIZATION_NAME, APPLICATION_NAME);
|
||||||
s.setValue("permFixed", true);
|
s.setValue("permFixed", true);
|
||||||
|
@ -87,16 +91,35 @@ void AmneziaApplication::init()
|
||||||
initModels();
|
initModels();
|
||||||
initControllers();
|
initControllers();
|
||||||
|
|
||||||
|
#ifdef Q_OS_ANDROID
|
||||||
|
connect(AndroidController::instance(), &AndroidController::initialized, this,
|
||||||
|
[this](bool status, bool connected, const QDateTime &connectionDate) {
|
||||||
|
if (connected) {
|
||||||
|
m_connectionController->onConnectionStateChanged(Vpn::ConnectionState::Connected);
|
||||||
|
if (m_vpnConnection)
|
||||||
|
m_vpnConnection->restoreConnection();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (!AndroidController::instance()->initialize()) {
|
||||||
|
qCritical() << QString("Init failed");
|
||||||
|
if (m_vpnConnection)
|
||||||
|
emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(AndroidController::instance(), &AndroidController::importConfigFromOutside, m_importController.get(),
|
||||||
|
&ImportController::extractConfigFromData);
|
||||||
|
connect(AndroidController::instance(), &AndroidController::importConfigFromOutside, m_pageController.get(),
|
||||||
|
&PageController::goToPageViewConfig);
|
||||||
|
#endif
|
||||||
|
|
||||||
m_notificationHandler.reset(NotificationHandler::create(nullptr));
|
m_notificationHandler.reset(NotificationHandler::create(nullptr));
|
||||||
|
|
||||||
connect(m_vpnConnection.get(), &VpnConnection::connectionStateChanged, m_notificationHandler.get(),
|
connect(m_vpnConnection.get(), &VpnConnection::connectionStateChanged, m_notificationHandler.get(),
|
||||||
&NotificationHandler::setConnectionState);
|
&NotificationHandler::setConnectionState);
|
||||||
|
|
||||||
void openConnection();
|
|
||||||
void closeConnection();
|
|
||||||
|
|
||||||
connect(m_notificationHandler.get(), &NotificationHandler::raiseRequested, m_pageController.get(),
|
connect(m_notificationHandler.get(), &NotificationHandler::raiseRequested, m_pageController.get(),
|
||||||
&PageController::raise);
|
&PageController::raiseMainWindow);
|
||||||
connect(m_notificationHandler.get(), &NotificationHandler::connectRequested, m_connectionController.get(),
|
connect(m_notificationHandler.get(), &NotificationHandler::connectRequested, m_connectionController.get(),
|
||||||
&ConnectionController::openConnection);
|
&ConnectionController::openConnection);
|
||||||
connect(m_notificationHandler.get(), &NotificationHandler::disconnectRequested, m_connectionController.get(),
|
connect(m_notificationHandler.get(), &NotificationHandler::disconnectRequested, m_connectionController.get(),
|
||||||
|
|
|
@ -13,16 +13,15 @@
|
||||||
|
|
||||||
#include "android_controller.h"
|
#include "android_controller.h"
|
||||||
#include "private/qandroidextras_p.h"
|
#include "private/qandroidextras_p.h"
|
||||||
#include "ui/pages_logic/StartPageLogic.h"
|
|
||||||
|
|
||||||
#include "androidvpnactivity.h"
|
|
||||||
#include "androidutils.h"
|
#include "androidutils.h"
|
||||||
|
#include "androidvpnactivity.h"
|
||||||
|
|
||||||
namespace {
|
namespace
|
||||||
|
{
|
||||||
AndroidController *s_instance = nullptr;
|
AndroidController *s_instance = nullptr;
|
||||||
|
|
||||||
constexpr auto PERMISSIONHELPER_CLASS =
|
constexpr auto PERMISSIONHELPER_CLASS = "org/amnezia/vpn/qt/VPNPermissionHelper";
|
||||||
"org/amnezia/vpn/qt/VPNPermissionHelper";
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
AndroidController::AndroidController() : QObject()
|
AndroidController::AndroidController() : QObject()
|
||||||
|
@ -33,12 +32,16 @@ AndroidController::AndroidController() : QObject()
|
||||||
|
|
||||||
auto activity = AndroidVPNActivity::instance();
|
auto activity = AndroidVPNActivity::instance();
|
||||||
|
|
||||||
connect(activity, &AndroidVPNActivity::serviceConnected, this, []() {
|
connect(
|
||||||
|
activity, &AndroidVPNActivity::serviceConnected, this,
|
||||||
|
[]() {
|
||||||
qDebug() << "Transact: service connected";
|
qDebug() << "Transact: service connected";
|
||||||
AndroidVPNActivity::sendToService(ServiceAction::ACTION_REQUEST_STATISTIC, "");
|
AndroidVPNActivity::sendToService(ServiceAction::ACTION_REQUEST_STATISTIC, "");
|
||||||
}, Qt::QueuedConnection);
|
},
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
|
||||||
connect(activity, &AndroidVPNActivity::eventInitialized, this,
|
connect(
|
||||||
|
activity, &AndroidVPNActivity::eventInitialized, this,
|
||||||
[this](const QString &parcelBody) {
|
[this](const QString &parcelBody) {
|
||||||
// We might get multiple Init events as widgets, or fragments
|
// We might get multiple Init events as widgets, or fragments
|
||||||
// might query this.
|
// might query this.
|
||||||
|
@ -59,14 +62,14 @@ AndroidController::AndroidController() : QObject()
|
||||||
emit scheduleStatusCheckSignal();
|
emit scheduleStatusCheckSignal();
|
||||||
}
|
}
|
||||||
|
|
||||||
emit initialized(
|
emit initialized(true, isConnected, time > 0 ? QDateTime::fromMSecsSinceEpoch(time) : QDateTime());
|
||||||
true, isConnected,
|
|
||||||
time > 0 ? QDateTime::fromMSecsSinceEpoch(time) : QDateTime());
|
|
||||||
|
|
||||||
setFallbackConnectedNotification();
|
setFallbackConnectedNotification();
|
||||||
}, Qt::QueuedConnection);
|
},
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
|
||||||
connect(activity, &AndroidVPNActivity::eventConnected, this,
|
connect(
|
||||||
|
activity, &AndroidVPNActivity::eventConnected, this,
|
||||||
[this](const QString &parcelBody) {
|
[this](const QString &parcelBody) {
|
||||||
Q_UNUSED(parcelBody);
|
Q_UNUSED(parcelBody);
|
||||||
qDebug() << "Transact: connected";
|
qDebug() << "Transact: connected";
|
||||||
|
@ -77,19 +80,23 @@ AndroidController::AndroidController() : QObject()
|
||||||
|
|
||||||
isConnected = true;
|
isConnected = true;
|
||||||
|
|
||||||
emit connectionStateChanged(VpnProtocol::Connected);
|
emit connectionStateChanged(Vpn::ConnectionState::Connected);
|
||||||
}, Qt::QueuedConnection);
|
},
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
|
||||||
connect(activity, &AndroidVPNActivity::eventDisconnected, this,
|
connect(
|
||||||
|
activity, &AndroidVPNActivity::eventDisconnected, this,
|
||||||
[this]() {
|
[this]() {
|
||||||
qDebug() << "Transact: disconnected";
|
qDebug() << "Transact: disconnected";
|
||||||
|
|
||||||
isConnected = false;
|
isConnected = false;
|
||||||
|
|
||||||
emit connectionStateChanged(VpnProtocol::Disconnected);
|
emit connectionStateChanged(Vpn::ConnectionState::Disconnected);
|
||||||
}, Qt::QueuedConnection);
|
},
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
|
||||||
connect(activity, &AndroidVPNActivity::eventStatisticUpdate, this,
|
connect(
|
||||||
|
activity, &AndroidVPNActivity::eventStatisticUpdate, this,
|
||||||
[this](const QString &parcelBody) {
|
[this](const QString &parcelBody) {
|
||||||
auto doc = QJsonDocument::fromJson(parcelBody.toUtf8());
|
auto doc = QJsonDocument::fromJson(parcelBody.toUtf8());
|
||||||
|
|
||||||
|
@ -99,9 +106,11 @@ AndroidController::AndroidController() : QObject()
|
||||||
QString deviceIPv4 = doc.object()["deviceIpv4"].toString();
|
QString deviceIPv4 = doc.object()["deviceIpv4"].toString();
|
||||||
|
|
||||||
emit statusUpdated(rx, tx, endpoint, deviceIPv4);
|
emit statusUpdated(rx, tx, endpoint, deviceIPv4);
|
||||||
}, Qt::QueuedConnection);
|
},
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
|
||||||
connect(activity, &AndroidVPNActivity::eventBackendLogs, this,
|
connect(
|
||||||
|
activity, &AndroidVPNActivity::eventBackendLogs, this,
|
||||||
[this](const QString &parcelBody) {
|
[this](const QString &parcelBody) {
|
||||||
qDebug() << "Transact: backend logs";
|
qDebug() << "Transact: backend logs";
|
||||||
|
|
||||||
|
@ -109,33 +118,41 @@ AndroidController::AndroidController() : QObject()
|
||||||
if (m_logCallback) {
|
if (m_logCallback) {
|
||||||
m_logCallback(buffer);
|
m_logCallback(buffer);
|
||||||
}
|
}
|
||||||
}, Qt::QueuedConnection);
|
},
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
|
||||||
connect(activity, &AndroidVPNActivity::eventActivationError, this,
|
connect(
|
||||||
|
activity, &AndroidVPNActivity::eventActivationError, this,
|
||||||
[this](const QString &parcelBody) {
|
[this](const QString &parcelBody) {
|
||||||
Q_UNUSED(parcelBody)
|
Q_UNUSED(parcelBody)
|
||||||
qDebug() << "Transact: error";
|
qDebug() << "Transact: error";
|
||||||
emit connectionStateChanged(VpnProtocol::Error);
|
emit connectionStateChanged(Vpn::ConnectionState::Error);
|
||||||
}, Qt::QueuedConnection);
|
},
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
|
||||||
connect(activity, &AndroidVPNActivity::eventConfigImport, this,
|
connect(
|
||||||
|
activity, &AndroidVPNActivity::eventConfigImport, this,
|
||||||
[this](const QString &parcelBody) {
|
[this](const QString &parcelBody) {
|
||||||
qDebug() << "Transact: config import";
|
qDebug() << "Transact: config import";
|
||||||
auto doc = QJsonDocument::fromJson(parcelBody.toUtf8());
|
auto doc = QJsonDocument::fromJson(parcelBody.toUtf8());
|
||||||
|
|
||||||
QString buffer = doc.object()["config"].toString();
|
QString buffer = doc.object()["config"].toString();
|
||||||
qDebug() << "Transact: config string" << buffer;
|
qDebug() << "Transact: config string" << buffer;
|
||||||
importConfig(buffer);
|
importConfigFromOutside(buffer);
|
||||||
}, Qt::QueuedConnection);
|
},
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
|
||||||
connect(activity, &AndroidVPNActivity::serviceDisconnected, this,
|
connect(
|
||||||
|
activity, &AndroidVPNActivity::serviceDisconnected, this,
|
||||||
[this]() {
|
[this]() {
|
||||||
qDebug() << "Transact: service disconnected";
|
qDebug() << "Transact: service disconnected";
|
||||||
m_serviceConnected = false;
|
m_serviceConnected = false;
|
||||||
}, Qt::QueuedConnection);
|
},
|
||||||
|
Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
AndroidController* AndroidController::instance() {
|
AndroidController *AndroidController::instance()
|
||||||
|
{
|
||||||
if (!s_instance) {
|
if (!s_instance) {
|
||||||
s_instance = new AndroidController();
|
s_instance = new AndroidController();
|
||||||
}
|
}
|
||||||
|
@ -143,15 +160,12 @@ AndroidController* AndroidController::instance() {
|
||||||
return s_instance;
|
return s_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AndroidController::initialize(StartPageLogic *startPageLogic)
|
bool AndroidController::initialize()
|
||||||
{
|
{
|
||||||
qDebug() << "Initializing";
|
qDebug() << "Initializing";
|
||||||
|
|
||||||
m_startPageLogic = startPageLogic;
|
|
||||||
|
|
||||||
// Hook in the native implementation for startActivityForResult into the JNI
|
// Hook in the native implementation for startActivityForResult into the JNI
|
||||||
JNINativeMethod methods[]{{"startActivityForResult",
|
JNINativeMethod methods[] { { "startActivityForResult", "(Landroid/content/Intent;)V",
|
||||||
"(Landroid/content/Intent;)V",
|
|
||||||
reinterpret_cast<void *>(startActivityForResult) } };
|
reinterpret_cast<void *>(startActivityForResult) } };
|
||||||
QJniObject javaClass(PERMISSIONHELPER_CLASS);
|
QJniObject javaClass(PERMISSIONHELPER_CLASS);
|
||||||
QJniEnvironment env;
|
QJniEnvironment env;
|
||||||
|
@ -168,10 +182,8 @@ ErrorCode AndroidController::start()
|
||||||
{
|
{
|
||||||
qDebug() << "Prompting for VPN permission";
|
qDebug() << "Prompting for VPN permission";
|
||||||
QJniObject activity = AndroidUtils::getActivity();
|
QJniObject activity = AndroidUtils::getActivity();
|
||||||
auto appContext = activity.callObjectMethod(
|
auto appContext = activity.callObjectMethod("getApplicationContext", "()Landroid/content/Context;");
|
||||||
"getApplicationContext", "()Landroid/content/Context;");
|
QJniObject::callStaticMethod<void>(PERMISSIONHELPER_CLASS, "startService", "(Landroid/content/Context;)V",
|
||||||
QJniObject::callStaticMethod<void>(
|
|
||||||
PERMISSIONHELPER_CLASS, "startService", "(Landroid/content/Context;)V",
|
|
||||||
appContext.object());
|
appContext.object());
|
||||||
|
|
||||||
QJsonDocument doc(m_vpnConfig);
|
QJsonDocument doc(m_vpnConfig);
|
||||||
|
@ -180,7 +192,8 @@ ErrorCode AndroidController::start()
|
||||||
return NoError;
|
return NoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidController::stop() {
|
void AndroidController::stop()
|
||||||
|
{
|
||||||
qDebug() << "AndroidController::stop";
|
qDebug() << "AndroidController::stop";
|
||||||
|
|
||||||
AndroidVPNActivity::sendToService(ServiceAction::ACTION_DEACTIVATE, QString());
|
AndroidVPNActivity::sendToService(ServiceAction::ACTION_DEACTIVATE, QString());
|
||||||
|
@ -188,16 +201,16 @@ void AndroidController::stop() {
|
||||||
|
|
||||||
// Activates the tunnel that is currently set
|
// Activates the tunnel that is currently set
|
||||||
// in the VPN Service
|
// in the VPN Service
|
||||||
void AndroidController::resumeStart() {
|
void AndroidController::resumeStart()
|
||||||
|
{
|
||||||
AndroidVPNActivity::sendToService(ServiceAction::ACTION_RESUME_ACTIVATE, QString());
|
AndroidVPNActivity::sendToService(ServiceAction::ACTION_RESUME_ACTIVATE, QString());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sets the current notification text that is shown
|
* Sets the current notification text that is shown
|
||||||
*/
|
*/
|
||||||
void AndroidController::setNotificationText(const QString& title,
|
void AndroidController::setNotificationText(const QString &title, const QString &message, int timerSec)
|
||||||
const QString& message,
|
{
|
||||||
int timerSec) {
|
|
||||||
QJsonObject args;
|
QJsonObject args;
|
||||||
args["title"] = title;
|
args["title"] = title;
|
||||||
args["message"] = message;
|
args["message"] = message;
|
||||||
|
@ -207,7 +220,8 @@ void AndroidController::setNotificationText(const QString& title,
|
||||||
AndroidVPNActivity::sendToService(ServiceAction::ACTION_SET_NOTIFICATION_TEXT, doc.toJson());
|
AndroidVPNActivity::sendToService(ServiceAction::ACTION_SET_NOTIFICATION_TEXT, doc.toJson());
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidController::shareConfig(const QString& configContent, const QString& suggestedName) {
|
void AndroidController::shareConfig(const QString &configContent, const QString &suggestedName)
|
||||||
|
{
|
||||||
AndroidVPNActivity::saveFileAs(configContent, suggestedName);
|
AndroidVPNActivity::saveFileAs(configContent, suggestedName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,7 +230,8 @@ void AndroidController::shareConfig(const QString& configContent, const QString&
|
||||||
* switches into the Connected state without the app open
|
* switches into the Connected state without the app open
|
||||||
* e.g via always-on vpn
|
* e.g via always-on vpn
|
||||||
*/
|
*/
|
||||||
void AndroidController::setFallbackConnectedNotification() {
|
void AndroidController::setFallbackConnectedNotification()
|
||||||
|
{
|
||||||
QJsonObject args;
|
QJsonObject args;
|
||||||
args["title"] = tr("AmneziaVPN");
|
args["title"] = tr("AmneziaVPN");
|
||||||
//% "Ready for you to connect"
|
//% "Ready for you to connect"
|
||||||
|
@ -227,11 +242,13 @@ void AndroidController::setFallbackConnectedNotification() {
|
||||||
AndroidVPNActivity::sendToService(ServiceAction::ACTION_SET_NOTIFICATION_FALLBACK, doc.toJson());
|
AndroidVPNActivity::sendToService(ServiceAction::ACTION_SET_NOTIFICATION_FALLBACK, doc.toJson());
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidController::checkStatus() {
|
void AndroidController::checkStatus()
|
||||||
|
{
|
||||||
AndroidVPNActivity::sendToService(ServiceAction::ACTION_REQUEST_STATISTIC, QString());
|
AndroidVPNActivity::sendToService(ServiceAction::ACTION_REQUEST_STATISTIC, QString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidController::getBackendLogs(std::function<void(const QString&)>&& a_callback) {
|
void AndroidController::getBackendLogs(std::function<void(const QString &)> &&a_callback)
|
||||||
|
{
|
||||||
qDebug() << "get logs";
|
qDebug() << "get logs";
|
||||||
|
|
||||||
m_logCallback = std::move(a_callback);
|
m_logCallback = std::move(a_callback);
|
||||||
|
@ -239,16 +256,13 @@ void AndroidController::getBackendLogs(std::function<void(const QString&)>&& a_c
|
||||||
AndroidVPNActivity::sendToService(ServiceAction::ACTION_REQUEST_GET_LOG, QString());
|
AndroidVPNActivity::sendToService(ServiceAction::ACTION_REQUEST_GET_LOG, QString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidController::cleanupBackendLogs() {
|
void AndroidController::cleanupBackendLogs()
|
||||||
|
{
|
||||||
qDebug() << "cleanup logs";
|
qDebug() << "cleanup logs";
|
||||||
|
|
||||||
AndroidVPNActivity::sendToService(ServiceAction::ACTION_REQUEST_CLEANUP_LOG, QString());
|
AndroidVPNActivity::sendToService(ServiceAction::ACTION_REQUEST_CLEANUP_LOG, QString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidController::importConfig(const QString& data){
|
|
||||||
m_startPageLogic->importAnyFile(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
const QJsonObject &AndroidController::vpnConfig() const
|
const QJsonObject &AndroidController::vpnConfig() const
|
||||||
{
|
{
|
||||||
return m_vpnConfig;
|
return m_vpnConfig;
|
||||||
|
@ -285,9 +299,7 @@ void AndroidController::startActivityForResult(JNIEnv *env, jobject, jobject int
|
||||||
qDebug() << "start vpnPermissionHelper";
|
qDebug() << "start vpnPermissionHelper";
|
||||||
Q_UNUSED(env);
|
Q_UNUSED(env);
|
||||||
|
|
||||||
QtAndroidPrivate::startActivity(intent, 1337,
|
QtAndroidPrivate::startActivity(intent, 1337, [](int receiverRequestCode, int resultCode, const QJniObject &data) {
|
||||||
[](int receiverRequestCode, int resultCode,
|
|
||||||
const QJniObject& data) {
|
|
||||||
// Currently this function just used in
|
// Currently this function just used in
|
||||||
// VPNService.kt::checkPermissions. So the result
|
// VPNService.kt::checkPermissions. So the result
|
||||||
// we're getting is if the User gave us the
|
// we're getting is if the User gave us the
|
||||||
|
@ -309,7 +321,7 @@ void AndroidController::startActivityForResult(JNIEnv *env, jobject, jobject int
|
||||||
// If the request got rejected abort the current
|
// If the request got rejected abort the current
|
||||||
// connection.
|
// connection.
|
||||||
qWarning() << "VPN PROMPT RESULT - Rejected";
|
qWarning() << "VPN PROMPT RESULT - Rejected";
|
||||||
emit controller->connectionStateChanged(VpnProtocol::Disconnected);
|
emit controller->connectionStateChanged(Vpn::ConnectionState::Disconnected);
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,13 +8,10 @@
|
||||||
#include <QJniEnvironment>
|
#include <QJniEnvironment>
|
||||||
#include <QJniObject>
|
#include <QJniObject>
|
||||||
|
|
||||||
#include "ui/pages_logic/StartPageLogic.h"
|
|
||||||
|
|
||||||
#include "protocols/vpnprotocol.h"
|
#include "protocols/vpnprotocol.h"
|
||||||
|
|
||||||
using namespace amnezia;
|
using namespace amnezia;
|
||||||
|
|
||||||
|
|
||||||
class AndroidController : public QObject
|
class AndroidController : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -25,7 +22,7 @@ public:
|
||||||
|
|
||||||
virtual ~AndroidController() override = default;
|
virtual ~AndroidController() override = default;
|
||||||
|
|
||||||
bool initialize(StartPageLogic *startPageLogic);
|
bool initialize();
|
||||||
|
|
||||||
ErrorCode start();
|
ErrorCode start();
|
||||||
void stop();
|
void stop();
|
||||||
|
@ -37,7 +34,6 @@ public:
|
||||||
void setFallbackConnectedNotification();
|
void setFallbackConnectedNotification();
|
||||||
void getBackendLogs(std::function<void(const QString &)> &&callback);
|
void getBackendLogs(std::function<void(const QString &)> &&callback);
|
||||||
void cleanupBackendLogs();
|
void cleanupBackendLogs();
|
||||||
void importConfig(const QString& data);
|
|
||||||
|
|
||||||
const QJsonObject &vpnConfig() const;
|
const QJsonObject &vpnConfig() const;
|
||||||
void setVpnConfig(const QJsonObject &newVpnConfig);
|
void setVpnConfig(const QJsonObject &newVpnConfig);
|
||||||
|
@ -45,7 +41,7 @@ public:
|
||||||
void startQrReaderActivity();
|
void startQrReaderActivity();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void connectionStateChanged(VpnProtocol::VpnConnectionState state);
|
void connectionStateChanged(Vpn::ConnectionState state);
|
||||||
|
|
||||||
// This signal is emitted when the controller is initialized. Note that the
|
// This signal is emitted when the controller is initialized. Note that the
|
||||||
// VPN tunnel can be already active. In this case, "connected" should be set
|
// VPN tunnel can be already active. In this case, "connected" should be set
|
||||||
|
@ -57,6 +53,8 @@ signals:
|
||||||
void statusUpdated(QString totalRx, QString totalTx, QString endpoint, QString deviceIPv4);
|
void statusUpdated(QString totalRx, QString totalTx, QString endpoint, QString deviceIPv4);
|
||||||
void scheduleStatusCheckSignal();
|
void scheduleStatusCheckSignal();
|
||||||
|
|
||||||
|
void importConfigFromOutside(QString &data);
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void scheduleStatusCheckSlot();
|
void scheduleStatusCheckSlot();
|
||||||
|
|
||||||
|
@ -65,8 +63,6 @@ private:
|
||||||
|
|
||||||
QJsonObject m_vpnConfig;
|
QJsonObject m_vpnConfig;
|
||||||
|
|
||||||
StartPageLogic *m_startPageLogic;
|
|
||||||
|
|
||||||
bool m_serviceConnected = false;
|
bool m_serviceConnected = false;
|
||||||
std::function<void(const QString &)> m_logCallback;
|
std::function<void(const QString &)> m_logCallback;
|
||||||
|
|
||||||
|
|
16
client/platforms/android/authResultReceiver.cpp
Normal file
16
client/platforms/android/authResultReceiver.cpp
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
#include "authResultReceiver.h"
|
||||||
|
|
||||||
|
AuthResultReceiver::AuthResultReceiver(QSharedPointer<AuthResultNotifier> ¬ifier) : m_notifier(notifier)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AuthResultReceiver::handleActivityResult(int receiverRequestCode, int resultCode, const QJniObject &data)
|
||||||
|
{
|
||||||
|
qDebug() << "receiverRequestCode" << receiverRequestCode << "resultCode" << resultCode;
|
||||||
|
|
||||||
|
if (resultCode == -1) { // ResultOK
|
||||||
|
emit m_notifier->authSuccessful();
|
||||||
|
} else {
|
||||||
|
emit m_notifier->authFailed();
|
||||||
|
}
|
||||||
|
}
|
32
client/platforms/android/authResultReceiver.h
Normal file
32
client/platforms/android/authResultReceiver.h
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
#ifndef AUTHRESULTRECEIVER_H
|
||||||
|
#define AUTHRESULTRECEIVER_H
|
||||||
|
|
||||||
|
#include <QJniObject>
|
||||||
|
|
||||||
|
#include <private/qandroidextras_p.h>
|
||||||
|
|
||||||
|
class AuthResultNotifier : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
AuthResultNotifier(QObject *parent = nullptr) : QObject(parent) {};
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void authFailed();
|
||||||
|
void authSuccessful();
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Auth result handler for Android */
|
||||||
|
class AuthResultReceiver final : public QAndroidActivityResultReceiver
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AuthResultReceiver(QSharedPointer<AuthResultNotifier> ¬ifier);
|
||||||
|
|
||||||
|
void handleActivityResult(int receiverRequestCode, int resultCode, const QJniObject &data) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QSharedPointer<AuthResultNotifier> m_notifier;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // AUTHRESULTRECEIVER_H
|
|
@ -5,12 +5,13 @@
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
|
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include "wireguardprotocol.h"
|
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
|
#include "wireguardprotocol.h"
|
||||||
|
|
||||||
#include "mozilla/localsocketcontroller.h"
|
#include "mozilla/localsocketcontroller.h"
|
||||||
|
|
||||||
WireguardProtocol::WireguardProtocol(const QJsonObject &configuration, QObject* parent) : VpnProtocol(configuration, parent)
|
WireguardProtocol::WireguardProtocol(const QJsonObject &configuration, QObject *parent)
|
||||||
|
: VpnProtocol(configuration, parent)
|
||||||
{
|
{
|
||||||
m_configFile.setFileName(QDir::tempPath() + QDir::separator() + serviceName() + ".conf");
|
m_configFile.setFileName(QDir::tempPath() + QDir::separator() + serviceName() + ".conf");
|
||||||
writeWireguardConfiguration(configuration);
|
writeWireguardConfiguration(configuration);
|
||||||
|
@ -20,12 +21,12 @@ WireguardProtocol::WireguardProtocol(const QJsonObject &configuration, QObject*
|
||||||
// m_impl.reset(new LinuxController());
|
// m_impl.reset(new LinuxController());
|
||||||
#elif defined(MZ_MACOS) // || defined(MZ_WINDOWS)
|
#elif defined(MZ_MACOS) // || defined(MZ_WINDOWS)
|
||||||
m_impl.reset(new LocalSocketController());
|
m_impl.reset(new LocalSocketController());
|
||||||
connect(m_impl.get(), &ControllerImpl::connected, this, [this](const QString& pubkey, const QDateTime& connectionTimestamp) {
|
connect(m_impl.get(), &ControllerImpl::connected, this,
|
||||||
emit connectionStateChanged(VpnProtocol::Connected);
|
[this](const QString &pubkey, const QDateTime &connectionTimestamp) {
|
||||||
});
|
emit connectionStateChanged(Vpn::ConnectionState::Connected);
|
||||||
connect(m_impl.get(), &ControllerImpl::disconnected, this, [this](){
|
|
||||||
emit connectionStateChanged(VpnProtocol::Disconnected);
|
|
||||||
});
|
});
|
||||||
|
connect(m_impl.get(), &ControllerImpl::disconnected, this,
|
||||||
|
[this]() { emit connectionStateChanged(Vpn::ConnectionState::Disconnected); });
|
||||||
m_impl->initialize(nullptr, nullptr);
|
m_impl->initialize(nullptr, nullptr);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -74,7 +75,8 @@ void WireguardProtocol::stop()
|
||||||
setConnectionState(Vpn::ConnectionState::Disconnected);
|
setConnectionState(Vpn::ConnectionState::Disconnected);
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(m_wireguardStopProcess.data(), &PrivilegedProcess::stateChanged, this, [this](QProcess::ProcessState newState) {
|
connect(m_wireguardStopProcess.data(), &PrivilegedProcess::stateChanged, this,
|
||||||
|
[this](QProcess::ProcessState newState) {
|
||||||
qDebug() << "WireguardProtocol::WireguardProtocol Stop stateChanged" << newState;
|
qDebug() << "WireguardProtocol::WireguardProtocol Stop stateChanged" << newState;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -143,8 +145,8 @@ void WireguardProtocol::writeWireguardConfiguration(const QJsonObject &configura
|
||||||
m_isConfigLoaded = true;
|
m_isConfigLoaded = true;
|
||||||
|
|
||||||
qDebug().noquote() << QString("Set config data") << configPath();
|
qDebug().noquote() << QString("Set config data") << configPath();
|
||||||
qDebug().noquote() << QString("Set config data") << configuration.value(ProtocolProps::key_proto_config_data(Proto::WireGuard)).toString().toUtf8();
|
qDebug().noquote() << QString("Set config data")
|
||||||
|
<< configuration.value(ProtocolProps::key_proto_config_data(Proto::WireGuard)).toString().toUtf8();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString WireguardProtocol::configPath() const
|
QString WireguardProtocol::configPath() const
|
||||||
|
@ -156,7 +158,8 @@ void WireguardProtocol::updateRouteGateway(QString line)
|
||||||
{
|
{
|
||||||
// TODO: fix for macos
|
// TODO: fix for macos
|
||||||
line = line.split("ROUTE_GATEWAY", Qt::SkipEmptyParts).at(1);
|
line = line.split("ROUTE_GATEWAY", Qt::SkipEmptyParts).at(1);
|
||||||
if (!line.contains("/")) return;
|
if (!line.contains("/"))
|
||||||
|
return;
|
||||||
m_routeGateway = line.split("/", Qt::SkipEmptyParts).first();
|
m_routeGateway = line.split("/", Qt::SkipEmptyParts).first();
|
||||||
m_routeGateway.replace(" ", "");
|
m_routeGateway.replace(" ", "");
|
||||||
qDebug() << "Set VPN route gateway" << m_routeGateway;
|
qDebug() << "Set VPN route gateway" << m_routeGateway;
|
||||||
|
@ -216,13 +219,13 @@ ErrorCode WireguardProtocol::start()
|
||||||
setConnectionState(Vpn::ConnectionState::Disconnected);
|
setConnectionState(Vpn::ConnectionState::Disconnected);
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(m_wireguardStartProcess.data(), &PrivilegedProcess::stateChanged, this, [this](QProcess::ProcessState newState) {
|
connect(m_wireguardStartProcess.data(), &PrivilegedProcess::stateChanged, this,
|
||||||
|
[this](QProcess::ProcessState newState) {
|
||||||
qDebug() << "WireguardProtocol::WireguardProtocol stateChanged" << newState;
|
qDebug() << "WireguardProtocol::WireguardProtocol stateChanged" << newState;
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(m_wireguardStartProcess.data(), &PrivilegedProcess::finished, this, [this]() {
|
connect(m_wireguardStartProcess.data(), &PrivilegedProcess::finished, this,
|
||||||
setConnectionState(Vpn::ConnectionState::Connected);
|
[this]() { setConnectionState(Vpn::ConnectionState::Connected); });
|
||||||
});
|
|
||||||
|
|
||||||
connect(m_wireguardStartProcess.data(), &PrivilegedProcess::readyRead, this, [this]() {
|
connect(m_wireguardStartProcess.data(), &PrivilegedProcess::readyRead, this, [this]() {
|
||||||
QRemoteObjectPendingReply<QByteArray> reply = m_wireguardStartProcess->readAll();
|
QRemoteObjectPendingReply<QByteArray> reply = m_wireguardStartProcess->readAll();
|
||||||
|
@ -250,7 +253,6 @@ ErrorCode WireguardProtocol::start()
|
||||||
|
|
||||||
void WireguardProtocol::updateVpnGateway(const QString &line)
|
void WireguardProtocol::updateVpnGateway(const QString &line)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString WireguardProtocol::serviceName() const
|
QString WireguardProtocol::serviceName() const
|
||||||
|
@ -279,4 +281,3 @@ QStringList WireguardProtocol::startArgs()
|
||||||
return {};
|
return {};
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -194,7 +194,6 @@
|
||||||
<file>ui/qml/Controls2/HorizontalRadioButton.qml</file>
|
<file>ui/qml/Controls2/HorizontalRadioButton.qml</file>
|
||||||
<file>ui/qml/Controls2/VerticalRadioButton.qml</file>
|
<file>ui/qml/Controls2/VerticalRadioButton.qml</file>
|
||||||
<file>ui/qml/Controls2/SwitcherType.qml</file>
|
<file>ui/qml/Controls2/SwitcherType.qml</file>
|
||||||
<file>ui/qml/Pages2/PageTest.qml</file>
|
|
||||||
<file>ui/qml/Controls2/TabButtonType.qml</file>
|
<file>ui/qml/Controls2/TabButtonType.qml</file>
|
||||||
<file>ui/qml/Pages2/PageSetupWizardProtocolSettings.qml</file>
|
<file>ui/qml/Pages2/PageSetupWizardProtocolSettings.qml</file>
|
||||||
<file>ui/qml/Pages2/PageSetupWizardInstalling.qml</file>
|
<file>ui/qml/Pages2/PageSetupWizardInstalling.qml</file>
|
||||||
|
@ -278,5 +277,6 @@
|
||||||
<file>ui/qml/Pages2/PageServiceSftpSettings.qml</file>
|
<file>ui/qml/Pages2/PageServiceSftpSettings.qml</file>
|
||||||
<file>images/controls/copy.svg</file>
|
<file>images/controls/copy.svg</file>
|
||||||
<file>ui/qml/Pages2/PageServiceTorWebsiteSettings.qml</file>
|
<file>ui/qml/Pages2/PageServiceTorWebsiteSettings.qml</file>
|
||||||
|
<file>ui/qml/Pages2/PageSetupWizardQrReader.qml</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
@ -11,9 +11,12 @@
|
||||||
|
|
||||||
#include "configurators/openvpn_configurator.h"
|
#include "configurators/openvpn_configurator.h"
|
||||||
#include "configurators/wireguard_configurator.h"
|
#include "configurators/wireguard_configurator.h"
|
||||||
#include "qrcodegen.hpp"
|
|
||||||
|
|
||||||
#include "core/errorstrings.h"
|
#include "core/errorstrings.h"
|
||||||
|
#ifdef Q_OS_ANDROID
|
||||||
|
#include "platforms/android/android_controller.h"
|
||||||
|
#include "platforms/android/androidutils.h"
|
||||||
|
#endif
|
||||||
|
#include "qrcodegen.hpp"
|
||||||
|
|
||||||
ExportController::ExportController(const QSharedPointer<ServersModel> &serversModel,
|
ExportController::ExportController(const QSharedPointer<ServersModel> &serversModel,
|
||||||
const QSharedPointer<ContainersModel> &containersModel,
|
const QSharedPointer<ContainersModel> &containersModel,
|
||||||
|
@ -25,6 +28,14 @@ ExportController::ExportController(const QSharedPointer<ServersModel> &serversMo
|
||||||
m_settings(settings),
|
m_settings(settings),
|
||||||
m_configurator(configurator)
|
m_configurator(configurator)
|
||||||
{
|
{
|
||||||
|
#ifdef Q_OS_ANDROID
|
||||||
|
m_authResultNotifier.reset(new AuthResultNotifier);
|
||||||
|
m_authResultReceiver.reset(new AuthResultReceiver(m_authResultNotifier));
|
||||||
|
connect(m_authResultNotifier.get(), &AuthResultNotifier::authFailed, this,
|
||||||
|
[this]() { emit exportErrorOccurred(tr("Access error!")); });
|
||||||
|
connect(m_authResultNotifier.get(), &AuthResultNotifier::authSuccessful, this,
|
||||||
|
&ExportController::generateFullAccessConfig);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExportController::generateFullAccessConfig()
|
void ExportController::generateFullAccessConfig()
|
||||||
|
@ -44,6 +55,27 @@ void ExportController::generateFullAccessConfig()
|
||||||
emit exportConfigChanged();
|
emit exportConfigChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(Q_OS_ANDROID)
|
||||||
|
void ExportController::generateFullAccessConfigAndroid()
|
||||||
|
{
|
||||||
|
/* We use builtin keyguard for ssh key export protection on Android */
|
||||||
|
QJniObject activity = AndroidUtils::getActivity();
|
||||||
|
auto appContext = activity.callObjectMethod("getApplicationContext", "()Landroid/content/Context;");
|
||||||
|
if (appContext.isValid()) {
|
||||||
|
auto intent = QJniObject::callStaticObjectMethod("org/amnezia/vpn/AuthHelper", "getAuthIntent",
|
||||||
|
"(Landroid/content/Context;)Landroid/content/Intent;",
|
||||||
|
appContext.object());
|
||||||
|
if (intent.isValid()) {
|
||||||
|
if (intent.object<jobject>() != nullptr) {
|
||||||
|
QtAndroidPrivate::startActivity(intent.object<jobject>(), 1, m_authResultReceiver.get());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
generateFullAccessConfig();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void ExportController::generateConnectionConfig()
|
void ExportController::generateConnectionConfig()
|
||||||
{
|
{
|
||||||
clearPreviousConfig();
|
clearPreviousConfig();
|
||||||
|
@ -194,6 +226,35 @@ void ExportController::saveFile()
|
||||||
QDesktopServices::openUrl(fi.absoluteDir().absolutePath());
|
QDesktopServices::openUrl(fi.absoluteDir().absolutePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ExportController::shareFile()
|
||||||
|
{
|
||||||
|
#if defined Q_OS_IOS
|
||||||
|
ext.replace("*", "");
|
||||||
|
QString fileName = QDir::tempPath() + "/" + suggestedName;
|
||||||
|
|
||||||
|
if (fileName.isEmpty())
|
||||||
|
return;
|
||||||
|
if (!fileName.endsWith(ext))
|
||||||
|
fileName.append(ext);
|
||||||
|
|
||||||
|
QFile::remove(fileName);
|
||||||
|
|
||||||
|
QFile save(fileName);
|
||||||
|
save.open(QIODevice::WriteOnly);
|
||||||
|
save.write(data.toUtf8());
|
||||||
|
save.close();
|
||||||
|
|
||||||
|
QStringList filesToSend;
|
||||||
|
filesToSend.append(fileName);
|
||||||
|
MobileUtils::shareText(filesToSend);
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
#if defined Q_OS_ANDROID
|
||||||
|
AndroidController::instance()->shareConfig(m_config, "amnezia_config");
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
QList<QString> ExportController::generateQrCodeImageSeries(const QByteArray &data)
|
QList<QString> ExportController::generateQrCodeImageSeries(const QByteArray &data)
|
||||||
{
|
{
|
||||||
double k = 850;
|
double k = 850;
|
||||||
|
|
|
@ -6,6 +6,9 @@
|
||||||
#include "configurators/vpn_configurator.h"
|
#include "configurators/vpn_configurator.h"
|
||||||
#include "ui/models/containers_model.h"
|
#include "ui/models/containers_model.h"
|
||||||
#include "ui/models/servers_model.h"
|
#include "ui/models/servers_model.h"
|
||||||
|
#ifdef Q_OS_ANDROID
|
||||||
|
#include "platforms/android/authResultReceiver.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
class ExportController : public QObject
|
class ExportController : public QObject
|
||||||
{
|
{
|
||||||
|
@ -22,6 +25,9 @@ public:
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void generateFullAccessConfig();
|
void generateFullAccessConfig();
|
||||||
|
#if defined(Q_OS_ANDROID)
|
||||||
|
void generateFullAccessConfigAndroid();
|
||||||
|
#endif
|
||||||
void generateConnectionConfig();
|
void generateConnectionConfig();
|
||||||
void generateOpenVpnConfig();
|
void generateOpenVpnConfig();
|
||||||
void generateWireGuardConfig();
|
void generateWireGuardConfig();
|
||||||
|
@ -30,6 +36,7 @@ public slots:
|
||||||
QList<QString> getQrCodes();
|
QList<QString> getQrCodes();
|
||||||
|
|
||||||
void saveFile();
|
void saveFile();
|
||||||
|
void shareFile();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void generateConfig(int type);
|
void generateConfig(int type);
|
||||||
|
@ -52,6 +59,11 @@ private:
|
||||||
|
|
||||||
QString m_config;
|
QString m_config;
|
||||||
QList<QString> m_qrCodes;
|
QList<QString> m_qrCodes;
|
||||||
|
|
||||||
|
#ifdef Q_OS_ANDROID
|
||||||
|
QSharedPointer<AuthResultNotifier> m_authResultNotifier;
|
||||||
|
QSharedPointer<QAndroidActivityResultReceiver> m_authResultReceiver;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // EXPORTCONTROLLER_H
|
#endif // EXPORTCONTROLLER_H
|
||||||
|
|
|
@ -2,8 +2,15 @@
|
||||||
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
|
#include <QStandardPaths>
|
||||||
|
|
||||||
#include "core/errorstrings.h"
|
#include "core/errorstrings.h"
|
||||||
|
#ifdef Q_OS_ANDROID
|
||||||
|
#include "../../platforms/android/android_controller.h"
|
||||||
|
#include "../../platforms/android/androidutils.h"
|
||||||
|
#include <QJniObject>
|
||||||
|
#endif
|
||||||
|
#include "utilities.h"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
@ -41,14 +48,35 @@ ImportController::ImportController(const QSharedPointer<ServersModel> &serversMo
|
||||||
const std::shared_ptr<Settings> &settings, QObject *parent)
|
const std::shared_ptr<Settings> &settings, QObject *parent)
|
||||||
: QObject(parent), m_serversModel(serversModel), m_containersModel(containersModel), m_settings(settings)
|
: QObject(parent), m_serversModel(serversModel), m_containersModel(containersModel), m_settings(settings)
|
||||||
{
|
{
|
||||||
|
#ifdef Q_OS_ANDROID
|
||||||
|
// Set security screen for Android app
|
||||||
|
AndroidUtils::runOnAndroidThreadSync([]() {
|
||||||
|
QJniObject activity = AndroidUtils::getActivity();
|
||||||
|
QJniObject window = activity.callObjectMethod("getWindow", "()Landroid/view/Window;");
|
||||||
|
if (window.isValid()) {
|
||||||
|
const int FLAG_SECURE = 8192;
|
||||||
|
window.callMethod<void>("addFlags", "(I)V", FLAG_SECURE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImportController::extractConfigFromFile(const QUrl &fileUrl)
|
void ImportController::extractConfigFromFile()
|
||||||
{
|
{
|
||||||
QFile file(fileUrl.toLocalFile());
|
QString fileName = Utils::getFileName(Q_NULLPTR, tr("Open config file"),
|
||||||
|
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),
|
||||||
|
"*.vpn *.ovpn *.conf");
|
||||||
|
QFile file(fileName);
|
||||||
if (file.open(QIODevice::ReadOnly)) {
|
if (file.open(QIODevice::ReadOnly)) {
|
||||||
QString data = file.readAll();
|
QString data = file.readAll();
|
||||||
|
|
||||||
|
extractConfigFromData(data);
|
||||||
|
m_configFileName = QFileInfo(file.fileName()).fileName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImportController::extractConfigFromData(QString &data)
|
||||||
|
{
|
||||||
auto configFormat = checkConfigFormat(data);
|
auto configFormat = checkConfigFormat(data);
|
||||||
if (configFormat == ConfigTypes::OpenVpn) {
|
if (configFormat == ConfigTypes::OpenVpn) {
|
||||||
m_config = extractOpenVpnConfig(data);
|
m_config = extractOpenVpnConfig(data);
|
||||||
|
@ -57,9 +85,6 @@ void ImportController::extractConfigFromFile(const QUrl &fileUrl)
|
||||||
} else {
|
} else {
|
||||||
m_config = extractAmneziaConfig(data);
|
m_config = extractAmneziaConfig(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_configFileName = QFileInfo(file.fileName()).fileName();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImportController::extractConfigFromCode(QString code)
|
void ImportController::extractConfigFromCode(QString code)
|
||||||
|
@ -68,6 +93,13 @@ void ImportController::extractConfigFromCode(QString code)
|
||||||
m_configFileName = "";
|
m_configFileName = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImportController::extractConfigFromQr()
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_ANDROID
|
||||||
|
AndroidController::instance()->startQrReaderActivity();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
QString ImportController::getConfig()
|
QString ImportController::getConfig()
|
||||||
{
|
{
|
||||||
return QJsonDocument(m_config).toJson(QJsonDocument::Indented);
|
return QJsonDocument(m_config).toJson(QJsonDocument::Indented);
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
#include "core/defs.h"
|
|
||||||
#include "containers/containers_defs.h"
|
#include "containers/containers_defs.h"
|
||||||
#include "ui/models/servers_model.h"
|
#include "core/defs.h"
|
||||||
#include "ui/models/containers_model.h"
|
#include "ui/models/containers_model.h"
|
||||||
|
#include "ui/models/servers_model.h"
|
||||||
|
|
||||||
class ImportController : public QObject
|
class ImportController : public QObject
|
||||||
{
|
{
|
||||||
|
@ -14,13 +14,14 @@ class ImportController : public QObject
|
||||||
public:
|
public:
|
||||||
explicit ImportController(const QSharedPointer<ServersModel> &serversModel,
|
explicit ImportController(const QSharedPointer<ServersModel> &serversModel,
|
||||||
const QSharedPointer<ContainersModel> &containersModel,
|
const QSharedPointer<ContainersModel> &containersModel,
|
||||||
const std::shared_ptr<Settings> &settings,
|
const std::shared_ptr<Settings> &settings, QObject *parent = nullptr);
|
||||||
QObject *parent = nullptr);
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void importConfig();
|
void importConfig();
|
||||||
void extractConfigFromFile(const QUrl &fileUrl);
|
void extractConfigFromFile();
|
||||||
|
void extractConfigFromData(QString &data);
|
||||||
void extractConfigFromCode(QString code);
|
void extractConfigFromCode(QString code);
|
||||||
|
void extractConfigFromQr();
|
||||||
QString getConfig();
|
QString getConfig();
|
||||||
QString getConfigFileName();
|
QString getConfigFileName();
|
||||||
|
|
||||||
|
@ -39,7 +40,6 @@ private:
|
||||||
|
|
||||||
QJsonObject m_config;
|
QJsonObject m_config;
|
||||||
QString m_configFileName;
|
QString m_configFileName;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // IMPORTCONTROLLER_H
|
#endif // IMPORTCONTROLLER_H
|
||||||
|
|
|
@ -8,6 +8,34 @@
|
||||||
#include "core/servercontroller.h"
|
#include "core/servercontroller.h"
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
QString getNextDriverLetter()
|
||||||
|
{
|
||||||
|
QProcess drivesProc;
|
||||||
|
drivesProc.start("wmic logicaldisk get caption");
|
||||||
|
drivesProc.waitForFinished();
|
||||||
|
QString drives = drivesProc.readAll();
|
||||||
|
qDebug() << drives;
|
||||||
|
|
||||||
|
QString letters = "CFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
QString letter;
|
||||||
|
for (int i = letters.size() - 1; i > 0; i--) {
|
||||||
|
letter = letters.at(i);
|
||||||
|
if (!drives.contains(letter + ":"))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (letter == "C:") {
|
||||||
|
// set err info
|
||||||
|
qDebug() << "Can't find free drive letter";
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return letter;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
InstallController::InstallController(const QSharedPointer<ServersModel> &serversModel,
|
InstallController::InstallController(const QSharedPointer<ServersModel> &serversModel,
|
||||||
const QSharedPointer<ContainersModel> &containersModel,
|
const QSharedPointer<ContainersModel> &containersModel,
|
||||||
const std::shared_ptr<Settings> &settings, QObject *parent)
|
const std::shared_ptr<Settings> &settings, QObject *parent)
|
||||||
|
@ -15,6 +43,17 @@ InstallController::InstallController(const QSharedPointer<ServersModel> &servers
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InstallController::~InstallController()
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
for (QSharedPointer<QProcess> process : m_sftpMountProcesses) {
|
||||||
|
Utils::signalCtrl(process->processId(), CTRL_C_EVENT);
|
||||||
|
process->kill();
|
||||||
|
process->waitForFinished();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void InstallController::install(DockerContainer container, int port, TransportProto transportProto)
|
void InstallController::install(DockerContainer container, int port, TransportProto transportProto)
|
||||||
{
|
{
|
||||||
Proto mainProto = ContainerProps::defaultProtocol(container);
|
Proto mainProto = ContainerProps::defaultProtocol(container);
|
||||||
|
|
|
@ -16,6 +16,7 @@ public:
|
||||||
explicit InstallController(const QSharedPointer<ServersModel> &serversModel,
|
explicit InstallController(const QSharedPointer<ServersModel> &serversModel,
|
||||||
const QSharedPointer<ContainersModel> &containersModel,
|
const QSharedPointer<ContainersModel> &containersModel,
|
||||||
const std::shared_ptr<Settings> &settings, QObject *parent = nullptr);
|
const std::shared_ptr<Settings> &settings, QObject *parent = nullptr);
|
||||||
|
~InstallController();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void install(DockerContainer container, int port, TransportProto transportProto);
|
void install(DockerContainer container, int port, TransportProto transportProto);
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
#include "pageController.h"
|
#include "pageController.h"
|
||||||
|
|
||||||
PageController::PageController(const QSharedPointer<ServersModel> &serversModel,
|
#include <QApplication>
|
||||||
QObject *parent) : QObject(parent), m_serversModel(serversModel)
|
|
||||||
|
PageController::PageController(const QSharedPointer<ServersModel> &serversModel, QObject *parent)
|
||||||
|
: QObject(parent), m_serversModel(serversModel)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,3 +26,24 @@ QString PageController::getPagePath(PageLoader::PageEnum page)
|
||||||
QString pageName = metaEnum.valueToKey(static_cast<int>(page));
|
QString pageName = metaEnum.valueToKey(static_cast<int>(page));
|
||||||
return "qrc:/ui/qml/Pages2/" + pageName + ".qml";
|
return "qrc:/ui/qml/Pages2/" + pageName + ".qml";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PageController::closeWindow()
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_ANDROID
|
||||||
|
qApp->quit();
|
||||||
|
#else
|
||||||
|
if (m_serversModel->getServersCount() == 0) {
|
||||||
|
qApp->quit();
|
||||||
|
} else {
|
||||||
|
emit hideMainWindow();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void PageController::keyPressEvent(Qt::Key key)
|
||||||
|
{
|
||||||
|
switch (key) {
|
||||||
|
case Qt::Key_Back: emit closePage();
|
||||||
|
default: return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@ namespace PageLoader
|
||||||
PageSetupWizardConfigSource,
|
PageSetupWizardConfigSource,
|
||||||
PageSetupWizardTextKey,
|
PageSetupWizardTextKey,
|
||||||
PageSetupWizardViewConfig,
|
PageSetupWizardViewConfig,
|
||||||
|
PageSetupWizardQrReader,
|
||||||
|
|
||||||
PageProtocolOpenVpnSettings,
|
PageProtocolOpenVpnSettings,
|
||||||
PageProtocolShadowSocksSettings,
|
PageProtocolShadowSocksSettings,
|
||||||
|
@ -67,15 +68,25 @@ public slots:
|
||||||
QString getInitialPage();
|
QString getInitialPage();
|
||||||
QString getPagePath(PageLoader::PageEnum page);
|
QString getPagePath(PageLoader::PageEnum page);
|
||||||
|
|
||||||
|
void closeWindow();
|
||||||
|
void keyPressEvent(Qt::Key key);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void goToPageHome();
|
void goToPageHome();
|
||||||
void goToPageSettings();
|
void goToPageSettings();
|
||||||
|
void goToPageViewConfig();
|
||||||
|
void closePage();
|
||||||
|
|
||||||
void restorePageHomeState(bool isContainerInstalled = false);
|
void restorePageHomeState(bool isContainerInstalled = false);
|
||||||
void replaceStartPage();
|
void replaceStartPage();
|
||||||
|
|
||||||
void showErrorMessage(QString errorMessage);
|
void showErrorMessage(QString errorMessage);
|
||||||
void showInfoMessage(QString message);
|
void showInfoMessage(QString message);
|
||||||
|
|
||||||
void showBusyIndicator(bool visible);
|
void showBusyIndicator(bool visible);
|
||||||
void raise();
|
|
||||||
|
void hideMainWindow();
|
||||||
|
void raiseMainWindow();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QSharedPointer<ServersModel> m_serversModel;
|
QSharedPointer<ServersModel> m_serversModel;
|
||||||
|
|
|
@ -6,20 +6,21 @@
|
||||||
#include "VpnLogic.h"
|
#include "VpnLogic.h"
|
||||||
|
|
||||||
#include "core/errorstrings.h"
|
#include "core/errorstrings.h"
|
||||||
#include <core/servercontroller.h>
|
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
#include <core/servercontroller.h>
|
||||||
|
|
||||||
#if defined(Q_OS_ANDROID)
|
#if defined(Q_OS_ANDROID)
|
||||||
#include "../../platforms/android/androidutils.h"
|
#include "../../platforms/android/androidutils.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ServerSettingsLogic::ServerSettingsLogic(UiLogic *logic, QObject *parent):
|
ServerSettingsLogic::ServerSettingsLogic(UiLogic *logic, QObject *parent)
|
||||||
PageLogicBase(logic, parent),
|
: PageLogicBase(logic, parent),
|
||||||
m_labelWaitInfoVisible { true },
|
m_labelWaitInfoVisible { true },
|
||||||
m_pushButtonClearClientCacheVisible { true },
|
m_pushButtonClearClientCacheVisible { true },
|
||||||
m_pushButtonShareFullVisible { true },
|
m_pushButtonShareFullVisible { true },
|
||||||
m_pushButtonClearClientCacheText { tr("Clear client cached profile") }
|
m_pushButtonClearClientCacheText { tr("Clear client cached profile") }
|
||||||
{ }
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void ServerSettingsLogic::onUpdatePage()
|
void ServerSettingsLogic::onUpdatePage()
|
||||||
{
|
{
|
||||||
|
@ -49,15 +50,15 @@ void ServerSettingsLogic::onUpdatePage()
|
||||||
|
|
||||||
void ServerSettingsLogic::onPushButtonForgetServer()
|
void ServerSettingsLogic::onPushButtonForgetServer()
|
||||||
{
|
{
|
||||||
if (m_settings->defaultServerIndex() == uiLogic()->m_selectedServerIndex && uiLogic()->m_vpnConnection->isConnected()) {
|
if (m_settings->defaultServerIndex() == uiLogic()->m_selectedServerIndex
|
||||||
|
&& uiLogic()->m_vpnConnection->isConnected()) {
|
||||||
uiLogic()->pageLogic<VpnLogic>()->onDisconnect();
|
uiLogic()->pageLogic<VpnLogic>()->onDisconnect();
|
||||||
}
|
}
|
||||||
m_settings->removeServer(uiLogic()->m_selectedServerIndex);
|
m_settings->removeServer(uiLogic()->m_selectedServerIndex);
|
||||||
|
|
||||||
if (m_settings->defaultServerIndex() == uiLogic()->m_selectedServerIndex) {
|
if (m_settings->defaultServerIndex() == uiLogic()->m_selectedServerIndex) {
|
||||||
m_settings->setDefaultServer(0);
|
m_settings->setDefaultServer(0);
|
||||||
}
|
} else if (m_settings->defaultServerIndex() > uiLogic()->m_selectedServerIndex) {
|
||||||
else if (m_settings->defaultServerIndex() > uiLogic()->m_selectedServerIndex) {
|
|
||||||
m_settings->setDefaultServer(m_settings->defaultServerIndex() - 1);
|
m_settings->setDefaultServer(m_settings->defaultServerIndex() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,14 +66,12 @@ void ServerSettingsLogic::onPushButtonForgetServer()
|
||||||
m_settings->setDefaultServer(-1);
|
m_settings->setDefaultServer(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uiLogic()->m_selectedServerIndex = -1;
|
uiLogic()->m_selectedServerIndex = -1;
|
||||||
uiLogic()->onUpdateAllPages();
|
uiLogic()->onUpdateAllPages();
|
||||||
|
|
||||||
if (m_settings->serversCount() == 0) {
|
if (m_settings->serversCount() == 0) {
|
||||||
uiLogic()->setStartPage(Page::Start);
|
uiLogic()->setStartPage(Page::Start);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
uiLogic()->closePage();
|
uiLogic()->closePage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,9 +85,7 @@ void ServerSettingsLogic::onPushButtonClearClientCacheClicked()
|
||||||
m_settings->clearLastConnectionConfig(uiLogic()->m_selectedServerIndex, container);
|
m_settings->clearLastConnectionConfig(uiLogic()->m_selectedServerIndex, container);
|
||||||
}
|
}
|
||||||
|
|
||||||
QTimer::singleShot(3000, this, [this]() {
|
QTimer::singleShot(3000, this, [this]() { set_pushButtonClearClientCacheText(tr("Clear client cached profile")); });
|
||||||
set_pushButtonClearClientCacheText(tr("Clear client cached profile"));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerSettingsLogic::onLineEditDescriptionEditingFinished()
|
void ServerSettingsLogic::onLineEditDescriptionEditingFinished()
|
||||||
|
@ -123,24 +120,25 @@ void ServerSettingsLogic::onPushButtonShareFullClicked()
|
||||||
#if defined(Q_OS_ANDROID)
|
#if defined(Q_OS_ANDROID)
|
||||||
/* We use builtin keyguard for ssh key export protection on Android */
|
/* We use builtin keyguard for ssh key export protection on Android */
|
||||||
QJniObject activity = AndroidUtils::getActivity();
|
QJniObject activity = AndroidUtils::getActivity();
|
||||||
auto appContext = activity.callObjectMethod(
|
auto appContext = activity.callObjectMethod("getApplicationContext", "()Landroid/content/Context;");
|
||||||
"getApplicationContext", "()Landroid/content/Context;");
|
|
||||||
if (appContext.isValid()) {
|
if (appContext.isValid()) {
|
||||||
QAndroidActivityResultReceiver *receiver = new authResultReceiver(uiLogic(), uiLogic()->m_selectedServerIndex);
|
QAndroidActivityResultReceiver *receiver = new authResultReceiver(uiLogic(), uiLogic()->m_selectedServerIndex);
|
||||||
auto intent = QJniObject::callStaticObjectMethod(
|
auto intent = QJniObject::callStaticObjectMethod("org/amnezia/vpn/AuthHelper", "getAuthIntent",
|
||||||
"org/amnezia/vpn/AuthHelper", "getAuthIntent",
|
"(Landroid/content/Context;)Landroid/content/Intent;",
|
||||||
"(Landroid/content/Context;)Landroid/content/Intent;", appContext.object());
|
appContext.object());
|
||||||
if (intent.isValid()) {
|
if (intent.isValid()) {
|
||||||
if (intent.object<jobject>() != nullptr) {
|
if (intent.object<jobject>() != nullptr) {
|
||||||
QtAndroidPrivate::startActivity(intent.object<jobject>(), 1, receiver);
|
QtAndroidPrivate::startActivity(intent.object<jobject>(), 1, receiver);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
uiLogic()->pageLogic<ShareConnectionLogic>()->updateSharingPage(uiLogic()->m_selectedServerIndex, DockerContainer::None);
|
uiLogic()->pageLogic<ShareConnectionLogic>()->updateSharingPage(uiLogic()->m_selectedServerIndex,
|
||||||
|
DockerContainer::None);
|
||||||
emit uiLogic()->goToShareProtocolPage(Proto::Any);
|
emit uiLogic()->goToShareProtocolPage(Proto::Any);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
uiLogic()->pageLogic<ShareConnectionLogic>()->updateSharingPage(uiLogic()->m_selectedServerIndex, DockerContainer::None);
|
uiLogic()->pageLogic<ShareConnectionLogic>()->updateSharingPage(uiLogic()->m_selectedServerIndex,
|
||||||
|
DockerContainer::None);
|
||||||
emit uiLogic()->goToShareProtocolPage(Proto::Any);
|
emit uiLogic()->goToShareProtocolPage(Proto::Any);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +1,25 @@
|
||||||
#include "StartPageLogic.h"
|
#include "StartPageLogic.h"
|
||||||
#include "ViewConfigLogic.h"
|
#include "ViewConfigLogic.h"
|
||||||
|
|
||||||
#include "core/errorstrings.h"
|
#include "../uilogic.h"
|
||||||
#include "configurators/ssh_configurator.h"
|
#include "configurators/ssh_configurator.h"
|
||||||
#include "configurators/vpn_configurator.h"
|
#include "configurators/vpn_configurator.h"
|
||||||
#include "../uilogic.h"
|
#include "core/errorstrings.h"
|
||||||
#include "utilities.h"
|
|
||||||
#include "core/servercontroller.h"
|
#include "core/servercontroller.h"
|
||||||
|
#include "utilities.h"
|
||||||
|
|
||||||
|
#include <QEventLoop>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
#include <QEventLoop>
|
|
||||||
|
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
#include <QJniObject>
|
|
||||||
#include "../../platforms/android/androidutils.h"
|
|
||||||
#include "../../platforms/android/android_controller.h"
|
#include "../../platforms/android/android_controller.h"
|
||||||
|
#include "../../platforms/android/androidutils.h"
|
||||||
|
#include <QJniObject>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace {
|
namespace
|
||||||
|
{
|
||||||
enum class ConfigTypes {
|
enum class ConfigTypes {
|
||||||
Amnezia,
|
Amnezia,
|
||||||
OpenVpn,
|
OpenVpn,
|
||||||
|
@ -36,20 +37,20 @@ ConfigTypes checkConfigFormat(const QString &config)
|
||||||
const QString wireguardConfigPatternSectionInterface = "[Interface]";
|
const QString wireguardConfigPatternSectionInterface = "[Interface]";
|
||||||
const QString wireguardConfigPatternSectionPeer = "[Peer]";
|
const QString wireguardConfigPatternSectionPeer = "[Peer]";
|
||||||
|
|
||||||
if (config.contains(openVpnConfigPatternCli) &&
|
if (config.contains(openVpnConfigPatternCli)
|
||||||
(config.contains(openVpnConfigPatternProto1) || config.contains(openVpnConfigPatternProto2)) &&
|
&& (config.contains(openVpnConfigPatternProto1) || config.contains(openVpnConfigPatternProto2))
|
||||||
(config.contains(openVpnConfigPatternDriver1) || config.contains(openVpnConfigPatternDriver2))) {
|
&& (config.contains(openVpnConfigPatternDriver1) || config.contains(openVpnConfigPatternDriver2))) {
|
||||||
return ConfigTypes::OpenVpn;
|
return ConfigTypes::OpenVpn;
|
||||||
} else if (config.contains(wireguardConfigPatternSectionInterface) &&
|
} else if (config.contains(wireguardConfigPatternSectionInterface)
|
||||||
config.contains(wireguardConfigPatternSectionPeer))
|
&& config.contains(wireguardConfigPatternSectionPeer))
|
||||||
return ConfigTypes::WireGuard;
|
return ConfigTypes::WireGuard;
|
||||||
return ConfigTypes::Amnezia;
|
return ConfigTypes::Amnezia;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StartPageLogic::StartPageLogic(UiLogic *logic, QObject *parent):
|
StartPageLogic::StartPageLogic(UiLogic *logic, QObject *parent)
|
||||||
PageLogicBase(logic, parent),
|
: PageLogicBase(logic, parent),
|
||||||
m_pushButtonConnectEnabled { true },
|
m_pushButtonConnectEnabled { true },
|
||||||
m_pushButtonConnectText { tr("Connect") },
|
m_pushButtonConnectText { tr("Connect") },
|
||||||
m_pushButtonConnectKeyChecked { false },
|
m_pushButtonConnectKeyChecked { false },
|
||||||
|
@ -90,16 +91,12 @@ void StartPageLogic::onUpdatePage()
|
||||||
void StartPageLogic::onPushButtonConnect()
|
void StartPageLogic::onPushButtonConnect()
|
||||||
{
|
{
|
||||||
if (pushButtonConnectKeyChecked()) {
|
if (pushButtonConnectKeyChecked()) {
|
||||||
if (lineEditIpText().isEmpty() ||
|
if (lineEditIpText().isEmpty() || lineEditLoginText().isEmpty() || textEditSshKeyText().isEmpty()) {
|
||||||
lineEditLoginText().isEmpty() ||
|
|
||||||
textEditSshKeyText().isEmpty() ) {
|
|
||||||
set_labelWaitInfoText(tr("Please fill in all fields"));
|
set_labelWaitInfoText(tr("Please fill in all fields"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (lineEditIpText().isEmpty() ||
|
if (lineEditIpText().isEmpty() || lineEditLoginText().isEmpty() || lineEditPasswordText().isEmpty()) {
|
||||||
lineEditLoginText().isEmpty() ||
|
|
||||||
lineEditPasswordText().isEmpty() ) {
|
|
||||||
set_labelWaitInfoText(tr("Please fill in all fields"));
|
set_labelWaitInfoText(tr("Please fill in all fields"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -174,7 +171,8 @@ void StartPageLogic::onPushButtonConnect()
|
||||||
set_pushButtonConnectText(tr("Connect"));
|
set_pushButtonConnectText(tr("Connect"));
|
||||||
|
|
||||||
uiLogic()->m_installCredentials = serverCredentials;
|
uiLogic()->m_installCredentials = serverCredentials;
|
||||||
if (ok) emit uiLogic()->goToPage(Page::NewServer);
|
if (ok)
|
||||||
|
emit uiLogic()->goToPage(Page::NewServer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartPageLogic::onPushButtonImport()
|
void StartPageLogic::onPushButtonImport()
|
||||||
|
@ -185,8 +183,10 @@ void StartPageLogic::onPushButtonImport()
|
||||||
void StartPageLogic::onPushButtonImportOpenFile()
|
void StartPageLogic::onPushButtonImportOpenFile()
|
||||||
{
|
{
|
||||||
QString fileName = UiLogic::getOpenFileName(Q_NULLPTR, tr("Open config file"),
|
QString fileName = UiLogic::getOpenFileName(Q_NULLPTR, tr("Open config file"),
|
||||||
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation), "*.vpn *.ovpn *.conf");
|
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),
|
||||||
if (fileName.isEmpty()) return;
|
"*.vpn *.ovpn *.conf");
|
||||||
|
if (fileName.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
QFile file(fileName);
|
QFile file(fileName);
|
||||||
file.open(QIODevice::ReadOnly);
|
file.open(QIODevice::ReadOnly);
|
||||||
|
@ -226,8 +226,7 @@ bool StartPageLogic::importConnection(const QJsonObject &profile)
|
||||||
// check config
|
// check config
|
||||||
uiLogic()->pageLogic<ViewConfigLogic>()->set_configJson(profile);
|
uiLogic()->pageLogic<ViewConfigLogic>()->set_configJson(profile);
|
||||||
emit uiLogic()->goToPage(Page::ViewConfig);
|
emit uiLogic()->goToPage(Page::ViewConfig);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
qDebug() << "Failed to import profile";
|
qDebug() << "Failed to import profile";
|
||||||
qDebug().noquote() << QJsonDocument(profile).toJson();
|
qDebug().noquote() << QJsonDocument(profile).toJson();
|
||||||
return false;
|
return false;
|
||||||
|
@ -298,7 +297,6 @@ bool StartPageLogic::importConnectionFromOpenVpnConfig(const QString &config)
|
||||||
o[config_key::defaultContainer] = "amnezia-openvpn";
|
o[config_key::defaultContainer] = "amnezia-openvpn";
|
||||||
o[config_key::description] = m_settings->nextAvailableServerName();
|
o[config_key::description] = m_settings->nextAvailableServerName();
|
||||||
|
|
||||||
|
|
||||||
const static QRegularExpression dnsRegExp("dhcp-option DNS (\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b)");
|
const static QRegularExpression dnsRegExp("dhcp-option DNS (\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b)");
|
||||||
QRegularExpressionMatchIterator dnsMatch = dnsRegExp.globalMatch(config);
|
QRegularExpressionMatchIterator dnsMatch = dnsRegExp.globalMatch(config);
|
||||||
if (dnsMatch.hasNext()) {
|
if (dnsMatch.hasNext()) {
|
||||||
|
@ -345,7 +343,9 @@ bool StartPageLogic::importConnectionFromWireguardConfig(const QString &config)
|
||||||
o[config_key::defaultContainer] = "amnezia-wireguard";
|
o[config_key::defaultContainer] = "amnezia-wireguard";
|
||||||
o[config_key::description] = m_settings->nextAvailableServerName();
|
o[config_key::description] = m_settings->nextAvailableServerName();
|
||||||
|
|
||||||
const static QRegularExpression dnsRegExp("DNS = (\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b).*(\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b)");
|
const static QRegularExpression dnsRegExp(
|
||||||
|
"DNS = "
|
||||||
|
"(\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b).*(\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b)");
|
||||||
QRegularExpressionMatch dnsMatch = dnsRegExp.match(config);
|
QRegularExpressionMatch dnsMatch = dnsRegExp.match(config);
|
||||||
if (dnsMatch.hasMatch()) {
|
if (dnsMatch.hasMatch()) {
|
||||||
o[config_key::dns1] = dnsMatch.captured(1);
|
o[config_key::dns1] = dnsMatch.captured(1);
|
||||||
|
|
|
@ -54,10 +54,10 @@ DrawerType {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 16
|
Layout.topMargin: 16
|
||||||
|
|
||||||
text: qsTr("Save connection code")
|
text: Qt.platform.os === "android" ? qsTr("Share") : qsTr("Save connection code")
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
ExportController.saveFile()
|
Qt.platform.os === "android" ? ExportController.shareFile() : ExportController.saveFile()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ CheckBox {
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
|
|
||||||
indicator: Rectangle {
|
indicator: Rectangle {
|
||||||
id: checkBoxBackground
|
id: background
|
||||||
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
@ -57,7 +57,6 @@ CheckBox {
|
||||||
radius: 4
|
radius: 4
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
id: indicator
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
|
|
||||||
source: root.pressed ? imageSource : root.checked ? imageSource : ""
|
source: root.pressed ? imageSource : root.checked ? imageSource : ""
|
||||||
|
@ -71,17 +70,24 @@ CheckBox {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
contentItem: ColumnLayout {
|
contentItem: Item {
|
||||||
|
implicitWidth: content.implicitWidth
|
||||||
|
implicitHeight: content.implicitHeight
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.leftMargin: 8 + background.width
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: content
|
||||||
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.leftMargin: 8 + checkBoxBackground.width
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
spacing: 4
|
spacing: 4
|
||||||
|
|
||||||
ListItemTitleType {
|
ListItemTitleType {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
// Layout.topMargin: 16
|
|
||||||
// Layout.bottomMargin: description.visible ? 0 : 16
|
|
||||||
|
|
||||||
text: root.text
|
text: root.text
|
||||||
}
|
}
|
||||||
|
@ -90,7 +96,6 @@ CheckBox {
|
||||||
id: description
|
id: description
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.bottomMargin: 16
|
|
||||||
|
|
||||||
text: root.descriptionText
|
text: root.descriptionText
|
||||||
color: "#878b91"
|
color: "#878b91"
|
||||||
|
@ -98,6 +103,7 @@ CheckBox {
|
||||||
visible: root.descriptionText !== ""
|
visible: root.descriptionText !== ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
|
@ -20,7 +20,6 @@ Item {
|
||||||
if (root.stackView.depth <= 1) {
|
if (root.stackView.depth <= 1) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
root.stackView.pop()
|
root.stackView.pop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,11 +85,19 @@ RadioButton {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
contentItem: ColumnLayout {
|
contentItem: Item {
|
||||||
|
implicitWidth: content.implicitWidth
|
||||||
|
implicitHeight: content.implicitHeight
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.leftMargin: 8 + background.width
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
id: content
|
id: content
|
||||||
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.leftMargin: 8 + background.width
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
spacing: 4
|
spacing: 4
|
||||||
|
|
||||||
|
@ -104,8 +112,6 @@ RadioButton {
|
||||||
}
|
}
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 16
|
|
||||||
Layout.bottomMargin: description.visible ? 0 : 16
|
|
||||||
|
|
||||||
Behavior on color {
|
Behavior on color {
|
||||||
PropertyAnimation { duration: 200 }
|
PropertyAnimation { duration: 200 }
|
||||||
|
@ -121,7 +127,7 @@ RadioButton {
|
||||||
visible: root.descriptionText !== ""
|
visible: root.descriptionText !== ""
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.bottomMargin: 16
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,8 +43,8 @@ PageType {
|
||||||
Layout.topMargin: 16
|
Layout.topMargin: 16
|
||||||
Layout.leftMargin: 16
|
Layout.leftMargin: 16
|
||||||
Layout.rightMargin: 16
|
Layout.rightMargin: 16
|
||||||
Layout.preferredWidth: 344
|
Layout.preferredWidth: 291
|
||||||
Layout.preferredHeight: 279
|
Layout.preferredHeight: 224
|
||||||
}
|
}
|
||||||
|
|
||||||
Header2TextType {
|
Header2TextType {
|
||||||
|
@ -100,7 +100,7 @@ And if you don't like the app, all the more support it - the donation will be us
|
||||||
|
|
||||||
text: qsTr("Show other methods on Github")
|
text: qsTr("Show other methods on Github")
|
||||||
|
|
||||||
onClicked: Qt.openUrlExternally("https://github.com/amnezia-vpn/amnezia-client")
|
onClicked: Qt.openUrlExternally("https://github.com/amnezia-vpn/amnezia-client#donate")
|
||||||
}
|
}
|
||||||
|
|
||||||
ParagraphTextType {
|
ParagraphTextType {
|
||||||
|
|
|
@ -61,16 +61,18 @@ PageType {
|
||||||
leftImageSource: "qrc:/images/controls/folder-open.svg"
|
leftImageSource: "qrc:/images/controls/folder-open.svg"
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
onClicked: fileDialog.open()
|
// onClicked: fileDialog.open()
|
||||||
}
|
ImportController.extractConfigFromFile()
|
||||||
|
|
||||||
FileDialog {
|
|
||||||
id: fileDialog
|
|
||||||
onAccepted: {
|
|
||||||
ImportController.extractConfigFromFile(selectedFile)
|
|
||||||
goToPage(PageEnum.PageSetupWizardViewConfig)
|
goToPage(PageEnum.PageSetupWizardViewConfig)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// FileDialog {
|
||||||
|
// id: fileDialog
|
||||||
|
// onAccepted: {
|
||||||
|
// ImportController.extractConfigFromFile(selectedFile)
|
||||||
|
// goToPage(PageEnum.PageSetupWizardViewConfig)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
DividerType {}
|
DividerType {}
|
||||||
|
@ -84,6 +86,8 @@ PageType {
|
||||||
leftImageSource: "qrc:/images/controls/qr-code.svg"
|
leftImageSource: "qrc:/images/controls/qr-code.svg"
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
|
ImportController.extractConfigFromQr()
|
||||||
|
// goToPage(PageEnum.PageSetupWizardQrReader)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
52
client/ui/qml/Pages2/PageSetupWizardQrReader.qml
Normal file
52
client/ui/qml/Pages2/PageSetupWizardQrReader.qml
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Dialogs
|
||||||
|
|
||||||
|
import PageEnum 1.0
|
||||||
|
import QRCodeReader 1.0
|
||||||
|
|
||||||
|
import "./"
|
||||||
|
import "../Controls2"
|
||||||
|
import "../Controls2/TextTypes"
|
||||||
|
import "../Config"
|
||||||
|
|
||||||
|
PageType {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
BackButtonType {
|
||||||
|
Layout.topMargin: 20
|
||||||
|
}
|
||||||
|
|
||||||
|
ParagraphTextType {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
text: qsTr("Point the camera at the QR code and hold for a couple of seconds.")
|
||||||
|
}
|
||||||
|
|
||||||
|
ProgressBarType {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
QRCodeReader {
|
||||||
|
id: qrCodeReader
|
||||||
|
Component.onCompleted: {
|
||||||
|
qrCodeReader.setCameraSize(Qt.rect(parent.x,
|
||||||
|
parent.y,
|
||||||
|
parent.width,
|
||||||
|
parent.height))
|
||||||
|
qrCodeReader.startReading()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,6 +20,10 @@ PageType {
|
||||||
popupErrorMessage.popupErrorMessageText = errorMessage
|
popupErrorMessage.popupErrorMessageText = errorMessage
|
||||||
popupErrorMessage.open()
|
popupErrorMessage.open()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onGoToPageViewConfig() {
|
||||||
|
goToPage(PageEnum.PageSetupWizardViewConfig)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
|
|
|
@ -18,7 +18,7 @@ PageType {
|
||||||
|
|
||||||
enum ConfigType {
|
enum ConfigType {
|
||||||
AmneziaConnection,
|
AmneziaConnection,
|
||||||
AmenziaFullAccess,
|
AmneziaFullAccess,
|
||||||
OpenVpn,
|
OpenVpn,
|
||||||
WireGuard
|
WireGuard
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,14 @@ PageType {
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case PageShare.ConfigType.AmneziaConnection: ExportController.generateConnectionConfig(); break;
|
case PageShare.ConfigType.AmneziaConnection: ExportController.generateConnectionConfig(); break;
|
||||||
case PageShare.ConfigType.AmenziaFullAccess: ExportController.generateFullAccessConfig(); break;
|
case PageShare.ConfigType.AmneziaFullAccess: {
|
||||||
|
if (Qt.platform.os === "android") {
|
||||||
|
ExportController.generateFullAccessConfigAndroid();
|
||||||
|
} else {
|
||||||
|
ExportController.generateFullAccessConfig();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case PageShare.ConfigType.OpenVpn: ExportController.generateOpenVpnConfig(); break;
|
case PageShare.ConfigType.OpenVpn: ExportController.generateOpenVpnConfig(); break;
|
||||||
case PageShare.ConfigType.WireGuard: ExportController.generateWireGuardConfig(); break;
|
case PageShare.ConfigType.WireGuard: ExportController.generateWireGuardConfig(); break;
|
||||||
}
|
}
|
||||||
|
@ -48,6 +55,8 @@ PageType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
property string fullConfigServerSelectorText
|
||||||
|
property string connectionServerSelectorText
|
||||||
property bool showContent: false
|
property bool showContent: false
|
||||||
property bool shareButtonEnabled: false
|
property bool shareButtonEnabled: false
|
||||||
property list<QtObject> connectionTypesModel: [
|
property list<QtObject> connectionTypesModel: [
|
||||||
|
@ -118,6 +127,7 @@ PageType {
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
accessTypeSelector.currentIndex = 0
|
accessTypeSelector.currentIndex = 0
|
||||||
|
serverSelector.text = root.connectionServerSelectorText
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,6 +139,7 @@ PageType {
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
accessTypeSelector.currentIndex = 1
|
accessTypeSelector.currentIndex = 1
|
||||||
|
serverSelector.text = root.fullConfigServerSelectorText
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -176,14 +187,24 @@ PageType {
|
||||||
currentIndex: 0
|
currentIndex: 0
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
serverSelector.text = selectedText
|
handler()
|
||||||
ServersModel.currentlyProcessedIndex = currentIndex
|
|
||||||
|
if (accessTypeSelector.currentIndex === 0) {
|
||||||
protocolSelector.visible = true
|
protocolSelector.visible = true
|
||||||
root.shareButtonEnabled = false
|
root.shareButtonEnabled = false
|
||||||
|
} else {
|
||||||
|
serverSelector.menuVisible = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
|
handler()
|
||||||
|
}
|
||||||
|
|
||||||
|
function handler() {
|
||||||
serverSelector.text = selectedText
|
serverSelector.text = selectedText
|
||||||
|
root.fullConfigServerSelectorText = selectedText
|
||||||
|
root.connectionServerSelectorText = selectedText
|
||||||
ServersModel.currentlyProcessedIndex = currentIndex
|
ServersModel.currentlyProcessedIndex = currentIndex
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -260,8 +281,10 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
|
if (accessTypeSelector.currentIndex === 0) {
|
||||||
handler()
|
handler()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function handler() {
|
function handler() {
|
||||||
if (!proxyContainersModel.count) {
|
if (!proxyContainersModel.count) {
|
||||||
|
@ -272,6 +295,8 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
serverSelector.text += ", " + selectedText
|
serverSelector.text += ", " + selectedText
|
||||||
|
root.connectionServerSelectorText = serverSelector.text
|
||||||
|
|
||||||
shareConnectionDrawer.headerText = qsTr("Connection to ") + serverSelector.text
|
shareConnectionDrawer.headerText = qsTr("Connection to ") + serverSelector.text
|
||||||
shareConnectionDrawer.configContentHeaderText = qsTr("File with connection settings to ") + serverSelector.text
|
shareConnectionDrawer.configContentHeaderText = qsTr("File with connection settings to ") + serverSelector.text
|
||||||
ContainersModel.setCurrentlyProcessedContainerIndex(proxyContainersModel.mapToSource(currentIndex))
|
ContainersModel.setCurrentlyProcessedContainerIndex(proxyContainersModel.mapToSource(currentIndex))
|
||||||
|
|
|
@ -25,6 +25,11 @@ PageType {
|
||||||
tabBarStackView.goToTabBarPage(PageController.getPagePath(PageEnum.PageSettings))
|
tabBarStackView.goToTabBarPage(PageController.getPagePath(PageEnum.PageSettings))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onGoToPageViewConfig() {
|
||||||
|
var pagePath = PageController.getPagePath(PageEnum.PageSetupWizardViewConfig)
|
||||||
|
tabBarStackView.push(pagePath, { "objectName" : pagePath }, StackView.PushTransition)
|
||||||
|
}
|
||||||
|
|
||||||
function onShowErrorMessage(errorMessage) {
|
function onShowErrorMessage(errorMessage) {
|
||||||
popupErrorMessage.popupErrorMessageText = errorMessage
|
popupErrorMessage.popupErrorMessageText = errorMessage
|
||||||
popupErrorMessage.open()
|
popupErrorMessage.open()
|
||||||
|
@ -35,6 +40,13 @@ PageType {
|
||||||
tabBarStackView.enabled = !visible
|
tabBarStackView.enabled = !visible
|
||||||
tabBar.enabled = !visible
|
tabBar.enabled = !visible
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onClosePage() {
|
||||||
|
if (tabBarStackView.depth <= 1) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
tabBarStackView.pop()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StackViewType {
|
StackViewType {
|
||||||
|
|
|
@ -1,282 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
import QtQuick.Layouts
|
|
||||||
import PageEnum 1.0
|
|
||||||
|
|
||||||
import "./"
|
|
||||||
import "../Controls2"
|
|
||||||
import "../Config"
|
|
||||||
import "../Controls2/TextTypes"
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: content
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
|
|
||||||
HeaderType {
|
|
||||||
id: header
|
|
||||||
|
|
||||||
Layout.rightMargin: 16
|
|
||||||
Layout.leftMargin: 16
|
|
||||||
Layout.topMargin: 20
|
|
||||||
Layout.bottomMargin: 32
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
backButtonImage: "qrc:/images/controls/arrow-left.svg"
|
|
||||||
headerText: "Server 1"
|
|
||||||
descriptionText: "root 192.168.111.111"
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
TabBar {
|
|
||||||
id: tabBar
|
|
||||||
|
|
||||||
anchors {
|
|
||||||
top: parent.top
|
|
||||||
right: parent.right
|
|
||||||
left: parent.left
|
|
||||||
}
|
|
||||||
|
|
||||||
background: Rectangle {
|
|
||||||
color: "transparent"
|
|
||||||
}
|
|
||||||
|
|
||||||
TabButtonType {
|
|
||||||
id: bb
|
|
||||||
isSelected: tabBar.currentIndex === 0
|
|
||||||
text: qsTr("Протоколы")
|
|
||||||
}
|
|
||||||
TabButtonType {
|
|
||||||
isSelected: tabBar.currentIndex === 1
|
|
||||||
text: qsTr("Сервисы")
|
|
||||||
}
|
|
||||||
TabButtonType {
|
|
||||||
isSelected: tabBar.currentIndex === 2
|
|
||||||
text: qsTr("Данные")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StackLayout {
|
|
||||||
id: stackLayout
|
|
||||||
currentIndex: tabBar.currentIndex
|
|
||||||
|
|
||||||
anchors.top: tabBar.bottom
|
|
||||||
anchors.topMargin: 16
|
|
||||||
|
|
||||||
width: parent.width
|
|
||||||
height: root.height - header.implicitHeight - tabBar.implicitHeight - 100
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: protocolsTab
|
|
||||||
|
|
||||||
FlickableType {
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
contentHeight: protocolsTabContent.height
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: protocolsTabContent
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
|
|
||||||
BasicButtonType {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.leftMargin: 16
|
|
||||||
Layout.rightMargin: 16
|
|
||||||
text: qsTr("Forget this server")
|
|
||||||
}
|
|
||||||
|
|
||||||
BasicButtonType {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.leftMargin: 16
|
|
||||||
Layout.rightMargin: 16
|
|
||||||
|
|
||||||
defaultColor: "transparent"
|
|
||||||
hoveredColor: Qt.rgba(255, 255, 255, 0.08)
|
|
||||||
pressedColor: Qt.rgba(255, 255, 255, 0.12)
|
|
||||||
disabledColor: "#878B91"
|
|
||||||
textColor: "#D7D8DB"
|
|
||||||
borderWidth: 1
|
|
||||||
|
|
||||||
text: qsTr("Forget this server")
|
|
||||||
}
|
|
||||||
|
|
||||||
TextFieldWithHeaderType {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.leftMargin: 16
|
|
||||||
Layout.rightMargin: 16
|
|
||||||
headerText: "Server IP adress [:port]"
|
|
||||||
}
|
|
||||||
|
|
||||||
LabelWithButtonType {
|
|
||||||
id: ip
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.leftMargin: 16
|
|
||||||
Layout.rightMargin: 16
|
|
||||||
|
|
||||||
text: "IP, логин и пароль от сервера"
|
|
||||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.leftMargin: 16
|
|
||||||
Layout.rightMargin: 16
|
|
||||||
height: 1
|
|
||||||
color: "#2C2D30"
|
|
||||||
}
|
|
||||||
|
|
||||||
LabelWithButtonType {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.leftMargin: 16
|
|
||||||
Layout.rightMargin: 16
|
|
||||||
|
|
||||||
text: "QR-код, ключ или файл настроек"
|
|
||||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.leftMargin: 16
|
|
||||||
Layout.rightMargin: 16
|
|
||||||
height: 1
|
|
||||||
color: "#2C2D30"
|
|
||||||
}
|
|
||||||
|
|
||||||
CardType {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.leftMargin: 16
|
|
||||||
Layout.rightMargin: 16
|
|
||||||
|
|
||||||
headerText: "Высокий"
|
|
||||||
bodyText: "Многие иностранные сайты и VPN-провайдеры заблокированы"
|
|
||||||
footerText: "футер"
|
|
||||||
}
|
|
||||||
|
|
||||||
CardType {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.leftMargin: 16
|
|
||||||
Layout.rightMargin: 16
|
|
||||||
|
|
||||||
headerText: "Высокий"
|
|
||||||
bodyText: "Многие иностранные сайты и VPN-провайдеры заблокированы"
|
|
||||||
footerText: "футер"
|
|
||||||
}
|
|
||||||
|
|
||||||
DropDownType {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
text: "IP, логин и пароль от сервера"
|
|
||||||
descriptionText: "IP, логин и пароль от сервера"
|
|
||||||
|
|
||||||
menuModel: [
|
|
||||||
qsTr("SHA512"),
|
|
||||||
qsTr("SHA384"),
|
|
||||||
qsTr("SHA256"),
|
|
||||||
qsTr("SHA3-512"),
|
|
||||||
qsTr("SHA3-384"),
|
|
||||||
qsTr("SHA3-256"),
|
|
||||||
qsTr("whirlpool"),
|
|
||||||
qsTr("BLAKE2b512"),
|
|
||||||
qsTr("BLAKE2s256"),
|
|
||||||
qsTr("SHA1")
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: servicesTab
|
|
||||||
|
|
||||||
FlickableType {
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
contentHeight: servicesTabContent.height
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: servicesTabContent
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
|
|
||||||
CheckBoxType {
|
|
||||||
Layout.leftMargin: 16
|
|
||||||
Layout.rightMargin: 16
|
|
||||||
Layout.fillWidth: true
|
|
||||||
text: qsTr("Auto-negotiate encryption")
|
|
||||||
}
|
|
||||||
CheckBoxType {
|
|
||||||
Layout.leftMargin: 16
|
|
||||||
Layout.rightMargin: 16
|
|
||||||
Layout.fillWidth: true
|
|
||||||
text: qsTr("Auto-negotiate encryption")
|
|
||||||
descriptionText: qsTr("Auto-negotiate encryption")
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
implicitWidth: buttonGroup.implicitWidth
|
|
||||||
implicitHeight: buttonGroup.implicitHeight
|
|
||||||
|
|
||||||
Layout.leftMargin: 16
|
|
||||||
Layout.rightMargin: 16
|
|
||||||
|
|
||||||
color: "#1C1D21"
|
|
||||||
radius: 16
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
id: buttonGroup
|
|
||||||
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
HorizontalRadioButton {
|
|
||||||
implicitWidth: (root.width - 32) / 2
|
|
||||||
text: "UDP"
|
|
||||||
}
|
|
||||||
|
|
||||||
HorizontalRadioButton {
|
|
||||||
implicitWidth: (root.width - 32) / 2
|
|
||||||
text: "TCP"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VerticalRadioButton {
|
|
||||||
text: "Раздельное туннелирование"
|
|
||||||
descriptionText: "Позволяет подключаться к одним сайтам через защищенное соединение, а к другим в обход него"
|
|
||||||
checked: true
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.leftMargin: 16
|
|
||||||
Layout.rightMargin: 16
|
|
||||||
}
|
|
||||||
|
|
||||||
VerticalRadioButton {
|
|
||||||
text: "Раздельное туннелирование"
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.leftMargin: 16
|
|
||||||
Layout.rightMargin: 16
|
|
||||||
}
|
|
||||||
|
|
||||||
SwitcherType {
|
|
||||||
text: "Auto-negotiate encryption"
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.leftMargin: 16
|
|
||||||
Layout.rightMargin: 16
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -18,10 +18,9 @@ Window {
|
||||||
|
|
||||||
color: "#0E0E11"
|
color: "#0E0E11"
|
||||||
|
|
||||||
// todo
|
|
||||||
onClosing: function() {
|
onClosing: function() {
|
||||||
console.debug("QML onClosing signal")
|
console.debug("QML onClosing signal")
|
||||||
UiLogic.onCloseWindow()
|
PageController.closeWindow()
|
||||||
}
|
}
|
||||||
|
|
||||||
title: "AmneziaVPN"
|
title: "AmneziaVPN"
|
||||||
|
@ -36,6 +35,11 @@ Window {
|
||||||
var pagePath = PageController.getInitialPage()
|
var pagePath = PageController.getInitialPage()
|
||||||
rootStackView.push(pagePath, { "objectName" : pagePath })
|
rootStackView.push(pagePath, { "objectName" : pagePath })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Keys.onPressed: function(event) {
|
||||||
|
PageController.keyPressEvent(event.key)
|
||||||
|
event.accepted = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
|
@ -49,10 +53,14 @@ Window {
|
||||||
rootStackView.replace(pagePath, { "objectName" : pagePath })
|
rootStackView.replace(pagePath, { "objectName" : pagePath })
|
||||||
}
|
}
|
||||||
|
|
||||||
function onRaise() {
|
function onRaiseMainWindow() {
|
||||||
root.show()
|
root.show()
|
||||||
root.raise()
|
root.raise()
|
||||||
root.requestActivate()
|
root.requestActivate()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onHideMainWindow() {
|
||||||
|
root.hide()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,33 +10,33 @@
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QMetaEnum>
|
#include <QMetaEnum>
|
||||||
|
#include <QMetaObject>
|
||||||
|
#include <QQmlFile>
|
||||||
|
#include <QStandardPaths>
|
||||||
#include <QSysInfo>
|
#include <QSysInfo>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QQmlFile>
|
|
||||||
#include <QMetaObject>
|
|
||||||
#include <QStandardPaths>
|
|
||||||
|
|
||||||
#include "amnezia_application.h"
|
#include "amnezia_application.h"
|
||||||
|
|
||||||
#include "configurators/cloak_configurator.h"
|
#include "configurators/cloak_configurator.h"
|
||||||
#include "configurators/vpn_configurator.h"
|
|
||||||
#include "configurators/openvpn_configurator.h"
|
#include "configurators/openvpn_configurator.h"
|
||||||
#include "configurators/shadowsocks_configurator.h"
|
#include "configurators/shadowsocks_configurator.h"
|
||||||
#include "configurators/ssh_configurator.h"
|
#include "configurators/ssh_configurator.h"
|
||||||
|
#include "configurators/vpn_configurator.h"
|
||||||
|
|
||||||
#include "core/servercontroller.h"
|
|
||||||
#include "core/server_defs.h"
|
|
||||||
#include "core/errorstrings.h"
|
#include "core/errorstrings.h"
|
||||||
|
#include "core/server_defs.h"
|
||||||
|
#include "core/servercontroller.h"
|
||||||
|
|
||||||
#include "containers/containers_defs.h"
|
#include "containers/containers_defs.h"
|
||||||
|
|
||||||
#include "ui/qautostart.h"
|
#include "ui/qautostart.h"
|
||||||
|
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include "version.h"
|
|
||||||
#include "uilogic.h"
|
#include "uilogic.h"
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
|
#include "version.h"
|
||||||
#include "vpnconnection.h"
|
#include "vpnconnection.h"
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
|
@ -50,39 +50,36 @@
|
||||||
|
|
||||||
#include "platforms/ios/MobileUtils.h"
|
#include "platforms/ios/MobileUtils.h"
|
||||||
|
|
||||||
|
#include "pages_logic/AdvancedServerSettingsLogic.h"
|
||||||
#include "pages_logic/AppSettingsLogic.h"
|
#include "pages_logic/AppSettingsLogic.h"
|
||||||
|
#include "pages_logic/ClientInfoLogic.h"
|
||||||
|
#include "pages_logic/ClientManagementLogic.h"
|
||||||
#include "pages_logic/GeneralSettingsLogic.h"
|
#include "pages_logic/GeneralSettingsLogic.h"
|
||||||
#include "pages_logic/NetworkSettingsLogic.h"
|
#include "pages_logic/NetworkSettingsLogic.h"
|
||||||
#include "pages_logic/NewServerProtocolsLogic.h"
|
#include "pages_logic/NewServerProtocolsLogic.h"
|
||||||
#include "pages_logic/QrDecoderLogic.h"
|
#include "pages_logic/QrDecoderLogic.h"
|
||||||
#include "pages_logic/ServerConfiguringProgressLogic.h"
|
#include "pages_logic/ServerConfiguringProgressLogic.h"
|
||||||
|
#include "pages_logic/ServerContainersLogic.h"
|
||||||
#include "pages_logic/ServerListLogic.h"
|
#include "pages_logic/ServerListLogic.h"
|
||||||
#include "pages_logic/ServerSettingsLogic.h"
|
#include "pages_logic/ServerSettingsLogic.h"
|
||||||
#include "pages_logic/ServerContainersLogic.h"
|
|
||||||
#include "pages_logic/ShareConnectionLogic.h"
|
#include "pages_logic/ShareConnectionLogic.h"
|
||||||
#include "pages_logic/SitesLogic.h"
|
#include "pages_logic/SitesLogic.h"
|
||||||
#include "pages_logic/StartPageLogic.h"
|
#include "pages_logic/StartPageLogic.h"
|
||||||
#include "pages_logic/ViewConfigLogic.h"
|
#include "pages_logic/ViewConfigLogic.h"
|
||||||
#include "pages_logic/VpnLogic.h"
|
#include "pages_logic/VpnLogic.h"
|
||||||
#include "pages_logic/WizardLogic.h"
|
#include "pages_logic/WizardLogic.h"
|
||||||
#include "pages_logic/AdvancedServerSettingsLogic.h"
|
|
||||||
#include "pages_logic/ClientManagementLogic.h"
|
|
||||||
#include "pages_logic/ClientInfoLogic.h"
|
|
||||||
|
|
||||||
#include "pages_logic/protocols/CloakLogic.h"
|
#include "pages_logic/protocols/CloakLogic.h"
|
||||||
#include "pages_logic/protocols/OpenVpnLogic.h"
|
#include "pages_logic/protocols/OpenVpnLogic.h"
|
||||||
#include "pages_logic/protocols/ShadowSocksLogic.h"
|
|
||||||
#include "pages_logic/protocols/OtherProtocolsLogic.h"
|
#include "pages_logic/protocols/OtherProtocolsLogic.h"
|
||||||
|
#include "pages_logic/protocols/ShadowSocksLogic.h"
|
||||||
#include "pages_logic/protocols/WireGuardLogic.h"
|
#include "pages_logic/protocols/WireGuardLogic.h"
|
||||||
|
|
||||||
using namespace amnezia;
|
using namespace amnezia;
|
||||||
using namespace PageEnumNS;
|
using namespace PageEnumNS;
|
||||||
|
|
||||||
UiLogic::UiLogic(std::shared_ptr<Settings> settings, std::shared_ptr<VpnConfigurator> configurator,
|
UiLogic::UiLogic(std::shared_ptr<Settings> settings, std::shared_ptr<VpnConfigurator> configurator, QObject *parent)
|
||||||
QObject *parent) :
|
: QObject(parent), m_settings(settings), m_configurator(configurator)
|
||||||
QObject(parent),
|
|
||||||
m_settings(settings),
|
|
||||||
m_configurator(configurator)
|
|
||||||
{
|
{
|
||||||
m_protocolsModel = new ProtocolsModel(settings, this);
|
m_protocolsModel = new ProtocolsModel(settings, this);
|
||||||
m_clientManagementModel = new ClientManagementModel(this);
|
m_clientManagementModel = new ClientManagementModel(this);
|
||||||
|
@ -90,7 +87,6 @@ UiLogic::UiLogic(std::shared_ptr<Settings> settings, std::shared_ptr<VpnConfigur
|
||||||
m_vpnConnection->moveToThread(&m_vpnConnectionThread);
|
m_vpnConnection->moveToThread(&m_vpnConnectionThread);
|
||||||
m_vpnConnectionThread.start();
|
m_vpnConnectionThread.start();
|
||||||
|
|
||||||
|
|
||||||
m_protocolLogicMap.insert(Proto::OpenVpn, new OpenVpnLogic(this));
|
m_protocolLogicMap.insert(Proto::OpenVpn, new OpenVpnLogic(this));
|
||||||
m_protocolLogicMap.insert(Proto::ShadowSocks, new ShadowSocksLogic(this));
|
m_protocolLogicMap.insert(Proto::ShadowSocks, new ShadowSocksLogic(this));
|
||||||
m_protocolLogicMap.insert(Proto::Cloak, new CloakLogic(this));
|
m_protocolLogicMap.insert(Proto::Cloak, new CloakLogic(this));
|
||||||
|
@ -99,7 +95,6 @@ UiLogic::UiLogic(std::shared_ptr<Settings> settings, std::shared_ptr<VpnConfigur
|
||||||
m_protocolLogicMap.insert(Proto::Dns, new OtherProtocolsLogic(this));
|
m_protocolLogicMap.insert(Proto::Dns, new OtherProtocolsLogic(this));
|
||||||
m_protocolLogicMap.insert(Proto::Sftp, new OtherProtocolsLogic(this));
|
m_protocolLogicMap.insert(Proto::Sftp, new OtherProtocolsLogic(this));
|
||||||
m_protocolLogicMap.insert(Proto::TorWebSite, new OtherProtocolsLogic(this));
|
m_protocolLogicMap.insert(Proto::TorWebSite, new OtherProtocolsLogic(this));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UiLogic::~UiLogic()
|
UiLogic::~UiLogic()
|
||||||
|
@ -129,25 +124,29 @@ UiLogic::~UiLogic()
|
||||||
void UiLogic::initializeUiLogic()
|
void UiLogic::initializeUiLogic()
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
connect(AndroidController::instance(), &AndroidController::initialized, [this](bool status, bool connected, const QDateTime& connectionDate) {
|
connect(AndroidController::instance(), &AndroidController::initialized,
|
||||||
|
[this](bool status, bool connected, const QDateTime &connectionDate) {
|
||||||
if (connected) {
|
if (connected) {
|
||||||
pageLogic<VpnLogic>()->onConnectionStateChanged(Vpn::ConnectionState::Connected);
|
pageLogic<VpnLogic>()->onConnectionStateChanged(Vpn::ConnectionState::Connected);
|
||||||
if (m_vpnConnection) m_vpnConnection->restoreConnection();
|
if (m_vpnConnection)
|
||||||
|
m_vpnConnection->restoreConnection();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (!AndroidController::instance()->initialize(pageLogic<StartPageLogic>())) {
|
// if (!AndroidController::instance()->initialize(pageLogic<StartPageLogic>())) {
|
||||||
qCritical() << QString("Init failed");
|
// qCritical() << QString("Init failed");
|
||||||
if (m_vpnConnection) m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Error);
|
// if (m_vpnConnection) m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Error);
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_notificationHandler = NotificationHandler::create(qmlRoot());
|
m_notificationHandler = NotificationHandler::create(qmlRoot());
|
||||||
|
|
||||||
connect(m_vpnConnection, &VpnConnection::connectionStateChanged, m_notificationHandler, &NotificationHandler::setConnectionState);
|
connect(m_vpnConnection, &VpnConnection::connectionStateChanged, m_notificationHandler,
|
||||||
|
&NotificationHandler::setConnectionState);
|
||||||
connect(m_notificationHandler, &NotificationHandler::raiseRequested, this, &UiLogic::raise);
|
connect(m_notificationHandler, &NotificationHandler::raiseRequested, this, &UiLogic::raise);
|
||||||
connect(m_notificationHandler, &NotificationHandler::connectRequested, pageLogic<VpnLogic>(), &VpnLogic::onConnect);
|
connect(m_notificationHandler, &NotificationHandler::connectRequested, pageLogic<VpnLogic>(), &VpnLogic::onConnect);
|
||||||
connect(m_notificationHandler, &NotificationHandler::disconnectRequested, pageLogic<VpnLogic>(), &VpnLogic::onDisconnect);
|
connect(m_notificationHandler, &NotificationHandler::disconnectRequested, pageLogic<VpnLogic>(),
|
||||||
|
&VpnLogic::onDisconnect);
|
||||||
|
|
||||||
// if (m_settings->serversCount() > 0) {
|
// if (m_settings->serversCount() > 0) {
|
||||||
// if (m_settings->defaultServerIndex() < 0) m_settings->setDefaultServer(0);
|
// if (m_settings->defaultServerIndex() < 0) m_settings->setDefaultServer(0);
|
||||||
|
@ -167,8 +166,7 @@ void UiLogic::showOnStartup()
|
||||||
{
|
{
|
||||||
if (!m_settings->isStartMinimized()) {
|
if (!m_settings->isStartMinimized()) {
|
||||||
emit show();
|
emit show();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
emit hide();
|
emit hide();
|
||||||
#elif defined Q_OS_MACX
|
#elif defined Q_OS_MACX
|
||||||
|
@ -191,16 +189,11 @@ void UiLogic::keyPressEvent(Qt::Key key)
|
||||||
{
|
{
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case Qt::Key_AsciiTilde:
|
case Qt::Key_AsciiTilde:
|
||||||
case Qt::Key_QuoteLeft: emit toggleLogPanel();
|
case Qt::Key_QuoteLeft: emit toggleLogPanel(); break;
|
||||||
break;
|
case Qt::Key_L: Logger::openLogsFolder(); break;
|
||||||
case Qt::Key_L: Logger::openLogsFolder();
|
case Qt::Key_K: Logger::openServiceLogsFolder(); break;
|
||||||
break;
|
|
||||||
case Qt::Key_K: Logger::openServiceLogsFolder();
|
|
||||||
break;
|
|
||||||
#ifdef QT_DEBUG
|
#ifdef QT_DEBUG
|
||||||
case Qt::Key_Q:
|
case Qt::Key_Q: qApp->quit(); break;
|
||||||
qApp->quit();
|
|
||||||
break;
|
|
||||||
case Qt::Key_H:
|
case Qt::Key_H:
|
||||||
m_selectedServerIndex = m_settings->defaultServerIndex();
|
m_selectedServerIndex = m_settings->defaultServerIndex();
|
||||||
m_selectedDockerContainer = m_settings->defaultContainer(m_selectedServerIndex);
|
m_selectedDockerContainer = m_settings->defaultContainer(m_selectedServerIndex);
|
||||||
|
@ -210,25 +203,24 @@ void UiLogic::keyPressEvent(Qt::Key key)
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case Qt::Key_C:
|
case Qt::Key_C:
|
||||||
qDebug().noquote() << "Def server" << m_settings->defaultServerIndex() << m_settings->defaultContainerName(m_settings->defaultServerIndex());
|
qDebug().noquote() << "Def server" << m_settings->defaultServerIndex()
|
||||||
|
<< m_settings->defaultContainerName(m_settings->defaultServerIndex());
|
||||||
qDebug().noquote() << QJsonDocument(m_settings->defaultServer()).toJson();
|
qDebug().noquote() << QJsonDocument(m_settings->defaultServer()).toJson();
|
||||||
break;
|
break;
|
||||||
case Qt::Key_A:
|
case Qt::Key_A: emit goToPage(Page::Start); break;
|
||||||
emit goToPage(Page::Start);
|
|
||||||
break;
|
|
||||||
case Qt::Key_S:
|
case Qt::Key_S:
|
||||||
m_selectedServerIndex = m_settings->defaultServerIndex();
|
m_selectedServerIndex = m_settings->defaultServerIndex();
|
||||||
emit goToPage(Page::ServerSettings);
|
emit goToPage(Page::ServerSettings);
|
||||||
break;
|
break;
|
||||||
case Qt::Key_P:
|
case Qt::Key_P: onGotoCurrentProtocolsPage(); break;
|
||||||
onGotoCurrentProtocolsPage();
|
|
||||||
break;
|
|
||||||
case Qt::Key_T:
|
case Qt::Key_T:
|
||||||
m_configurator->sshConfigurator->openSshTerminal(m_settings->serverCredentials(m_settings->defaultServerIndex()));
|
m_configurator->sshConfigurator->openSshTerminal(m_settings->serverCredentials(m_settings->defaultServerIndex()));
|
||||||
break;
|
break;
|
||||||
case Qt::Key_Escape:
|
case Qt::Key_Escape:
|
||||||
if (currentPage() == Page::Vpn) break;
|
if (currentPage() == Page::Vpn)
|
||||||
if (currentPage() == Page::ServerConfiguringProgress) break;
|
break;
|
||||||
|
if (currentPage() == Page::ServerConfiguringProgress)
|
||||||
|
break;
|
||||||
case Qt::Key_Back:
|
case Qt::Key_Back:
|
||||||
|
|
||||||
// if (currentPage() == Page::Start && pagesStack.size() < 2) break;
|
// if (currentPage() == Page::Start && pagesStack.size() < 2) break;
|
||||||
|
@ -240,8 +232,7 @@ void UiLogic::keyPressEvent(Qt::Key key)
|
||||||
|
|
||||||
emit closePage();
|
emit closePage();
|
||||||
//}
|
//}
|
||||||
default:
|
default:;
|
||||||
;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,8 +241,7 @@ void UiLogic::onCloseWindow()
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
qApp->quit();
|
qApp->quit();
|
||||||
#else
|
#else
|
||||||
if (m_settings->serversCount() == 0)
|
if (m_settings->serversCount() == 0) {
|
||||||
{
|
|
||||||
qApp->quit();
|
qApp->quit();
|
||||||
} else {
|
} else {
|
||||||
emit hide();
|
emit hide();
|
||||||
|
@ -267,7 +257,6 @@ QString UiLogic::containerName(int container)
|
||||||
QString UiLogic::containerDesc(int container)
|
QString UiLogic::containerDesc(int container)
|
||||||
{
|
{
|
||||||
return ContainerProps::containerDescriptions().value(static_cast<DockerContainer>(container));
|
return ContainerProps::containerDescriptions().value(static_cast<DockerContainer>(container));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UiLogic::onGotoCurrentProtocolsPage()
|
void UiLogic::onGotoCurrentProtocolsPage()
|
||||||
|
@ -342,9 +331,8 @@ void UiLogic::installServer(QPair<DockerContainer, QJsonObject> &container)
|
||||||
ServerController serverController(m_settings);
|
ServerController serverController(m_settings);
|
||||||
return serverController.setupContainer(m_installCredentials, container.first, container.second);
|
return serverController.setupContainer(m_installCredentials, container.first, container.second);
|
||||||
};
|
};
|
||||||
errorCode = pageLogic<ServerConfiguringProgressLogic>()->doInstallAction(installAction, pageFunc, progressBarFunc,
|
errorCode = pageLogic<ServerConfiguringProgressLogic>()->doInstallAction(
|
||||||
noButton, waitInfoFunc,
|
installAction, pageFunc, progressBarFunc, noButton, waitInfoFunc, busyInfoFunc, cancelButtonFunc);
|
||||||
busyInfoFunc, cancelButtonFunc);
|
|
||||||
if (errorCode == ErrorCode::NoError) {
|
if (errorCode == ErrorCode::NoError) {
|
||||||
if (!isServerCreated) {
|
if (!isServerCreated) {
|
||||||
QJsonObject server;
|
QJsonObject server;
|
||||||
|
@ -371,22 +359,23 @@ void UiLogic::installServer(QPair<DockerContainer, QJsonObject> &container)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
onUpdateAllPages();
|
onUpdateAllPages();
|
||||||
emit showWarningMessage("Attention! The container you are trying to install is already installed on the server. "
|
emit showWarningMessage(
|
||||||
|
"Attention! The container you are trying to install is already installed on the server. "
|
||||||
"All installed containers have been added to the application ");
|
"All installed containers have been added to the application ");
|
||||||
emit setStartPage(Page::Vpn);
|
emit setStartPage(Page::Vpn);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
emit showWarningMessage(tr("Error occurred while configuring server.") + "\n" +
|
emit showWarningMessage(tr("Error occurred while configuring server.") + "\n" + tr("Error message: ")
|
||||||
tr("Error message: ") + errorString(errorCode) + "\n" +
|
+ errorString(errorCode) + "\n" + tr("See logs for details."));
|
||||||
tr("See logs for details."));
|
|
||||||
emit closePage();
|
emit closePage();
|
||||||
}
|
}
|
||||||
|
|
||||||
PageProtocolLogicBase *UiLogic::protocolLogic(Proto p)
|
PageProtocolLogicBase *UiLogic::protocolLogic(Proto p)
|
||||||
{
|
{
|
||||||
PageProtocolLogicBase *logic = m_protocolLogicMap.value(p);
|
PageProtocolLogicBase *logic = m_protocolLogicMap.value(p);
|
||||||
if (logic) return logic;
|
if (logic)
|
||||||
|
return logic;
|
||||||
else {
|
else {
|
||||||
qCritical() << "UiLogic::protocolLogic Warning: logic missing for" << p;
|
qCritical() << "UiLogic::protocolLogic Warning: logic missing for" << p;
|
||||||
return new PageProtocolLogicBase(this);
|
return new PageProtocolLogicBase(this);
|
||||||
|
@ -429,17 +418,19 @@ void UiLogic::saveTextFile(const QString& desc, const QString& suggestedName, QS
|
||||||
QString docDir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
|
QString docDir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
|
||||||
QUrl fileName;
|
QUrl fileName;
|
||||||
#ifdef AMNEZIA_DESKTOP
|
#ifdef AMNEZIA_DESKTOP
|
||||||
fileName = QFileDialog::getSaveFileUrl(nullptr, desc,
|
fileName = QFileDialog::getSaveFileUrl(nullptr, desc, QUrl::fromLocalFile(docDir + "/" + suggestedName), "*" + ext);
|
||||||
QUrl::fromLocalFile(docDir + "/" + suggestedName), "*" + ext);
|
if (fileName.isEmpty())
|
||||||
if (fileName.isEmpty()) return;
|
return;
|
||||||
if (!fileName.toString().endsWith(ext)) fileName = QUrl(fileName.toString() + ext);
|
if (!fileName.toString().endsWith(ext))
|
||||||
|
fileName = QUrl(fileName.toString() + ext);
|
||||||
#elif defined Q_OS_ANDROID
|
#elif defined Q_OS_ANDROID
|
||||||
qDebug() << "UiLogic::shareConfig" << data;
|
qDebug() << "UiLogic::shareConfig" << data;
|
||||||
AndroidController::instance()->shareConfig(data, suggestedName);
|
AndroidController::instance()->shareConfig(data, suggestedName);
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (fileName.isEmpty()) return;
|
if (fileName.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
#ifdef AMNEZIA_DESKTOP
|
#ifdef AMNEZIA_DESKTOP
|
||||||
QFile save(fileName.toLocalFile());
|
QFile save(fileName.toLocalFile());
|
||||||
|
@ -458,11 +449,13 @@ void UiLogic::saveTextFile(const QString& desc, const QString& suggestedName, QS
|
||||||
void UiLogic::saveBinaryFile(const QString &desc, QString ext, const QString &data)
|
void UiLogic::saveBinaryFile(const QString &desc, QString ext, const QString &data)
|
||||||
{
|
{
|
||||||
ext.replace("*", "");
|
ext.replace("*", "");
|
||||||
QString fileName = QFileDialog::getSaveFileName(nullptr, desc,
|
QString fileName = QFileDialog::getSaveFileName(
|
||||||
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation), "*" + ext);
|
nullptr, desc, QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation), "*" + ext);
|
||||||
|
|
||||||
if (fileName.isEmpty()) return;
|
if (fileName.isEmpty())
|
||||||
if (!fileName.endsWith(ext)) fileName.append(ext);
|
return;
|
||||||
|
if (!fileName.endsWith(ext))
|
||||||
|
fileName.append(ext);
|
||||||
|
|
||||||
QFile save(fileName);
|
QFile save(fileName);
|
||||||
save.open(QIODevice::WriteOnly);
|
save.open(QIODevice::WriteOnly);
|
||||||
|
@ -478,12 +471,15 @@ void UiLogic::copyToClipboard(const QString &text)
|
||||||
qApp->clipboard()->setText(text);
|
qApp->clipboard()->setText(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UiLogic::shareTempFile(const QString &suggestedName, QString ext, const QString& data) {
|
void UiLogic::shareTempFile(const QString &suggestedName, QString ext, const QString &data)
|
||||||
|
{
|
||||||
ext.replace("*", "");
|
ext.replace("*", "");
|
||||||
QString fileName = QDir::tempPath() + "/" + suggestedName;
|
QString fileName = QDir::tempPath() + "/" + suggestedName;
|
||||||
|
|
||||||
if (fileName.isEmpty()) return;
|
if (fileName.isEmpty())
|
||||||
if (!fileName.endsWith(ext)) fileName.append(ext);
|
return;
|
||||||
|
if (!fileName.endsWith(ext))
|
||||||
|
fileName.append(ext);
|
||||||
|
|
||||||
QFile::remove(fileName);
|
QFile::remove(fileName);
|
||||||
|
|
||||||
|
@ -497,8 +493,8 @@ void UiLogic::shareTempFile(const QString &suggestedName, QString ext, const QSt
|
||||||
MobileUtils::shareText(filesToSend);
|
MobileUtils::shareText(filesToSend);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString UiLogic::getOpenFileName(QWidget *parent, const QString &caption, const QString &dir,
|
QString UiLogic::getOpenFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter,
|
||||||
const QString &filter, QString *selectedFilter, QFileDialog::Options options)
|
QString *selectedFilter, QFileDialog::Options options)
|
||||||
{
|
{
|
||||||
QString fileName = QFileDialog::getOpenFileName(parent, caption, dir, filter, selectedFilter, options);
|
QString fileName = QFileDialog::getOpenFileName(parent, caption, dir, filter, selectedFilter, options);
|
||||||
|
|
||||||
|
@ -590,7 +586,8 @@ ErrorCode UiLogic::addAlreadyInstalledContainersGui(bool &isServerCreated)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (createNewServer) {
|
if (createNewServer) {
|
||||||
server.insert(config_key::defaultContainer, ContainerProps::containerToString(installedContainers.firstKey()));
|
server.insert(config_key::defaultContainer,
|
||||||
|
ContainerProps::containerToString(installedContainers.firstKey()));
|
||||||
m_settings->addServer(server);
|
m_settings->addServer(server);
|
||||||
m_settings->setDefaultServer(m_settings->serversCount() - 1);
|
m_settings->setDefaultServer(m_settings->serversCount() - 1);
|
||||||
isServerCreated = true;
|
isServerCreated = true;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue