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/pages.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}/protocols/vpnprotocol.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}/protocols/protocols_defs.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}/protocols/vpnprotocol.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/core/sshclient.cpp
|
||||
|
|
|
@ -156,7 +156,7 @@ void AmneziaApplication::init()
|
|||
// Android TextField clipboard workaround
|
||||
// https://bugreports.qt.io/browse/QTBUG-113461
|
||||
#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 (qApp->clipboard()->mimeData()->formats().contains("text/html")) {
|
||||
QTextDocument doc;
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
#define amnApp (static_cast<AmneziaApplication *>(QCoreApplication::instance()))
|
||||
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
||||
#define AMNEZIA_BASE_CLASS QGuiApp
|
||||
#define AMNEZIA_BASE_CLASS QGuiApplication
|
||||
#else
|
||||
#define AMNEZIA_BASE_CLASS SingleApplication
|
||||
#define QAPPLICATION_CLASS QApplication
|
||||
|
|
|
@ -1,28 +1,26 @@
|
|||
#include "ikev2_configurator.h"
|
||||
#include <QApplication>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QJsonDocument>
|
||||
#include <QProcess>
|
||||
#include <QString>
|
||||
#include <QTemporaryDir>
|
||||
#include <QDebug>
|
||||
#include <QTemporaryFile>
|
||||
#include <QJsonDocument>
|
||||
#include <QUuid>
|
||||
|
||||
#include "containers/containers_defs.h"
|
||||
#include "core/server_defs.h"
|
||||
#include "core/scripts_registry.h"
|
||||
#include "utilities.h"
|
||||
#include "core/server_defs.h"
|
||||
#include "core/servercontroller.h"
|
||||
#include "utilities.h"
|
||||
|
||||
|
||||
Ikev2Configurator::Ikev2Configurator(std::shared_ptr<Settings> settings, QObject *parent):
|
||||
ConfiguratorBase(settings, parent)
|
||||
Ikev2Configurator::Ikev2Configurator(std::shared_ptr<Settings> settings, QObject *parent)
|
||||
: ConfiguratorBase(settings, parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Ikev2Configurator::ConnectionData Ikev2Configurator::prepareIkev2Config(const ServerCredentials &credentials,
|
||||
DockerContainer container, ErrorCode *errorCode)
|
||||
DockerContainer container, ErrorCode *errorCode)
|
||||
{
|
||||
Ikev2Configurator::ConnectionData connData;
|
||||
connData.host = credentials.hostName;
|
||||
|
@ -32,26 +30,27 @@ Ikev2Configurator::ConnectionData Ikev2Configurator::prepareIkev2Config(const Se
|
|||
|
||||
QString certFileName = "/opt/amnezia/ikev2/clients/" + connData.clientId + ".p12";
|
||||
|
||||
QString scriptCreateCert = QString("certutil -z <(head -c 1024 /dev/urandom) "\
|
||||
"-S -c \"IKEv2 VPN CA\" -n \"%1\" "\
|
||||
"-s \"O=IKEv2 VPN,CN=%1\" "\
|
||||
"-k rsa -g 3072 -v 120 "\
|
||||
"-d sql:/etc/ipsec.d -t \",,\" "\
|
||||
"--keyUsage digitalSignature,keyEncipherment "\
|
||||
"--extKeyUsage serverAuth,clientAuth -8 \"%1\"")
|
||||
.arg(connData.clientId);
|
||||
QString scriptCreateCert = QString("certutil -z <(head -c 1024 /dev/urandom) "
|
||||
"-S -c \"IKEv2 VPN CA\" -n \"%1\" "
|
||||
"-s \"O=IKEv2 VPN,CN=%1\" "
|
||||
"-k rsa -g 3072 -v 120 "
|
||||
"-d sql:/etc/ipsec.d -t \",,\" "
|
||||
"--keyUsage digitalSignature,keyEncipherment "
|
||||
"--extKeyUsage serverAuth,clientAuth -8 \"%1\"")
|
||||
.arg(connData.clientId);
|
||||
|
||||
ServerController serverController(m_settings);
|
||||
ErrorCode e = serverController.runContainerScript(credentials, container, scriptCreateCert);
|
||||
|
||||
QString scriptExportCert = QString("pk12util -W \"%1\" -d sql:/etc/ipsec.d -n \"%2\" -o \"%3\"")
|
||||
.arg(connData.password)
|
||||
.arg(connData.clientId)
|
||||
.arg(certFileName);
|
||||
.arg(connData.password)
|
||||
.arg(connData.clientId)
|
||||
.arg(certFileName);
|
||||
e = serverController.runContainerScript(credentials, container, scriptExportCert);
|
||||
|
||||
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 ca cert size:" << connData.caCert.size();
|
||||
|
@ -59,8 +58,8 @@ Ikev2Configurator::ConnectionData Ikev2Configurator::prepareIkev2Config(const Se
|
|||
return connData;
|
||||
}
|
||||
|
||||
QString Ikev2Configurator::genIkev2Config(const ServerCredentials &credentials,
|
||||
DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode)
|
||||
QString Ikev2Configurator::genIkev2Config(const ServerCredentials &credentials, DockerContainer container,
|
||||
const QJsonObject &containerConfig, ErrorCode *errorCode)
|
||||
{
|
||||
Q_UNUSED(containerConfig)
|
||||
|
||||
|
@ -120,4 +119,3 @@ QString Ikev2Configurator::genStrongSwanConfig(const ConnectionData &connData)
|
|||
|
||||
return config;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,82 +1,89 @@
|
|||
#include "openvpn_configurator.h"
|
||||
#include <QApplication>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QProcess>
|
||||
#include <QString>
|
||||
#include <QTemporaryDir>
|
||||
#include <QDebug>
|
||||
#include <QTemporaryFile>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
|
||||
#include "containers/containers_defs.h"
|
||||
#include "core/scripts_registry.h"
|
||||
#include "core/server_defs.h"
|
||||
#include "core/servercontroller.h"
|
||||
#include "core/scripts_registry.h"
|
||||
#include "utilities.h"
|
||||
#include "settings.h"
|
||||
#include "utilities.h"
|
||||
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/pem.h>
|
||||
|
||||
OpenVpnConfigurator::OpenVpnConfigurator(std::shared_ptr<Settings> settings, QObject *parent):
|
||||
ConfiguratorBase(settings, parent)
|
||||
OpenVpnConfigurator::OpenVpnConfigurator(std::shared_ptr<Settings> settings, QObject *parent)
|
||||
: ConfiguratorBase(settings, parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::prepareOpenVpnConfig(const ServerCredentials &credentials,
|
||||
DockerContainer container, ErrorCode *errorCode)
|
||||
DockerContainer container,
|
||||
ErrorCode *errorCode)
|
||||
{
|
||||
OpenVpnConfigurator::ConnectionData connData = OpenVpnConfigurator::createCertRequest();
|
||||
connData.host = credentials.hostName;
|
||||
|
||||
if (connData.privKey.isEmpty() || connData.request.isEmpty()) {
|
||||
if (errorCode) *errorCode = ErrorCode::OpenSslFailed;
|
||||
if (errorCode)
|
||||
*errorCode = ErrorCode::OpenSslFailed;
|
||||
return connData;
|
||||
}
|
||||
|
||||
QString reqFileName = QString("%1/%2.req").
|
||||
arg(amnezia::protocols::openvpn::clientsDirPath).
|
||||
arg(connData.clientId);
|
||||
QString reqFileName = QString("%1/%2.req").arg(amnezia::protocols::openvpn::clientsDirPath).arg(connData.clientId);
|
||||
|
||||
ServerController serverController(m_settings);
|
||||
ErrorCode e = serverController.uploadTextFileToContainer(container, credentials, connData.request, reqFileName);
|
||||
if (e) {
|
||||
if (errorCode) *errorCode = e;
|
||||
if (errorCode)
|
||||
*errorCode = e;
|
||||
return connData;
|
||||
}
|
||||
|
||||
e = signCert(container, credentials, connData.clientId);
|
||||
if (e) {
|
||||
if (errorCode) *errorCode = e;
|
||||
if (errorCode)
|
||||
*errorCode = e;
|
||||
return connData;
|
||||
}
|
||||
|
||||
connData.caCert = 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);
|
||||
connData.caCert = 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);
|
||||
|
||||
if (e) {
|
||||
if (errorCode) *errorCode = e;
|
||||
if (errorCode)
|
||||
*errorCode = e;
|
||||
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 (errorCode) *errorCode = ErrorCode::SshSftpFailureError;
|
||||
if (errorCode)
|
||||
*errorCode = ErrorCode::SshSftpFailureError;
|
||||
}
|
||||
|
||||
return connData;
|
||||
}
|
||||
|
||||
QString OpenVpnConfigurator::genOpenVpnConfig(const ServerCredentials &credentials,
|
||||
DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode)
|
||||
QString OpenVpnConfigurator::genOpenVpnConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||
const QJsonObject &containerConfig, ErrorCode *errorCode)
|
||||
{
|
||||
ServerController serverController(m_settings);
|
||||
QString config = serverController.replaceVars(amnezia::scriptData(ProtocolScriptType::openvpn_template, container),
|
||||
serverController.genVarsForScript(credentials, container, containerConfig));
|
||||
QString config =
|
||||
serverController.replaceVars(amnezia::scriptData(ProtocolScriptType::openvpn_template, container),
|
||||
serverController.genVarsForScript(credentials, container, containerConfig));
|
||||
|
||||
ConnectionData connData = prepareOpenVpnConfig(credentials, container, errorCode);
|
||||
if (errorCode && *errorCode) {
|
||||
|
@ -89,8 +96,7 @@ QString OpenVpnConfigurator::genOpenVpnConfig(const ServerCredentials &credentia
|
|||
|
||||
if (config.contains("$OPENVPN_TA_KEY")) {
|
||||
config.replace("$OPENVPN_TA_KEY", connData.taKey);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
config.replace("<tls-auth>", "");
|
||||
config.replace("</tls-auth>", "");
|
||||
}
|
||||
|
@ -133,12 +139,11 @@ QString OpenVpnConfigurator::processConfigWithLocalSettings(QString jsonConfig)
|
|||
config.replace("block-outside-dns", "");
|
||||
#endif
|
||||
|
||||
#if (defined (MZ_MACOS) || defined(MZ_LINUX))
|
||||
QString dnsConf = QString(
|
||||
"\nscript-security 2\n"
|
||||
"up %1/update-resolv-conf.sh\n"
|
||||
"down %1/update-resolv-conf.sh\n").
|
||||
arg(qApp->applicationDirPath());
|
||||
#if (defined(MZ_MACOS) || defined(MZ_LINUX))
|
||||
QString dnsConf = QString("\nscript-security 2\n"
|
||||
"up %1/update-resolv-conf.sh\n"
|
||||
"down %1/update-resolv-conf.sh\n")
|
||||
.arg(qApp->applicationDirPath());
|
||||
|
||||
config.append(dnsConf);
|
||||
#endif
|
||||
|
@ -168,23 +173,23 @@ QString OpenVpnConfigurator::processConfigWithExportSettings(QString jsonConfig)
|
|||
return QJsonDocument(json).toJson();
|
||||
}
|
||||
|
||||
ErrorCode OpenVpnConfigurator::signCert(DockerContainer container,
|
||||
const ServerCredentials &credentials, QString clientId)
|
||||
ErrorCode OpenVpnConfigurator::signCert(DockerContainer container, const ServerCredentials &credentials, QString clientId)
|
||||
{
|
||||
QString script_import = QString("sudo docker exec -i %1 bash -c \"cd /opt/amnezia/openvpn && "
|
||||
"easyrsa import-req %2/%3.req %3\"")
|
||||
.arg(ContainerProps::containerToString(container))
|
||||
.arg(amnezia::protocols::openvpn::clientsDirPath)
|
||||
.arg(clientId);
|
||||
"easyrsa import-req %2/%3.req %3\"")
|
||||
.arg(ContainerProps::containerToString(container))
|
||||
.arg(amnezia::protocols::openvpn::clientsDirPath)
|
||||
.arg(clientId);
|
||||
|
||||
QString script_sign = QString("sudo docker exec -i %1 bash -c \"export EASYRSA_BATCH=1; cd /opt/amnezia/openvpn && "
|
||||
"easyrsa sign-req client %2\"")
|
||||
.arg(ContainerProps::containerToString(container))
|
||||
.arg(clientId);
|
||||
"easyrsa sign-req client %2\"")
|
||||
.arg(ContainerProps::containerToString(container))
|
||||
.arg(clientId);
|
||||
|
||||
ServerController serverController(m_settings);
|
||||
QStringList scriptList {script_import, script_sign};
|
||||
QString script = serverController.replaceVars(scriptList.join("\n"), serverController.genVarsForScript(credentials, container));
|
||||
QStringList scriptList { script_import, script_sign };
|
||||
QString script = serverController.replaceVars(scriptList.join("\n"),
|
||||
serverController.genVarsForScript(credentials, container));
|
||||
|
||||
return serverController.runScript(credentials, script);
|
||||
}
|
||||
|
@ -194,18 +199,17 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::createCertRequest()
|
|||
ConnectionData connData;
|
||||
connData.clientId = Utils::getRandomString(32);
|
||||
|
||||
int ret = 0;
|
||||
int nVersion = 1;
|
||||
int ret = 0;
|
||||
int nVersion = 1;
|
||||
|
||||
QByteArray clientIdUtf8 = connData.clientId.toUtf8();
|
||||
|
||||
EVP_PKEY * pKey = EVP_PKEY_new();
|
||||
EVP_PKEY *pKey = EVP_PKEY_new();
|
||||
q_check_ptr(pKey);
|
||||
RSA * rsa = RSA_generate_key(2048, RSA_F4, nullptr, nullptr);
|
||||
RSA *rsa = RSA_generate_key(2048, RSA_F4, nullptr, nullptr);
|
||||
q_check_ptr(rsa);
|
||||
EVP_PKEY_assign_RSA(pKey, rsa);
|
||||
|
||||
|
||||
// 2. set version of x509 req
|
||||
X509_REQ *x509_req = X509_REQ_new();
|
||||
ret = X509_REQ_set_version(x509_req, nVersion);
|
||||
|
@ -219,16 +223,14 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::createCertRequest()
|
|||
// 3. set subject of x509 req
|
||||
X509_NAME *x509_name = X509_REQ_get_subject_name(x509_req);
|
||||
|
||||
X509_NAME_add_entry_by_txt(x509_name, "C", MBSTRING_ASC,
|
||||
(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, "C", MBSTRING_ASC, (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, "CN", MBSTRING_ASC,
|
||||
reinterpret_cast<unsigned char const *>(clientIdUtf8.data()), clientIdUtf8.size(), -1, 0);
|
||||
|
||||
// 4. set public key of x509 req
|
||||
ret = X509_REQ_set_pubkey(x509_req, pKey);
|
||||
if (ret != 1){
|
||||
if (ret != 1) {
|
||||
qWarning() << "Could not set pubkey!";
|
||||
X509_REQ_free(x509_req);
|
||||
EVP_PKEY_free(pKey);
|
||||
|
@ -236,8 +238,8 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::createCertRequest()
|
|||
}
|
||||
|
||||
// 5. set sign key of x509 req
|
||||
ret = X509_REQ_sign(x509_req, pKey, EVP_sha256()); // return x509_req->signature->length
|
||||
if (ret <= 0){
|
||||
ret = X509_REQ_sign(x509_req, pKey, EVP_sha256()); // return x509_req->signature->length
|
||||
if (ret <= 0) {
|
||||
qWarning() << "Could not sign request!";
|
||||
X509_REQ_free(x509_req);
|
||||
EVP_PKEY_free(pKey);
|
||||
|
@ -245,10 +247,9 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::createCertRequest()
|
|||
}
|
||||
|
||||
// save private key
|
||||
BIO * bp_private = BIO_new(BIO_s_mem());
|
||||
BIO *bp_private = BIO_new(BIO_s_mem());
|
||||
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");
|
||||
EVP_PKEY_free(pKey);
|
||||
BIO_free_all(bp_private);
|
||||
|
@ -256,7 +257,7 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::createCertRequest()
|
|||
return connData;
|
||||
}
|
||||
|
||||
const char * buffer = nullptr;
|
||||
const char *buffer = nullptr;
|
||||
size_t size = BIO_get_mem_data(bp_private, &buffer);
|
||||
q_check_ptr(buffer);
|
||||
connData.privKey = QByteArray(buffer, size);
|
||||
|
@ -270,7 +271,7 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::createCertRequest()
|
|||
BIO_free_all(bp_private);
|
||||
|
||||
// save req
|
||||
BIO * bio_req = BIO_new(BIO_s_mem());
|
||||
BIO *bio_req = BIO_new(BIO_s_mem());
|
||||
PEM_write_bio_X509_REQ(bio_req, x509_req);
|
||||
|
||||
BUF_MEM *bio_buf;
|
||||
|
@ -278,7 +279,6 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::createCertRequest()
|
|||
connData.request = QByteArray(bio_buf->data, bio_buf->length);
|
||||
BIO_free(bio_req);
|
||||
|
||||
|
||||
EVP_PKEY_free(pKey); // this will also free the rsa key
|
||||
|
||||
return connData;
|
||||
|
|
|
@ -1,24 +1,25 @@
|
|||
#include "ssh_configurator.h"
|
||||
#include <QApplication>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QObject>
|
||||
#include <QProcess>
|
||||
#include <QString>
|
||||
#include <QTemporaryDir>
|
||||
#include <QDebug>
|
||||
#include <QTemporaryFile>
|
||||
#include <QThread>
|
||||
#include <QObject>
|
||||
#include <QTextEdit>
|
||||
#include <QPlainTextEdit>
|
||||
#include <qtimer.h>
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
||||
#include <QGuiApplication>
|
||||
#else
|
||||
#include <QApplication>
|
||||
#endif
|
||||
|
||||
#include "core/server_defs.h"
|
||||
#include "utilities.h"
|
||||
|
||||
|
||||
SshConfigurator::SshConfigurator(std::shared_ptr<Settings> settings, QObject *parent):
|
||||
ConfiguratorBase(settings, parent)
|
||||
SshConfigurator::SshConfigurator(std::shared_ptr<Settings> settings, QObject *parent)
|
||||
: ConfiguratorBase(settings, parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QString SshConfigurator::convertOpenSShKey(const QString &key)
|
||||
|
@ -28,23 +29,30 @@ QString SshConfigurator::convertOpenSShKey(const QString &key)
|
|||
p.setProcessChannelMode(QProcess::MergedChannels);
|
||||
|
||||
QTemporaryFile tmp;
|
||||
#ifdef QT_DEBUG
|
||||
#ifdef QT_DEBUG
|
||||
tmp.setAutoRemove(false);
|
||||
#endif
|
||||
#endif
|
||||
tmp.open();
|
||||
tmp.write(key.toUtf8());
|
||||
tmp.close();
|
||||
|
||||
// ssh-keygen -p -P "" -N "" -m pem -f id_ssh
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#ifdef Q_OS_WIN
|
||||
p.setProcessEnvironment(prepareEnv());
|
||||
p.setProgram("cmd.exe");
|
||||
p.setNativeArguments(QString("/C \"ssh-keygen.exe -p -P \"\" -N \"\" -m pem -f \"%1\"\"").arg(tmp.fileName()));
|
||||
#else
|
||||
#else
|
||||
p.setProgram("ssh-keygen");
|
||||
p.setArguments(QStringList() << "-p" << "-P" << "" << "-N" << "" << "-m" << "pem" << "-f" << tmp.fileName());
|
||||
#endif
|
||||
p.setArguments(QStringList() << "-p"
|
||||
<< "-P"
|
||||
<< ""
|
||||
<< "-N"
|
||||
<< ""
|
||||
<< "-m"
|
||||
<< "pem"
|
||||
<< "-f" << tmp.fileName());
|
||||
#endif
|
||||
|
||||
p.start();
|
||||
p.waitForFinished();
|
||||
|
@ -65,22 +73,21 @@ void SshConfigurator::openSshTerminal(const ServerCredentials &credentials)
|
|||
QProcess *p = new QProcess();
|
||||
p->setProcessChannelMode(QProcess::SeparateChannels);
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#ifdef Q_OS_WIN
|
||||
p->setProcessEnvironment(prepareEnv());
|
||||
p->setProgram(qApp->applicationDirPath() + "\\cygwin\\putty.exe");
|
||||
|
||||
if (credentials.secretData.contains("PRIVATE KEY")) {
|
||||
// todo: connect by key
|
||||
// p->setNativeArguments(QString("%1@%2")
|
||||
// .arg(credentials.userName).arg(credentials.hostName).arg(credentials.secretData));
|
||||
// p->setNativeArguments(QString("%1@%2")
|
||||
// .arg(credentials.userName).arg(credentials.hostName).arg(credentials.secretData));
|
||||
} else {
|
||||
p->setNativeArguments(
|
||||
QString("%1@%2 -pw %3").arg(credentials.userName).arg(credentials.hostName).arg(credentials.secretData));
|
||||
}
|
||||
else {
|
||||
p->setNativeArguments(QString("%1@%2 -pw %3")
|
||||
.arg(credentials.userName).arg(credentials.hostName).arg(credentials.secretData));
|
||||
}
|
||||
#else
|
||||
#else
|
||||
p->setProgram("/bin/bash");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
p->startDetached();
|
||||
#endif
|
||||
|
@ -95,11 +102,11 @@ QProcessEnvironment SshConfigurator::prepareEnv()
|
|||
pathEnvVar.clear();
|
||||
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "\\cygwin;");
|
||||
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "\\openvpn;");
|
||||
#else
|
||||
#elif defined(Q_OS_MACX)
|
||||
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "/Contents/MacOS");
|
||||
#endif
|
||||
|
||||
env.insert("PATH", pathEnvVar);
|
||||
//qDebug().noquote() << "ENV PATH" << pathEnvVar;
|
||||
// qDebug().noquote() << "ENV PATH" << pathEnvVar;
|
||||
return env;
|
||||
}
|
||||
|
|
|
@ -1,30 +1,27 @@
|
|||
#include "wireguard_configurator.h"
|
||||
#include <QApplication>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QJsonDocument>
|
||||
#include <QProcess>
|
||||
#include <QString>
|
||||
#include <QTemporaryDir>
|
||||
#include <QDebug>
|
||||
#include <QTemporaryFile>
|
||||
#include <QJsonDocument>
|
||||
|
||||
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/pem.h>
|
||||
|
||||
|
||||
#include "containers/containers_defs.h"
|
||||
#include "core/server_defs.h"
|
||||
#include "core/scripts_registry.h"
|
||||
#include "utilities.h"
|
||||
#include "core/server_defs.h"
|
||||
#include "core/servercontroller.h"
|
||||
#include "settings.h"
|
||||
#include "utilities.h"
|
||||
|
||||
WireguardConfigurator::WireguardConfigurator(std::shared_ptr<Settings> settings, QObject *parent):
|
||||
ConfiguratorBase(settings, parent)
|
||||
WireguardConfigurator::WireguardConfigurator(std::shared_ptr<Settings> settings, QObject *parent)
|
||||
: ConfiguratorBase(settings, parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
WireguardConfigurator::ConnectionData WireguardConfigurator::genClientKeys()
|
||||
|
@ -36,37 +33,40 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::genClientKeys()
|
|||
|
||||
unsigned char 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);
|
||||
pKey = EVP_PKEY_new_raw_private_key(EVP_PKEY_X25519, NULL, &buff[0], EDDSA_KEY_LENGTH);
|
||||
|
||||
|
||||
size_t keySize = EDDSA_KEY_LENGTH;
|
||||
|
||||
// save private key
|
||||
unsigned char priv[EDDSA_KEY_LENGTH];
|
||||
EVP_PKEY_get_raw_private_key(pKey, priv, &keySize);
|
||||
connData.clientPrivKey = QByteArray::fromRawData((char*)priv, keySize).toBase64();
|
||||
connData.clientPrivKey = QByteArray::fromRawData((char *)priv, keySize).toBase64();
|
||||
|
||||
// save public key
|
||||
unsigned char pub[EDDSA_KEY_LENGTH];
|
||||
EVP_PKEY_get_raw_public_key(pKey, pub, &keySize);
|
||||
connData.clientPubKey = QByteArray::fromRawData((char*)pub, keySize).toBase64();
|
||||
connData.clientPubKey = QByteArray::fromRawData((char *)pub, keySize).toBase64();
|
||||
|
||||
return connData;
|
||||
}
|
||||
|
||||
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();
|
||||
connData.host = credentials.hostName;
|
||||
connData.port = containerConfig.value(config_key::port).toString(protocols::wireguard::defaultPort);
|
||||
|
||||
if (connData.clientPrivKey.isEmpty() || connData.clientPubKey.isEmpty()) {
|
||||
if (errorCode) *errorCode = ErrorCode::InternalError;
|
||||
if (errorCode)
|
||||
*errorCode = ErrorCode::InternalError;
|
||||
return connData;
|
||||
}
|
||||
|
||||
|
@ -96,22 +96,24 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
|
|||
// Calc next IP address
|
||||
if (ips.isEmpty()) {
|
||||
nextIpNumber = "2";
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
int next = ips.last().split(".").last().toInt() + 1;
|
||||
if (next > 254) {
|
||||
if (errorCode) *errorCode = ErrorCode::AddressPoolError;
|
||||
if (errorCode)
|
||||
*errorCode = ErrorCode::AddressPoolError;
|
||||
return connData;
|
||||
}
|
||||
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);
|
||||
if (l.isEmpty()) {
|
||||
if (errorCode) *errorCode = ErrorCode::AddressPoolError;
|
||||
if (errorCode)
|
||||
*errorCode = ErrorCode::AddressPoolError;
|
||||
return connData;
|
||||
}
|
||||
l.removeLast();
|
||||
|
@ -121,52 +123,60 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
|
|||
}
|
||||
|
||||
// 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", "");
|
||||
if (e) {
|
||||
if (errorCode) *errorCode = e;
|
||||
if (errorCode)
|
||||
*errorCode = e;
|
||||
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", "");
|
||||
|
||||
if (e) {
|
||||
if (errorCode) *errorCode = e;
|
||||
if (errorCode)
|
||||
*errorCode = e;
|
||||
return connData;
|
||||
}
|
||||
|
||||
// Add client to config
|
||||
QString configPart = QString(
|
||||
"[Peer]\n"
|
||||
"PublicKey = %1\n"
|
||||
"PresharedKey = %2\n"
|
||||
"AllowedIPs = %3/32\n\n").
|
||||
arg(connData.clientPubKey).
|
||||
arg(connData.pskKey).
|
||||
arg(connData.clientIP);
|
||||
QString configPart = QString("[Peer]\n"
|
||||
"PublicKey = %1\n"
|
||||
"PresharedKey = %2\n"
|
||||
"AllowedIPs = %3/32\n\n")
|
||||
.arg(connData.clientPubKey)
|
||||
.arg(connData.pskKey)
|
||||
.arg(connData.clientIP);
|
||||
|
||||
e = serverController.uploadTextFileToContainer(container, credentials, configPart,
|
||||
protocols::wireguard::serverConfigPath, libssh::SftpOverwriteMode::SftpAppendToExisting);
|
||||
protocols::wireguard::serverConfigPath,
|
||||
libssh::SftpOverwriteMode::SftpAppendToExisting);
|
||||
|
||||
if (e) {
|
||||
if (errorCode) *errorCode = e;
|
||||
if (errorCode)
|
||||
*errorCode = e;
|
||||
return connData;
|
||||
}
|
||||
|
||||
e = serverController.runScript(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)));
|
||||
e = serverController.runScript(
|
||||
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)));
|
||||
|
||||
return connData;
|
||||
}
|
||||
|
||||
QString WireguardConfigurator::genWireguardConfig(const ServerCredentials &credentials,
|
||||
DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode)
|
||||
QString WireguardConfigurator::genWireguardConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||
const QJsonObject &containerConfig, ErrorCode *errorCode)
|
||||
{
|
||||
ServerController serverController(m_settings);
|
||||
QString config = serverController.replaceVars(amnezia::scriptData(ProtocolScriptType::wireguard_template, container),
|
||||
serverController.genVarsForScript(credentials, container, containerConfig));
|
||||
QString config =
|
||||
serverController.replaceVars(amnezia::scriptData(ProtocolScriptType::wireguard_template, container),
|
||||
serverController.genVarsForScript(credentials, container, containerConfig));
|
||||
|
||||
ConnectionData connData = prepareWireguardConfig(credentials, container, containerConfig, errorCode);
|
||||
if (errorCode && *errorCode) {
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
#include "fileUtilites.h"
|
||||
#include "platforms/ios/MobileUtils.h"
|
||||
|
||||
#include <QDesktopServices>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QStandardPaths>
|
||||
|
||||
#ifdef Q_OS_ANDROID
|
||||
|
|
|
@ -4,23 +4,25 @@
|
|||
|
||||
#include "androidutils.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QGuiApplication>
|
||||
#include <QJniEnvironment>
|
||||
#include <QJniObject>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QNetworkCookieJar>
|
||||
#include <QUrlQuery>
|
||||
#include <QTimer>
|
||||
#include <QUrlQuery>
|
||||
|
||||
#include "jni.h"
|
||||
|
||||
namespace {
|
||||
AndroidUtils* s_instance = nullptr;
|
||||
} // namespace
|
||||
namespace
|
||||
{
|
||||
AndroidUtils *s_instance = nullptr;
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
QString AndroidUtils::GetDeviceName() {
|
||||
QString AndroidUtils::GetDeviceName()
|
||||
{
|
||||
QJniEnvironment env;
|
||||
jclass BUILD = env->FindClass("android/os/Build");
|
||||
jfieldID model = env->GetStaticFieldID(BUILD, "MODEL", "Ljava/lang/String;");
|
||||
|
@ -30,7 +32,7 @@ QString AndroidUtils::GetDeviceName() {
|
|||
return QString("Android Device");
|
||||
}
|
||||
|
||||
const char* buffer = env->GetStringUTFChars(value, nullptr);
|
||||
const char *buffer = env->GetStringUTFChars(value, nullptr);
|
||||
if (!buffer) {
|
||||
return QString("Android Device");
|
||||
}
|
||||
|
@ -42,7 +44,8 @@ QString AndroidUtils::GetDeviceName() {
|
|||
};
|
||||
|
||||
// static
|
||||
AndroidUtils* AndroidUtils::instance() {
|
||||
AndroidUtils *AndroidUtils::instance()
|
||||
{
|
||||
if (!s_instance) {
|
||||
Q_ASSERT(qApp);
|
||||
s_instance = new AndroidUtils(qApp);
|
||||
|
@ -51,19 +54,22 @@ AndroidUtils* AndroidUtils::instance() {
|
|||
return s_instance;
|
||||
}
|
||||
|
||||
AndroidUtils::AndroidUtils(QObject* parent) : QObject(parent) {
|
||||
AndroidUtils::AndroidUtils(QObject *parent) : QObject(parent)
|
||||
{
|
||||
Q_ASSERT(!s_instance);
|
||||
s_instance = this;
|
||||
}
|
||||
|
||||
AndroidUtils::~AndroidUtils() {
|
||||
AndroidUtils::~AndroidUtils()
|
||||
{
|
||||
Q_ASSERT(s_instance == this);
|
||||
s_instance = nullptr;
|
||||
}
|
||||
|
||||
// static
|
||||
void AndroidUtils::dispatchToMainThread(std::function<void()> callback) {
|
||||
QTimer* timer = new QTimer();
|
||||
void AndroidUtils::dispatchToMainThread(std::function<void()> callback)
|
||||
{
|
||||
QTimer *timer = new QTimer();
|
||||
timer->moveToThread(qApp->thread());
|
||||
timer->setSingleShot(true);
|
||||
QObject::connect(timer, &QTimer::timeout, [=]() {
|
||||
|
@ -74,8 +80,9 @@ void AndroidUtils::dispatchToMainThread(std::function<void()> callback) {
|
|||
}
|
||||
|
||||
// static
|
||||
QByteArray AndroidUtils::getQByteArrayFromJString(JNIEnv* env, jstring data) {
|
||||
const char* buffer = env->GetStringUTFChars(data, nullptr);
|
||||
QByteArray AndroidUtils::getQByteArrayFromJString(JNIEnv *env, jstring data)
|
||||
{
|
||||
const char *buffer = env->GetStringUTFChars(data, nullptr);
|
||||
if (!buffer) {
|
||||
qDebug() << "getQByteArrayFromJString - failed to parse data.";
|
||||
return QByteArray();
|
||||
|
@ -87,8 +94,9 @@ QByteArray AndroidUtils::getQByteArrayFromJString(JNIEnv* env, jstring data) {
|
|||
}
|
||||
|
||||
// static
|
||||
QString AndroidUtils::getQStringFromJString(JNIEnv* env, jstring data) {
|
||||
const char* buffer = env->GetStringUTFChars(data, nullptr);
|
||||
QString AndroidUtils::getQStringFromJString(JNIEnv *env, jstring data)
|
||||
{
|
||||
const char *buffer = env->GetStringUTFChars(data, nullptr);
|
||||
if (!buffer) {
|
||||
qDebug() << "getQStringFromJString - failed to parse data.";
|
||||
return QString();
|
||||
|
@ -100,15 +108,14 @@ QString AndroidUtils::getQStringFromJString(JNIEnv* env, jstring data) {
|
|||
}
|
||||
|
||||
// static
|
||||
QJsonObject AndroidUtils::getQJsonObjectFromJString(JNIEnv* env, jstring data) {
|
||||
QJsonObject AndroidUtils::getQJsonObjectFromJString(JNIEnv *env, jstring data)
|
||||
{
|
||||
QByteArray raw(getQByteArrayFromJString(env, data));
|
||||
QJsonParseError jsonError;
|
||||
QJsonDocument json = QJsonDocument::fromJson(raw, &jsonError);
|
||||
if (QJsonParseError::NoError != jsonError.error) {
|
||||
qDebug() << "getQJsonObjectFromJstring - error parsing json. Code: "
|
||||
<< jsonError.error << "Offset: " << jsonError.offset
|
||||
<< "Message: " << jsonError.errorString()
|
||||
<< "Data: " << raw;
|
||||
qDebug() << "getQJsonObjectFromJstring - error parsing json. Code: " << jsonError.error
|
||||
<< "Offset: " << jsonError.offset << "Message: " << jsonError.errorString() << "Data: " << raw;
|
||||
return QJsonObject();
|
||||
}
|
||||
|
||||
|
@ -120,11 +127,13 @@ QJsonObject AndroidUtils::getQJsonObjectFromJString(JNIEnv* env, jstring data) {
|
|||
return json.object();
|
||||
}
|
||||
|
||||
QJniObject AndroidUtils::getActivity() {
|
||||
QJniObject AndroidUtils::getActivity()
|
||||
{
|
||||
return QNativeInterface::QAndroidApplication::context();
|
||||
}
|
||||
|
||||
int AndroidUtils::GetSDKVersion() {
|
||||
int AndroidUtils::GetSDKVersion()
|
||||
{
|
||||
QJniEnvironment env;
|
||||
jclass versionClass = env->FindClass("android/os/Build$VERSION");
|
||||
jfieldID sdkIntFieldID = env->GetStaticFieldID(versionClass, "SDK_INT", "I");
|
||||
|
@ -133,15 +142,14 @@ int AndroidUtils::GetSDKVersion() {
|
|||
return sdk;
|
||||
}
|
||||
|
||||
QString AndroidUtils::GetManufacturer() {
|
||||
QString AndroidUtils::GetManufacturer()
|
||||
{
|
||||
QJniEnvironment env;
|
||||
jclass buildClass = env->FindClass("android/os/Build");
|
||||
jfieldID manuFacturerField =
|
||||
env->GetStaticFieldID(buildClass, "MANUFACTURER", "Ljava/lang/String;");
|
||||
jstring value =
|
||||
(jstring)env->GetStaticObjectField(buildClass, manuFacturerField);
|
||||
jfieldID manuFacturerField = env->GetStaticFieldID(buildClass, "MANUFACTURER", "Ljava/lang/String;");
|
||||
jstring value = (jstring)env->GetStaticObjectField(buildClass, manuFacturerField);
|
||||
|
||||
const char* buffer = env->GetStringUTFChars(value, nullptr);
|
||||
const char *buffer = env->GetStringUTFChars(value, nullptr);
|
||||
|
||||
if (!buffer) {
|
||||
qDebug() << "Failed to fetch MANUFACTURER";
|
||||
|
@ -154,21 +162,22 @@ QString AndroidUtils::GetManufacturer() {
|
|||
return res;
|
||||
}
|
||||
|
||||
void AndroidUtils::runOnAndroidThreadSync(const std::function<void()> runnable) {
|
||||
QNativeInterface::QAndroidApplication::runOnAndroidMainThread(runnable)
|
||||
.waitForFinished();
|
||||
void AndroidUtils::runOnAndroidThreadSync(const std::function<void()> runnable)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
// Static
|
||||
// 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;
|
||||
jbyteArray out = env->NewByteArray(data.size());
|
||||
env->SetByteArrayRegion(out, 0, data.size(),
|
||||
reinterpret_cast<const jbyte*>(data.constData()));
|
||||
env->SetByteArrayRegion(out, 0, data.size(), reinterpret_cast<const jbyte *>(data.constData()));
|
||||
return out;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
#include "androidvpnactivity.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QJniEnvironment>
|
||||
#include <QJniObject>
|
||||
#include <QJsonDocument>
|
||||
|
@ -13,19 +12,21 @@
|
|||
#include "androidutils.h"
|
||||
#include "jni.h"
|
||||
|
||||
namespace {
|
||||
AndroidVPNActivity* s_instance = nullptr;
|
||||
namespace
|
||||
{
|
||||
AndroidVPNActivity *s_instance = nullptr;
|
||||
constexpr auto CLASSNAME = "org.amnezia.vpn.qt.VPNActivity";
|
||||
}
|
||||
|
||||
AndroidVPNActivity::AndroidVPNActivity() {
|
||||
AndroidVPNActivity::AndroidVPNActivity()
|
||||
{
|
||||
AndroidUtils::runOnAndroidThreadAsync([]() {
|
||||
JNINativeMethod methods[]{
|
||||
{"handleBackButton", "()Z", reinterpret_cast<bool*>(handleBackButton)},
|
||||
{"onServiceMessage", "(ILjava/lang/String;)V", reinterpret_cast<void*>(onServiceMessage)},
|
||||
{"qtOnServiceConnected", "()V", reinterpret_cast<void*>(onServiceConnected)},
|
||||
{"qtOnServiceDisconnected", "()V", reinterpret_cast<void*>(onServiceDisconnected)},
|
||||
{"onActivityMessage", "(ILjava/lang/String;)V", reinterpret_cast<void*>(onAndroidVpnActivityMessage)}
|
||||
JNINativeMethod methods[] {
|
||||
{ "handleBackButton", "()Z", reinterpret_cast<bool *>(handleBackButton) },
|
||||
{ "onServiceMessage", "(ILjava/lang/String;)V", reinterpret_cast<void *>(onServiceMessage) },
|
||||
{ "qtOnServiceConnected", "()V", reinterpret_cast<void *>(onServiceConnected) },
|
||||
{ "qtOnServiceDisconnected", "()V", reinterpret_cast<void *>(onServiceDisconnected) },
|
||||
{ "onActivityMessage", "(ILjava/lang/String;)V", reinterpret_cast<void *>(onAndroidVpnActivityMessage) }
|
||||
};
|
||||
|
||||
QJniObject javaClass(CLASSNAME);
|
||||
|
@ -36,19 +37,22 @@ AndroidVPNActivity::AndroidVPNActivity() {
|
|||
});
|
||||
}
|
||||
|
||||
void AndroidVPNActivity::maybeInit() {
|
||||
void AndroidVPNActivity::maybeInit()
|
||||
{
|
||||
if (s_instance == nullptr) {
|
||||
s_instance = new AndroidVPNActivity();
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
bool AndroidVPNActivity::handleBackButton(JNIEnv* env, jobject thiz) {
|
||||
bool AndroidVPNActivity::handleBackButton(JNIEnv *env, jobject thiz)
|
||||
{
|
||||
Q_UNUSED(env);
|
||||
Q_UNUSED(thiz);
|
||||
}
|
||||
|
||||
void AndroidVPNActivity::connectService() {
|
||||
void AndroidVPNActivity::connectService()
|
||||
{
|
||||
QJniObject::callStaticMethod<void>(CLASSNAME, "connectService", "()V");
|
||||
}
|
||||
|
||||
|
@ -57,16 +61,16 @@ void AndroidVPNActivity::startQrCodeReader()
|
|||
QJniObject::callStaticMethod<void>(CLASSNAME, "startQrCodeReader", "()V");
|
||||
}
|
||||
|
||||
void AndroidVPNActivity::saveFileAs(QString fileContent, QString suggestedFilename) {
|
||||
QJniObject::callStaticMethod<void>(
|
||||
CLASSNAME,
|
||||
"saveFileAs", "(Ljava/lang/String;Ljava/lang/String;)V",
|
||||
QJniObject::fromString(fileContent).object<jstring>(),
|
||||
QJniObject::fromString(suggestedFilename).object<jstring>());
|
||||
void AndroidVPNActivity::saveFileAs(QString fileContent, QString suggestedFilename)
|
||||
{
|
||||
QJniObject::callStaticMethod<void>(CLASSNAME, "saveFileAs", "(Ljava/lang/String;Ljava/lang/String;)V",
|
||||
QJniObject::fromString(fileContent).object<jstring>(),
|
||||
QJniObject::fromString(suggestedFilename).object<jstring>());
|
||||
}
|
||||
|
||||
// static
|
||||
AndroidVPNActivity* AndroidVPNActivity::instance() {
|
||||
AndroidVPNActivity *AndroidVPNActivity::instance()
|
||||
{
|
||||
if (s_instance == nullptr) {
|
||||
AndroidVPNActivity::maybeInit();
|
||||
}
|
||||
|
@ -75,21 +79,19 @@ AndroidVPNActivity* AndroidVPNActivity::instance() {
|
|||
}
|
||||
|
||||
// static
|
||||
void AndroidVPNActivity::sendToService(ServiceAction type, const QString& data) {
|
||||
void AndroidVPNActivity::sendToService(ServiceAction type, const QString &data)
|
||||
{
|
||||
int messageType = (int)type;
|
||||
|
||||
QJniObject::callStaticMethod<void>(
|
||||
CLASSNAME,
|
||||
"sendToService", "(ILjava/lang/String;)V",
|
||||
static_cast<int>(messageType),
|
||||
QJniObject::fromString(data).object<jstring>());
|
||||
QJniObject::callStaticMethod<void>(CLASSNAME, "sendToService", "(ILjava/lang/String;)V",
|
||||
static_cast<int>(messageType), QJniObject::fromString(data).object<jstring>());
|
||||
}
|
||||
|
||||
// static
|
||||
void AndroidVPNActivity::onServiceMessage(JNIEnv* env, jobject thiz,
|
||||
jint messageType, jstring body) {
|
||||
void AndroidVPNActivity::onServiceMessage(JNIEnv *env, jobject thiz, jint messageType, jstring body)
|
||||
{
|
||||
Q_UNUSED(thiz);
|
||||
const char* buffer = env->GetStringUTFChars(body, nullptr);
|
||||
const char *buffer = env->GetStringUTFChars(body, nullptr);
|
||||
if (!buffer) {
|
||||
return;
|
||||
}
|
||||
|
@ -97,38 +99,23 @@ void AndroidVPNActivity::onServiceMessage(JNIEnv* env, jobject thiz,
|
|||
QString parcelBody(buffer);
|
||||
env->ReleaseStringUTFChars(body, buffer);
|
||||
AndroidUtils::dispatchToMainThread([messageType, parcelBody] {
|
||||
AndroidVPNActivity::instance()->handleServiceMessage(messageType,
|
||||
parcelBody);
|
||||
AndroidVPNActivity::instance()->handleServiceMessage(messageType, parcelBody);
|
||||
});
|
||||
}
|
||||
|
||||
void AndroidVPNActivity::handleServiceMessage(int code, const QString& data) {
|
||||
void AndroidVPNActivity::handleServiceMessage(int code, const QString &data)
|
||||
{
|
||||
auto mode = (ServiceEvents)code;
|
||||
|
||||
switch (mode) {
|
||||
case ServiceEvents::EVENT_INIT:
|
||||
emit eventInitialized(data);
|
||||
break;
|
||||
case ServiceEvents::EVENT_CONNECTED:
|
||||
emit eventConnected(data);
|
||||
break;
|
||||
case ServiceEvents::EVENT_DISCONNECTED:
|
||||
emit eventDisconnected(data);
|
||||
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);
|
||||
case ServiceEvents::EVENT_INIT: emit eventInitialized(data); break;
|
||||
case ServiceEvents::EVENT_CONNECTED: emit eventConnected(data); break;
|
||||
case ServiceEvents::EVENT_DISCONNECTED: emit eventDisconnected(data); 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;
|
||||
|
||||
switch (mode) {
|
||||
case UIEvents::QR_CODED_DECODED:
|
||||
emit eventQrCodeReceived(data);
|
||||
break;
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
case UIEvents::QR_CODED_DECODED: emit eventQrCodeReceived(data); break;
|
||||
default: Q_ASSERT(false);
|
||||
}
|
||||
}
|
||||
|
||||
void AndroidVPNActivity::onServiceConnected(JNIEnv* env, jobject thiz) {
|
||||
void AndroidVPNActivity::onServiceConnected(JNIEnv *env, jobject thiz)
|
||||
{
|
||||
Q_UNUSED(env);
|
||||
Q_UNUSED(thiz);
|
||||
|
||||
emit AndroidVPNActivity::instance()->serviceConnected();
|
||||
}
|
||||
|
||||
void AndroidVPNActivity::onServiceDisconnected(JNIEnv* env, jobject thiz) {
|
||||
void AndroidVPNActivity::onServiceDisconnected(JNIEnv *env, jobject thiz)
|
||||
{
|
||||
Q_UNUSED(env);
|
||||
Q_UNUSED(thiz);
|
||||
|
||||
|
@ -162,7 +148,7 @@ void AndroidVPNActivity::onServiceDisconnected(JNIEnv* env, jobject thiz) {
|
|||
void AndroidVPNActivity::onAndroidVpnActivityMessage(JNIEnv *env, jobject thiz, jint messageType, jstring message)
|
||||
{
|
||||
Q_UNUSED(thiz);
|
||||
const char* buffer = env->GetStringUTFChars(message, nullptr);
|
||||
const char *buffer = env->GetStringUTFChars(message, nullptr);
|
||||
if (!buffer) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -56,75 +56,6 @@
|
|||
<file>server_scripts/wireguard/template.conf</file>
|
||||
<file>server_scripts/website_tor/configure_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/qmldir</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/settings_suggest_black_24dp.svg</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>ui/qml/Controls2/BasicButtonType.qml</file>
|
||||
<file>ui/qml/Controls2/TextFieldWithHeaderType.qml</file>
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#include "connectionController.h"
|
||||
|
||||
#include <QApplication>
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
||||
#include <QGuiApplication>
|
||||
#else
|
||||
#include <QApplication>
|
||||
#endif
|
||||
|
||||
#include "core/errorstrings.h"
|
||||
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
#include "pageController.h"
|
||||
|
||||
#include <QApplication>
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
||||
#include <QGuiApplication>
|
||||
#else
|
||||
#include <QApplication>
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_ANDROID
|
||||
#include "../../platforms/android/androidutils.h"
|
||||
#include <QJniObject>
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
|
||||
#include <QStandardPaths>
|
||||
|
||||
#ifdef Q_OS_IOS
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#endif
|
||||
|
||||
#include "fileUtilites.h"
|
||||
#include "logger.h"
|
||||
#include "ui/qautostart.h"
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
#include "sitesController.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <QHostInfo>
|
||||
#include <QStandardPaths>
|
||||
|
||||
#ifdef Q_OS_IOS
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#endif
|
||||
|
||||
#include "fileUtilites.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