added protocol settings pages and models for openvpn, cloak and shadowsocks
This commit is contained in:
parent
a97417fd38
commit
c13b9754eb
42 changed files with 2130 additions and 576 deletions
|
@ -129,8 +129,8 @@ file(GLOB_RECURSE PAGE_LOGIC_CPP CONFIGURE_DEPENDS ${CMAKE_CURRENT_LIST_DIR}/ui/
|
|||
file(GLOB CONFIGURATORS_H CONFIGURE_DEPENDS ${CMAKE_CURRENT_LIST_DIR}/configurators/*.h)
|
||||
file(GLOB CONFIGURATORS_CPP CONFIGURE_DEPENDS ${CMAKE_CURRENT_LIST_DIR}/configurators/*.cpp)
|
||||
|
||||
file(GLOB UI_MODELS_H CONFIGURE_DEPENDS ${CMAKE_CURRENT_LIST_DIR}/ui/models/*.h)
|
||||
file(GLOB UI_MODELS_CPP CONFIGURE_DEPENDS ${CMAKE_CURRENT_LIST_DIR}/ui/models/*.cpp)
|
||||
file(GLOB UI_MODELS_H CONFIGURE_DEPENDS ${CMAKE_CURRENT_LIST_DIR}/ui/models/*.h ${CMAKE_CURRENT_LIST_DIR}/ui/models/protocols/*.h)
|
||||
file(GLOB UI_MODELS_CPP CONFIGURE_DEPENDS ${CMAKE_CURRENT_LIST_DIR}/ui/models/*.cpp ${CMAKE_CURRENT_LIST_DIR}/ui/models/protocols/*.cpp)
|
||||
|
||||
file(GLOB UI_CONTROLLERS_H CONFIGURE_DEPENDS ${CMAKE_CURRENT_LIST_DIR}/ui/controllers/*.h)
|
||||
file(GLOB UI_CONTROLLERS_CPP CONFIGURE_DEPENDS ${CMAKE_CURRENT_LIST_DIR}/ui/controllers/*.cpp)
|
||||
|
|
|
@ -79,38 +79,12 @@ void AmneziaApplication::init()
|
|||
m_engine->rootContext()->setContextProperty("Debug", &Logger::Instance());
|
||||
|
||||
//
|
||||
m_containersModel.reset(new ContainersModel(m_settings, this));
|
||||
m_engine->rootContext()->setContextProperty("ContainersModel", m_containersModel.get());
|
||||
|
||||
m_serversModel.reset(new ServersModel(m_settings, this));
|
||||
m_engine->rootContext()->setContextProperty("ServersModel", m_serversModel.get());
|
||||
connect(m_serversModel.get(), &ServersModel::currentlyProcessedServerIndexChanged, m_containersModel.get(),
|
||||
&ContainersModel::setCurrentlyProcessedServerIndex);
|
||||
|
||||
m_languageModel.reset(new LanguageModel(m_settings, this));
|
||||
m_engine->rootContext()->setContextProperty("LanguageModel", m_languageModel.get());
|
||||
connect(m_languageModel.get(), &LanguageModel::updateTranslations, this, &AmneziaApplication::updateTranslator);
|
||||
|
||||
m_configurator = std::shared_ptr<VpnConfigurator>(new VpnConfigurator(m_settings, this));
|
||||
m_vpnConnection.reset(new VpnConnection(m_settings, m_configurator));
|
||||
|
||||
m_connectionController.reset(new ConnectionController(m_serversModel, m_containersModel, m_vpnConnection));
|
||||
m_engine->rootContext()->setContextProperty("ConnectionController", m_connectionController.get());
|
||||
|
||||
m_pageController.reset(new PageController(m_serversModel));
|
||||
m_engine->rootContext()->setContextProperty("PageController", m_pageController.get());
|
||||
|
||||
m_installController.reset(new InstallController(m_serversModel, m_containersModel, m_settings));
|
||||
m_engine->rootContext()->setContextProperty("InstallController", m_installController.get());
|
||||
|
||||
m_importController.reset(new ImportController(m_serversModel, m_containersModel, m_settings));
|
||||
m_engine->rootContext()->setContextProperty("ImportController", m_importController.get());
|
||||
|
||||
m_exportController.reset(new ExportController(m_serversModel, m_containersModel, m_settings, m_configurator));
|
||||
m_engine->rootContext()->setContextProperty("ExportController", m_exportController.get());
|
||||
|
||||
m_settingsController.reset(new SettingsController(m_serversModel, m_containersModel, m_settings));
|
||||
m_engine->rootContext()->setContextProperty("SettingsController", m_settingsController.get());
|
||||
initModels();
|
||||
initControllers();
|
||||
|
||||
//
|
||||
|
||||
|
@ -244,3 +218,59 @@ QQmlApplicationEngine *AmneziaApplication::qmlEngine() const
|
|||
{
|
||||
return m_engine;
|
||||
}
|
||||
|
||||
void AmneziaApplication::initModels()
|
||||
{
|
||||
m_containersModel.reset(new ContainersModel(m_settings, this));
|
||||
m_engine->rootContext()->setContextProperty("ContainersModel", m_containersModel.get());
|
||||
|
||||
m_serversModel.reset(new ServersModel(m_settings, this));
|
||||
m_engine->rootContext()->setContextProperty("ServersModel", m_serversModel.get());
|
||||
connect(m_serversModel.get(), &ServersModel::currentlyProcessedServerIndexChanged, m_containersModel.get(),
|
||||
&ContainersModel::setCurrentlyProcessedServerIndex);
|
||||
|
||||
m_languageModel.reset(new LanguageModel(m_settings, this));
|
||||
m_engine->rootContext()->setContextProperty("LanguageModel", m_languageModel.get());
|
||||
connect(m_languageModel.get(), &LanguageModel::updateTranslations, this, &AmneziaApplication::updateTranslator);
|
||||
|
||||
m_protocolsModel.reset(new ProtocolsModel(m_settings, this));
|
||||
m_engine->rootContext()->setContextProperty("ProtocolsModel", m_protocolsModel.get());
|
||||
|
||||
m_openVpnConfigModel.reset(new OpenVpnConfigModel(this));
|
||||
m_engine->rootContext()->setContextProperty("OpenVpnConfigModel", m_openVpnConfigModel.get());
|
||||
|
||||
m_shadowSocksConfigModel.reset(new ShadowSocksConfigModel(this));
|
||||
m_engine->rootContext()->setContextProperty("ShadowSocksConfigModel", m_shadowSocksConfigModel.get());
|
||||
|
||||
m_cloakConfigModel.reset(new CloakConfigModel(this));
|
||||
m_engine->rootContext()->setContextProperty("CloakConfigModel", m_cloakConfigModel.get());
|
||||
|
||||
m_wireguardConfigModel.reset(new WireGuardConfigModel(this));
|
||||
m_engine->rootContext()->setContextProperty("WireGuardConfigModel", m_wireguardConfigModel.get());
|
||||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
m_ikev2ConfigModel.reset(new Ikev2ConfigModel(this));
|
||||
m_engine->rootContext()->setContextProperty("Ikev2ConfigModel", m_ikev2ConfigModel.get());
|
||||
#endif
|
||||
}
|
||||
|
||||
void AmneziaApplication::initControllers()
|
||||
{
|
||||
m_connectionController.reset(new ConnectionController(m_serversModel, m_containersModel, m_vpnConnection));
|
||||
m_engine->rootContext()->setContextProperty("ConnectionController", m_connectionController.get());
|
||||
|
||||
m_pageController.reset(new PageController(m_serversModel));
|
||||
m_engine->rootContext()->setContextProperty("PageController", m_pageController.get());
|
||||
|
||||
m_installController.reset(new InstallController(m_serversModel, m_containersModel, m_settings));
|
||||
m_engine->rootContext()->setContextProperty("InstallController", m_installController.get());
|
||||
|
||||
m_importController.reset(new ImportController(m_serversModel, m_containersModel, m_settings));
|
||||
m_engine->rootContext()->setContextProperty("ImportController", m_importController.get());
|
||||
|
||||
m_exportController.reset(new ExportController(m_serversModel, m_containersModel, m_settings, m_configurator));
|
||||
m_engine->rootContext()->setContextProperty("ExportController", m_exportController.get());
|
||||
|
||||
m_settingsController.reset(new SettingsController(m_serversModel, m_containersModel, m_settings));
|
||||
m_engine->rootContext()->setContextProperty("SettingsController", m_settingsController.get());
|
||||
}
|
||||
|
|
|
@ -21,6 +21,14 @@
|
|||
#include "ui/controllers/settingsController.h"
|
||||
#include "ui/models/containers_model.h"
|
||||
#include "ui/models/languageModel.h"
|
||||
#include "ui/models/protocols/cloakConfigModel.h"
|
||||
#ifdef Q_OS_WINDOWS
|
||||
#include "ui/models/protocols/ikev2ConfigModel.h"
|
||||
#endif
|
||||
#include "ui/models/protocols/openvpnConfigModel.h"
|
||||
#include "ui/models/protocols/shadowsocksConfigModel.h"
|
||||
#include "ui/models/protocols/wireguardConfigModel.h"
|
||||
#include "ui/models/protocols_model.h"
|
||||
#include "ui/models/servers_model.h"
|
||||
|
||||
#define amnApp (static_cast<AmneziaApplication *>(QCoreApplication::instance()))
|
||||
|
@ -56,6 +64,9 @@ public:
|
|||
QQmlApplicationEngine *qmlEngine() const;
|
||||
|
||||
private:
|
||||
void initModels();
|
||||
void initControllers();
|
||||
|
||||
QQmlApplicationEngine *m_engine {};
|
||||
std::shared_ptr<Settings> m_settings;
|
||||
std::shared_ptr<VpnConfigurator> m_configurator;
|
||||
|
@ -69,6 +80,15 @@ private:
|
|||
QSharedPointer<ContainersModel> m_containersModel;
|
||||
QSharedPointer<ServersModel> m_serversModel;
|
||||
QScopedPointer<LanguageModel> m_languageModel;
|
||||
QScopedPointer<ProtocolsModel> m_protocolsModel;
|
||||
|
||||
QScopedPointer<OpenVpnConfigModel> m_openVpnConfigModel;
|
||||
QScopedPointer<ShadowSocksConfigModel> m_shadowSocksConfigModel;
|
||||
QScopedPointer<CloakConfigModel> m_cloakConfigModel;
|
||||
QScopedPointer<WireGuardConfigModel> m_wireguardConfigModel;
|
||||
#ifdef Q_OS_WINDOWS
|
||||
QScopedPointer<Ikev2ConfigModel> m_ikev2ConfigModel;
|
||||
#endif
|
||||
|
||||
QSharedPointer<VpnConnection> m_vpnConnection;
|
||||
|
||||
|
|
|
@ -1,229 +1,223 @@
|
|||
#ifndef PROTOCOLS_DEFS_H
|
||||
#define PROTOCOLS_DEFS_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QDebug>
|
||||
#include <QObject>
|
||||
#include <QQmlEngine>
|
||||
|
||||
namespace amnezia {
|
||||
namespace config_key {
|
||||
|
||||
// Json config strings
|
||||
constexpr char hostName[] = "hostName";
|
||||
constexpr char userName[] = "userName";
|
||||
constexpr char password[] = "password";
|
||||
constexpr char port[] = "port";
|
||||
constexpr char local_port[] = "local_port";
|
||||
|
||||
constexpr char dns1[] = "dns1";
|
||||
constexpr char dns2[] = "dns2";
|
||||
|
||||
|
||||
constexpr char description[] = "description";
|
||||
constexpr char cert[] = "cert";
|
||||
constexpr char config[] = "config";
|
||||
|
||||
|
||||
constexpr char containers[] = "containers";
|
||||
constexpr char container[] = "container";
|
||||
constexpr char defaultContainer[] = "defaultContainer";
|
||||
|
||||
constexpr char vpnproto[] = "protocol";
|
||||
constexpr char protocols[] = "protocols";
|
||||
|
||||
constexpr char remote[] = "remote";
|
||||
constexpr char transport_proto[] = "transport_proto";
|
||||
constexpr char cipher[] = "cipher";
|
||||
constexpr char hash[] = "hash";
|
||||
constexpr char ncp_disable[] = "ncp_disable";
|
||||
constexpr char tls_auth[] = "tls_auth";
|
||||
|
||||
constexpr char client_priv_key[] = "client_priv_key";
|
||||
constexpr char client_pub_key[] = "client_pub_key";
|
||||
constexpr char server_priv_key[] = "server_priv_key";
|
||||
constexpr char server_pub_key[] = "server_pub_key";
|
||||
constexpr char psk_key[] = "psk_key";
|
||||
|
||||
constexpr char client_ip[] = "client_ip"; // internal ip address
|
||||
|
||||
constexpr char site[] = "site";
|
||||
constexpr char block_outside_dns[] = "block_outside_dns";
|
||||
|
||||
constexpr char subnet_address[] = "subnet_address";
|
||||
constexpr char subnet_mask[] = "subnet_mask";
|
||||
constexpr char subnet_cidr[] = "subnet_cidr";
|
||||
|
||||
constexpr char additional_client_config[] = "additional_client_config";
|
||||
constexpr char additional_server_config[] = "additional_server_config";
|
||||
|
||||
// proto config keys
|
||||
constexpr char last_config[] = "last_config";
|
||||
|
||||
constexpr char isThirdPartyConfig[] = "isThirdPartyConfig";
|
||||
|
||||
constexpr char openvpn[] = "openvpn";
|
||||
constexpr char wireguard[] = "wireguard";
|
||||
|
||||
}
|
||||
|
||||
namespace protocols {
|
||||
|
||||
namespace dns {
|
||||
constexpr char amneziaDnsIp[] = "172.29.172.254";
|
||||
}
|
||||
|
||||
namespace openvpn {
|
||||
constexpr char defaultSubnetAddress[] = "10.8.0.0";
|
||||
constexpr char defaultSubnetMask[] = "255.255.255.0";
|
||||
constexpr char defaultSubnetCidr[] = "24";
|
||||
|
||||
constexpr char serverConfigPath[] = "/opt/amnezia/openvpn/server.conf";
|
||||
constexpr char caCertPath[] = "/opt/amnezia/openvpn/pki/ca.crt";
|
||||
constexpr char clientCertPath[] = "/opt/amnezia/openvpn/pki/issued";
|
||||
constexpr char taKeyPath[] = "/opt/amnezia/openvpn/ta.key";
|
||||
constexpr char clientsDirPath[] = "/opt/amnezia/openvpn/clients";
|
||||
constexpr char defaultPort[] = "1194";
|
||||
constexpr char defaultTransportProto[] = "udp";
|
||||
constexpr char defaultCipher[] = "AES-256-GCM";
|
||||
constexpr char defaultHash[] = "SHA512";
|
||||
constexpr bool defaultBlockOutsideDns = true;
|
||||
constexpr bool defaultNcpDisable = false;
|
||||
constexpr bool defaultTlsAuth = true;
|
||||
constexpr char ncpDisableString[] = "ncp-disable";
|
||||
constexpr char tlsAuthString[] = "tls-auth /opt/amnezia/openvpn/ta.key 0";
|
||||
|
||||
constexpr char defaultAdditionalClientConfig[] = "";
|
||||
constexpr char defaultAdditionalServerConfig[] = "";
|
||||
}
|
||||
|
||||
namespace shadowsocks {
|
||||
constexpr char ssKeyPath[] = "/opt/amnezia/shadowsocks/shadowsocks.key";
|
||||
constexpr char defaultPort[] = "6789";
|
||||
constexpr char defaultLocalProxyPort[] = "8585";
|
||||
constexpr char defaultCipher[] = "chacha20-ietf-poly1305";
|
||||
}
|
||||
|
||||
namespace cloak {
|
||||
constexpr char ckPublicKeyPath[] = "/opt/amnezia/cloak/cloak_public.key";
|
||||
constexpr char ckBypassUidKeyPath[] = "/opt/amnezia/cloak/cloak_bypass_uid.key";
|
||||
constexpr char ckAdminKeyPath[] = "/opt/amnezia/cloak/cloak_admin_uid.key";
|
||||
constexpr char defaultPort[] = "443";
|
||||
constexpr char defaultRedirSite[] = "tile.openstreetmap.org";
|
||||
constexpr char defaultCipher[] = "chacha20-poly1305";
|
||||
|
||||
}
|
||||
|
||||
namespace wireguard {
|
||||
constexpr char defaultSubnetAddress[] = "10.8.1.0";
|
||||
constexpr char defaultSubnetMask[] = "255.255.255.0";
|
||||
constexpr char defaultSubnetCidr[] = "24";
|
||||
|
||||
constexpr char defaultPort[] = "51820";
|
||||
constexpr char serverConfigPath[] = "/opt/amnezia/wireguard/wg0.conf";
|
||||
constexpr char serverPublicKeyPath[] = "/opt/amnezia/wireguard/wireguard_server_public_key.key";
|
||||
constexpr char serverPskKeyPath[] = "/opt/amnezia/wireguard/wireguard_psk.key";
|
||||
|
||||
}
|
||||
|
||||
namespace sftp {
|
||||
constexpr char defaultUserName[] = "sftp_user";
|
||||
|
||||
} // namespace sftp
|
||||
|
||||
} // namespace protocols
|
||||
|
||||
namespace ProtocolEnumNS {
|
||||
Q_NAMESPACE
|
||||
|
||||
enum TransportProto {
|
||||
Udp,
|
||||
Tcp
|
||||
};
|
||||
Q_ENUM_NS(TransportProto)
|
||||
|
||||
enum Proto {
|
||||
Any = 0,
|
||||
OpenVpn,
|
||||
ShadowSocks,
|
||||
Cloak,
|
||||
WireGuard,
|
||||
Ikev2,
|
||||
L2tp,
|
||||
|
||||
// non-vpn
|
||||
TorWebSite,
|
||||
Dns,
|
||||
FileShare,
|
||||
Sftp
|
||||
};
|
||||
Q_ENUM_NS(Proto)
|
||||
|
||||
enum ServiceType {
|
||||
None = 0,
|
||||
Vpn,
|
||||
Other
|
||||
};
|
||||
Q_ENUM_NS(ServiceType)
|
||||
} // namespace ProtocolEnumNS
|
||||
|
||||
using namespace ProtocolEnumNS;
|
||||
|
||||
class ProtocolProps : public QObject
|
||||
namespace amnezia
|
||||
{
|
||||
Q_OBJECT
|
||||
namespace config_key
|
||||
{
|
||||
|
||||
public:
|
||||
Q_INVOKABLE static QList<Proto> allProtocols();
|
||||
// Json config strings
|
||||
constexpr char hostName[] = "hostName";
|
||||
constexpr char userName[] = "userName";
|
||||
constexpr char password[] = "password";
|
||||
constexpr char port[] = "port";
|
||||
constexpr char local_port[] = "local_port";
|
||||
|
||||
// spelling may differ for various protocols - TCP for OpenVPN, tcp for others
|
||||
Q_INVOKABLE static TransportProto transportProtoFromString(QString p);
|
||||
Q_INVOKABLE static QString transportProtoToString(TransportProto proto, Proto p = Proto::Any);
|
||||
constexpr char dns1[] = "dns1";
|
||||
constexpr char dns2[] = "dns2";
|
||||
|
||||
Q_INVOKABLE static Proto protoFromString(QString p);
|
||||
Q_INVOKABLE static QString protoToString(Proto p);
|
||||
constexpr char description[] = "description";
|
||||
constexpr char cert[] = "cert";
|
||||
constexpr char config[] = "config";
|
||||
|
||||
Q_INVOKABLE static QMap<Proto, QString> protocolHumanNames();
|
||||
Q_INVOKABLE static QMap<Proto, QString> protocolDescriptions();
|
||||
constexpr char containers[] = "containers";
|
||||
constexpr char container[] = "container";
|
||||
constexpr char defaultContainer[] = "defaultContainer";
|
||||
|
||||
Q_INVOKABLE static ServiceType protocolService(Proto p);
|
||||
constexpr char vpnproto[] = "protocol";
|
||||
constexpr char protocols[] = "protocols";
|
||||
|
||||
Q_INVOKABLE static int defaultPort(Proto p);
|
||||
Q_INVOKABLE static bool defaultPortChangeable(Proto p);
|
||||
constexpr char remote[] = "remote";
|
||||
constexpr char transport_proto[] = "transport_proto";
|
||||
constexpr char cipher[] = "cipher";
|
||||
constexpr char hash[] = "hash";
|
||||
constexpr char ncp_disable[] = "ncp_disable";
|
||||
constexpr char tls_auth[] = "tls_auth";
|
||||
|
||||
Q_INVOKABLE static TransportProto defaultTransportProto(Proto p);
|
||||
Q_INVOKABLE static bool defaultTransportProtoChangeable(Proto p);
|
||||
constexpr char client_priv_key[] = "client_priv_key";
|
||||
constexpr char client_pub_key[] = "client_pub_key";
|
||||
constexpr char server_priv_key[] = "server_priv_key";
|
||||
constexpr char server_pub_key[] = "server_pub_key";
|
||||
constexpr char psk_key[] = "psk_key";
|
||||
|
||||
constexpr char client_ip[] = "client_ip"; // internal ip address
|
||||
|
||||
Q_INVOKABLE static QString key_proto_config_data(Proto p);
|
||||
Q_INVOKABLE static QString key_proto_config_path(Proto p);
|
||||
constexpr char site[] = "site";
|
||||
constexpr char block_outside_dns[] = "block_outside_dns";
|
||||
|
||||
};
|
||||
constexpr char subnet_address[] = "subnet_address";
|
||||
constexpr char subnet_mask[] = "subnet_mask";
|
||||
constexpr char subnet_cidr[] = "subnet_cidr";
|
||||
|
||||
static void declareQmlProtocolEnum() {
|
||||
qmlRegisterUncreatableMetaObject(
|
||||
ProtocolEnumNS::staticMetaObject,
|
||||
"ProtocolEnum",
|
||||
1, 0,
|
||||
"ProtocolEnum",
|
||||
"Error: only enums"
|
||||
);
|
||||
constexpr char additional_client_config[] = "additional_client_config";
|
||||
constexpr char additional_server_config[] = "additional_server_config";
|
||||
|
||||
qmlRegisterUncreatableMetaObject(
|
||||
ProtocolEnumNS::staticMetaObject,
|
||||
"ProtocolEnum",
|
||||
1, 0,
|
||||
"TransportProto",
|
||||
"Error: only enums"
|
||||
);
|
||||
// proto config keys
|
||||
constexpr char last_config[] = "last_config";
|
||||
|
||||
qmlRegisterUncreatableMetaObject(
|
||||
ProtocolEnumNS::staticMetaObject,
|
||||
"ProtocolEnum",
|
||||
1, 0,
|
||||
"ServiceType",
|
||||
"Error: only enums"
|
||||
);
|
||||
}
|
||||
constexpr char isThirdPartyConfig[] = "isThirdPartyConfig";
|
||||
|
||||
constexpr char openvpn[] = "openvpn";
|
||||
constexpr char wireguard[] = "wireguard";
|
||||
constexpr char shadowsocks[] = "shadowsocks";
|
||||
constexpr char cloak[] = "cloak";
|
||||
|
||||
}
|
||||
|
||||
namespace protocols
|
||||
{
|
||||
|
||||
namespace dns
|
||||
{
|
||||
constexpr char amneziaDnsIp[] = "172.29.172.254";
|
||||
}
|
||||
|
||||
namespace openvpn
|
||||
{
|
||||
constexpr char defaultSubnetAddress[] = "10.8.0.0";
|
||||
constexpr char defaultSubnetMask[] = "255.255.255.0";
|
||||
constexpr char defaultSubnetCidr[] = "24";
|
||||
|
||||
constexpr char serverConfigPath[] = "/opt/amnezia/openvpn/server.conf";
|
||||
constexpr char caCertPath[] = "/opt/amnezia/openvpn/pki/ca.crt";
|
||||
constexpr char clientCertPath[] = "/opt/amnezia/openvpn/pki/issued";
|
||||
constexpr char taKeyPath[] = "/opt/amnezia/openvpn/ta.key";
|
||||
constexpr char clientsDirPath[] = "/opt/amnezia/openvpn/clients";
|
||||
constexpr char defaultPort[] = "1194";
|
||||
constexpr char defaultTransportProto[] = "udp";
|
||||
constexpr char defaultCipher[] = "AES-256-GCM";
|
||||
constexpr char defaultHash[] = "SHA512";
|
||||
constexpr bool defaultBlockOutsideDns = true;
|
||||
constexpr bool defaultNcpDisable = false;
|
||||
constexpr bool defaultTlsAuth = true;
|
||||
constexpr char ncpDisableString[] = "ncp-disable";
|
||||
constexpr char tlsAuthString[] = "tls-auth /opt/amnezia/openvpn/ta.key 0";
|
||||
|
||||
constexpr char defaultAdditionalClientConfig[] = "";
|
||||
constexpr char defaultAdditionalServerConfig[] = "";
|
||||
}
|
||||
|
||||
namespace shadowsocks
|
||||
{
|
||||
constexpr char ssKeyPath[] = "/opt/amnezia/shadowsocks/shadowsocks.key";
|
||||
constexpr char defaultPort[] = "6789";
|
||||
constexpr char defaultLocalProxyPort[] = "8585";
|
||||
constexpr char defaultCipher[] = "chacha20-ietf-poly1305";
|
||||
}
|
||||
|
||||
namespace cloak
|
||||
{
|
||||
constexpr char ckPublicKeyPath[] = "/opt/amnezia/cloak/cloak_public.key";
|
||||
constexpr char ckBypassUidKeyPath[] = "/opt/amnezia/cloak/cloak_bypass_uid.key";
|
||||
constexpr char ckAdminKeyPath[] = "/opt/amnezia/cloak/cloak_admin_uid.key";
|
||||
constexpr char defaultPort[] = "443";
|
||||
constexpr char defaultRedirSite[] = "tile.openstreetmap.org";
|
||||
constexpr char defaultCipher[] = "chacha20-poly1305";
|
||||
|
||||
}
|
||||
|
||||
namespace wireguard
|
||||
{
|
||||
constexpr char defaultSubnetAddress[] = "10.8.1.0";
|
||||
constexpr char defaultSubnetMask[] = "255.255.255.0";
|
||||
constexpr char defaultSubnetCidr[] = "24";
|
||||
|
||||
constexpr char defaultPort[] = "51820";
|
||||
constexpr char serverConfigPath[] = "/opt/amnezia/wireguard/wg0.conf";
|
||||
constexpr char serverPublicKeyPath[] = "/opt/amnezia/wireguard/wireguard_server_public_key.key";
|
||||
constexpr char serverPskKeyPath[] = "/opt/amnezia/wireguard/wireguard_psk.key";
|
||||
|
||||
}
|
||||
|
||||
namespace sftp
|
||||
{
|
||||
constexpr char defaultUserName[] = "sftp_user";
|
||||
|
||||
} // namespace sftp
|
||||
|
||||
} // namespace protocols
|
||||
|
||||
namespace ProtocolEnumNS
|
||||
{
|
||||
Q_NAMESPACE
|
||||
|
||||
enum TransportProto {
|
||||
Udp,
|
||||
Tcp
|
||||
};
|
||||
Q_ENUM_NS(TransportProto)
|
||||
|
||||
enum Proto {
|
||||
Any = 0,
|
||||
OpenVpn,
|
||||
ShadowSocks,
|
||||
Cloak,
|
||||
WireGuard,
|
||||
Ikev2,
|
||||
L2tp,
|
||||
|
||||
// non-vpn
|
||||
TorWebSite,
|
||||
Dns,
|
||||
FileShare,
|
||||
Sftp
|
||||
};
|
||||
Q_ENUM_NS(Proto)
|
||||
|
||||
enum ServiceType {
|
||||
None = 0,
|
||||
Vpn,
|
||||
Other
|
||||
};
|
||||
Q_ENUM_NS(ServiceType)
|
||||
} // namespace ProtocolEnumNS
|
||||
|
||||
using namespace ProtocolEnumNS;
|
||||
|
||||
class ProtocolProps : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Q_INVOKABLE static QList<Proto> allProtocols();
|
||||
|
||||
// spelling may differ for various protocols - TCP for OpenVPN, tcp for others
|
||||
Q_INVOKABLE static TransportProto transportProtoFromString(QString p);
|
||||
Q_INVOKABLE static QString transportProtoToString(TransportProto proto, Proto p = Proto::Any);
|
||||
|
||||
Q_INVOKABLE static Proto protoFromString(QString p);
|
||||
Q_INVOKABLE static QString protoToString(Proto p);
|
||||
|
||||
Q_INVOKABLE static QMap<Proto, QString> protocolHumanNames();
|
||||
Q_INVOKABLE static QMap<Proto, QString> protocolDescriptions();
|
||||
|
||||
Q_INVOKABLE static ServiceType protocolService(Proto p);
|
||||
|
||||
Q_INVOKABLE static int defaultPort(Proto p);
|
||||
Q_INVOKABLE static bool defaultPortChangeable(Proto p);
|
||||
|
||||
Q_INVOKABLE static TransportProto defaultTransportProto(Proto p);
|
||||
Q_INVOKABLE static bool defaultTransportProtoChangeable(Proto p);
|
||||
|
||||
Q_INVOKABLE static QString key_proto_config_data(Proto p);
|
||||
Q_INVOKABLE static QString key_proto_config_path(Proto p);
|
||||
};
|
||||
|
||||
static void declareQmlProtocolEnum()
|
||||
{
|
||||
qmlRegisterUncreatableMetaObject(ProtocolEnumNS::staticMetaObject, "ProtocolEnum", 1, 0, "ProtocolEnum",
|
||||
"Error: only enums");
|
||||
|
||||
qmlRegisterUncreatableMetaObject(ProtocolEnumNS::staticMetaObject, "ProtocolEnum", 1, 0, "TransportProto",
|
||||
"Error: only enums");
|
||||
|
||||
qmlRegisterUncreatableMetaObject(ProtocolEnumNS::staticMetaObject, "ProtocolEnum", 1, 0, "ServiceType",
|
||||
"Error: only enums");
|
||||
}
|
||||
|
||||
} // namespace amnezia
|
||||
|
||||
|
|
|
@ -250,7 +250,6 @@
|
|||
<file>ui/qml/Pages2/PageDeinstalling.qml</file>
|
||||
<file>ui/qml/Controls2/BackButtonType.qml</file>
|
||||
<file>ui/qml/Pages2/PageSettingsServerProtocol.qml</file>
|
||||
<file>ui/qml/Components/Protocols/OpenVpnSettings.qml</file>
|
||||
<file>ui/qml/Components/TransportProtoSelector.qml</file>
|
||||
<file>ui/qml/Controls2/ListViewType.qml</file>
|
||||
<file>images/controls/radio-button.svg</file>
|
||||
|
@ -271,5 +270,8 @@
|
|||
<file>ui/qml/Filters/ContainersModelFilters.qml</file>
|
||||
<file>ui/qml/Components/SelectLanguageDrawer.qml</file>
|
||||
<file>ui/qml/Controls2/BusyIndicatorType.qml</file>
|
||||
<file>ui/qml/Pages2/PageProtocolOpenVpnSettings.qml</file>
|
||||
<file>ui/qml/Pages2/PageProtocolShadowSocksSettings.qml</file>
|
||||
<file>ui/qml/Pages2/PageProtocolCloakSettings.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
|
@ -69,7 +69,7 @@ void InstallController::installServer(DockerContainer container, QJsonObject &co
|
|||
m_serversModel->addServer(server);
|
||||
m_serversModel->setDefaultServerIndex(m_serversModel->getServersCount() - 1);
|
||||
|
||||
emit installServerFinished(isInstalledContainerFound);
|
||||
emit installServerFinished(false); // todo incorrect notification about found containers
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -108,7 +108,7 @@ void InstallController::installContainer(DockerContainer container, QJsonObject
|
|||
}
|
||||
}
|
||||
|
||||
emit installContainerFinished(isInstalledContainerFound);
|
||||
emit installContainerFinished(false); // todo incorrect notification about found containers
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -162,6 +162,29 @@ void InstallController::scanServerForInstalledContainers()
|
|||
emit installationErrorOccurred(errorString(errorCode));
|
||||
}
|
||||
|
||||
void InstallController::updateContainer(QJsonObject config)
|
||||
{
|
||||
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex();
|
||||
ServerCredentials serverCredentials =
|
||||
qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
|
||||
|
||||
const DockerContainer container = ContainerProps::containerFromString(config.value(config_key::container).toString());
|
||||
auto modelIndex = m_containersModel->index(container);
|
||||
QJsonObject oldContainerConfig =
|
||||
qvariant_cast<QJsonObject>(m_containersModel->data(modelIndex, ContainersModel::Roles::ConfigRole));
|
||||
|
||||
ServerController serverController(m_settings);
|
||||
|
||||
auto errorCode = serverController.updateContainer(serverCredentials, container, oldContainerConfig, config);
|
||||
if (errorCode == ErrorCode::NoError) {
|
||||
m_containersModel->setData(modelIndex, config, ContainersModel::Roles::ConfigRole);
|
||||
emit updateContainerFinished();
|
||||
return;
|
||||
}
|
||||
|
||||
emit installationErrorOccurred(errorString(errorCode));
|
||||
}
|
||||
|
||||
QRegularExpression InstallController::ipAddressPortRegExp()
|
||||
{
|
||||
return Utils::ipAddressPortRegExp();
|
||||
|
|
|
@ -24,12 +24,16 @@ public slots:
|
|||
|
||||
void scanServerForInstalledContainers();
|
||||
|
||||
void updateContainer(QJsonObject config);
|
||||
|
||||
QRegularExpression ipAddressPortRegExp();
|
||||
|
||||
signals:
|
||||
void installContainerFinished(bool isInstalledContainerFound);
|
||||
void installServerFinished(bool isInstalledContainerFound);
|
||||
|
||||
void updateContainerFinished();
|
||||
|
||||
void scanServerFinished(bool isInstalledContainerFound);
|
||||
|
||||
void installationErrorOccurred(QString errorMessage);
|
||||
|
|
|
@ -36,7 +36,13 @@ namespace PageLoader
|
|||
PageSetupWizardInstalling,
|
||||
PageSetupWizardConfigSource,
|
||||
PageSetupWizardTextKey,
|
||||
PageSetupWizardViewConfig
|
||||
PageSetupWizardViewConfig,
|
||||
|
||||
PageProtocolOpenVpnSettings,
|
||||
PageProtocolShadowSocksSettings,
|
||||
PageProtocolCloakSettings,
|
||||
PageProtocolWireGuardSettings,
|
||||
PageProtocolIKev2Settings
|
||||
};
|
||||
Q_ENUM_NS(PageEnum)
|
||||
|
||||
|
|
|
@ -29,6 +29,11 @@ bool ContainersModel::setData(const QModelIndex &index, const QVariant &value, i
|
|||
case ConfigRole: {
|
||||
m_settings->setContainerConfig(m_currentlyProcessedServerIndex, container, value.toJsonObject());
|
||||
m_containers = m_settings->containers(m_currentlyProcessedServerIndex);
|
||||
if (m_defaultContainerIndex != DockerContainer::None) {
|
||||
break;
|
||||
} else if (ContainerProps::containerService(container) == ServiceType::Other) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
case ServiceTypeRole:
|
||||
// return ContainerProps::containerService(container);
|
||||
|
@ -108,6 +113,11 @@ int ContainersModel::getCurrentlyProcessedContainerIndex()
|
|||
return m_currentlyProcessedContainerIndex;
|
||||
}
|
||||
|
||||
QString ContainersModel::getCurrentlyProcessedContainerName()
|
||||
{
|
||||
return ContainerProps::containerHumanNames().value(static_cast<DockerContainer>(m_currentlyProcessedContainerIndex));
|
||||
}
|
||||
|
||||
void ContainersModel::removeAllContainers()
|
||||
{
|
||||
|
||||
|
@ -116,14 +126,39 @@ void ContainersModel::removeAllContainers()
|
|||
|
||||
if (errorCode == ErrorCode::NoError) {
|
||||
beginResetModel();
|
||||
|
||||
m_settings->setContainers(m_currentlyProcessedServerIndex, {});
|
||||
m_settings->setDefaultContainer(m_currentlyProcessedServerIndex, DockerContainer::None);
|
||||
m_containers = m_settings->containers(m_currentlyProcessedServerIndex);
|
||||
|
||||
setData(index(DockerContainer::None, 0), true, IsDefaultRole);
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
// todo process errors
|
||||
}
|
||||
|
||||
void ContainersModel::removeCurrentlyProcessedContainer()
|
||||
{
|
||||
ServerController serverController(m_settings);
|
||||
auto credentials = m_settings->serverCredentials(m_currentlyProcessedServerIndex);
|
||||
auto dockerContainer = static_cast<DockerContainer>(m_currentlyProcessedContainerIndex);
|
||||
|
||||
ErrorCode e = serverController.removeContainer(credentials, dockerContainer);
|
||||
|
||||
beginResetModel(); // todo change to begin remove rows?
|
||||
m_settings->removeContainerConfig(m_currentlyProcessedServerIndex, dockerContainer);
|
||||
m_containers = m_settings->containers(m_currentlyProcessedServerIndex);
|
||||
|
||||
if (m_defaultContainerIndex == m_currentlyProcessedContainerIndex) {
|
||||
if (m_containers.isEmpty()) {
|
||||
setData(index(DockerContainer::None, 0), true, IsDefaultRole);
|
||||
} else {
|
||||
setData(index(m_containers.begin().key(), 0), true, IsDefaultRole);
|
||||
}
|
||||
}
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
void ContainersModel::clearCachedProfiles()
|
||||
{
|
||||
const auto &containers = m_settings->containers(m_currentlyProcessedServerIndex);
|
||||
|
@ -150,6 +185,7 @@ QHash<int, QByteArray> ContainersModel::roleNames() const
|
|||
roles[DescRole] = "description";
|
||||
roles[ServiceTypeRole] = "serviceType";
|
||||
roles[DockerContainerRole] = "dockerContainer";
|
||||
roles[ConfigRole] = "config";
|
||||
|
||||
roles[IsEasySetupContainerRole] = "isEasySetupContainer";
|
||||
roles[EasySetupHeaderRole] = "easySetupHeader";
|
||||
|
|
|
@ -45,10 +45,14 @@ public slots:
|
|||
QString getDefaultContainerName();
|
||||
|
||||
void setCurrentlyProcessedServerIndex(const int index);
|
||||
|
||||
void setCurrentlyProcessedContainerIndex(int index);
|
||||
int getCurrentlyProcessedContainerIndex();
|
||||
|
||||
QString getCurrentlyProcessedContainerName();
|
||||
|
||||
void removeAllContainers();
|
||||
void removeCurrentlyProcessedContainer();
|
||||
void clearCachedProfiles();
|
||||
|
||||
bool isAmneziaDnsContainerInstalled();
|
||||
|
|
|
@ -22,14 +22,8 @@ QVariant LanguageModel::data(const QModelIndex &index, int role) const
|
|||
}
|
||||
|
||||
switch (role) {
|
||||
case NameRole: {
|
||||
return m_availableLanguages[index.row()].name;
|
||||
break;
|
||||
}
|
||||
case IndexRole: {
|
||||
return static_cast<int>(m_availableLanguages[index.row()].index);
|
||||
break;
|
||||
}
|
||||
case NameRole: return m_availableLanguages[index.row()].name;
|
||||
case IndexRole: return static_cast<int>(m_availableLanguages[index.row()].index);
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
|
81
client/ui/models/protocols/cloakConfigModel.cpp
Normal file
81
client/ui/models/protocols/cloakConfigModel.cpp
Normal file
|
@ -0,0 +1,81 @@
|
|||
#include "cloakConfigModel.h"
|
||||
|
||||
#include "protocols/protocols_defs.h"
|
||||
|
||||
CloakConfigModel::CloakConfigModel(QObject *parent) : QAbstractListModel(parent)
|
||||
{
|
||||
}
|
||||
|
||||
int CloakConfigModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool CloakConfigModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
if (!index.isValid() || index.row() < 0 || index.row() >= ContainerProps::allContainers().size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (role) {
|
||||
case Roles::PortRole: m_protocolConfig.insert(config_key::port, value.toString()); break;
|
||||
case Roles::CipherRole: m_protocolConfig.insert(config_key::cipher, value.toString()); break;
|
||||
case Roles::SiteRole: m_protocolConfig.insert(config_key::site, value.toString()); break;
|
||||
}
|
||||
|
||||
emit dataChanged(index, index, QList { role });
|
||||
return true;
|
||||
}
|
||||
|
||||
QVariant CloakConfigModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid() || index.row() < 0 || index.row() >= rowCount()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (role) {
|
||||
case Roles::PortRole: return m_protocolConfig.value(config_key::port).toString(protocols::cloak::defaultPort);
|
||||
case Roles::CipherRole: return m_protocolConfig.value(config_key::cipher).toString(protocols::cloak::defaultCipher);
|
||||
case Roles::SiteRole: return m_protocolConfig.value(config_key::site).toString(protocols::cloak::defaultRedirSite);
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void CloakConfigModel::updateModel(const QJsonObject &config)
|
||||
{
|
||||
beginResetModel();
|
||||
m_container = ContainerProps::containerFromString(config.value(config_key::container).toString());
|
||||
|
||||
m_fullConfig = config;
|
||||
QJsonObject protocolConfig = config.value(config_key::cloak).toObject();
|
||||
|
||||
m_protocolConfig.insert(config_key::cipher,
|
||||
protocolConfig.value(config_key::cipher).toString(protocols::cloak::defaultCipher));
|
||||
|
||||
m_protocolConfig.insert(config_key::port,
|
||||
protocolConfig.value(config_key::port).toString(protocols::cloak::defaultPort));
|
||||
|
||||
m_protocolConfig.insert(config_key::site,
|
||||
protocolConfig.value(config_key::site).toString(protocols::cloak::defaultRedirSite));
|
||||
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
QJsonObject CloakConfigModel::getConfig()
|
||||
{
|
||||
m_fullConfig.insert(config_key::cloak, m_protocolConfig);
|
||||
return m_fullConfig;
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> CloakConfigModel::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roles;
|
||||
|
||||
roles[PortRole] = "port";
|
||||
roles[CipherRole] = "cipher";
|
||||
roles[SiteRole] = "site";
|
||||
|
||||
return roles;
|
||||
}
|
40
client/ui/models/protocols/cloakConfigModel.h
Normal file
40
client/ui/models/protocols/cloakConfigModel.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
#ifndef CLOAKCONFIGMODEL_H
|
||||
#define CLOAKCONFIGMODEL_H
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QJsonObject>
|
||||
|
||||
#include "containers/containers_defs.h"
|
||||
|
||||
class CloakConfigModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Roles {
|
||||
PortRole = Qt::UserRole + 1,
|
||||
CipherRole,
|
||||
SiteRole
|
||||
};
|
||||
|
||||
explicit CloakConfigModel(QObject *parent = nullptr);
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
public slots:
|
||||
void updateModel(const QJsonObject &config);
|
||||
QJsonObject getConfig();
|
||||
|
||||
protected:
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
private:
|
||||
DockerContainer m_container;
|
||||
QJsonObject m_protocolConfig;
|
||||
QJsonObject m_fullConfig;
|
||||
};
|
||||
|
||||
#endif // CLOAKCONFIGMODEL_H
|
76
client/ui/models/protocols/ikev2ConfigModel.cpp
Normal file
76
client/ui/models/protocols/ikev2ConfigModel.cpp
Normal file
|
@ -0,0 +1,76 @@
|
|||
#include "ikev2ConfigModel.h".h "
|
||||
|
||||
#include "protocols/protocols_defs.h"
|
||||
|
||||
Ikev2ConfigModel::Ikev2ConfigModel(QObject *parent) : QAbstractListModel(parent)
|
||||
{
|
||||
}
|
||||
|
||||
int Ikev2ConfigModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool Ikev2ConfigModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
if (!index.isValid() || index.row() < 0 || index.row() >= ContainerProps::allContainers().size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (role) {
|
||||
case Roles::PortRole: m_protocolConfig.insert(config_key::port, value.toString()); break;
|
||||
case Roles::CipherRole: m_protocolConfig.insert(config_key::cipher, value.toString()); break;
|
||||
}
|
||||
|
||||
emit dataChanged(index, index, QList { role });
|
||||
return true;
|
||||
}
|
||||
|
||||
QVariant Ikev2ConfigModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid() || index.row() < 0 || index.row() >= rowCount()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (role) {
|
||||
case Roles::PortRole: return m_protocolConfig.value(config_key::port).toString(protocols::shadowsocks::defaultPort);
|
||||
case Roles::CipherRole:
|
||||
return m_protocolConfig.value(config_key::cipher).toString(protocols::shadowsocks::defaultCipher);
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void Ikev2ConfigModel::updateModel(const QJsonObject &config)
|
||||
{
|
||||
beginResetModel();
|
||||
m_container = ContainerProps::containerFromString(config.value(config_key::container).toString());
|
||||
|
||||
m_fullConfig = config;
|
||||
QJsonObject protocolConfig = config.value(config_key::shadowsocks).toObject();
|
||||
|
||||
m_protocolConfig.insert(config_key::cipher,
|
||||
protocolConfig.value(config_key::cipher).toString(protocols::shadowsocks::defaultCipher));
|
||||
|
||||
m_protocolConfig.insert(config_key::port,
|
||||
protocolConfig.value(config_key::port).toString(protocols::shadowsocks::defaultPort));
|
||||
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
QJsonObject Ikev2ConfigModel::getConfig()
|
||||
{
|
||||
m_fullConfig.insert(config_key::shadowsocks, m_protocolConfig);
|
||||
return m_fullConfig;
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> Ikev2ConfigModel::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roles;
|
||||
|
||||
roles[PortRole] = "port";
|
||||
roles[CipherRole] = "cipher";
|
||||
|
||||
return roles;
|
||||
}
|
39
client/ui/models/protocols/ikev2ConfigModel.h
Normal file
39
client/ui/models/protocols/ikev2ConfigModel.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
#ifndef IKEV2CONFIGMODEL_H
|
||||
#define IKEV2CONFIGMODEL_H
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QJsonObject>
|
||||
|
||||
#include "containers/containers_defs.h"
|
||||
|
||||
class Ikev2ConfigModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Roles {
|
||||
PortRole = Qt::UserRole + 1,
|
||||
CipherRole
|
||||
};
|
||||
|
||||
explicit Ikev2ConfigModel(QObject *parent = nullptr);
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
public slots:
|
||||
void updateModel(const QJsonObject &config);
|
||||
QJsonObject getConfig();
|
||||
|
||||
protected:
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
private:
|
||||
DockerContainer m_container;
|
||||
QJsonObject m_protocolConfig;
|
||||
QJsonObject m_fullConfig;
|
||||
};
|
||||
|
||||
#endif // IKEV2CONFIGMODEL_H
|
152
client/ui/models/protocols/openvpnConfigModel.cpp
Normal file
152
client/ui/models/protocols/openvpnConfigModel.cpp
Normal file
|
@ -0,0 +1,152 @@
|
|||
#include "openvpnConfigModel.h"
|
||||
|
||||
#include "protocols/protocols_defs.h"
|
||||
|
||||
OpenVpnConfigModel::OpenVpnConfigModel(QObject *parent) : QAbstractListModel(parent)
|
||||
{
|
||||
}
|
||||
|
||||
int OpenVpnConfigModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool OpenVpnConfigModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
if (!index.isValid() || index.row() < 0 || index.row() >= ContainerProps::allContainers().size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (role) {
|
||||
case Roles::SubnetAddressRole:
|
||||
m_protocolConfig.insert(amnezia::config_key::subnet_address, value.toString());
|
||||
break;
|
||||
case Roles::TransportProtoRole: m_protocolConfig.insert(config_key::transport_proto, value.toString()); break;
|
||||
case Roles::PortRole: m_protocolConfig.insert(config_key::port, value.toString()); break;
|
||||
case Roles::AutoNegotiateEncryprionRole: m_protocolConfig.insert(config_key::ncp_disable, !value.toBool()); break;
|
||||
case Roles::HashRole: m_protocolConfig.insert(config_key::hash, value.toString()); break;
|
||||
case Roles::CipherRole: m_protocolConfig.insert(config_key::cipher, value.toString()); break;
|
||||
case Roles::TlsAuthRole: m_protocolConfig.insert(config_key::tls_auth, value.toBool()); break;
|
||||
case Roles::BlockDnsRole: m_protocolConfig.insert(config_key::block_outside_dns, value.toBool()); break;
|
||||
case Roles::AdditionalClientCommandsRole:
|
||||
m_protocolConfig.insert(config_key::additional_client_config, value.toString());
|
||||
break;
|
||||
case Roles::AdditionalServerCommandsRole:
|
||||
m_protocolConfig.insert(config_key::additional_server_config, value.toString());
|
||||
break;
|
||||
}
|
||||
|
||||
emit dataChanged(index, index, QList { role });
|
||||
return true;
|
||||
}
|
||||
|
||||
QVariant OpenVpnConfigModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid() || index.row() < 0 || index.row() >= rowCount()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (role) {
|
||||
case Roles::SubnetAddressRole:
|
||||
return m_protocolConfig.value(amnezia::config_key::subnet_address)
|
||||
.toString(amnezia::protocols::openvpn::defaultSubnetAddress);
|
||||
case Roles::TransportProtoRole:
|
||||
return m_protocolConfig.value(config_key::transport_proto).toString(protocols::openvpn::defaultTransportProto);
|
||||
case Roles::PortRole: return m_protocolConfig.value(config_key::port).toString(protocols::openvpn::defaultPort);
|
||||
case Roles::AutoNegotiateEncryprionRole:
|
||||
return !m_protocolConfig.value(config_key::ncp_disable).toBool(protocols::openvpn::defaultNcpDisable);
|
||||
case Roles::HashRole: return m_protocolConfig.value(config_key::hash).toString(protocols::openvpn::defaultHash);
|
||||
case Roles::CipherRole:
|
||||
return m_protocolConfig.value(config_key::cipher).toString(protocols::openvpn::defaultCipher);
|
||||
case Roles::TlsAuthRole:
|
||||
return m_protocolConfig.value(config_key::tls_auth).toBool(protocols::openvpn::defaultTlsAuth);
|
||||
case Roles::BlockDnsRole:
|
||||
return m_protocolConfig.value(config_key::block_outside_dns).toBool(protocols::openvpn::defaultBlockOutsideDns);
|
||||
case Roles::AdditionalClientCommandsRole:
|
||||
return m_protocolConfig.value(config_key::additional_client_config)
|
||||
.toString(protocols::openvpn::defaultAdditionalClientConfig);
|
||||
case Roles::AdditionalServerCommandsRole:
|
||||
return m_protocolConfig.value(config_key::additional_server_config)
|
||||
.toString(protocols::openvpn::defaultAdditionalServerConfig);
|
||||
case Roles::IsPortEditable: return m_container == DockerContainer::OpenVpn ? true : false;
|
||||
case Roles::IsTransportProtoEditable: return m_container == DockerContainer::OpenVpn ? true : false;
|
||||
case Roles::HasRemoveButton: return m_container == DockerContainer::OpenVpn ? true : false;
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void OpenVpnConfigModel::updateModel(const QJsonObject &config)
|
||||
{
|
||||
beginResetModel();
|
||||
m_container =
|
||||
ContainerProps::containerFromString(config.value(config_key::container).toString()); // todo maybe unused
|
||||
|
||||
m_fullConfig = config;
|
||||
QJsonObject protocolConfig = config.value(config_key::openvpn).toObject();
|
||||
|
||||
m_protocolConfig.insert(config_key::subnet_address,
|
||||
protocolConfig.value(amnezia::config_key::subnet_address)
|
||||
.toString(amnezia::protocols::openvpn::defaultSubnetAddress));
|
||||
|
||||
QString transportProto;
|
||||
if (m_container == DockerContainer::OpenVpn) {
|
||||
transportProto =
|
||||
protocolConfig.value(config_key::transport_proto).toString(protocols::openvpn::defaultTransportProto);
|
||||
} else {
|
||||
transportProto = "tcp";
|
||||
}
|
||||
|
||||
m_protocolConfig.insert(config_key::transport_proto, transportProto);
|
||||
|
||||
m_protocolConfig.insert(config_key::ncp_disable,
|
||||
protocolConfig.value(config_key::ncp_disable).toBool(protocols::openvpn::defaultNcpDisable));
|
||||
m_protocolConfig.insert(config_key::cipher,
|
||||
protocolConfig.value(config_key::cipher).toString(protocols::openvpn::defaultCipher));
|
||||
m_protocolConfig.insert(config_key::hash,
|
||||
protocolConfig.value(config_key::hash).toString(protocols::openvpn::defaultHash));
|
||||
m_protocolConfig.insert(config_key::block_outside_dns,
|
||||
protocolConfig.value(config_key::tls_auth).toBool(protocols::openvpn::defaultTlsAuth));
|
||||
m_protocolConfig.insert(config_key::port,
|
||||
protocolConfig.value(config_key::port).toString(protocols::openvpn::defaultPort));
|
||||
m_protocolConfig.insert(
|
||||
config_key::tls_auth,
|
||||
protocolConfig.value(config_key::block_outside_dns).toBool(protocols::openvpn::defaultBlockOutsideDns));
|
||||
m_protocolConfig.insert(config_key::additional_client_config,
|
||||
protocolConfig.value(config_key::additional_client_config)
|
||||
.toString(protocols::openvpn::defaultAdditionalClientConfig));
|
||||
m_protocolConfig.insert(config_key::additional_server_config,
|
||||
protocolConfig.value(config_key::additional_server_config)
|
||||
.toString(protocols::openvpn::defaultAdditionalServerConfig));
|
||||
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
QJsonObject OpenVpnConfigModel::getConfig()
|
||||
{
|
||||
m_fullConfig.insert(config_key::openvpn, m_protocolConfig);
|
||||
return m_fullConfig;
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> OpenVpnConfigModel::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roles;
|
||||
|
||||
roles[SubnetAddressRole] = "subnetAddress";
|
||||
roles[TransportProtoRole] = "transportProto";
|
||||
roles[PortRole] = "port";
|
||||
roles[AutoNegotiateEncryprionRole] = "autoNegotiateEncryprion";
|
||||
roles[HashRole] = "hash";
|
||||
roles[CipherRole] = "cipher";
|
||||
roles[TlsAuthRole] = "tlsAuth";
|
||||
roles[BlockDnsRole] = "blockDns";
|
||||
roles[AdditionalClientCommandsRole] = "additionalClientCommands";
|
||||
roles[AdditionalServerCommandsRole] = "additionalServerCommands";
|
||||
|
||||
roles[IsPortEditable] = "isPortEditable";
|
||||
roles[IsTransportProtoEditable] = "isTransportProtoEditable";
|
||||
|
||||
roles[HasRemoveButton] = "hasRemoveButton";
|
||||
|
||||
return roles;
|
||||
}
|
52
client/ui/models/protocols/openvpnConfigModel.h
Normal file
52
client/ui/models/protocols/openvpnConfigModel.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
#ifndef OPENVPNCONFIGMODEL_H
|
||||
#define OPENVPNCONFIGMODEL_H
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QJsonObject>
|
||||
|
||||
#include "containers/containers_defs.h"
|
||||
|
||||
class OpenVpnConfigModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Roles {
|
||||
SubnetAddressRole = Qt::UserRole + 1,
|
||||
TransportProtoRole,
|
||||
PortRole,
|
||||
AutoNegotiateEncryprionRole,
|
||||
HashRole,
|
||||
CipherRole,
|
||||
TlsAuthRole,
|
||||
BlockDnsRole,
|
||||
AdditionalClientCommandsRole,
|
||||
AdditionalServerCommandsRole,
|
||||
|
||||
IsPortEditable,
|
||||
IsTransportProtoEditable,
|
||||
|
||||
HasRemoveButton
|
||||
};
|
||||
|
||||
explicit OpenVpnConfigModel(QObject *parent = nullptr);
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
public slots:
|
||||
void updateModel(const QJsonObject &config);
|
||||
QJsonObject getConfig();
|
||||
|
||||
protected:
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
private:
|
||||
DockerContainer m_container;
|
||||
QJsonObject m_protocolConfig;
|
||||
QJsonObject m_fullConfig;
|
||||
};
|
||||
|
||||
#endif // OPENVPNCONFIGMODEL_H
|
76
client/ui/models/protocols/shadowsocksConfigModel.cpp
Normal file
76
client/ui/models/protocols/shadowsocksConfigModel.cpp
Normal file
|
@ -0,0 +1,76 @@
|
|||
#include "shadowsocksConfigModel.h"
|
||||
|
||||
#include "protocols/protocols_defs.h"
|
||||
|
||||
ShadowSocksConfigModel::ShadowSocksConfigModel(QObject *parent) : QAbstractListModel(parent)
|
||||
{
|
||||
}
|
||||
|
||||
int ShadowSocksConfigModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool ShadowSocksConfigModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
if (!index.isValid() || index.row() < 0 || index.row() >= ContainerProps::allContainers().size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (role) {
|
||||
case Roles::PortRole: m_protocolConfig.insert(config_key::port, value.toString()); break;
|
||||
case Roles::CipherRole: m_protocolConfig.insert(config_key::cipher, value.toString()); break;
|
||||
}
|
||||
|
||||
emit dataChanged(index, index, QList { role });
|
||||
return true;
|
||||
}
|
||||
|
||||
QVariant ShadowSocksConfigModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid() || index.row() < 0 || index.row() >= rowCount()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (role) {
|
||||
case Roles::PortRole: return m_protocolConfig.value(config_key::port).toString(protocols::shadowsocks::defaultPort);
|
||||
case Roles::CipherRole:
|
||||
return m_protocolConfig.value(config_key::cipher).toString(protocols::shadowsocks::defaultCipher);
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void ShadowSocksConfigModel::updateModel(const QJsonObject &config)
|
||||
{
|
||||
beginResetModel();
|
||||
m_container = ContainerProps::containerFromString(config.value(config_key::container).toString());
|
||||
|
||||
m_fullConfig = config;
|
||||
QJsonObject protocolConfig = config.value(config_key::shadowsocks).toObject();
|
||||
|
||||
m_protocolConfig.insert(config_key::cipher,
|
||||
protocolConfig.value(config_key::cipher).toString(protocols::shadowsocks::defaultCipher));
|
||||
|
||||
m_protocolConfig.insert(config_key::port,
|
||||
protocolConfig.value(config_key::port).toString(protocols::shadowsocks::defaultPort));
|
||||
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
QJsonObject ShadowSocksConfigModel::getConfig()
|
||||
{
|
||||
m_fullConfig.insert(config_key::shadowsocks, m_protocolConfig);
|
||||
return m_fullConfig;
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> ShadowSocksConfigModel::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roles;
|
||||
|
||||
roles[PortRole] = "port";
|
||||
roles[CipherRole] = "cipher";
|
||||
|
||||
return roles;
|
||||
}
|
39
client/ui/models/protocols/shadowsocksConfigModel.h
Normal file
39
client/ui/models/protocols/shadowsocksConfigModel.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
#ifndef SHADOWSOCKSCONFIGMODEL_H
|
||||
#define SHADOWSOCKSCONFIGMODEL_H
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QJsonObject>
|
||||
|
||||
#include "containers/containers_defs.h"
|
||||
|
||||
class ShadowSocksConfigModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Roles {
|
||||
PortRole = Qt::UserRole + 1,
|
||||
CipherRole
|
||||
};
|
||||
|
||||
explicit ShadowSocksConfigModel(QObject *parent = nullptr);
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
public slots:
|
||||
void updateModel(const QJsonObject &config);
|
||||
QJsonObject getConfig();
|
||||
|
||||
protected:
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
private:
|
||||
DockerContainer m_container;
|
||||
QJsonObject m_protocolConfig;
|
||||
QJsonObject m_fullConfig;
|
||||
};
|
||||
|
||||
#endif // SHADOWSOCKSCONFIGMODEL_H
|
70
client/ui/models/protocols/wireguardConfigModel.cpp
Normal file
70
client/ui/models/protocols/wireguardConfigModel.cpp
Normal file
|
@ -0,0 +1,70 @@
|
|||
#include "wireguardConfigModel.h"
|
||||
|
||||
#include "protocols/protocols_defs.h"
|
||||
|
||||
WireGuardConfigModel::WireGuardConfigModel(QObject *parent) : QAbstractListModel(parent)
|
||||
{
|
||||
}
|
||||
|
||||
int WireGuardConfigModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool WireGuardConfigModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
if (!index.isValid() || index.row() < 0 || index.row() >= ContainerProps::allContainers().size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (role) {
|
||||
case Roles::PortRole: m_protocolConfig.insert(config_key::port, value.toString()); break;
|
||||
case Roles::CipherRole: m_protocolConfig.insert(config_key::cipher, value.toString()); break;
|
||||
}
|
||||
|
||||
emit dataChanged(index, index, QList { role });
|
||||
return true;
|
||||
}
|
||||
|
||||
QVariant WireGuardConfigModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid() || index.row() < 0 || index.row() >= rowCount()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (role) {
|
||||
case Roles::PortRole: return m_protocolConfig.value(config_key::port).toString(protocols::shadowsocks::defaultPort);
|
||||
case Roles::CipherRole:
|
||||
return m_protocolConfig.value(config_key::cipher).toString(protocols::shadowsocks::defaultCipher);
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void WireGuardConfigModel::updateModel(const QJsonObject &config)
|
||||
{
|
||||
beginResetModel();
|
||||
m_container = ContainerProps::containerFromString(config.value(config_key::container).toString());
|
||||
|
||||
m_fullConfig = config;
|
||||
QJsonObject protocolConfig = config.value(config_key::wireguard).toObject();
|
||||
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
QJsonObject WireGuardConfigModel::getConfig()
|
||||
{
|
||||
m_fullConfig.insert(config_key::wireguard, m_protocolConfig);
|
||||
return m_fullConfig;
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> WireGuardConfigModel::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roles;
|
||||
|
||||
roles[PortRole] = "port";
|
||||
roles[CipherRole] = "cipher";
|
||||
|
||||
return roles;
|
||||
}
|
39
client/ui/models/protocols/wireguardConfigModel.h
Normal file
39
client/ui/models/protocols/wireguardConfigModel.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
#ifndef WIREGUARDCONFIGMODEL_H
|
||||
#define WIREGUARDCONFIGMODEL_H
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QJsonObject>
|
||||
|
||||
#include "containers/containers_defs.h"
|
||||
|
||||
class WireGuardConfigModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Roles {
|
||||
PortRole = Qt::UserRole + 1,
|
||||
CipherRole
|
||||
};
|
||||
|
||||
explicit WireGuardConfigModel(QObject *parent = nullptr);
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
public slots:
|
||||
void updateModel(const QJsonObject &config);
|
||||
QJsonObject getConfig();
|
||||
|
||||
protected:
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
private:
|
||||
DockerContainer m_container;
|
||||
QJsonObject m_protocolConfig;
|
||||
QJsonObject m_fullConfig;
|
||||
};
|
||||
|
||||
#endif // WIREGUARDCONFIGMODEL_H
|
|
@ -1,62 +1,73 @@
|
|||
#include "protocols_model.h"
|
||||
|
||||
ProtocolsModel::ProtocolsModel(std::shared_ptr<Settings> settings, QObject *parent) :
|
||||
m_settings(settings),
|
||||
QAbstractListModel(parent)
|
||||
ProtocolsModel::ProtocolsModel(std::shared_ptr<Settings> settings, QObject *parent)
|
||||
: m_settings(settings), QAbstractListModel(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int ProtocolsModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
return ProtocolProps::allProtocols().size();
|
||||
return m_content.size();
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> ProtocolsModel::roleNames() const {
|
||||
QHash<int, QByteArray> ProtocolsModel::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roles;
|
||||
roles[NameRole] = "name_role";
|
||||
roles[DescRole] = "desc_role";
|
||||
roles[ServiceTypeRole] = "service_type_role";
|
||||
roles[IsInstalledRole] = "is_installed_role";
|
||||
|
||||
roles[ProtocolNameRole] = "protocolName";
|
||||
roles[ProtocolPageRole] = "protocolPage";
|
||||
|
||||
return roles;
|
||||
}
|
||||
|
||||
QVariant ProtocolsModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid() || index.row() < 0
|
||||
|| index.row() >= ProtocolProps::allProtocols().size()) {
|
||||
if (!index.isValid() || index.row() < 0 || index.row() >= m_content.size()) {
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
Proto p = ProtocolProps::allProtocols().at(index.row());
|
||||
if (role == NameRole) {
|
||||
return ProtocolProps::protocolHumanNames().value(p);
|
||||
switch (role) {
|
||||
case ProtocolNameRole: {
|
||||
amnezia::Proto proto = ProtocolProps::protoFromString(m_content.keys().at(index.row()));
|
||||
return ProtocolProps::protocolHumanNames().value(proto);
|
||||
}
|
||||
if (role == DescRole) {
|
||||
return ProtocolProps::protocolDescriptions().value(p);
|
||||
}
|
||||
if (role == ServiceTypeRole) {
|
||||
return ProtocolProps::protocolService(p);
|
||||
}
|
||||
if (role == IsInstalledRole) {
|
||||
return ContainerProps::protocolsForContainer(m_selectedDockerContainer).contains(p);
|
||||
case ProtocolPageRole:
|
||||
return static_cast<int>(protocolPage(ProtocolProps::protoFromString(m_content.keys().at(index.row()))));
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void ProtocolsModel::setSelectedServerIndex(int index)
|
||||
void ProtocolsModel::updateModel(const QJsonObject &content)
|
||||
{
|
||||
beginResetModel();
|
||||
m_selectedServerIndex = index;
|
||||
endResetModel();
|
||||
m_container = ContainerProps::containerFromString(content.value(config_key::container).toString());
|
||||
|
||||
m_content = content;
|
||||
m_content.remove(config_key::container);
|
||||
}
|
||||
|
||||
void ProtocolsModel::setSelectedDockerContainer(DockerContainer c)
|
||||
QJsonObject ProtocolsModel::getConfig()
|
||||
{
|
||||
beginResetModel();
|
||||
m_selectedDockerContainer = c;
|
||||
endResetModel();
|
||||
QJsonObject config = m_content;
|
||||
config.insert(config_key::container, ContainerProps::containerToString(m_container));
|
||||
return config;
|
||||
}
|
||||
|
||||
|
||||
PageLoader::PageEnum ProtocolsModel::protocolPage(Proto protocol) const
|
||||
{
|
||||
switch (protocol) {
|
||||
case Proto::OpenVpn: return PageLoader::PageEnum::PageProtocolOpenVpnSettings;
|
||||
case Proto::Cloak: return PageLoader::PageEnum::PageProtocolCloakSettings;
|
||||
case Proto::ShadowSocks: return PageLoader::PageEnum::PageProtocolShadowSocksSettings;
|
||||
case Proto::WireGuard: return PageLoader::PageEnum::PageProtocolWireGuardSettings;
|
||||
case Proto::Ikev2: return PageLoader::PageEnum::PageProtocolIKev2Settings;
|
||||
case Proto::L2tp: return PageLoader::PageEnum::PageProtocolOpenVpnSettings;
|
||||
// non-vpn
|
||||
case Proto::TorWebSite: return PageLoader::PageEnum::PageProtocolOpenVpnSettings;
|
||||
case Proto::Dns: return PageLoader::PageEnum::PageProtocolOpenVpnSettings;
|
||||
case Proto::FileShare: return PageLoader::PageEnum::PageProtocolOpenVpnSettings;
|
||||
case Proto::Sftp: return PageLoader::PageEnum::PageProtocolOpenVpnSettings;
|
||||
default: return PageLoader::PageEnum::PageProtocolOpenVpnSettings;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,38 +3,40 @@
|
|||
|
||||
#include <QAbstractListModel>
|
||||
#include <QJsonObject>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
#include "../controllers/pageController.h"
|
||||
#include "settings.h"
|
||||
#include "containers/containers_defs.h"
|
||||
|
||||
class ProtocolsModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ProtocolsModel(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
||||
public:
|
||||
enum SiteRoles {
|
||||
NameRole = Qt::UserRole + 1,
|
||||
DescRole,
|
||||
ServiceTypeRole,
|
||||
IsInstalledRole
|
||||
enum Roles {
|
||||
ProtocolNameRole = Qt::UserRole + 1,
|
||||
ProtocolPageRole
|
||||
};
|
||||
|
||||
ProtocolsModel(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
Q_INVOKABLE void setSelectedServerIndex(int index);
|
||||
Q_INVOKABLE void setSelectedDockerContainer(DockerContainer c);
|
||||
|
||||
public slots:
|
||||
void updateModel(const QJsonObject &content);
|
||||
|
||||
QJsonObject getConfig();
|
||||
|
||||
protected:
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
private:
|
||||
int m_selectedServerIndex;
|
||||
DockerContainer m_selectedDockerContainer;
|
||||
PageLoader::PageEnum protocolPage(Proto protocol) const;
|
||||
|
||||
std::shared_ptr<Settings> m_settings;
|
||||
|
||||
DockerContainer m_container;
|
||||
QJsonObject m_content;
|
||||
};
|
||||
|
||||
#endif // PROTOCOLS_MODEL_H
|
||||
|
|
|
@ -123,6 +123,7 @@ bool ServersModel::isDefaultServerHasWriteAccess()
|
|||
|
||||
void ServersModel::addServer(const QJsonObject &server)
|
||||
{
|
||||
// todo beginInsertRows()?
|
||||
beginResetModel();
|
||||
m_settings->addServer(server);
|
||||
m_servers = m_settings->serversArray();
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
#include "GeneralSettingsLogic.h"
|
||||
#include "ShareConnectionLogic.h"
|
||||
|
||||
#include "../uilogic.h"
|
||||
#include "../models/protocols_model.h"
|
||||
#include "../uilogic.h"
|
||||
|
||||
GeneralSettingsLogic::GeneralSettingsLogic(UiLogic *logic, QObject *parent):
|
||||
PageLogicBase(logic, parent)
|
||||
GeneralSettingsLogic::GeneralSettingsLogic(UiLogic *logic, QObject *parent) : PageLogicBase(logic, parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void GeneralSettingsLogic::onUpdatePage()
|
||||
|
@ -32,9 +30,11 @@ 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);
|
||||
// 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);
|
||||
uiLogic()->pageLogic<ShareConnectionLogic>()->updateSharingPage(uiLogic()->m_selectedServerIndex,
|
||||
uiLogic()->m_selectedDockerContainer);
|
||||
emit uiLogic()->goToPage(Page::ShareConnection);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "ServerContainersLogic.h"
|
||||
#include "ShareConnectionLogic.h"
|
||||
#include "ServerConfiguringProgressLogic.h"
|
||||
#include "ShareConnectionLogic.h"
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
|
@ -9,24 +9,22 @@
|
|||
#include "core/servercontroller.h"
|
||||
#include <functional>
|
||||
|
||||
#include "../uilogic.h"
|
||||
#include "../pages_logic/VpnLogic.h"
|
||||
#include "vpnconnection.h"
|
||||
#include "../uilogic.h"
|
||||
#include "core/errorstrings.h"
|
||||
#include "vpnconnection.h"
|
||||
|
||||
|
||||
ServerContainersLogic::ServerContainersLogic(UiLogic *logic, QObject *parent):
|
||||
PageLogicBase(logic, parent)
|
||||
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);
|
||||
// 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);
|
||||
// p_model->setSelectedServerIndex(uiLogic()->m_selectedServerIndex);
|
||||
|
||||
set_isManagedServer(m_settings->haveAuthData(uiLogic()->m_selectedServerIndex));
|
||||
uiLogic()->m_installCredentials = m_settings->serverCredentials(uiLogic()->m_selectedServerIndex);
|
||||
|
@ -35,25 +33,29 @@ void ServerContainersLogic::onUpdatePage()
|
|||
|
||||
void ServerContainersLogic::onPushButtonProtoSettingsClicked(DockerContainer c, Proto p)
|
||||
{
|
||||
qDebug()<< "ServerContainersLogic::onPushButtonProtoSettingsClicked" << c << 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));
|
||||
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;
|
||||
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;
|
||||
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();
|
||||
|
@ -67,16 +69,19 @@ void ServerContainersLogic::onPushButtonShareClicked(DockerContainer c)
|
|||
|
||||
void ServerContainersLogic::onPushButtonRemoveClicked(DockerContainer container)
|
||||
{
|
||||
//buttonSetEnabledFunc(false);
|
||||
// buttonSetEnabledFunc(false);
|
||||
ServerController serverController(m_settings);
|
||||
ErrorCode e = serverController.removeContainer(m_settings->serverCredentials(uiLogic()->m_selectedServerIndex), container);
|
||||
ErrorCode e =
|
||||
serverController.removeContainer(m_settings->serverCredentials(uiLogic()->m_selectedServerIndex), container);
|
||||
m_settings->removeContainerConfig(uiLogic()->m_selectedServerIndex, container);
|
||||
//buttonSetEnabledFunc(true);
|
||||
// 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());
|
||||
if (c.isEmpty())
|
||||
m_settings->setDefaultContainer(uiLogic()->m_selectedServerIndex, DockerContainer::None);
|
||||
else
|
||||
m_settings->setDefaultContainer(uiLogic()->m_selectedServerIndex, c.keys().first());
|
||||
}
|
||||
uiLogic()->onUpdateAllPages();
|
||||
}
|
||||
|
@ -96,7 +101,8 @@ void ServerContainersLogic::onPushButtonContinueClicked(DockerContainer c, int p
|
|||
if (!uiLogic()->isContainerAlreadyAddedToGui(c)) {
|
||||
auto installAction = [this, c, &config]() {
|
||||
ServerController serverController(m_settings);
|
||||
return serverController.setupContainer(m_settings->serverCredentials(uiLogic()->m_selectedServerIndex), c, config);
|
||||
return serverController.setupContainer(m_settings->serverCredentials(uiLogic()->m_selectedServerIndex),
|
||||
c, config);
|
||||
};
|
||||
errorCode = uiLogic()->pageLogic<ServerConfiguringProgressLogic>()->doInstallAction(installAction);
|
||||
|
||||
|
@ -107,16 +113,16 @@ void ServerContainersLogic::onPushButtonContinueClicked(DockerContainer c, int p
|
|||
}
|
||||
}
|
||||
} 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 ");
|
||||
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()->showWarningMessage(tr("Error occurred while configuring server.") + "\n" + tr("Error message: ")
|
||||
+ errorString(errorCode) + "\n" + tr("See logs for details."));
|
||||
}
|
||||
emit uiLogic()->closePage();
|
||||
}
|
||||
|
|
|
@ -1,147 +0,0 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
|
||||
import "../../Controls2"
|
||||
import "../../Controls2/TextTypes"
|
||||
import "../../Components"
|
||||
|
||||
Item {
|
||||
id: root
|
||||
implicitHeight: col.implicitHeight
|
||||
implicitWidth: col.implicitWidth
|
||||
|
||||
ColumnLayout {
|
||||
id: col
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
anchors.leftMargin: 16
|
||||
anchors.rightMargin: 16
|
||||
|
||||
spacing: 16
|
||||
|
||||
Header2TextType {
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: "OpenVpn"
|
||||
}
|
||||
|
||||
TextFieldWithHeaderType {
|
||||
Layout.fillWidth: true
|
||||
|
||||
headerText: qsTr("VPN Addresses Subnet")
|
||||
}
|
||||
|
||||
ParagraphTextType {
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: qsTr("Network protocol")
|
||||
}
|
||||
|
||||
TransportProtoSelector {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
TextFieldWithHeaderType {
|
||||
Layout.fillWidth: true
|
||||
|
||||
headerText: qsTr("Port")
|
||||
}
|
||||
|
||||
SwitcherType {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Auto-negotiate encryption")
|
||||
}
|
||||
|
||||
DropDownType {
|
||||
id: hash
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: 74
|
||||
|
||||
descriptionText: qsTr("Hash")
|
||||
headerText: qsTr("Hash")
|
||||
|
||||
listView: ListViewType {
|
||||
rootWidth: root.width
|
||||
|
||||
model: ListModel {
|
||||
ListElement { name : qsTr("SHA512") }
|
||||
ListElement { name : qsTr("SHA384") }
|
||||
ListElement { name : qsTr("SHA256") }
|
||||
ListElement { name : qsTr("SHA3-512") }
|
||||
ListElement { name : qsTr("SHA3-384") }
|
||||
ListElement { name : qsTr("SHA3-256") }
|
||||
ListElement { name : qsTr("whirlpool") }
|
||||
ListElement { name : qsTr("BLAKE2b512") }
|
||||
ListElement { name : qsTr("BLAKE2s256") }
|
||||
ListElement { name : qsTr("SHA1") }
|
||||
}
|
||||
currentIndex: 0
|
||||
|
||||
clickedFunction: {
|
||||
hash.text = selectedText
|
||||
hash.menuVisible = false
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
hash.text = selectedText
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DropDownType {
|
||||
id: cipher
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: 74
|
||||
|
||||
descriptionText: qsTr("Cipher")
|
||||
headerText: qsTr("Cipher")
|
||||
|
||||
listView: ListViewType {
|
||||
rootWidth: root.width
|
||||
|
||||
model: ListModel {
|
||||
ListElement { name : qsTr("AES-256-GCM") }
|
||||
ListElement { name : qsTr("AES-192-GCM") }
|
||||
ListElement { name : qsTr("AES-128-GCM") }
|
||||
ListElement { name : qsTr("AES-256-CBC") }
|
||||
ListElement { name : qsTr("AES-192-CBC") }
|
||||
ListElement { name : qsTr("AES-128-CBC") }
|
||||
ListElement { name : qsTr("ChaCha20-Poly1305") }
|
||||
ListElement { name : qsTr("ARIA-256-CBC") }
|
||||
ListElement { name : qsTr("CAMELLIA-256-CBC") }
|
||||
ListElement { name : qsTr("none") }
|
||||
}
|
||||
currentIndex: 0
|
||||
|
||||
clickedFunction: {
|
||||
cipher.text = selectedText
|
||||
cipher.menuVisible = false
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
cipher.text = selectedText
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CheckBoxType {
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: qsTr("TLS auth")
|
||||
}
|
||||
|
||||
CheckBoxType {
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: qsTr("Block DNS requests outside of VPN")
|
||||
}
|
||||
|
||||
SwitcherType {
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: qsTr("Additional configuration commands")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,6 +6,7 @@ import SortFilterProxyModel 0.2
|
|||
|
||||
import PageEnum 1.0
|
||||
import ProtocolEnum 1.0
|
||||
import ContainerEnum 1.0
|
||||
|
||||
import "../Controls2"
|
||||
import "../Controls2/TextTypes"
|
||||
|
@ -88,8 +89,32 @@ ListView {
|
|||
|
||||
onClicked: {
|
||||
if (isInstalled) {
|
||||
ContainersModel.setCurrentlyProcessedContainerIndex(root.model.mapToSource(index))
|
||||
goToPage(PageEnum.PageSettingsServerProtocol)
|
||||
var containerIndex = root.model.mapToSource(index)
|
||||
ContainersModel.setCurrentlyProcessedContainerIndex(containerIndex)
|
||||
switch (containerIndex) {
|
||||
case ContainerEnum.OpenVpn: {
|
||||
OpenVpnConfigModel.updateModel(ProtocolsModel.getConfig())
|
||||
goToPage(PageEnum.PageProtocolOpenVpnSettings)
|
||||
break
|
||||
}
|
||||
case ContainerEnum.WireGuard: {
|
||||
WireGuardConfigModel.updateModel(ProtocolsModel.getConfig())
|
||||
goToPage(PageEnum.PageProtocolWireGuardSettings)
|
||||
break
|
||||
}
|
||||
case ContainerEnum.Ipsec: {
|
||||
Ikev2ConfigModel.updateModel(ProtocolsModel.getConfig())
|
||||
goToPage(PageEnum.PageProtocolIKev2Settings)
|
||||
break
|
||||
}
|
||||
default: {
|
||||
if (serviceType !== ProtocolEnum.Other) { //todo disable settings for dns container
|
||||
ProtocolsModel.updateModel(config)
|
||||
goToPage(PageEnum.PageSettingsServerProtocol)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
ContainersModel.setCurrentlyProcessedContainerIndex(root.model.mapToSource(index))
|
||||
InstallController.setShouldCreateServer(false)
|
||||
|
|
|
@ -75,9 +75,9 @@ DrawerType {
|
|||
text: qsTr("Copy")
|
||||
|
||||
onClicked: {
|
||||
configContent.selectAll()
|
||||
configContent.copy()
|
||||
configContent.select(0, 0)
|
||||
configText.selectAll()
|
||||
configText.copy()
|
||||
configText.select(0, 0)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,6 +138,8 @@ DrawerType {
|
|||
}
|
||||
|
||||
TextArea {
|
||||
id: configText
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 16
|
||||
Layout.bottomMargin: 16
|
||||
|
|
|
@ -25,6 +25,8 @@ Rectangle {
|
|||
HorizontalRadioButton {
|
||||
checked: root.currentIndex === 0
|
||||
|
||||
hoverEnabled: root.enabled
|
||||
|
||||
implicitWidth: (rootWidth - 32) / 2
|
||||
text: "UDP"
|
||||
|
||||
|
@ -36,6 +38,8 @@ Rectangle {
|
|||
HorizontalRadioButton {
|
||||
checked: root.currentIndex === 1
|
||||
|
||||
hoverEnabled: root.enabled
|
||||
|
||||
implicitWidth: (rootWidth - 32) / 2
|
||||
text: "TCP"
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@ import QtQuick.Controls
|
|||
import QtQuick.Layouts
|
||||
import Qt5Compat.GraphicalEffects
|
||||
|
||||
import "TextTypes"
|
||||
|
||||
CheckBox {
|
||||
id: root
|
||||
|
||||
|
@ -26,6 +28,8 @@ CheckBox {
|
|||
indicator: Rectangle {
|
||||
id: checkBoxBackground
|
||||
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
implicitWidth: 56
|
||||
implicitHeight: 56
|
||||
radius: 16
|
||||
|
@ -57,43 +61,41 @@ CheckBox {
|
|||
anchors.centerIn: parent
|
||||
|
||||
source: root.pressed ? imageSource : root.checked ? imageSource : ""
|
||||
|
||||
ColorOverlay {
|
||||
id: imageColor
|
||||
anchors.fill: indicator
|
||||
source: indicator
|
||||
|
||||
color: root.pressed ? pressedImageColor : root.checked ? checkedImageColor : defaultImageColor
|
||||
layer {
|
||||
enabled: true
|
||||
effect: ColorOverlay {
|
||||
color: root.pressed ? pressedImageColor : root.checked ? checkedImageColor : defaultImageColor
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
contentItem: ColumnLayout {
|
||||
anchors.fill: parent
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.leftMargin: 8 + checkBoxBackground.width
|
||||
|
||||
Text {
|
||||
text: root.text
|
||||
color: "#D7D8DB"
|
||||
font.pixelSize: 18
|
||||
font.weight: 400
|
||||
font.family: "PT Root UI VF"
|
||||
spacing: 4
|
||||
|
||||
height: 22
|
||||
ListItemTitleType {
|
||||
Layout.fillWidth: true
|
||||
// Layout.topMargin: 16
|
||||
// Layout.bottomMargin: description.visible ? 0 : 16
|
||||
|
||||
text: root.text
|
||||
}
|
||||
|
||||
Text {
|
||||
CaptionTextType {
|
||||
id: description
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.bottomMargin: 16
|
||||
|
||||
text: root.descriptionText
|
||||
color: "#878b91"
|
||||
font.pixelSize: 13
|
||||
font.weight: 400
|
||||
font.family: "PT Root UI VF"
|
||||
font.letterSpacing: 0.02
|
||||
|
||||
height: 16
|
||||
Layout.fillWidth: true
|
||||
visible: root.descriptionText !== ""
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,8 +9,11 @@ Item {
|
|||
|
||||
property string text
|
||||
property string textColor: "#d7d8db"
|
||||
property string textDisabledColor: "#878B91"
|
||||
|
||||
property string descriptionText
|
||||
property string descriptionTextColor: "#878B91"
|
||||
property string descriptionTextDisabledColor: "#494B50"
|
||||
|
||||
property string headerText
|
||||
property string headerBackButtonImage
|
||||
|
@ -23,7 +26,6 @@ Item {
|
|||
property string rootButtonHoveredBorderColor: "#494B50"
|
||||
property string rootButtonDefaultBorderColor: "transparent"
|
||||
property string rootButtonPressedBorderColor: "#D7D8DB"
|
||||
property int rootButtonBorderWidth: 1
|
||||
|
||||
property real drawerHeight: 0.9
|
||||
property Component listView
|
||||
|
@ -36,10 +38,18 @@ Item {
|
|||
onMenuVisibleChanged: {
|
||||
if (menuVisible) {
|
||||
rootButtonBackground.border.color = rootButtonPressedBorderColor
|
||||
rootButtonBackground.border.width = rootButtonBorderWidth
|
||||
} else {
|
||||
rootButtonBackground.border.color = rootButtonDefaultBorderColor
|
||||
rootButtonBackground.border.width = 0
|
||||
}
|
||||
}
|
||||
|
||||
onEnabledChanged: {
|
||||
if (enabled) {
|
||||
rootButtonBackground.color = rootButtonBackgroundColor
|
||||
rootButtonBackground.border.color = rootButtonDefaultBorderColor
|
||||
} else {
|
||||
rootButtonBackground.color = "transparent"
|
||||
rootButtonBackground.border.color = rootButtonHoveredBorderColor
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,13 +58,10 @@ Item {
|
|||
anchors.fill: rootButtonContent
|
||||
|
||||
radius: 16
|
||||
color: rootButtonBackgroundColor
|
||||
border.color: rootButtonDefaultBorderColor
|
||||
border.width: 0
|
||||
color: root.enabled ? rootButtonBackgroundColor : "transparent"
|
||||
border.color: root.enabled ? rootButtonDefaultBorderColor : rootButtonHoveredBorderColor
|
||||
border.width: 1
|
||||
|
||||
Behavior on border.width {
|
||||
PropertyAnimation { duration: 200 }
|
||||
}
|
||||
Behavior on border.color {
|
||||
PropertyAnimation { duration: 200 }
|
||||
}
|
||||
|
@ -77,7 +84,7 @@ Item {
|
|||
|
||||
visible: root.descriptionText !== ""
|
||||
|
||||
color: "#878B91"
|
||||
color: root.enabled ? root.descriptionTextColor : root.descriptionTextDisabledColor
|
||||
text: root.descriptionText
|
||||
}
|
||||
|
||||
|
@ -87,7 +94,7 @@ Item {
|
|||
horizontalAlignment: Text.AlignLeft
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
||||
color: root.textColor
|
||||
color: root.enabled ? root.textColor : root.textDisabledColor
|
||||
text: root.text
|
||||
|
||||
wrapMode: Text.NoWrap
|
||||
|
@ -108,18 +115,16 @@ Item {
|
|||
MouseArea {
|
||||
anchors.fill: rootButtonContent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
hoverEnabled: true
|
||||
hoverEnabled: root.enabled ? true : false
|
||||
|
||||
onEntered: {
|
||||
if (menu.visible === false) {
|
||||
rootButtonBackground.border.width = rootButtonBorderWidth
|
||||
rootButtonBackground.border.color = rootButtonHoveredBorderColor
|
||||
}
|
||||
}
|
||||
|
||||
onExited: {
|
||||
if (menu.visible === false) {
|
||||
rootButtonBackground.border.width = 0
|
||||
rootButtonBackground.border.color = rootButtonDefaultBorderColor
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,45 +22,44 @@ RadioButton {
|
|||
implicitWidth: content.implicitWidth
|
||||
implicitHeight: content.implicitHeight
|
||||
|
||||
hoverEnabled: true
|
||||
|
||||
indicator: Rectangle {
|
||||
anchors.fill: parent
|
||||
radius: 16
|
||||
|
||||
color: {
|
||||
if (root.enabled) {
|
||||
// if (root.enabled) {
|
||||
if (root.hovered) {
|
||||
return hoveredColor
|
||||
} else if (root.checked) {
|
||||
return selectedColor
|
||||
}
|
||||
return defaultColor
|
||||
} else {
|
||||
return disabledColor
|
||||
}
|
||||
// } else {
|
||||
// return disabledColor
|
||||
// }
|
||||
}
|
||||
|
||||
border.color: {
|
||||
if (root.enabled) {
|
||||
// if (root.enabled) {
|
||||
if (root.pressed) {
|
||||
return pressedBorderColor
|
||||
} else if (root.checked) {
|
||||
return selectedBorderColor
|
||||
}
|
||||
}
|
||||
return defaultBodredColor
|
||||
return defaultBodredColor
|
||||
// }
|
||||
// return defaultBodredColor
|
||||
}
|
||||
|
||||
border.width: {
|
||||
if (root.enabled) {
|
||||
// if (root.enabled) {
|
||||
if(root.checked) {
|
||||
return 1
|
||||
}
|
||||
return root.pressed ? 1 : 0
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
// } else {
|
||||
// return 0
|
||||
// }
|
||||
}
|
||||
|
||||
Behavior on color {
|
||||
|
|
|
@ -8,6 +8,9 @@ Item {
|
|||
id: root
|
||||
|
||||
property string headerText
|
||||
property string headerTextDisabledColor: "#494B50"
|
||||
property string headerTextColor: "#878b91"
|
||||
|
||||
property alias errorText: errorField.text
|
||||
|
||||
property string buttonText
|
||||
|
@ -15,9 +18,18 @@ Item {
|
|||
|
||||
property alias textField: textField
|
||||
property alias textFieldText: textField.text
|
||||
property string textFieldTextColor: "#d7d8db"
|
||||
property string textFieldTextDisabledColor: "#878B91"
|
||||
|
||||
property string textFieldPlaceholderText
|
||||
property bool textFieldEditable: true
|
||||
|
||||
property string borderColor: "#2C2D30"
|
||||
property string borderFocusedColor: "#d7d8db"
|
||||
|
||||
property string backgroundColor: "#1c1d21"
|
||||
property string backgroundDisabledColor: "transparent"
|
||||
|
||||
implicitWidth: content.implicitWidth
|
||||
implicitHeight: content.implicitHeight
|
||||
|
||||
|
@ -29,9 +41,9 @@ Item {
|
|||
id: backgroud
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 74
|
||||
color: "#1c1d21"
|
||||
color: root.enabled ? root.backgroundColor : root.backgroundDisabledColor
|
||||
radius: 16
|
||||
border.color: textField.focus ? "#d7d8db" : "#2C2D30"
|
||||
border.color: textField.focus ? root.borderFocusedColor : root.borderColor
|
||||
border.width: 1
|
||||
|
||||
Behavior on border.color {
|
||||
|
@ -43,7 +55,7 @@ Item {
|
|||
ColumnLayout {
|
||||
LabelTextType {
|
||||
text: root.headerText
|
||||
color: "#878b91"
|
||||
color: root.enabled ? root.headerTextColor : root.headerTextDisabledColor
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.rightMargin: 16
|
||||
|
@ -55,9 +67,9 @@ Item {
|
|||
id: textField
|
||||
|
||||
enabled: root.textFieldEditable
|
||||
color: "#d7d8db"
|
||||
color: root.enabled ? root.textFieldTextColor : root.textFieldTextDisabledColor
|
||||
|
||||
placeholderText: textFieldPlaceholderText
|
||||
placeholderText: root.textFieldPlaceholderText
|
||||
placeholderTextColor: "#494B50"
|
||||
|
||||
selectionColor: "#412102"
|
||||
|
@ -79,7 +91,7 @@ Item {
|
|||
|
||||
background: Rectangle {
|
||||
anchors.fill: parent
|
||||
color: "#1c1d21"
|
||||
color: root.enabled ? root.backgroundColor : root.backgroundDisabledColor
|
||||
}
|
||||
|
||||
onTextChanged: {
|
||||
|
@ -98,13 +110,13 @@ Item {
|
|||
textColor: "#D7D8DB"
|
||||
borderWidth: 0
|
||||
|
||||
text: buttonText
|
||||
text: root.buttonText
|
||||
|
||||
Layout.rightMargin: 24
|
||||
|
||||
onClicked: {
|
||||
if (clickedFunc && typeof clickedFunc === "function") {
|
||||
clickedFunc()
|
||||
if (root.clickedFunc && typeof root.clickedFunc === "function") {
|
||||
root.clickedFunc()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -158,7 +158,6 @@ PageType {
|
|||
|
||||
implicitHeight: 40
|
||||
|
||||
rootButtonBorderWidth: 0
|
||||
rootButtonImageColor: "#0E0E11"
|
||||
rootButtonBackgroundColor: "#D7D8DB"
|
||||
|
||||
|
|
176
client/ui/qml/Pages2/PageProtocolCloakSettings.qml
Normal file
176
client/ui/qml/Pages2/PageProtocolCloakSettings.qml
Normal file
|
@ -0,0 +1,176 @@
|
|||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
|
||||
import SortFilterProxyModel 0.2
|
||||
|
||||
import "./"
|
||||
import "../Controls2"
|
||||
import "../Controls2/TextTypes"
|
||||
import "../Config"
|
||||
import "../Components"
|
||||
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
//todo move to main?
|
||||
Connections {
|
||||
target: InstallController
|
||||
|
||||
function onInstallationErrorOccurred(errorMessage) {
|
||||
PageController.showErrorMessage(errorMessage)
|
||||
}
|
||||
|
||||
function onUpdateContainerFinished() {
|
||||
//todo change to notification
|
||||
PageController.showErrorMessage(qsTr("Settings updated successfully"))
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: backButton
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
anchors.topMargin: 20
|
||||
|
||||
BackButtonType {
|
||||
}
|
||||
}
|
||||
|
||||
FlickableType {
|
||||
id: fl
|
||||
anchors.top: backButton.bottom
|
||||
anchors.bottom: parent.bottom
|
||||
contentHeight: content.implicitHeight
|
||||
|
||||
Column {
|
||||
id: content
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
ListView {
|
||||
id: listview
|
||||
|
||||
width: parent.width
|
||||
height: listview.contentItem.height
|
||||
|
||||
clip: true
|
||||
interactive: false
|
||||
|
||||
model: CloakConfigModel
|
||||
|
||||
delegate: Item {
|
||||
implicitWidth: listview.width
|
||||
implicitHeight: col.implicitHeight
|
||||
|
||||
ColumnLayout {
|
||||
id: col
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
anchors.leftMargin: 16
|
||||
anchors.rightMargin: 16
|
||||
|
||||
spacing: 0
|
||||
|
||||
HeaderType {
|
||||
Layout.fillWidth: true
|
||||
|
||||
headerText: qsTr("Cloak settings")
|
||||
}
|
||||
|
||||
TextFieldWithHeaderType {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 32
|
||||
|
||||
headerText: qsTr("Masquerading as traffic from")
|
||||
textFieldText: site
|
||||
|
||||
textField.onEditingFinished: {
|
||||
if (textFieldText !== site) {
|
||||
site = textFieldText
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TextFieldWithHeaderType {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 16
|
||||
|
||||
headerText: qsTr("Port")
|
||||
textFieldText: port
|
||||
|
||||
textField.onEditingFinished: {
|
||||
if (textFieldText !== port) {
|
||||
port = textFieldText
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DropDownType {
|
||||
id: cipherDropDown
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 16
|
||||
implicitHeight: 74
|
||||
|
||||
descriptionText: qsTr("Cipher")
|
||||
headerText: qsTr("Cipher")
|
||||
|
||||
listView: ListViewType {
|
||||
id: cipherListView
|
||||
|
||||
rootWidth: root.width
|
||||
|
||||
model: ListModel {
|
||||
ListElement { name : "chacha20-ietf-poly1305" }
|
||||
ListElement { name : "xchacha20-ietf-poly1305" }
|
||||
ListElement { name : "aes-256-gcm" }
|
||||
ListElement { name : "aes-192-gcm" }
|
||||
ListElement { name : "aes-128-gcm" }
|
||||
}
|
||||
|
||||
clickedFunction: function() {
|
||||
cipherDropDown.text = selectedText
|
||||
cipher = cipherDropDown.text
|
||||
cipherDropDown.menuVisible = false
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
cipherDropDown.text = cipher
|
||||
|
||||
for (var i = 0; i < cipherListView.model.count; i++) {
|
||||
if (cipherListView.model.get(i).name === cipherDropDown.text) {
|
||||
currentIndex = i
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 24
|
||||
Layout.bottomMargin: 24
|
||||
|
||||
text: qsTr("Save and Restart Amnesia")
|
||||
|
||||
onClicked: {
|
||||
forceActiveFocus()
|
||||
PageController.showBusyIndicator(true)
|
||||
InstallController.updateContainer(CloakConfigModel.getConfig())
|
||||
PageController.showBusyIndicator(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
465
client/ui/qml/Pages2/PageProtocolOpenVpnSettings.qml
Normal file
465
client/ui/qml/Pages2/PageProtocolOpenVpnSettings.qml
Normal file
|
@ -0,0 +1,465 @@
|
|||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
|
||||
import SortFilterProxyModel 0.2
|
||||
|
||||
import PageEnum 1.0
|
||||
|
||||
import "./"
|
||||
import "../Controls2"
|
||||
import "../Controls2/TextTypes"
|
||||
import "../Config"
|
||||
import "../Components"
|
||||
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
Connections {
|
||||
target: InstallController
|
||||
|
||||
function onInstallationErrorOccurred(errorMessage) {
|
||||
PageController.showErrorMessage(errorMessage)
|
||||
}
|
||||
|
||||
function onUpdateContainerFinished() {
|
||||
//todo change to notification
|
||||
PageController.showErrorMessage(qsTr("Settings updated successfully"))
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: backButton
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
anchors.topMargin: 20
|
||||
|
||||
BackButtonType {
|
||||
}
|
||||
}
|
||||
|
||||
FlickableType {
|
||||
id: fl
|
||||
anchors.top: backButton.bottom
|
||||
anchors.bottom: parent.bottom
|
||||
contentHeight: content.implicitHeight
|
||||
|
||||
Column {
|
||||
id: content
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
ListView {
|
||||
id: listview
|
||||
|
||||
width: parent.width
|
||||
height: listview.contentItem.height
|
||||
|
||||
clip: true
|
||||
interactive: false
|
||||
|
||||
model: OpenVpnConfigModel
|
||||
|
||||
delegate: Item {
|
||||
implicitWidth: listview.width
|
||||
implicitHeight: col.implicitHeight
|
||||
|
||||
ColumnLayout {
|
||||
id: col
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
anchors.leftMargin: 16
|
||||
anchors.rightMargin: 16
|
||||
|
||||
spacing: 0
|
||||
|
||||
HeaderType {
|
||||
Layout.fillWidth: true
|
||||
|
||||
headerText: qsTr("OpenVPN settings")
|
||||
}
|
||||
|
||||
TextFieldWithHeaderType {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 32
|
||||
|
||||
headerText: qsTr("VPN Addresses Subnet")
|
||||
textFieldText: subnetAddress
|
||||
|
||||
textField.onEditingFinished: {
|
||||
if (textFieldText !== subnetAddress) {
|
||||
subnetAddress = textFieldText
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ParagraphTextType {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 32
|
||||
|
||||
text: qsTr("Network protocol")
|
||||
}
|
||||
|
||||
TransportProtoSelector {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 16
|
||||
rootWidth: root.width
|
||||
|
||||
enabled: isTransportProtoEditable
|
||||
|
||||
currentIndex: {
|
||||
return transportProto === "tcp" ? 1 : 0
|
||||
}
|
||||
|
||||
onCurrentIndexChanged: {
|
||||
if (transportProto === "tcp" && currentIndex === 0) {
|
||||
transportProto = "udp"
|
||||
} else if (transportProto === "udp" && currentIndex === 1) {
|
||||
transportProto = "tcp"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TextFieldWithHeaderType {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 40
|
||||
|
||||
enabled: isPortEditable
|
||||
|
||||
headerText: qsTr("Port")
|
||||
textFieldText: port
|
||||
|
||||
textField.onEditingFinished: {
|
||||
if (textFieldText !== port) {
|
||||
port = textFieldText
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SwitcherType {
|
||||
id: autoNegotiateEncryprionSwitcher
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 24
|
||||
|
||||
text: qsTr("Auto-negotiate encryption")
|
||||
checked: autoNegotiateEncryprion
|
||||
|
||||
onCheckedChanged: {
|
||||
if (checked !== autoNegotiateEncryprion) {
|
||||
autoNegotiateEncryprion = checked
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DropDownType {
|
||||
id: hashDropDown
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 20
|
||||
implicitHeight: 74
|
||||
|
||||
enabled: !autoNegotiateEncryprionSwitcher.checked
|
||||
|
||||
descriptionText: qsTr("Hash")
|
||||
headerText: qsTr("Hash")
|
||||
|
||||
listView: ListViewType {
|
||||
id: hashListView
|
||||
|
||||
rootWidth: root.width
|
||||
|
||||
model: ListModel {
|
||||
ListElement { name : qsTr("SHA512") }
|
||||
ListElement { name : qsTr("SHA384") }
|
||||
ListElement { name : qsTr("SHA256") }
|
||||
ListElement { name : qsTr("SHA3-512") }
|
||||
ListElement { name : qsTr("SHA3-384") }
|
||||
ListElement { name : qsTr("SHA3-256") }
|
||||
ListElement { name : qsTr("whirlpool") }
|
||||
ListElement { name : qsTr("BLAKE2b512") }
|
||||
ListElement { name : qsTr("BLAKE2s256") }
|
||||
ListElement { name : qsTr("SHA1") }
|
||||
}
|
||||
|
||||
clickedFunction: function() {
|
||||
hashDropDown.text = selectedText
|
||||
hash = hashDropDown.text
|
||||
hashDropDown.menuVisible = false
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
hashDropDown.text = hash
|
||||
|
||||
for (var i = 0; i < hashListView.model.count; i++) {
|
||||
if (hashListView.model.get(i).name === hashDropDown.text) {
|
||||
currentIndex = i
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DropDownType {
|
||||
id: cipherDropDown
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 16
|
||||
implicitHeight: 74
|
||||
|
||||
enabled: !autoNegotiateEncryprionSwitcher.checked
|
||||
|
||||
descriptionText: qsTr("Cipher")
|
||||
headerText: qsTr("Cipher")
|
||||
|
||||
listView: ListViewType {
|
||||
id: cipherListView
|
||||
|
||||
rootWidth: root.width
|
||||
|
||||
model: ListModel {
|
||||
ListElement { name : qsTr("AES-256-GCM") }
|
||||
ListElement { name : qsTr("AES-192-GCM") }
|
||||
ListElement { name : qsTr("AES-128-GCM") }
|
||||
ListElement { name : qsTr("AES-256-CBC") }
|
||||
ListElement { name : qsTr("AES-192-CBC") }
|
||||
ListElement { name : qsTr("AES-128-CBC") }
|
||||
ListElement { name : qsTr("ChaCha20-Poly1305") }
|
||||
ListElement { name : qsTr("ARIA-256-CBC") }
|
||||
ListElement { name : qsTr("CAMELLIA-256-CBC") }
|
||||
ListElement { name : qsTr("none") }
|
||||
}
|
||||
|
||||
clickedFunction: function() {
|
||||
cipherDropDown.text = selectedText
|
||||
cipher = cipherDropDown.text
|
||||
cipherDropDown.menuVisible = false
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
cipherDropDown.text = cipher
|
||||
|
||||
for (var i = 0; i < cipherListView.model.count; i++) {
|
||||
if (cipherListView.model.get(i).name === cipherDropDown.text) {
|
||||
currentIndex = i
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 32
|
||||
Layout.preferredHeight: checkboxLayout.implicitHeight
|
||||
color: "#1C1D21"
|
||||
radius: 16
|
||||
|
||||
ColumnLayout {
|
||||
id: checkboxLayout
|
||||
CheckBoxType {
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: qsTr("TLS auth")
|
||||
checked: tlsAuth
|
||||
|
||||
onCheckedChanged: {
|
||||
if (checked !== tlsAuth) {
|
||||
tlsAuth = checked
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DividerType {}
|
||||
|
||||
CheckBoxType {
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: qsTr("Block DNS requests outside of VPN")
|
||||
checked: blockDns
|
||||
|
||||
onCheckedChanged: {
|
||||
if (checked !== blockDns) {
|
||||
blockDns = checked
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SwitcherType {
|
||||
id: additionalClientCommandsSwitcher
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 32
|
||||
|
||||
checked: additionalClientCommands !== ""
|
||||
|
||||
text: qsTr("Additional client configuration commands")
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 16
|
||||
|
||||
height: 148
|
||||
color: "#1C1D21"
|
||||
border.width: 1
|
||||
border.color: "#2C2D30"
|
||||
radius: 16
|
||||
visible: additionalClientCommandsSwitcher.checked
|
||||
|
||||
FlickableType {
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
contentHeight: additionalClientCommandsTextArea.implicitHeight
|
||||
TextArea {
|
||||
id: additionalClientCommandsTextArea
|
||||
|
||||
width: parent.width
|
||||
anchors.topMargin: 16
|
||||
anchors.bottomMargin: 16
|
||||
|
||||
topPadding: 16
|
||||
leftPadding: 16
|
||||
|
||||
color: "#D7D8DB"
|
||||
selectionColor: "#412102"
|
||||
selectedTextColor: "#D7D8DB"
|
||||
placeholderTextColor: "#878B91"
|
||||
|
||||
font.pixelSize: 16
|
||||
font.weight: Font.Medium
|
||||
font.family: "PT Root UI VF"
|
||||
|
||||
placeholderText: qsTr("Commands:")
|
||||
text: additionalClientCommands
|
||||
|
||||
wrapMode: Text.Wrap
|
||||
|
||||
onEditingFinished: {
|
||||
if (additionalClientCommands !== text) {
|
||||
additionalClientCommands = text
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SwitcherType {
|
||||
id: additionalServerCommandsSwitcher
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 16
|
||||
|
||||
checked: additionalServerCommands !== ""
|
||||
|
||||
text: qsTr("Additional server configuration commands")
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 16
|
||||
|
||||
height: 148
|
||||
color: "#1C1D21"
|
||||
border.width: 1
|
||||
border.color: "#2C2D30"
|
||||
radius: 16
|
||||
visible: additionalServerCommandsSwitcher.checked
|
||||
|
||||
FlickableType {
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
contentHeight: additionalServerCommandsTextArea.implicitHeight
|
||||
TextArea {
|
||||
id: additionalServerCommandsTextArea
|
||||
|
||||
width: parent.width
|
||||
anchors.topMargin: 16
|
||||
anchors.bottomMargin: 16
|
||||
|
||||
topPadding: 16
|
||||
leftPadding: 16
|
||||
|
||||
color: "#D7D8DB"
|
||||
selectionColor: "#412102"
|
||||
selectedTextColor: "#D7D8DB"
|
||||
placeholderTextColor: "#878B91"
|
||||
|
||||
font.pixelSize: 16
|
||||
font.weight: Font.Medium
|
||||
font.family: "PT Root UI VF"
|
||||
|
||||
placeholderText: qsTr("Commands:")
|
||||
text: additionalServerCommands
|
||||
|
||||
wrapMode: Text.Wrap
|
||||
|
||||
onEditingFinished: {
|
||||
if (additionalServerCommands !== text) {
|
||||
additionalServerCommands = text
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
Layout.topMargin: 24
|
||||
|
||||
defaultColor: "transparent"
|
||||
hoveredColor: Qt.rgba(1, 1, 1, 0.08)
|
||||
pressedColor: Qt.rgba(1, 1, 1, 0.12)
|
||||
textColor: "#EB5757"
|
||||
|
||||
text: qsTr("Remove OpenVPN")
|
||||
|
||||
onClicked: {
|
||||
questionDrawer.headerText = qsTr("Remove OpenVpn from server?")
|
||||
// questionDrawer.descriptionText = qsTr("")
|
||||
questionDrawer.yesButtonText = qsTr("Continue")
|
||||
questionDrawer.noButtonText = qsTr("Cancel")
|
||||
|
||||
questionDrawer.yesButtonFunction = function() {
|
||||
questionDrawer.visible = false
|
||||
goToPage(PageEnum.PageDeinstalling)
|
||||
ContainersModel.removeCurrentlyProcessedContainer()
|
||||
closePage()
|
||||
closePage() //todo auto close to deinstall page?
|
||||
}
|
||||
questionDrawer.noButtonFunction = function() {
|
||||
questionDrawer.visible = false
|
||||
}
|
||||
questionDrawer.visible = true
|
||||
}
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 24
|
||||
Layout.bottomMargin: 24
|
||||
|
||||
text: qsTr("Save and Restart Amnesia")
|
||||
|
||||
onClicked: {
|
||||
forceActiveFocus()
|
||||
PageController.showBusyIndicator(true)
|
||||
InstallController.updateContainer(OpenVpnConfigModel.getConfig())
|
||||
PageController.showBusyIndicator(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QuestionDrawer {
|
||||
id: questionDrawer
|
||||
}
|
||||
}
|
||||
}
|
162
client/ui/qml/Pages2/PageProtocolShadowSocksSettings.qml
Normal file
162
client/ui/qml/Pages2/PageProtocolShadowSocksSettings.qml
Normal file
|
@ -0,0 +1,162 @@
|
|||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
|
||||
import SortFilterProxyModel 0.2
|
||||
|
||||
import "./"
|
||||
import "../Controls2"
|
||||
import "../Controls2/TextTypes"
|
||||
import "../Config"
|
||||
import "../Components"
|
||||
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
//todo move to main?
|
||||
Connections {
|
||||
target: InstallController
|
||||
|
||||
function onInstallationErrorOccurred(errorMessage) {
|
||||
PageController.showErrorMessage(errorMessage)
|
||||
}
|
||||
|
||||
function onUpdateContainerFinished() {
|
||||
//todo change to notification
|
||||
PageController.showErrorMessage(qsTr("Settings updated successfully"))
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: backButton
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
anchors.topMargin: 20
|
||||
|
||||
BackButtonType {
|
||||
}
|
||||
}
|
||||
|
||||
FlickableType {
|
||||
id: fl
|
||||
anchors.top: backButton.bottom
|
||||
anchors.bottom: parent.bottom
|
||||
contentHeight: content.implicitHeight
|
||||
|
||||
Column {
|
||||
id: content
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
ListView {
|
||||
id: listview
|
||||
|
||||
width: parent.width
|
||||
height: listview.contentItem.height
|
||||
|
||||
clip: true
|
||||
interactive: false
|
||||
|
||||
model: ShadowSocksConfigModel
|
||||
|
||||
delegate: Item {
|
||||
implicitWidth: listview.width
|
||||
implicitHeight: col.implicitHeight
|
||||
|
||||
ColumnLayout {
|
||||
id: col
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
anchors.leftMargin: 16
|
||||
anchors.rightMargin: 16
|
||||
|
||||
spacing: 0
|
||||
|
||||
HeaderType {
|
||||
Layout.fillWidth: true
|
||||
|
||||
headerText: qsTr("ShadowSocks settings")
|
||||
}
|
||||
|
||||
TextFieldWithHeaderType {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 40
|
||||
|
||||
headerText: qsTr("Port")
|
||||
textFieldText: port
|
||||
|
||||
textField.onEditingFinished: {
|
||||
if (textFieldText !== port) {
|
||||
port = textFieldText
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DropDownType {
|
||||
id: cipherDropDown
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 20
|
||||
implicitHeight: 74
|
||||
|
||||
descriptionText: qsTr("Cipher")
|
||||
headerText: qsTr("Cipher")
|
||||
|
||||
listView: ListViewType {
|
||||
id: cipherListView
|
||||
|
||||
rootWidth: root.width
|
||||
|
||||
model: ListModel {
|
||||
ListElement { name : "chacha20-ietf-poly1305" }
|
||||
ListElement { name : "xchacha20-ietf-poly1305" }
|
||||
ListElement { name : "aes-256-gcm" }
|
||||
ListElement { name : "aes-192-gcm" }
|
||||
ListElement { name : "aes-128-gcm" }
|
||||
}
|
||||
|
||||
clickedFunction: function() {
|
||||
cipherDropDown.text = selectedText
|
||||
cipher = cipherDropDown.text
|
||||
cipherDropDown.menuVisible = false
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
cipherDropDown.text = cipher
|
||||
|
||||
for (var i = 0; i < cipherListView.model.count; i++) {
|
||||
if (cipherListView.model.get(i).name === cipherDropDown.text) {
|
||||
currentIndex = i
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 24
|
||||
Layout.bottomMargin: 24
|
||||
|
||||
text: qsTr("Save and Restart Amnesia")
|
||||
|
||||
onClicked: {
|
||||
forceActiveFocus()
|
||||
PageController.showBusyIndicator(true)
|
||||
InstallController.updateContainer(ShadowSocksConfigModel.getConfig())
|
||||
PageController.showBusyIndicator(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,6 +6,7 @@ import SortFilterProxyModel 0.2
|
|||
|
||||
import PageEnum 1.0
|
||||
import ProtocolEnum 1.0
|
||||
import ContainerEnum 1.0
|
||||
import ContainerProps 1.0
|
||||
|
||||
import "./"
|
||||
|
@ -13,15 +14,37 @@ import "../Controls2"
|
|||
import "../Controls2/TextTypes"
|
||||
import "../Config"
|
||||
import "../Components"
|
||||
import "../Components/Protocols"
|
||||
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
ColumnLayout {
|
||||
id: header
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
anchors.topMargin: 20
|
||||
|
||||
BackButtonType {
|
||||
}
|
||||
|
||||
HeaderType {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: 16
|
||||
Layout.rightMargin: 16
|
||||
|
||||
headerText: ContainersModel.getCurrentlyProcessedContainerName() + qsTr(" settings")
|
||||
}
|
||||
}
|
||||
|
||||
FlickableType {
|
||||
id: fl
|
||||
anchors.fill: parent
|
||||
contentHeight: content.height + openVpnSettings.implicitHeight
|
||||
anchors.top: header.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
contentHeight: content.height
|
||||
|
||||
Column {
|
||||
id: content
|
||||
|
@ -29,8 +52,7 @@ PageType {
|
|||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
spacing: 16
|
||||
anchors.topMargin: 32
|
||||
|
||||
ListView {
|
||||
// todo change id naming
|
||||
|
@ -39,16 +61,7 @@ PageType {
|
|||
height: container.contentItem.height
|
||||
clip: true
|
||||
interactive: false
|
||||
model: SortFilterProxyModel {
|
||||
id: proxyContainersModel
|
||||
sourceModel: ContainersModel
|
||||
filters: [
|
||||
ValueFilter {
|
||||
roleName: "isCurrentlyProcessed"
|
||||
value: true
|
||||
}
|
||||
]
|
||||
}
|
||||
model: ProtocolsModel
|
||||
|
||||
delegate: Item {
|
||||
implicitWidth: container.width
|
||||
|
@ -58,24 +71,60 @@ PageType {
|
|||
id: delegateContent
|
||||
|
||||
anchors.fill: parent
|
||||
anchors.rightMargin: 16
|
||||
anchors.leftMargin: 16
|
||||
|
||||
HeaderType {
|
||||
LabelWithButtonType {
|
||||
id: button
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 20
|
||||
|
||||
headerText: name
|
||||
text: protocolName
|
||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||
|
||||
clickedFunction: function() {
|
||||
var containerIndex = ContainersModel.getCurrentlyProcessedContainerIndex()
|
||||
switch (containerIndex) {
|
||||
case ContainerEnum.OpenVpn: OpenVpnConfigModel.updateModel(ProtocolsModel.getConfig()); break;
|
||||
case ContainerEnum.ShadowSocks: ShadowSocksConfigModel.updateModel(ProtocolsModel.getConfig()); break;
|
||||
case ContainerEnum.Cloak: CloakConfigModel.updateModel(ProtocolsModel.getConfig()); break;
|
||||
case ContainerEnum.WireGuard: WireGuardConfigModel.updateModel(ProtocolsModel.getConfig()); break;
|
||||
case ContainerEnum.Ipsec: Ikev2ConfigModel.updateModel(ProtocolsModel.getConfig()); break;
|
||||
}
|
||||
goToPage(protocolPage);
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: button
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
|
||||
DividerType {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OpenVpnSettings {
|
||||
id: openVpnSettings
|
||||
LabelWithButtonType {
|
||||
id: removeButton
|
||||
|
||||
width: parent.width
|
||||
|
||||
text: qsTr("Remove ") + ContainersModel.getCurrentlyProcessedContainerName()
|
||||
textColor: "#EB5757"
|
||||
|
||||
clickedFunction: function() {
|
||||
ContainersModel.removeCurrentlyProcessedContainer()
|
||||
closePage()
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: removeButton
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
|
||||
DividerType {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,8 +14,6 @@ import "../Config"
|
|||
PageType {
|
||||
id: root
|
||||
|
||||
property real progressBarValue: 0
|
||||
|
||||
Connections {
|
||||
target: InstallController
|
||||
|
||||
|
@ -128,8 +126,6 @@ PageType {
|
|||
Layout.fillWidth: true
|
||||
Layout.topMargin: 32
|
||||
|
||||
// value: progressBarValue
|
||||
|
||||
Timer {
|
||||
id: timer
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ PageType {
|
|||
|
||||
FlickableType {
|
||||
id: fl
|
||||
anchors.top: backButton.top
|
||||
anchors.top: backButton.bottom
|
||||
anchors.bottom: parent.bottom
|
||||
contentHeight: content.implicitHeight + content.anchors.topMargin + content.anchors.bottomMargin
|
||||
|
||||
|
|
|
@ -31,8 +31,6 @@ PageType {
|
|||
shareConnectionDrawer.contentVisible = false
|
||||
PageController.showBusyIndicator(true)
|
||||
|
||||
console.log(type)
|
||||
|
||||
switch (type) {
|
||||
case PageShare.ConfigType.AmneziaConnection: ExportController.generateConnectionConfig(); break;
|
||||
case PageShare.ConfigType.AmenziaFullAccess: ExportController.generateFullAccessConfig(); break;
|
||||
|
@ -51,6 +49,7 @@ PageType {
|
|||
}
|
||||
|
||||
property bool showContent: false
|
||||
property bool shareButtonEnabled: false
|
||||
property list<QtObject> connectionTypesModel: [
|
||||
amneziaConnectionFormat
|
||||
]
|
||||
|
@ -180,6 +179,7 @@ PageType {
|
|||
serverSelector.text = selectedText
|
||||
ServersModel.currentlyProcessedIndex = currentIndex
|
||||
protocolSelector.visible = true
|
||||
root.shareButtonEnabled = false
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
|
@ -253,18 +253,24 @@ PageType {
|
|||
currentIndex: 0
|
||||
|
||||
clickedFunction: function () {
|
||||
serverSelector.text += ", " + selectedText
|
||||
shareConnectionDrawer.headerText = qsTr("Connection to ") + serverSelector.text
|
||||
shareConnectionDrawer.configContentHeaderText = qsTr("File with connection settings to ") + serverSelector.text
|
||||
ContainersModel.setCurrentlyProcessedContainerIndex(proxyContainersModel.mapToSource(currentIndex))
|
||||
handler()
|
||||
|
||||
protocolSelector.visible = false
|
||||
serverSelector.menuVisible = false
|
||||
|
||||
fillConnectionTypeModel()
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
handler()
|
||||
}
|
||||
|
||||
function handler() {
|
||||
if (!proxyContainersModel.count) {
|
||||
root.shareButtonEnabled = false
|
||||
return
|
||||
} else {
|
||||
root.shareButtonEnabled = true
|
||||
}
|
||||
|
||||
serverSelector.text += ", " + selectedText
|
||||
shareConnectionDrawer.headerText = qsTr("Connection to ") + serverSelector.text
|
||||
shareConnectionDrawer.configContentHeaderText = qsTr("File with connection settings to ") + serverSelector.text
|
||||
|
@ -336,6 +342,8 @@ PageType {
|
|||
Layout.fillWidth: true
|
||||
Layout.topMargin: 32
|
||||
|
||||
enabled: shareButtonEnabled
|
||||
|
||||
text: qsTr("Share")
|
||||
|
||||
onClicked: {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue