removed old ui files

This commit is contained in:
vladimir.kuznetsov 2023-08-31 16:00:41 +05:00
parent 8cf8c3c122
commit 4baa003c0d
140 changed files with 285 additions and 12695 deletions

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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;
}

View file

@ -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;

View file

@ -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;
}

View file

@ -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) {

View file

@ -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

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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>

View 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"

View file

@ -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>

View file

@ -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"

View file

@ -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"

View file

@ -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);
}

View file

@ -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

View file

@ -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."));
}
}

View file

@ -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

View file

@ -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 &section : 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;
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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();
}
}
}

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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();
}

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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
}

View file

@ -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

View file

@ -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());
}

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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 + "&nbsp;\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);
}
}

View file

@ -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

View file

@ -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();
}

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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()
{
}

View file

@ -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

View file

@ -1,8 +0,0 @@
#include "PageProtocolLogicBase.h"
PageProtocolLogicBase::PageProtocolLogicBase(UiLogic *logic, QObject *parent):
PageLogicBase(logic, parent)
{
}

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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());
}

View file

@ -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

View file

@ -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
}
}

View file

@ -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
}
}

View file

@ -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
}

View file

@ -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
}

View file

@ -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
}
}

View file

@ -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
}

View file

@ -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()
}
}

View file

@ -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]
}
}
}

View file

@ -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
}
}

View file

@ -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
}
}

View file

@ -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
}

View file

@ -1,8 +0,0 @@
import QtQuick
import QtQuick.Controls
Image {
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottomMargin: 30
source: "qrc:/images/AmneziaVPN.png"
}

View file

@ -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()
}
}
}
}

View file

@ -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()
}
}
}
}
}
}

View file

@ -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()
}
}
}
}
}
}

View file

@ -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
}

View file

@ -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
}
}

View file

@ -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
}
}
}

View file

@ -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)
}
}

View file

@ -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
}

View file

@ -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()
}
}
}

View file

@ -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
}
}

View file

@ -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"
}
}

View file

@ -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
// }
}
}

View file

@ -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
}
}

View file

@ -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
}
}

View file

@ -1,6 +0,0 @@
FadeBehavior {
fadeProperty: "opacity"
fadeDuration: 200
outAnimation.duration: targetValue ? 0 : fadeDuration
inAnimation.duration: targetValue ? fadeDuration : 0
}

View file

@ -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
}

View file

@ -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()
}
}
}
}
}

View file

@ -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()
}
}
}
}
}

View file

@ -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
}
}
}
}
}

View file

@ -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()
}
}
}
}
}
}
}

View file

@ -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
}
}

View file

@ -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
}
}

View file

@ -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