removed old ui files
This commit is contained in:
parent
8cf8c3c122
commit
4baa003c0d
140 changed files with 285 additions and 12695 deletions
|
|
@ -95,7 +95,6 @@ set(HEADERS ${HEADERS}
|
||||||
${CMAKE_CURRENT_LIST_DIR}/ui/notificationhandler.h
|
${CMAKE_CURRENT_LIST_DIR}/ui/notificationhandler.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/ui/pages.h
|
${CMAKE_CURRENT_LIST_DIR}/ui/pages.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/ui/property_helper.h
|
${CMAKE_CURRENT_LIST_DIR}/ui/property_helper.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/ui/uilogic.h
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/ui/qautostart.h
|
${CMAKE_CURRENT_LIST_DIR}/ui/qautostart.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/vpnprotocol.h
|
${CMAKE_CURRENT_LIST_DIR}/protocols/vpnprotocol.h
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/version.h
|
${CMAKE_CURRENT_BINARY_DIR}/version.h
|
||||||
|
|
@ -132,7 +131,6 @@ set(SOURCES ${SOURCES}
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/servercontroller.cpp
|
${CMAKE_CURRENT_LIST_DIR}/core/servercontroller.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/protocols_defs.cpp
|
${CMAKE_CURRENT_LIST_DIR}/protocols/protocols_defs.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/ui/notificationhandler.cpp
|
${CMAKE_CURRENT_LIST_DIR}/ui/notificationhandler.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/ui/uilogic.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/ui/qautostart.cpp
|
${CMAKE_CURRENT_LIST_DIR}/ui/qautostart.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/vpnprotocol.cpp
|
${CMAKE_CURRENT_LIST_DIR}/protocols/vpnprotocol.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/core/sshclient.cpp
|
${CMAKE_CURRENT_LIST_DIR}/core/sshclient.cpp
|
||||||
|
|
|
||||||
|
|
@ -156,7 +156,7 @@ void AmneziaApplication::init()
|
||||||
// Android TextField clipboard workaround
|
// Android TextField clipboard workaround
|
||||||
// https://bugreports.qt.io/browse/QTBUG-113461
|
// https://bugreports.qt.io/browse/QTBUG-113461
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
QObject::connect(qApp, &QApplication::applicationStateChanged, [](Qt::ApplicationState state) {
|
QObject::connect(qApp, &QGuiApplication::applicationStateChanged, [](Qt::ApplicationState state) {
|
||||||
if (state == Qt::ApplicationActive) {
|
if (state == Qt::ApplicationActive) {
|
||||||
if (qApp->clipboard()->mimeData()->formats().contains("text/html")) {
|
if (qApp->clipboard()->mimeData()->formats().contains("text/html")) {
|
||||||
QTextDocument doc;
|
QTextDocument doc;
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@
|
||||||
#define amnApp (static_cast<AmneziaApplication *>(QCoreApplication::instance()))
|
#define amnApp (static_cast<AmneziaApplication *>(QCoreApplication::instance()))
|
||||||
|
|
||||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
||||||
#define AMNEZIA_BASE_CLASS QGuiApp
|
#define AMNEZIA_BASE_CLASS QGuiApplication
|
||||||
#else
|
#else
|
||||||
#define AMNEZIA_BASE_CLASS SingleApplication
|
#define AMNEZIA_BASE_CLASS SingleApplication
|
||||||
#define QAPPLICATION_CLASS QApplication
|
#define QAPPLICATION_CLASS QApplication
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,22 @@
|
||||||
#include "ikev2_configurator.h"
|
#include "ikev2_configurator.h"
|
||||||
#include <QApplication>
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QJsonDocument>
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QTemporaryDir>
|
#include <QTemporaryDir>
|
||||||
#include <QDebug>
|
|
||||||
#include <QTemporaryFile>
|
#include <QTemporaryFile>
|
||||||
#include <QJsonDocument>
|
|
||||||
#include <QUuid>
|
#include <QUuid>
|
||||||
|
|
||||||
#include "containers/containers_defs.h"
|
#include "containers/containers_defs.h"
|
||||||
#include "core/server_defs.h"
|
|
||||||
#include "core/scripts_registry.h"
|
#include "core/scripts_registry.h"
|
||||||
#include "utilities.h"
|
#include "core/server_defs.h"
|
||||||
#include "core/servercontroller.h"
|
#include "core/servercontroller.h"
|
||||||
|
#include "utilities.h"
|
||||||
|
|
||||||
|
Ikev2Configurator::Ikev2Configurator(std::shared_ptr<Settings> settings, QObject *parent)
|
||||||
Ikev2Configurator::Ikev2Configurator(std::shared_ptr<Settings> settings, QObject *parent):
|
: ConfiguratorBase(settings, parent)
|
||||||
ConfiguratorBase(settings, parent)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ikev2Configurator::ConnectionData Ikev2Configurator::prepareIkev2Config(const ServerCredentials &credentials,
|
Ikev2Configurator::ConnectionData Ikev2Configurator::prepareIkev2Config(const ServerCredentials &credentials,
|
||||||
|
|
@ -32,12 +30,12 @@ Ikev2Configurator::ConnectionData Ikev2Configurator::prepareIkev2Config(const Se
|
||||||
|
|
||||||
QString certFileName = "/opt/amnezia/ikev2/clients/" + connData.clientId + ".p12";
|
QString certFileName = "/opt/amnezia/ikev2/clients/" + connData.clientId + ".p12";
|
||||||
|
|
||||||
QString scriptCreateCert = QString("certutil -z <(head -c 1024 /dev/urandom) "\
|
QString scriptCreateCert = QString("certutil -z <(head -c 1024 /dev/urandom) "
|
||||||
"-S -c \"IKEv2 VPN CA\" -n \"%1\" "\
|
"-S -c \"IKEv2 VPN CA\" -n \"%1\" "
|
||||||
"-s \"O=IKEv2 VPN,CN=%1\" "\
|
"-s \"O=IKEv2 VPN,CN=%1\" "
|
||||||
"-k rsa -g 3072 -v 120 "\
|
"-k rsa -g 3072 -v 120 "
|
||||||
"-d sql:/etc/ipsec.d -t \",,\" "\
|
"-d sql:/etc/ipsec.d -t \",,\" "
|
||||||
"--keyUsage digitalSignature,keyEncipherment "\
|
"--keyUsage digitalSignature,keyEncipherment "
|
||||||
"--extKeyUsage serverAuth,clientAuth -8 \"%1\"")
|
"--extKeyUsage serverAuth,clientAuth -8 \"%1\"")
|
||||||
.arg(connData.clientId);
|
.arg(connData.clientId);
|
||||||
|
|
||||||
|
|
@ -51,7 +49,8 @@ Ikev2Configurator::ConnectionData Ikev2Configurator::prepareIkev2Config(const Se
|
||||||
e = serverController.runContainerScript(credentials, container, scriptExportCert);
|
e = serverController.runContainerScript(credentials, container, scriptExportCert);
|
||||||
|
|
||||||
connData.clientCert = serverController.getTextFileFromContainer(container, credentials, certFileName, &e);
|
connData.clientCert = serverController.getTextFileFromContainer(container, credentials, certFileName, &e);
|
||||||
connData.caCert = serverController.getTextFileFromContainer(container, credentials, "/etc/ipsec.d/ca_cert_base64.p12", &e);
|
connData.caCert =
|
||||||
|
serverController.getTextFileFromContainer(container, credentials, "/etc/ipsec.d/ca_cert_base64.p12", &e);
|
||||||
|
|
||||||
qDebug() << "Ikev2Configurator::ConnectionData client cert size:" << connData.clientCert.size();
|
qDebug() << "Ikev2Configurator::ConnectionData client cert size:" << connData.clientCert.size();
|
||||||
qDebug() << "Ikev2Configurator::ConnectionData ca cert size:" << connData.caCert.size();
|
qDebug() << "Ikev2Configurator::ConnectionData ca cert size:" << connData.caCert.size();
|
||||||
|
|
@ -59,8 +58,8 @@ Ikev2Configurator::ConnectionData Ikev2Configurator::prepareIkev2Config(const Se
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Ikev2Configurator::genIkev2Config(const ServerCredentials &credentials,
|
QString Ikev2Configurator::genIkev2Config(const ServerCredentials &credentials, DockerContainer container,
|
||||||
DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode)
|
const QJsonObject &containerConfig, ErrorCode *errorCode)
|
||||||
{
|
{
|
||||||
Q_UNUSED(containerConfig)
|
Q_UNUSED(containerConfig)
|
||||||
|
|
||||||
|
|
@ -120,4 +119,3 @@ QString Ikev2Configurator::genStrongSwanConfig(const ConnectionData &connData)
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,81 +1,88 @@
|
||||||
#include "openvpn_configurator.h"
|
#include "openvpn_configurator.h"
|
||||||
#include <QApplication>
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonObject>
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QTemporaryDir>
|
#include <QTemporaryDir>
|
||||||
#include <QDebug>
|
|
||||||
#include <QTemporaryFile>
|
#include <QTemporaryFile>
|
||||||
#include <QJsonObject>
|
|
||||||
#include <QJsonDocument>
|
|
||||||
|
|
||||||
#include "containers/containers_defs.h"
|
#include "containers/containers_defs.h"
|
||||||
|
#include "core/scripts_registry.h"
|
||||||
#include "core/server_defs.h"
|
#include "core/server_defs.h"
|
||||||
#include "core/servercontroller.h"
|
#include "core/servercontroller.h"
|
||||||
#include "core/scripts_registry.h"
|
|
||||||
#include "utilities.h"
|
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
#include "utilities.h"
|
||||||
|
|
||||||
|
#include <openssl/pem.h>
|
||||||
#include <openssl/rsa.h>
|
#include <openssl/rsa.h>
|
||||||
#include <openssl/x509.h>
|
#include <openssl/x509.h>
|
||||||
#include <openssl/pem.h>
|
|
||||||
|
|
||||||
OpenVpnConfigurator::OpenVpnConfigurator(std::shared_ptr<Settings> settings, QObject *parent):
|
OpenVpnConfigurator::OpenVpnConfigurator(std::shared_ptr<Settings> settings, QObject *parent)
|
||||||
ConfiguratorBase(settings, parent)
|
: ConfiguratorBase(settings, parent)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::prepareOpenVpnConfig(const ServerCredentials &credentials,
|
OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::prepareOpenVpnConfig(const ServerCredentials &credentials,
|
||||||
DockerContainer container, ErrorCode *errorCode)
|
DockerContainer container,
|
||||||
|
ErrorCode *errorCode)
|
||||||
{
|
{
|
||||||
OpenVpnConfigurator::ConnectionData connData = OpenVpnConfigurator::createCertRequest();
|
OpenVpnConfigurator::ConnectionData connData = OpenVpnConfigurator::createCertRequest();
|
||||||
connData.host = credentials.hostName;
|
connData.host = credentials.hostName;
|
||||||
|
|
||||||
if (connData.privKey.isEmpty() || connData.request.isEmpty()) {
|
if (connData.privKey.isEmpty() || connData.request.isEmpty()) {
|
||||||
if (errorCode) *errorCode = ErrorCode::OpenSslFailed;
|
if (errorCode)
|
||||||
|
*errorCode = ErrorCode::OpenSslFailed;
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString reqFileName = QString("%1/%2.req").
|
QString reqFileName = QString("%1/%2.req").arg(amnezia::protocols::openvpn::clientsDirPath).arg(connData.clientId);
|
||||||
arg(amnezia::protocols::openvpn::clientsDirPath).
|
|
||||||
arg(connData.clientId);
|
|
||||||
|
|
||||||
ServerController serverController(m_settings);
|
ServerController serverController(m_settings);
|
||||||
ErrorCode e = serverController.uploadTextFileToContainer(container, credentials, connData.request, reqFileName);
|
ErrorCode e = serverController.uploadTextFileToContainer(container, credentials, connData.request, reqFileName);
|
||||||
if (e) {
|
if (e) {
|
||||||
if (errorCode) *errorCode = e;
|
if (errorCode)
|
||||||
|
*errorCode = e;
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
e = signCert(container, credentials, connData.clientId);
|
e = signCert(container, credentials, connData.clientId);
|
||||||
if (e) {
|
if (e) {
|
||||||
if (errorCode) *errorCode = e;
|
if (errorCode)
|
||||||
|
*errorCode = e;
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
connData.caCert = serverController.getTextFileFromContainer(container, credentials, amnezia::protocols::openvpn::caCertPath, &e);
|
connData.caCert = serverController.getTextFileFromContainer(container, credentials,
|
||||||
connData.clientCert = serverController.getTextFileFromContainer(container, credentials,
|
amnezia::protocols::openvpn::caCertPath, &e);
|
||||||
|
connData.clientCert = serverController.getTextFileFromContainer(
|
||||||
|
container, credentials,
|
||||||
QString("%1/%2.crt").arg(amnezia::protocols::openvpn::clientCertPath).arg(connData.clientId), &e);
|
QString("%1/%2.crt").arg(amnezia::protocols::openvpn::clientCertPath).arg(connData.clientId), &e);
|
||||||
|
|
||||||
if (e) {
|
if (e) {
|
||||||
if (errorCode) *errorCode = e;
|
if (errorCode)
|
||||||
|
*errorCode = e;
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
connData.taKey = serverController.getTextFileFromContainer(container, credentials, amnezia::protocols::openvpn::taKeyPath, &e);
|
connData.taKey = serverController.getTextFileFromContainer(container, credentials,
|
||||||
|
amnezia::protocols::openvpn::taKeyPath, &e);
|
||||||
|
|
||||||
if (connData.caCert.isEmpty() || connData.clientCert.isEmpty() || connData.taKey.isEmpty()) {
|
if (connData.caCert.isEmpty() || connData.clientCert.isEmpty() || connData.taKey.isEmpty()) {
|
||||||
if (errorCode) *errorCode = ErrorCode::SshSftpFailureError;
|
if (errorCode)
|
||||||
|
*errorCode = ErrorCode::SshSftpFailureError;
|
||||||
}
|
}
|
||||||
|
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString OpenVpnConfigurator::genOpenVpnConfig(const ServerCredentials &credentials,
|
QString OpenVpnConfigurator::genOpenVpnConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode)
|
const QJsonObject &containerConfig, ErrorCode *errorCode)
|
||||||
{
|
{
|
||||||
ServerController serverController(m_settings);
|
ServerController serverController(m_settings);
|
||||||
QString config = serverController.replaceVars(amnezia::scriptData(ProtocolScriptType::openvpn_template, container),
|
QString config =
|
||||||
|
serverController.replaceVars(amnezia::scriptData(ProtocolScriptType::openvpn_template, container),
|
||||||
serverController.genVarsForScript(credentials, container, containerConfig));
|
serverController.genVarsForScript(credentials, container, containerConfig));
|
||||||
|
|
||||||
ConnectionData connData = prepareOpenVpnConfig(credentials, container, errorCode);
|
ConnectionData connData = prepareOpenVpnConfig(credentials, container, errorCode);
|
||||||
|
|
@ -89,8 +96,7 @@ QString OpenVpnConfigurator::genOpenVpnConfig(const ServerCredentials &credentia
|
||||||
|
|
||||||
if (config.contains("$OPENVPN_TA_KEY")) {
|
if (config.contains("$OPENVPN_TA_KEY")) {
|
||||||
config.replace("$OPENVPN_TA_KEY", connData.taKey);
|
config.replace("$OPENVPN_TA_KEY", connData.taKey);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
config.replace("<tls-auth>", "");
|
config.replace("<tls-auth>", "");
|
||||||
config.replace("</tls-auth>", "");
|
config.replace("</tls-auth>", "");
|
||||||
}
|
}
|
||||||
|
|
@ -134,11 +140,10 @@ QString OpenVpnConfigurator::processConfigWithLocalSettings(QString jsonConfig)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (defined(MZ_MACOS) || defined(MZ_LINUX))
|
#if (defined(MZ_MACOS) || defined(MZ_LINUX))
|
||||||
QString dnsConf = QString(
|
QString dnsConf = QString("\nscript-security 2\n"
|
||||||
"\nscript-security 2\n"
|
|
||||||
"up %1/update-resolv-conf.sh\n"
|
"up %1/update-resolv-conf.sh\n"
|
||||||
"down %1/update-resolv-conf.sh\n").
|
"down %1/update-resolv-conf.sh\n")
|
||||||
arg(qApp->applicationDirPath());
|
.arg(qApp->applicationDirPath());
|
||||||
|
|
||||||
config.append(dnsConf);
|
config.append(dnsConf);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -168,8 +173,7 @@ QString OpenVpnConfigurator::processConfigWithExportSettings(QString jsonConfig)
|
||||||
return QJsonDocument(json).toJson();
|
return QJsonDocument(json).toJson();
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode OpenVpnConfigurator::signCert(DockerContainer container,
|
ErrorCode OpenVpnConfigurator::signCert(DockerContainer container, const ServerCredentials &credentials, QString clientId)
|
||||||
const ServerCredentials &credentials, QString clientId)
|
|
||||||
{
|
{
|
||||||
QString script_import = QString("sudo docker exec -i %1 bash -c \"cd /opt/amnezia/openvpn && "
|
QString script_import = QString("sudo docker exec -i %1 bash -c \"cd /opt/amnezia/openvpn && "
|
||||||
"easyrsa import-req %2/%3.req %3\"")
|
"easyrsa import-req %2/%3.req %3\"")
|
||||||
|
|
@ -184,7 +188,8 @@ ErrorCode OpenVpnConfigurator::signCert(DockerContainer container,
|
||||||
|
|
||||||
ServerController serverController(m_settings);
|
ServerController serverController(m_settings);
|
||||||
QStringList scriptList { script_import, script_sign };
|
QStringList scriptList { script_import, script_sign };
|
||||||
QString script = serverController.replaceVars(scriptList.join("\n"), serverController.genVarsForScript(credentials, container));
|
QString script = serverController.replaceVars(scriptList.join("\n"),
|
||||||
|
serverController.genVarsForScript(credentials, container));
|
||||||
|
|
||||||
return serverController.runScript(credentials, script);
|
return serverController.runScript(credentials, script);
|
||||||
}
|
}
|
||||||
|
|
@ -205,7 +210,6 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::createCertRequest()
|
||||||
q_check_ptr(rsa);
|
q_check_ptr(rsa);
|
||||||
EVP_PKEY_assign_RSA(pKey, rsa);
|
EVP_PKEY_assign_RSA(pKey, rsa);
|
||||||
|
|
||||||
|
|
||||||
// 2. set version of x509 req
|
// 2. set version of x509 req
|
||||||
X509_REQ *x509_req = X509_REQ_new();
|
X509_REQ *x509_req = X509_REQ_new();
|
||||||
ret = X509_REQ_set_version(x509_req, nVersion);
|
ret = X509_REQ_set_version(x509_req, nVersion);
|
||||||
|
|
@ -219,10 +223,8 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::createCertRequest()
|
||||||
// 3. set subject of x509 req
|
// 3. set subject of x509 req
|
||||||
X509_NAME *x509_name = X509_REQ_get_subject_name(x509_req);
|
X509_NAME *x509_name = X509_REQ_get_subject_name(x509_req);
|
||||||
|
|
||||||
X509_NAME_add_entry_by_txt(x509_name, "C", MBSTRING_ASC,
|
X509_NAME_add_entry_by_txt(x509_name, "C", MBSTRING_ASC, (unsigned char *)"ORG", -1, -1, 0);
|
||||||
(unsigned char *)"ORG", -1, -1, 0);
|
X509_NAME_add_entry_by_txt(x509_name, "O", MBSTRING_ASC, (unsigned char *)"", -1, -1, 0);
|
||||||
X509_NAME_add_entry_by_txt(x509_name, "O", MBSTRING_ASC,
|
|
||||||
(unsigned char *)"", -1, -1, 0);
|
|
||||||
X509_NAME_add_entry_by_txt(x509_name, "CN", MBSTRING_ASC,
|
X509_NAME_add_entry_by_txt(x509_name, "CN", MBSTRING_ASC,
|
||||||
reinterpret_cast<unsigned char const *>(clientIdUtf8.data()), clientIdUtf8.size(), -1, 0);
|
reinterpret_cast<unsigned char const *>(clientIdUtf8.data()), clientIdUtf8.size(), -1, 0);
|
||||||
|
|
||||||
|
|
@ -247,8 +249,7 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::createCertRequest()
|
||||||
// save private key
|
// save private key
|
||||||
BIO *bp_private = BIO_new(BIO_s_mem());
|
BIO *bp_private = BIO_new(BIO_s_mem());
|
||||||
q_check_ptr(bp_private);
|
q_check_ptr(bp_private);
|
||||||
if (PEM_write_bio_PrivateKey(bp_private, pKey, nullptr, nullptr, 0, nullptr, nullptr) != 1)
|
if (PEM_write_bio_PrivateKey(bp_private, pKey, nullptr, nullptr, 0, nullptr, nullptr) != 1) {
|
||||||
{
|
|
||||||
qFatal("PEM_write_bio_PrivateKey");
|
qFatal("PEM_write_bio_PrivateKey");
|
||||||
EVP_PKEY_free(pKey);
|
EVP_PKEY_free(pKey);
|
||||||
BIO_free_all(bp_private);
|
BIO_free_all(bp_private);
|
||||||
|
|
@ -278,7 +279,6 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::createCertRequest()
|
||||||
connData.request = QByteArray(bio_buf->data, bio_buf->length);
|
connData.request = QByteArray(bio_buf->data, bio_buf->length);
|
||||||
BIO_free(bio_req);
|
BIO_free(bio_req);
|
||||||
|
|
||||||
|
|
||||||
EVP_PKEY_free(pKey); // this will also free the rsa key
|
EVP_PKEY_free(pKey); // this will also free the rsa key
|
||||||
|
|
||||||
return connData;
|
return connData;
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,25 @@
|
||||||
#include "ssh_configurator.h"
|
#include "ssh_configurator.h"
|
||||||
#include <QApplication>
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QObject>
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QTemporaryDir>
|
#include <QTemporaryDir>
|
||||||
#include <QDebug>
|
|
||||||
#include <QTemporaryFile>
|
#include <QTemporaryFile>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <QObject>
|
|
||||||
#include <QTextEdit>
|
|
||||||
#include <QPlainTextEdit>
|
|
||||||
#include <qtimer.h>
|
#include <qtimer.h>
|
||||||
|
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
||||||
|
#include <QGuiApplication>
|
||||||
|
#else
|
||||||
|
#include <QApplication>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "core/server_defs.h"
|
#include "core/server_defs.h"
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
|
|
||||||
|
SshConfigurator::SshConfigurator(std::shared_ptr<Settings> settings, QObject *parent)
|
||||||
SshConfigurator::SshConfigurator(std::shared_ptr<Settings> settings, QObject *parent):
|
: ConfiguratorBase(settings, parent)
|
||||||
ConfiguratorBase(settings, parent)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString SshConfigurator::convertOpenSShKey(const QString &key)
|
QString SshConfigurator::convertOpenSShKey(const QString &key)
|
||||||
|
|
@ -43,7 +44,14 @@ QString SshConfigurator::convertOpenSShKey(const QString &key)
|
||||||
p.setNativeArguments(QString("/C \"ssh-keygen.exe -p -P \"\" -N \"\" -m pem -f \"%1\"\"").arg(tmp.fileName()));
|
p.setNativeArguments(QString("/C \"ssh-keygen.exe -p -P \"\" -N \"\" -m pem -f \"%1\"\"").arg(tmp.fileName()));
|
||||||
#else
|
#else
|
||||||
p.setProgram("ssh-keygen");
|
p.setProgram("ssh-keygen");
|
||||||
p.setArguments(QStringList() << "-p" << "-P" << "" << "-N" << "" << "-m" << "pem" << "-f" << tmp.fileName());
|
p.setArguments(QStringList() << "-p"
|
||||||
|
<< "-P"
|
||||||
|
<< ""
|
||||||
|
<< "-N"
|
||||||
|
<< ""
|
||||||
|
<< "-m"
|
||||||
|
<< "pem"
|
||||||
|
<< "-f" << tmp.fileName());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
p.start();
|
p.start();
|
||||||
|
|
@ -73,10 +81,9 @@ void SshConfigurator::openSshTerminal(const ServerCredentials &credentials)
|
||||||
// todo: connect by key
|
// todo: connect by key
|
||||||
// p->setNativeArguments(QString("%1@%2")
|
// p->setNativeArguments(QString("%1@%2")
|
||||||
// .arg(credentials.userName).arg(credentials.hostName).arg(credentials.secretData));
|
// .arg(credentials.userName).arg(credentials.hostName).arg(credentials.secretData));
|
||||||
}
|
} else {
|
||||||
else {
|
p->setNativeArguments(
|
||||||
p->setNativeArguments(QString("%1@%2 -pw %3")
|
QString("%1@%2 -pw %3").arg(credentials.userName).arg(credentials.hostName).arg(credentials.secretData));
|
||||||
.arg(credentials.userName).arg(credentials.hostName).arg(credentials.secretData));
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
p->setProgram("/bin/bash");
|
p->setProgram("/bin/bash");
|
||||||
|
|
@ -95,7 +102,7 @@ QProcessEnvironment SshConfigurator::prepareEnv()
|
||||||
pathEnvVar.clear();
|
pathEnvVar.clear();
|
||||||
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "\\cygwin;");
|
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "\\cygwin;");
|
||||||
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "\\openvpn;");
|
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "\\openvpn;");
|
||||||
#else
|
#elif defined(Q_OS_MACX)
|
||||||
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "/Contents/MacOS");
|
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "/Contents/MacOS");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,27 @@
|
||||||
#include "wireguard_configurator.h"
|
#include "wireguard_configurator.h"
|
||||||
#include <QApplication>
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QJsonDocument>
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QTemporaryDir>
|
#include <QTemporaryDir>
|
||||||
#include <QDebug>
|
|
||||||
#include <QTemporaryFile>
|
#include <QTemporaryFile>
|
||||||
#include <QJsonDocument>
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <openssl/pem.h>
|
||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
#include <openssl/rsa.h>
|
#include <openssl/rsa.h>
|
||||||
#include <openssl/x509.h>
|
#include <openssl/x509.h>
|
||||||
#include <openssl/pem.h>
|
|
||||||
|
|
||||||
|
|
||||||
#include "containers/containers_defs.h"
|
#include "containers/containers_defs.h"
|
||||||
#include "core/server_defs.h"
|
|
||||||
#include "core/scripts_registry.h"
|
#include "core/scripts_registry.h"
|
||||||
#include "utilities.h"
|
#include "core/server_defs.h"
|
||||||
#include "core/servercontroller.h"
|
#include "core/servercontroller.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
#include "utilities.h"
|
||||||
|
|
||||||
WireguardConfigurator::WireguardConfigurator(std::shared_ptr<Settings> settings, QObject *parent):
|
WireguardConfigurator::WireguardConfigurator(std::shared_ptr<Settings> settings, QObject *parent)
|
||||||
ConfiguratorBase(settings, parent)
|
: ConfiguratorBase(settings, parent)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WireguardConfigurator::ConnectionData WireguardConfigurator::genClientKeys()
|
WireguardConfigurator::ConnectionData WireguardConfigurator::genClientKeys()
|
||||||
|
|
@ -36,13 +33,13 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::genClientKeys()
|
||||||
|
|
||||||
unsigned char buff[EDDSA_KEY_LENGTH];
|
unsigned char buff[EDDSA_KEY_LENGTH];
|
||||||
int ret = RAND_priv_bytes(buff, EDDSA_KEY_LENGTH);
|
int ret = RAND_priv_bytes(buff, EDDSA_KEY_LENGTH);
|
||||||
if (ret <=0) return connData;
|
if (ret <= 0)
|
||||||
|
return connData;
|
||||||
|
|
||||||
EVP_PKEY *pKey = EVP_PKEY_new();
|
EVP_PKEY *pKey = EVP_PKEY_new();
|
||||||
q_check_ptr(pKey);
|
q_check_ptr(pKey);
|
||||||
pKey = EVP_PKEY_new_raw_private_key(EVP_PKEY_X25519, NULL, &buff[0], EDDSA_KEY_LENGTH);
|
pKey = EVP_PKEY_new_raw_private_key(EVP_PKEY_X25519, NULL, &buff[0], EDDSA_KEY_LENGTH);
|
||||||
|
|
||||||
|
|
||||||
size_t keySize = EDDSA_KEY_LENGTH;
|
size_t keySize = EDDSA_KEY_LENGTH;
|
||||||
|
|
||||||
// save private key
|
// save private key
|
||||||
|
|
@ -59,14 +56,17 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::genClientKeys()
|
||||||
}
|
}
|
||||||
|
|
||||||
WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardConfig(const ServerCredentials &credentials,
|
WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardConfig(const ServerCredentials &credentials,
|
||||||
DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode)
|
DockerContainer container,
|
||||||
|
const QJsonObject &containerConfig,
|
||||||
|
ErrorCode *errorCode)
|
||||||
{
|
{
|
||||||
WireguardConfigurator::ConnectionData connData = WireguardConfigurator::genClientKeys();
|
WireguardConfigurator::ConnectionData connData = WireguardConfigurator::genClientKeys();
|
||||||
connData.host = credentials.hostName;
|
connData.host = credentials.hostName;
|
||||||
connData.port = containerConfig.value(config_key::port).toString(protocols::wireguard::defaultPort);
|
connData.port = containerConfig.value(config_key::port).toString(protocols::wireguard::defaultPort);
|
||||||
|
|
||||||
if (connData.clientPrivKey.isEmpty() || connData.clientPubKey.isEmpty()) {
|
if (connData.clientPrivKey.isEmpty() || connData.clientPubKey.isEmpty()) {
|
||||||
if (errorCode) *errorCode = ErrorCode::InternalError;
|
if (errorCode)
|
||||||
|
*errorCode = ErrorCode::InternalError;
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -96,22 +96,24 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
|
||||||
// Calc next IP address
|
// Calc next IP address
|
||||||
if (ips.isEmpty()) {
|
if (ips.isEmpty()) {
|
||||||
nextIpNumber = "2";
|
nextIpNumber = "2";
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
int next = ips.last().split(".").last().toInt() + 1;
|
int next = ips.last().split(".").last().toInt() + 1;
|
||||||
if (next > 254) {
|
if (next > 254) {
|
||||||
if (errorCode) *errorCode = ErrorCode::AddressPoolError;
|
if (errorCode)
|
||||||
|
*errorCode = ErrorCode::AddressPoolError;
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
nextIpNumber = QString::number(next);
|
nextIpNumber = QString::number(next);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString subnetIp = containerConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress);
|
QString subnetIp =
|
||||||
|
containerConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress);
|
||||||
{
|
{
|
||||||
QStringList l = subnetIp.split(".", Qt::SkipEmptyParts);
|
QStringList l = subnetIp.split(".", Qt::SkipEmptyParts);
|
||||||
if (l.isEmpty()) {
|
if (l.isEmpty()) {
|
||||||
if (errorCode) *errorCode = ErrorCode::AddressPoolError;
|
if (errorCode)
|
||||||
|
*errorCode = ErrorCode::AddressPoolError;
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
l.removeLast();
|
l.removeLast();
|
||||||
|
|
@ -121,51 +123,59 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get keys
|
// Get keys
|
||||||
connData.serverPubKey = serverController.getTextFileFromContainer(container, credentials, amnezia::protocols::wireguard::serverPublicKeyPath, &e);
|
connData.serverPubKey = serverController.getTextFileFromContainer(
|
||||||
|
container, credentials, amnezia::protocols::wireguard::serverPublicKeyPath, &e);
|
||||||
connData.serverPubKey.replace("\n", "");
|
connData.serverPubKey.replace("\n", "");
|
||||||
if (e) {
|
if (e) {
|
||||||
if (errorCode) *errorCode = e;
|
if (errorCode)
|
||||||
|
*errorCode = e;
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
connData.pskKey = serverController.getTextFileFromContainer(container, credentials, amnezia::protocols::wireguard::serverPskKeyPath, &e);
|
connData.pskKey = serverController.getTextFileFromContainer(container, credentials,
|
||||||
|
amnezia::protocols::wireguard::serverPskKeyPath, &e);
|
||||||
connData.pskKey.replace("\n", "");
|
connData.pskKey.replace("\n", "");
|
||||||
|
|
||||||
if (e) {
|
if (e) {
|
||||||
if (errorCode) *errorCode = e;
|
if (errorCode)
|
||||||
|
*errorCode = e;
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add client to config
|
// Add client to config
|
||||||
QString configPart = QString(
|
QString configPart = QString("[Peer]\n"
|
||||||
"[Peer]\n"
|
|
||||||
"PublicKey = %1\n"
|
"PublicKey = %1\n"
|
||||||
"PresharedKey = %2\n"
|
"PresharedKey = %2\n"
|
||||||
"AllowedIPs = %3/32\n\n").
|
"AllowedIPs = %3/32\n\n")
|
||||||
arg(connData.clientPubKey).
|
.arg(connData.clientPubKey)
|
||||||
arg(connData.pskKey).
|
.arg(connData.pskKey)
|
||||||
arg(connData.clientIP);
|
.arg(connData.clientIP);
|
||||||
|
|
||||||
e = serverController.uploadTextFileToContainer(container, credentials, configPart,
|
e = serverController.uploadTextFileToContainer(container, credentials, configPart,
|
||||||
protocols::wireguard::serverConfigPath, libssh::SftpOverwriteMode::SftpAppendToExisting);
|
protocols::wireguard::serverConfigPath,
|
||||||
|
libssh::SftpOverwriteMode::SftpAppendToExisting);
|
||||||
|
|
||||||
if (e) {
|
if (e) {
|
||||||
if (errorCode) *errorCode = e;
|
if (errorCode)
|
||||||
|
*errorCode = e;
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
e = serverController.runScript(credentials,
|
e = serverController.runScript(
|
||||||
serverController.replaceVars("sudo docker exec -i $CONTAINER_NAME bash -c 'wg syncconf wg0 <(wg-quick strip /opt/amnezia/wireguard/wg0.conf)'",
|
credentials,
|
||||||
|
serverController.replaceVars("sudo docker exec -i $CONTAINER_NAME bash -c 'wg syncconf wg0 <(wg-quick "
|
||||||
|
"strip /opt/amnezia/wireguard/wg0.conf)'",
|
||||||
serverController.genVarsForScript(credentials, container)));
|
serverController.genVarsForScript(credentials, container)));
|
||||||
|
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString WireguardConfigurator::genWireguardConfig(const ServerCredentials &credentials,
|
QString WireguardConfigurator::genWireguardConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode)
|
const QJsonObject &containerConfig, ErrorCode *errorCode)
|
||||||
{
|
{
|
||||||
ServerController serverController(m_settings);
|
ServerController serverController(m_settings);
|
||||||
QString config = serverController.replaceVars(amnezia::scriptData(ProtocolScriptType::wireguard_template, container),
|
QString config =
|
||||||
|
serverController.replaceVars(amnezia::scriptData(ProtocolScriptType::wireguard_template, container),
|
||||||
serverController.genVarsForScript(credentials, container, containerConfig));
|
serverController.genVarsForScript(credentials, container, containerConfig));
|
||||||
|
|
||||||
ConnectionData connData = prepareWireguardConfig(credentials, container, containerConfig, errorCode);
|
ConnectionData connData = prepareWireguardConfig(credentials, container, containerConfig, errorCode);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
#include "fileUtilites.h"
|
#include "fileUtilites.h"
|
||||||
#include "platforms/ios/MobileUtils.h"
|
|
||||||
|
|
||||||
#include <QDesktopServices>
|
#include <QDesktopServices>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QFileInfo>
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
|
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
|
|
|
||||||
|
|
@ -4,23 +4,25 @@
|
||||||
|
|
||||||
#include "androidutils.h"
|
#include "androidutils.h"
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QGuiApplication>
|
||||||
#include <QJniEnvironment>
|
#include <QJniEnvironment>
|
||||||
#include <QJniObject>
|
#include <QJniObject>
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QNetworkCookieJar>
|
#include <QNetworkCookieJar>
|
||||||
#include <QUrlQuery>
|
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
#include <QUrlQuery>
|
||||||
|
|
||||||
#include "jni.h"
|
#include "jni.h"
|
||||||
|
|
||||||
namespace {
|
namespace
|
||||||
|
{
|
||||||
AndroidUtils *s_instance = nullptr;
|
AndroidUtils *s_instance = nullptr;
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
// static
|
// static
|
||||||
QString AndroidUtils::GetDeviceName() {
|
QString AndroidUtils::GetDeviceName()
|
||||||
|
{
|
||||||
QJniEnvironment env;
|
QJniEnvironment env;
|
||||||
jclass BUILD = env->FindClass("android/os/Build");
|
jclass BUILD = env->FindClass("android/os/Build");
|
||||||
jfieldID model = env->GetStaticFieldID(BUILD, "MODEL", "Ljava/lang/String;");
|
jfieldID model = env->GetStaticFieldID(BUILD, "MODEL", "Ljava/lang/String;");
|
||||||
|
|
@ -42,7 +44,8 @@ QString AndroidUtils::GetDeviceName() {
|
||||||
};
|
};
|
||||||
|
|
||||||
// static
|
// static
|
||||||
AndroidUtils* AndroidUtils::instance() {
|
AndroidUtils *AndroidUtils::instance()
|
||||||
|
{
|
||||||
if (!s_instance) {
|
if (!s_instance) {
|
||||||
Q_ASSERT(qApp);
|
Q_ASSERT(qApp);
|
||||||
s_instance = new AndroidUtils(qApp);
|
s_instance = new AndroidUtils(qApp);
|
||||||
|
|
@ -51,18 +54,21 @@ AndroidUtils* AndroidUtils::instance() {
|
||||||
return s_instance;
|
return s_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
AndroidUtils::AndroidUtils(QObject* parent) : QObject(parent) {
|
AndroidUtils::AndroidUtils(QObject *parent) : QObject(parent)
|
||||||
|
{
|
||||||
Q_ASSERT(!s_instance);
|
Q_ASSERT(!s_instance);
|
||||||
s_instance = this;
|
s_instance = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
AndroidUtils::~AndroidUtils() {
|
AndroidUtils::~AndroidUtils()
|
||||||
|
{
|
||||||
Q_ASSERT(s_instance == this);
|
Q_ASSERT(s_instance == this);
|
||||||
s_instance = nullptr;
|
s_instance = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void AndroidUtils::dispatchToMainThread(std::function<void()> callback) {
|
void AndroidUtils::dispatchToMainThread(std::function<void()> callback)
|
||||||
|
{
|
||||||
QTimer *timer = new QTimer();
|
QTimer *timer = new QTimer();
|
||||||
timer->moveToThread(qApp->thread());
|
timer->moveToThread(qApp->thread());
|
||||||
timer->setSingleShot(true);
|
timer->setSingleShot(true);
|
||||||
|
|
@ -74,7 +80,8 @@ void AndroidUtils::dispatchToMainThread(std::function<void()> callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
QByteArray AndroidUtils::getQByteArrayFromJString(JNIEnv* env, jstring data) {
|
QByteArray AndroidUtils::getQByteArrayFromJString(JNIEnv *env, jstring data)
|
||||||
|
{
|
||||||
const char *buffer = env->GetStringUTFChars(data, nullptr);
|
const char *buffer = env->GetStringUTFChars(data, nullptr);
|
||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
qDebug() << "getQByteArrayFromJString - failed to parse data.";
|
qDebug() << "getQByteArrayFromJString - failed to parse data.";
|
||||||
|
|
@ -87,7 +94,8 @@ QByteArray AndroidUtils::getQByteArrayFromJString(JNIEnv* env, jstring data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
QString AndroidUtils::getQStringFromJString(JNIEnv* env, jstring data) {
|
QString AndroidUtils::getQStringFromJString(JNIEnv *env, jstring data)
|
||||||
|
{
|
||||||
const char *buffer = env->GetStringUTFChars(data, nullptr);
|
const char *buffer = env->GetStringUTFChars(data, nullptr);
|
||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
qDebug() << "getQStringFromJString - failed to parse data.";
|
qDebug() << "getQStringFromJString - failed to parse data.";
|
||||||
|
|
@ -100,15 +108,14 @@ QString AndroidUtils::getQStringFromJString(JNIEnv* env, jstring data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
QJsonObject AndroidUtils::getQJsonObjectFromJString(JNIEnv* env, jstring data) {
|
QJsonObject AndroidUtils::getQJsonObjectFromJString(JNIEnv *env, jstring data)
|
||||||
|
{
|
||||||
QByteArray raw(getQByteArrayFromJString(env, data));
|
QByteArray raw(getQByteArrayFromJString(env, data));
|
||||||
QJsonParseError jsonError;
|
QJsonParseError jsonError;
|
||||||
QJsonDocument json = QJsonDocument::fromJson(raw, &jsonError);
|
QJsonDocument json = QJsonDocument::fromJson(raw, &jsonError);
|
||||||
if (QJsonParseError::NoError != jsonError.error) {
|
if (QJsonParseError::NoError != jsonError.error) {
|
||||||
qDebug() << "getQJsonObjectFromJstring - error parsing json. Code: "
|
qDebug() << "getQJsonObjectFromJstring - error parsing json. Code: " << jsonError.error
|
||||||
<< jsonError.error << "Offset: " << jsonError.offset
|
<< "Offset: " << jsonError.offset << "Message: " << jsonError.errorString() << "Data: " << raw;
|
||||||
<< "Message: " << jsonError.errorString()
|
|
||||||
<< "Data: " << raw;
|
|
||||||
return QJsonObject();
|
return QJsonObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -120,11 +127,13 @@ QJsonObject AndroidUtils::getQJsonObjectFromJString(JNIEnv* env, jstring data) {
|
||||||
return json.object();
|
return json.object();
|
||||||
}
|
}
|
||||||
|
|
||||||
QJniObject AndroidUtils::getActivity() {
|
QJniObject AndroidUtils::getActivity()
|
||||||
|
{
|
||||||
return QNativeInterface::QAndroidApplication::context();
|
return QNativeInterface::QAndroidApplication::context();
|
||||||
}
|
}
|
||||||
|
|
||||||
int AndroidUtils::GetSDKVersion() {
|
int AndroidUtils::GetSDKVersion()
|
||||||
|
{
|
||||||
QJniEnvironment env;
|
QJniEnvironment env;
|
||||||
jclass versionClass = env->FindClass("android/os/Build$VERSION");
|
jclass versionClass = env->FindClass("android/os/Build$VERSION");
|
||||||
jfieldID sdkIntFieldID = env->GetStaticFieldID(versionClass, "SDK_INT", "I");
|
jfieldID sdkIntFieldID = env->GetStaticFieldID(versionClass, "SDK_INT", "I");
|
||||||
|
|
@ -133,13 +142,12 @@ int AndroidUtils::GetSDKVersion() {
|
||||||
return sdk;
|
return sdk;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AndroidUtils::GetManufacturer() {
|
QString AndroidUtils::GetManufacturer()
|
||||||
|
{
|
||||||
QJniEnvironment env;
|
QJniEnvironment env;
|
||||||
jclass buildClass = env->FindClass("android/os/Build");
|
jclass buildClass = env->FindClass("android/os/Build");
|
||||||
jfieldID manuFacturerField =
|
jfieldID manuFacturerField = env->GetStaticFieldID(buildClass, "MANUFACTURER", "Ljava/lang/String;");
|
||||||
env->GetStaticFieldID(buildClass, "MANUFACTURER", "Ljava/lang/String;");
|
jstring value = (jstring)env->GetStaticObjectField(buildClass, manuFacturerField);
|
||||||
jstring value =
|
|
||||||
(jstring)env->GetStaticObjectField(buildClass, manuFacturerField);
|
|
||||||
|
|
||||||
const char *buffer = env->GetStringUTFChars(value, nullptr);
|
const char *buffer = env->GetStringUTFChars(value, nullptr);
|
||||||
|
|
||||||
|
|
@ -154,21 +162,22 @@ QString AndroidUtils::GetManufacturer() {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidUtils::runOnAndroidThreadSync(const std::function<void()> runnable) {
|
void AndroidUtils::runOnAndroidThreadSync(const std::function<void()> runnable)
|
||||||
QNativeInterface::QAndroidApplication::runOnAndroidMainThread(runnable)
|
{
|
||||||
.waitForFinished();
|
QNativeInterface::QAndroidApplication::runOnAndroidMainThread(runnable).waitForFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidUtils::runOnAndroidThreadAsync(const std::function<void()> runnable) {
|
void AndroidUtils::runOnAndroidThreadAsync(const std::function<void()> runnable)
|
||||||
|
{
|
||||||
QNativeInterface::QAndroidApplication::runOnAndroidMainThread(runnable);
|
QNativeInterface::QAndroidApplication::runOnAndroidMainThread(runnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Static
|
// Static
|
||||||
// Creates a copy of the passed QByteArray in the JVM and passes back a ref
|
// Creates a copy of the passed QByteArray in the JVM and passes back a ref
|
||||||
jbyteArray AndroidUtils::tojByteArray(const QByteArray& data) {
|
jbyteArray AndroidUtils::tojByteArray(const QByteArray &data)
|
||||||
|
{
|
||||||
QJniEnvironment env;
|
QJniEnvironment env;
|
||||||
jbyteArray out = env->NewByteArray(data.size());
|
jbyteArray out = env->NewByteArray(data.size());
|
||||||
env->SetByteArrayRegion(out, 0, data.size(),
|
env->SetByteArrayRegion(out, 0, data.size(), reinterpret_cast<const jbyte *>(data.constData()));
|
||||||
reinterpret_cast<const jbyte*>(data.constData()));
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
#include "androidvpnactivity.h"
|
#include "androidvpnactivity.h"
|
||||||
|
|
||||||
#include <QApplication>
|
|
||||||
#include <QJniEnvironment>
|
#include <QJniEnvironment>
|
||||||
#include <QJniObject>
|
#include <QJniObject>
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
|
|
@ -13,12 +12,14 @@
|
||||||
#include "androidutils.h"
|
#include "androidutils.h"
|
||||||
#include "jni.h"
|
#include "jni.h"
|
||||||
|
|
||||||
namespace {
|
namespace
|
||||||
|
{
|
||||||
AndroidVPNActivity *s_instance = nullptr;
|
AndroidVPNActivity *s_instance = nullptr;
|
||||||
constexpr auto CLASSNAME = "org.amnezia.vpn.qt.VPNActivity";
|
constexpr auto CLASSNAME = "org.amnezia.vpn.qt.VPNActivity";
|
||||||
}
|
}
|
||||||
|
|
||||||
AndroidVPNActivity::AndroidVPNActivity() {
|
AndroidVPNActivity::AndroidVPNActivity()
|
||||||
|
{
|
||||||
AndroidUtils::runOnAndroidThreadAsync([]() {
|
AndroidUtils::runOnAndroidThreadAsync([]() {
|
||||||
JNINativeMethod methods[] {
|
JNINativeMethod methods[] {
|
||||||
{ "handleBackButton", "()Z", reinterpret_cast<bool *>(handleBackButton) },
|
{ "handleBackButton", "()Z", reinterpret_cast<bool *>(handleBackButton) },
|
||||||
|
|
@ -36,19 +37,22 @@ AndroidVPNActivity::AndroidVPNActivity() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidVPNActivity::maybeInit() {
|
void AndroidVPNActivity::maybeInit()
|
||||||
|
{
|
||||||
if (s_instance == nullptr) {
|
if (s_instance == nullptr) {
|
||||||
s_instance = new AndroidVPNActivity();
|
s_instance = new AndroidVPNActivity();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
bool AndroidVPNActivity::handleBackButton(JNIEnv* env, jobject thiz) {
|
bool AndroidVPNActivity::handleBackButton(JNIEnv *env, jobject thiz)
|
||||||
|
{
|
||||||
Q_UNUSED(env);
|
Q_UNUSED(env);
|
||||||
Q_UNUSED(thiz);
|
Q_UNUSED(thiz);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidVPNActivity::connectService() {
|
void AndroidVPNActivity::connectService()
|
||||||
|
{
|
||||||
QJniObject::callStaticMethod<void>(CLASSNAME, "connectService", "()V");
|
QJniObject::callStaticMethod<void>(CLASSNAME, "connectService", "()V");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -57,16 +61,16 @@ void AndroidVPNActivity::startQrCodeReader()
|
||||||
QJniObject::callStaticMethod<void>(CLASSNAME, "startQrCodeReader", "()V");
|
QJniObject::callStaticMethod<void>(CLASSNAME, "startQrCodeReader", "()V");
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidVPNActivity::saveFileAs(QString fileContent, QString suggestedFilename) {
|
void AndroidVPNActivity::saveFileAs(QString fileContent, QString suggestedFilename)
|
||||||
QJniObject::callStaticMethod<void>(
|
{
|
||||||
CLASSNAME,
|
QJniObject::callStaticMethod<void>(CLASSNAME, "saveFileAs", "(Ljava/lang/String;Ljava/lang/String;)V",
|
||||||
"saveFileAs", "(Ljava/lang/String;Ljava/lang/String;)V",
|
|
||||||
QJniObject::fromString(fileContent).object<jstring>(),
|
QJniObject::fromString(fileContent).object<jstring>(),
|
||||||
QJniObject::fromString(suggestedFilename).object<jstring>());
|
QJniObject::fromString(suggestedFilename).object<jstring>());
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
AndroidVPNActivity* AndroidVPNActivity::instance() {
|
AndroidVPNActivity *AndroidVPNActivity::instance()
|
||||||
|
{
|
||||||
if (s_instance == nullptr) {
|
if (s_instance == nullptr) {
|
||||||
AndroidVPNActivity::maybeInit();
|
AndroidVPNActivity::maybeInit();
|
||||||
}
|
}
|
||||||
|
|
@ -75,19 +79,17 @@ AndroidVPNActivity* AndroidVPNActivity::instance() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void AndroidVPNActivity::sendToService(ServiceAction type, const QString& data) {
|
void AndroidVPNActivity::sendToService(ServiceAction type, const QString &data)
|
||||||
|
{
|
||||||
int messageType = (int)type;
|
int messageType = (int)type;
|
||||||
|
|
||||||
QJniObject::callStaticMethod<void>(
|
QJniObject::callStaticMethod<void>(CLASSNAME, "sendToService", "(ILjava/lang/String;)V",
|
||||||
CLASSNAME,
|
static_cast<int>(messageType), QJniObject::fromString(data).object<jstring>());
|
||||||
"sendToService", "(ILjava/lang/String;)V",
|
|
||||||
static_cast<int>(messageType),
|
|
||||||
QJniObject::fromString(data).object<jstring>());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void AndroidVPNActivity::onServiceMessage(JNIEnv* env, jobject thiz,
|
void AndroidVPNActivity::onServiceMessage(JNIEnv *env, jobject thiz, jint messageType, jstring body)
|
||||||
jint messageType, jstring body) {
|
{
|
||||||
Q_UNUSED(thiz);
|
Q_UNUSED(thiz);
|
||||||
const char *buffer = env->GetStringUTFChars(body, nullptr);
|
const char *buffer = env->GetStringUTFChars(body, nullptr);
|
||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
|
|
@ -97,38 +99,23 @@ void AndroidVPNActivity::onServiceMessage(JNIEnv* env, jobject thiz,
|
||||||
QString parcelBody(buffer);
|
QString parcelBody(buffer);
|
||||||
env->ReleaseStringUTFChars(body, buffer);
|
env->ReleaseStringUTFChars(body, buffer);
|
||||||
AndroidUtils::dispatchToMainThread([messageType, parcelBody] {
|
AndroidUtils::dispatchToMainThread([messageType, parcelBody] {
|
||||||
AndroidVPNActivity::instance()->handleServiceMessage(messageType,
|
AndroidVPNActivity::instance()->handleServiceMessage(messageType, parcelBody);
|
||||||
parcelBody);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidVPNActivity::handleServiceMessage(int code, const QString& data) {
|
void AndroidVPNActivity::handleServiceMessage(int code, const QString &data)
|
||||||
|
{
|
||||||
auto mode = (ServiceEvents)code;
|
auto mode = (ServiceEvents)code;
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case ServiceEvents::EVENT_INIT:
|
case ServiceEvents::EVENT_INIT: emit eventInitialized(data); break;
|
||||||
emit eventInitialized(data);
|
case ServiceEvents::EVENT_CONNECTED: emit eventConnected(data); break;
|
||||||
break;
|
case ServiceEvents::EVENT_DISCONNECTED: emit eventDisconnected(data); break;
|
||||||
case ServiceEvents::EVENT_CONNECTED:
|
case ServiceEvents::EVENT_STATISTIC_UPDATE: emit eventStatisticUpdate(data); break;
|
||||||
emit eventConnected(data);
|
case ServiceEvents::EVENT_BACKEND_LOGS: emit eventBackendLogs(data); break;
|
||||||
break;
|
case ServiceEvents::EVENT_ACTIVATION_ERROR: emit eventActivationError(data); break;
|
||||||
case ServiceEvents::EVENT_DISCONNECTED:
|
case ServiceEvents::EVENT_CONFIG_IMPORT: emit eventConfigImport(data); break;
|
||||||
emit eventDisconnected(data);
|
default: Q_ASSERT(false);
|
||||||
break;
|
|
||||||
case ServiceEvents::EVENT_STATISTIC_UPDATE:
|
|
||||||
emit eventStatisticUpdate(data);
|
|
||||||
break;
|
|
||||||
case ServiceEvents::EVENT_BACKEND_LOGS:
|
|
||||||
emit eventBackendLogs(data);
|
|
||||||
break;
|
|
||||||
case ServiceEvents::EVENT_ACTIVATION_ERROR:
|
|
||||||
emit eventActivationError(data);
|
|
||||||
break;
|
|
||||||
case ServiceEvents::EVENT_CONFIG_IMPORT:
|
|
||||||
emit eventConfigImport(data);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Q_ASSERT(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -137,22 +124,21 @@ void AndroidVPNActivity::handleActivityMessage(int code, const QString &data)
|
||||||
auto mode = (UIEvents)code;
|
auto mode = (UIEvents)code;
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case UIEvents::QR_CODED_DECODED:
|
case UIEvents::QR_CODED_DECODED: emit eventQrCodeReceived(data); break;
|
||||||
emit eventQrCodeReceived(data);
|
default: Q_ASSERT(false);
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Q_ASSERT(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidVPNActivity::onServiceConnected(JNIEnv* env, jobject thiz) {
|
void AndroidVPNActivity::onServiceConnected(JNIEnv *env, jobject thiz)
|
||||||
|
{
|
||||||
Q_UNUSED(env);
|
Q_UNUSED(env);
|
||||||
Q_UNUSED(thiz);
|
Q_UNUSED(thiz);
|
||||||
|
|
||||||
emit AndroidVPNActivity::instance()->serviceConnected();
|
emit AndroidVPNActivity::instance()->serviceConnected();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidVPNActivity::onServiceDisconnected(JNIEnv* env, jobject thiz) {
|
void AndroidVPNActivity::onServiceDisconnected(JNIEnv *env, jobject thiz)
|
||||||
|
{
|
||||||
Q_UNUSED(env);
|
Q_UNUSED(env);
|
||||||
Q_UNUSED(thiz);
|
Q_UNUSED(thiz);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,75 +56,6 @@
|
||||||
<file>server_scripts/wireguard/template.conf</file>
|
<file>server_scripts/wireguard/template.conf</file>
|
||||||
<file>server_scripts/website_tor/configure_container.sh</file>
|
<file>server_scripts/website_tor/configure_container.sh</file>
|
||||||
<file>server_scripts/website_tor/run_container.sh</file>
|
<file>server_scripts/website_tor/run_container.sh</file>
|
||||||
<file>ui/qml/main.qml</file>
|
|
||||||
<file>ui/qml/Pages/PageBase.qml</file>
|
|
||||||
<file>ui/qml/Pages/PageAppSetting.qml</file>
|
|
||||||
<file>ui/qml/Pages/PageGeneralSettings.qml</file>
|
|
||||||
<file>ui/qml/Pages/PageNetworkSetting.qml</file>
|
|
||||||
<file>ui/qml/Pages/PageNewServer.qml</file>
|
|
||||||
<file>ui/qml/Pages/PageServerConfiguringProgress.qml</file>
|
|
||||||
<file>ui/qml/Pages/PageNewServerProtocols.qml</file>
|
|
||||||
<file>ui/qml/Pages/PageServerList.qml</file>
|
|
||||||
<file>ui/qml/Pages/PageServerContainers.qml</file>
|
|
||||||
<file>ui/qml/Pages/PageServerSettings.qml</file>
|
|
||||||
<file>ui/qml/Pages/PageSetupWizard.qml</file>
|
|
||||||
<file>ui/qml/Pages/PageSetupWizardHighLevel.qml</file>
|
|
||||||
<file>ui/qml/Pages/PageSetupWizardLowLevel.qml</file>
|
|
||||||
<file>ui/qml/Pages/PageSetupWizardMediumLevel.qml</file>
|
|
||||||
<file>ui/qml/Pages/PageSetupWizardVPNMode.qml</file>
|
|
||||||
<file>ui/qml/Pages/PageShareConnection.qml</file>
|
|
||||||
<file>ui/qml/Pages/PageSites.qml</file>
|
|
||||||
<file>ui/qml/Pages/PageStart.qml</file>
|
|
||||||
<file>ui/qml/Pages/PageVPN.qml</file>
|
|
||||||
<file>ui/qml/Pages/PageAbout.qml</file>
|
|
||||||
<file>ui/qml/Pages/PageQrDecoderIos.qml</file>
|
|
||||||
<file>ui/qml/Pages/PageViewConfig.qml</file>
|
|
||||||
<file>ui/qml/Pages/PageClientManagement.qml</file>
|
|
||||||
<file>ui/qml/Pages/ClientInfo/PageClientInfoBase.qml</file>
|
|
||||||
<file>ui/qml/Pages/ClientInfo/PageClientInfoOpenVPN.qml</file>
|
|
||||||
<file>ui/qml/Pages/ClientInfo/PageClientInfoWireGuard.qml</file>
|
|
||||||
<file>ui/qml/Pages/Protocols/PageProtoCloak.qml</file>
|
|
||||||
<file>ui/qml/Pages/Protocols/PageProtoOpenVPN.qml</file>
|
|
||||||
<file>ui/qml/Pages/Protocols/PageProtoShadowSocks.qml</file>
|
|
||||||
<file>ui/qml/Pages/Protocols/PageProtoSftp.qml</file>
|
|
||||||
<file>ui/qml/Pages/Protocols/PageProtoTorWebSite.qml</file>
|
|
||||||
<file>ui/qml/Pages/Protocols/PageProtocolBase.qml</file>
|
|
||||||
<file>ui/qml/Pages/Protocols/PageProtoWireGuard.qml</file>
|
|
||||||
<file>ui/qml/Pages/InstallSettings/InstallSettingsBase.qml</file>
|
|
||||||
<file>ui/qml/Pages/InstallSettings/SelectContainer.qml</file>
|
|
||||||
<file>ui/qml/Pages/Share/PageShareProtoCloak.qml</file>
|
|
||||||
<file>ui/qml/Pages/Share/PageShareProtocolBase.qml</file>
|
|
||||||
<file>ui/qml/Pages/Share/PageShareProtoOpenVPN.qml</file>
|
|
||||||
<file>ui/qml/Pages/Share/PageShareProtoSftp.qml</file>
|
|
||||||
<file>ui/qml/Pages/Share/PageShareProtoShadowSocks.qml</file>
|
|
||||||
<file>ui/qml/Pages/Share/PageShareProtoTorWebSite.qml</file>
|
|
||||||
<file>ui/qml/Pages/Share/PageShareProtoAmnezia.qml</file>
|
|
||||||
<file>ui/qml/Pages/Share/PageShareProtoWireGuard.qml</file>
|
|
||||||
<file>ui/qml/Pages/Share/PageShareProtoIkev2.qml</file>
|
|
||||||
<file>ui/qml/Controls/BasicButtonType.qml</file>
|
|
||||||
<file>ui/qml/Controls/BlueButtonType.qml</file>
|
|
||||||
<file>ui/qml/Controls/CheckBoxType.qml</file>
|
|
||||||
<file>ui/qml/Controls/ComboBoxType.qml</file>
|
|
||||||
<file>ui/qml/Controls/ImageButtonType.qml</file>
|
|
||||||
<file>ui/qml/Controls/LabelType.qml</file>
|
|
||||||
<file>ui/qml/Controls/RadioButtonType.qml</file>
|
|
||||||
<file>ui/qml/Controls/SettingButtonType.qml</file>
|
|
||||||
<file>ui/qml/Controls/ShareConnectionButtonType.qml</file>
|
|
||||||
<file>ui/qml/Controls/ShareConnectionContent.qml</file>
|
|
||||||
<file>ui/qml/Controls/TextFieldType.qml</file>
|
|
||||||
<file>ui/qml/Controls/RichLabelType.qml</file>
|
|
||||||
<file>ui/qml/Controls/SvgImageType.qml</file>
|
|
||||||
<file>ui/qml/Controls/FlickableType.qml</file>
|
|
||||||
<file>ui/qml/Controls/UrlButtonType.qml</file>
|
|
||||||
<file>ui/qml/Controls/TextAreaType.qml</file>
|
|
||||||
<file>ui/qml/Controls/ContextMenu.qml</file>
|
|
||||||
<file>ui/qml/Controls/FadeBehavior.qml</file>
|
|
||||||
<file>ui/qml/Controls/VisibleBehavior.qml</file>
|
|
||||||
<file>ui/qml/Controls/Caption.qml</file>
|
|
||||||
<file>ui/qml/Controls/Logo.qml</file>
|
|
||||||
<file>ui/qml/Controls/BackButton.qml</file>
|
|
||||||
<file>ui/qml/Controls/ShareConnectionButtonCopyType.qml</file>
|
|
||||||
<file>ui/qml/Controls/SvgButtonType.qml</file>
|
|
||||||
<file>ui/qml/Config/GlobalConfig.qml</file>
|
<file>ui/qml/Config/GlobalConfig.qml</file>
|
||||||
<file>ui/qml/Config/qmldir</file>
|
<file>ui/qml/Config/qmldir</file>
|
||||||
<file>server_scripts/check_server_is_busy.sh</file>
|
<file>server_scripts/check_server_is_busy.sh</file>
|
||||||
|
|
@ -161,10 +92,6 @@
|
||||||
<file>images/svg/control_point_black_24dp.svg</file>
|
<file>images/svg/control_point_black_24dp.svg</file>
|
||||||
<file>images/svg/settings_suggest_black_24dp.svg</file>
|
<file>images/svg/settings_suggest_black_24dp.svg</file>
|
||||||
<file>server_scripts/website_tor/Dockerfile</file>
|
<file>server_scripts/website_tor/Dockerfile</file>
|
||||||
<file>ui/qml/Controls/PopupWithQuestion.qml</file>
|
|
||||||
<file>ui/qml/Pages/PageAdvancedServerSettings.qml</file>
|
|
||||||
<file>ui/qml/Controls/PopupWarning.qml</file>
|
|
||||||
<file>ui/qml/Controls/PopupWithTextField.qml</file>
|
|
||||||
<file>server_scripts/check_user_in_sudo.sh</file>
|
<file>server_scripts/check_user_in_sudo.sh</file>
|
||||||
<file>ui/qml/Controls2/BasicButtonType.qml</file>
|
<file>ui/qml/Controls2/BasicButtonType.qml</file>
|
||||||
<file>ui/qml/Controls2/TextFieldWithHeaderType.qml</file>
|
<file>ui/qml/Controls2/TextFieldWithHeaderType.qml</file>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,10 @@
|
||||||
#include "connectionController.h"
|
#include "connectionController.h"
|
||||||
|
|
||||||
|
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
||||||
|
#include <QGuiApplication>
|
||||||
|
#else
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "core/errorstrings.h"
|
#include "core/errorstrings.h"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,11 @@
|
||||||
#include "pageController.h"
|
#include "pageController.h"
|
||||||
|
|
||||||
|
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
||||||
|
#include <QGuiApplication>
|
||||||
|
#else
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
#include "../../platforms/android/androidutils.h"
|
#include "../../platforms/android/androidutils.h"
|
||||||
#include <QJniObject>
|
#include <QJniObject>
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,6 @@
|
||||||
|
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
|
|
||||||
#ifdef Q_OS_IOS
|
|
||||||
#include <CoreFoundation/CoreFoundation.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "fileUtilites.h"
|
#include "fileUtilites.h"
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include "ui/qautostart.h"
|
#include "ui/qautostart.h"
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,9 @@
|
||||||
#include "sitesController.h"
|
#include "sitesController.h"
|
||||||
|
|
||||||
|
#include <QFile>
|
||||||
#include <QHostInfo>
|
#include <QHostInfo>
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
|
|
||||||
#ifdef Q_OS_IOS
|
|
||||||
#include <CoreFoundation/CoreFoundation.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "fileUtilites.h"
|
#include "fileUtilites.h"
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,88 +0,0 @@
|
||||||
#include "AdvancedServerSettingsLogic.h"
|
|
||||||
|
|
||||||
#include "VpnLogic.h"
|
|
||||||
#include "ui/uilogic.h"
|
|
||||||
#include "core/errorstrings.h"
|
|
||||||
#include "core/servercontroller.h"
|
|
||||||
|
|
||||||
AdvancedServerSettingsLogic::AdvancedServerSettingsLogic(UiLogic *uiLogic, QObject *parent): PageLogicBase(uiLogic, parent),
|
|
||||||
m_labelWaitInfoVisible{true},
|
|
||||||
m_pushButtonClearVisible{true},
|
|
||||||
m_pushButtonClearText{tr("Clear server from Amnezia software")}
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void AdvancedServerSettingsLogic::onUpdatePage()
|
|
||||||
{
|
|
||||||
set_labelWaitInfoVisible(false);
|
|
||||||
set_labelWaitInfoText("");
|
|
||||||
set_pushButtonClearVisible(m_settings->haveAuthData(uiLogic()->m_selectedServerIndex));
|
|
||||||
const QJsonObject &server = m_settings->server(uiLogic()->m_selectedServerIndex);
|
|
||||||
const QString &port = server.value(config_key::port).toString();
|
|
||||||
|
|
||||||
const QString &userName = server.value(config_key::userName).toString();
|
|
||||||
const QString &hostName = server.value(config_key::hostName).toString();
|
|
||||||
QString name = QString("%1%2%3%4%5").arg(userName,
|
|
||||||
userName.isEmpty() ? "" : "@",
|
|
||||||
hostName,
|
|
||||||
port.isEmpty() ? "" : ":",
|
|
||||||
port);
|
|
||||||
|
|
||||||
set_labelServerText(name);
|
|
||||||
|
|
||||||
DockerContainer selectedContainer = m_settings->defaultContainer(uiLogic()->m_selectedServerIndex);
|
|
||||||
QString selectedContainerName = ContainerProps::containerHumanNames().value(selectedContainer);
|
|
||||||
set_labelCurrentVpnProtocolText(tr("Service: ") + selectedContainerName);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AdvancedServerSettingsLogic::onPushButtonClearServerClicked()
|
|
||||||
{
|
|
||||||
set_pageEnabled(false);
|
|
||||||
set_pushButtonClearText(tr("Uninstalling Amnezia software..."));
|
|
||||||
|
|
||||||
if (m_settings->defaultServerIndex() == uiLogic()->m_selectedServerIndex) {
|
|
||||||
uiLogic()->pageLogic<VpnLogic>()->onDisconnect();
|
|
||||||
}
|
|
||||||
|
|
||||||
ServerController serverController(m_settings);
|
|
||||||
ErrorCode errorCode = serverController.removeAllContainers(m_settings->serverCredentials(uiLogic()->m_selectedServerIndex));
|
|
||||||
if (errorCode) {
|
|
||||||
emit uiLogic()->showWarningMessage(tr("Error occurred while cleaning the server.") + "\n" +
|
|
||||||
tr("Error message: ") + errorString(errorCode) + "\n" +
|
|
||||||
tr("See logs for details."));
|
|
||||||
} else {
|
|
||||||
set_labelWaitInfoVisible(true);
|
|
||||||
set_labelWaitInfoText(tr("Amnezia server successfully uninstalled"));
|
|
||||||
}
|
|
||||||
|
|
||||||
m_settings->setContainers(uiLogic()->m_selectedServerIndex, {});
|
|
||||||
m_settings->setDefaultContainer(uiLogic()->m_selectedServerIndex, DockerContainer::None);
|
|
||||||
|
|
||||||
set_pageEnabled(true);
|
|
||||||
set_pushButtonClearText(tr("Clear server from Amnezia software"));
|
|
||||||
}
|
|
||||||
|
|
||||||
void AdvancedServerSettingsLogic::onPushButtonScanServerClicked()
|
|
||||||
{
|
|
||||||
set_labelWaitInfoVisible(false);
|
|
||||||
set_pageEnabled(false);
|
|
||||||
|
|
||||||
bool isServerCreated;
|
|
||||||
auto containersCount = m_settings->containers(uiLogic()->m_selectedServerIndex).size();
|
|
||||||
ErrorCode errorCode = uiLogic()->addAlreadyInstalledContainersGui(isServerCreated);
|
|
||||||
if (errorCode != ErrorCode::NoError) {
|
|
||||||
emit uiLogic()->showWarningMessage(tr("Error occurred while scanning the server.") + "\n" +
|
|
||||||
tr("Error message: ") + errorString(errorCode) + "\n" +
|
|
||||||
tr("See logs for details."));
|
|
||||||
}
|
|
||||||
auto newContainersCount = m_settings->containers(uiLogic()->m_selectedServerIndex).size();
|
|
||||||
if (containersCount != newContainersCount) {
|
|
||||||
emit uiLogic()->showWarningMessage(tr("All containers installed on the server are added to the GUI"));
|
|
||||||
} else {
|
|
||||||
emit uiLogic()->showWarningMessage(tr("No installed containers found on the server"));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
onUpdatePage();
|
|
||||||
set_pageEnabled(true);
|
|
||||||
}
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
#ifndef ADVANCEDSERVERSETTINGSLOGIC_H
|
|
||||||
#define ADVANCEDSERVERSETTINGSLOGIC_H
|
|
||||||
|
|
||||||
#include "PageLogicBase.h"
|
|
||||||
|
|
||||||
class UiLogic;
|
|
||||||
|
|
||||||
class AdvancedServerSettingsLogic : public PageLogicBase
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
AUTO_PROPERTY(bool, labelWaitInfoVisible)
|
|
||||||
AUTO_PROPERTY(QString, labelWaitInfoText)
|
|
||||||
|
|
||||||
AUTO_PROPERTY(QString, pushButtonClearText)
|
|
||||||
AUTO_PROPERTY(bool, pushButtonClearVisible)
|
|
||||||
|
|
||||||
AUTO_PROPERTY(QString, labelServerText)
|
|
||||||
AUTO_PROPERTY(QString, labelCurrentVpnProtocolText)
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit AdvancedServerSettingsLogic(UiLogic *uiLogic, QObject *parent = nullptr);
|
|
||||||
~AdvancedServerSettingsLogic() = default;
|
|
||||||
|
|
||||||
Q_INVOKABLE void onUpdatePage() override;
|
|
||||||
|
|
||||||
Q_INVOKABLE void onPushButtonClearServerClicked();
|
|
||||||
Q_INVOKABLE void onPushButtonScanServerClicked();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // ADVANCEDSERVERSETTINGSLOGIC_H
|
|
||||||
|
|
@ -1,119 +0,0 @@
|
||||||
#include "AppSettingsLogic.h"
|
|
||||||
|
|
||||||
#include "logger.h"
|
|
||||||
#include "version.h"
|
|
||||||
#include "ui/qautostart.h"
|
|
||||||
#include "ui/uilogic.h"
|
|
||||||
|
|
||||||
#include <QDesktopServices>
|
|
||||||
#include <QFileDialog>
|
|
||||||
#include <QStandardPaths>
|
|
||||||
#include <utilities.h>
|
|
||||||
|
|
||||||
#ifdef Q_OS_IOS
|
|
||||||
#include <CoreFoundation/CoreFoundation.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
using namespace amnezia;
|
|
||||||
using namespace PageEnumNS;
|
|
||||||
|
|
||||||
AppSettingsLogic::AppSettingsLogic(UiLogic *logic, QObject *parent):
|
|
||||||
PageLogicBase(logic, parent),
|
|
||||||
m_checkBoxAutostartChecked{false},
|
|
||||||
m_checkBoxAutoConnectChecked{false},
|
|
||||||
m_checkBoxStartMinimizedChecked{false},
|
|
||||||
m_checkBoxSaveLogsChecked{false}
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppSettingsLogic::onUpdatePage()
|
|
||||||
{
|
|
||||||
set_checkBoxAutostartChecked(Autostart::isAutostart());
|
|
||||||
set_checkBoxAutoConnectChecked(m_settings->isAutoConnect());
|
|
||||||
set_checkBoxStartMinimizedChecked(m_settings->isStartMinimized());
|
|
||||||
set_checkBoxSaveLogsChecked(m_settings->isSaveLogs());
|
|
||||||
|
|
||||||
QString ver = QString("%1: %2 (%3)")
|
|
||||||
.arg(tr("Software version"))
|
|
||||||
.arg(QString(APP_MAJOR_VERSION))
|
|
||||||
.arg(__DATE__);
|
|
||||||
set_labelVersionText(ver);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppSettingsLogic::onCheckBoxAutostartToggled(bool checked)
|
|
||||||
{
|
|
||||||
if (!checked) {
|
|
||||||
set_checkBoxAutoConnectChecked(false);
|
|
||||||
}
|
|
||||||
Autostart::setAutostart(checked);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppSettingsLogic::onCheckBoxAutoconnectToggled(bool checked)
|
|
||||||
{
|
|
||||||
m_settings->setAutoConnect(checked);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppSettingsLogic::onCheckBoxStartMinimizedToggled(bool checked)
|
|
||||||
{
|
|
||||||
m_settings->setStartMinimized(checked);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppSettingsLogic::onCheckBoxSaveLogsCheckedToggled(bool checked)
|
|
||||||
{
|
|
||||||
m_settings->setSaveLogs(checked);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppSettingsLogic::onPushButtonOpenLogsClicked()
|
|
||||||
{
|
|
||||||
Logger::openLogsFolder();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppSettingsLogic::onPushButtonExportLogsClicked()
|
|
||||||
{
|
|
||||||
uiLogic()->saveTextFile(tr("Save log"), "AmneziaVPN.log", ".log", Logger::getLogFile());
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppSettingsLogic::onPushButtonClearLogsClicked()
|
|
||||||
{
|
|
||||||
Logger::clearLogs();
|
|
||||||
Logger::clearServiceLogs();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppSettingsLogic::onPushButtonBackupAppConfigClicked()
|
|
||||||
{
|
|
||||||
uiLogic()->saveTextFile("Backup application config", "AmneziaVPN.backup", ".backup", m_settings->backupAppConfig());
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppSettingsLogic::onPushButtonRestoreAppConfigClicked()
|
|
||||||
{
|
|
||||||
QString fileName = UiLogic::getOpenFileName(Q_NULLPTR, tr("Open backup"),
|
|
||||||
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation), "*.backup");
|
|
||||||
|
|
||||||
if (fileName.isEmpty()) return;
|
|
||||||
|
|
||||||
QFile file(fileName);
|
|
||||||
|
|
||||||
#ifdef Q_OS_IOS
|
|
||||||
CFURLRef url = CFURLCreateWithFileSystemPath(
|
|
||||||
kCFAllocatorDefault, CFStringCreateWithCharacters(0, reinterpret_cast<const UniChar *>(fileName.unicode()),
|
|
||||||
fileName.length()),
|
|
||||||
kCFURLPOSIXPathStyle, 0);
|
|
||||||
|
|
||||||
if (!CFURLStartAccessingSecurityScopedResource(url)) {
|
|
||||||
qDebug() << "Could not access path " << QUrl::fromLocalFile(fileName).toString();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
file.open(QIODevice::ReadOnly);
|
|
||||||
QByteArray data = file.readAll();
|
|
||||||
|
|
||||||
bool ok = m_settings->restoreAppConfig(data);
|
|
||||||
if (ok) {
|
|
||||||
emit uiLogic()->goToPage(Page::Vpn);
|
|
||||||
emit uiLogic()->setStartPage(Page::Vpn);
|
|
||||||
} else {
|
|
||||||
emit uiLogic()->showWarningMessage(tr("Can't import config, file is corrupted."));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
#ifndef APP_SETTINGS_LOGIC_H
|
|
||||||
#define APP_SETTINGS_LOGIC_H
|
|
||||||
|
|
||||||
#include "PageLogicBase.h"
|
|
||||||
|
|
||||||
class UiLogic;
|
|
||||||
|
|
||||||
class AppSettingsLogic : public PageLogicBase
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
AUTO_PROPERTY(bool, checkBoxAutostartChecked)
|
|
||||||
AUTO_PROPERTY(bool, checkBoxAutoConnectChecked)
|
|
||||||
AUTO_PROPERTY(bool, checkBoxStartMinimizedChecked)
|
|
||||||
AUTO_PROPERTY(bool, checkBoxSaveLogsChecked)
|
|
||||||
AUTO_PROPERTY(QString, labelVersionText)
|
|
||||||
|
|
||||||
public:
|
|
||||||
Q_INVOKABLE void onUpdatePage() override;
|
|
||||||
|
|
||||||
Q_INVOKABLE void onCheckBoxAutostartToggled(bool checked);
|
|
||||||
Q_INVOKABLE void onCheckBoxAutoconnectToggled(bool checked);
|
|
||||||
Q_INVOKABLE void onCheckBoxStartMinimizedToggled(bool checked);
|
|
||||||
Q_INVOKABLE void onCheckBoxSaveLogsCheckedToggled(bool checked);
|
|
||||||
Q_INVOKABLE void onPushButtonOpenLogsClicked();
|
|
||||||
Q_INVOKABLE void onPushButtonExportLogsClicked();
|
|
||||||
Q_INVOKABLE void onPushButtonClearLogsClicked();
|
|
||||||
|
|
||||||
Q_INVOKABLE void onPushButtonBackupAppConfigClicked();
|
|
||||||
Q_INVOKABLE void onPushButtonRestoreAppConfigClicked();
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit AppSettingsLogic(UiLogic *uiLogic, QObject *parent = nullptr);
|
|
||||||
~AppSettingsLogic() = default;
|
|
||||||
|
|
||||||
};
|
|
||||||
#endif // APP_SETTINGS_LOGIC_H
|
|
||||||
|
|
@ -1,213 +0,0 @@
|
||||||
#include "ClientInfoLogic.h"
|
|
||||||
|
|
||||||
#include <QMessageBox>
|
|
||||||
|
|
||||||
#include "version.h"
|
|
||||||
#include "core/errorstrings.h"
|
|
||||||
#include "core/servercontroller.h"
|
|
||||||
#include "ui/models/clientManagementModel.h"
|
|
||||||
#include "ui/uilogic.h"
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
bool isErrorOccured(ErrorCode error) {
|
|
||||||
if (error != ErrorCode::NoError) {
|
|
||||||
QMessageBox::warning(nullptr, APPLICATION_NAME,
|
|
||||||
QObject::tr("An error occurred while saving the list of clients.") + "\n" + errorString(error));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ClientInfoLogic::ClientInfoLogic(UiLogic *logic, QObject *parent):
|
|
||||||
PageLogicBase(logic, parent)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClientInfoLogic::setCurrentClientId(int index)
|
|
||||||
{
|
|
||||||
m_currentClientIndex = index;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClientInfoLogic::onUpdatePage()
|
|
||||||
{
|
|
||||||
set_pageContentVisible(false);
|
|
||||||
set_busyIndicatorIsRunning(true);
|
|
||||||
|
|
||||||
const ServerCredentials credentials = m_settings->serverCredentials(uiLogic()->m_selectedServerIndex);
|
|
||||||
const DockerContainer container = m_settings->defaultContainer(uiLogic()->m_selectedServerIndex);
|
|
||||||
const QString containerNameString = ContainerProps::containerHumanNames().value(container);
|
|
||||||
set_labelCurrentVpnProtocolText(tr("Service: ") + containerNameString);
|
|
||||||
|
|
||||||
const QVector<amnezia::Proto> protocols = ContainerProps::protocolsForContainer(container);
|
|
||||||
if (!protocols.empty()) {
|
|
||||||
const Proto currentMainProtocol = protocols.front();
|
|
||||||
|
|
||||||
auto model = qobject_cast<ClientManagementModel*>(uiLogic()->clientManagementModel());
|
|
||||||
const QModelIndex modelIndex = model->index(m_currentClientIndex);
|
|
||||||
|
|
||||||
set_lineEditNameAliasText(model->data(modelIndex, ClientManagementModel::ClientRoles::NameRole).toString());
|
|
||||||
if (currentMainProtocol == Proto::OpenVpn) {
|
|
||||||
const QString certId = model->data(modelIndex, ClientManagementModel::ClientRoles::OpenVpnCertIdRole).toString();
|
|
||||||
QString certData = model->data(modelIndex, ClientManagementModel::ClientRoles::OpenVpnCertDataRole).toString();
|
|
||||||
|
|
||||||
if (certData.isEmpty() && !certId.isEmpty()) {
|
|
||||||
QString stdOut;
|
|
||||||
auto cbReadStdOut = [&](const QString &data, libssh::Client &) {
|
|
||||||
stdOut += data + "\n";
|
|
||||||
return ErrorCode::NoError;
|
|
||||||
};
|
|
||||||
|
|
||||||
const QString getOpenVpnCertData = QString("sudo docker exec -i $CONTAINER_NAME bash -c 'cat /opt/amnezia/openvpn/pki/issued/%1.crt'")
|
|
||||||
.arg(certId);
|
|
||||||
ServerController serverController(m_settings);
|
|
||||||
const QString script = serverController.replaceVars(getOpenVpnCertData, serverController.genVarsForScript(credentials, container));
|
|
||||||
ErrorCode error = serverController.runScript(credentials, script, cbReadStdOut);
|
|
||||||
certData = stdOut;
|
|
||||||
if (isErrorOccured(error)) {
|
|
||||||
set_busyIndicatorIsRunning(false);
|
|
||||||
emit uiLogic()->closePage();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
set_labelOpenVpnCertId(certId);
|
|
||||||
set_textAreaOpenVpnCertData(certData);
|
|
||||||
} else if (currentMainProtocol == Proto::WireGuard) {
|
|
||||||
set_textAreaWireGuardKeyData(model->data(modelIndex, ClientManagementModel::ClientRoles::WireGuardPublicKey).toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
set_pageContentVisible(true);
|
|
||||||
set_busyIndicatorIsRunning(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClientInfoLogic::onLineEditNameAliasEditingFinished()
|
|
||||||
{
|
|
||||||
set_busyIndicatorIsRunning(true);
|
|
||||||
|
|
||||||
auto model = qobject_cast<ClientManagementModel*>(uiLogic()->clientManagementModel());
|
|
||||||
const QModelIndex modelIndex = model->index(m_currentClientIndex);
|
|
||||||
model->setData(modelIndex, m_lineEditNameAliasText, ClientManagementModel::ClientRoles::NameRole);
|
|
||||||
|
|
||||||
const DockerContainer selectedContainer = m_settings->defaultContainer(uiLogic()->m_selectedServerIndex);
|
|
||||||
const ServerCredentials credentials = m_settings->serverCredentials(uiLogic()->m_selectedServerIndex);
|
|
||||||
const QVector<amnezia::Proto> protocols = ContainerProps::protocolsForContainer(selectedContainer);
|
|
||||||
if (!protocols.empty()) {
|
|
||||||
const Proto currentMainProtocol = protocols.front();
|
|
||||||
const QJsonObject clientsTable = model->getContent(currentMainProtocol);
|
|
||||||
ErrorCode error = setClientsList(credentials,
|
|
||||||
selectedContainer,
|
|
||||||
currentMainProtocol,
|
|
||||||
clientsTable);
|
|
||||||
isErrorOccured(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
set_busyIndicatorIsRunning(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClientInfoLogic::onRevokeOpenVpnCertificateClicked()
|
|
||||||
{
|
|
||||||
set_busyIndicatorIsRunning(true);
|
|
||||||
const DockerContainer container = m_settings->defaultContainer(uiLogic()->m_selectedServerIndex);
|
|
||||||
const ServerCredentials credentials = m_settings->serverCredentials(uiLogic()->m_selectedServerIndex);
|
|
||||||
|
|
||||||
auto model = qobject_cast<ClientManagementModel*>(uiLogic()->clientManagementModel());
|
|
||||||
const QModelIndex modelIndex = model->index(m_currentClientIndex);
|
|
||||||
const QString certId = model->data(modelIndex, ClientManagementModel::ClientRoles::OpenVpnCertIdRole).toString();
|
|
||||||
|
|
||||||
const QString getOpenVpnCertData = QString("sudo docker exec -i $CONTAINER_NAME bash -c '"
|
|
||||||
"cd /opt/amnezia/openvpn ;\\"
|
|
||||||
"easyrsa revoke %1 ;\\"
|
|
||||||
"easyrsa gen-crl ;\\"
|
|
||||||
"cp pki/crl.pem .'").arg(certId);
|
|
||||||
ServerController serverController(m_settings);
|
|
||||||
const QString script = serverController.replaceVars(getOpenVpnCertData,
|
|
||||||
serverController.genVarsForScript(credentials, container));
|
|
||||||
auto error = serverController.runScript(credentials, script);
|
|
||||||
if (isErrorOccured(error)) {
|
|
||||||
set_busyIndicatorIsRunning(false);
|
|
||||||
emit uiLogic()->goToPage(Page::ServerSettings);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
model->removeRows(m_currentClientIndex);
|
|
||||||
const QJsonObject clientsTable = model->getContent(Proto::OpenVpn);
|
|
||||||
error = setClientsList(credentials, container, Proto::OpenVpn, clientsTable);
|
|
||||||
if (isErrorOccured(error)) {
|
|
||||||
set_busyIndicatorIsRunning(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QJsonObject &containerConfig = m_settings->containerConfig(uiLogic()->m_selectedServerIndex, container);
|
|
||||||
error = serverController.startupContainerWorker(credentials, container, containerConfig);
|
|
||||||
if (isErrorOccured(error)) {
|
|
||||||
set_busyIndicatorIsRunning(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
set_busyIndicatorIsRunning(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClientInfoLogic::onRevokeWireGuardKeyClicked()
|
|
||||||
{
|
|
||||||
set_busyIndicatorIsRunning(true);
|
|
||||||
ErrorCode error;
|
|
||||||
const DockerContainer container = m_settings->defaultContainer(uiLogic()->m_selectedServerIndex);
|
|
||||||
const ServerCredentials credentials = m_settings->serverCredentials(uiLogic()->m_selectedServerIndex);
|
|
||||||
|
|
||||||
ServerController serverController(m_settings);
|
|
||||||
|
|
||||||
const QString wireGuardConfigFile = "opt/amnezia/wireguard/wg0.conf";
|
|
||||||
const QString wireguardConfigString = serverController.getTextFileFromContainer(container, credentials, wireGuardConfigFile, &error);
|
|
||||||
if (isErrorOccured(error)) {
|
|
||||||
set_busyIndicatorIsRunning(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto model = qobject_cast<ClientManagementModel*>(uiLogic()->clientManagementModel());
|
|
||||||
const QModelIndex modelIndex = model->index(m_currentClientIndex);
|
|
||||||
const QString key = model->data(modelIndex, ClientManagementModel::ClientRoles::WireGuardPublicKey).toString();
|
|
||||||
|
|
||||||
auto configSections = wireguardConfigString.split("[", Qt::SkipEmptyParts);
|
|
||||||
for (auto §ion : configSections) {
|
|
||||||
if (section.contains(key)) {
|
|
||||||
configSections.removeOne(section);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
QString newWireGuardConfig = configSections.join("[");
|
|
||||||
newWireGuardConfig.insert(0, "[");
|
|
||||||
error = serverController.uploadTextFileToContainer(container, credentials, newWireGuardConfig,
|
|
||||||
protocols::wireguard::serverConfigPath,
|
|
||||||
libssh::SftpOverwriteMode::SftpOverwriteExisting);
|
|
||||||
if (isErrorOccured(error)) {
|
|
||||||
set_busyIndicatorIsRunning(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
model->removeRows(m_currentClientIndex);
|
|
||||||
const QJsonObject clientsTable = model->getContent(Proto::WireGuard);
|
|
||||||
error = setClientsList(credentials, container, Proto::WireGuard, clientsTable);
|
|
||||||
if (isErrorOccured(error)) {
|
|
||||||
set_busyIndicatorIsRunning(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString script = "sudo docker exec -i $CONTAINER_NAME bash -c 'wg syncconf wg0 <(wg-quick strip /opt/amnezia/wireguard/wg0.conf)'";
|
|
||||||
error = serverController.runScript(credentials,
|
|
||||||
serverController.replaceVars(script, serverController.genVarsForScript(credentials, container)));
|
|
||||||
if (isErrorOccured(error)) {
|
|
||||||
set_busyIndicatorIsRunning(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
set_busyIndicatorIsRunning(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
ErrorCode ClientInfoLogic::setClientsList(const ServerCredentials &credentials, DockerContainer container, Proto mainProtocol, const QJsonObject &clietns)
|
|
||||||
{
|
|
||||||
const QString mainProtocolString = ProtocolProps::protoToString(mainProtocol);
|
|
||||||
const QString clientsTableFile = QString("opt/amnezia/%1/clientsTable").arg(mainProtocolString);
|
|
||||||
ServerController serverController(m_settings);
|
|
||||||
ErrorCode error = serverController.uploadTextFileToContainer(container, credentials, QJsonDocument(clietns).toJson(), clientsTableFile);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
#ifndef CLIENTINFOLOGIC_H
|
|
||||||
#define CLIENTINFOLOGIC_H
|
|
||||||
|
|
||||||
#include "PageLogicBase.h"
|
|
||||||
|
|
||||||
#include "core/defs.h"
|
|
||||||
#include "containers/containers_defs.h"
|
|
||||||
#include "protocols/protocols_defs.h"
|
|
||||||
|
|
||||||
class UiLogic;
|
|
||||||
|
|
||||||
class ClientInfoLogic : public PageLogicBase
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
AUTO_PROPERTY(QString, lineEditNameAliasText)
|
|
||||||
AUTO_PROPERTY(QString, labelOpenVpnCertId)
|
|
||||||
AUTO_PROPERTY(QString, textAreaOpenVpnCertData)
|
|
||||||
AUTO_PROPERTY(QString, labelCurrentVpnProtocolText)
|
|
||||||
AUTO_PROPERTY(QString, textAreaWireGuardKeyData)
|
|
||||||
AUTO_PROPERTY(bool, busyIndicatorIsRunning);
|
|
||||||
AUTO_PROPERTY(bool, pageContentVisible);
|
|
||||||
|
|
||||||
public:
|
|
||||||
ClientInfoLogic(UiLogic *uiLogic, QObject *parent = nullptr);
|
|
||||||
~ClientInfoLogic() = default;
|
|
||||||
|
|
||||||
void setCurrentClientId(int index);
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void onUpdatePage() override;
|
|
||||||
void onLineEditNameAliasEditingFinished();
|
|
||||||
void onRevokeOpenVpnCertificateClicked();
|
|
||||||
void onRevokeWireGuardKeyClicked();
|
|
||||||
|
|
||||||
private:
|
|
||||||
ErrorCode setClientsList(const ServerCredentials &credentials, DockerContainer container, Proto mainProtocol, const QJsonObject &clietns);
|
|
||||||
|
|
||||||
int m_currentClientIndex;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // CLIENTINFOLOGIC_H
|
|
||||||
|
|
@ -1,143 +0,0 @@
|
||||||
#include "ClientManagementLogic.h"
|
|
||||||
|
|
||||||
#include <QMessageBox>
|
|
||||||
|
|
||||||
#include "version.h"
|
|
||||||
#include "core/errorstrings.h"
|
|
||||||
#include "core/servercontroller.h"
|
|
||||||
#include "ui/pages_logic/ClientInfoLogic.h"
|
|
||||||
#include "ui/models/clientManagementModel.h"
|
|
||||||
#include "ui/uilogic.h"
|
|
||||||
|
|
||||||
ClientManagementLogic::ClientManagementLogic(UiLogic *logic, QObject *parent):
|
|
||||||
PageLogicBase(logic, parent)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClientManagementLogic::onUpdatePage()
|
|
||||||
{
|
|
||||||
set_busyIndicatorIsRunning(true);
|
|
||||||
|
|
||||||
qobject_cast<ClientManagementModel*>(uiLogic()->clientManagementModel())->clearData();
|
|
||||||
DockerContainer selectedContainer = m_settings->defaultContainer(uiLogic()->m_selectedServerIndex);
|
|
||||||
QString selectedContainerName = ContainerProps::containerHumanNames().value(selectedContainer);
|
|
||||||
set_labelCurrentVpnProtocolText(tr("Service: ") + selectedContainerName);
|
|
||||||
|
|
||||||
QJsonObject clients;
|
|
||||||
|
|
||||||
auto protocols = ContainerProps::protocolsForContainer(selectedContainer);
|
|
||||||
if (!protocols.empty()) {
|
|
||||||
m_currentMainProtocol = protocols.front();
|
|
||||||
|
|
||||||
const ServerCredentials credentials = m_settings->serverCredentials(uiLogic()->m_selectedServerIndex);
|
|
||||||
|
|
||||||
ErrorCode error = getClientsList(credentials, selectedContainer, m_currentMainProtocol, clients);
|
|
||||||
if (error != ErrorCode::NoError) {
|
|
||||||
QMessageBox::warning(nullptr, APPLICATION_NAME,
|
|
||||||
tr("An error occurred while getting the list of clients.") + "\n" + errorString(error));
|
|
||||||
set_busyIndicatorIsRunning(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
QVector<QVariant> clientsArray;
|
|
||||||
for (auto &clientId : clients.keys()) {
|
|
||||||
clientsArray.push_back(clients[clientId].toObject());
|
|
||||||
}
|
|
||||||
qobject_cast<ClientManagementModel*>(uiLogic()->clientManagementModel())->setContent(clientsArray);
|
|
||||||
|
|
||||||
set_busyIndicatorIsRunning(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClientManagementLogic::onClientItemClicked(int index)
|
|
||||||
{
|
|
||||||
uiLogic()->pageLogic<ClientInfoLogic>()->setCurrentClientId(index);
|
|
||||||
emit uiLogic()->goToClientInfoPage(m_currentMainProtocol);
|
|
||||||
}
|
|
||||||
|
|
||||||
ErrorCode ClientManagementLogic::getClientsList(const ServerCredentials &credentials, DockerContainer container, Proto mainProtocol, QJsonObject &clietns)
|
|
||||||
{
|
|
||||||
ErrorCode error = ErrorCode::NoError;
|
|
||||||
QString stdOut;
|
|
||||||
auto cbReadStdOut = [&](const QString &data, libssh::Client &) {
|
|
||||||
stdOut += data + "\n";
|
|
||||||
return ErrorCode::NoError;
|
|
||||||
};
|
|
||||||
|
|
||||||
const QString mainProtocolString = ProtocolProps::protoToString(mainProtocol);
|
|
||||||
|
|
||||||
ServerController serverController(m_settings);
|
|
||||||
|
|
||||||
const QString clientsTableFile = QString("/opt/amnezia/%1/clientsTable").arg(mainProtocolString);
|
|
||||||
const QByteArray clientsTableString = serverController.getTextFileFromContainer(container, credentials, clientsTableFile, &error);
|
|
||||||
if (error != ErrorCode::NoError) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
QJsonObject clientsTable = QJsonDocument::fromJson(clientsTableString).object();
|
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
if (mainProtocol == Proto::OpenVpn) {
|
|
||||||
const QString getOpenVpnClientsList = "sudo docker exec -i $CONTAINER_NAME bash -c 'ls /opt/amnezia/openvpn/pki/issued'";
|
|
||||||
QString script = serverController.replaceVars(getOpenVpnClientsList, serverController.genVarsForScript(credentials, container));
|
|
||||||
error = serverController.runScript(credentials, script, cbReadStdOut);
|
|
||||||
if (error != ErrorCode::NoError) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!stdOut.isEmpty()) {
|
|
||||||
QStringList certsIds = stdOut.split("\n", Qt::SkipEmptyParts);
|
|
||||||
certsIds.removeAll("AmneziaReq.crt");
|
|
||||||
|
|
||||||
for (auto &openvpnCertId : certsIds) {
|
|
||||||
openvpnCertId.replace(".crt", "");
|
|
||||||
if (!clientsTable.contains(openvpnCertId)) {
|
|
||||||
|
|
||||||
QJsonObject client;
|
|
||||||
client["openvpnCertId"] = openvpnCertId;
|
|
||||||
client["clientName"] = QString("Client %1").arg(count);
|
|
||||||
client["openvpnCertData"] = "";
|
|
||||||
clientsTable[openvpnCertId] = client;
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (mainProtocol == Proto::WireGuard) {
|
|
||||||
const QString wireGuardConfigFile = "opt/amnezia/wireguard/wg0.conf";
|
|
||||||
const QString wireguardConfigString = serverController.getTextFileFromContainer(container, credentials, wireGuardConfigFile, &error);
|
|
||||||
if (error != ErrorCode::NoError) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto configLines = wireguardConfigString.split("\n", Qt::SkipEmptyParts);
|
|
||||||
QStringList wireguardKeys;
|
|
||||||
for (const auto &line : configLines) {
|
|
||||||
auto configPair = line.split(" = ", Qt::SkipEmptyParts);
|
|
||||||
if (configPair.front() == "PublicKey") {
|
|
||||||
wireguardKeys.push_back(configPair.back());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto &wireguardKey : wireguardKeys) {
|
|
||||||
if (!clientsTable.contains(wireguardKey)) {
|
|
||||||
QJsonObject client;
|
|
||||||
client["clientName"] = QString("Client %1").arg(count);
|
|
||||||
client["wireguardPublicKey"] = wireguardKey;
|
|
||||||
clientsTable[wireguardKey] = client;
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const QByteArray newClientsTableString = QJsonDocument(clientsTable).toJson();
|
|
||||||
if (clientsTableString != newClientsTableString) {
|
|
||||||
error = serverController.uploadTextFileToContainer(container, credentials, newClientsTableString, clientsTableFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error != ErrorCode::NoError) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
clietns = clientsTable;
|
|
||||||
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
#ifndef CLIENTMANAGMENTLOGIC_H
|
|
||||||
#define CLIENTMANAGMENTLOGIC_H
|
|
||||||
|
|
||||||
#include "PageLogicBase.h"
|
|
||||||
|
|
||||||
#include "core/defs.h"
|
|
||||||
#include "containers/containers_defs.h"
|
|
||||||
#include "protocols/protocols_defs.h"
|
|
||||||
|
|
||||||
class UiLogic;
|
|
||||||
|
|
||||||
class ClientManagementLogic : public PageLogicBase
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
AUTO_PROPERTY(QString, labelCurrentVpnProtocolText)
|
|
||||||
AUTO_PROPERTY(bool, busyIndicatorIsRunning);
|
|
||||||
|
|
||||||
public:
|
|
||||||
ClientManagementLogic(UiLogic *uiLogic, QObject *parent = nullptr);
|
|
||||||
~ClientManagementLogic() = default;
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void onUpdatePage() override;
|
|
||||||
void onClientItemClicked(int index);
|
|
||||||
|
|
||||||
private:
|
|
||||||
ErrorCode getClientsList(const ServerCredentials &credentials, DockerContainer container, Proto mainProtocol, QJsonObject &clietns);
|
|
||||||
|
|
||||||
amnezia::Proto m_currentMainProtocol;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // CLIENTMANAGMENTLOGIC_H
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
#include "GeneralSettingsLogic.h"
|
|
||||||
#include "ShareConnectionLogic.h"
|
|
||||||
|
|
||||||
#include "../models/protocols_model.h"
|
|
||||||
#include "../uilogic.h"
|
|
||||||
|
|
||||||
GeneralSettingsLogic::GeneralSettingsLogic(UiLogic *logic, QObject *parent) : PageLogicBase(logic, parent)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void GeneralSettingsLogic::onUpdatePage()
|
|
||||||
{
|
|
||||||
uiLogic()->m_selectedServerIndex = m_settings->defaultServerIndex();
|
|
||||||
set_existsAnyServer(m_settings->serversCount() > 0);
|
|
||||||
uiLogic()->m_selectedDockerContainer = m_settings->defaultContainer(m_settings->defaultServerIndex());
|
|
||||||
|
|
||||||
set_pushButtonGeneralSettingsShareConnectionEnable(m_settings->haveAuthData(m_settings->defaultServerIndex()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void GeneralSettingsLogic::onPushButtonGeneralSettingsServerSettingsClicked()
|
|
||||||
{
|
|
||||||
uiLogic()->m_selectedServerIndex = m_settings->defaultServerIndex();
|
|
||||||
uiLogic()->m_selectedDockerContainer = m_settings->defaultContainer(m_settings->defaultServerIndex());
|
|
||||||
|
|
||||||
emit uiLogic()->goToPage(Page::ServerSettings);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GeneralSettingsLogic::onPushButtonGeneralSettingsShareConnectionClicked()
|
|
||||||
{
|
|
||||||
uiLogic()->m_selectedServerIndex = m_settings->defaultServerIndex();
|
|
||||||
uiLogic()->m_selectedDockerContainer = m_settings->defaultContainer(uiLogic()->m_selectedServerIndex);
|
|
||||||
|
|
||||||
// qobject_cast<ProtocolsModel
|
|
||||||
// *>(uiLogic()->protocolsModel())->setSelectedServerIndex(uiLogic()->m_selectedServerIndex); qobject_cast<ProtocolsModel
|
|
||||||
// *>(uiLogic()->protocolsModel())->setSelectedDockerContainer(uiLogic()->m_selectedDockerContainer);
|
|
||||||
|
|
||||||
uiLogic()->pageLogic<ShareConnectionLogic>()->updateSharingPage(uiLogic()->m_selectedServerIndex,
|
|
||||||
uiLogic()->m_selectedDockerContainer);
|
|
||||||
emit uiLogic()->goToPage(Page::ShareConnection);
|
|
||||||
}
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
#ifndef GENERAL_SETTINGS_LOGIC_H
|
|
||||||
#define GENERAL_SETTINGS_LOGIC_H
|
|
||||||
|
|
||||||
#include "PageLogicBase.h"
|
|
||||||
|
|
||||||
class UiLogic;
|
|
||||||
|
|
||||||
class GeneralSettingsLogic : public PageLogicBase
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
AUTO_PROPERTY(bool, pushButtonGeneralSettingsShareConnectionEnable)
|
|
||||||
AUTO_PROPERTY(bool, existsAnyServer)
|
|
||||||
|
|
||||||
public:
|
|
||||||
Q_INVOKABLE void onUpdatePage() override;
|
|
||||||
Q_INVOKABLE void onPushButtonGeneralSettingsServerSettingsClicked();
|
|
||||||
Q_INVOKABLE void onPushButtonGeneralSettingsShareConnectionClicked();
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit GeneralSettingsLogic(UiLogic *uiLogic, QObject *parent = nullptr);
|
|
||||||
~GeneralSettingsLogic() = default;
|
|
||||||
|
|
||||||
};
|
|
||||||
#endif // GENERAL_SETTINGS_LOGIC_H
|
|
||||||
|
|
@ -1,52 +0,0 @@
|
||||||
#include "NetworkSettingsLogic.h"
|
|
||||||
|
|
||||||
#include "version.h"
|
|
||||||
#include "utilities.h"
|
|
||||||
#include "settings.h"
|
|
||||||
|
|
||||||
NetworkSettingsLogic::NetworkSettingsLogic(UiLogic *logic, QObject *parent):
|
|
||||||
PageLogicBase(logic, parent),
|
|
||||||
m_checkBoxUseAmneziaDnsChecked{false},
|
|
||||||
m_ipAddressRegex{Utils::ipAddressRegExp()}
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void NetworkSettingsLogic::onUpdatePage()
|
|
||||||
{
|
|
||||||
set_checkBoxUseAmneziaDnsChecked(m_settings->useAmneziaDns());
|
|
||||||
|
|
||||||
set_lineEditDns1Text(m_settings->primaryDns());
|
|
||||||
set_lineEditDns2Text(m_settings->secondaryDns());
|
|
||||||
}
|
|
||||||
|
|
||||||
void NetworkSettingsLogic::onLineEditDns1EditFinished(const QString &text)
|
|
||||||
{
|
|
||||||
if (ipAddressRegex().match(text).hasMatch()) {
|
|
||||||
m_settings->setPrimaryDns(text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void NetworkSettingsLogic::onLineEditDns2EditFinished(const QString &text)
|
|
||||||
{
|
|
||||||
if (ipAddressRegex().match(text).hasMatch()) {
|
|
||||||
m_settings->setSecondaryDns(text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void NetworkSettingsLogic::onPushButtonResetDns1Clicked()
|
|
||||||
{
|
|
||||||
m_settings->setPrimaryDns(m_settings->cloudFlareNs1);
|
|
||||||
onUpdatePage();
|
|
||||||
}
|
|
||||||
|
|
||||||
void NetworkSettingsLogic::onPushButtonResetDns2Clicked()
|
|
||||||
{
|
|
||||||
m_settings->setSecondaryDns(m_settings->cloudFlareNs2);
|
|
||||||
onUpdatePage();
|
|
||||||
}
|
|
||||||
|
|
||||||
void NetworkSettingsLogic::onCheckBoxUseAmneziaDnsToggled(bool checked)
|
|
||||||
{
|
|
||||||
m_settings->setUseAmneziaDns(checked);
|
|
||||||
}
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
#ifndef NETWORK_SETTINGS_LOGIC_H
|
|
||||||
#define NETWORK_SETTINGS_LOGIC_H
|
|
||||||
|
|
||||||
#include "PageLogicBase.h"
|
|
||||||
|
|
||||||
#include <QRegularExpression>
|
|
||||||
|
|
||||||
class UiLogic;
|
|
||||||
|
|
||||||
class NetworkSettingsLogic : public PageLogicBase
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
AUTO_PROPERTY(bool, checkBoxUseAmneziaDnsChecked)
|
|
||||||
|
|
||||||
AUTO_PROPERTY(QString, lineEditDns1Text)
|
|
||||||
AUTO_PROPERTY(QString, lineEditDns2Text)
|
|
||||||
READONLY_PROPERTY(QRegularExpression, ipAddressRegex)
|
|
||||||
|
|
||||||
public:
|
|
||||||
Q_INVOKABLE void onUpdatePage() override;
|
|
||||||
|
|
||||||
Q_INVOKABLE void onLineEditDns1EditFinished(const QString& text);
|
|
||||||
Q_INVOKABLE void onLineEditDns2EditFinished(const QString& text);
|
|
||||||
Q_INVOKABLE void onPushButtonResetDns1Clicked();
|
|
||||||
Q_INVOKABLE void onPushButtonResetDns2Clicked();
|
|
||||||
|
|
||||||
Q_INVOKABLE void onCheckBoxUseAmneziaDnsToggled(bool checked);
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit NetworkSettingsLogic(UiLogic *uiLogic, QObject *parent = nullptr);
|
|
||||||
~NetworkSettingsLogic() = default;
|
|
||||||
|
|
||||||
};
|
|
||||||
#endif // NETWORK_SETTINGS_LOGIC_H
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
#include "NewServerProtocolsLogic.h"
|
|
||||||
#include "../uilogic.h"
|
|
||||||
|
|
||||||
NewServerProtocolsLogic::NewServerProtocolsLogic(UiLogic *logic, QObject *parent):
|
|
||||||
PageLogicBase(logic, parent),
|
|
||||||
m_progressBarConnectionMinimum{0},
|
|
||||||
m_progressBarConnectionMaximum{100}
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void NewServerProtocolsLogic::onUpdatePage()
|
|
||||||
{
|
|
||||||
set_progressBarConnectionMinimum(0);
|
|
||||||
set_progressBarConnectionMaximum(300);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NewServerProtocolsLogic::onPushButtonConfigureClicked(DockerContainer c, int port, TransportProto tp)
|
|
||||||
{
|
|
||||||
Proto mainProto = ContainerProps::defaultProtocol(c);
|
|
||||||
|
|
||||||
QJsonObject config {
|
|
||||||
{ config_key::container, ContainerProps::containerToString(c) },
|
|
||||||
{ ProtocolProps::protoToString(mainProto), QJsonObject {
|
|
||||||
{ config_key::port, QString::number(port) },
|
|
||||||
{ config_key::transport_proto, ProtocolProps::transportProtoToString(tp, mainProto) }}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
QPair<DockerContainer, QJsonObject> container(c, config);
|
|
||||||
|
|
||||||
uiLogic()->installServer(container);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
#ifndef NEW_SERVER_PROTOCOLS_LOGIC_H
|
|
||||||
#define NEW_SERVER_PROTOCOLS_LOGIC_H
|
|
||||||
|
|
||||||
#include "PageLogicBase.h"
|
|
||||||
#include "containers/containers_defs.h"
|
|
||||||
|
|
||||||
class UiLogic;
|
|
||||||
|
|
||||||
class NewServerProtocolsLogic : public PageLogicBase
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
AUTO_PROPERTY(double, progressBarConnectionMinimum)
|
|
||||||
AUTO_PROPERTY(double, progressBarConnectionMaximum)
|
|
||||||
|
|
||||||
public:
|
|
||||||
Q_INVOKABLE void onUpdatePage() override;
|
|
||||||
Q_INVOKABLE void onPushButtonConfigureClicked(DockerContainer c, int port, TransportProto tp);
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit NewServerProtocolsLogic(UiLogic *uiLogic, QObject *parent = nullptr);
|
|
||||||
~NewServerProtocolsLogic() = default;
|
|
||||||
|
|
||||||
};
|
|
||||||
#endif // NEW_SERVER_PROTOCOLS_LOGIC_H
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
#include "PageLogicBase.h"
|
|
||||||
|
|
||||||
#include "ui/uilogic.h"
|
|
||||||
#include "settings.h"
|
|
||||||
#include "configurators/vpn_configurator.h"
|
|
||||||
|
|
||||||
PageLogicBase::PageLogicBase(UiLogic *logic, QObject *parent):
|
|
||||||
QObject(parent),
|
|
||||||
m_pageEnabled{true},
|
|
||||||
m_uiLogic(logic)
|
|
||||||
{
|
|
||||||
m_settings = logic->m_settings;
|
|
||||||
m_configurator = logic->m_configurator;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
#ifndef PAGE_LOGIC_BASE_H
|
|
||||||
#define PAGE_LOGIC_BASE_H
|
|
||||||
|
|
||||||
#include "../pages.h"
|
|
||||||
#include "../property_helper.h"
|
|
||||||
|
|
||||||
using namespace PageEnumNS;
|
|
||||||
|
|
||||||
class UiLogic;
|
|
||||||
class Settings;
|
|
||||||
class VpnConfigurator;
|
|
||||||
class ServerController;
|
|
||||||
|
|
||||||
class PageLogicBase : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
AUTO_PROPERTY(bool, pageEnabled)
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit PageLogicBase(UiLogic *uiLogic, QObject *parent = nullptr);
|
|
||||||
~PageLogicBase() = default;
|
|
||||||
|
|
||||||
Q_INVOKABLE virtual void onUpdatePage() {}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
UiLogic *m_uiLogic;
|
|
||||||
UiLogic *uiLogic() const { return m_uiLogic; }
|
|
||||||
|
|
||||||
std::shared_ptr<Settings> m_settings;
|
|
||||||
std::shared_ptr<VpnConfigurator> m_configurator;
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void updatePage();
|
|
||||||
};
|
|
||||||
#endif // PAGE_LOGIC_BASE_H
|
|
||||||
|
|
@ -1,125 +0,0 @@
|
||||||
#include "QrDecoderLogic.h"
|
|
||||||
|
|
||||||
#include "ui/uilogic.h"
|
|
||||||
#include "ui/pages_logic/StartPageLogic.h"
|
|
||||||
|
|
||||||
#ifdef Q_OS_ANDROID
|
|
||||||
#include <QJniEnvironment>
|
|
||||||
#include <QJniObject>
|
|
||||||
#include "../../platforms/android/androidutils.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
using namespace amnezia;
|
|
||||||
using namespace PageEnumNS;
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
QrDecoderLogic* mInstance = nullptr;
|
|
||||||
constexpr auto CLASSNAME = "org.amnezia.vpn.qt.CameraActivity";
|
|
||||||
}
|
|
||||||
|
|
||||||
QrDecoderLogic::QrDecoderLogic(UiLogic *logic, QObject *parent):
|
|
||||||
PageLogicBase(logic, parent)
|
|
||||||
{
|
|
||||||
mInstance = this;
|
|
||||||
|
|
||||||
#if (defined(Q_OS_ANDROID))
|
|
||||||
AndroidUtils::runOnAndroidThreadAsync([]() {
|
|
||||||
JNINativeMethod methods[]{
|
|
||||||
{"passDataToDecoder", "(Ljava/lang/String;)V", reinterpret_cast<void*>(onNewDataChunk)},
|
|
||||||
};
|
|
||||||
|
|
||||||
QJniObject javaClass(CLASSNAME);
|
|
||||||
QJniEnvironment env;
|
|
||||||
jclass objectClass = env->GetObjectClass(javaClass.object<jobject>());
|
|
||||||
env->RegisterNatives(objectClass, methods, sizeof(methods) / sizeof(methods[0]));
|
|
||||||
env->DeleteLocalRef(objectClass);
|
|
||||||
});
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void QrDecoderLogic::stopDecodingQr()
|
|
||||||
{
|
|
||||||
#if (defined(Q_OS_ANDROID))
|
|
||||||
QJniObject::callStaticMethod<void>(CLASSNAME, "stopQrCodeReader", "()V");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
emit stopDecode();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef Q_OS_ANDROID
|
|
||||||
void QrDecoderLogic::onNewDataChunk(JNIEnv *env, jobject thiz, jstring data)
|
|
||||||
{
|
|
||||||
Q_UNUSED(thiz);
|
|
||||||
const char* buffer = env->GetStringUTFChars(data, nullptr);
|
|
||||||
if (!buffer) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString parcelBody(buffer);
|
|
||||||
env->ReleaseStringUTFChars(data, buffer);
|
|
||||||
|
|
||||||
if (mInstance != nullptr) {
|
|
||||||
if (!mInstance->m_detectingEnabled) {
|
|
||||||
mInstance->onUpdatePage();
|
|
||||||
}
|
|
||||||
mInstance->onDetectedQrCode(parcelBody);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void QrDecoderLogic::onUpdatePage()
|
|
||||||
{
|
|
||||||
m_chunks.clear();
|
|
||||||
set_detectingEnabled(true);
|
|
||||||
set_totalChunksCount(0);
|
|
||||||
set_receivedChunksCount(0);
|
|
||||||
emit startDecode();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QrDecoderLogic::onDetectedQrCode(const QString &code)
|
|
||||||
{
|
|
||||||
//qDebug() << code;
|
|
||||||
if (!detectingEnabled()) return;
|
|
||||||
|
|
||||||
// check if chunk received
|
|
||||||
QByteArray ba = QByteArray::fromBase64(code.toUtf8(), QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
|
|
||||||
QDataStream s(&ba, QIODevice::ReadOnly);
|
|
||||||
qint16 magic; s >> magic;
|
|
||||||
|
|
||||||
if (magic == amnezia::qrMagicCode) {
|
|
||||||
quint8 chunksCount; s >> chunksCount;
|
|
||||||
if (totalChunksCount() != chunksCount) {
|
|
||||||
m_chunks.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
set_totalChunksCount(chunksCount);
|
|
||||||
|
|
||||||
quint8 chunkId; s >> chunkId;
|
|
||||||
s >> m_chunks[chunkId];
|
|
||||||
set_receivedChunksCount(m_chunks.size());
|
|
||||||
|
|
||||||
if (m_chunks.size() == totalChunksCount()) {
|
|
||||||
QByteArray data;
|
|
||||||
|
|
||||||
for (int i = 0; i < totalChunksCount(); ++i) {
|
|
||||||
data.append(m_chunks.value(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ok = uiLogic()->pageLogic<StartPageLogic>()->importConnectionFromQr(data);
|
|
||||||
if (ok) {
|
|
||||||
set_detectingEnabled(false);
|
|
||||||
stopDecodingQr();
|
|
||||||
} else {
|
|
||||||
m_chunks.clear();
|
|
||||||
set_totalChunksCount(0);
|
|
||||||
set_receivedChunksCount(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
bool ok = uiLogic()->pageLogic<StartPageLogic>()->importConnectionFromQr(ba);
|
|
||||||
if (ok) {
|
|
||||||
set_detectingEnabled(false);
|
|
||||||
stopDecodingQr();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
#ifndef QR_DECODER_LOGIC_H
|
|
||||||
#define QR_DECODER_LOGIC_H
|
|
||||||
|
|
||||||
#include "PageLogicBase.h"
|
|
||||||
|
|
||||||
#ifdef Q_OS_ANDROID
|
|
||||||
#include "jni.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class UiLogic;
|
|
||||||
|
|
||||||
class QrDecoderLogic : public PageLogicBase
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
AUTO_PROPERTY(bool, detectingEnabled)
|
|
||||||
AUTO_PROPERTY(int, totalChunksCount)
|
|
||||||
AUTO_PROPERTY(int, receivedChunksCount)
|
|
||||||
|
|
||||||
public:
|
|
||||||
Q_INVOKABLE void onUpdatePage() override;
|
|
||||||
Q_INVOKABLE void onDetectedQrCode(const QString &code);
|
|
||||||
|
|
||||||
#ifdef Q_OS_ANDROID
|
|
||||||
static void onNewDataChunk(JNIEnv *env, jobject thiz, jstring data);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit QrDecoderLogic(UiLogic *uiLogic, QObject *parent = nullptr);
|
|
||||||
~QrDecoderLogic() = default;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void stopDecodingQr();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void startDecode();
|
|
||||||
void stopDecode();
|
|
||||||
|
|
||||||
private:
|
|
||||||
QMap<int, QByteArray> m_chunks;
|
|
||||||
};
|
|
||||||
#endif // QR_DECODER_LOGIC_H
|
|
||||||
|
|
@ -1,187 +0,0 @@
|
||||||
#include "ServerConfiguringProgressLogic.h"
|
|
||||||
#include "version.h"
|
|
||||||
#include "core/errorstrings.h"
|
|
||||||
#include <QTimer>
|
|
||||||
#include <QEventLoop>
|
|
||||||
|
|
||||||
#include "core/servercontroller.h"
|
|
||||||
|
|
||||||
ServerConfiguringProgressLogic::ServerConfiguringProgressLogic(UiLogic *logic, QObject *parent):
|
|
||||||
PageLogicBase(logic, parent),
|
|
||||||
m_progressBarValue{0},
|
|
||||||
m_labelWaitInfoVisible{true},
|
|
||||||
m_labelWaitInfoText{tr("Please wait, configuring process may take up to 5 minutes")},
|
|
||||||
m_progressBarVisible{true},
|
|
||||||
m_progressBarMaximum{100},
|
|
||||||
m_progressBarTextVisible{true},
|
|
||||||
m_progressBarText{tr("Configuring...")},
|
|
||||||
m_labelServerBusyVisible{false},
|
|
||||||
m_labelServerBusyText{""}
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerConfiguringProgressLogic::onUpdatePage()
|
|
||||||
{
|
|
||||||
set_progressBarValue(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ErrorCode ServerConfiguringProgressLogic::doInstallAction(const std::function<ErrorCode()> &action)
|
|
||||||
{
|
|
||||||
PageFunc page;
|
|
||||||
page.setEnabledFunc = [this] (bool enabled) -> void {
|
|
||||||
set_pageEnabled(enabled);
|
|
||||||
};
|
|
||||||
ButtonFunc noButton;
|
|
||||||
LabelFunc noWaitInfo;
|
|
||||||
ProgressFunc progress;
|
|
||||||
progress.setVisibleFunc = [this] (bool visible) -> void {
|
|
||||||
set_progressBarVisible(visible);
|
|
||||||
};
|
|
||||||
|
|
||||||
progress.setValueFunc = [this] (int value) -> void {
|
|
||||||
set_progressBarValue(value);
|
|
||||||
};
|
|
||||||
progress.getValueFunc = [this] (void) -> int {
|
|
||||||
return progressBarValue();
|
|
||||||
};
|
|
||||||
progress.getMaximumFunc = [this] (void) -> int {
|
|
||||||
return progressBarMaximum();
|
|
||||||
};
|
|
||||||
|
|
||||||
LabelFunc busyInfo;
|
|
||||||
busyInfo.setTextFunc = [this] (const QString& text) -> void {
|
|
||||||
set_labelServerBusyText(text);
|
|
||||||
};
|
|
||||||
busyInfo.setVisibleFunc = [this] (bool visible) -> void {
|
|
||||||
set_labelServerBusyVisible(visible);
|
|
||||||
};
|
|
||||||
|
|
||||||
ButtonFunc cancelButton;
|
|
||||||
cancelButton.setVisibleFunc = [this] (bool visible) -> void {
|
|
||||||
set_pushButtonCancelVisible(visible);
|
|
||||||
};
|
|
||||||
|
|
||||||
return doInstallAction(action, page, progress, noButton, noWaitInfo, busyInfo, cancelButton);
|
|
||||||
}
|
|
||||||
|
|
||||||
ErrorCode ServerConfiguringProgressLogic::doInstallAction(const std::function<ErrorCode()> &action,
|
|
||||||
const PageFunc &page,
|
|
||||||
const ProgressFunc &progress,
|
|
||||||
const ButtonFunc &saveButton,
|
|
||||||
const LabelFunc &waitInfo,
|
|
||||||
const LabelFunc &serverBusyInfo,
|
|
||||||
const ButtonFunc &cancelButton)
|
|
||||||
{
|
|
||||||
progress.setVisibleFunc(true);
|
|
||||||
if (page.setEnabledFunc) {
|
|
||||||
page.setEnabledFunc(false);
|
|
||||||
}
|
|
||||||
if (saveButton.setVisibleFunc) {
|
|
||||||
saveButton.setVisibleFunc(false);
|
|
||||||
}
|
|
||||||
if (waitInfo.setVisibleFunc) {
|
|
||||||
waitInfo.setVisibleFunc(true);
|
|
||||||
}
|
|
||||||
if (waitInfo.setTextFunc) {
|
|
||||||
waitInfo.setTextFunc(tr("Please wait, configuring process may take up to 5 minutes"));
|
|
||||||
}
|
|
||||||
|
|
||||||
QTimer timer;
|
|
||||||
connect(&timer, &QTimer::timeout, [progress](){
|
|
||||||
progress.setValueFunc(progress.getValueFunc() + 1);
|
|
||||||
});
|
|
||||||
|
|
||||||
progress.setValueFunc(0);
|
|
||||||
timer.start(1000);
|
|
||||||
|
|
||||||
ServerController serverController(m_settings);
|
|
||||||
|
|
||||||
QMetaObject::Connection cancelDoInstallActionConnection;
|
|
||||||
if (cancelButton.setVisibleFunc) {
|
|
||||||
cancelDoInstallActionConnection = connect(this, &ServerConfiguringProgressLogic::cancelDoInstallAction,
|
|
||||||
&serverController, &ServerController::setCancelInstallation);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QMetaObject::Connection serverBusyConnection;
|
|
||||||
if (serverBusyInfo.setVisibleFunc && serverBusyInfo.setTextFunc) {
|
|
||||||
auto onServerIsBusy = [&serverBusyInfo, &timer, &cancelButton](const bool isBusy) {
|
|
||||||
isBusy ? timer.stop() : timer.start(1000);
|
|
||||||
serverBusyInfo.setVisibleFunc(isBusy);
|
|
||||||
serverBusyInfo.setTextFunc(isBusy ? "Amnesia has detected that your server is currently "
|
|
||||||
"busy installing other software. Amnesia installation "
|
|
||||||
"will pause until the server finishes installing other software"
|
|
||||||
: "");
|
|
||||||
if (cancelButton.setVisibleFunc) {
|
|
||||||
cancelButton.setVisibleFunc(isBusy ? true : false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
serverBusyConnection = connect(&serverController, &ServerController::serverIsBusy, this, onServerIsBusy);
|
|
||||||
}
|
|
||||||
|
|
||||||
ErrorCode e = action();
|
|
||||||
qDebug() << "doInstallAction finished with code" << e;
|
|
||||||
if (cancelButton.setVisibleFunc) {
|
|
||||||
disconnect(cancelDoInstallActionConnection);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (serverBusyInfo.setVisibleFunc && serverBusyInfo.setTextFunc) {
|
|
||||||
disconnect(serverBusyConnection);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e) {
|
|
||||||
if (page.setEnabledFunc) {
|
|
||||||
page.setEnabledFunc(true);
|
|
||||||
}
|
|
||||||
if (saveButton.setVisibleFunc) {
|
|
||||||
saveButton.setVisibleFunc(true);
|
|
||||||
}
|
|
||||||
if (waitInfo.setVisibleFunc) {
|
|
||||||
waitInfo.setVisibleFunc(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
progress.setVisibleFunc(false);
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
// just ui progressbar tweak
|
|
||||||
timer.stop();
|
|
||||||
|
|
||||||
int remainingVal = progress.getMaximumFunc() - progress.getValueFunc();
|
|
||||||
|
|
||||||
if (remainingVal > 0) {
|
|
||||||
QTimer timer1;
|
|
||||||
QEventLoop loop1;
|
|
||||||
|
|
||||||
connect(&timer1, &QTimer::timeout, [&](){
|
|
||||||
progress.setValueFunc(progress.getValueFunc() + 1);
|
|
||||||
if (progress.getValueFunc() >= progress.getMaximumFunc()) {
|
|
||||||
loop1.quit();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
timer1.start(5);
|
|
||||||
loop1.exec();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
progress.setVisibleFunc(false);
|
|
||||||
if (saveButton.setVisibleFunc) {
|
|
||||||
saveButton.setVisibleFunc(true);
|
|
||||||
}
|
|
||||||
if (page.setEnabledFunc) {
|
|
||||||
page.setEnabledFunc(true);
|
|
||||||
}
|
|
||||||
if (waitInfo.setTextFunc) {
|
|
||||||
waitInfo.setTextFunc(tr("Operation finished"));
|
|
||||||
}
|
|
||||||
return ErrorCode::NoError;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerConfiguringProgressLogic::onPushButtonCancelClicked()
|
|
||||||
{
|
|
||||||
emit cancelDoInstallAction(true);
|
|
||||||
}
|
|
||||||
|
|
@ -1,73 +0,0 @@
|
||||||
#ifndef SERVER_CONFIGURING_PROGRESS_LOGIC_H
|
|
||||||
#define SERVER_CONFIGURING_PROGRESS_LOGIC_H
|
|
||||||
|
|
||||||
#include <functional>
|
|
||||||
#include "PageLogicBase.h"
|
|
||||||
#include "core/defs.h"
|
|
||||||
|
|
||||||
using namespace amnezia;
|
|
||||||
|
|
||||||
class UiLogic;
|
|
||||||
|
|
||||||
class ServerConfiguringProgressLogic : public PageLogicBase
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
AUTO_PROPERTY(double, progressBarValue)
|
|
||||||
AUTO_PROPERTY(bool, labelWaitInfoVisible)
|
|
||||||
AUTO_PROPERTY(QString, labelWaitInfoText)
|
|
||||||
AUTO_PROPERTY(bool, progressBarVisible)
|
|
||||||
AUTO_PROPERTY(int, progressBarMaximum)
|
|
||||||
AUTO_PROPERTY(bool, progressBarTextVisible)
|
|
||||||
AUTO_PROPERTY(QString, progressBarText)
|
|
||||||
AUTO_PROPERTY(bool, labelServerBusyVisible)
|
|
||||||
AUTO_PROPERTY(QString, labelServerBusyText)
|
|
||||||
AUTO_PROPERTY(bool, pushButtonCancelVisible)
|
|
||||||
|
|
||||||
public:
|
|
||||||
Q_INVOKABLE void onPushButtonCancelClicked();
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct ProgressFunc {
|
|
||||||
std::function<void(bool)> setVisibleFunc;
|
|
||||||
std::function<void(int)> setValueFunc;
|
|
||||||
std::function<int(void)> getValueFunc;
|
|
||||||
std::function<int(void)> getMaximumFunc;
|
|
||||||
std::function<void(bool)> setTextVisibleFunc;
|
|
||||||
std::function<void(const QString&)> setTextFunc;
|
|
||||||
};
|
|
||||||
struct PageFunc {
|
|
||||||
std::function<void(bool)> setEnabledFunc;
|
|
||||||
};
|
|
||||||
struct ButtonFunc {
|
|
||||||
std::function<void(bool)> setVisibleFunc;
|
|
||||||
};
|
|
||||||
struct LabelFunc {
|
|
||||||
std::function<void(bool)> setVisibleFunc;
|
|
||||||
std::function<void(const QString&)> setTextFunc;
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit ServerConfiguringProgressLogic(UiLogic *uiLogic, QObject *parent = nullptr);
|
|
||||||
~ServerConfiguringProgressLogic() = default;
|
|
||||||
|
|
||||||
friend class OpenVpnLogic;
|
|
||||||
friend class ShadowSocksLogic;
|
|
||||||
friend class CloakLogic;
|
|
||||||
friend class UiLogic;
|
|
||||||
|
|
||||||
void onUpdatePage() override;
|
|
||||||
ErrorCode doInstallAction(const std::function<ErrorCode()> &action);
|
|
||||||
ErrorCode doInstallAction(const std::function<ErrorCode()> &action,
|
|
||||||
const PageFunc &page,
|
|
||||||
const ProgressFunc &progress,
|
|
||||||
const ButtonFunc &saveButton,
|
|
||||||
const LabelFunc &waitInfo,
|
|
||||||
const LabelFunc &serverBusyInfo,
|
|
||||||
const ButtonFunc &cancelButton);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void cancelDoInstallAction(const bool cancel);
|
|
||||||
|
|
||||||
};
|
|
||||||
#endif // SERVER_CONFIGURING_PROGRESS_LOGIC_H
|
|
||||||
|
|
@ -1,128 +0,0 @@
|
||||||
#include "ServerContainersLogic.h"
|
|
||||||
#include "ServerConfiguringProgressLogic.h"
|
|
||||||
#include "ShareConnectionLogic.h"
|
|
||||||
|
|
||||||
#include <QApplication>
|
|
||||||
|
|
||||||
#include "protocols/PageProtocolLogicBase.h"
|
|
||||||
|
|
||||||
#include "core/servercontroller.h"
|
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
#include "../pages_logic/VpnLogic.h"
|
|
||||||
#include "../uilogic.h"
|
|
||||||
#include "core/errorstrings.h"
|
|
||||||
#include "vpnconnection.h"
|
|
||||||
|
|
||||||
ServerContainersLogic::ServerContainersLogic(UiLogic *logic, QObject *parent) : PageLogicBase(logic, parent)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerContainersLogic::onUpdatePage()
|
|
||||||
{
|
|
||||||
// ContainersModel *c_model = qobject_cast<ContainersModel *>(uiLogic()->containersModel());
|
|
||||||
// c_model->setSelectedServerIndex(uiLogic()->m_selectedServerIndex);
|
|
||||||
|
|
||||||
ProtocolsModel *p_model = qobject_cast<ProtocolsModel *>(uiLogic()->protocolsModel());
|
|
||||||
// p_model->setSelectedServerIndex(uiLogic()->m_selectedServerIndex);
|
|
||||||
|
|
||||||
set_isManagedServer(m_settings->haveAuthData(uiLogic()->m_selectedServerIndex));
|
|
||||||
uiLogic()->m_installCredentials = m_settings->serverCredentials(uiLogic()->m_selectedServerIndex);
|
|
||||||
emit updatePage();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerContainersLogic::onPushButtonProtoSettingsClicked(DockerContainer c, Proto p)
|
|
||||||
{
|
|
||||||
qDebug() << "ServerContainersLogic::onPushButtonProtoSettingsClicked" << c << p;
|
|
||||||
uiLogic()->m_selectedDockerContainer = c;
|
|
||||||
uiLogic()->protocolLogic(p)->updateProtocolPage(
|
|
||||||
m_settings->protocolConfig(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer, p),
|
|
||||||
uiLogic()->m_selectedDockerContainer, m_settings->haveAuthData(uiLogic()->m_selectedServerIndex));
|
|
||||||
|
|
||||||
emit uiLogic()->goToProtocolPage(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerContainersLogic::onPushButtonDefaultClicked(DockerContainer c)
|
|
||||||
{
|
|
||||||
if (m_settings->defaultContainer(uiLogic()->m_selectedServerIndex) == c)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_settings->setDefaultContainer(uiLogic()->m_selectedServerIndex, c);
|
|
||||||
uiLogic()->onUpdateAllPages();
|
|
||||||
|
|
||||||
if (uiLogic()->m_selectedServerIndex != m_settings->defaultServerIndex())
|
|
||||||
return;
|
|
||||||
if (!uiLogic()->m_vpnConnection)
|
|
||||||
return;
|
|
||||||
if (!uiLogic()->m_vpnConnection->isConnected())
|
|
||||||
return;
|
|
||||||
|
|
||||||
uiLogic()->pageLogic<VpnLogic>()->onDisconnect();
|
|
||||||
uiLogic()->pageLogic<VpnLogic>()->onConnect();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerContainersLogic::onPushButtonShareClicked(DockerContainer c)
|
|
||||||
{
|
|
||||||
uiLogic()->pageLogic<ShareConnectionLogic>()->updateSharingPage(uiLogic()->m_selectedServerIndex, c);
|
|
||||||
emit uiLogic()->goToPage(Page::ShareConnection);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerContainersLogic::onPushButtonRemoveClicked(DockerContainer container)
|
|
||||||
{
|
|
||||||
// buttonSetEnabledFunc(false);
|
|
||||||
ServerController serverController(m_settings);
|
|
||||||
ErrorCode e =
|
|
||||||
serverController.removeContainer(m_settings->serverCredentials(uiLogic()->m_selectedServerIndex), container);
|
|
||||||
m_settings->removeContainerConfig(uiLogic()->m_selectedServerIndex, container);
|
|
||||||
// buttonSetEnabledFunc(true);
|
|
||||||
|
|
||||||
if (m_settings->defaultContainer(uiLogic()->m_selectedServerIndex) == container) {
|
|
||||||
const auto &c = m_settings->containers(uiLogic()->m_selectedServerIndex);
|
|
||||||
if (c.isEmpty())
|
|
||||||
m_settings->setDefaultContainer(uiLogic()->m_selectedServerIndex, DockerContainer::None);
|
|
||||||
else
|
|
||||||
m_settings->setDefaultContainer(uiLogic()->m_selectedServerIndex, c.keys().first());
|
|
||||||
}
|
|
||||||
uiLogic()->onUpdateAllPages();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerContainersLogic::onPushButtonContinueClicked(DockerContainer c, int port, TransportProto tp)
|
|
||||||
{
|
|
||||||
ServerController serverController(m_settings);
|
|
||||||
QJsonObject config; // = serverController.createContainerInitialConfig(c, port, tp);
|
|
||||||
|
|
||||||
emit uiLogic()->goToPage(Page::ServerConfiguringProgress);
|
|
||||||
qApp->processEvents();
|
|
||||||
|
|
||||||
bool isServerCreated = false;
|
|
||||||
ErrorCode errorCode = uiLogic()->addAlreadyInstalledContainersGui(isServerCreated);
|
|
||||||
|
|
||||||
if (errorCode == ErrorCode::NoError) {
|
|
||||||
if (!uiLogic()->isContainerAlreadyAddedToGui(c)) {
|
|
||||||
auto installAction = [this, c, &config]() {
|
|
||||||
ServerController serverController(m_settings);
|
|
||||||
return serverController.setupContainer(m_settings->serverCredentials(uiLogic()->m_selectedServerIndex),
|
|
||||||
c, config);
|
|
||||||
};
|
|
||||||
errorCode = uiLogic()->pageLogic<ServerConfiguringProgressLogic>()->doInstallAction(installAction);
|
|
||||||
|
|
||||||
if (errorCode == ErrorCode::NoError) {
|
|
||||||
m_settings->setContainerConfig(uiLogic()->m_selectedServerIndex, c, config);
|
|
||||||
if (ContainerProps::containerService(c) == ServiceType::Vpn) {
|
|
||||||
m_settings->setDefaultContainer(uiLogic()->m_selectedServerIndex, c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
emit uiLogic()->showWarningMessage(
|
|
||||||
"Attention! The container you are trying to install is already installed on the server. "
|
|
||||||
"All installed containers have been added to the application ");
|
|
||||||
}
|
|
||||||
|
|
||||||
uiLogic()->onUpdateAllPages();
|
|
||||||
}
|
|
||||||
if (errorCode != ErrorCode::NoError) {
|
|
||||||
emit uiLogic()->showWarningMessage(tr("Error occurred while configuring server.") + "\n" + tr("Error message: ")
|
|
||||||
+ errorString(errorCode) + "\n" + tr("See logs for details."));
|
|
||||||
}
|
|
||||||
emit uiLogic()->closePage();
|
|
||||||
}
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
#ifndef SERVER_CONTAINERS_LOGIC_H
|
|
||||||
#define SERVER_CONTAINERS_LOGIC_H
|
|
||||||
|
|
||||||
#include "PageLogicBase.h"
|
|
||||||
#include "containers/containers_defs.h"
|
|
||||||
|
|
||||||
class UiLogic;
|
|
||||||
|
|
||||||
class ServerContainersLogic : public PageLogicBase
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
Q_INVOKABLE void onUpdatePage() override;
|
|
||||||
|
|
||||||
Q_INVOKABLE void onPushButtonProtoSettingsClicked(DockerContainer c, Proto p);
|
|
||||||
Q_INVOKABLE void onPushButtonDefaultClicked(DockerContainer c);
|
|
||||||
Q_INVOKABLE void onPushButtonShareClicked(DockerContainer c);
|
|
||||||
Q_INVOKABLE void onPushButtonRemoveClicked(DockerContainer c);
|
|
||||||
Q_INVOKABLE void onPushButtonContinueClicked(DockerContainer c, int port, TransportProto tp);
|
|
||||||
|
|
||||||
AUTO_PROPERTY(bool, isManagedServer)
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit ServerContainersLogic(UiLogic *uiLogic, QObject *parent = nullptr);
|
|
||||||
~ServerContainersLogic() = default;
|
|
||||||
|
|
||||||
};
|
|
||||||
#endif // SERVER_CONTAINERS_LOGIC_H
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
||||||
#include "ServerListLogic.h"
|
|
||||||
|
|
||||||
#include "../models/servers_model.h"
|
|
||||||
#include "../uilogic.h"
|
|
||||||
#include "vpnconnection.h"
|
|
||||||
|
|
||||||
ServerListLogic::ServerListLogic(UiLogic *logic, QObject *parent)
|
|
||||||
: PageLogicBase(logic, parent), m_serverListModel { new ServersModel(m_settings, this) }
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerListLogic::onServerListPushbuttonDefaultClicked(int index)
|
|
||||||
{
|
|
||||||
m_settings->setDefaultServer(index);
|
|
||||||
uiLogic()->onUpdateAllPages();
|
|
||||||
emit currServerIdxChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerListLogic::onServerListPushbuttonSettingsClicked(int index)
|
|
||||||
{
|
|
||||||
uiLogic()->m_selectedServerIndex = index;
|
|
||||||
uiLogic()->goToPage(Page::ServerSettings);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ServerListLogic::currServerIdx() const
|
|
||||||
{
|
|
||||||
return m_settings->defaultServerIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerListLogic::onUpdatePage()
|
|
||||||
{
|
|
||||||
// const QJsonArray &servers = m_settings->serversArray();
|
|
||||||
// int defaultServer = m_settings->defaultServerIndex();
|
|
||||||
// QVector<ServerModelContent> serverListContent;
|
|
||||||
// for(int i = 0; i < servers.size(); i++) {
|
|
||||||
// ServerModelContent c;
|
|
||||||
// auto server = servers.at(i).toObject();
|
|
||||||
// c.desc = server.value(config_key::description).toString();
|
|
||||||
// c.address = server.value(config_key::hostName).toString();
|
|
||||||
// if (c.desc.isEmpty()) {
|
|
||||||
// c.desc = c.address;
|
|
||||||
// }
|
|
||||||
// c.isDefault = (i == defaultServer);
|
|
||||||
// serverListContent.push_back(c);
|
|
||||||
// }
|
|
||||||
// qobject_cast<ServersModel*>(m_serverListModel)->setContent(serverListContent);
|
|
||||||
}
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
#ifndef SERVER_LIST_LOGIC_H
|
|
||||||
#define SERVER_LIST_LOGIC_H
|
|
||||||
|
|
||||||
#include "PageLogicBase.h"
|
|
||||||
|
|
||||||
class UiLogic;
|
|
||||||
|
|
||||||
class ServerListLogic : public PageLogicBase
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
READONLY_PROPERTY(QObject *, serverListModel)
|
|
||||||
Q_PROPERTY(int currServerIdx READ currServerIdx NOTIFY currServerIdxChanged)
|
|
||||||
|
|
||||||
public:
|
|
||||||
int currServerIdx() const;
|
|
||||||
|
|
||||||
Q_INVOKABLE void onUpdatePage() override;
|
|
||||||
Q_INVOKABLE void onServerListPushbuttonDefaultClicked(int index);
|
|
||||||
Q_INVOKABLE void onServerListPushbuttonSettingsClicked(int index);
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit ServerListLogic(UiLogic *uiLogic, QObject *parent = nullptr);
|
|
||||||
~ServerListLogic() = default;
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void currServerIdxChanged();
|
|
||||||
|
|
||||||
};
|
|
||||||
#endif // SERVER_LIST_LOGIC_H
|
|
||||||
|
|
@ -1,144 +0,0 @@
|
||||||
#include "ServerSettingsLogic.h"
|
|
||||||
#include "vpnconnection.h"
|
|
||||||
|
|
||||||
#include "../uilogic.h"
|
|
||||||
#include "ShareConnectionLogic.h"
|
|
||||||
#include "VpnLogic.h"
|
|
||||||
|
|
||||||
#include "core/errorstrings.h"
|
|
||||||
#include <QTimer>
|
|
||||||
#include <core/servercontroller.h>
|
|
||||||
|
|
||||||
#if defined(Q_OS_ANDROID)
|
|
||||||
#include "../../platforms/android/androidutils.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ServerSettingsLogic::ServerSettingsLogic(UiLogic *logic, QObject *parent)
|
|
||||||
: PageLogicBase(logic, parent),
|
|
||||||
m_labelWaitInfoVisible { true },
|
|
||||||
m_pushButtonClearClientCacheVisible { true },
|
|
||||||
m_pushButtonShareFullVisible { true },
|
|
||||||
m_pushButtonClearClientCacheText { tr("Clear client cached profile") }
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerSettingsLogic::onUpdatePage()
|
|
||||||
{
|
|
||||||
set_labelWaitInfoVisible(false);
|
|
||||||
set_labelWaitInfoText("");
|
|
||||||
set_pushButtonClearClientCacheVisible(m_settings->haveAuthData(uiLogic()->m_selectedServerIndex));
|
|
||||||
set_pushButtonShareFullVisible(m_settings->haveAuthData(uiLogic()->m_selectedServerIndex));
|
|
||||||
const QJsonObject &server = m_settings->server(uiLogic()->m_selectedServerIndex);
|
|
||||||
const QString &port = server.value(config_key::port).toString();
|
|
||||||
|
|
||||||
const QString &userName = server.value(config_key::userName).toString();
|
|
||||||
const QString &hostName = server.value(config_key::hostName).toString();
|
|
||||||
QString name = QString("%1%2%3%4%5")
|
|
||||||
.arg(userName)
|
|
||||||
.arg(userName.isEmpty() ? "" : "@")
|
|
||||||
.arg(hostName)
|
|
||||||
.arg(port.isEmpty() ? "" : ":")
|
|
||||||
.arg(port);
|
|
||||||
|
|
||||||
set_labelServerText(name);
|
|
||||||
set_lineEditDescriptionText(server.value(config_key::description).toString());
|
|
||||||
|
|
||||||
DockerContainer selectedContainer = m_settings->defaultContainer(uiLogic()->m_selectedServerIndex);
|
|
||||||
QString selectedContainerName = ContainerProps::containerHumanNames().value(selectedContainer);
|
|
||||||
set_labelCurrentVpnProtocolText(tr("Service: ") + selectedContainerName);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerSettingsLogic::onPushButtonForgetServer()
|
|
||||||
{
|
|
||||||
if (m_settings->defaultServerIndex() == uiLogic()->m_selectedServerIndex
|
|
||||||
&& uiLogic()->m_vpnConnection->isConnected()) {
|
|
||||||
uiLogic()->pageLogic<VpnLogic>()->onDisconnect();
|
|
||||||
}
|
|
||||||
m_settings->removeServer(uiLogic()->m_selectedServerIndex);
|
|
||||||
|
|
||||||
if (m_settings->defaultServerIndex() == uiLogic()->m_selectedServerIndex) {
|
|
||||||
m_settings->setDefaultServer(0);
|
|
||||||
} else if (m_settings->defaultServerIndex() > uiLogic()->m_selectedServerIndex) {
|
|
||||||
m_settings->setDefaultServer(m_settings->defaultServerIndex() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_settings->serversCount() == 0) {
|
|
||||||
m_settings->setDefaultServer(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
uiLogic()->m_selectedServerIndex = -1;
|
|
||||||
uiLogic()->onUpdateAllPages();
|
|
||||||
|
|
||||||
if (m_settings->serversCount() == 0) {
|
|
||||||
uiLogic()->setStartPage(Page::Start);
|
|
||||||
} else {
|
|
||||||
uiLogic()->closePage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerSettingsLogic::onPushButtonClearClientCacheClicked()
|
|
||||||
{
|
|
||||||
set_pushButtonClearClientCacheText(tr("Cache cleared"));
|
|
||||||
|
|
||||||
const auto &containers = m_settings->containers(uiLogic()->m_selectedServerIndex);
|
|
||||||
for (DockerContainer container : containers.keys()) {
|
|
||||||
m_settings->clearLastConnectionConfig(uiLogic()->m_selectedServerIndex, container);
|
|
||||||
}
|
|
||||||
|
|
||||||
QTimer::singleShot(3000, this, [this]() { set_pushButtonClearClientCacheText(tr("Clear client cached profile")); });
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerSettingsLogic::onLineEditDescriptionEditingFinished()
|
|
||||||
{
|
|
||||||
const QString &newText = lineEditDescriptionText();
|
|
||||||
QJsonObject server = m_settings->server(uiLogic()->m_selectedServerIndex);
|
|
||||||
server.insert(config_key::description, newText);
|
|
||||||
m_settings->editServer(uiLogic()->m_selectedServerIndex, server);
|
|
||||||
uiLogic()->onUpdateAllPages();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ServerSettingsLogic::isCurrentServerHasCredentials()
|
|
||||||
{
|
|
||||||
return m_settings->haveAuthData(uiLogic()->m_selectedServerIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(Q_OS_ANDROID)
|
|
||||||
/* Auth result handler for Android */
|
|
||||||
void authResultReceiver::handleActivityResult(int receiverRequestCode, int resultCode, const QJniObject &data)
|
|
||||||
{
|
|
||||||
qDebug() << "receiverRequestCode" << receiverRequestCode << "resultCode" << resultCode;
|
|
||||||
|
|
||||||
if (resultCode == -1) { // ResultOK
|
|
||||||
uiLogic()->pageLogic<ShareConnectionLogic>()->updateSharingPage(m_serverIndex, DockerContainer::None);
|
|
||||||
emit uiLogic()->goToShareProtocolPage(Proto::Any);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void ServerSettingsLogic::onPushButtonShareFullClicked()
|
|
||||||
{
|
|
||||||
#if defined(Q_OS_ANDROID)
|
|
||||||
/* 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()) {
|
|
||||||
QAndroidActivityResultReceiver *receiver = new authResultReceiver(uiLogic(), uiLogic()->m_selectedServerIndex);
|
|
||||||
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, receiver);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
uiLogic()->pageLogic<ShareConnectionLogic>()->updateSharingPage(uiLogic()->m_selectedServerIndex,
|
|
||||||
DockerContainer::None);
|
|
||||||
emit uiLogic()->goToShareProtocolPage(Proto::Any);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
uiLogic()->pageLogic<ShareConnectionLogic>()->updateSharingPage(uiLogic()->m_selectedServerIndex,
|
|
||||||
DockerContainer::None);
|
|
||||||
emit uiLogic()->goToShareProtocolPage(Proto::Any);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
@ -1,62 +0,0 @@
|
||||||
#ifndef SERVER_SETTINGS_LOGIC_H
|
|
||||||
#define SERVER_SETTINGS_LOGIC_H
|
|
||||||
|
|
||||||
#include "PageLogicBase.h"
|
|
||||||
|
|
||||||
#if defined(Q_OS_ANDROID)
|
|
||||||
#include <QJniObject>
|
|
||||||
#include <private/qandroidextras_p.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class UiLogic;
|
|
||||||
|
|
||||||
class ServerSettingsLogic : public PageLogicBase
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
AUTO_PROPERTY(bool, labelWaitInfoVisible)
|
|
||||||
AUTO_PROPERTY(QString, labelWaitInfoText)
|
|
||||||
AUTO_PROPERTY(QString, pushButtonClearClientCacheText)
|
|
||||||
AUTO_PROPERTY(bool, pushButtonClearClientCacheVisible)
|
|
||||||
AUTO_PROPERTY(bool, pushButtonShareFullVisible)
|
|
||||||
AUTO_PROPERTY(QString, labelServerText)
|
|
||||||
AUTO_PROPERTY(QString, lineEditDescriptionText)
|
|
||||||
AUTO_PROPERTY(QString, labelCurrentVpnProtocolText)
|
|
||||||
|
|
||||||
public:
|
|
||||||
Q_INVOKABLE void onUpdatePage() override;
|
|
||||||
|
|
||||||
Q_INVOKABLE void onPushButtonForgetServer();
|
|
||||||
Q_INVOKABLE void onPushButtonShareFullClicked();
|
|
||||||
Q_INVOKABLE void onPushButtonClearClientCacheClicked();
|
|
||||||
Q_INVOKABLE void onLineEditDescriptionEditingFinished();
|
|
||||||
|
|
||||||
Q_INVOKABLE bool isCurrentServerHasCredentials();
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit ServerSettingsLogic(UiLogic *uiLogic, QObject *parent = nullptr);
|
|
||||||
~ServerSettingsLogic() = default;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#if defined(Q_OS_ANDROID)
|
|
||||||
/* Auth result handler for Android */
|
|
||||||
class authResultReceiver final : public PageLogicBase, public QAndroidActivityResultReceiver
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
authResultReceiver(UiLogic *uiLogic, int serverIndex , QObject *parent = nullptr) : PageLogicBase(uiLogic, parent) {
|
|
||||||
m_serverIndex = serverIndex;
|
|
||||||
}
|
|
||||||
~authResultReceiver() {}
|
|
||||||
|
|
||||||
public:
|
|
||||||
void handleActivityResult(int receiverRequestCode, int resultCode, const QJniObject &data) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
int m_serverIndex;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // SERVER_SETTINGS_LOGIC_H
|
|
||||||
|
|
@ -1,293 +0,0 @@
|
||||||
#include <QBuffer>
|
|
||||||
#include <QImage>
|
|
||||||
#include <QDataStream>
|
|
||||||
|
|
||||||
#include "qrcodegen.hpp"
|
|
||||||
|
|
||||||
#include "ShareConnectionLogic.h"
|
|
||||||
|
|
||||||
#include "configurators/cloak_configurator.h"
|
|
||||||
#include "configurators/vpn_configurator.h"
|
|
||||||
#include "configurators/openvpn_configurator.h"
|
|
||||||
#include "configurators/shadowsocks_configurator.h"
|
|
||||||
#include "configurators/wireguard_configurator.h"
|
|
||||||
#include "configurators/ikev2_configurator.h"
|
|
||||||
#include "configurators/ssh_configurator.h"
|
|
||||||
|
|
||||||
#include "version.h"
|
|
||||||
#include "core/defs.h"
|
|
||||||
#include "core/errorstrings.h"
|
|
||||||
#include "core/servercontroller.h"
|
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
#include "../uilogic.h"
|
|
||||||
|
|
||||||
#ifdef __linux__
|
|
||||||
#include <math.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
using namespace qrcodegen;
|
|
||||||
|
|
||||||
ShareConnectionLogic::ShareConnectionLogic(UiLogic *logic, QObject *parent):
|
|
||||||
PageLogicBase(logic, parent),
|
|
||||||
m_textEditShareOpenVpnCodeText{},
|
|
||||||
m_lineEditShareShadowSocksStringText{},
|
|
||||||
m_shareShadowSocksQrCodeText{},
|
|
||||||
m_textEditShareCloakText{},
|
|
||||||
m_textEditShareAmneziaCodeText{}
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShareConnectionLogic::onUpdatePage()
|
|
||||||
{
|
|
||||||
set_textEditShareAmneziaCodeText(tr(""));
|
|
||||||
set_shareAmneziaQrCodeTextSeries({});
|
|
||||||
set_shareAmneziaQrCodeTextSeriesLength(0);
|
|
||||||
|
|
||||||
set_textEditShareOpenVpnCodeText("");
|
|
||||||
|
|
||||||
set_shareShadowSocksQrCodeText("");
|
|
||||||
set_textEditShareShadowSocksText("");
|
|
||||||
set_lineEditShareShadowSocksStringText("");
|
|
||||||
|
|
||||||
set_textEditShareCloakText("");
|
|
||||||
|
|
||||||
set_textEditShareWireGuardCodeText("");
|
|
||||||
set_shareWireGuardQrCodeText("");
|
|
||||||
|
|
||||||
set_textEditShareIkev2CertText("");
|
|
||||||
set_textEditShareIkev2MobileConfigText("");
|
|
||||||
set_textEditShareIkev2StrongSwanConfigText("");
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShareConnectionLogic::onPushButtonShareAmneziaGenerateClicked()
|
|
||||||
{
|
|
||||||
set_textEditShareAmneziaCodeText("");
|
|
||||||
set_shareAmneziaQrCodeTextSeries({});
|
|
||||||
set_shareAmneziaQrCodeTextSeriesLength(0);
|
|
||||||
|
|
||||||
QJsonObject serverConfig;
|
|
||||||
int serverIndex = uiLogic()->m_selectedServerIndex;
|
|
||||||
DockerContainer container = uiLogic()->m_selectedDockerContainer;
|
|
||||||
|
|
||||||
// Full access
|
|
||||||
if (shareFullAccess()) {
|
|
||||||
serverConfig = m_settings->server(serverIndex);
|
|
||||||
}
|
|
||||||
// Container share
|
|
||||||
else {
|
|
||||||
ServerCredentials credentials = m_settings->serverCredentials(serverIndex);
|
|
||||||
QJsonObject containerConfig = m_settings->containerConfig(serverIndex, container);
|
|
||||||
containerConfig.insert(config_key::container, ContainerProps::containerToString(container));
|
|
||||||
|
|
||||||
ErrorCode e = ErrorCode::NoError;
|
|
||||||
for (Proto p: ContainerProps::protocolsForContainer(container)) {
|
|
||||||
QJsonObject protoConfig = m_settings->protocolConfig(serverIndex, container, p);
|
|
||||||
|
|
||||||
QString cfg = m_configurator->genVpnProtocolConfig(credentials, container, containerConfig, p, &e);
|
|
||||||
if (e) {
|
|
||||||
cfg = "Error generating config";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
protoConfig.insert(config_key::last_config, cfg);
|
|
||||||
containerConfig.insert(ProtocolProps::protoToString(p), protoConfig);
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray ba;
|
|
||||||
if (!e) {
|
|
||||||
serverConfig = m_settings->server(serverIndex);
|
|
||||||
serverConfig.remove(config_key::userName);
|
|
||||||
serverConfig.remove(config_key::password);
|
|
||||||
serverConfig.remove(config_key::port);
|
|
||||||
serverConfig.insert(config_key::containers, QJsonArray {containerConfig});
|
|
||||||
serverConfig.insert(config_key::defaultContainer, ContainerProps::containerToString(container));
|
|
||||||
|
|
||||||
auto dns = m_configurator->getDnsForConfig(serverIndex);
|
|
||||||
serverConfig.insert(config_key::dns1, dns.first);
|
|
||||||
serverConfig.insert(config_key::dns2, dns.second);
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
set_textEditShareAmneziaCodeText(tr("Error while generating connection profile"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray ba = QJsonDocument(serverConfig).toJson();
|
|
||||||
ba = qCompress(ba, 8);
|
|
||||||
QString code = QString("vpn://%1").arg(QString(ba.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals)));
|
|
||||||
set_textEditShareAmneziaCodeText(code);
|
|
||||||
|
|
||||||
|
|
||||||
QList<QString> qrChunks = genQrCodeImageSeries(ba);
|
|
||||||
set_shareAmneziaQrCodeTextSeries(qrChunks);
|
|
||||||
set_shareAmneziaQrCodeTextSeriesLength(qrChunks.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShareConnectionLogic::onPushButtonShareOpenVpnGenerateClicked()
|
|
||||||
{
|
|
||||||
int serverIndex = uiLogic()->m_selectedServerIndex;
|
|
||||||
DockerContainer container = uiLogic()->m_selectedDockerContainer;
|
|
||||||
ServerCredentials credentials = m_settings->serverCredentials(serverIndex);
|
|
||||||
|
|
||||||
const QJsonObject &containerConfig = m_settings->containerConfig(serverIndex, container);
|
|
||||||
|
|
||||||
ErrorCode e = ErrorCode::NoError;
|
|
||||||
QString cfg = m_configurator->openVpnConfigurator->genOpenVpnConfig(credentials, container, containerConfig, &e);
|
|
||||||
cfg = m_configurator->processConfigWithExportSettings(serverIndex, container, Proto::OpenVpn, cfg);
|
|
||||||
|
|
||||||
set_textEditShareOpenVpnCodeText(QJsonDocument::fromJson(cfg.toUtf8()).object()[config_key::config].toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShareConnectionLogic::onPushButtonShareShadowSocksGenerateClicked()
|
|
||||||
{
|
|
||||||
int serverIndex = uiLogic()->m_selectedServerIndex;
|
|
||||||
DockerContainer container = uiLogic()->m_selectedDockerContainer;
|
|
||||||
ServerCredentials credentials = m_settings->serverCredentials(serverIndex);
|
|
||||||
|
|
||||||
QJsonObject protoConfig = m_settings->protocolConfig(serverIndex, container, Proto::ShadowSocks);
|
|
||||||
QString cfg = protoConfig.value(config_key::last_config).toString();
|
|
||||||
|
|
||||||
if (cfg.isEmpty()) {
|
|
||||||
const QJsonObject &containerConfig = m_settings->containerConfig(serverIndex, container);
|
|
||||||
|
|
||||||
ErrorCode e = ErrorCode::NoError;
|
|
||||||
cfg = m_configurator->shadowSocksConfigurator->genShadowSocksConfig(credentials, container, containerConfig, &e);
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonObject ssConfig = QJsonDocument::fromJson(cfg.toUtf8()).object();
|
|
||||||
|
|
||||||
QString ssString = QString("%1:%2@%3:%4")
|
|
||||||
.arg(ssConfig.value("method").toString())
|
|
||||||
.arg(ssConfig.value("password").toString())
|
|
||||||
.arg(ssConfig.value("server").toString())
|
|
||||||
.arg(ssConfig.value("server_port").toString());
|
|
||||||
|
|
||||||
ssString = "ss://" + ssString.toUtf8().toBase64();
|
|
||||||
set_lineEditShareShadowSocksStringText(ssString);
|
|
||||||
|
|
||||||
QrCode qr = QrCode::encodeText(ssString.toUtf8(), QrCode::Ecc::LOW);
|
|
||||||
QString svg = QString::fromStdString(toSvgString(qr, 0));
|
|
||||||
|
|
||||||
set_shareShadowSocksQrCodeText(svgToBase64(svg));
|
|
||||||
|
|
||||||
QString humanString = QString("Server: %3\n"
|
|
||||||
"Port: %4\n"
|
|
||||||
"Encryption: %1\n"
|
|
||||||
"Password: %2")
|
|
||||||
.arg(ssConfig.value("method").toString())
|
|
||||||
.arg(ssConfig.value("password").toString())
|
|
||||||
.arg(ssConfig.value("server").toString())
|
|
||||||
.arg(ssConfig.value("server_port").toString());
|
|
||||||
|
|
||||||
set_textEditShareShadowSocksText(humanString);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShareConnectionLogic::onPushButtonShareCloakGenerateClicked()
|
|
||||||
{
|
|
||||||
int serverIndex = uiLogic()->m_selectedServerIndex;
|
|
||||||
DockerContainer container = uiLogic()->m_selectedDockerContainer;
|
|
||||||
ServerCredentials credentials = m_settings->serverCredentials(serverIndex);
|
|
||||||
|
|
||||||
QJsonObject protoConfig = m_settings->protocolConfig(serverIndex, container, Proto::Cloak);
|
|
||||||
QString cfg = protoConfig.value(config_key::last_config).toString();
|
|
||||||
|
|
||||||
if (cfg.isEmpty()) {
|
|
||||||
const QJsonObject &containerConfig = m_settings->containerConfig(serverIndex, container);
|
|
||||||
|
|
||||||
ErrorCode e = ErrorCode::NoError;
|
|
||||||
cfg = m_configurator->cloakConfigurator->genCloakConfig(credentials, container, containerConfig, &e);
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonObject cloakConfig = QJsonDocument::fromJson(cfg.toUtf8()).object();
|
|
||||||
cloakConfig.remove(config_key::transport_proto);
|
|
||||||
cloakConfig.insert("ProxyMethod", "shadowsocks");
|
|
||||||
|
|
||||||
set_textEditShareCloakText(QJsonDocument(cloakConfig).toJson());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShareConnectionLogic::onPushButtonShareWireGuardGenerateClicked()
|
|
||||||
{
|
|
||||||
int serverIndex = uiLogic()->m_selectedServerIndex;
|
|
||||||
DockerContainer container = uiLogic()->m_selectedDockerContainer;
|
|
||||||
ServerCredentials credentials = m_settings->serverCredentials(serverIndex);
|
|
||||||
|
|
||||||
const QJsonObject &containerConfig = m_settings->containerConfig(serverIndex, container);
|
|
||||||
|
|
||||||
ErrorCode e = ErrorCode::NoError;
|
|
||||||
QString cfg = m_configurator->wireguardConfigurator->genWireguardConfig(credentials, container, containerConfig, &e);
|
|
||||||
if (e) {
|
|
||||||
emit uiLogic()->showWarningMessage(tr("Error occurred while generating the config.") + "\n" +
|
|
||||||
tr("Error message: ") + errorString(e) + "\n" +
|
|
||||||
tr("See logs for details."));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cfg = m_configurator->processConfigWithExportSettings(serverIndex, container, Proto::WireGuard, cfg);
|
|
||||||
cfg = QJsonDocument::fromJson(cfg.toUtf8()).object()[config_key::config].toString();
|
|
||||||
|
|
||||||
set_textEditShareWireGuardCodeText(cfg);
|
|
||||||
|
|
||||||
QrCode qr = QrCode::encodeText(cfg.toUtf8(), QrCode::Ecc::LOW);
|
|
||||||
QString svg = QString::fromStdString(toSvgString(qr, 0));
|
|
||||||
|
|
||||||
set_shareWireGuardQrCodeText(svgToBase64(svg));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShareConnectionLogic::onPushButtonShareIkev2GenerateClicked()
|
|
||||||
{
|
|
||||||
int serverIndex = uiLogic()->m_selectedServerIndex;
|
|
||||||
DockerContainer container = uiLogic()->m_selectedDockerContainer;
|
|
||||||
ServerCredentials credentials = m_settings->serverCredentials(serverIndex);
|
|
||||||
|
|
||||||
Ikev2Configurator::ConnectionData connData = m_configurator->ikev2Configurator->prepareIkev2Config(credentials, container);
|
|
||||||
|
|
||||||
QString cfg = m_configurator->ikev2Configurator->genIkev2Config(connData);
|
|
||||||
cfg = m_configurator->processConfigWithExportSettings(serverIndex, container, Proto::Ikev2, cfg);
|
|
||||||
cfg = QJsonDocument::fromJson(cfg.toUtf8()).object()[config_key::cert].toString();
|
|
||||||
|
|
||||||
set_textEditShareIkev2CertText(cfg);
|
|
||||||
|
|
||||||
QString mobileCfg = m_configurator->ikev2Configurator->genMobileConfig(connData);
|
|
||||||
set_textEditShareIkev2MobileConfigText(mobileCfg);
|
|
||||||
|
|
||||||
QString strongSwanCfg = m_configurator->ikev2Configurator->genStrongSwanConfig(connData);
|
|
||||||
set_textEditShareIkev2StrongSwanConfigText(strongSwanCfg);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ShareConnectionLogic::updateSharingPage(int serverIndex, DockerContainer container)
|
|
||||||
{
|
|
||||||
uiLogic()->m_selectedDockerContainer = container;
|
|
||||||
uiLogic()->m_selectedServerIndex = serverIndex;
|
|
||||||
set_shareFullAccess(container == DockerContainer::None);
|
|
||||||
|
|
||||||
m_shareAmneziaQrCodeTextSeries.clear();
|
|
||||||
set_shareAmneziaQrCodeTextSeriesLength(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<QString> ShareConnectionLogic::genQrCodeImageSeries(const QByteArray &data)
|
|
||||||
{
|
|
||||||
double k = 850;
|
|
||||||
|
|
||||||
quint8 chunksCount = std::ceil(data.size() / k);
|
|
||||||
QList<QString> chunks;
|
|
||||||
for (int i = 0; i < data.size(); i = i + k) {
|
|
||||||
QByteArray chunk;
|
|
||||||
QDataStream s(&chunk, QIODevice::WriteOnly);
|
|
||||||
s << amnezia::qrMagicCode << chunksCount << (quint8)std::round(i/k) << data.mid(i, k);
|
|
||||||
|
|
||||||
QByteArray ba = chunk.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
|
|
||||||
|
|
||||||
QrCode qr = QrCode::encodeText(ba, QrCode::Ecc::LOW);
|
|
||||||
QString svg = QString::fromStdString(toSvgString(qr, 0));
|
|
||||||
chunks.append(svgToBase64(svg));
|
|
||||||
}
|
|
||||||
|
|
||||||
return chunks;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString ShareConnectionLogic::svgToBase64(const QString &image)
|
|
||||||
{
|
|
||||||
return "data:image/svg;base64," + QString::fromLatin1(image.toUtf8().toBase64().data());
|
|
||||||
}
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
||||||
#ifndef SHARE_CONNECTION_LOGIC_H
|
|
||||||
#define SHARE_CONNECTION_LOGIC_H
|
|
||||||
|
|
||||||
#include "PageLogicBase.h"
|
|
||||||
#include "containers/containers_defs.h"
|
|
||||||
|
|
||||||
class UiLogic;
|
|
||||||
|
|
||||||
class ShareConnectionLogic: public PageLogicBase
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
AUTO_PROPERTY(bool, shareFullAccess)
|
|
||||||
|
|
||||||
AUTO_PROPERTY(QString, textEditShareAmneziaCodeText)
|
|
||||||
AUTO_PROPERTY(QStringList, shareAmneziaQrCodeTextSeries)
|
|
||||||
AUTO_PROPERTY(int, shareAmneziaQrCodeTextSeriesLength)
|
|
||||||
|
|
||||||
AUTO_PROPERTY(QString, textEditShareOpenVpnCodeText)
|
|
||||||
|
|
||||||
AUTO_PROPERTY(QString, textEditShareShadowSocksText)
|
|
||||||
AUTO_PROPERTY(QString, lineEditShareShadowSocksStringText)
|
|
||||||
AUTO_PROPERTY(QString, shareShadowSocksQrCodeText)
|
|
||||||
|
|
||||||
AUTO_PROPERTY(QString, textEditShareCloakText)
|
|
||||||
|
|
||||||
AUTO_PROPERTY(QString, textEditShareWireGuardCodeText)
|
|
||||||
AUTO_PROPERTY(QString, shareWireGuardQrCodeText)
|
|
||||||
|
|
||||||
AUTO_PROPERTY(QString, textEditShareIkev2CertText)
|
|
||||||
AUTO_PROPERTY(QString, textEditShareIkev2MobileConfigText)
|
|
||||||
AUTO_PROPERTY(QString, textEditShareIkev2StrongSwanConfigText)
|
|
||||||
|
|
||||||
public:
|
|
||||||
Q_INVOKABLE void onPushButtonShareAmneziaGenerateClicked();
|
|
||||||
Q_INVOKABLE void onPushButtonShareOpenVpnGenerateClicked();
|
|
||||||
Q_INVOKABLE void onPushButtonShareShadowSocksGenerateClicked();
|
|
||||||
Q_INVOKABLE void onPushButtonShareCloakGenerateClicked();
|
|
||||||
Q_INVOKABLE void onPushButtonShareWireGuardGenerateClicked();
|
|
||||||
Q_INVOKABLE void onPushButtonShareIkev2GenerateClicked();
|
|
||||||
|
|
||||||
Q_INVOKABLE virtual void onUpdatePage() override;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit ShareConnectionLogic(UiLogic *uiLogic, QObject *parent = nullptr);
|
|
||||||
~ShareConnectionLogic() = default;
|
|
||||||
|
|
||||||
void updateSharingPage(int serverIndex, DockerContainer container);
|
|
||||||
QList<QString> genQrCodeImageSeries(const QByteArray &data);
|
|
||||||
|
|
||||||
QString svgToBase64(const QString &image);
|
|
||||||
};
|
|
||||||
#endif // SHARE_CONNECTION_LOGIC_H
|
|
||||||
|
|
@ -1,211 +0,0 @@
|
||||||
#include <QDebug>
|
|
||||||
#include <QDesktopServices>
|
|
||||||
#include <QFile>
|
|
||||||
#include <QHostInfo>
|
|
||||||
|
|
||||||
#include "SitesLogic.h"
|
|
||||||
#include "VpnLogic.h"
|
|
||||||
#include "utilities.h"
|
|
||||||
#include "vpnconnection.h"
|
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
#include "../models/sites_model.h"
|
|
||||||
#include "../uilogic.h"
|
|
||||||
|
|
||||||
SitesLogic::SitesLogic(UiLogic *logic, QObject *parent)
|
|
||||||
: PageLogicBase(logic, parent),
|
|
||||||
m_labelSitesAddCustomText {},
|
|
||||||
m_tableViewSitesModel { nullptr },
|
|
||||||
m_lineEditSitesAddCustomText {}
|
|
||||||
{
|
|
||||||
// sitesModels.insert(Settings::VpnOnlyForwardSites, new SitesModel(m_settings, Settings::VpnOnlyForwardSites));
|
|
||||||
// sitesModels.insert(Settings::VpnAllExceptSites, new SitesModel(m_settings, Settings::VpnAllExceptSites));
|
|
||||||
}
|
|
||||||
|
|
||||||
void SitesLogic::onUpdatePage()
|
|
||||||
{
|
|
||||||
Settings::RouteMode m = m_settings->routeMode();
|
|
||||||
if (m == Settings::VpnAllSites)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (m == Settings::VpnOnlyForwardSites) {
|
|
||||||
set_labelSitesAddCustomText(tr("These sites will be opened using VPN"));
|
|
||||||
}
|
|
||||||
if (m == Settings::VpnAllExceptSites) {
|
|
||||||
set_labelSitesAddCustomText(tr("These sites will be excepted from VPN"));
|
|
||||||
}
|
|
||||||
|
|
||||||
set_tableViewSitesModel(sitesModels.value(m));
|
|
||||||
// sitesModels.value(m)->resetCache();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SitesLogic::onPushButtonAddCustomSitesClicked()
|
|
||||||
{
|
|
||||||
if (uiLogic()->pageLogic<VpnLogic>()->radioButtonVpnModeAllSitesChecked()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Settings::RouteMode mode = m_settings->routeMode();
|
|
||||||
|
|
||||||
QString newSite = lineEditSitesAddCustomText();
|
|
||||||
|
|
||||||
if (newSite.isEmpty())
|
|
||||||
return;
|
|
||||||
if (!newSite.contains("."))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!Utils::ipAddressWithSubnetRegExp().exactMatch(newSite)) {
|
|
||||||
// get domain name if it present
|
|
||||||
newSite.replace("https://", "");
|
|
||||||
newSite.replace("http://", "");
|
|
||||||
newSite.replace("ftp://", "");
|
|
||||||
|
|
||||||
newSite = newSite.split("/", Qt::SkipEmptyParts).first();
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto &cbProcess = [this, mode](const QString &newSite, const QString &ip) {
|
|
||||||
m_settings->addVpnSite(mode, newSite, ip);
|
|
||||||
|
|
||||||
if (!ip.isEmpty()) {
|
|
||||||
QMetaObject::invokeMethod(uiLogic()->m_vpnConnection, "addRoutes", Qt::QueuedConnection,
|
|
||||||
Q_ARG(QStringList, QStringList() << ip));
|
|
||||||
} else if (Utils::ipAddressWithSubnetRegExp().exactMatch(newSite)) {
|
|
||||||
QMetaObject::invokeMethod(uiLogic()->m_vpnConnection, "addRoutes", Qt::QueuedConnection,
|
|
||||||
Q_ARG(QStringList, QStringList() << newSite));
|
|
||||||
}
|
|
||||||
|
|
||||||
QMetaObject::invokeMethod(uiLogic()->m_vpnConnection, "flushDns", Qt::QueuedConnection);
|
|
||||||
|
|
||||||
onUpdatePage();
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto &cbResolv = [this, cbProcess](const QHostInfo &hostInfo) {
|
|
||||||
const QList<QHostAddress> &addresses = hostInfo.addresses();
|
|
||||||
QString ipv4Addr;
|
|
||||||
for (const QHostAddress &addr : hostInfo.addresses()) {
|
|
||||||
if (addr.protocol() == QAbstractSocket::NetworkLayerProtocol::IPv4Protocol) {
|
|
||||||
cbProcess(hostInfo.hostName(), addr.toString());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
set_lineEditSitesAddCustomText("");
|
|
||||||
|
|
||||||
if (Utils::ipAddressWithSubnetRegExp().exactMatch(newSite)) {
|
|
||||||
cbProcess(newSite, "");
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
cbProcess(newSite, "");
|
|
||||||
onUpdatePage();
|
|
||||||
QHostInfo::lookupHost(newSite, this, cbResolv);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SitesLogic::onPushButtonSitesDeleteClicked(QStringList items)
|
|
||||||
{
|
|
||||||
Settings::RouteMode mode = m_settings->routeMode();
|
|
||||||
|
|
||||||
auto siteModel = qobject_cast<SitesModel *>(tableViewSitesModel());
|
|
||||||
if (!siteModel || items.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList sites;
|
|
||||||
QStringList ips;
|
|
||||||
|
|
||||||
for (const QString &s : items) {
|
|
||||||
bool ok;
|
|
||||||
int row = s.toInt(&ok);
|
|
||||||
if (!ok || row < 0 || row >= siteModel->rowCount())
|
|
||||||
return;
|
|
||||||
// sites.append(siteModel->data(row, 0).toString());
|
|
||||||
|
|
||||||
// if (uiLogic()->m_vpnConnection && uiLogic()->m_vpnConnection->connectionState() == VpnProtocol::Connected) {
|
|
||||||
// ips.append(siteModel->data(row, 1).toString());
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
m_settings->removeVpnSites(mode, sites);
|
|
||||||
|
|
||||||
QMetaObject::invokeMethod(uiLogic()->m_vpnConnection, "deleteRoutes", Qt::QueuedConnection, Q_ARG(QStringList, ips));
|
|
||||||
|
|
||||||
QMetaObject::invokeMethod(uiLogic()->m_vpnConnection, "flushDns", Qt::QueuedConnection);
|
|
||||||
|
|
||||||
onUpdatePage();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SitesLogic::onPushButtonSitesImportClicked(const QString &fileName)
|
|
||||||
{
|
|
||||||
QFile file(QUrl { fileName }.toLocalFile());
|
|
||||||
if (!file.open(QIODevice::ReadOnly)) {
|
|
||||||
qDebug() << "Can't open file " << QUrl { fileName }.toLocalFile();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Settings::RouteMode mode = m_settings->routeMode();
|
|
||||||
|
|
||||||
QStringList ips;
|
|
||||||
QMap<QString, QString> sites;
|
|
||||||
|
|
||||||
while (!file.atEnd()) {
|
|
||||||
QString line = file.readLine();
|
|
||||||
QStringList line_ips;
|
|
||||||
QStringList line_sites;
|
|
||||||
|
|
||||||
int posDomain = 0;
|
|
||||||
QRegExp domainRx = Utils::domainRegExp();
|
|
||||||
while ((posDomain = domainRx.indexIn(line, posDomain)) != -1) {
|
|
||||||
line_sites.append(domainRx.cap(0));
|
|
||||||
posDomain += domainRx.matchedLength();
|
|
||||||
}
|
|
||||||
|
|
||||||
int posIp = 0;
|
|
||||||
QRegExp ipRx = Utils::ipAddressWithSubnetRegExp();
|
|
||||||
while ((posIp = ipRx.indexIn(line, posIp)) != -1) {
|
|
||||||
line_ips.append(ipRx.cap(0));
|
|
||||||
posIp += ipRx.matchedLength();
|
|
||||||
}
|
|
||||||
|
|
||||||
// domain regex cover ip regex, so remove ips from sites
|
|
||||||
for (const QString &ip : line_ips) {
|
|
||||||
line_sites.removeAll(ip);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (line_sites.size() == 1 && line_ips.size() == 1) {
|
|
||||||
sites.insert(line_sites.at(0), line_ips.at(0));
|
|
||||||
} else if (line_sites.size() > 0 && line_ips.size() == 0) {
|
|
||||||
for (const QString &site : line_sites) {
|
|
||||||
sites.insert(site, "");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (const QString &site : line_sites) {
|
|
||||||
sites.insert(site, "");
|
|
||||||
}
|
|
||||||
for (const QString &ip : line_ips) {
|
|
||||||
ips.append(ip);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_settings->addVpnIps(mode, ips);
|
|
||||||
m_settings->addVpnSites(mode, sites);
|
|
||||||
|
|
||||||
QMetaObject::invokeMethod(uiLogic()->m_vpnConnection, "addRoutes", Qt::QueuedConnection, Q_ARG(QStringList, ips));
|
|
||||||
|
|
||||||
QMetaObject::invokeMethod(uiLogic()->m_vpnConnection, "flushDns", Qt::QueuedConnection);
|
|
||||||
|
|
||||||
onUpdatePage();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SitesLogic::onPushButtonSitesExportClicked()
|
|
||||||
{
|
|
||||||
Settings::RouteMode mode = m_settings->routeMode();
|
|
||||||
|
|
||||||
QVariantMap sites = m_settings->vpnSites(mode);
|
|
||||||
|
|
||||||
QString data;
|
|
||||||
for (auto s : sites.keys()) {
|
|
||||||
data += s + "\t" + sites.value(s).toString() + "\n";
|
|
||||||
}
|
|
||||||
uiLogic()->saveTextFile("Export Sites", "sites.txt", ".txt", data);
|
|
||||||
}
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
#ifndef SITES_LOGIC_H
|
|
||||||
#define SITES_LOGIC_H
|
|
||||||
|
|
||||||
#include "PageLogicBase.h"
|
|
||||||
#include "settings.h"
|
|
||||||
|
|
||||||
class UiLogic;
|
|
||||||
class SitesModel;
|
|
||||||
|
|
||||||
class SitesLogic : public PageLogicBase
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
AUTO_PROPERTY(QString, labelSitesAddCustomText)
|
|
||||||
AUTO_PROPERTY(QObject*, tableViewSitesModel)
|
|
||||||
AUTO_PROPERTY(QString, lineEditSitesAddCustomText)
|
|
||||||
|
|
||||||
public:
|
|
||||||
Q_INVOKABLE void onUpdatePage() override;
|
|
||||||
|
|
||||||
Q_INVOKABLE void onPushButtonAddCustomSitesClicked();
|
|
||||||
Q_INVOKABLE void onPushButtonSitesDeleteClicked(QStringList items);
|
|
||||||
Q_INVOKABLE void onPushButtonSitesImportClicked(const QString &fileName);
|
|
||||||
Q_INVOKABLE void onPushButtonSitesExportClicked();
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit SitesLogic(UiLogic *uiLogic, QObject *parent = nullptr);
|
|
||||||
~SitesLogic() = default;
|
|
||||||
|
|
||||||
QMap<Settings::RouteMode, SitesModel *> sitesModels;
|
|
||||||
};
|
|
||||||
#endif // SITES_LOGIC_H
|
|
||||||
|
|
@ -1,374 +0,0 @@
|
||||||
#include "StartPageLogic.h"
|
|
||||||
#include "ViewConfigLogic.h"
|
|
||||||
|
|
||||||
#include "../uilogic.h"
|
|
||||||
#include "configurators/ssh_configurator.h"
|
|
||||||
#include "configurators/vpn_configurator.h"
|
|
||||||
#include "core/errorstrings.h"
|
|
||||||
#include "core/servercontroller.h"
|
|
||||||
#include "utilities.h"
|
|
||||||
|
|
||||||
#include <QEventLoop>
|
|
||||||
#include <QFileDialog>
|
|
||||||
#include <QStandardPaths>
|
|
||||||
|
|
||||||
#ifdef Q_OS_ANDROID
|
|
||||||
#include "../../platforms/android/android_controller.h"
|
|
||||||
#include "../../platforms/android/androidutils.h"
|
|
||||||
#include <QJniObject>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef Q_OS_IOS
|
|
||||||
#include <CoreFoundation/CoreFoundation.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
enum class ConfigTypes {
|
|
||||||
Amnezia,
|
|
||||||
OpenVpn,
|
|
||||||
WireGuard
|
|
||||||
};
|
|
||||||
|
|
||||||
ConfigTypes checkConfigFormat(const QString &config)
|
|
||||||
{
|
|
||||||
const QString openVpnConfigPatternCli = "client";
|
|
||||||
const QString openVpnConfigPatternProto1 = "proto tcp";
|
|
||||||
const QString openVpnConfigPatternProto2 = "proto udp";
|
|
||||||
const QString openVpnConfigPatternDriver1 = "dev tun";
|
|
||||||
const QString openVpnConfigPatternDriver2 = "dev tap";
|
|
||||||
|
|
||||||
const QString wireguardConfigPatternSectionInterface = "[Interface]";
|
|
||||||
const QString wireguardConfigPatternSectionPeer = "[Peer]";
|
|
||||||
|
|
||||||
if (config.contains(openVpnConfigPatternCli)
|
|
||||||
&& (config.contains(openVpnConfigPatternProto1) || config.contains(openVpnConfigPatternProto2))
|
|
||||||
&& (config.contains(openVpnConfigPatternDriver1) || config.contains(openVpnConfigPatternDriver2))) {
|
|
||||||
return ConfigTypes::OpenVpn;
|
|
||||||
} else if (config.contains(wireguardConfigPatternSectionInterface)
|
|
||||||
&& config.contains(wireguardConfigPatternSectionPeer))
|
|
||||||
return ConfigTypes::WireGuard;
|
|
||||||
return ConfigTypes::Amnezia;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
StartPageLogic::StartPageLogic(UiLogic *logic, QObject *parent)
|
|
||||||
: PageLogicBase(logic, parent),
|
|
||||||
m_pushButtonConnectEnabled { true },
|
|
||||||
m_pushButtonConnectText { tr("Connect") },
|
|
||||||
m_pushButtonConnectKeyChecked { false },
|
|
||||||
m_labelWaitInfoVisible { true },
|
|
||||||
m_pushButtonBackFromStartVisible { true },
|
|
||||||
m_ipAddressPortRegex { Utils::ipAddressPortRegExp() }
|
|
||||||
{
|
|
||||||
#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 StartPageLogic::onUpdatePage()
|
|
||||||
{
|
|
||||||
set_lineEditStartExistingCodeText("");
|
|
||||||
set_textEditSshKeyText("");
|
|
||||||
set_lineEditIpText("");
|
|
||||||
set_lineEditPasswordText("");
|
|
||||||
set_textEditSshKeyText("");
|
|
||||||
set_lineEditLoginText("");
|
|
||||||
|
|
||||||
set_labelWaitInfoVisible(false);
|
|
||||||
set_labelWaitInfoText("");
|
|
||||||
|
|
||||||
set_pushButtonConnectKeyChecked(false);
|
|
||||||
|
|
||||||
set_pushButtonBackFromStartVisible(uiLogic()->pagesStackDepth() > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void StartPageLogic::onPushButtonConnect()
|
|
||||||
{
|
|
||||||
if (pushButtonConnectKeyChecked()) {
|
|
||||||
if (lineEditIpText().isEmpty() || lineEditLoginText().isEmpty() || textEditSshKeyText().isEmpty()) {
|
|
||||||
set_labelWaitInfoText(tr("Please fill in all fields"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (lineEditIpText().isEmpty() || lineEditLoginText().isEmpty() || lineEditPasswordText().isEmpty()) {
|
|
||||||
set_labelWaitInfoText(tr("Please fill in all fields"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ServerCredentials serverCredentials;
|
|
||||||
serverCredentials.hostName = lineEditIpText();
|
|
||||||
if (serverCredentials.hostName.contains(":")) {
|
|
||||||
serverCredentials.port = serverCredentials.hostName.split(":").at(1).toInt();
|
|
||||||
serverCredentials.hostName = serverCredentials.hostName.split(":").at(0);
|
|
||||||
}
|
|
||||||
serverCredentials.userName = lineEditLoginText();
|
|
||||||
if (pushButtonConnectKeyChecked()) {
|
|
||||||
QString key = textEditSshKeyText();
|
|
||||||
if (key.startsWith("ssh-rsa")) {
|
|
||||||
emit uiLogic()->showPublicKeyWarning();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (key.contains("OPENSSH") && key.contains("BEGIN") && key.contains("PRIVATE KEY")) {
|
|
||||||
key = m_configurator->sshConfigurator->convertOpenSShKey(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
serverCredentials.secretData = key;
|
|
||||||
} else {
|
|
||||||
serverCredentials.secretData = lineEditPasswordText();
|
|
||||||
}
|
|
||||||
|
|
||||||
set_pushButtonConnectEnabled(false);
|
|
||||||
set_pushButtonConnectText(tr("Connecting..."));
|
|
||||||
|
|
||||||
ServerController serverController(m_settings);
|
|
||||||
ErrorCode errorCode = ErrorCode::NoError;
|
|
||||||
|
|
||||||
if (pushButtonConnectKeyChecked()) {
|
|
||||||
auto passphraseCallback = [this, &serverController]() {
|
|
||||||
emit showPassphraseRequestMessage();
|
|
||||||
QEventLoop loop;
|
|
||||||
QObject::connect(this, &StartPageLogic::passphraseDialogClosed, &loop, &QEventLoop::quit);
|
|
||||||
loop.exec();
|
|
||||||
|
|
||||||
return m_privateKeyPassphrase;
|
|
||||||
};
|
|
||||||
|
|
||||||
QString decryptedPrivateKey;
|
|
||||||
errorCode = serverController.getDecryptedPrivateKey(serverCredentials, decryptedPrivateKey, passphraseCallback);
|
|
||||||
if (errorCode == ErrorCode::NoError) {
|
|
||||||
serverCredentials.secretData = decryptedPrivateKey;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString output;
|
|
||||||
if (errorCode == ErrorCode::NoError) {
|
|
||||||
output = serverController.checkSshConnection(serverCredentials, &errorCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ok = true;
|
|
||||||
if (errorCode) {
|
|
||||||
set_labelWaitInfoVisible(true);
|
|
||||||
set_labelWaitInfoText(errorString(errorCode));
|
|
||||||
ok = false;
|
|
||||||
} else {
|
|
||||||
if (output.contains("Please login as the user")) {
|
|
||||||
output.replace("\n", "");
|
|
||||||
set_labelWaitInfoVisible(true);
|
|
||||||
set_labelWaitInfoText(output);
|
|
||||||
ok = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
set_pushButtonConnectEnabled(true);
|
|
||||||
set_pushButtonConnectText(tr("Connect"));
|
|
||||||
|
|
||||||
uiLogic()->m_installCredentials = serverCredentials;
|
|
||||||
if (ok)
|
|
||||||
emit uiLogic()->goToPage(Page::NewServer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void StartPageLogic::onPushButtonImport()
|
|
||||||
{
|
|
||||||
importConnectionFromCode(lineEditStartExistingCodeText());
|
|
||||||
}
|
|
||||||
|
|
||||||
void StartPageLogic::onPushButtonImportOpenFile()
|
|
||||||
{
|
|
||||||
QString fileName = UiLogic::getOpenFileName(Q_NULLPTR, tr("Open config file"),
|
|
||||||
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),
|
|
||||||
"*.vpn *.ovpn *.conf");
|
|
||||||
if (fileName.isEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
QFile file(fileName);
|
|
||||||
|
|
||||||
#ifdef Q_OS_IOS
|
|
||||||
CFURLRef url = CFURLCreateWithFileSystemPath(
|
|
||||||
kCFAllocatorDefault,
|
|
||||||
CFStringCreateWithCharacters(0, reinterpret_cast<const UniChar *>(fileName.unicode()), fileName.length()),
|
|
||||||
kCFURLPOSIXPathStyle, 0);
|
|
||||||
|
|
||||||
if (!CFURLStartAccessingSecurityScopedResource(url)) {
|
|
||||||
qDebug() << "Could not access path " << QUrl::fromLocalFile(fileName).toString();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
file.open(QIODevice::ReadOnly);
|
|
||||||
QByteArray data = file.readAll();
|
|
||||||
|
|
||||||
importAnyFile(QString(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef Q_OS_ANDROID
|
|
||||||
void StartPageLogic::startQrDecoder()
|
|
||||||
{
|
|
||||||
AndroidController::instance()->startQrReaderActivity();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void StartPageLogic::importAnyFile(const QString &configData)
|
|
||||||
{
|
|
||||||
auto configFormat = checkConfigFormat(configData);
|
|
||||||
if (configFormat == ConfigTypes::OpenVpn) {
|
|
||||||
importConnectionFromOpenVpnConfig(configData);
|
|
||||||
} else if (configFormat == ConfigTypes::WireGuard) {
|
|
||||||
importConnectionFromWireguardConfig(configData);
|
|
||||||
} else {
|
|
||||||
importConnectionFromCode(configData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool StartPageLogic::importConnection(const QJsonObject &profile)
|
|
||||||
{
|
|
||||||
ServerCredentials credentials;
|
|
||||||
credentials.hostName = profile.value(config_key::hostName).toString();
|
|
||||||
credentials.port = profile.value(config_key::port).toInt();
|
|
||||||
credentials.userName = profile.value(config_key::userName).toString();
|
|
||||||
credentials.secretData = profile.value(config_key::password).toString();
|
|
||||||
|
|
||||||
if (credentials.isValid() || profile.contains(config_key::containers)) {
|
|
||||||
// check config
|
|
||||||
uiLogic()->pageLogic<ViewConfigLogic>()->set_configJson(profile);
|
|
||||||
emit uiLogic()->goToPage(Page::ViewConfig);
|
|
||||||
} else {
|
|
||||||
qDebug() << "Failed to import profile";
|
|
||||||
qDebug().noquote() << QJsonDocument(profile).toJson();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool StartPageLogic::importConnectionFromCode(QString code)
|
|
||||||
{
|
|
||||||
code.replace("vpn://", "");
|
|
||||||
QByteArray ba = QByteArray::fromBase64(code.toUtf8(), QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
|
|
||||||
|
|
||||||
QByteArray ba_uncompressed = qUncompress(ba);
|
|
||||||
if (!ba_uncompressed.isEmpty()) {
|
|
||||||
ba = ba_uncompressed;
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonObject o;
|
|
||||||
o = QJsonDocument::fromJson(ba).object();
|
|
||||||
if (!o.isEmpty()) {
|
|
||||||
return importConnection(o);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool StartPageLogic::importConnectionFromQr(const QByteArray &data)
|
|
||||||
{
|
|
||||||
QJsonObject dataObj = QJsonDocument::fromJson(data).object();
|
|
||||||
if (!dataObj.isEmpty()) {
|
|
||||||
return importConnection(dataObj);
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray ba_uncompressed = qUncompress(data);
|
|
||||||
if (!ba_uncompressed.isEmpty()) {
|
|
||||||
return importConnection(QJsonDocument::fromJson(ba_uncompressed).object());
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool StartPageLogic::importConnectionFromOpenVpnConfig(const QString &config)
|
|
||||||
{
|
|
||||||
QJsonObject openVpnConfig;
|
|
||||||
openVpnConfig[config_key::config] = config;
|
|
||||||
|
|
||||||
QJsonObject lastConfig;
|
|
||||||
lastConfig[config_key::last_config] = QString(QJsonDocument(openVpnConfig).toJson());
|
|
||||||
lastConfig[config_key::isThirdPartyConfig] = true;
|
|
||||||
|
|
||||||
QJsonObject containers;
|
|
||||||
containers.insert(config_key::container, QJsonValue("amnezia-openvpn"));
|
|
||||||
containers.insert(config_key::openvpn, QJsonValue(lastConfig));
|
|
||||||
|
|
||||||
QJsonArray arr;
|
|
||||||
arr.push_back(containers);
|
|
||||||
|
|
||||||
QString hostName;
|
|
||||||
const static QRegularExpression hostNameRegExp("remote (.*) [0-9]*");
|
|
||||||
QRegularExpressionMatch hostNameMatch = hostNameRegExp.match(config);
|
|
||||||
if (hostNameMatch.hasMatch()) {
|
|
||||||
hostName = hostNameMatch.captured(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonObject o;
|
|
||||||
o[config_key::containers] = arr;
|
|
||||||
o[config_key::defaultContainer] = "amnezia-openvpn";
|
|
||||||
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)");
|
|
||||||
QRegularExpressionMatchIterator dnsMatch = dnsRegExp.globalMatch(config);
|
|
||||||
if (dnsMatch.hasNext()) {
|
|
||||||
o[config_key::dns1] = dnsMatch.next().captured(1);
|
|
||||||
}
|
|
||||||
if (dnsMatch.hasNext()) {
|
|
||||||
o[config_key::dns2] = dnsMatch.next().captured(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
o[config_key::hostName] = hostName;
|
|
||||||
|
|
||||||
return importConnection(o);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool StartPageLogic::importConnectionFromWireguardConfig(const QString &config)
|
|
||||||
{
|
|
||||||
QJsonObject lastConfig;
|
|
||||||
lastConfig[config_key::config] = config;
|
|
||||||
|
|
||||||
const static QRegularExpression hostNameAndPortRegExp("Endpoint = (.*):([0-9]*)");
|
|
||||||
QRegularExpressionMatch hostNameAndPortMatch = hostNameAndPortRegExp.match(config);
|
|
||||||
QString hostName;
|
|
||||||
QString port;
|
|
||||||
if (hostNameAndPortMatch.hasMatch()) {
|
|
||||||
hostName = hostNameAndPortMatch.captured(1);
|
|
||||||
port = hostNameAndPortMatch.captured(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonObject wireguardConfig;
|
|
||||||
wireguardConfig[config_key::last_config] = QString(QJsonDocument(lastConfig).toJson());
|
|
||||||
wireguardConfig[config_key::isThirdPartyConfig] = true;
|
|
||||||
wireguardConfig[config_key::port] = port;
|
|
||||||
wireguardConfig[config_key::transport_proto] = "udp";
|
|
||||||
|
|
||||||
QJsonObject containers;
|
|
||||||
containers.insert(config_key::container, QJsonValue("amnezia-wireguard"));
|
|
||||||
containers.insert(config_key::wireguard, QJsonValue(wireguardConfig));
|
|
||||||
|
|
||||||
QJsonArray arr;
|
|
||||||
arr.push_back(containers);
|
|
||||||
|
|
||||||
QJsonObject o;
|
|
||||||
o[config_key::containers] = arr;
|
|
||||||
o[config_key::defaultContainer] = "amnezia-wireguard";
|
|
||||||
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)");
|
|
||||||
QRegularExpressionMatch dnsMatch = dnsRegExp.match(config);
|
|
||||||
if (dnsMatch.hasMatch()) {
|
|
||||||
o[config_key::dns1] = dnsMatch.captured(1);
|
|
||||||
o[config_key::dns2] = dnsMatch.captured(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
o[config_key::hostName] = hostName;
|
|
||||||
|
|
||||||
return importConnection(o);
|
|
||||||
}
|
|
||||||
|
|
@ -1,56 +0,0 @@
|
||||||
#ifndef START_PAGE_LOGIC_H
|
|
||||||
#define START_PAGE_LOGIC_H
|
|
||||||
|
|
||||||
#include "PageLogicBase.h"
|
|
||||||
|
|
||||||
#include <QRegularExpression>
|
|
||||||
|
|
||||||
class UiLogic;
|
|
||||||
|
|
||||||
class StartPageLogic : public PageLogicBase
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
AUTO_PROPERTY(bool, pushButtonConnectEnabled)
|
|
||||||
AUTO_PROPERTY(bool, pushButtonConnectKeyChecked)
|
|
||||||
AUTO_PROPERTY(QString, pushButtonConnectText)
|
|
||||||
AUTO_PROPERTY(QString, lineEditStartExistingCodeText)
|
|
||||||
AUTO_PROPERTY(QString, textEditSshKeyText)
|
|
||||||
AUTO_PROPERTY(QString, lineEditIpText)
|
|
||||||
AUTO_PROPERTY(QString, lineEditPasswordText)
|
|
||||||
AUTO_PROPERTY(QString, lineEditLoginText)
|
|
||||||
AUTO_PROPERTY(bool, labelWaitInfoVisible)
|
|
||||||
AUTO_PROPERTY(QString, labelWaitInfoText)
|
|
||||||
AUTO_PROPERTY(bool, pushButtonBackFromStartVisible)
|
|
||||||
|
|
||||||
AUTO_PROPERTY(QString, privateKeyPassphrase)
|
|
||||||
|
|
||||||
READONLY_PROPERTY(QRegularExpression, ipAddressPortRegex)
|
|
||||||
public:
|
|
||||||
Q_INVOKABLE void onUpdatePage() override;
|
|
||||||
|
|
||||||
Q_INVOKABLE void onPushButtonConnect();
|
|
||||||
Q_INVOKABLE void onPushButtonImport();
|
|
||||||
Q_INVOKABLE void onPushButtonImportOpenFile();
|
|
||||||
|
|
||||||
#ifdef Q_OS_ANDROID
|
|
||||||
Q_INVOKABLE void startQrDecoder();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void importAnyFile(const QString &configData);
|
|
||||||
|
|
||||||
bool importConnection(const QJsonObject &profile);
|
|
||||||
bool importConnectionFromCode(QString code);
|
|
||||||
bool importConnectionFromQr(const QByteArray &data);
|
|
||||||
bool importConnectionFromOpenVpnConfig(const QString &config);
|
|
||||||
bool importConnectionFromWireguardConfig(const QString &config);
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit StartPageLogic(UiLogic *uiLogic, QObject *parent = nullptr);
|
|
||||||
~StartPageLogic() = default;
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void showPassphraseRequestMessage();
|
|
||||||
void passphraseDialogClosed();
|
|
||||||
};
|
|
||||||
#endif // START_PAGE_LOGIC_H
|
|
||||||
|
|
@ -1,93 +0,0 @@
|
||||||
#include "ViewConfigLogic.h"
|
|
||||||
#include "core/errorstrings.h"
|
|
||||||
#include "../uilogic.h"
|
|
||||||
|
|
||||||
|
|
||||||
ViewConfigLogic::ViewConfigLogic(UiLogic *logic, QObject *parent):
|
|
||||||
PageLogicBase(logic, parent)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void ViewConfigLogic::onUpdatePage()
|
|
||||||
{
|
|
||||||
set_configText(QJsonDocument(configJson()).toJson());
|
|
||||||
|
|
||||||
auto s = configJson()[config_key::isThirdPartyConfig].toBool();
|
|
||||||
|
|
||||||
m_openVpnLastConfigs = m_openVpnMalStrings =
|
|
||||||
"<style> \
|
|
||||||
div { line-height: 0.5; } \
|
|
||||||
</style><div>";
|
|
||||||
|
|
||||||
m_warningStringNumber = 3;
|
|
||||||
m_warningActive = false;
|
|
||||||
|
|
||||||
const QJsonArray &containers = configJson()[config_key::containers].toArray();
|
|
||||||
int i = 0;
|
|
||||||
for (const QJsonValue &v: containers) {
|
|
||||||
auto containerName = v.toObject()[config_key::container].toString();
|
|
||||||
QJsonObject containerConfig = v.toObject()[containerName.replace("amnezia-", "")].toObject();
|
|
||||||
if (containerConfig[config_key::isThirdPartyConfig].toBool()) {
|
|
||||||
auto lastConfig = containerConfig.value(config_key::last_config).toString();
|
|
||||||
auto lastConfigJson = QJsonDocument::fromJson(lastConfig.toUtf8()).object();
|
|
||||||
QStringList lines = lastConfigJson.value(config_key::config).toString().replace("\r", "").split("\n");
|
|
||||||
QString lastConfigText;
|
|
||||||
for (const QString &l: lines) {
|
|
||||||
lastConfigText.append(l + "\n");
|
|
||||||
}
|
|
||||||
set_configText(lastConfigText);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (v.toObject()[config_key::container].toString() == "amnezia-openvpn") {
|
|
||||||
QString lastConfig = v.toObject()[ProtocolProps::protoToString(Proto::OpenVpn)]
|
|
||||||
.toObject()[config_key::last_config].toString();
|
|
||||||
|
|
||||||
QString lastConfigJson = QJsonDocument::fromJson(lastConfig.toUtf8()).object()[config_key::config]
|
|
||||||
.toString();
|
|
||||||
|
|
||||||
QStringList lines = lastConfigJson.replace("\r", "").split("\n");
|
|
||||||
for (const QString &l: lines) {
|
|
||||||
i++;
|
|
||||||
QRegularExpressionMatch match = m_re.match(l);
|
|
||||||
if (dangerousTags.contains(match.captured(0))) {
|
|
||||||
QString t = QString("<p><font color=\"red\">%1</font>").arg(l);
|
|
||||||
m_openVpnLastConfigs.append(t + "\n");
|
|
||||||
m_openVpnMalStrings.append(t);
|
|
||||||
if (m_warningStringNumber == 3) m_warningStringNumber = i - 3;
|
|
||||||
m_warningActive = true;
|
|
||||||
qDebug() << "ViewConfigLogic : malicious scripts warning:" << l;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
m_openVpnLastConfigs.append("<p>" + l + " \n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
emit openVpnLastConfigsChanged(m_openVpnLastConfigs);
|
|
||||||
emit openVpnMalStringsChanged(m_openVpnMalStrings);
|
|
||||||
emit warningStringNumberChanged(m_warningStringNumber);
|
|
||||||
emit warningActiveChanged(m_warningActive);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ViewConfigLogic::importConfig()
|
|
||||||
{
|
|
||||||
m_settings->addServer(configJson());
|
|
||||||
m_settings->setDefaultServer(m_settings->serversCount() - 1);
|
|
||||||
|
|
||||||
|
|
||||||
if (!configJson().contains(config_key::containers) || configJson().value(config_key::containers).toArray().isEmpty()) {
|
|
||||||
uiLogic()->m_selectedServerIndex = m_settings->defaultServerIndex();
|
|
||||||
uiLogic()->m_selectedDockerContainer = m_settings->defaultContainer(uiLogic()->m_selectedServerIndex);
|
|
||||||
uiLogic()->onUpdateAllPages();
|
|
||||||
emit uiLogic()->goToPage(Page::Vpn);
|
|
||||||
emit uiLogic()->setStartPage(Page::Vpn);
|
|
||||||
emit uiLogic()->goToPage(Page::ServerContainers);
|
|
||||||
} else {
|
|
||||||
emit uiLogic()->goToPage(Page::Vpn);
|
|
||||||
emit uiLogic()->setStartPage(Page::Vpn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
||||||
#ifndef VIEW_CONFIG_LOGIC_H
|
|
||||||
#define VIEW_CONFIG_LOGIC_H
|
|
||||||
|
|
||||||
#include "PageLogicBase.h"
|
|
||||||
|
|
||||||
#include <QJsonObject>
|
|
||||||
|
|
||||||
class UiLogic;
|
|
||||||
|
|
||||||
class ViewConfigLogic : public PageLogicBase
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
AUTO_PROPERTY(QString, configText)
|
|
||||||
AUTO_PROPERTY(QString, openVpnLastConfigs)
|
|
||||||
AUTO_PROPERTY(QString, openVpnMalStrings)
|
|
||||||
AUTO_PROPERTY(QJsonObject, configJson)
|
|
||||||
AUTO_PROPERTY(int, warningStringNumber)
|
|
||||||
AUTO_PROPERTY(bool, warningActive)
|
|
||||||
|
|
||||||
public:
|
|
||||||
Q_INVOKABLE void onUpdatePage() override;
|
|
||||||
Q_INVOKABLE void importConfig();
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit ViewConfigLogic(UiLogic *uiLogic, QObject *parent = nullptr);
|
|
||||||
~ViewConfigLogic() = default;
|
|
||||||
|
|
||||||
private:
|
|
||||||
QRegularExpression m_re {"(\\w+-\\w+|\\w+)"};
|
|
||||||
|
|
||||||
// https://github.com/OpenVPN/openvpn/blob/master/doc/man-sections/script-options.rst
|
|
||||||
QStringList dangerousTags {
|
|
||||||
"up",
|
|
||||||
"tls-verify",
|
|
||||||
"ipchange",
|
|
||||||
"client-connect",
|
|
||||||
"route-up",
|
|
||||||
"route-pre-down",
|
|
||||||
"client-disconnect",
|
|
||||||
"down",
|
|
||||||
"learn-address",
|
|
||||||
"auth-user-pass-verify"
|
|
||||||
};
|
|
||||||
};
|
|
||||||
#endif // VIEW_CONFIG_LOGIC_H
|
|
||||||
|
|
@ -1,245 +0,0 @@
|
||||||
#include <QApplication>
|
|
||||||
|
|
||||||
#include "VpnLogic.h"
|
|
||||||
|
|
||||||
#include "core/errorstrings.h"
|
|
||||||
#include "vpnconnection.h"
|
|
||||||
#include <QTimer>
|
|
||||||
#include <functional>
|
|
||||||
#include "../uilogic.h"
|
|
||||||
#include "version.h"
|
|
||||||
#include <configurators/vpn_configurator.h>
|
|
||||||
|
|
||||||
|
|
||||||
VpnLogic::VpnLogic(UiLogic *logic, QObject *parent):
|
|
||||||
PageLogicBase(logic, parent),
|
|
||||||
m_pushButtonConnectChecked{false},
|
|
||||||
|
|
||||||
m_radioButtonVpnModeAllSitesChecked{true},
|
|
||||||
m_radioButtonVpnModeForwardSitesChecked{false},
|
|
||||||
m_radioButtonVpnModeExceptSitesChecked{false},
|
|
||||||
|
|
||||||
m_labelSpeedReceivedText{tr("0 Mbps")},
|
|
||||||
m_labelSpeedSentText{tr("0 Mbps")},
|
|
||||||
m_labelStateText{},
|
|
||||||
m_isContainerHaveAuthData{false},
|
|
||||||
m_isContainerSupportedByCurrentPlatform{false},
|
|
||||||
m_widgetVpnModeEnabled{false}
|
|
||||||
{
|
|
||||||
connect(uiLogic()->m_vpnConnection, &VpnConnection::bytesChanged, this, &VpnLogic::onBytesChanged);
|
|
||||||
connect(uiLogic()->m_vpnConnection, &VpnConnection::connectionStateChanged, this, &VpnLogic::onConnectionStateChanged);
|
|
||||||
connect(uiLogic()->m_vpnConnection, &VpnConnection::vpnProtocolError, this, &VpnLogic::onVpnProtocolError);
|
|
||||||
|
|
||||||
connect(this, &VpnLogic::connectToVpn, uiLogic()->m_vpnConnection, &VpnConnection::connectToVpn, Qt::QueuedConnection);
|
|
||||||
connect(this, &VpnLogic::disconnectFromVpn, uiLogic()->m_vpnConnection, &VpnConnection::disconnectFromVpn, Qt::QueuedConnection);
|
|
||||||
|
|
||||||
connect(m_settings.get(), &Settings::saveLogsChanged, this, &VpnLogic::onUpdatePage);
|
|
||||||
|
|
||||||
if (m_settings->isAutoConnect() && m_settings->defaultServerIndex() >= 0) {
|
|
||||||
QTimer::singleShot(1000, this, [this](){
|
|
||||||
set_pushButtonConnectEnabled(false);
|
|
||||||
onConnect();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
onConnectionStateChanged(Vpn::ConnectionState::Disconnected);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void VpnLogic::onUpdatePage()
|
|
||||||
{
|
|
||||||
Settings::RouteMode mode = m_settings->routeMode();
|
|
||||||
DockerContainer selectedContainer = m_settings->defaultContainer(m_settings->defaultServerIndex());
|
|
||||||
|
|
||||||
set_isCustomRoutesSupported (selectedContainer == DockerContainer::OpenVpn ||
|
|
||||||
selectedContainer == DockerContainer::ShadowSocks||
|
|
||||||
selectedContainer == DockerContainer::Cloak);
|
|
||||||
|
|
||||||
set_isContainerHaveAuthData(m_settings->haveAuthData(m_settings->defaultServerIndex()));
|
|
||||||
|
|
||||||
set_radioButtonVpnModeAllSitesChecked(mode == Settings::VpnAllSites || !isCustomRoutesSupported());
|
|
||||||
set_radioButtonVpnModeForwardSitesChecked(mode == Settings::VpnOnlyForwardSites && isCustomRoutesSupported());
|
|
||||||
set_radioButtonVpnModeExceptSitesChecked(mode == Settings::VpnAllExceptSites && isCustomRoutesSupported());
|
|
||||||
|
|
||||||
const QJsonObject &server = uiLogic()->m_settings->defaultServer();
|
|
||||||
QString serverString = QString("%2 (%3)")
|
|
||||||
.arg(server.value(config_key::description).toString())
|
|
||||||
.arg(server.value(config_key::hostName).toString());
|
|
||||||
set_labelCurrentServer(serverString);
|
|
||||||
|
|
||||||
QString selectedContainerName = ContainerProps::containerHumanNames().value(selectedContainer);
|
|
||||||
set_labelCurrentService(selectedContainerName);
|
|
||||||
|
|
||||||
auto dns = m_configurator->getDnsForConfig(m_settings->defaultServerIndex());
|
|
||||||
set_amneziaDnsEnabled(dns.first == protocols::dns::amneziaDnsIp);
|
|
||||||
if (dns.first == protocols::dns::amneziaDnsIp) {
|
|
||||||
set_labelCurrentDns("On your server");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
set_labelCurrentDns(dns.first + ", " + dns.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
set_isContainerSupportedByCurrentPlatform(ContainerProps::isSupportedByCurrentPlatform(selectedContainer));
|
|
||||||
if (!isContainerSupportedByCurrentPlatform()) {
|
|
||||||
set_labelErrorText(tr("AmneziaVPN not supporting selected protocol on this device. Select another protocol."));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
set_labelErrorText("");
|
|
||||||
}
|
|
||||||
QString ver = QString("v. %2").arg(QString(APP_MAJOR_VERSION));
|
|
||||||
set_labelVersionText(ver);
|
|
||||||
|
|
||||||
set_labelLogEnabledVisible(m_settings->isSaveLogs());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void VpnLogic::onRadioButtonVpnModeAllSitesClicked()
|
|
||||||
{
|
|
||||||
m_settings->setRouteMode(Settings::VpnAllSites);
|
|
||||||
onUpdatePage();
|
|
||||||
}
|
|
||||||
|
|
||||||
void VpnLogic::onRadioButtonVpnModeForwardSitesClicked()
|
|
||||||
{
|
|
||||||
m_settings->setRouteMode(Settings::VpnOnlyForwardSites);
|
|
||||||
onUpdatePage();
|
|
||||||
}
|
|
||||||
|
|
||||||
void VpnLogic::onRadioButtonVpnModeExceptSitesClicked()
|
|
||||||
{
|
|
||||||
m_settings->setRouteMode(Settings::VpnAllExceptSites);
|
|
||||||
onUpdatePage();
|
|
||||||
}
|
|
||||||
|
|
||||||
void VpnLogic::onBytesChanged(quint64 receivedData, quint64 sentData)
|
|
||||||
{
|
|
||||||
set_labelSpeedReceivedText(VpnConnection::bytesPerSecToText(receivedData));
|
|
||||||
set_labelSpeedSentText(VpnConnection::bytesPerSecToText(sentData));
|
|
||||||
}
|
|
||||||
|
|
||||||
void VpnLogic::onConnectionStateChanged(Vpn::ConnectionState state)
|
|
||||||
{
|
|
||||||
qDebug() << "VpnLogic::onConnectionStateChanged" << VpnProtocol::textConnectionState(state);
|
|
||||||
if (uiLogic()->m_vpnConnection == NULL) {
|
|
||||||
qDebug() << "VpnLogic::onConnectionStateChanged" << VpnProtocol::textConnectionState(state) << "невозможно, соединение отсутствует (уничтожено ранее)";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
bool pbConnectEnabled = false;
|
|
||||||
bool pbConnectChecked = false;
|
|
||||||
|
|
||||||
bool rbModeEnabled = false;
|
|
||||||
bool pbConnectVisible = false;
|
|
||||||
set_labelStateText(VpnProtocol::textConnectionState(state));
|
|
||||||
|
|
||||||
switch (state) {
|
|
||||||
case Vpn::ConnectionState::Disconnected:
|
|
||||||
onBytesChanged(0,0);
|
|
||||||
pbConnectChecked = false;
|
|
||||||
pbConnectEnabled = true;
|
|
||||||
pbConnectVisible = true;
|
|
||||||
rbModeEnabled = true;
|
|
||||||
break;
|
|
||||||
case Vpn::ConnectionState::Preparing:
|
|
||||||
pbConnectChecked = true;
|
|
||||||
pbConnectEnabled = false;
|
|
||||||
pbConnectVisible = false;
|
|
||||||
rbModeEnabled = false;
|
|
||||||
break;
|
|
||||||
case Vpn::ConnectionState::Connecting:
|
|
||||||
pbConnectChecked = true;
|
|
||||||
pbConnectEnabled = true;
|
|
||||||
pbConnectVisible = false;
|
|
||||||
rbModeEnabled = false;
|
|
||||||
break;
|
|
||||||
case Vpn::ConnectionState::Connected:
|
|
||||||
pbConnectChecked = true;
|
|
||||||
pbConnectEnabled = true;
|
|
||||||
pbConnectVisible = true;
|
|
||||||
rbModeEnabled = false;
|
|
||||||
break;
|
|
||||||
case Vpn::ConnectionState::Disconnecting:
|
|
||||||
pbConnectChecked = false;
|
|
||||||
pbConnectEnabled = false;
|
|
||||||
pbConnectVisible = false;
|
|
||||||
rbModeEnabled = false;
|
|
||||||
break;
|
|
||||||
case Vpn::ConnectionState::Reconnecting:
|
|
||||||
pbConnectChecked = true;
|
|
||||||
pbConnectEnabled = true;
|
|
||||||
pbConnectVisible = false;
|
|
||||||
rbModeEnabled = false;
|
|
||||||
break;
|
|
||||||
case Vpn::ConnectionState::Error:
|
|
||||||
pbConnectChecked = false;
|
|
||||||
pbConnectEnabled = true;
|
|
||||||
pbConnectVisible = true;
|
|
||||||
rbModeEnabled = true;
|
|
||||||
break;
|
|
||||||
case Vpn::ConnectionState::Unknown:
|
|
||||||
pbConnectChecked = false;
|
|
||||||
pbConnectEnabled = true;
|
|
||||||
pbConnectVisible = true;
|
|
||||||
rbModeEnabled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
set_pushButtonConnectEnabled(pbConnectEnabled);
|
|
||||||
set_pushButtonConnectChecked(pbConnectChecked);
|
|
||||||
|
|
||||||
set_pushButtonConnectVisible(pbConnectVisible);
|
|
||||||
set_widgetVpnModeEnabled(rbModeEnabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
void VpnLogic::onVpnProtocolError(ErrorCode errorCode)
|
|
||||||
{
|
|
||||||
set_labelErrorText(errorString(errorCode));
|
|
||||||
}
|
|
||||||
|
|
||||||
void VpnLogic::onPushButtonConnectClicked()
|
|
||||||
{
|
|
||||||
if (! pushButtonConnectChecked()) {
|
|
||||||
onConnect();
|
|
||||||
} else {
|
|
||||||
onDisconnect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void VpnLogic::onConnect()
|
|
||||||
{
|
|
||||||
int serverIndex = m_settings->defaultServerIndex();
|
|
||||||
ServerCredentials credentials = m_settings->serverCredentials(serverIndex);
|
|
||||||
DockerContainer container = m_settings->defaultContainer(serverIndex);
|
|
||||||
|
|
||||||
if (m_settings->containers(serverIndex).isEmpty()) {
|
|
||||||
set_labelErrorText(tr("VPN Protocols is not installed.\n Please install VPN container at first"));
|
|
||||||
set_pushButtonConnectChecked(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (container == DockerContainer::None) {
|
|
||||||
set_labelErrorText(tr("VPN Protocol not chosen"));
|
|
||||||
set_pushButtonConnectChecked(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const QJsonObject &containerConfig = m_settings->containerConfig(serverIndex, container);
|
|
||||||
onConnectWorker(serverIndex, credentials, container, containerConfig);
|
|
||||||
}
|
|
||||||
|
|
||||||
void VpnLogic::onConnectWorker(int serverIndex, const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig)
|
|
||||||
{
|
|
||||||
set_labelErrorText("");
|
|
||||||
set_pushButtonConnectChecked(true);
|
|
||||||
set_pushButtonConnectEnabled(false);
|
|
||||||
|
|
||||||
qApp->processEvents();
|
|
||||||
|
|
||||||
emit connectToVpn(serverIndex, credentials, container, containerConfig);
|
|
||||||
}
|
|
||||||
|
|
||||||
void VpnLogic::onDisconnect()
|
|
||||||
{
|
|
||||||
onConnectionStateChanged(Vpn::ConnectionState::Disconnected);
|
|
||||||
emit disconnectFromVpn();
|
|
||||||
}
|
|
||||||
|
|
@ -1,70 +0,0 @@
|
||||||
#ifndef VPN_LOGIC_H
|
|
||||||
#define VPN_LOGIC_H
|
|
||||||
|
|
||||||
#include "PageLogicBase.h"
|
|
||||||
#include "protocols/vpnprotocol.h"
|
|
||||||
|
|
||||||
class UiLogic;
|
|
||||||
|
|
||||||
class VpnLogic : public PageLogicBase
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
AUTO_PROPERTY(bool, pushButtonConnectChecked)
|
|
||||||
AUTO_PROPERTY(QString, labelSpeedReceivedText)
|
|
||||||
AUTO_PROPERTY(QString, labelSpeedSentText)
|
|
||||||
AUTO_PROPERTY(QString, labelStateText)
|
|
||||||
AUTO_PROPERTY(QString, labelCurrentServer)
|
|
||||||
AUTO_PROPERTY(QString, labelCurrentService)
|
|
||||||
AUTO_PROPERTY(QString, labelCurrentDns)
|
|
||||||
AUTO_PROPERTY(bool, amneziaDnsEnabled)
|
|
||||||
|
|
||||||
AUTO_PROPERTY(bool, pushButtonConnectEnabled)
|
|
||||||
AUTO_PROPERTY(bool, pushButtonConnectVisible)
|
|
||||||
AUTO_PROPERTY(bool, widgetVpnModeEnabled)
|
|
||||||
AUTO_PROPERTY(bool, isContainerSupportedByCurrentPlatform)
|
|
||||||
AUTO_PROPERTY(bool, isContainerHaveAuthData)
|
|
||||||
|
|
||||||
AUTO_PROPERTY(QString, labelErrorText)
|
|
||||||
AUTO_PROPERTY(QString, labelVersionText)
|
|
||||||
|
|
||||||
AUTO_PROPERTY(bool, isCustomRoutesSupported)
|
|
||||||
|
|
||||||
AUTO_PROPERTY(bool, radioButtonVpnModeAllSitesChecked)
|
|
||||||
AUTO_PROPERTY(bool, radioButtonVpnModeForwardSitesChecked)
|
|
||||||
AUTO_PROPERTY(bool, radioButtonVpnModeExceptSitesChecked)
|
|
||||||
|
|
||||||
AUTO_PROPERTY(bool, labelLogEnabledVisible)
|
|
||||||
|
|
||||||
public:
|
|
||||||
Q_INVOKABLE void onUpdatePage() override;
|
|
||||||
|
|
||||||
Q_INVOKABLE void onRadioButtonVpnModeAllSitesClicked();
|
|
||||||
Q_INVOKABLE void onRadioButtonVpnModeForwardSitesClicked();
|
|
||||||
Q_INVOKABLE void onRadioButtonVpnModeExceptSitesClicked();
|
|
||||||
|
|
||||||
Q_INVOKABLE void onPushButtonConnectClicked();
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit VpnLogic(UiLogic *uiLogic, QObject *parent = nullptr);
|
|
||||||
~VpnLogic() = default;
|
|
||||||
|
|
||||||
bool getPushButtonConnectChecked() const;
|
|
||||||
void setPushButtonConnectChecked(bool pushButtonConnectChecked);
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void onConnect();
|
|
||||||
void onConnectWorker(int serverIndex, const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig);
|
|
||||||
void onDisconnect();
|
|
||||||
|
|
||||||
void onBytesChanged(quint64 receivedBytes, quint64 sentBytes);
|
|
||||||
void onConnectionStateChanged(Vpn::ConnectionState state);
|
|
||||||
void onVpnProtocolError(amnezia::ErrorCode errorCode);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void connectToVpn(int serverIndex,
|
|
||||||
const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig);
|
|
||||||
|
|
||||||
void disconnectFromVpn();
|
|
||||||
};
|
|
||||||
#endif // VPN_LOGIC_H
|
|
||||||
|
|
@ -1,70 +0,0 @@
|
||||||
#include "WizardLogic.h"
|
|
||||||
#include "../uilogic.h"
|
|
||||||
|
|
||||||
WizardLogic::WizardLogic(UiLogic *logic, QObject *parent):
|
|
||||||
PageLogicBase(logic, parent),
|
|
||||||
m_radioButtonHighChecked{false},
|
|
||||||
m_radioButtonMediumChecked{true},
|
|
||||||
m_radioButtonLowChecked{false},
|
|
||||||
m_lineEditHighWebsiteMaskingText{},
|
|
||||||
m_checkBoxVpnModeChecked{false}
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void WizardLogic::onUpdatePage()
|
|
||||||
{
|
|
||||||
set_lineEditHighWebsiteMaskingText(protocols::cloak::defaultRedirSite);
|
|
||||||
set_radioButtonMediumChecked(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
QPair<DockerContainer, QJsonObject> WizardLogic::getInstallConfigsFromWizardPage() const
|
|
||||||
{
|
|
||||||
QJsonObject cloakConfig {
|
|
||||||
{ config_key::container, ContainerProps::containerToString(DockerContainer::Cloak) },
|
|
||||||
{ ProtocolProps::protoToString(Proto::Cloak), QJsonObject {
|
|
||||||
{ config_key::site, lineEditHighWebsiteMaskingText() }}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
QJsonObject ssConfig {
|
|
||||||
{ config_key::container, ContainerProps::containerToString(DockerContainer::ShadowSocks) }
|
|
||||||
};
|
|
||||||
QJsonObject openVpnConfig {
|
|
||||||
{ config_key::container, ContainerProps::containerToString(DockerContainer::OpenVpn) }
|
|
||||||
};
|
|
||||||
|
|
||||||
QPair<DockerContainer, QJsonObject> container;
|
|
||||||
|
|
||||||
DockerContainer dockerContainer;
|
|
||||||
|
|
||||||
if (radioButtonHighChecked()) {
|
|
||||||
container = {DockerContainer::Cloak, cloakConfig};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (radioButtonMediumChecked()) {
|
|
||||||
container = {DockerContainer::ShadowSocks, ssConfig};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (radioButtonLowChecked()) {
|
|
||||||
container = {DockerContainer::OpenVpn, openVpnConfig};
|
|
||||||
}
|
|
||||||
|
|
||||||
return container;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WizardLogic::onPushButtonVpnModeFinishClicked()
|
|
||||||
{
|
|
||||||
auto container = getInstallConfigsFromWizardPage();
|
|
||||||
uiLogic()->installServer(container);
|
|
||||||
if (checkBoxVpnModeChecked()) {
|
|
||||||
m_settings->setRouteMode(Settings::VpnOnlyForwardSites);
|
|
||||||
} else {
|
|
||||||
m_settings->setRouteMode(Settings::VpnAllSites);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WizardLogic::onPushButtonLowFinishClicked()
|
|
||||||
{
|
|
||||||
auto container = getInstallConfigsFromWizardPage();
|
|
||||||
uiLogic()->installServer(container);
|
|
||||||
}
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
#ifndef WIZARD_LOGIC_H
|
|
||||||
#define WIZARD_LOGIC_H
|
|
||||||
|
|
||||||
#include "PageLogicBase.h"
|
|
||||||
#include "containers/containers_defs.h"
|
|
||||||
|
|
||||||
class UiLogic;
|
|
||||||
|
|
||||||
class WizardLogic : public PageLogicBase
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
AUTO_PROPERTY(bool, radioButtonHighChecked)
|
|
||||||
AUTO_PROPERTY(bool, radioButtonMediumChecked)
|
|
||||||
AUTO_PROPERTY(bool, radioButtonLowChecked)
|
|
||||||
AUTO_PROPERTY(bool, checkBoxVpnModeChecked)
|
|
||||||
AUTO_PROPERTY(QString, lineEditHighWebsiteMaskingText)
|
|
||||||
|
|
||||||
public:
|
|
||||||
Q_INVOKABLE void onUpdatePage() override;
|
|
||||||
Q_INVOKABLE void onPushButtonVpnModeFinishClicked();
|
|
||||||
Q_INVOKABLE void onPushButtonLowFinishClicked();
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit WizardLogic(UiLogic *uiLogic, QObject *parent = nullptr);
|
|
||||||
~WizardLogic() = default;
|
|
||||||
|
|
||||||
QPair<DockerContainer, QJsonObject> getInstallConfigsFromWizardPage() const;
|
|
||||||
|
|
||||||
};
|
|
||||||
#endif // WIZARD_LOGIC_H
|
|
||||||
|
|
@ -1,137 +0,0 @@
|
||||||
#include "CloakLogic.h"
|
|
||||||
|
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
#include "core/servercontroller.h"
|
|
||||||
#include "ui/uilogic.h"
|
|
||||||
#include "ui/pages_logic/ServerConfiguringProgressLogic.h"
|
|
||||||
|
|
||||||
using namespace amnezia;
|
|
||||||
using namespace PageEnumNS;
|
|
||||||
|
|
||||||
CloakLogic::CloakLogic(UiLogic *logic, QObject *parent):
|
|
||||||
PageProtocolLogicBase(logic, parent),
|
|
||||||
m_comboBoxCipherText{"chacha20-poly1305"},
|
|
||||||
m_lineEditSiteText{"tile.openstreetmap.org"},
|
|
||||||
m_lineEditPortText{},
|
|
||||||
m_pushButtonSaveVisible{false},
|
|
||||||
m_progressBarResetVisible{false},
|
|
||||||
m_lineEditPortEnabled{false},
|
|
||||||
m_pageEnabled{true},
|
|
||||||
m_labelInfoVisible{true},
|
|
||||||
m_labelInfoText{},
|
|
||||||
m_progressBarResetValue{0},
|
|
||||||
m_progressBarResetMaximum{100}
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void CloakLogic::updateProtocolPage(const QJsonObject &ckConfig, DockerContainer container, bool haveAuthData)
|
|
||||||
{
|
|
||||||
set_pageEnabled(haveAuthData);
|
|
||||||
set_pushButtonSaveVisible(haveAuthData);
|
|
||||||
set_progressBarResetVisible(haveAuthData);
|
|
||||||
|
|
||||||
set_comboBoxCipherText(ckConfig.value(config_key::cipher).
|
|
||||||
toString(protocols::cloak::defaultCipher));
|
|
||||||
|
|
||||||
set_lineEditSiteText(ckConfig.value(config_key::site).
|
|
||||||
toString(protocols::cloak::defaultRedirSite));
|
|
||||||
|
|
||||||
set_lineEditPortText(ckConfig.value(config_key::port).
|
|
||||||
toString(protocols::cloak::defaultPort));
|
|
||||||
|
|
||||||
set_lineEditPortEnabled(container == DockerContainer::Cloak);
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonObject CloakLogic::getProtocolConfigFromPage(QJsonObject oldConfig)
|
|
||||||
{
|
|
||||||
oldConfig.insert(config_key::cipher, comboBoxCipherText());
|
|
||||||
oldConfig.insert(config_key::site, lineEditSiteText());
|
|
||||||
oldConfig.insert(config_key::port, lineEditPortText());
|
|
||||||
|
|
||||||
return oldConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CloakLogic::onPushButtonSaveClicked()
|
|
||||||
{
|
|
||||||
QJsonObject protocolConfig = m_settings->protocolConfig(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer, Proto::Cloak);
|
|
||||||
protocolConfig = getProtocolConfigFromPage(protocolConfig);
|
|
||||||
|
|
||||||
QJsonObject containerConfig = m_settings->containerConfig(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer);
|
|
||||||
QJsonObject newContainerConfig = containerConfig;
|
|
||||||
newContainerConfig.insert(ProtocolProps::protoToString(Proto::Cloak), protocolConfig);
|
|
||||||
|
|
||||||
ServerConfiguringProgressLogic::PageFunc pageFunc;
|
|
||||||
pageFunc.setEnabledFunc = [this] (bool enabled) -> void {
|
|
||||||
set_pageEnabled(enabled);
|
|
||||||
};
|
|
||||||
ServerConfiguringProgressLogic::ButtonFunc saveButtonFunc;
|
|
||||||
saveButtonFunc.setVisibleFunc = [this] (bool visible) -> void {
|
|
||||||
set_pushButtonSaveVisible(visible);
|
|
||||||
};
|
|
||||||
ServerConfiguringProgressLogic::LabelFunc waitInfoFunc;
|
|
||||||
waitInfoFunc.setVisibleFunc = [this] (bool visible) -> void {
|
|
||||||
set_labelInfoVisible(visible);
|
|
||||||
};
|
|
||||||
waitInfoFunc.setTextFunc = [this] (const QString& text) -> void {
|
|
||||||
set_labelInfoText(text);
|
|
||||||
};
|
|
||||||
ServerConfiguringProgressLogic::ProgressFunc progressBarFunc;
|
|
||||||
progressBarFunc.setVisibleFunc = [this] (bool visible) -> void {
|
|
||||||
set_progressBarResetVisible(visible);
|
|
||||||
};
|
|
||||||
progressBarFunc.setValueFunc = [this] (int value) -> void {
|
|
||||||
set_progressBarResetValue(value);
|
|
||||||
};
|
|
||||||
progressBarFunc.getValueFunc = [this] (void) -> int {
|
|
||||||
return progressBarResetValue();
|
|
||||||
};
|
|
||||||
progressBarFunc.getMaximumFunc = [this] (void) -> int {
|
|
||||||
return progressBarResetMaximum();
|
|
||||||
};
|
|
||||||
progressBarFunc.setTextVisibleFunc = [this] (bool visible) -> void {
|
|
||||||
set_progressBarTextVisible(visible);
|
|
||||||
};
|
|
||||||
progressBarFunc.setTextFunc = [this] (const QString& text) -> void {
|
|
||||||
set_progressBarText(text);
|
|
||||||
};
|
|
||||||
|
|
||||||
ServerConfiguringProgressLogic::LabelFunc busyInfoFuncy;
|
|
||||||
busyInfoFuncy.setTextFunc = [this] (const QString& text) -> void {
|
|
||||||
set_labelServerBusyText(text);
|
|
||||||
};
|
|
||||||
busyInfoFuncy.setVisibleFunc = [this] (bool visible) -> void {
|
|
||||||
set_labelServerBusyVisible(visible);
|
|
||||||
};
|
|
||||||
|
|
||||||
ServerConfiguringProgressLogic::ButtonFunc cancelButtonFunc;
|
|
||||||
cancelButtonFunc.setVisibleFunc = [this] (bool visible) -> void {
|
|
||||||
set_pushButtonCancelVisible(visible);
|
|
||||||
};
|
|
||||||
|
|
||||||
progressBarFunc.setTextVisibleFunc(true);
|
|
||||||
progressBarFunc.setTextFunc(QString("Configuring..."));
|
|
||||||
|
|
||||||
auto installAction = [this, containerConfig, &newContainerConfig]() {
|
|
||||||
ServerController serverController(m_settings);
|
|
||||||
return serverController.updateContainer(m_settings->serverCredentials(uiLogic()->m_selectedServerIndex),
|
|
||||||
uiLogic()->m_selectedDockerContainer, containerConfig, newContainerConfig);
|
|
||||||
};
|
|
||||||
|
|
||||||
ErrorCode e = uiLogic()->pageLogic<ServerConfiguringProgressLogic>()->doInstallAction(installAction, pageFunc, progressBarFunc,
|
|
||||||
saveButtonFunc, waitInfoFunc,
|
|
||||||
busyInfoFuncy, cancelButtonFunc);
|
|
||||||
|
|
||||||
if (!e) {
|
|
||||||
m_settings->setContainerConfig(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer, newContainerConfig);
|
|
||||||
m_settings->clearLastConnectionConfig(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer);
|
|
||||||
}
|
|
||||||
|
|
||||||
qDebug() << "Protocol saved with code:" << e << "for" << uiLogic()->m_selectedServerIndex << uiLogic()->m_selectedDockerContainer;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CloakLogic::onPushButtonCancelClicked()
|
|
||||||
{
|
|
||||||
emit uiLogic()->pageLogic<ServerConfiguringProgressLogic>()->cancelDoInstallAction(true);
|
|
||||||
}
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
#ifndef CLOAK_LOGIC_H
|
|
||||||
#define CLOAK_LOGIC_H
|
|
||||||
|
|
||||||
#include "PageProtocolLogicBase.h"
|
|
||||||
|
|
||||||
class UiLogic;
|
|
||||||
|
|
||||||
class CloakLogic : public PageProtocolLogicBase
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
AUTO_PROPERTY(QString, comboBoxCipherText)
|
|
||||||
AUTO_PROPERTY(QString, lineEditSiteText)
|
|
||||||
AUTO_PROPERTY(QString, lineEditPortText)
|
|
||||||
AUTO_PROPERTY(bool, pushButtonSaveVisible)
|
|
||||||
AUTO_PROPERTY(bool, progressBarResetVisible)
|
|
||||||
AUTO_PROPERTY(bool, lineEditPortEnabled)
|
|
||||||
AUTO_PROPERTY(bool, pageEnabled)
|
|
||||||
AUTO_PROPERTY(bool, labelInfoVisible)
|
|
||||||
AUTO_PROPERTY(QString, labelInfoText)
|
|
||||||
AUTO_PROPERTY(int, progressBarResetValue)
|
|
||||||
AUTO_PROPERTY(int, progressBarResetMaximum)
|
|
||||||
AUTO_PROPERTY(bool, progressBarTextVisible)
|
|
||||||
AUTO_PROPERTY(QString, progressBarText)
|
|
||||||
|
|
||||||
AUTO_PROPERTY(bool, labelServerBusyVisible)
|
|
||||||
AUTO_PROPERTY(QString, labelServerBusyText)
|
|
||||||
|
|
||||||
AUTO_PROPERTY(bool, pushButtonCancelVisible)
|
|
||||||
|
|
||||||
public:
|
|
||||||
Q_INVOKABLE void onPushButtonSaveClicked();
|
|
||||||
Q_INVOKABLE void onPushButtonCancelClicked();
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit CloakLogic(UiLogic *uiLogic, QObject *parent = nullptr);
|
|
||||||
~CloakLogic() = default;
|
|
||||||
|
|
||||||
void updateProtocolPage(const QJsonObject &ckConfig, DockerContainer container, bool haveAuthData) override;
|
|
||||||
QJsonObject getProtocolConfigFromPage(QJsonObject oldConfig) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
UiLogic *m_uiLogic;
|
|
||||||
|
|
||||||
};
|
|
||||||
#endif // CLOAK_LOGIC_H
|
|
||||||
|
|
@ -1,203 +0,0 @@
|
||||||
#include "OpenVpnLogic.h"
|
|
||||||
|
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
#include "core/servercontroller.h"
|
|
||||||
#include "ui/uilogic.h"
|
|
||||||
#include "ui/pages_logic/ServerConfiguringProgressLogic.h"
|
|
||||||
|
|
||||||
using namespace amnezia;
|
|
||||||
using namespace PageEnumNS;
|
|
||||||
|
|
||||||
OpenVpnLogic::OpenVpnLogic(UiLogic *logic, QObject *parent):
|
|
||||||
PageProtocolLogicBase(logic, parent),
|
|
||||||
m_lineEditSubnetText{""},
|
|
||||||
|
|
||||||
m_radioButtonTcpEnabled{true},
|
|
||||||
m_radioButtonTcpChecked{false},
|
|
||||||
m_radioButtonUdpEnabled{true},
|
|
||||||
m_radioButtonUdpChecked{false},
|
|
||||||
|
|
||||||
m_checkBoxAutoEncryptionChecked{},
|
|
||||||
m_comboBoxVpnCipherText{"AES-256-GCM"},
|
|
||||||
m_comboBoxVpnHashText{"SHA512"},
|
|
||||||
m_checkBoxBlockDnsChecked{false},
|
|
||||||
m_lineEditPortText{},
|
|
||||||
m_checkBoxTlsAuthChecked{false},
|
|
||||||
m_textAreaAdditionalClientConfig{""},
|
|
||||||
m_textAreaAdditionalServerConfig{""},
|
|
||||||
m_pushButtonSaveVisible{false},
|
|
||||||
m_progressBarResetVisible{false},
|
|
||||||
|
|
||||||
m_lineEditPortEnabled{false},
|
|
||||||
m_labelProtoOpenVpnInfoVisible{true},
|
|
||||||
m_labelProtoOpenVpnInfoText{},
|
|
||||||
m_progressBarResetValue{0},
|
|
||||||
m_progressBarResetMaximum{100}
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void OpenVpnLogic::updateProtocolPage(const QJsonObject &openvpnConfig, DockerContainer container, bool haveAuthData)
|
|
||||||
{
|
|
||||||
qDebug() << "OpenVpnLogic::updateProtocolPage";
|
|
||||||
set_pageEnabled(haveAuthData);
|
|
||||||
set_pushButtonSaveVisible(haveAuthData);
|
|
||||||
set_progressBarResetVisible(haveAuthData);
|
|
||||||
|
|
||||||
set_radioButtonUdpEnabled(true);
|
|
||||||
set_radioButtonTcpEnabled(true);
|
|
||||||
|
|
||||||
set_lineEditSubnetText(openvpnConfig.value(config_key::subnet_address).
|
|
||||||
toString(protocols::openvpn::defaultSubnetAddress));
|
|
||||||
|
|
||||||
QString transport;
|
|
||||||
if (container == DockerContainer::ShadowSocks || container == DockerContainer::Cloak) {
|
|
||||||
transport = "tcp";
|
|
||||||
set_radioButtonUdpEnabled(false);
|
|
||||||
set_radioButtonTcpEnabled(false);
|
|
||||||
} else {
|
|
||||||
transport = openvpnConfig.value(config_key::transport_proto).
|
|
||||||
toString(protocols::openvpn::defaultTransportProto);
|
|
||||||
}
|
|
||||||
set_radioButtonUdpChecked(transport == protocols::openvpn::defaultTransportProto);
|
|
||||||
set_radioButtonTcpChecked(transport != protocols::openvpn::defaultTransportProto);
|
|
||||||
|
|
||||||
set_comboBoxVpnCipherText(openvpnConfig.value(config_key::cipher).
|
|
||||||
toString(protocols::openvpn::defaultCipher));
|
|
||||||
|
|
||||||
set_comboBoxVpnHashText(openvpnConfig.value(config_key::hash).
|
|
||||||
toString(protocols::openvpn::defaultHash));
|
|
||||||
|
|
||||||
bool blockOutsideDns = openvpnConfig.value(config_key::block_outside_dns).toBool(protocols::openvpn::defaultBlockOutsideDns);
|
|
||||||
set_checkBoxBlockDnsChecked(blockOutsideDns);
|
|
||||||
|
|
||||||
bool isNcpDisabled = openvpnConfig.value(config_key::ncp_disable).toBool(protocols::openvpn::defaultNcpDisable);
|
|
||||||
set_checkBoxAutoEncryptionChecked(!isNcpDisabled);
|
|
||||||
|
|
||||||
bool isTlsAuth = openvpnConfig.value(config_key::tls_auth).toBool(protocols::openvpn::defaultTlsAuth);
|
|
||||||
set_checkBoxTlsAuthChecked(isTlsAuth);
|
|
||||||
|
|
||||||
QString additionalClientConfig = openvpnConfig.value(config_key::additional_client_config).
|
|
||||||
toString(protocols::openvpn::defaultAdditionalClientConfig);
|
|
||||||
set_textAreaAdditionalClientConfig(additionalClientConfig);
|
|
||||||
|
|
||||||
QString additionalServerConfig = openvpnConfig.value(config_key::additional_server_config).
|
|
||||||
toString(protocols::openvpn::defaultAdditionalServerConfig);
|
|
||||||
set_textAreaAdditionalServerConfig(additionalServerConfig);
|
|
||||||
|
|
||||||
set_lineEditPortText(openvpnConfig.value(config_key::port).
|
|
||||||
toString(protocols::openvpn::defaultPort));
|
|
||||||
|
|
||||||
set_lineEditPortEnabled(container == DockerContainer::OpenVpn);
|
|
||||||
|
|
||||||
auto lastConfig = openvpnConfig.value(config_key::last_config).toString();
|
|
||||||
auto lastConfigJson = QJsonDocument::fromJson(lastConfig.toUtf8()).object();
|
|
||||||
QStringList lines = lastConfigJson.value(config_key::config).toString().replace("\r", "").split("\n");
|
|
||||||
QString openVpnLastConfigText;
|
|
||||||
for (const QString &l: lines) {
|
|
||||||
openVpnLastConfigText.append(l + "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
set_openVpnLastConfigText(openVpnLastConfigText);
|
|
||||||
set_isThirdPartyConfig(openvpnConfig.value(config_key::isThirdPartyConfig).isBool());
|
|
||||||
}
|
|
||||||
|
|
||||||
void OpenVpnLogic::onPushButtonSaveClicked()
|
|
||||||
{
|
|
||||||
QJsonObject protocolConfig = m_settings->protocolConfig(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer, Proto::OpenVpn);
|
|
||||||
protocolConfig = getProtocolConfigFromPage(protocolConfig);
|
|
||||||
|
|
||||||
QJsonObject containerConfig = m_settings->containerConfig(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer);
|
|
||||||
QJsonObject newContainerConfig = containerConfig;
|
|
||||||
newContainerConfig.insert(ProtocolProps::protoToString(Proto::OpenVpn), protocolConfig);
|
|
||||||
|
|
||||||
ServerConfiguringProgressLogic::PageFunc pageFunc;
|
|
||||||
pageFunc.setEnabledFunc = [this] (bool enabled) -> void {
|
|
||||||
set_pageEnabled(enabled);
|
|
||||||
};
|
|
||||||
ServerConfiguringProgressLogic::ButtonFunc saveButtonFunc;
|
|
||||||
saveButtonFunc.setVisibleFunc = [this] (bool visible) -> void {
|
|
||||||
set_pushButtonSaveVisible(visible);
|
|
||||||
};
|
|
||||||
ServerConfiguringProgressLogic::LabelFunc waitInfoFunc;
|
|
||||||
waitInfoFunc.setVisibleFunc = [this] (bool visible) -> void {
|
|
||||||
set_labelProtoOpenVpnInfoVisible(visible);
|
|
||||||
};
|
|
||||||
waitInfoFunc.setTextFunc = [this] (const QString& text) -> void {
|
|
||||||
set_labelProtoOpenVpnInfoText(text);
|
|
||||||
};
|
|
||||||
ServerConfiguringProgressLogic::ProgressFunc progressBarFunc;
|
|
||||||
progressBarFunc.setVisibleFunc = [this] (bool visible) -> void {
|
|
||||||
set_progressBarResetVisible(visible);
|
|
||||||
};
|
|
||||||
progressBarFunc.setValueFunc = [this] (int value) -> void {
|
|
||||||
set_progressBarResetValue(value);
|
|
||||||
};
|
|
||||||
progressBarFunc.getValueFunc = [this] (void) -> int {
|
|
||||||
return progressBarResetValue();
|
|
||||||
};
|
|
||||||
progressBarFunc.getMaximumFunc = [this] (void) -> int {
|
|
||||||
return progressBarResetMaximum();
|
|
||||||
};
|
|
||||||
progressBarFunc.setTextVisibleFunc = [this] (bool visible) -> void {
|
|
||||||
set_progressBarTextVisible(visible);
|
|
||||||
};
|
|
||||||
progressBarFunc.setTextFunc = [this] (const QString& text) -> void {
|
|
||||||
set_progressBarText(text);
|
|
||||||
};
|
|
||||||
|
|
||||||
ServerConfiguringProgressLogic::LabelFunc busyInfoFuncy;
|
|
||||||
busyInfoFuncy.setTextFunc = [this] (const QString& text) -> void {
|
|
||||||
set_labelServerBusyText(text);
|
|
||||||
};
|
|
||||||
busyInfoFuncy.setVisibleFunc = [this] (bool visible) -> void {
|
|
||||||
set_labelServerBusyVisible(visible);
|
|
||||||
};
|
|
||||||
|
|
||||||
ServerConfiguringProgressLogic::ButtonFunc cancelButtonFunc;
|
|
||||||
cancelButtonFunc.setVisibleFunc = [this] (bool visible) -> void {
|
|
||||||
set_pushButtonCancelVisible(visible);
|
|
||||||
};
|
|
||||||
|
|
||||||
progressBarFunc.setTextVisibleFunc(true);
|
|
||||||
progressBarFunc.setTextFunc(QString("Configuring..."));
|
|
||||||
|
|
||||||
auto installAction = [this, containerConfig, &newContainerConfig]() {
|
|
||||||
ServerController serverController(m_settings);
|
|
||||||
return serverController.updateContainer(m_settings->serverCredentials(uiLogic()->m_selectedServerIndex),
|
|
||||||
uiLogic()->m_selectedDockerContainer, containerConfig, newContainerConfig);
|
|
||||||
};
|
|
||||||
|
|
||||||
ErrorCode e = uiLogic()->pageLogic<ServerConfiguringProgressLogic>()->doInstallAction(installAction, pageFunc, progressBarFunc,
|
|
||||||
saveButtonFunc, waitInfoFunc,
|
|
||||||
busyInfoFuncy, cancelButtonFunc);
|
|
||||||
|
|
||||||
if (!e) {
|
|
||||||
m_settings->setContainerConfig(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer, newContainerConfig);
|
|
||||||
m_settings->clearLastConnectionConfig(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer);
|
|
||||||
}
|
|
||||||
qDebug() << "Protocol saved with code:" << e << "for" << uiLogic()->m_selectedServerIndex << uiLogic()->m_selectedDockerContainer;
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonObject OpenVpnLogic::getProtocolConfigFromPage(QJsonObject oldConfig)
|
|
||||||
{
|
|
||||||
oldConfig.insert(config_key::subnet_address, lineEditSubnetText());
|
|
||||||
oldConfig.insert(config_key::transport_proto,
|
|
||||||
ProtocolProps::transportProtoToString(radioButtonUdpChecked() ? ProtocolEnumNS::Udp : ProtocolEnumNS::Tcp));
|
|
||||||
|
|
||||||
oldConfig.insert(config_key::ncp_disable, ! checkBoxAutoEncryptionChecked());
|
|
||||||
oldConfig.insert(config_key::cipher, comboBoxVpnCipherText());
|
|
||||||
oldConfig.insert(config_key::hash, comboBoxVpnHashText());
|
|
||||||
oldConfig.insert(config_key::block_outside_dns, checkBoxBlockDnsChecked());
|
|
||||||
oldConfig.insert(config_key::port, lineEditPortText());
|
|
||||||
oldConfig.insert(config_key::tls_auth, checkBoxTlsAuthChecked());
|
|
||||||
oldConfig.insert(config_key::additional_client_config, textAreaAdditionalClientConfig());
|
|
||||||
oldConfig.insert(config_key::additional_server_config, textAreaAdditionalServerConfig());
|
|
||||||
return oldConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OpenVpnLogic::onPushButtonCancelClicked()
|
|
||||||
{
|
|
||||||
emit uiLogic()->pageLogic<ServerConfiguringProgressLogic>()->cancelDoInstallAction(true);
|
|
||||||
}
|
|
||||||
|
|
@ -1,63 +0,0 @@
|
||||||
#ifndef OPENVPN_LOGIC_H
|
|
||||||
#define OPENVPN_LOGIC_H
|
|
||||||
|
|
||||||
#include "PageProtocolLogicBase.h"
|
|
||||||
|
|
||||||
class UiLogic;
|
|
||||||
|
|
||||||
class OpenVpnLogic : public PageProtocolLogicBase
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
AUTO_PROPERTY(QString, lineEditSubnetText)
|
|
||||||
|
|
||||||
AUTO_PROPERTY(bool, radioButtonTcpEnabled)
|
|
||||||
AUTO_PROPERTY(bool, radioButtonUdpEnabled)
|
|
||||||
AUTO_PROPERTY(bool, radioButtonTcpChecked)
|
|
||||||
AUTO_PROPERTY(bool, radioButtonUdpChecked)
|
|
||||||
|
|
||||||
AUTO_PROPERTY(bool, checkBoxAutoEncryptionChecked)
|
|
||||||
AUTO_PROPERTY(QString, comboBoxVpnCipherText)
|
|
||||||
AUTO_PROPERTY(QString, comboBoxVpnHashText)
|
|
||||||
AUTO_PROPERTY(bool, checkBoxBlockDnsChecked)
|
|
||||||
AUTO_PROPERTY(QString, lineEditPortText)
|
|
||||||
AUTO_PROPERTY(bool, checkBoxTlsAuthChecked)
|
|
||||||
AUTO_PROPERTY(QString, textAreaAdditionalClientConfig)
|
|
||||||
AUTO_PROPERTY(QString, textAreaAdditionalServerConfig)
|
|
||||||
|
|
||||||
AUTO_PROPERTY(bool, pushButtonSaveVisible)
|
|
||||||
AUTO_PROPERTY(bool, progressBarResetVisible)
|
|
||||||
|
|
||||||
AUTO_PROPERTY(bool, lineEditPortEnabled)
|
|
||||||
|
|
||||||
AUTO_PROPERTY(bool, labelProtoOpenVpnInfoVisible)
|
|
||||||
AUTO_PROPERTY(QString, labelProtoOpenVpnInfoText)
|
|
||||||
AUTO_PROPERTY(int, progressBarResetValue)
|
|
||||||
AUTO_PROPERTY(int, progressBarResetMaximum)
|
|
||||||
AUTO_PROPERTY(bool, progressBarTextVisible)
|
|
||||||
AUTO_PROPERTY(QString, progressBarText)
|
|
||||||
|
|
||||||
AUTO_PROPERTY(bool, labelServerBusyVisible)
|
|
||||||
AUTO_PROPERTY(QString, labelServerBusyText)
|
|
||||||
|
|
||||||
AUTO_PROPERTY(bool, pushButtonCancelVisible)
|
|
||||||
|
|
||||||
AUTO_PROPERTY(QString, openVpnLastConfigText)
|
|
||||||
AUTO_PROPERTY(bool, isThirdPartyConfig)
|
|
||||||
|
|
||||||
public:
|
|
||||||
Q_INVOKABLE void onPushButtonSaveClicked();
|
|
||||||
Q_INVOKABLE void onPushButtonCancelClicked();
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit OpenVpnLogic(UiLogic *uiLogic, QObject *parent = nullptr);
|
|
||||||
~OpenVpnLogic() = default;
|
|
||||||
|
|
||||||
void updateProtocolPage(const QJsonObject &openvpnConfig, DockerContainer container, bool haveAuthData) override;
|
|
||||||
QJsonObject getProtocolConfigFromPage(QJsonObject oldConfig) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
UiLogic *m_uiLogic;
|
|
||||||
|
|
||||||
};
|
|
||||||
#endif // OPENVPN_LOGIC_H
|
|
||||||
|
|
@ -1,169 +0,0 @@
|
||||||
#include <QDesktopServices>
|
|
||||||
#include <QTimer>
|
|
||||||
#include <QProcess>
|
|
||||||
#include <QStorageInfo>
|
|
||||||
#include <QStandardPaths>
|
|
||||||
|
|
||||||
#include "OtherProtocolsLogic.h"
|
|
||||||
#include <functional>
|
|
||||||
#include "../../uilogic.h"
|
|
||||||
#include "utilities.h"
|
|
||||||
|
|
||||||
#ifdef Q_OS_WINDOWS
|
|
||||||
#include <Windows.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
using namespace amnezia;
|
|
||||||
using namespace PageEnumNS;
|
|
||||||
|
|
||||||
OtherProtocolsLogic::OtherProtocolsLogic(UiLogic *logic, QObject *parent):
|
|
||||||
PageProtocolLogicBase(logic, parent),
|
|
||||||
m_checkBoxSftpRestoreChecked{false}
|
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
OtherProtocolsLogic::~OtherProtocolsLogic()
|
|
||||||
{
|
|
||||||
#ifdef Q_OS_WINDOWS
|
|
||||||
for (QProcess *p: m_sftpMountProcesses) {
|
|
||||||
if (p) Utils::signalCtrl(p->processId(), CTRL_C_EVENT);
|
|
||||||
if (p) p->kill();
|
|
||||||
if (p) p->waitForFinished();
|
|
||||||
if (p) delete p;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void OtherProtocolsLogic::updateProtocolPage(const QJsonObject &config, DockerContainer container, bool haveAuthData)
|
|
||||||
{
|
|
||||||
set_labelTftpUserNameText(config.value(config_key::userName).toString());
|
|
||||||
set_labelTftpPasswordText(config.value(config_key::password).toString(protocols::sftp::defaultUserName));
|
|
||||||
set_labelTftpPortText(config.value(config_key::port).toString());
|
|
||||||
|
|
||||||
set_labelTorWebSiteAddressText(config.value(config_key::site).toString());
|
|
||||||
set_pushButtonSftpMountEnabled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef Q_OS_WINDOWS
|
|
||||||
QString OtherProtocolsLogic::getNextDriverLetter() const
|
|
||||||
{
|
|
||||||
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
|
|
||||||
|
|
||||||
//QJsonObject OtherProtocolsLogic::getProtocolConfigFromPage(QJsonObject oldConfig)
|
|
||||||
//{
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
||||||
void OtherProtocolsLogic::onPushButtonSftpMountDriveClicked()
|
|
||||||
{
|
|
||||||
QString mountPath;
|
|
||||||
QString cmd;
|
|
||||||
QString host = m_settings->serverCredentials(uiLogic()->m_selectedServerIndex).hostName;
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef Q_OS_WINDOWS
|
|
||||||
mountPath = getNextDriverLetter() + ":";
|
|
||||||
// QString cmd = QString("net use \\\\sshfs\\%1@x.x.x.x!%2 /USER:%1 %3")
|
|
||||||
// .arg(labelTftpUserNameText())
|
|
||||||
// .arg(labelTftpPortText())
|
|
||||||
// .arg(labelTftpPasswordText());
|
|
||||||
|
|
||||||
cmd = "C:\\Program Files\\SSHFS-Win\\bin\\sshfs.exe";
|
|
||||||
#elif defined AMNEZIA_DESKTOP
|
|
||||||
mountPath = QString("%1/sftp:%2:%3")
|
|
||||||
.arg(QStandardPaths::writableLocation(QStandardPaths::HomeLocation))
|
|
||||||
.arg(host)
|
|
||||||
.arg(labelTftpPortText());
|
|
||||||
QDir dir(mountPath);
|
|
||||||
if (!dir.exists()){
|
|
||||||
dir.mkpath(mountPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd = "/usr/local/bin/sshfs";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef AMNEZIA_DESKTOP
|
|
||||||
set_pushButtonSftpMountEnabled(false);
|
|
||||||
QProcess *p = new QProcess;
|
|
||||||
m_sftpMountProcesses.append(p);
|
|
||||||
p->setProcessChannelMode(QProcess::MergedChannels);
|
|
||||||
|
|
||||||
connect(p, &QProcess::readyRead, this, [this, p, mountPath](){
|
|
||||||
QString s = p->readAll();
|
|
||||||
if (s.contains("The service sshfs has been started")) {
|
|
||||||
QDesktopServices::openUrl(QUrl("file:///" + mountPath));
|
|
||||||
set_pushButtonSftpMountEnabled(true);
|
|
||||||
}
|
|
||||||
qDebug() << s;
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
p->setProgram(cmd);
|
|
||||||
|
|
||||||
QString args = QString(
|
|
||||||
"%1@%2:/ %3 "
|
|
||||||
"-o port=%4 "
|
|
||||||
"-f "
|
|
||||||
"-o reconnect "
|
|
||||||
"-o rellinks "
|
|
||||||
"-o fstypename=SSHFS "
|
|
||||||
"-o ssh_command=/usr/bin/ssh.exe "
|
|
||||||
"-o UserKnownHostsFile=/dev/null "
|
|
||||||
"-o StrictHostKeyChecking=no "
|
|
||||||
"-o password_stdin")
|
|
||||||
.arg(labelTftpUserNameText())
|
|
||||||
.arg(host)
|
|
||||||
.arg(mountPath)
|
|
||||||
.arg(labelTftpPortText());
|
|
||||||
|
|
||||||
|
|
||||||
// args.replace("\n", " ");
|
|
||||||
// args.replace("\r", " ");
|
|
||||||
//#ifndef Q_OS_WIN
|
|
||||||
// args.replace("reconnect-orellinks", "");
|
|
||||||
//#endif
|
|
||||||
p->setArguments(args.split(" ", Qt::SkipEmptyParts));
|
|
||||||
p->start();
|
|
||||||
p->waitForStarted(50);
|
|
||||||
if (p->state() != QProcess::Running) {
|
|
||||||
qDebug() << "onPushButtonSftpMountDriveClicked process not started";
|
|
||||||
qDebug() << args;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
p->write((labelTftpPasswordText() + "\n").toUtf8());
|
|
||||||
}
|
|
||||||
|
|
||||||
//qDebug().noquote() << "onPushButtonSftpMountDriveClicked" << args;
|
|
||||||
|
|
||||||
set_pushButtonSftpMountEnabled(true);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void OtherProtocolsLogic::checkBoxSftpRestoreClicked()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
#ifndef OTHER_PROTOCOLS_LOGIC_H
|
|
||||||
#define OTHER_PROTOCOLS_LOGIC_H
|
|
||||||
|
|
||||||
#include "PageProtocolLogicBase.h"
|
|
||||||
|
|
||||||
#include <QProcess>
|
|
||||||
|
|
||||||
class UiLogic;
|
|
||||||
|
|
||||||
class OtherProtocolsLogic : public PageProtocolLogicBase
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
AUTO_PROPERTY(QString, labelTftpUserNameText)
|
|
||||||
AUTO_PROPERTY(QString, labelTftpPasswordText)
|
|
||||||
AUTO_PROPERTY(QString, labelTftpPortText)
|
|
||||||
AUTO_PROPERTY(bool, pushButtonSftpMountEnabled)
|
|
||||||
AUTO_PROPERTY(bool, checkBoxSftpRestoreChecked)
|
|
||||||
|
|
||||||
AUTO_PROPERTY(QString, labelTorWebSiteAddressText)
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
Q_INVOKABLE void onPushButtonSftpMountDriveClicked();
|
|
||||||
Q_INVOKABLE void checkBoxSftpRestoreClicked();
|
|
||||||
public:
|
|
||||||
explicit OtherProtocolsLogic(UiLogic *uiLogic, QObject *parent = nullptr);
|
|
||||||
~OtherProtocolsLogic();
|
|
||||||
|
|
||||||
void updateProtocolPage(const QJsonObject &config, DockerContainer container, bool haveAuthData) override;
|
|
||||||
//QJsonObject getProtocolConfigFromPage(QJsonObject oldConfig) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
UiLogic *m_uiLogic;
|
|
||||||
|
|
||||||
#ifdef AMNEZIA_DESKTOP
|
|
||||||
QList <QProcess *> m_sftpMountProcesses;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef Q_OS_WINDOWS
|
|
||||||
QString getNextDriverLetter() const;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
};
|
|
||||||
#endif // OTHER_PROTOCOLS_LOGIC_H
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
#include "PageProtocolLogicBase.h"
|
|
||||||
|
|
||||||
|
|
||||||
PageProtocolLogicBase::PageProtocolLogicBase(UiLogic *logic, QObject *parent):
|
|
||||||
PageLogicBase(logic, parent)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
#ifndef PAGE_PROTOCOL_LOGIC_BASE_H
|
|
||||||
#define PAGE_PROTOCOL_LOGIC_BASE_H
|
|
||||||
|
|
||||||
#include "settings.h"
|
|
||||||
#include "../PageLogicBase.h"
|
|
||||||
|
|
||||||
using namespace amnezia;
|
|
||||||
using namespace PageEnumNS;
|
|
||||||
|
|
||||||
class UiLogic;
|
|
||||||
|
|
||||||
class PageProtocolLogicBase : public PageLogicBase
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit PageProtocolLogicBase(UiLogic *uiLogic, QObject *parent = nullptr);
|
|
||||||
~PageProtocolLogicBase() = default;
|
|
||||||
|
|
||||||
virtual void updateProtocolPage(const QJsonObject &config, DockerContainer container, bool haveAuthData) {}
|
|
||||||
virtual QJsonObject getProtocolConfigFromPage(QJsonObject oldConfig) { return QJsonObject(); }
|
|
||||||
|
|
||||||
};
|
|
||||||
#endif // PAGE_PROTOCOL_LOGIC_BASE_H
|
|
||||||
|
|
@ -1,127 +0,0 @@
|
||||||
#include "ShadowSocksLogic.h"
|
|
||||||
|
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
#include "core/servercontroller.h"
|
|
||||||
#include "ui/pages_logic/ServerConfiguringProgressLogic.h"
|
|
||||||
#include "ui/uilogic.h"
|
|
||||||
|
|
||||||
using namespace amnezia;
|
|
||||||
using namespace PageEnumNS;
|
|
||||||
|
|
||||||
ShadowSocksLogic::ShadowSocksLogic(UiLogic *logic, QObject *parent):
|
|
||||||
PageProtocolLogicBase(logic, parent),
|
|
||||||
m_comboBoxCipherText{"chacha20-poly1305"},
|
|
||||||
m_lineEditPortText{},
|
|
||||||
m_pushButtonSaveVisible{false},
|
|
||||||
m_progressBarResetVisible{false},
|
|
||||||
m_lineEditPortEnabled{false},
|
|
||||||
m_labelInfoVisible{true},
|
|
||||||
m_labelInfoText{},
|
|
||||||
m_progressBarResetValue{0},
|
|
||||||
m_progressBarResetMaximum{100}
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShadowSocksLogic::updateProtocolPage(const QJsonObject &ssConfig, DockerContainer container, bool haveAuthData)
|
|
||||||
{
|
|
||||||
set_pageEnabled(haveAuthData);
|
|
||||||
set_pushButtonSaveVisible(haveAuthData);
|
|
||||||
set_progressBarResetVisible(haveAuthData);
|
|
||||||
|
|
||||||
set_comboBoxCipherText(ssConfig.value(config_key::cipher).
|
|
||||||
toString(protocols::shadowsocks::defaultCipher));
|
|
||||||
|
|
||||||
set_lineEditPortText(ssConfig.value(config_key::port).
|
|
||||||
toString(protocols::shadowsocks::defaultPort));
|
|
||||||
|
|
||||||
set_lineEditPortEnabled(container == DockerContainer::ShadowSocks);
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonObject ShadowSocksLogic::getProtocolConfigFromPage(QJsonObject oldConfig)
|
|
||||||
{
|
|
||||||
oldConfig.insert(config_key::cipher, comboBoxCipherText());
|
|
||||||
oldConfig.insert(config_key::port, lineEditPortText());
|
|
||||||
|
|
||||||
return oldConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShadowSocksLogic::onPushButtonSaveClicked()
|
|
||||||
{
|
|
||||||
QJsonObject protocolConfig = m_settings->protocolConfig(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer, Proto::ShadowSocks);
|
|
||||||
|
|
||||||
QJsonObject containerConfig = m_settings->containerConfig(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer);
|
|
||||||
QJsonObject newContainerConfig = containerConfig;
|
|
||||||
newContainerConfig.insert(ProtocolProps::protoToString(Proto::ShadowSocks), protocolConfig);
|
|
||||||
ServerConfiguringProgressLogic::PageFunc pageFunc;
|
|
||||||
pageFunc.setEnabledFunc = [this] (bool enabled) -> void {
|
|
||||||
set_pageEnabled(enabled);
|
|
||||||
};
|
|
||||||
ServerConfiguringProgressLogic::ButtonFunc saveButtonFunc;
|
|
||||||
saveButtonFunc.setVisibleFunc = [this] (bool visible) -> void {
|
|
||||||
set_pushButtonSaveVisible(visible);
|
|
||||||
};
|
|
||||||
ServerConfiguringProgressLogic::LabelFunc waitInfoFunc;
|
|
||||||
waitInfoFunc.setVisibleFunc = [this] (bool visible) -> void {
|
|
||||||
set_labelInfoVisible(visible);
|
|
||||||
};
|
|
||||||
waitInfoFunc.setTextFunc = [this] (const QString& text) -> void {
|
|
||||||
set_labelInfoText(text);
|
|
||||||
};
|
|
||||||
ServerConfiguringProgressLogic::ProgressFunc progressBarFunc;
|
|
||||||
progressBarFunc.setVisibleFunc = [this] (bool visible) -> void {
|
|
||||||
set_progressBarResetVisible(visible);
|
|
||||||
};
|
|
||||||
progressBarFunc.setValueFunc = [this] (int value) -> void {
|
|
||||||
set_progressBarResetValue(value);
|
|
||||||
};
|
|
||||||
progressBarFunc.getValueFunc = [this] (void) -> int {
|
|
||||||
return progressBarResetValue();
|
|
||||||
};
|
|
||||||
progressBarFunc.getMaximumFunc = [this] (void) -> int {
|
|
||||||
return progressBarResetMaximum();
|
|
||||||
};
|
|
||||||
progressBarFunc.setTextVisibleFunc = [this] (bool visible) -> void {
|
|
||||||
set_progressBarTextVisible(visible);
|
|
||||||
};
|
|
||||||
progressBarFunc.setTextFunc = [this] (const QString& text) -> void {
|
|
||||||
set_progressBarText(text);
|
|
||||||
};
|
|
||||||
|
|
||||||
ServerConfiguringProgressLogic::LabelFunc busyInfoFuncy;
|
|
||||||
busyInfoFuncy.setTextFunc = [this] (const QString& text) -> void {
|
|
||||||
set_labelServerBusyText(text);
|
|
||||||
};
|
|
||||||
busyInfoFuncy.setVisibleFunc = [this] (bool visible) -> void {
|
|
||||||
set_labelServerBusyVisible(visible);
|
|
||||||
};
|
|
||||||
|
|
||||||
ServerConfiguringProgressLogic::ButtonFunc cancelButtonFunc;
|
|
||||||
cancelButtonFunc.setVisibleFunc = [this] (bool visible) -> void {
|
|
||||||
set_pushButtonCancelVisible(visible);
|
|
||||||
};
|
|
||||||
|
|
||||||
progressBarFunc.setTextVisibleFunc(true);
|
|
||||||
progressBarFunc.setTextFunc(QString("Configuring..."));
|
|
||||||
|
|
||||||
auto installAction = [this, containerConfig, &newContainerConfig]() {
|
|
||||||
ServerController serverController(m_settings);
|
|
||||||
return serverController.updateContainer(m_settings->serverCredentials(uiLogic()->m_selectedServerIndex),
|
|
||||||
uiLogic()->m_selectedDockerContainer, containerConfig, newContainerConfig);
|
|
||||||
};
|
|
||||||
ErrorCode e = uiLogic()->pageLogic<ServerConfiguringProgressLogic>()->doInstallAction(installAction, pageFunc, progressBarFunc,
|
|
||||||
saveButtonFunc, waitInfoFunc,
|
|
||||||
busyInfoFuncy, cancelButtonFunc);
|
|
||||||
|
|
||||||
if (!e) {
|
|
||||||
m_settings->setContainerConfig(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer, newContainerConfig);
|
|
||||||
m_settings->clearLastConnectionConfig(uiLogic()->m_selectedServerIndex, uiLogic()->m_selectedDockerContainer);
|
|
||||||
}
|
|
||||||
qDebug() << "Protocol saved with code:" << e << "for" << uiLogic()->m_selectedServerIndex << uiLogic()->m_selectedDockerContainer;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShadowSocksLogic::onPushButtonCancelClicked()
|
|
||||||
{
|
|
||||||
emit uiLogic()->pageLogic<ServerConfiguringProgressLogic>()->cancelDoInstallAction(true);
|
|
||||||
}
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
||||||
#ifndef SHADOWSOCKS_LOGIC_H
|
|
||||||
#define SHADOWSOCKS_LOGIC_H
|
|
||||||
|
|
||||||
#include "PageProtocolLogicBase.h"
|
|
||||||
|
|
||||||
class UiLogic;
|
|
||||||
|
|
||||||
class ShadowSocksLogic : public PageProtocolLogicBase
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
AUTO_PROPERTY(QString, comboBoxCipherText)
|
|
||||||
AUTO_PROPERTY(QString, lineEditPortText)
|
|
||||||
AUTO_PROPERTY(bool, pushButtonSaveVisible)
|
|
||||||
AUTO_PROPERTY(bool, progressBarResetVisible)
|
|
||||||
AUTO_PROPERTY(bool, lineEditPortEnabled)
|
|
||||||
AUTO_PROPERTY(bool, labelInfoVisible)
|
|
||||||
AUTO_PROPERTY(QString, labelInfoText)
|
|
||||||
AUTO_PROPERTY(int, progressBarResetValue)
|
|
||||||
AUTO_PROPERTY(int, progressBarResetMaximum)
|
|
||||||
AUTO_PROPERTY(bool, progressBarTextVisible)
|
|
||||||
AUTO_PROPERTY(QString, progressBarText)
|
|
||||||
|
|
||||||
AUTO_PROPERTY(bool, labelServerBusyVisible)
|
|
||||||
AUTO_PROPERTY(QString, labelServerBusyText)
|
|
||||||
|
|
||||||
AUTO_PROPERTY(bool, pushButtonCancelVisible)
|
|
||||||
|
|
||||||
public:
|
|
||||||
Q_INVOKABLE void onPushButtonSaveClicked();
|
|
||||||
Q_INVOKABLE void onPushButtonCancelClicked();
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit ShadowSocksLogic(UiLogic *uiLogic, QObject *parent = nullptr);
|
|
||||||
~ShadowSocksLogic() = default;
|
|
||||||
|
|
||||||
void updateProtocolPage(const QJsonObject &ssConfig, DockerContainer container, bool haveAuthData) override;
|
|
||||||
QJsonObject getProtocolConfigFromPage(QJsonObject oldConfig) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
UiLogic *m_uiLogic;
|
|
||||||
|
|
||||||
};
|
|
||||||
#endif // SHADOWSOCKS_LOGIC_H
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
#include "WireGuardLogic.h"
|
|
||||||
#include "core/servercontroller.h"
|
|
||||||
#include <functional>
|
|
||||||
#include "../../uilogic.h"
|
|
||||||
|
|
||||||
using namespace amnezia;
|
|
||||||
using namespace PageEnumNS;
|
|
||||||
|
|
||||||
WireGuardLogic::WireGuardLogic(UiLogic *logic, QObject *parent):
|
|
||||||
PageProtocolLogicBase(logic, parent)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void WireGuardLogic::updateProtocolPage(const QJsonObject &wireGuardConfig, DockerContainer container, bool haveAuthData)
|
|
||||||
{
|
|
||||||
qDebug() << "WireGuardLogic::updateProtocolPage";
|
|
||||||
|
|
||||||
auto lastConfigJsonDoc = QJsonDocument::fromJson(wireGuardConfig.value(config_key::last_config).toString().toUtf8());
|
|
||||||
auto lastConfigJson = lastConfigJsonDoc.object();
|
|
||||||
|
|
||||||
QString wireGuardLastConfigText;
|
|
||||||
QStringList lines = lastConfigJson.value(config_key::config).toString().replace("\r", "").split("\n");
|
|
||||||
for (const QString &l: lines) {
|
|
||||||
wireGuardLastConfigText.append(l + "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
set_wireGuardLastConfigText(wireGuardLastConfigText);
|
|
||||||
set_isThirdPartyConfig(wireGuardConfig.value(config_key::isThirdPartyConfig).toBool());
|
|
||||||
}
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
#ifndef WIREGUARDLOGIC_H
|
|
||||||
#define WIREGUARDLOGIC_H
|
|
||||||
|
|
||||||
#include "PageProtocolLogicBase.h"
|
|
||||||
|
|
||||||
class UiLogic;
|
|
||||||
|
|
||||||
class WireGuardLogic : public PageProtocolLogicBase
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
AUTO_PROPERTY(QString, wireGuardLastConfigText)
|
|
||||||
AUTO_PROPERTY(bool, isThirdPartyConfig)
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit WireGuardLogic(UiLogic *uiLogic, QObject *parent = nullptr);
|
|
||||||
~WireGuardLogic() = default;
|
|
||||||
|
|
||||||
void updateProtocolPage(const QJsonObject &wireGuardConfig, DockerContainer container, bool haveAuthData) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
UiLogic *m_uiLogic;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // WIREGUARDLOGIC_H
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
|
|
||||||
Button {
|
|
||||||
id: root
|
|
||||||
x: 10
|
|
||||||
y: 5
|
|
||||||
width: 41
|
|
||||||
height: 35
|
|
||||||
|
|
||||||
hoverEnabled: true
|
|
||||||
property bool containsMouse: hovered
|
|
||||||
|
|
||||||
background: Item {}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: mouseArea
|
|
||||||
anchors.fill: parent
|
|
||||||
enabled: false
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
}
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
UiLogic.closePage()
|
|
||||||
}
|
|
||||||
|
|
||||||
contentItem: Image {
|
|
||||||
id: img
|
|
||||||
source: "qrc:/images/arrow_left.png"
|
|
||||||
anchors.fill: root
|
|
||||||
anchors.margins: root.containsMouse ? 9 : 10
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
|
|
||||||
Button {
|
|
||||||
id: root
|
|
||||||
property bool containsMouse: hovered
|
|
||||||
hoverEnabled: true
|
|
||||||
flat: true
|
|
||||||
highlighted: false
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: mouseArea
|
|
||||||
anchors.fill: parent
|
|
||||||
enabled: false
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
|
|
||||||
import "../Config"
|
|
||||||
|
|
||||||
BasicButtonType {
|
|
||||||
id: root
|
|
||||||
width: parent.width - 2 * GC.defaultMargin
|
|
||||||
implicitHeight: 40
|
|
||||||
|
|
||||||
background: Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
radius: 4
|
|
||||||
color: root.enabled ? (root.containsMouse ? "#211966" : "#100A44") : "#888888"
|
|
||||||
}
|
|
||||||
font.pixelSize: 16
|
|
||||||
contentItem: Text {
|
|
||||||
anchors.fill: parent
|
|
||||||
font.family: "Lato"
|
|
||||||
font.styleName: "normal"
|
|
||||||
font.pixelSize: root.font.pixelSize
|
|
||||||
color: "#D4D4D4"
|
|
||||||
text: root.text
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
}
|
|
||||||
antialiasing: true
|
|
||||||
}
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
|
|
||||||
Text {
|
|
||||||
font.family: "Lato"
|
|
||||||
font.styleName: "normal"
|
|
||||||
font.pixelSize: 24
|
|
||||||
color: "#100A44"
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
x: 10
|
|
||||||
y: 35
|
|
||||||
width: parent.width - 40
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
//height: 31
|
|
||||||
}
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
|
|
||||||
CheckBox {
|
|
||||||
id: root
|
|
||||||
property int imageWidth : 20
|
|
||||||
property int imageHeight : 20
|
|
||||||
indicator: Image {
|
|
||||||
id: indicator
|
|
||||||
anchors.verticalCenter: root.verticalCenter
|
|
||||||
height: imageHeight
|
|
||||||
width: imageWidth
|
|
||||||
source: root.checked ? "qrc:/images/controls/check_on.png"
|
|
||||||
: "qrc:/images/controls/check_off.png"
|
|
||||||
}
|
|
||||||
|
|
||||||
contentItem: Text {
|
|
||||||
text: root.text
|
|
||||||
font.family: "Lato"
|
|
||||||
font.styleName: "normal"
|
|
||||||
font.pixelSize: 16
|
|
||||||
color: "#181922"
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
leftPadding: root.indicator.width + root.spacing
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
|
|
||||||
ComboBox {
|
|
||||||
id: root
|
|
||||||
font.family: "Lato"
|
|
||||||
font.styleName: "normal"
|
|
||||||
font.pixelSize: 16
|
|
||||||
|
|
||||||
popup.font.pixelSize: 16
|
|
||||||
}
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
import Qt.labs.platform
|
|
||||||
|
|
||||||
Menu {
|
|
||||||
property var textObj
|
|
||||||
|
|
||||||
MenuItem {
|
|
||||||
text: qsTr("C&ut")
|
|
||||||
shortcut: StandardKey.Cut
|
|
||||||
enabled: textObj.selectedText
|
|
||||||
onTriggered: textObj.cut()
|
|
||||||
}
|
|
||||||
MenuItem {
|
|
||||||
text: qsTr("&Copy")
|
|
||||||
shortcut: StandardKey.Copy
|
|
||||||
enabled: textObj.selectedText
|
|
||||||
onTriggered: textObj.copy()
|
|
||||||
}
|
|
||||||
MenuItem {
|
|
||||||
text: qsTr("&Paste")
|
|
||||||
shortcut: StandardKey.Paste
|
|
||||||
enabled: textObj.canPaste
|
|
||||||
onTriggered: textObj.paste()
|
|
||||||
}
|
|
||||||
|
|
||||||
MenuItem {
|
|
||||||
text: qsTr("&SelectAll")
|
|
||||||
shortcut: StandardKey.SelectAll
|
|
||||||
enabled: textObj.length > 0
|
|
||||||
onTriggered: textObj.selectAll()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
import QtQml
|
|
||||||
|
|
||||||
Behavior {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property QtObject fadeTarget: targetProperty.object
|
|
||||||
property string fadeProperty: "scale"
|
|
||||||
property int fadeDuration: 150
|
|
||||||
property string easingType: "Quad"
|
|
||||||
|
|
||||||
property alias outAnimation: outAnimation
|
|
||||||
property alias inAnimation: inAnimation
|
|
||||||
|
|
||||||
SequentialAnimation {
|
|
||||||
NumberAnimation {
|
|
||||||
id: outAnimation
|
|
||||||
target: root.fadeTarget
|
|
||||||
property: root.fadeProperty
|
|
||||||
duration: root.fadeDuration
|
|
||||||
to: 0
|
|
||||||
easing.type: Easing["In"+root.easingType]
|
|
||||||
}
|
|
||||||
PropertyAction { }
|
|
||||||
NumberAnimation {
|
|
||||||
id: inAnimation
|
|
||||||
target: root.fadeTarget
|
|
||||||
property: root.fadeProperty
|
|
||||||
duration: root.fadeDuration
|
|
||||||
to: target[property]
|
|
||||||
easing.type: Easing["Out"+root.easingType]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
import QtQuick 2.12
|
|
||||||
import QtQuick.Controls 2.12
|
|
||||||
import "../Config"
|
|
||||||
|
|
||||||
Flickable {
|
|
||||||
id: fl
|
|
||||||
|
|
||||||
clip: true
|
|
||||||
width: parent.width
|
|
||||||
|
|
||||||
anchors.topMargin: GC.defaultMargin
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
anchors.bottomMargin: GC.defaultMargin
|
|
||||||
anchors.left: root.left
|
|
||||||
anchors.leftMargin: GC.defaultMargin
|
|
||||||
anchors.right: root.right
|
|
||||||
anchors.rightMargin: 1
|
|
||||||
|
|
||||||
Keys.onUpPressed: scrollBar.decrease()
|
|
||||||
Keys.onDownPressed: scrollBar.increase()
|
|
||||||
|
|
||||||
ScrollBar.vertical: ScrollBar {
|
|
||||||
id: scrollBar
|
|
||||||
policy: fl.height >= fl.contentHeight ? ScrollBar.AlwaysOff : ScrollBar.AlwaysOn
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
|
|
||||||
BasicButtonType {
|
|
||||||
id: root
|
|
||||||
property alias iconMargin: img.anchors.margins
|
|
||||||
property alias img: img
|
|
||||||
property int imgMargin: 4
|
|
||||||
property int imgMarginHover: 3
|
|
||||||
background: Item {}
|
|
||||||
contentItem: Image {
|
|
||||||
id: img
|
|
||||||
source: root.icon.source
|
|
||||||
anchors.fill: root
|
|
||||||
anchors.margins: root.containsMouse ? imgMarginHover : imgMargin
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
import "../Config"
|
|
||||||
|
|
||||||
Text {
|
|
||||||
id: root
|
|
||||||
width: parent.width - 2 * GC.defaultMargin
|
|
||||||
anchors.topMargin: 10
|
|
||||||
|
|
||||||
font.family: "Lato"
|
|
||||||
font.styleName: "normal"
|
|
||||||
font.pixelSize: 16
|
|
||||||
color: "#181922"
|
|
||||||
horizontalAlignment: Text.AlignLeft
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
|
|
||||||
Image {
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
anchors.bottomMargin: 30
|
|
||||||
source: "qrc:/images/AmneziaVPN.png"
|
|
||||||
}
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
import QtQuick.Layouts
|
|
||||||
|
|
||||||
Popup {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property string popupWarningText
|
|
||||||
|
|
||||||
anchors.centerIn: Overlay.overlay
|
|
||||||
modal: true
|
|
||||||
closePolicy: Popup.NoAutoClose
|
|
||||||
width: parent.width - 20
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
width: parent.width
|
|
||||||
Text {
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
Layout.fillWidth: true
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
font.pixelSize: 16
|
|
||||||
text: root.popupWarningText
|
|
||||||
}
|
|
||||||
|
|
||||||
BlueButtonType {
|
|
||||||
Layout.preferredWidth: parent.width / 2
|
|
||||||
Layout.fillWidth: true
|
|
||||||
text: "Continue"
|
|
||||||
onClicked: {
|
|
||||||
root.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,62 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
import QtQuick.Layouts
|
|
||||||
|
|
||||||
Popup {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property string questionText
|
|
||||||
property string yesText: "yes"
|
|
||||||
property string noText: "no"
|
|
||||||
property var yesFunc
|
|
||||||
property var noFunc
|
|
||||||
|
|
||||||
anchors.centerIn: Overlay.overlay
|
|
||||||
modal: true
|
|
||||||
closePolicy: Popup.CloseOnEscape
|
|
||||||
|
|
||||||
width: parent.width - 20
|
|
||||||
focus: true
|
|
||||||
|
|
||||||
onAboutToHide: {
|
|
||||||
parent.forceActiveFocus(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
width: parent.width
|
|
||||||
|
|
||||||
Text {
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
Layout.fillWidth: true
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
font.pixelSize: 16
|
|
||||||
text: questionText
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
BlueButtonType {
|
|
||||||
id: yesButton
|
|
||||||
Layout.fillWidth: true
|
|
||||||
text: yesText
|
|
||||||
onClicked: {
|
|
||||||
root.enabled = false
|
|
||||||
if (yesFunc && typeof yesFunc === "function") {
|
|
||||||
yesFunc()
|
|
||||||
}
|
|
||||||
root.enabled = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BlueButtonType {
|
|
||||||
id: noButton
|
|
||||||
Layout.fillWidth: true
|
|
||||||
text: noText
|
|
||||||
onClicked: {
|
|
||||||
if (noFunc && typeof noFunc === "function") {
|
|
||||||
noFunc()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,62 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
import QtQuick.Layouts
|
|
||||||
|
|
||||||
Popup {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property alias text: textField.text
|
|
||||||
property alias placeholderText: textField.placeholderText
|
|
||||||
property string yesText: "yes"
|
|
||||||
property string noText: "no"
|
|
||||||
property var yesFunc
|
|
||||||
property var noFunc
|
|
||||||
|
|
||||||
signal editingFinished()
|
|
||||||
|
|
||||||
anchors.centerIn: Overlay.overlay
|
|
||||||
modal: true
|
|
||||||
closePolicy: Popup.NoAutoClose
|
|
||||||
|
|
||||||
width: parent.width - 20
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
width: parent.width
|
|
||||||
|
|
||||||
TextField {
|
|
||||||
id: textField
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
Layout.fillWidth: true
|
|
||||||
font.pixelSize: 16
|
|
||||||
echoMode: TextInput.Password
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
BlueButtonType {
|
|
||||||
id: yesButton
|
|
||||||
Layout.preferredWidth: parent.width / 2
|
|
||||||
Layout.fillWidth: true
|
|
||||||
text: yesText
|
|
||||||
onClicked: {
|
|
||||||
root.enabled = false
|
|
||||||
if (yesFunc && typeof yesFunc === "function") {
|
|
||||||
yesFunc()
|
|
||||||
}
|
|
||||||
root.enabled = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BlueButtonType {
|
|
||||||
id: noButton
|
|
||||||
Layout.preferredWidth: parent.width / 2
|
|
||||||
Layout.fillWidth: true
|
|
||||||
text: noText
|
|
||||||
onClicked: {
|
|
||||||
if (noFunc && typeof noFunc === "function") {
|
|
||||||
noFunc()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
|
|
||||||
RadioButton {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
indicator: Rectangle {
|
|
||||||
implicitWidth: 13
|
|
||||||
implicitHeight: 13
|
|
||||||
x: root.leftPadding
|
|
||||||
y: parent.height / 2 - height / 2
|
|
||||||
radius: 13
|
|
||||||
border.color: root.down ? "#777777" : "#777777"
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
width: 7
|
|
||||||
height: 7
|
|
||||||
x: 3
|
|
||||||
y: 3
|
|
||||||
radius: 4
|
|
||||||
color: root.down ? "#15CDCB" : "#15CDCB"
|
|
||||||
visible: root.checked
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
contentItem: Text {
|
|
||||||
text: root.text
|
|
||||||
font.family: "Lato"
|
|
||||||
font.styleName: "normal"
|
|
||||||
font.pixelSize: 16
|
|
||||||
color: enabled ? "#181922" : "#686972"
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
leftPadding: root.indicator.width + root.spacing
|
|
||||||
}
|
|
||||||
height: 10
|
|
||||||
}
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
|
|
||||||
LabelType {
|
|
||||||
id: label_connection_code
|
|
||||||
width: parent.width - 60
|
|
||||||
x: 30
|
|
||||||
font.pixelSize: 14
|
|
||||||
textFormat: Text.RichText
|
|
||||||
onLinkActivated: Qt.openUrlExternally(link)
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
|
|
||||||
acceptedButtons: Qt.NoButton
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
|
|
||||||
BasicButtonType {
|
|
||||||
id: root
|
|
||||||
property alias textItem: textItem
|
|
||||||
height: 30
|
|
||||||
|
|
||||||
background: Item {}
|
|
||||||
contentItem: Item {
|
|
||||||
SvgImageType {
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
svg.source: root.icon.source
|
|
||||||
enabled: root.enabled
|
|
||||||
color: "#100A44"
|
|
||||||
width: 25
|
|
||||||
height: 25
|
|
||||||
}
|
|
||||||
Text {
|
|
||||||
id: textItem
|
|
||||||
anchors.fill: parent
|
|
||||||
leftPadding: 30
|
|
||||||
text: root.text
|
|
||||||
color: root.enabled ? "#100A44": "#AAAAAA"
|
|
||||||
font.family: "Lato"
|
|
||||||
font.styleName: "normal"
|
|
||||||
font.pixelSize: 20
|
|
||||||
horizontalAlignment: Text.AlignLeft
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
|
|
||||||
ShareConnectionButtonType {
|
|
||||||
property string start_text: qsTr("Copy")
|
|
||||||
property string end_text: qsTr("Copied")
|
|
||||||
|
|
||||||
property string copyText
|
|
||||||
|
|
||||||
enabled: copyText.length > 0
|
|
||||||
visible: copyText.length > 0
|
|
||||||
|
|
||||||
Timer {
|
|
||||||
id: timer
|
|
||||||
interval: 1000; running: false; repeat: false
|
|
||||||
onTriggered: text = start_text
|
|
||||||
}
|
|
||||||
|
|
||||||
text: start_text
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
text = end_text
|
|
||||||
timer.running = true
|
|
||||||
UiLogic.copyToClipboard(copyText)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
|
|
||||||
|
|
||||||
BasicButtonType {
|
|
||||||
id: root
|
|
||||||
height: 40
|
|
||||||
background: Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
radius: 4
|
|
||||||
color: root.enabled
|
|
||||||
? (root.containsMouse ? "#282932" : "#181922")
|
|
||||||
: "#484952"
|
|
||||||
}
|
|
||||||
font.pixelSize: 16
|
|
||||||
contentItem: Text {
|
|
||||||
anchors.fill: parent
|
|
||||||
font.family: "Lato"
|
|
||||||
font.styleName: "normal"
|
|
||||||
font.pixelSize: root.font.pixelSize
|
|
||||||
color: "#D4D4D4"
|
|
||||||
text: root.text
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
}
|
|
||||||
antialiasing: true
|
|
||||||
}
|
|
||||||
|
|
@ -1,65 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
import QtQuick.Shapes 1.4
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: root
|
|
||||||
property bool active: false
|
|
||||||
property string text: ""
|
|
||||||
height: active ? contentLoader.item.height + 40 + 5 * 2 : 40
|
|
||||||
signal clicked()
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
x: 0
|
|
||||||
y: 0
|
|
||||||
width: parent.width
|
|
||||||
height: 40
|
|
||||||
color: "transparent"
|
|
||||||
clip: true
|
|
||||||
radius: 2
|
|
||||||
gradient: LinearGradient {
|
|
||||||
x1: 0 ; y1: 0
|
|
||||||
x2: 0 ; y2: height
|
|
||||||
stops: [
|
|
||||||
GradientStop { position: 0.0; color: "#E1E1E1" },
|
|
||||||
GradientStop { position: 0.4; color: "#DDDDDD" },
|
|
||||||
GradientStop { position: 0.5; color: "#D8D8D8" },
|
|
||||||
GradientStop { position: 1.0; color: "#D3D3D3" }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
Image {
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: 10
|
|
||||||
source: "qrc:/images/share.png"
|
|
||||||
}
|
|
||||||
Rectangle {
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
height: 2
|
|
||||||
color: "#148CD2"
|
|
||||||
visible: ms.containsMouse ? true : false
|
|
||||||
}
|
|
||||||
Text {
|
|
||||||
x: 40
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
font.family: "Lato"
|
|
||||||
font.styleName: "normal"
|
|
||||||
font.pixelSize: 18
|
|
||||||
color: "#100A44"
|
|
||||||
font.bold: true
|
|
||||||
text: root.text
|
|
||||||
horizontalAlignment: Text.AlignLeft
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
}
|
|
||||||
MouseArea {
|
|
||||||
id: ms
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
onClicked: root.clicked()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
import "."
|
|
||||||
|
|
||||||
BasicButtonType {
|
|
||||||
id: root
|
|
||||||
icon.color: "#181922"
|
|
||||||
|
|
||||||
background: Item {}
|
|
||||||
contentItem: SvgImageType {
|
|
||||||
svg.source: icon.source
|
|
||||||
color: icon.color
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: parent.containsMouse ? 0 : 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
import Qt5Compat.GraphicalEffects
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: root
|
|
||||||
property color color: "#181922"
|
|
||||||
property alias svg: image
|
|
||||||
Image {
|
|
||||||
anchors.fill: parent
|
|
||||||
id: image
|
|
||||||
sourceSize: Qt.size(root.width, root.height)
|
|
||||||
|
|
||||||
antialiasing: true
|
|
||||||
visible: false
|
|
||||||
}
|
|
||||||
|
|
||||||
ColorOverlay {
|
|
||||||
anchors.fill: image
|
|
||||||
source: image
|
|
||||||
color: root.enabled ? root.color : "grey"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,63 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
import Qt.labs.platform
|
|
||||||
|
|
||||||
import "../Config"
|
|
||||||
|
|
||||||
Flickable
|
|
||||||
{
|
|
||||||
property alias textArea: root
|
|
||||||
id: flickable
|
|
||||||
flickableDirection: Flickable.VerticalFlick
|
|
||||||
clip: true
|
|
||||||
TextArea.flickable:
|
|
||||||
|
|
||||||
TextArea {
|
|
||||||
id: root
|
|
||||||
property bool error: false
|
|
||||||
|
|
||||||
height: 40
|
|
||||||
anchors.topMargin: 5
|
|
||||||
selectByMouse: false
|
|
||||||
|
|
||||||
selectionColor: "darkgray"
|
|
||||||
font.pixelSize: 16
|
|
||||||
color: "#333333"
|
|
||||||
background: Rectangle {
|
|
||||||
implicitWidth: 200
|
|
||||||
implicitHeight: 40
|
|
||||||
border.width: 1
|
|
||||||
color: {
|
|
||||||
if (root.error) {
|
|
||||||
return Qt.rgba(213, 40, 60, 255)
|
|
||||||
}
|
|
||||||
return root.enabled ? "#F4F4F4" : Qt.rgba(127, 127, 127, 255)
|
|
||||||
}
|
|
||||||
border.color: {
|
|
||||||
if (!root.enabled) {
|
|
||||||
return Qt.rgba(127, 127, 127, 255)
|
|
||||||
}
|
|
||||||
if (root.error) {
|
|
||||||
return Qt.rgba(213, 40, 60, 255)
|
|
||||||
}
|
|
||||||
if (root.focus) {
|
|
||||||
return "#A7A7A7"
|
|
||||||
}
|
|
||||||
return "#A7A7A7"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MouseArea {
|
|
||||||
// anchors.fill: root
|
|
||||||
// enabled: GC.isDesktop()
|
|
||||||
// acceptedButtons: Qt.RightButton
|
|
||||||
// onClicked: contextMenu.open()
|
|
||||||
// }
|
|
||||||
|
|
||||||
// ContextMenu {
|
|
||||||
// id: contextMenu
|
|
||||||
// textObj: root
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,52 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
import Qt.labs.platform
|
|
||||||
import "../Config"
|
|
||||||
|
|
||||||
TextField {
|
|
||||||
id: root
|
|
||||||
property bool error: false
|
|
||||||
|
|
||||||
width: parent.width - 2 * GC.defaultMargin
|
|
||||||
height: 40
|
|
||||||
anchors.topMargin: 5
|
|
||||||
selectByMouse: true
|
|
||||||
selectionColor: "darkgray"
|
|
||||||
font.pixelSize: 16
|
|
||||||
color: "#333333"
|
|
||||||
|
|
||||||
background: Rectangle {
|
|
||||||
implicitWidth: 200
|
|
||||||
implicitHeight: 40
|
|
||||||
border.width: 1
|
|
||||||
color: {
|
|
||||||
if (root.error) {
|
|
||||||
return Qt.rgba(213, 40, 60, 255)
|
|
||||||
}
|
|
||||||
return root.enabled ? "#F4F4F4" : Qt.rgba(127, 127, 127, 255)
|
|
||||||
}
|
|
||||||
border.color: {
|
|
||||||
if (!root.enabled) {
|
|
||||||
return Qt.rgba(127, 127, 127, 255)
|
|
||||||
}
|
|
||||||
if (root.error) {
|
|
||||||
return Qt.rgba(213, 40, 60, 255)
|
|
||||||
}
|
|
||||||
if (root.focus) {
|
|
||||||
return "#A7A7A7"
|
|
||||||
}
|
|
||||||
return "#A7A7A7"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
acceptedButtons: Qt.RightButton
|
|
||||||
onClicked: contextMenu.open()
|
|
||||||
}
|
|
||||||
|
|
||||||
ContextMenu {
|
|
||||||
id: contextMenu
|
|
||||||
textObj: root
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
import QtQuick 2.12
|
|
||||||
import QtQuick.Controls 2.12
|
|
||||||
|
|
||||||
BasicButtonType {
|
|
||||||
property alias label: lbl
|
|
||||||
id: root
|
|
||||||
antialiasing: true
|
|
||||||
height: 21
|
|
||||||
background: Item {}
|
|
||||||
|
|
||||||
contentItem: Text {
|
|
||||||
id: lbl
|
|
||||||
anchors.fill: parent
|
|
||||||
font.family: "Lato"
|
|
||||||
font.styleName: "normal"
|
|
||||||
font.pixelSize: 18
|
|
||||||
font.underline: true
|
|
||||||
|
|
||||||
text: root.text
|
|
||||||
color: "#3045ee"
|
|
||||||
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
FadeBehavior {
|
|
||||||
fadeProperty: "opacity"
|
|
||||||
fadeDuration: 200
|
|
||||||
outAnimation.duration: targetValue ? 0 : fadeDuration
|
|
||||||
inAnimation.duration: targetValue ? fadeDuration : 0
|
|
||||||
}
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
import QtQuick.Layouts
|
|
||||||
import PageEnum 1.0
|
|
||||||
import ProtocolEnum 1.0
|
|
||||||
import "../"
|
|
||||||
import "../../Controls"
|
|
||||||
import "../../Config"
|
|
||||||
|
|
||||||
PageBase {
|
|
||||||
id: root
|
|
||||||
property var protocol: ProtocolEnum.Any
|
|
||||||
page: PageEnum.ClientInfo
|
|
||||||
logic: ClientInfoLogic
|
|
||||||
}
|
|
||||||
|
|
@ -1,115 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
import QtQuick.Layouts
|
|
||||||
import ProtocolEnum 1.0
|
|
||||||
import "../"
|
|
||||||
import "../../Controls"
|
|
||||||
import "../../Config"
|
|
||||||
|
|
||||||
PageClientInfoBase {
|
|
||||||
id: root
|
|
||||||
protocol: ProtocolEnum.OpenVpn
|
|
||||||
|
|
||||||
BackButton {
|
|
||||||
id: back
|
|
||||||
enabled: !ClientInfoLogic.busyIndicatorIsRunning
|
|
||||||
}
|
|
||||||
|
|
||||||
Caption {
|
|
||||||
id: caption
|
|
||||||
text: qsTr("Client Info")
|
|
||||||
}
|
|
||||||
|
|
||||||
BusyIndicator {
|
|
||||||
z: 99
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
visible: ClientInfoLogic.busyIndicatorIsRunning
|
|
||||||
running: ClientInfoLogic.busyIndicatorIsRunning
|
|
||||||
}
|
|
||||||
|
|
||||||
FlickableType {
|
|
||||||
id: fl
|
|
||||||
anchors.top: caption.bottom
|
|
||||||
contentHeight: content.height
|
|
||||||
visible: ClientInfoLogic.pageContentVisible
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: content
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: GC.defaultMargin
|
|
||||||
|
|
||||||
LabelType {
|
|
||||||
enabled: !ClientInfoLogic.busyIndicatorIsRunning
|
|
||||||
Layout.fillWidth: true
|
|
||||||
font.pixelSize: 20
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
text: ClientInfoLogic.labelCurrentVpnProtocolText
|
|
||||||
}
|
|
||||||
|
|
||||||
LabelType {
|
|
||||||
enabled: !ClientInfoLogic.busyIndicatorIsRunning
|
|
||||||
height: 21
|
|
||||||
text: qsTr("Client name")
|
|
||||||
}
|
|
||||||
|
|
||||||
TextFieldType {
|
|
||||||
enabled: !ClientInfoLogic.busyIndicatorIsRunning
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: 31
|
|
||||||
text: ClientInfoLogic.lineEditNameAliasText
|
|
||||||
onEditingFinished: {
|
|
||||||
if (text !== ClientInfoLogic.lineEditNameAliasText) {
|
|
||||||
ClientInfoLogic.lineEditNameAliasText = text
|
|
||||||
ClientInfoLogic.onLineEditNameAliasEditingFinished()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LabelType {
|
|
||||||
enabled: !ClientInfoLogic.busyIndicatorIsRunning
|
|
||||||
Layout.topMargin: 20
|
|
||||||
height: 21
|
|
||||||
text: qsTr("Certificate id")
|
|
||||||
}
|
|
||||||
|
|
||||||
LabelType {
|
|
||||||
enabled: !ClientInfoLogic.busyIndicatorIsRunning
|
|
||||||
Layout.fillWidth: true
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
text: ClientInfoLogic.labelOpenVpnCertId
|
|
||||||
}
|
|
||||||
|
|
||||||
LabelType {
|
|
||||||
enabled: !ClientInfoLogic.busyIndicatorIsRunning
|
|
||||||
Layout.topMargin: 20
|
|
||||||
height: 21
|
|
||||||
text: qsTr("Certificate")
|
|
||||||
}
|
|
||||||
|
|
||||||
TextAreaType {
|
|
||||||
enabled: !ClientInfoLogic.busyIndicatorIsRunning
|
|
||||||
Layout.preferredHeight: 200
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
textArea.readOnly: true
|
|
||||||
textArea.wrapMode: TextEdit.WrapAnywhere
|
|
||||||
textArea.verticalAlignment: Text.AlignTop
|
|
||||||
textArea.text: ClientInfoLogic.textAreaOpenVpnCertData
|
|
||||||
}
|
|
||||||
|
|
||||||
BlueButtonType {
|
|
||||||
enabled: !ClientInfoLogic.busyIndicatorIsRunning
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: 41
|
|
||||||
text: qsTr("Revoke Certificate")
|
|
||||||
onClicked: {
|
|
||||||
ClientInfoLogic.onRevokeOpenVpnCertificateClicked()
|
|
||||||
UiLogic.closePage()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,100 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
import QtQuick.Layouts
|
|
||||||
import ProtocolEnum 1.0
|
|
||||||
import "../"
|
|
||||||
import "../../Controls"
|
|
||||||
import "../../Config"
|
|
||||||
|
|
||||||
PageClientInfoBase {
|
|
||||||
id: root
|
|
||||||
protocol: ProtocolEnum.WireGuard
|
|
||||||
|
|
||||||
BackButton {
|
|
||||||
id: back
|
|
||||||
enabled: !ClientInfoLogic.busyIndicatorIsRunning
|
|
||||||
}
|
|
||||||
|
|
||||||
Caption {
|
|
||||||
id: caption
|
|
||||||
text: qsTr("Client Info")
|
|
||||||
}
|
|
||||||
|
|
||||||
BusyIndicator {
|
|
||||||
z: 99
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
visible: ClientInfoLogic.busyIndicatorIsRunning
|
|
||||||
running: ClientInfoLogic.busyIndicatorIsRunning
|
|
||||||
}
|
|
||||||
|
|
||||||
FlickableType {
|
|
||||||
id: fl
|
|
||||||
anchors.top: caption.bottom
|
|
||||||
contentHeight: content.height
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: content
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: GC.defaultMargin
|
|
||||||
|
|
||||||
LabelType {
|
|
||||||
enabled: !ClientInfoLogic.busyIndicatorIsRunning
|
|
||||||
Layout.fillWidth: true
|
|
||||||
font.pixelSize: 20
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
text: ClientInfoLogic.labelCurrentVpnProtocolText
|
|
||||||
}
|
|
||||||
|
|
||||||
LabelType {
|
|
||||||
enabled: !ClientInfoLogic.busyIndicatorIsRunning
|
|
||||||
height: 21
|
|
||||||
text: qsTr("Client name")
|
|
||||||
}
|
|
||||||
|
|
||||||
TextFieldType {
|
|
||||||
enabled: !ClientInfoLogic.busyIndicatorIsRunning
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: 31
|
|
||||||
text: ClientInfoLogic.lineEditNameAliasText
|
|
||||||
onEditingFinished: {
|
|
||||||
if (text !== ClientInfoLogic.lineEditNameAliasText) {
|
|
||||||
ClientInfoLogic.lineEditNameAliasText = text
|
|
||||||
ClientInfoLogic.onLineEditNameAliasEditingFinished()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LabelType {
|
|
||||||
enabled: !ClientInfoLogic.busyIndicatorIsRunning
|
|
||||||
Layout.topMargin: 20
|
|
||||||
height: 21
|
|
||||||
text: qsTr("Public Key")
|
|
||||||
}
|
|
||||||
|
|
||||||
TextAreaType {
|
|
||||||
enabled: !ClientInfoLogic.busyIndicatorIsRunning
|
|
||||||
Layout.preferredHeight: 200
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
textArea.readOnly: true
|
|
||||||
textArea.wrapMode: TextEdit.WrapAnywhere
|
|
||||||
textArea.verticalAlignment: Text.AlignTop
|
|
||||||
textArea.text: ClientInfoLogic.textAreaWireGuardKeyData
|
|
||||||
}
|
|
||||||
|
|
||||||
BlueButtonType {
|
|
||||||
enabled: !ClientInfoLogic.busyIndicatorIsRunning
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: 41
|
|
||||||
text: qsTr("Revoke Key")
|
|
||||||
onClicked: {
|
|
||||||
ClientInfoLogic.onRevokeWireGuardKeyClicked()
|
|
||||||
UiLogic.closePage()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,75 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
import "./"
|
|
||||||
import "../../Controls"
|
|
||||||
import "../../Config"
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
signal containerChecked(bool checked)
|
|
||||||
property bool initiallyChecked: false
|
|
||||||
property string containerDescription
|
|
||||||
default property alias itemSettings: container.data
|
|
||||||
|
|
||||||
x: 5
|
|
||||||
y: 5
|
|
||||||
width: parent.width - 20
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
|
|
||||||
height: frame_settings.visible ? 140 : 72
|
|
||||||
border.width: 1
|
|
||||||
border.color: "lightgray"
|
|
||||||
radius: 2
|
|
||||||
Rectangle {
|
|
||||||
id: frame_settings
|
|
||||||
height: 77
|
|
||||||
width: parent.width
|
|
||||||
border.width: 1
|
|
||||||
border.color: "lightgray"
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
anchors.bottomMargin: 5
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
visible: false
|
|
||||||
radius: 2
|
|
||||||
Grid {
|
|
||||||
id: container
|
|
||||||
anchors.fill: parent
|
|
||||||
columns: 2
|
|
||||||
horizontalItemAlignment: Grid.AlignHCenter
|
|
||||||
verticalItemAlignment: Grid.AlignVCenter
|
|
||||||
topPadding: 5
|
|
||||||
leftPadding: 10
|
|
||||||
spacing: 5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Row {
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.topMargin: 5
|
|
||||||
leftPadding: 15
|
|
||||||
rightPadding: 5
|
|
||||||
height: 55
|
|
||||||
width: parent.width
|
|
||||||
CheckBoxType {
|
|
||||||
text: containerDescription
|
|
||||||
height: parent.height
|
|
||||||
width: parent.width - 50
|
|
||||||
checked: initiallyChecked
|
|
||||||
onCheckedChanged: containerChecked(checked)
|
|
||||||
}
|
|
||||||
ImageButtonType {
|
|
||||||
width: 35
|
|
||||||
height: 35
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
icon.source: "qrc:/images/settings.png"
|
|
||||||
checkable: true
|
|
||||||
checked: initiallyChecked
|
|
||||||
onCheckedChanged: {
|
|
||||||
//NewServerProtocolsLogic.pushButtonSettingsCloakChecked = checked
|
|
||||||
if (checked) {
|
|
||||||
frame_settings.visible = true
|
|
||||||
} else {
|
|
||||||
frame_settings.visible = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,200 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
import SortFilterProxyModel 0.2
|
|
||||||
import ProtocolEnum 1.0
|
|
||||||
import "./"
|
|
||||||
import "../../Controls"
|
|
||||||
import "../../Config"
|
|
||||||
|
|
||||||
Drawer {
|
|
||||||
id: root
|
|
||||||
signal containerSelected(int c_index)
|
|
||||||
property int selectedIndex: -1
|
|
||||||
|
|
||||||
y: 0
|
|
||||||
x: 0
|
|
||||||
edge: Qt.RightEdge
|
|
||||||
width: parent.width * 0.85
|
|
||||||
height: parent.height
|
|
||||||
|
|
||||||
modal: true
|
|
||||||
interactive: activeFocus
|
|
||||||
|
|
||||||
SortFilterProxyModel {
|
|
||||||
id: proxyModel
|
|
||||||
sourceModel: UiLogic.containersModel
|
|
||||||
filters: [
|
|
||||||
ValueFilter {
|
|
||||||
roleName: "is_installed_role"
|
|
||||||
value: false },
|
|
||||||
ValueFilter {
|
|
||||||
roleName: "service_type_role"
|
|
||||||
value: ProtocolEnum.Vpn }
|
|
||||||
]
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
SortFilterProxyModel {
|
|
||||||
id: proxyModel_other
|
|
||||||
sourceModel: UiLogic.containersModel
|
|
||||||
filters: [
|
|
||||||
ValueFilter {
|
|
||||||
roleName: "is_installed_role"
|
|
||||||
value: false },
|
|
||||||
ValueFilter {
|
|
||||||
roleName: "service_type_role"
|
|
||||||
value: ProtocolEnum.Other }
|
|
||||||
]
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
FlickableType {
|
|
||||||
anchors.fill: parent
|
|
||||||
contentHeight: col.height
|
|
||||||
|
|
||||||
Column {
|
|
||||||
id: col
|
|
||||||
anchors {
|
|
||||||
left: parent.left;
|
|
||||||
right: parent.right;
|
|
||||||
}
|
|
||||||
topPadding: 20
|
|
||||||
spacing: 10
|
|
||||||
|
|
||||||
Caption {
|
|
||||||
id: cap1
|
|
||||||
text: qsTr("VPN containers")
|
|
||||||
font.pixelSize: 20
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ListView {
|
|
||||||
id: tb
|
|
||||||
x: 10
|
|
||||||
currentIndex: -1
|
|
||||||
width: parent.width - 20
|
|
||||||
height: contentItem.height
|
|
||||||
|
|
||||||
spacing: 0
|
|
||||||
clip: true
|
|
||||||
interactive: false
|
|
||||||
model: proxyModel
|
|
||||||
|
|
||||||
delegate: Item {
|
|
||||||
implicitWidth: 170 * 2
|
|
||||||
implicitHeight: 30
|
|
||||||
Item {
|
|
||||||
width: parent.width
|
|
||||||
height: 30
|
|
||||||
anchors.left: parent.left
|
|
||||||
id: c1
|
|
||||||
Rectangle {
|
|
||||||
anchors.top: parent.top
|
|
||||||
width: parent.width
|
|
||||||
height: 1
|
|
||||||
color: "lightgray"
|
|
||||||
visible: index !== tb.currentIndex
|
|
||||||
}
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
color: "#63B4FB"
|
|
||||||
visible: index === tb.currentIndex
|
|
||||||
|
|
||||||
}
|
|
||||||
Text {
|
|
||||||
id: text_name
|
|
||||||
text: name_role
|
|
||||||
font.pixelSize: 16
|
|
||||||
anchors.fill: parent
|
|
||||||
leftPadding: 10
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
onClicked: {
|
|
||||||
tb.currentIndex = index
|
|
||||||
tb_other.currentIndex = -1
|
|
||||||
containerSelected(proxyModel.mapToSource(index))
|
|
||||||
selectedIndex = proxyModel.mapToSource(index)
|
|
||||||
root.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Caption {
|
|
||||||
id: cap2
|
|
||||||
font.pixelSize: 20
|
|
||||||
text: qsTr("Other containers")
|
|
||||||
}
|
|
||||||
|
|
||||||
ListView {
|
|
||||||
id: tb_other
|
|
||||||
x: 10
|
|
||||||
currentIndex: -1
|
|
||||||
width: parent.width - 20
|
|
||||||
height: contentItem.height
|
|
||||||
|
|
||||||
spacing: 0
|
|
||||||
clip: true
|
|
||||||
interactive: false
|
|
||||||
model: proxyModel_other
|
|
||||||
|
|
||||||
delegate: Item {
|
|
||||||
implicitWidth: 170 * 2
|
|
||||||
implicitHeight: 30
|
|
||||||
Item {
|
|
||||||
width: parent.width
|
|
||||||
height: 30
|
|
||||||
anchors.left: parent.left
|
|
||||||
id: c1_other
|
|
||||||
Rectangle {
|
|
||||||
anchors.top: parent.top
|
|
||||||
width: parent.width
|
|
||||||
height: 1
|
|
||||||
color: "lightgray"
|
|
||||||
visible: index !== tb_other.currentIndex
|
|
||||||
}
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
color: "#63B4FB"
|
|
||||||
visible: index === tb_other.currentIndex
|
|
||||||
|
|
||||||
}
|
|
||||||
Text {
|
|
||||||
id: text_name_other
|
|
||||||
text: name_role
|
|
||||||
font.pixelSize: 16
|
|
||||||
anchors.fill: parent
|
|
||||||
leftPadding: 10
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
onClicked: {
|
|
||||||
tb_other.currentIndex = index
|
|
||||||
tb.currentIndex = -1
|
|
||||||
containerSelected(proxyModel_other.mapToSource(index))
|
|
||||||
selectedIndex = proxyModel_other.mapToSource(index)
|
|
||||||
root.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,90 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
import PageEnum 1.0
|
|
||||||
import "./"
|
|
||||||
import "../Controls"
|
|
||||||
import "../Config"
|
|
||||||
|
|
||||||
PageBase {
|
|
||||||
id: root
|
|
||||||
page: PageEnum.About
|
|
||||||
|
|
||||||
BackButton {
|
|
||||||
id: back_from_start
|
|
||||||
}
|
|
||||||
|
|
||||||
Caption {
|
|
||||||
id: caption
|
|
||||||
font.pixelSize: 22
|
|
||||||
text: qsTr("About Amnezia")
|
|
||||||
}
|
|
||||||
|
|
||||||
RichLabelType {
|
|
||||||
id: label_about
|
|
||||||
anchors.top: caption.bottom
|
|
||||||
|
|
||||||
text: qsTr("AmneziaVPN is opensource software, it's free forever. Our goal is to make the best VPN client in the world.
|
|
||||||
<ul>
|
|
||||||
<li>Sources on <a href=\"https://github.com/amnezia-vpn/desktop-client\">GitHub</a></li>
|
|
||||||
<li><a href=\"https://amnezia.org/\">Web Site</a></li>
|
|
||||||
<li><a href=\"https://t.me/amnezia_vpn_en\">Telegram group</a></li>
|
|
||||||
<li><a href=\"https://signal.group/#CjQKIB2gUf8QH_IXnOJMGQWMDjYz9cNfmRQipGWLFiIgc4MwEhAKBONrSiWHvoUFbbD0xwdh\">Signal group</a></li>
|
|
||||||
</ul>
|
|
||||||
")
|
|
||||||
}
|
|
||||||
|
|
||||||
Caption {
|
|
||||||
id: caption2
|
|
||||||
anchors.topMargin: 20
|
|
||||||
font.pixelSize: 22
|
|
||||||
text: qsTr("Support")
|
|
||||||
anchors.top: label_about.bottom
|
|
||||||
}
|
|
||||||
|
|
||||||
RichLabelType {
|
|
||||||
id: label_support
|
|
||||||
anchors.top: caption2.bottom
|
|
||||||
|
|
||||||
text: qsTr("Have questions? You can get support by:
|
|
||||||
<ul>
|
|
||||||
<li><a href=\"https://t.me/amnezia_vpn_en\">Telegram group</a> (preferred way)</li>
|
|
||||||
<li>Create issue on <a href=\"https://github.com/amnezia-vpn/desktop-client/issues\">GitHub</a></li>
|
|
||||||
<li>Email to: <a href=\"support@amnezia.org\">support@amnezia.org</a></li>
|
|
||||||
</ul>")
|
|
||||||
}
|
|
||||||
|
|
||||||
Caption {
|
|
||||||
id: caption3
|
|
||||||
anchors.topMargin: 20
|
|
||||||
font.pixelSize: 22
|
|
||||||
text: qsTr("Donate")
|
|
||||||
width: undefined
|
|
||||||
anchors.top: label_support.bottom
|
|
||||||
}
|
|
||||||
|
|
||||||
LabelType {
|
|
||||||
anchors.bottom: caption3.bottom
|
|
||||||
anchors.left: caption3.right
|
|
||||||
anchors.leftMargin: 5
|
|
||||||
font.pixelSize: 24
|
|
||||||
text: "♥"
|
|
||||||
color: "red"
|
|
||||||
}
|
|
||||||
|
|
||||||
RichLabelType {
|
|
||||||
id: label_donate
|
|
||||||
anchors.top: caption3.bottom
|
|
||||||
|
|
||||||
text: qsTr("Please support Amnezia project by donation, we really need it now more than ever.
|
|
||||||
<ul>
|
|
||||||
<li>By credit card on <a href=\"https://www.patreon.com/amneziavpn\">Patreon</a> (starting from $1)</li>
|
|
||||||
<li>Send some coins to addresses listed <a href=\"https://github.com/amnezia-vpn/desktop-client/blob/master/README.md\">on GitHub page</a></li>
|
|
||||||
</ul>
|
|
||||||
")
|
|
||||||
}
|
|
||||||
|
|
||||||
Logo {
|
|
||||||
id: logo
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,118 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
import QtQuick.Layouts
|
|
||||||
import PageEnum 1.0
|
|
||||||
import "./"
|
|
||||||
import "../Controls"
|
|
||||||
import "../Config"
|
|
||||||
|
|
||||||
PageBase {
|
|
||||||
id: root
|
|
||||||
page: PageEnum.AdvancedServerSettings
|
|
||||||
logic: AdvancedServerSettingsLogic
|
|
||||||
|
|
||||||
enabled: AdvancedServerSettingsLogic.pageEnabled
|
|
||||||
|
|
||||||
BackButton {
|
|
||||||
id: back
|
|
||||||
}
|
|
||||||
|
|
||||||
Caption {
|
|
||||||
id: caption
|
|
||||||
text: qsTr("Advanced server settings")
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
BusyIndicator {
|
|
||||||
z: 99
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
visible: !AdvancedServerSettingsLogic.pageEnabled
|
|
||||||
running: !AdvancedServerSettingsLogic.pageEnabled
|
|
||||||
}
|
|
||||||
|
|
||||||
FlickableType {
|
|
||||||
id: fl
|
|
||||||
anchors.top: caption.bottom
|
|
||||||
anchors.bottom: logo.top
|
|
||||||
contentHeight: content.height
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: content
|
|
||||||
enabled: logic.pageEnabled
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: 15
|
|
||||||
|
|
||||||
LabelType {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
font.pixelSize: 20
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
text: AdvancedServerSettingsLogic.labelCurrentVpnProtocolText
|
|
||||||
}
|
|
||||||
|
|
||||||
TextFieldType {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
font.pixelSize: 20
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
text: AdvancedServerSettingsLogic.labelServerText
|
|
||||||
readOnly: true
|
|
||||||
background: Item {}
|
|
||||||
}
|
|
||||||
|
|
||||||
LabelType {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
text: AdvancedServerSettingsLogic.labelWaitInfoText
|
|
||||||
visible: AdvancedServerSettingsLogic.labelWaitInfoVisible
|
|
||||||
}
|
|
||||||
|
|
||||||
BlueButtonType {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.topMargin: 10
|
|
||||||
text: "Scan the server for installed containers"
|
|
||||||
visible: AdvancedServerSettingsLogic.pushButtonClearVisible
|
|
||||||
onClicked: {
|
|
||||||
AdvancedServerSettingsLogic.onPushButtonScanServerClicked()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BlueButtonType {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.topMargin: 10
|
|
||||||
text: AdvancedServerSettingsLogic.pushButtonClearText
|
|
||||||
visible: AdvancedServerSettingsLogic.pushButtonClearVisible
|
|
||||||
onClicked: {
|
|
||||||
popupClearServer.open()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BlueButtonType {
|
|
||||||
Layout.topMargin: 10
|
|
||||||
Layout.fillWidth: true
|
|
||||||
text: qsTr("Clients Management")
|
|
||||||
onClicked: {
|
|
||||||
UiLogic.goToPage(PageEnum.ClientManagement)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PopupWithQuestion {
|
|
||||||
id: popupClearServer
|
|
||||||
questionText: "Attention! All containers will be deleted on the server. This means that configuration files, keys and certificates will be deleted. Continue?"
|
|
||||||
yesFunc: function() {
|
|
||||||
close()
|
|
||||||
AdvancedServerSettingsLogic.onPushButtonClearServerClicked()
|
|
||||||
}
|
|
||||||
noFunc: function() {
|
|
||||||
close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Logo {
|
|
||||||
id : logo
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,152 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
import QtQuick.Layouts
|
|
||||||
import PageEnum 1.0
|
|
||||||
import "./"
|
|
||||||
import "../Controls"
|
|
||||||
import "../Config"
|
|
||||||
|
|
||||||
PageBase {
|
|
||||||
id: root
|
|
||||||
page: PageEnum.AppSettings
|
|
||||||
logic: AppSettingsLogic
|
|
||||||
|
|
||||||
BackButton {
|
|
||||||
id: back
|
|
||||||
}
|
|
||||||
Caption {
|
|
||||||
id: caption
|
|
||||||
text: qsTr("Application Settings")
|
|
||||||
}
|
|
||||||
|
|
||||||
FlickableType {
|
|
||||||
id: fl
|
|
||||||
anchors.top: caption.bottom
|
|
||||||
contentHeight: content.height
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: content
|
|
||||||
enabled: logic.pageEnabled
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: 15
|
|
||||||
|
|
||||||
CheckBoxType {
|
|
||||||
visible: !GC.isMobile()
|
|
||||||
Layout.fillWidth: true
|
|
||||||
text: qsTr("Auto connect")
|
|
||||||
checked: AppSettingsLogic.checkBoxAutoConnectChecked
|
|
||||||
onCheckedChanged: {
|
|
||||||
AppSettingsLogic.checkBoxAutoConnectChecked = checked
|
|
||||||
AppSettingsLogic.onCheckBoxAutoconnectToggled(checked)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CheckBoxType {
|
|
||||||
visible: !GC.isMobile()
|
|
||||||
Layout.fillWidth: true
|
|
||||||
text: qsTr("Auto start")
|
|
||||||
checked: AppSettingsLogic.checkBoxAutostartChecked
|
|
||||||
onCheckedChanged: {
|
|
||||||
AppSettingsLogic.checkBoxAutostartChecked = checked
|
|
||||||
AppSettingsLogic.onCheckBoxAutostartToggled(checked)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CheckBoxType {
|
|
||||||
visible: !GC.isMobile()
|
|
||||||
Layout.fillWidth: true
|
|
||||||
text: qsTr("Start minimized")
|
|
||||||
checked: AppSettingsLogic.checkBoxStartMinimizedChecked
|
|
||||||
onCheckedChanged: {
|
|
||||||
AppSettingsLogic.checkBoxStartMinimizedChecked = checked
|
|
||||||
AppSettingsLogic.onCheckBoxStartMinimizedToggled(checked)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LabelType {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.topMargin: 15
|
|
||||||
text: AppSettingsLogic.labelVersionText
|
|
||||||
}
|
|
||||||
BlueButtonType {
|
|
||||||
visible: !GC.isMobile()
|
|
||||||
Layout.fillWidth: true
|
|
||||||
text: qsTr("Check for updates")
|
|
||||||
onClicked: {
|
|
||||||
Qt.openUrlExternally("https://github.com/amnezia-vpn/desktop-client/releases/latest")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CheckBoxType {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.topMargin: 15
|
|
||||||
text: qsTr("Keep logs")
|
|
||||||
checked: AppSettingsLogic.checkBoxSaveLogsChecked
|
|
||||||
onCheckedChanged: {
|
|
||||||
AppSettingsLogic.checkBoxSaveLogsChecked = checked
|
|
||||||
AppSettingsLogic.onCheckBoxSaveLogsCheckedToggled(checked)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BlueButtonType {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
text: qsTr("Open logs folder")
|
|
||||||
onClicked: {
|
|
||||||
AppSettingsLogic.onPushButtonOpenLogsClicked()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BlueButtonType {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.topMargin: 10
|
|
||||||
text: qsTr("Export logs")
|
|
||||||
onClicked: {
|
|
||||||
AppSettingsLogic.onPushButtonExportLogsClicked()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BlueButtonType {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.topMargin: 10
|
|
||||||
|
|
||||||
property string start_text: qsTr("Clear logs")
|
|
||||||
property string end_text: qsTr("Cleared")
|
|
||||||
text: start_text
|
|
||||||
|
|
||||||
Timer {
|
|
||||||
id: timer
|
|
||||||
interval: 1000; running: false; repeat: false
|
|
||||||
onTriggered: parent.text = parent.start_text
|
|
||||||
}
|
|
||||||
onClicked: {
|
|
||||||
text = end_text
|
|
||||||
timer.running = true
|
|
||||||
AppSettingsLogic.onPushButtonClearLogsClicked()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LabelType {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.topMargin: 30
|
|
||||||
text: qsTr("Backup and restore configuration")
|
|
||||||
}
|
|
||||||
|
|
||||||
BlueButtonType {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.topMargin: 10
|
|
||||||
Layout.preferredHeight: 41
|
|
||||||
text: qsTr("Backup app config")
|
|
||||||
onClicked: {
|
|
||||||
AppSettingsLogic.onPushButtonBackupAppConfigClicked()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BlueButtonType {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.topMargin: 10
|
|
||||||
Layout.preferredHeight: 41
|
|
||||||
text: qsTr("Restore app config")
|
|
||||||
onClicked: {
|
|
||||||
AppSettingsLogic.onPushButtonRestoreAppConfigClicked()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue