Share WireGuard page
Share IKEv2 page
This commit is contained in:
parent
c6efc5b212
commit
25428c9165
28 changed files with 907 additions and 238 deletions
|
@ -6,6 +6,7 @@
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QTemporaryFile>
|
#include <QTemporaryFile>
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
|
#include <QUuid>
|
||||||
|
|
||||||
#include "sftpdefs.h"
|
#include "sftpdefs.h"
|
||||||
|
|
||||||
|
@ -21,6 +22,7 @@ Ikev2Configurator::ConnectionData Ikev2Configurator::prepareIkev2Config(const Se
|
||||||
connData.host = credentials.hostName;
|
connData.host = credentials.hostName;
|
||||||
connData.clientId = Utils::getRandomString(16);
|
connData.clientId = Utils::getRandomString(16);
|
||||||
connData.password = Utils::getRandomString(16);
|
connData.password = Utils::getRandomString(16);
|
||||||
|
connData.password = "";
|
||||||
|
|
||||||
QString certFileName = "/opt/amnezia/ikev2/clients/" + connData.clientId + ".p12";
|
QString certFileName = "/opt/amnezia/ikev2/clients/" + connData.clientId + ".p12";
|
||||||
|
|
||||||
|
@ -41,8 +43,11 @@ Ikev2Configurator::ConnectionData Ikev2Configurator::prepareIkev2Config(const Se
|
||||||
.arg(certFileName);
|
.arg(certFileName);
|
||||||
e = ServerController::runContainerScript(credentials, container, scriptExportCert);
|
e = ServerController::runContainerScript(credentials, container, scriptExportCert);
|
||||||
|
|
||||||
connData.cert = ServerController::getTextFileFromContainer(container, credentials, certFileName, &e);
|
connData.clientCert = ServerController::getTextFileFromContainer(container, credentials, certFileName, &e);
|
||||||
qDebug() << "Ikev2Configurator::ConnectionData cert size:" << connData.cert.size();
|
connData.caCert = ServerController::getTextFileFromContainer(container, credentials, "/etc/ipsec.d/ca_cert_base64.p12", &e);
|
||||||
|
|
||||||
|
qDebug() << "Ikev2Configurator::ConnectionData client cert size:" << connData.clientCert.size();
|
||||||
|
qDebug() << "Ikev2Configurator::ConnectionData ca cert size:" << connData.caCert.size();
|
||||||
|
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
@ -50,17 +55,62 @@ Ikev2Configurator::ConnectionData Ikev2Configurator::prepareIkev2Config(const Se
|
||||||
QString Ikev2Configurator::genIkev2Config(const ServerCredentials &credentials,
|
QString Ikev2Configurator::genIkev2Config(const ServerCredentials &credentials,
|
||||||
DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode)
|
DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(containerConfig)
|
||||||
|
|
||||||
ConnectionData connData = prepareIkev2Config(credentials, container, errorCode);
|
ConnectionData connData = prepareIkev2Config(credentials, container, errorCode);
|
||||||
if (errorCode && *errorCode) {
|
if (errorCode && *errorCode) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return genIkev2Config(connData);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Ikev2Configurator::genIkev2Config(const ConnectionData &connData)
|
||||||
|
{
|
||||||
QJsonObject config;
|
QJsonObject config;
|
||||||
config[config_key::hostName] = connData.host;
|
config[config_key::hostName] = connData.host;
|
||||||
config[config_key::userName] = connData.clientId;
|
config[config_key::userName] = connData.clientId;
|
||||||
config[config_key::cert] = QString(connData.cert.toBase64());
|
config[config_key::cert] = QString(connData.clientCert.toBase64());
|
||||||
config[config_key::password] = connData.password;
|
config[config_key::password] = connData.password;
|
||||||
|
|
||||||
return QJsonDocument(config).toJson();
|
return QJsonDocument(config).toJson();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString Ikev2Configurator::genMobileConfig(const ConnectionData &connData)
|
||||||
|
{
|
||||||
|
QFile file(":/server_scripts/ipsec/mobileconfig.plist");
|
||||||
|
file.open(QIODevice::ReadOnly);
|
||||||
|
QString config = QString(file.readAll());
|
||||||
|
|
||||||
|
config.replace("$CLIENT_NAME", connData.clientId);
|
||||||
|
config.replace("$UUID1", QUuid::createUuid().toString());
|
||||||
|
config.replace("$SERVER_ADDR", connData.host);
|
||||||
|
|
||||||
|
QString subStr("$(UUID_GEN)");
|
||||||
|
while (config.indexOf(subStr) > 0) {
|
||||||
|
config.replace(config.indexOf(subStr), subStr.size(), QUuid::createUuid().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
config.replace("$P12_BASE64", connData.clientCert.toBase64());
|
||||||
|
config.replace("$CA_BASE64", connData.caCert.toBase64());
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Ikev2Configurator::genStrongSwanConfig(const ConnectionData &connData)
|
||||||
|
{
|
||||||
|
QFile file(":/server_scripts/ipsec/strongswan.profile");
|
||||||
|
file.open(QIODevice::ReadOnly);
|
||||||
|
QString config = QString(file.readAll());
|
||||||
|
|
||||||
|
config.replace("$CLIENT_NAME", connData.clientId);
|
||||||
|
config.replace("$UUID", QUuid::createUuid().toString());
|
||||||
|
config.replace("$SERVER_ADDR", connData.host);
|
||||||
|
|
||||||
|
QByteArray cert = connData.clientCert.toBase64();
|
||||||
|
cert.replace("\r", "").replace("\n", "");
|
||||||
|
config.replace("$P12_BASE64", cert);
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,8 @@ class Ikev2Configurator
|
||||||
public:
|
public:
|
||||||
|
|
||||||
struct ConnectionData {
|
struct ConnectionData {
|
||||||
QByteArray cert; // p12 client cert
|
QByteArray clientCert; // p12 client cert
|
||||||
|
QByteArray caCert; // p12 server cert
|
||||||
QString clientId;
|
QString clientId;
|
||||||
QString password; // certificate password
|
QString password; // certificate password
|
||||||
QString host; // host ip
|
QString host; // host ip
|
||||||
|
@ -21,8 +22,10 @@ public:
|
||||||
static QString genIkev2Config(const ServerCredentials &credentials, DockerContainer container,
|
static QString genIkev2Config(const ServerCredentials &credentials, DockerContainer container,
|
||||||
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
|
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
|
||||||
|
|
||||||
|
static QString genIkev2Config(const ConnectionData &connData);
|
||||||
|
static QString genMobileConfig(const ConnectionData &connData);
|
||||||
|
static QString genStrongSwanConfig(const ConnectionData &connData);
|
||||||
|
|
||||||
private:
|
|
||||||
static ConnectionData prepareIkev2Config(const ServerCredentials &credentials,
|
static ConnectionData prepareIkev2Config(const ServerCredentials &credentials,
|
||||||
DockerContainer container, ErrorCode *errorCode = nullptr);
|
DockerContainer container, ErrorCode *errorCode = nullptr);
|
||||||
};
|
};
|
||||||
|
|
|
@ -72,7 +72,7 @@ QMap<DockerContainer, QString> ContainerProps::containerHumanNames()
|
||||||
{DockerContainer::ShadowSocks, "OpenVpn over ShadowSocks"},
|
{DockerContainer::ShadowSocks, "OpenVpn over ShadowSocks"},
|
||||||
{DockerContainer::Cloak, "OpenVpn over Cloak"},
|
{DockerContainer::Cloak, "OpenVpn over Cloak"},
|
||||||
{DockerContainer::WireGuard, "WireGuard"},
|
{DockerContainer::WireGuard, "WireGuard"},
|
||||||
{DockerContainer::Ipsec, QObject::tr("IPsec container")},
|
{DockerContainer::Ipsec, QObject::tr("IPsec")},
|
||||||
|
|
||||||
{DockerContainer::TorWebSite, QObject::tr("Web site in TOR network")},
|
{DockerContainer::TorWebSite, QObject::tr("Web site in TOR network")},
|
||||||
{DockerContainer::Dns, QObject::tr("DNS Service")},
|
{DockerContainer::Dns, QObject::tr("DNS Service")},
|
||||||
|
|
|
@ -134,9 +134,9 @@ ErrorCode ServerController::runContainerScript(const ServerCredentials &credenti
|
||||||
e = runScript(credentials,
|
e = runScript(credentials,
|
||||||
replaceVars(runner, genVarsForScript(credentials, container)), cbReadStdOut, cbReadStdErr);
|
replaceVars(runner, genVarsForScript(credentials, container)), cbReadStdOut, cbReadStdErr);
|
||||||
|
|
||||||
// QString remover = QString("sudo docker exec -i $CONTAINER_NAME rm %1 ").arg(fileName);
|
QString remover = QString("sudo docker exec -i $CONTAINER_NAME rm %1 ").arg(fileName);
|
||||||
// runScript(credentials,
|
runScript(credentials,
|
||||||
// replaceVars(remover, genVarsForScript(credentials, container)));
|
replaceVars(remover, genVarsForScript(credentials, container)));
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,5 +136,9 @@
|
||||||
<file>ui/qml/Controls/ContextMenu.qml</file>
|
<file>ui/qml/Controls/ContextMenu.qml</file>
|
||||||
<file>ui/qml/Pages/Share/PageShareProtoAmnezia.qml</file>
|
<file>ui/qml/Pages/Share/PageShareProtoAmnezia.qml</file>
|
||||||
<file>ui/qml/Controls/ShareConnectionButtonCopyType.qml</file>
|
<file>ui/qml/Controls/ShareConnectionButtonCopyType.qml</file>
|
||||||
|
<file>ui/qml/Pages/Share/PageShareProtoWireGuard.qml</file>
|
||||||
|
<file>server_scripts/ipsec/mobileconfig.plist</file>
|
||||||
|
<file>ui/qml/Pages/Share/PageShareProtoIkev2.qml</file>
|
||||||
|
<file>server_scripts/ipsec/strongswan.profile</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
@ -222,6 +222,8 @@ certutil -z <(head -c 1024 /dev/urandom) \
|
||||||
--extKeyUsage serverAuth \
|
--extKeyUsage serverAuth \
|
||||||
--extSAN "ip:$SERVER_IP_ADDRESS,dns:$SERVER_IP_ADDRESS"
|
--extSAN "ip:$SERVER_IP_ADDRESS,dns:$SERVER_IP_ADDRESS"
|
||||||
|
|
||||||
|
certutil -L -d sql:/etc/ipsec.d -n "IKEv2 VPN CA" -a | grep -v CERTIFICATE > /etc/ipsec.d/ca_cert_base64.p12
|
||||||
|
|
||||||
cat > /etc/ipsec.d/ikev2.conf <<EOF
|
cat > /etc/ipsec.d/ikev2.conf <<EOF
|
||||||
conn ikev2-cp
|
conn ikev2-cp
|
||||||
left=%defaultroute
|
left=%defaultroute
|
||||||
|
|
145
client/server_scripts/ipsec/mobileconfig.plist
Normal file
145
client/server_scripts/ipsec/mobileconfig.plist
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>PayloadContent</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>IKEv2</key>
|
||||||
|
<dict>
|
||||||
|
<key>AuthenticationMethod</key>
|
||||||
|
<string>Certificate</string>
|
||||||
|
<key>ChildSecurityAssociationParameters</key>
|
||||||
|
<dict>
|
||||||
|
<key>DiffieHellmanGroup</key>
|
||||||
|
<integer>14</integer>
|
||||||
|
<key>EncryptionAlgorithm</key>
|
||||||
|
<string>AES-128-GCM</string>
|
||||||
|
<key>LifeTimeInMinutes</key>
|
||||||
|
<integer>1410</integer>
|
||||||
|
</dict>
|
||||||
|
<key>DeadPeerDetectionRate</key>
|
||||||
|
<string>Medium</string>
|
||||||
|
<key>DisableRedirect</key>
|
||||||
|
<true/>
|
||||||
|
<key>EnableCertificateRevocationCheck</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
<key>EnablePFS</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
<key>IKESecurityAssociationParameters</key>
|
||||||
|
<dict>
|
||||||
|
<key>DiffieHellmanGroup</key>
|
||||||
|
<integer>14</integer>
|
||||||
|
<key>EncryptionAlgorithm</key>
|
||||||
|
<string>AES-256</string>
|
||||||
|
<key>IntegrityAlgorithm</key>
|
||||||
|
<string>SHA2-256</string>
|
||||||
|
<key>LifeTimeInMinutes</key>
|
||||||
|
<integer>1410</integer>
|
||||||
|
</dict>
|
||||||
|
<key>LocalIdentifier</key>
|
||||||
|
<string>$CLIENT_NAME</string>
|
||||||
|
<key>PayloadCertificateUUID</key>
|
||||||
|
<string>$UUID1</string>
|
||||||
|
<key>OnDemandEnabled</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
<key>OnDemandRules</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>Action</key>
|
||||||
|
<string>Connect</string>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>RemoteAddress</key>
|
||||||
|
<string>$SERVER_ADDR</string>
|
||||||
|
<key>RemoteIdentifier</key>
|
||||||
|
<string>$SERVER_ADDR</string>
|
||||||
|
<key>UseConfigurationAttributeInternalIPSubnet</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<key>IPv4</key>
|
||||||
|
<dict>
|
||||||
|
<key>OverridePrimary</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
</dict>
|
||||||
|
<key>PayloadDescription</key>
|
||||||
|
<string>Configures VPN settings</string>
|
||||||
|
<key>PayloadDisplayName</key>
|
||||||
|
<string>VPN</string>
|
||||||
|
<key>PayloadOrganization</key>
|
||||||
|
<string>IKEv2 VPN</string>
|
||||||
|
<key>PayloadIdentifier</key>
|
||||||
|
<string>com.apple.vpn.managed.$(UUID_GEN)</string>
|
||||||
|
<key>PayloadType</key>
|
||||||
|
<string>com.apple.vpn.managed</string>
|
||||||
|
<key>PayloadUUID</key>
|
||||||
|
<string>$(UUID_GEN)</string>
|
||||||
|
<key>PayloadVersion</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>Proxies</key>
|
||||||
|
<dict>
|
||||||
|
<key>HTTPEnable</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
<key>HTTPSEnable</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<key>UserDefinedName</key>
|
||||||
|
<string>$SERVER_ADDR</string>
|
||||||
|
<key>VPNType</key>
|
||||||
|
<string>IKEv2</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>PayloadCertificateFileName</key>
|
||||||
|
<string>$CLIENT_NAME</string>
|
||||||
|
<key>PayloadContent</key>
|
||||||
|
<data>
|
||||||
|
$P12_BASE64
|
||||||
|
</data>
|
||||||
|
<key>PayloadDescription</key>
|
||||||
|
<string>Adds a PKCS#12-formatted certificate</string>
|
||||||
|
<key>PayloadDisplayName</key>
|
||||||
|
<string>$CLIENT_NAME</string>
|
||||||
|
<key>PayloadIdentifier</key>
|
||||||
|
<string>com.apple.security.pkcs12.$(UUID_GEN)</string>
|
||||||
|
<key>PayloadType</key>
|
||||||
|
<string>com.apple.security.pkcs12</string>
|
||||||
|
<key>PayloadUUID</key>
|
||||||
|
<string>$UUID1</string>
|
||||||
|
<key>PayloadVersion</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>PayloadContent</key>
|
||||||
|
<data>
|
||||||
|
$CA_BASE64
|
||||||
|
</data>
|
||||||
|
<key>PayloadCertificateFileName</key>
|
||||||
|
<string>ikev2vpnca</string>
|
||||||
|
<key>PayloadDescription</key>
|
||||||
|
<string>Adds a CA root certificate</string>
|
||||||
|
<key>PayloadDisplayName</key>
|
||||||
|
<string>Certificate Authority (CA)</string>
|
||||||
|
<key>PayloadIdentifier</key>
|
||||||
|
<string>com.apple.security.root.$(UUID_GEN)</string>
|
||||||
|
<key>PayloadType</key>
|
||||||
|
<string>com.apple.security.root</string>
|
||||||
|
<key>PayloadUUID</key>
|
||||||
|
<string>$(UUID_GEN)</string>
|
||||||
|
<key>PayloadVersion</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>PayloadDisplayName</key>
|
||||||
|
<string>IKEv2 VPN ($SERVER_ADDR)</string>
|
||||||
|
<key>PayloadIdentifier</key>
|
||||||
|
<string>com.apple.vpn.managed.$(UUID_GEN)</string>
|
||||||
|
<key>PayloadRemovalDisallowed</key>
|
||||||
|
<false/>
|
||||||
|
<key>PayloadType</key>
|
||||||
|
<string>Configuration</string>
|
||||||
|
<key>PayloadUUID</key>
|
||||||
|
<string>$(UUID_GEN)</string>
|
||||||
|
<key>PayloadVersion</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
14
client/server_scripts/ipsec/strongswan.profile
Normal file
14
client/server_scripts/ipsec/strongswan.profile
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"uuid": "$UUID",
|
||||||
|
"name": "IKEv2 VPN ($SERVER_ADDR)",
|
||||||
|
"type": "ikev2-cert",
|
||||||
|
"remote": {
|
||||||
|
"addr": "$SERVER_ADDR"
|
||||||
|
},
|
||||||
|
"local": {
|
||||||
|
"p12": "$P12_BASE64",
|
||||||
|
"rsa-pss": "true"
|
||||||
|
},
|
||||||
|
"ike-proposal": "aes256-sha256-modp2048",
|
||||||
|
"esp-proposal": "aes128gcm16"
|
||||||
|
}
|
|
@ -24,7 +24,7 @@ enum class Page {Start = 0, NewServer, NewServerProtocols, Vpn,
|
||||||
Wizard, WizardLow, WizardMedium, WizardHigh, WizardVpnMode, ServerConfiguringProgress,
|
Wizard, WizardLow, WizardMedium, WizardHigh, WizardVpnMode, ServerConfiguringProgress,
|
||||||
GeneralSettings, AppSettings, NetworkSettings, ServerSettings,
|
GeneralSettings, AppSettings, NetworkSettings, ServerSettings,
|
||||||
ServerContainers, ServersList, ShareConnection, Sites,
|
ServerContainers, ServersList, ShareConnection, Sites,
|
||||||
ProtocolSettings};
|
ProtocolSettings, ProtocolShare};
|
||||||
Q_ENUM_NS(Page)
|
Q_ENUM_NS(Page)
|
||||||
|
|
||||||
static void declareQmlPageEnum() {
|
static void declareQmlPageEnum() {
|
||||||
|
|
|
@ -34,6 +34,6 @@ void GeneralSettingsLogic::onPushButtonGeneralSettingsShareConnectionClicked()
|
||||||
qobject_cast<ProtocolsModel *>(uiLogic()->protocolsModel())->setSelectedServerIndex(uiLogic()->selectedServerIndex);
|
qobject_cast<ProtocolsModel *>(uiLogic()->protocolsModel())->setSelectedServerIndex(uiLogic()->selectedServerIndex);
|
||||||
qobject_cast<ProtocolsModel *>(uiLogic()->protocolsModel())->setSelectedDockerContainer(uiLogic()->selectedDockerContainer);
|
qobject_cast<ProtocolsModel *>(uiLogic()->protocolsModel())->setSelectedDockerContainer(uiLogic()->selectedDockerContainer);
|
||||||
|
|
||||||
uiLogic()->shareConnectionLogic()->updateSharingPage(uiLogic()->selectedServerIndex, m_settings.serverCredentials(uiLogic()->selectedServerIndex), uiLogic()->selectedDockerContainer);
|
uiLogic()->shareConnectionLogic()->updateSharingPage(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
|
||||||
emit uiLogic()->goToPage(Page::ShareConnection);
|
emit uiLogic()->goToPage(Page::ShareConnection);
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ void ServerContainersLogic::onPushButtonDefaultClicked(DockerContainer c)
|
||||||
|
|
||||||
void ServerContainersLogic::onPushButtonShareClicked(DockerContainer c)
|
void ServerContainersLogic::onPushButtonShareClicked(DockerContainer c)
|
||||||
{
|
{
|
||||||
uiLogic()->shareConnectionLogic()->updateSharingPage(uiLogic()->selectedServerIndex, m_settings.serverCredentials(uiLogic()->selectedServerIndex), c);
|
uiLogic()->shareConnectionLogic()->updateSharingPage(uiLogic()->selectedServerIndex, c);
|
||||||
emit uiLogic()->goToPage(Page::ShareConnection);
|
emit uiLogic()->goToPage(Page::ShareConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -126,6 +126,6 @@ void ServerSettingsLogic::onLineEditDescriptionEditingFinished()
|
||||||
|
|
||||||
void ServerSettingsLogic::onPushButtonShareFullClicked()
|
void ServerSettingsLogic::onPushButtonShareFullClicked()
|
||||||
{
|
{
|
||||||
uiLogic()->shareConnectionLogic()->updateSharingPage(uiLogic()->selectedServerIndex, m_settings.serverCredentials(uiLogic()->selectedServerIndex), DockerContainer::None);
|
uiLogic()->shareConnectionLogic()->updateSharingPage(uiLogic()->selectedServerIndex, DockerContainer::None);
|
||||||
emit uiLogic()->goToShareProtocolPage(Protocol::Any);
|
emit uiLogic()->goToShareProtocolPage(Protocol::Any);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
#include "configurators/vpn_configurator.h"
|
#include "configurators/vpn_configurator.h"
|
||||||
#include "configurators/openvpn_configurator.h"
|
#include "configurators/openvpn_configurator.h"
|
||||||
#include "configurators/shadowsocks_configurator.h"
|
#include "configurators/shadowsocks_configurator.h"
|
||||||
|
#include "configurators/wireguard_configurator.h"
|
||||||
|
#include "configurators/ikev2_configurator.h"
|
||||||
#include "configurators/ssh_configurator.h"
|
#include "configurators/ssh_configurator.h"
|
||||||
|
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
|
@ -25,20 +27,30 @@ ShareConnectionLogic::ShareConnectionLogic(UiLogic *logic, QObject *parent):
|
||||||
m_textEditShareOpenVpnCodeText{},
|
m_textEditShareOpenVpnCodeText{},
|
||||||
m_lineEditShareShadowSocksStringText{},
|
m_lineEditShareShadowSocksStringText{},
|
||||||
m_shareShadowSocksQrCodeText{},
|
m_shareShadowSocksQrCodeText{},
|
||||||
m_labelShareShadowSocksServerText{},
|
|
||||||
m_labelShareShadowSocksPortText{},
|
|
||||||
m_labelShareShadowSocksMethodText{},
|
|
||||||
m_labelShareShadowSocksPasswordText{},
|
|
||||||
m_textEditShareCloakText{},
|
m_textEditShareCloakText{},
|
||||||
m_textEditShareAmneziaCodeText{},
|
m_textEditShareAmneziaCodeText{}
|
||||||
m_pushButtonShareOpenVpnGenerateText{tr("Generate config")}
|
|
||||||
{
|
{
|
||||||
// TODO consider move to Component.onCompleted
|
|
||||||
//updateSharingPage(uiLogic()->selectedServerIndex, m_settings.serverCredentials(uiLogic()->selectedServerIndex), uiLogic()->selectedDockerContainer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShareConnectionLogic::onUpdatePage()
|
void ShareConnectionLogic::onUpdatePage()
|
||||||
{
|
{
|
||||||
|
set_textEditShareAmneziaCodeText(tr(""));
|
||||||
|
set_shareAmneziaQrCodeText("");
|
||||||
|
|
||||||
|
set_textEditShareOpenVpnCodeText("");
|
||||||
|
|
||||||
|
set_shareShadowSocksQrCodeText("");
|
||||||
|
set_textEditShareShadowSocksText("");
|
||||||
|
set_lineEditShareShadowSocksStringText("");
|
||||||
|
|
||||||
|
set_textEditShareCloakText("");
|
||||||
|
|
||||||
|
set_textEditShareWireGuardCodeText("");
|
||||||
|
set_shareWireGuardQrCodeText("");
|
||||||
|
|
||||||
|
set_textEditShareIkev2CertText("");
|
||||||
|
set_textEditShareIkev2MobileConfigText("");
|
||||||
|
set_textEditShareIkev2StrongSwanConfigText("");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShareConnectionLogic::onPushButtonShareAmneziaGenerateClicked()
|
void ShareConnectionLogic::onPushButtonShareAmneziaGenerateClicked()
|
||||||
|
@ -90,7 +102,7 @@ void ShareConnectionLogic::onPushButtonShareAmneziaGenerateClicked()
|
||||||
QString code = QString("vpn://%1").arg(QString(ba.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals)));
|
QString code = QString("vpn://%1").arg(QString(ba.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals)));
|
||||||
set_textEditShareAmneziaCodeText(code);
|
set_textEditShareAmneziaCodeText(code);
|
||||||
|
|
||||||
if (ba.size() < 1024) {
|
if (ba.size() < 2900) {
|
||||||
QImage qr = updateQRCodeImage(ba.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals));
|
QImage qr = updateQRCodeImage(ba.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals));
|
||||||
set_shareAmneziaQrCodeText(imageToBase64(qr));
|
set_shareAmneziaQrCodeText(imageToBase64(qr));
|
||||||
}
|
}
|
||||||
|
@ -98,30 +110,22 @@ void ShareConnectionLogic::onPushButtonShareAmneziaGenerateClicked()
|
||||||
|
|
||||||
void ShareConnectionLogic::onPushButtonShareOpenVpnGenerateClicked()
|
void ShareConnectionLogic::onPushButtonShareOpenVpnGenerateClicked()
|
||||||
{
|
{
|
||||||
set_pushButtonShareOpenVpnGenerateText(tr("Generating..."));
|
|
||||||
|
|
||||||
ServerCredentials credentials = m_settings.serverCredentials(uiLogic()->selectedServerIndex);
|
ServerCredentials credentials = m_settings.serverCredentials(uiLogic()->selectedServerIndex);
|
||||||
const QJsonObject &containerConfig = m_settings.containerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
|
const QJsonObject &containerConfig = m_settings.containerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
|
||||||
|
|
||||||
ErrorCode e = ErrorCode::NoError;
|
ErrorCode e = ErrorCode::NoError;
|
||||||
QString cfg = OpenVpnConfigurator::genOpenVpnConfig(credentials, uiLogic()->selectedDockerContainer, containerConfig, &e);
|
QString cfg = OpenVpnConfigurator::genOpenVpnConfig(credentials, uiLogic()->selectedDockerContainer, containerConfig, &e);
|
||||||
cfg = OpenVpnConfigurator::processConfigWithExportSettings(cfg);
|
cfg = VpnConfigurator::processConfigWithExportSettings(uiLogic()->selectedDockerContainer, Protocol::OpenVpn, cfg);
|
||||||
|
|
||||||
set_textEditShareOpenVpnCodeText(QJsonDocument::fromJson(cfg.toUtf8()).object()[config_key::config].toString());
|
set_textEditShareOpenVpnCodeText(QJsonDocument::fromJson(cfg.toUtf8()).object()[config_key::config].toString());
|
||||||
|
|
||||||
set_pushButtonShareOpenVpnGenerateText(tr("Generate config"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShareConnectionLogic::updateSharingPage(int serverIndex, const ServerCredentials &credentials,
|
void ShareConnectionLogic::onPushButtonShareShadowSocksGenerateClicked()
|
||||||
DockerContainer container)
|
|
||||||
{
|
{
|
||||||
uiLogic()->selectedDockerContainer = container;
|
int serverIndex = uiLogic()->selectedServerIndex;
|
||||||
uiLogic()->selectedServerIndex = serverIndex;
|
DockerContainer container = uiLogic()->selectedDockerContainer;
|
||||||
set_shareFullAccess(container == DockerContainer::None);
|
ServerCredentials credentials = m_settings.serverCredentials(serverIndex);
|
||||||
|
|
||||||
if (! shareFullAccess()) {
|
|
||||||
for (Protocol p : ContainerProps::protocolsForContainer(container)) {
|
|
||||||
if (p == Protocol::ShadowSocks) {
|
|
||||||
QJsonObject protoConfig = m_settings.protocolConfig(serverIndex, container, Protocol::ShadowSocks);
|
QJsonObject protoConfig = m_settings.protocolConfig(serverIndex, container, Protocol::ShadowSocks);
|
||||||
QString cfg = protoConfig.value(config_key::last_config).toString();
|
QString cfg = protoConfig.value(config_key::last_config).toString();
|
||||||
|
|
||||||
|
@ -146,14 +150,23 @@ void ShareConnectionLogic::updateSharingPage(int serverIndex, const ServerCreden
|
||||||
QImage qr = updateQRCodeImage(ssString.toUtf8());
|
QImage qr = updateQRCodeImage(ssString.toUtf8());
|
||||||
set_shareShadowSocksQrCodeText(imageToBase64(qr));
|
set_shareShadowSocksQrCodeText(imageToBase64(qr));
|
||||||
|
|
||||||
set_labelShareShadowSocksServerText(ssConfig.value("server").toString());
|
QString humanString = QString("Server: %3\n"
|
||||||
set_labelShareShadowSocksPortText(ssConfig.value("server_port").toString());
|
"Port: %4\n"
|
||||||
set_labelShareShadowSocksMethodText(ssConfig.value("method").toString());
|
"Encryption: %1\n"
|
||||||
set_labelShareShadowSocksPasswordText(ssConfig.value("password").toString());
|
"Password: %2")
|
||||||
|
.arg(ssConfig.value("method").toString())
|
||||||
|
.arg(ssConfig.value("password").toString())
|
||||||
|
.arg(ssConfig.value("server").toString())
|
||||||
|
.arg(ssConfig.value("server_port").toString());
|
||||||
|
|
||||||
}
|
set_textEditShareShadowSocksText(humanString);
|
||||||
else if (p == Protocol::Cloak) {
|
}
|
||||||
set_textEditShareCloakText(QString(""));
|
|
||||||
|
void ShareConnectionLogic::onPushButtonShareCloakGenerateClicked()
|
||||||
|
{
|
||||||
|
int serverIndex = uiLogic()->selectedServerIndex;
|
||||||
|
DockerContainer container = uiLogic()->selectedDockerContainer;
|
||||||
|
ServerCredentials credentials = m_settings.serverCredentials(serverIndex);
|
||||||
|
|
||||||
QJsonObject protoConfig = m_settings.protocolConfig(serverIndex, container, Protocol::Cloak);
|
QJsonObject protoConfig = m_settings.protocolConfig(serverIndex, container, Protocol::Cloak);
|
||||||
QString cfg = protoConfig.value(config_key::last_config).toString();
|
QString cfg = protoConfig.value(config_key::last_config).toString();
|
||||||
|
@ -163,8 +176,6 @@ void ShareConnectionLogic::updateSharingPage(int serverIndex, const ServerCreden
|
||||||
|
|
||||||
ErrorCode e = ErrorCode::NoError;
|
ErrorCode e = ErrorCode::NoError;
|
||||||
cfg = CloakConfigurator::genCloakConfig(credentials, container, containerConfig, &e);
|
cfg = CloakConfigurator::genCloakConfig(credentials, container, containerConfig, &e);
|
||||||
|
|
||||||
//set_pushButtonShareCloakCopyEnabled(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonObject cloakConfig = QJsonDocument::fromJson(cfg.toUtf8()).object();
|
QJsonObject cloakConfig = QJsonDocument::fromJson(cfg.toUtf8()).object();
|
||||||
|
@ -172,12 +183,57 @@ void ShareConnectionLogic::updateSharingPage(int serverIndex, const ServerCreden
|
||||||
cloakConfig.insert("ProxyMethod", "shadowsocks");
|
cloakConfig.insert("ProxyMethod", "shadowsocks");
|
||||||
|
|
||||||
set_textEditShareCloakText(QJsonDocument(cloakConfig).toJson());
|
set_textEditShareCloakText(QJsonDocument(cloakConfig).toJson());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
void ShareConnectionLogic::onPushButtonShareWireGuardGenerateClicked()
|
||||||
|
{
|
||||||
|
int serverIndex = uiLogic()->selectedServerIndex;
|
||||||
|
DockerContainer container = uiLogic()->selectedDockerContainer;
|
||||||
|
ServerCredentials credentials = m_settings.serverCredentials(serverIndex);
|
||||||
|
|
||||||
set_textEditShareAmneziaCodeText(tr(""));
|
const QJsonObject &containerConfig = m_settings.containerConfig(serverIndex, container);
|
||||||
|
|
||||||
|
ErrorCode e = ErrorCode::NoError;
|
||||||
|
QString cfg = WireguardConfigurator::genWireguardConfig(credentials, container, containerConfig, &e);
|
||||||
|
cfg = VpnConfigurator::processConfigWithExportSettings(container, Protocol::WireGuard, cfg);
|
||||||
|
cfg = QJsonDocument::fromJson(cfg.toUtf8()).object()[config_key::config].toString();
|
||||||
|
|
||||||
|
set_textEditShareWireGuardCodeText(cfg);
|
||||||
|
|
||||||
|
QImage qr = updateQRCodeImage(cfg.toUtf8());
|
||||||
|
set_shareWireGuardQrCodeText(imageToBase64(qr));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShareConnectionLogic::onPushButtonShareIkev2GenerateClicked()
|
||||||
|
{
|
||||||
|
int serverIndex = uiLogic()->selectedServerIndex;
|
||||||
|
DockerContainer container = uiLogic()->selectedDockerContainer;
|
||||||
|
ServerCredentials credentials = m_settings.serverCredentials(serverIndex);
|
||||||
|
|
||||||
|
//const QJsonObject &containerConfig = m_settings.containerConfig(serverIndex, container);
|
||||||
|
|
||||||
|
Ikev2Configurator::ConnectionData connData = Ikev2Configurator::prepareIkev2Config(credentials, container);
|
||||||
|
|
||||||
|
QString cfg = Ikev2Configurator::genIkev2Config(connData);
|
||||||
|
cfg = VpnConfigurator::processConfigWithExportSettings(container, Protocol::Ikev2, cfg);
|
||||||
|
cfg = QJsonDocument::fromJson(cfg.toUtf8()).object()[config_key::cert].toString();
|
||||||
|
|
||||||
|
set_textEditShareIkev2CertText(cfg);
|
||||||
|
|
||||||
|
QString mobileCfg = Ikev2Configurator::genMobileConfig(connData);
|
||||||
|
set_textEditShareIkev2MobileConfigText(mobileCfg);
|
||||||
|
|
||||||
|
QString strongSwanCfg = Ikev2Configurator::genStrongSwanConfig(connData);
|
||||||
|
set_textEditShareIkev2StrongSwanConfigText(strongSwanCfg);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ShareConnectionLogic::updateSharingPage(int serverIndex, DockerContainer container)
|
||||||
|
{
|
||||||
|
uiLogic()->selectedDockerContainer = container;
|
||||||
|
uiLogic()->selectedServerIndex = serverIndex;
|
||||||
|
set_shareFullAccess(container == DockerContainer::None);
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage ShareConnectionLogic::updateQRCodeImage(const QByteArray &data)
|
QImage ShareConnectionLogic::updateQRCodeImage(const QByteArray &data)
|
||||||
|
|
|
@ -17,20 +17,27 @@ public:
|
||||||
AUTO_PROPERTY(QString, shareAmneziaQrCodeText)
|
AUTO_PROPERTY(QString, shareAmneziaQrCodeText)
|
||||||
|
|
||||||
AUTO_PROPERTY(QString, textEditShareOpenVpnCodeText)
|
AUTO_PROPERTY(QString, textEditShareOpenVpnCodeText)
|
||||||
AUTO_PROPERTY(QString, pushButtonShareOpenVpnGenerateText)
|
|
||||||
|
|
||||||
|
AUTO_PROPERTY(QString, textEditShareShadowSocksText)
|
||||||
AUTO_PROPERTY(QString, lineEditShareShadowSocksStringText)
|
AUTO_PROPERTY(QString, lineEditShareShadowSocksStringText)
|
||||||
AUTO_PROPERTY(QString, shareShadowSocksQrCodeText)
|
AUTO_PROPERTY(QString, shareShadowSocksQrCodeText)
|
||||||
AUTO_PROPERTY(QString, labelShareShadowSocksServerText)
|
|
||||||
AUTO_PROPERTY(QString, labelShareShadowSocksPortText)
|
|
||||||
AUTO_PROPERTY(QString, labelShareShadowSocksMethodText)
|
|
||||||
AUTO_PROPERTY(QString, labelShareShadowSocksPasswordText)
|
|
||||||
|
|
||||||
AUTO_PROPERTY(QString, textEditShareCloakText)
|
AUTO_PROPERTY(QString, textEditShareCloakText)
|
||||||
|
|
||||||
|
AUTO_PROPERTY(QString, textEditShareWireGuardCodeText)
|
||||||
|
AUTO_PROPERTY(QString, shareWireGuardQrCodeText)
|
||||||
|
|
||||||
|
AUTO_PROPERTY(QString, textEditShareIkev2CertText)
|
||||||
|
AUTO_PROPERTY(QString, textEditShareIkev2MobileConfigText)
|
||||||
|
AUTO_PROPERTY(QString, textEditShareIkev2StrongSwanConfigText)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Q_INVOKABLE void onPushButtonShareAmneziaGenerateClicked();
|
Q_INVOKABLE void onPushButtonShareAmneziaGenerateClicked();
|
||||||
Q_INVOKABLE void onPushButtonShareOpenVpnGenerateClicked();
|
Q_INVOKABLE void onPushButtonShareOpenVpnGenerateClicked();
|
||||||
|
Q_INVOKABLE void onPushButtonShareShadowSocksGenerateClicked();
|
||||||
|
Q_INVOKABLE void onPushButtonShareCloakGenerateClicked();
|
||||||
|
Q_INVOKABLE void onPushButtonShareWireGuardGenerateClicked();
|
||||||
|
Q_INVOKABLE void onPushButtonShareIkev2GenerateClicked();
|
||||||
|
|
||||||
Q_INVOKABLE virtual void onUpdatePage() override;
|
Q_INVOKABLE virtual void onUpdatePage() override;
|
||||||
|
|
||||||
|
@ -38,8 +45,7 @@ public:
|
||||||
explicit ShareConnectionLogic(UiLogic *uiLogic, QObject *parent = nullptr);
|
explicit ShareConnectionLogic(UiLogic *uiLogic, QObject *parent = nullptr);
|
||||||
~ShareConnectionLogic() = default;
|
~ShareConnectionLogic() = default;
|
||||||
|
|
||||||
void updateSharingPage(int serverIndex, const ServerCredentials &credentials,
|
void updateSharingPage(int serverIndex, DockerContainer container);
|
||||||
DockerContainer container);
|
|
||||||
QImage updateQRCodeImage(const QByteArray &data);
|
QImage updateQRCodeImage(const QByteArray &data);
|
||||||
QString imageToBase64(const QImage &image);
|
QString imageToBase64(const QImage &image);
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,13 @@ import QtQuick 2.12
|
||||||
import QtQuick.Controls 2.12
|
import QtQuick.Controls 2.12
|
||||||
|
|
||||||
ShareConnectionButtonType {
|
ShareConnectionButtonType {
|
||||||
readonly property string start_text: qsTr("Copy")
|
property string start_text: qsTr("Copy")
|
||||||
readonly property string end_text: qsTr("Copied")
|
property string end_text: qsTr("Copied")
|
||||||
|
|
||||||
|
property string copyText
|
||||||
|
|
||||||
|
enabled: copyText.length > 0
|
||||||
|
visible: copyText.length > 0
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
id: timer
|
id: timer
|
||||||
|
@ -16,5 +21,6 @@ ShareConnectionButtonType {
|
||||||
onClicked: {
|
onClicked: {
|
||||||
text = end_text
|
text = end_text
|
||||||
timer.running = true
|
timer.running = true
|
||||||
|
UiLogic.copyToClipboard(copyText)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,8 @@ import QtQuick 2.12
|
||||||
import QtQuick.Controls 2.12
|
import QtQuick.Controls 2.12
|
||||||
import Qt.labs.platform 1.0
|
import Qt.labs.platform 1.0
|
||||||
|
|
||||||
|
import "../Config"
|
||||||
|
|
||||||
Flickable
|
Flickable
|
||||||
{
|
{
|
||||||
property alias textArea: root
|
property alias textArea: root
|
||||||
|
@ -44,6 +46,18 @@ Flickable
|
||||||
return "#A7A7A7"
|
return "#A7A7A7"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MouseArea {
|
||||||
|
// anchors.fill: root
|
||||||
|
// enabled: GC.isDesktop()
|
||||||
|
// acceptedButtons: Qt.RightButton
|
||||||
|
// onClicked: contextMenu.open()
|
||||||
|
// }
|
||||||
|
|
||||||
|
// ContextMenu {
|
||||||
|
// id: contextMenu
|
||||||
|
// textObj: root
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,6 @@ PageBase {
|
||||||
height: 40
|
height: 40
|
||||||
width: tb_c.width - 10
|
width: tb_c.width - 10
|
||||||
onClicked: UiLogic.onGotoShareProtocolPage(proxyProtocolsModel.mapToSource(index))
|
onClicked: UiLogic.onGotoShareProtocolPage(proxyProtocolsModel.mapToSource(index))
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,12 +9,6 @@ import "../../Config"
|
||||||
PageShareProtocolBase {
|
PageShareProtocolBase {
|
||||||
id: root
|
id: root
|
||||||
protocol: ProtocolEnum.Any
|
protocol: ProtocolEnum.Any
|
||||||
logic: ShareConnectionLogic
|
|
||||||
|
|
||||||
readonly property string generateConfigText: qsTr("Generate config")
|
|
||||||
readonly property string generatingConfigText: qsTr("Generating config...")
|
|
||||||
readonly property string showConfigText: qsTr("Show config")
|
|
||||||
property bool genConfigProcess: false
|
|
||||||
|
|
||||||
BackButton {
|
BackButton {
|
||||||
id: back
|
id: back
|
||||||
|
@ -66,7 +60,6 @@ New encryption keys pair will be generated.")
|
||||||
}
|
}
|
||||||
|
|
||||||
ShareConnectionButtonType {
|
ShareConnectionButtonType {
|
||||||
id: pb_gen
|
|
||||||
Layout.topMargin: 20
|
Layout.topMargin: 20
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: 40
|
Layout.preferredHeight: 40
|
||||||
|
@ -102,15 +95,12 @@ New encryption keys pair will be generated.")
|
||||||
|
|
||||||
|
|
||||||
ShareConnectionButtonCopyType {
|
ShareConnectionButtonCopyType {
|
||||||
id: pb_copy
|
|
||||||
Layout.bottomMargin: 10
|
Layout.bottomMargin: 10
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: 40
|
Layout.preferredHeight: 40
|
||||||
enabled: tfShareCode.textArea.length > 0
|
copyText: tfShareCode.textArea.text
|
||||||
visible: tfShareCode.textArea.length > 0
|
|
||||||
}
|
}
|
||||||
ShareConnectionButtonType {
|
ShareConnectionButtonType {
|
||||||
id: pb_save
|
|
||||||
Layout.bottomMargin: 10
|
Layout.bottomMargin: 10
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: 40
|
Layout.preferredHeight: 40
|
||||||
|
@ -135,7 +125,7 @@ New encryption keys pair will be generated.")
|
||||||
|
|
||||||
LabelType {
|
LabelType {
|
||||||
height: 20
|
height: 20
|
||||||
text: qsTr("Config to long to be displayed as QR code")
|
text: qsTr("Config too long to be displayed as QR code")
|
||||||
visible: ShareConnectionLogic.shareAmneziaQrCodeText.length == 0 && tfShareCode.textArea.length > 0
|
visible: ShareConnectionLogic.shareAmneziaQrCodeText.length == 0 && tfShareCode.textArea.length > 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@ import "../../Config"
|
||||||
PageShareProtocolBase {
|
PageShareProtocolBase {
|
||||||
id: root
|
id: root
|
||||||
protocol: ProtocolEnum.Cloak
|
protocol: ProtocolEnum.Cloak
|
||||||
logic: UiLogic.protocolLogic(protocol)
|
|
||||||
|
|
||||||
BackButton {
|
BackButton {
|
||||||
id: back
|
id: back
|
||||||
|
@ -19,25 +18,93 @@ PageShareProtocolBase {
|
||||||
text: qsTr("Share Cloak Settings")
|
text: qsTr("Share Cloak Settings")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Flickable {
|
||||||
TextAreaType {
|
id: fl
|
||||||
|
width: root.width
|
||||||
anchors.top: caption.bottom
|
anchors.top: caption.bottom
|
||||||
anchors.topMargin: 20
|
anchors.topMargin: 20
|
||||||
anchors.bottom: pb_save.top
|
anchors.bottom: root.bottom
|
||||||
anchors.bottomMargin: 20
|
anchors.bottomMargin: 20
|
||||||
anchors.horizontalCenter: root.horizontalCenter
|
anchors.left: root.left
|
||||||
width: parent.width - 60
|
anchors.leftMargin: 30
|
||||||
|
anchors.right: root.right
|
||||||
|
anchors.rightMargin: 30
|
||||||
|
|
||||||
|
contentHeight: content.height
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: content
|
||||||
|
enabled: logic.pageEnabled
|
||||||
|
anchors.top: content.bottom
|
||||||
|
anchors.topMargin: 20
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
|
||||||
|
|
||||||
|
LabelType {
|
||||||
|
id: lb_desc
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 10
|
||||||
|
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
text: qsTr("Note: Cloak protocol using same password for all connections")
|
||||||
|
}
|
||||||
|
|
||||||
|
ShareConnectionButtonType {
|
||||||
|
Layout.topMargin: 10
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: 40
|
||||||
|
|
||||||
|
text: genConfigProcess ? generatingConfigText : generateConfigText
|
||||||
|
onClicked: {
|
||||||
|
enabled = false
|
||||||
|
genConfigProcess = true
|
||||||
|
ShareConnectionLogic.onPushButtonShareCloakGenerateClicked()
|
||||||
|
enabled = true
|
||||||
|
genConfigProcess = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TextAreaType {
|
||||||
|
id: tfShareCode
|
||||||
|
|
||||||
|
Layout.topMargin: 20
|
||||||
|
Layout.bottomMargin: 20
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: 200
|
||||||
|
|
||||||
textArea.readOnly: true
|
textArea.readOnly: true
|
||||||
textArea.text: ShareConnectionLogic.textEditShareCloakText
|
textArea.text: ShareConnectionLogic.textEditShareCloakText
|
||||||
|
|
||||||
|
visible: tfShareCode.textArea.length > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
ShareConnectionButtonCopyType {
|
ShareConnectionButtonCopyType {
|
||||||
id: pb_save
|
Layout.bottomMargin: 10
|
||||||
anchors.bottom: root.bottom
|
Layout.fillWidth: true
|
||||||
anchors.bottomMargin: 10
|
Layout.preferredHeight: 40
|
||||||
anchors.horizontalCenter: root.horizontalCenter
|
|
||||||
width: parent.width - 60
|
copyText: tfShareCode.textArea.text
|
||||||
//enabled: ShareConnectionLogic.pushButtonShareCloakCopyEnabled
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ShareConnectionButtonType {
|
||||||
|
Layout.bottomMargin: 10
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: 40
|
||||||
|
|
||||||
|
text: qsTr("Save to file")
|
||||||
|
enabled: tfShareCode.textArea.length > 0
|
||||||
|
visible: tfShareCode.textArea.length > 0
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
UiLogic.saveTextFile(qsTr("Save AmneziaVPN config"), "*.json", tfShareCode.textArea.text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
141
client/ui/qml/Pages/Share/PageShareProtoIkev2.qml
Normal file
141
client/ui/qml/Pages/Share/PageShareProtoIkev2.qml
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
import QtQuick 2.12
|
||||||
|
import QtQuick.Controls 2.12
|
||||||
|
import QtQuick.Layouts 1.15
|
||||||
|
import ProtocolEnum 1.0
|
||||||
|
import "../"
|
||||||
|
import "../../Controls"
|
||||||
|
import "../../Config"
|
||||||
|
|
||||||
|
PageShareProtocolBase {
|
||||||
|
id: root
|
||||||
|
protocol: ProtocolEnum.Ikev2
|
||||||
|
|
||||||
|
BackButton {
|
||||||
|
id: back
|
||||||
|
}
|
||||||
|
Caption {
|
||||||
|
id: caption
|
||||||
|
text: qsTr("Share IKEv2 Settings")
|
||||||
|
}
|
||||||
|
|
||||||
|
TextAreaType {
|
||||||
|
id: tfCert
|
||||||
|
textArea.readOnly: true
|
||||||
|
textArea.text: ShareConnectionLogic.textEditShareIkev2CertText
|
||||||
|
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
TextAreaType {
|
||||||
|
id: tfMobileConfig
|
||||||
|
textArea.readOnly: true
|
||||||
|
textArea.text: ShareConnectionLogic.textEditShareIkev2MobileConfigText
|
||||||
|
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
TextAreaType {
|
||||||
|
id: tfStrongSwanConfig
|
||||||
|
textArea.readOnly: true
|
||||||
|
textArea.text: ShareConnectionLogic.textEditShareIkev2StrongSwanConfigText
|
||||||
|
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
Flickable {
|
||||||
|
id: fl
|
||||||
|
width: root.width
|
||||||
|
anchors.top: caption.bottom
|
||||||
|
anchors.topMargin: 20
|
||||||
|
anchors.bottom: root.bottom
|
||||||
|
anchors.bottomMargin: 20
|
||||||
|
anchors.left: root.left
|
||||||
|
anchors.leftMargin: 30
|
||||||
|
anchors.right: root.right
|
||||||
|
anchors.rightMargin: 30
|
||||||
|
|
||||||
|
contentHeight: content.height
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: content
|
||||||
|
enabled: logic.pageEnabled
|
||||||
|
anchors.top: content.bottom
|
||||||
|
anchors.topMargin: 20
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
|
||||||
|
// LabelType {
|
||||||
|
// id: lb_desc
|
||||||
|
// Layout.fillWidth: true
|
||||||
|
// Layout.topMargin: 10
|
||||||
|
|
||||||
|
// horizontalAlignment: Text.AlignHCenter
|
||||||
|
|
||||||
|
// wrapMode: Text.Wrap
|
||||||
|
// text: qsTr("Note: ShadowSocks protocol using same password for all connections")
|
||||||
|
// }
|
||||||
|
|
||||||
|
ShareConnectionButtonType {
|
||||||
|
Layout.topMargin: 10
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: 40
|
||||||
|
|
||||||
|
text: genConfigProcess ? generatingConfigText : generateConfigText
|
||||||
|
onClicked: {
|
||||||
|
enabled = false
|
||||||
|
genConfigProcess = true
|
||||||
|
ShareConnectionLogic.onPushButtonShareIkev2GenerateClicked()
|
||||||
|
enabled = true
|
||||||
|
genConfigProcess = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ShareConnectionButtonType {
|
||||||
|
Layout.topMargin: 30
|
||||||
|
Layout.bottomMargin: 10
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: 40
|
||||||
|
width: parent.width - 60
|
||||||
|
|
||||||
|
text: qsTr("Export p12 certificate")
|
||||||
|
enabled: tfCert.textArea.length > 0
|
||||||
|
visible: tfCert.textArea.length > 0
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
UiLogic.saveTextFile(qsTr("Export p12 certificate"), "*.p12", tfCert.textArea.text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ShareConnectionButtonType {
|
||||||
|
Layout.bottomMargin: 10
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: 40
|
||||||
|
width: parent.width - 60
|
||||||
|
|
||||||
|
text: qsTr("Export config for Apple")
|
||||||
|
enabled: tfMobileConfig.textArea.length > 0
|
||||||
|
visible: tfMobileConfig.textArea.length > 0
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
UiLogic.saveTextFile(qsTr("Export config for Apple"), "*.plist", tfMobileConfig.textArea.text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ShareConnectionButtonType {
|
||||||
|
Layout.bottomMargin: 10
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: 40
|
||||||
|
width: parent.width - 60
|
||||||
|
|
||||||
|
text: qsTr("Export config for StrongSwan")
|
||||||
|
enabled: tfStrongSwanConfig.textArea.length > 0
|
||||||
|
visible: tfStrongSwanConfig.textArea.length > 0
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
UiLogic.saveTextFile(qsTr("Export config for StrongSwan"), "*.profile", tfStrongSwanConfig.textArea.text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,7 +9,6 @@ import "../../Config"
|
||||||
PageShareProtocolBase {
|
PageShareProtocolBase {
|
||||||
id: root
|
id: root
|
||||||
protocol: ProtocolEnum.OpenVpn
|
protocol: ProtocolEnum.OpenVpn
|
||||||
logic: ShareConnectionLogic
|
|
||||||
|
|
||||||
BackButton {
|
BackButton {
|
||||||
id: back
|
id: back
|
||||||
|
@ -19,58 +18,90 @@ PageShareProtocolBase {
|
||||||
text: qsTr("Share OpenVPN Settings")
|
text: qsTr("Share OpenVPN Settings")
|
||||||
}
|
}
|
||||||
|
|
||||||
TextAreaType {
|
Flickable {
|
||||||
id: tfShareCode
|
id: fl
|
||||||
|
width: root.width
|
||||||
anchors.top: caption.bottom
|
anchors.top: caption.bottom
|
||||||
anchors.topMargin: 20
|
anchors.topMargin: 20
|
||||||
anchors.bottom: pb_gen.top
|
anchors.bottom: root.bottom
|
||||||
anchors.bottomMargin: 20
|
anchors.bottomMargin: 20
|
||||||
|
anchors.left: root.left
|
||||||
|
anchors.leftMargin: 30
|
||||||
|
anchors.right: root.right
|
||||||
|
anchors.rightMargin: 30
|
||||||
|
|
||||||
anchors.horizontalCenter: root.horizontalCenter
|
contentHeight: content.height
|
||||||
width: parent.width - 60
|
clip: true
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: content
|
||||||
|
enabled: logic.pageEnabled
|
||||||
|
anchors.top: content.bottom
|
||||||
|
anchors.topMargin: 20
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
|
||||||
|
|
||||||
|
LabelType {
|
||||||
|
id: lb_desc
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 10
|
||||||
|
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
text: qsTr("New encryption keys pair will be generated.")
|
||||||
|
}
|
||||||
|
|
||||||
|
ShareConnectionButtonType {
|
||||||
|
Layout.topMargin: 20
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: 40
|
||||||
|
|
||||||
|
text: genConfigProcess ? generatingConfigText : generateConfigText
|
||||||
|
onClicked: {
|
||||||
|
enabled = false
|
||||||
|
genConfigProcess = true
|
||||||
|
ShareConnectionLogic.onPushButtonShareOpenVpnGenerateClicked()
|
||||||
|
genConfigProcess = false
|
||||||
|
enabled = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TextAreaType {
|
||||||
|
id: tfShareCode
|
||||||
|
Layout.topMargin: 20
|
||||||
|
Layout.preferredHeight: 200
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
textArea.readOnly: true
|
textArea.readOnly: true
|
||||||
|
|
||||||
textArea.verticalAlignment: Text.AlignTop
|
textArea.verticalAlignment: Text.AlignTop
|
||||||
textArea.text: ShareConnectionLogic.textEditShareOpenVpnCodeText
|
textArea.text: ShareConnectionLogic.textEditShareOpenVpnCodeText
|
||||||
|
|
||||||
|
visible: tfShareCode.textArea.length > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ShareConnectionButtonType {
|
|
||||||
id: pb_gen
|
|
||||||
anchors.bottom: pb_copy.top
|
|
||||||
anchors.bottomMargin: 10
|
|
||||||
anchors.horizontalCenter: root.horizontalCenter
|
|
||||||
width: parent.width - 60
|
|
||||||
|
|
||||||
text: ShareConnectionLogic.pushButtonShareOpenVpnGenerateText
|
|
||||||
onClicked: {
|
|
||||||
enabled = false
|
|
||||||
ShareConnectionLogic.onPushButtonShareOpenVpnGenerateClicked()
|
|
||||||
enabled = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ShareConnectionButtonCopyType {
|
ShareConnectionButtonCopyType {
|
||||||
id: pb_copy
|
Layout.preferredHeight: 40
|
||||||
anchors.bottom: pb_save.top
|
Layout.fillWidth: true
|
||||||
anchors.bottomMargin: 10
|
|
||||||
anchors.horizontalCenter: root.horizontalCenter
|
|
||||||
width: parent.width - 60
|
|
||||||
|
|
||||||
enabled: tfShareCode.textArea.length > 0
|
copyText: tfShareCode.textArea.text
|
||||||
}
|
}
|
||||||
ShareConnectionButtonType {
|
ShareConnectionButtonType {
|
||||||
id: pb_save
|
Layout.bottomMargin: 10
|
||||||
anchors.bottom: root.bottom
|
Layout.fillWidth: true
|
||||||
anchors.bottomMargin: 10
|
Layout.preferredHeight: 40
|
||||||
anchors.horizontalCenter: root.horizontalCenter
|
|
||||||
width: parent.width - 60
|
width: parent.width - 60
|
||||||
|
|
||||||
text: qsTr("Save to file")
|
text: qsTr("Save to file")
|
||||||
enabled: tfShareCode.textArea.length > 0
|
enabled: tfShareCode.textArea.length > 0
|
||||||
|
visible: tfShareCode.textArea.length > 0
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
UiLogic.saveTextFile(qsTr("Save OpenVPN config"), "*.ovpn", tfShareCode.textArea.text)
|
UiLogic.saveTextFile(qsTr("Save OpenVPN config"), "*.ovpn", tfShareCode.textArea.text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@ import "../../Config"
|
||||||
PageShareProtocolBase {
|
PageShareProtocolBase {
|
||||||
id: root
|
id: root
|
||||||
protocol: ProtocolEnum.Sftp
|
protocol: ProtocolEnum.Sftp
|
||||||
logic: UiLogic.protocolLogic(protocol)
|
|
||||||
|
|
||||||
BackButton {
|
BackButton {
|
||||||
id: back
|
id: back
|
||||||
|
|
|
@ -9,7 +9,6 @@ import "../../Config"
|
||||||
PageShareProtocolBase {
|
PageShareProtocolBase {
|
||||||
id: root
|
id: root
|
||||||
protocol: ProtocolEnum.ShadowSocks
|
protocol: ProtocolEnum.ShadowSocks
|
||||||
logic: UiLogic.protocolLogic(protocol)
|
|
||||||
|
|
||||||
BackButton {
|
BackButton {
|
||||||
id: back
|
id: back
|
||||||
|
@ -31,73 +30,69 @@ PageShareProtocolBase {
|
||||||
anchors.right: root.right
|
anchors.right: root.right
|
||||||
anchors.rightMargin: 30
|
anchors.rightMargin: 30
|
||||||
|
|
||||||
contentHeight: content.height + content2.height + 40
|
contentHeight: content.height
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
GridLayout {
|
|
||||||
id: content
|
|
||||||
enabled: logic.pageEnabled
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
|
|
||||||
columns: 2
|
|
||||||
|
|
||||||
//
|
|
||||||
LabelType {
|
|
||||||
height: 20
|
|
||||||
text: qsTr("Server:")
|
|
||||||
}
|
|
||||||
TextFieldType {
|
|
||||||
height: 20
|
|
||||||
text: ShareConnectionLogic.labelShareShadowSocksServerText
|
|
||||||
readOnly: true
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
LabelType {
|
|
||||||
height: 20
|
|
||||||
text: qsTr("Port:")
|
|
||||||
}
|
|
||||||
TextFieldType {
|
|
||||||
height: 20
|
|
||||||
text: ShareConnectionLogic.labelShareShadowSocksPortText
|
|
||||||
readOnly: true
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
LabelType {
|
|
||||||
height: 20
|
|
||||||
text: qsTr("Password")
|
|
||||||
}
|
|
||||||
TextFieldType {
|
|
||||||
height: 20
|
|
||||||
text: ShareConnectionLogic.labelShareShadowSocksPasswordText
|
|
||||||
readOnly: true
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
LabelType {
|
|
||||||
height: 20
|
|
||||||
text: qsTr("Encryption:")
|
|
||||||
}
|
|
||||||
TextFieldType {
|
|
||||||
height: 20
|
|
||||||
text: ShareConnectionLogic.labelShareShadowSocksMethodText
|
|
||||||
readOnly: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: content2
|
id: content
|
||||||
enabled: logic.pageEnabled
|
enabled: logic.pageEnabled
|
||||||
anchors.top: content.bottom
|
anchors.top: content.bottom
|
||||||
anchors.topMargin: 20
|
anchors.topMargin: 20
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
|
|
||||||
|
LabelType {
|
||||||
|
id: lb_desc
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 10
|
||||||
|
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
text: qsTr("Note: ShadowSocks protocol using same password for all connections")
|
||||||
|
}
|
||||||
|
|
||||||
|
ShareConnectionButtonType {
|
||||||
|
Layout.topMargin: 10
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: 40
|
||||||
|
|
||||||
|
text: genConfigProcess ? generatingConfigText : generateConfigText
|
||||||
|
onClicked: {
|
||||||
|
enabled = false
|
||||||
|
genConfigProcess = true
|
||||||
|
ShareConnectionLogic.onPushButtonShareShadowSocksGenerateClicked()
|
||||||
|
enabled = true
|
||||||
|
genConfigProcess = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TextAreaType {
|
||||||
|
id: tfShareCode
|
||||||
|
|
||||||
|
Layout.topMargin: 20
|
||||||
|
Layout.preferredHeight: 200
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
textArea.readOnly: true
|
||||||
|
textArea.wrapMode: TextEdit.WrapAnywhere
|
||||||
|
textArea.verticalAlignment: Text.AlignTop
|
||||||
|
textArea.text: ShareConnectionLogic.textEditShareShadowSocksText
|
||||||
|
|
||||||
|
visible: tfShareCode.textArea.length > 0
|
||||||
|
}
|
||||||
|
ShareConnectionButtonCopyType {
|
||||||
|
Layout.preferredHeight: 40
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.bottomMargin: 20
|
||||||
|
|
||||||
|
start_text: qsTr("Copy config")
|
||||||
|
copyText: tfShareCode.textArea.text
|
||||||
|
}
|
||||||
|
|
||||||
LabelType {
|
LabelType {
|
||||||
height: 20
|
height: 20
|
||||||
|
visible: tfConnString.length > 0
|
||||||
text: qsTr("Connection string")
|
text: qsTr("Connection string")
|
||||||
}
|
}
|
||||||
TextFieldType {
|
TextFieldType {
|
||||||
|
@ -106,12 +101,15 @@ PageShareProtocolBase {
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
text: ShareConnectionLogic.lineEditShareShadowSocksStringText
|
text: ShareConnectionLogic.lineEditShareShadowSocksStringText
|
||||||
|
visible: tfConnString.length > 0
|
||||||
|
|
||||||
readOnly: true
|
readOnly: true
|
||||||
}
|
}
|
||||||
ShareConnectionButtonCopyType {
|
ShareConnectionButtonCopyType {
|
||||||
Layout.preferredHeight: 40
|
Layout.preferredHeight: 40
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
enabled: tfConnString.length > 0
|
start_text: qsTr("Copy string")
|
||||||
|
copyText: tfConnString.text
|
||||||
}
|
}
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
|
|
|
@ -8,7 +8,6 @@ import "../../Config"
|
||||||
PageShareProtocolBase {
|
PageShareProtocolBase {
|
||||||
id: root
|
id: root
|
||||||
protocol: ProtocolEnum.TorWebSite
|
protocol: ProtocolEnum.TorWebSite
|
||||||
logic: UiLogic.protocolLogic(protocol)
|
|
||||||
|
|
||||||
BackButton {
|
BackButton {
|
||||||
id: back
|
id: back
|
||||||
|
|
113
client/ui/qml/Pages/Share/PageShareProtoWireGuard.qml
Normal file
113
client/ui/qml/Pages/Share/PageShareProtoWireGuard.qml
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
import QtQuick 2.12
|
||||||
|
import QtQuick.Controls 2.12
|
||||||
|
import QtQuick.Layouts 1.15
|
||||||
|
import ProtocolEnum 1.0
|
||||||
|
import "../"
|
||||||
|
import "../../Controls"
|
||||||
|
import "../../Config"
|
||||||
|
|
||||||
|
PageShareProtocolBase {
|
||||||
|
id: root
|
||||||
|
protocol: ProtocolEnum.WireGuard
|
||||||
|
|
||||||
|
BackButton {
|
||||||
|
id: back
|
||||||
|
}
|
||||||
|
Caption {
|
||||||
|
id: caption
|
||||||
|
text: qsTr("Share WireGuard Settings")
|
||||||
|
}
|
||||||
|
|
||||||
|
Flickable {
|
||||||
|
id: fl
|
||||||
|
width: root.width
|
||||||
|
anchors.top: caption.bottom
|
||||||
|
anchors.topMargin: 20
|
||||||
|
anchors.bottom: root.bottom
|
||||||
|
anchors.bottomMargin: 20
|
||||||
|
anchors.left: root.left
|
||||||
|
anchors.leftMargin: 30
|
||||||
|
anchors.right: root.right
|
||||||
|
anchors.rightMargin: 30
|
||||||
|
|
||||||
|
contentHeight: content.height
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: content
|
||||||
|
enabled: logic.pageEnabled
|
||||||
|
anchors.top: content.bottom
|
||||||
|
anchors.topMargin: 20
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
|
||||||
|
LabelType {
|
||||||
|
id: lb_desc
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 10
|
||||||
|
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
text: qsTr("New encryption keys pair will be generated.")
|
||||||
|
}
|
||||||
|
|
||||||
|
ShareConnectionButtonType {
|
||||||
|
Layout.topMargin: 10
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: 40
|
||||||
|
|
||||||
|
text: genConfigProcess ? generatingConfigText : generateConfigText
|
||||||
|
onClicked: {
|
||||||
|
enabled = false
|
||||||
|
genConfigProcess = true
|
||||||
|
ShareConnectionLogic.onPushButtonShareWireGuardGenerateClicked()
|
||||||
|
enabled = true
|
||||||
|
genConfigProcess = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TextAreaType {
|
||||||
|
id: tfShareCode
|
||||||
|
|
||||||
|
Layout.topMargin: 20
|
||||||
|
Layout.preferredHeight: 200
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
textArea.readOnly: true
|
||||||
|
textArea.wrapMode: TextEdit.WrapAnywhere
|
||||||
|
textArea.verticalAlignment: Text.AlignTop
|
||||||
|
textArea.text: ShareConnectionLogic.textEditShareWireGuardCodeText
|
||||||
|
|
||||||
|
visible: tfShareCode.textArea.length > 0
|
||||||
|
}
|
||||||
|
ShareConnectionButtonCopyType {
|
||||||
|
Layout.preferredHeight: 40
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
copyText: tfShareCode.textArea.text
|
||||||
|
}
|
||||||
|
|
||||||
|
ShareConnectionButtonType {
|
||||||
|
Layout.preferredHeight: 40
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
text: qsTr("Save to file")
|
||||||
|
enabled: tfShareCode.textArea.length > 0
|
||||||
|
visible: tfShareCode.textArea.length > 0
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
UiLogic.saveTextFile(qsTr("Save OpenVPN config"), "*.conf", tfShareCode.textArea.text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
Layout.topMargin: 20
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: width
|
||||||
|
smooth: false
|
||||||
|
source: ShareConnectionLogic.shareWireGuardQrCodeText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,5 +9,11 @@ import "../../Config"
|
||||||
PageBase {
|
PageBase {
|
||||||
id: root
|
id: root
|
||||||
property var protocol: ProtocolEnum.Any
|
property var protocol: ProtocolEnum.Any
|
||||||
page: PageEnum.ProtocolSettings
|
page: PageEnum.ProtocolShare
|
||||||
|
logic: ShareConnectionLogic
|
||||||
|
|
||||||
|
readonly property string generateConfigText: qsTr("Generate config")
|
||||||
|
readonly property string generatingConfigText: qsTr("Generating config...")
|
||||||
|
readonly property string showConfigText: qsTr("Show config")
|
||||||
|
property bool genConfigProcess: false
|
||||||
}
|
}
|
||||||
|
|
|
@ -705,5 +705,29 @@ bool UiLogic::saveTextFile(const QString& desc, const QString& ext, const QStrin
|
||||||
QSaveFile save(fileName);
|
QSaveFile save(fileName);
|
||||||
save.open(QIODevice::WriteOnly);
|
save.open(QIODevice::WriteOnly);
|
||||||
save.write(data.toUtf8());
|
save.write(data.toUtf8());
|
||||||
|
|
||||||
|
QFileInfo fi(fileName);
|
||||||
|
QDesktopServices::openUrl(fi.absoluteDir().absolutePath());
|
||||||
|
|
||||||
return save.commit();
|
return save.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool UiLogic::saveBinaryFile(const QString &desc, const QString &ext, const QString &data)
|
||||||
|
{
|
||||||
|
QString fileName = QFileDialog::getSaveFileName(nullptr, desc,
|
||||||
|
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation), ext);
|
||||||
|
|
||||||
|
QSaveFile save(fileName);
|
||||||
|
save.open(QIODevice::WriteOnly);
|
||||||
|
save.write(QByteArray::fromBase64(data.toUtf8()));
|
||||||
|
|
||||||
|
QFileInfo fi(fileName);
|
||||||
|
QDesktopServices::openUrl(fi.absoluteDir().absolutePath());
|
||||||
|
|
||||||
|
return save.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UiLogic::copyToClipboard(const QString &text)
|
||||||
|
{
|
||||||
|
qApp->clipboard()->setText(text);
|
||||||
|
}
|
||||||
|
|
|
@ -99,6 +99,8 @@ public:
|
||||||
Q_INVOKABLE void keyPressEvent(Qt::Key key);
|
Q_INVOKABLE void keyPressEvent(Qt::Key key);
|
||||||
|
|
||||||
Q_INVOKABLE bool saveTextFile(const QString& desc, const QString& ext, const QString& data);
|
Q_INVOKABLE bool saveTextFile(const QString& desc, const QString& ext, const QString& data);
|
||||||
|
Q_INVOKABLE bool saveBinaryFile(const QString& desc, const QString& ext, const QString& data);
|
||||||
|
Q_INVOKABLE void copyToClipboard(const QString& text);
|
||||||
|
|
||||||
QString getTrayIconUrl() const;
|
QString getTrayIconUrl() const;
|
||||||
void setTrayIconUrl(const QString &trayIconUrl);
|
void setTrayIconUrl(const QString &trayIconUrl);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue