Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into HEAD
This commit is contained in:
commit
98a5219137
37 changed files with 340 additions and 169 deletions
|
|
@ -120,7 +120,7 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
|
|||
}
|
||||
}
|
||||
|
||||
QString subnetIp = containerConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress);
|
||||
QString subnetIp = containerConfig.value(m_protocolName).toObject().value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress);
|
||||
{
|
||||
QStringList l = subnetIp.split(".", Qt::SkipEmptyParts);
|
||||
if (l.isEmpty()) {
|
||||
|
|
|
|||
|
|
@ -346,7 +346,9 @@ bool ServerController::isReinstallContainerRequired(DockerContainer container, c
|
|||
}
|
||||
|
||||
if (container == DockerContainer::Awg) {
|
||||
if ((oldProtoConfig.value(config_key::port).toString(protocols::awg::defaultPort)
|
||||
if ((oldProtoConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress)
|
||||
!= newProtoConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress))
|
||||
|| (oldProtoConfig.value(config_key::port).toString(protocols::awg::defaultPort)
|
||||
!= newProtoConfig.value(config_key::port).toString(protocols::awg::defaultPort))
|
||||
|| (oldProtoConfig.value(config_key::junkPacketCount).toString(protocols::awg::defaultJunkPacketCount)
|
||||
!= newProtoConfig.value(config_key::junkPacketCount).toString(protocols::awg::defaultJunkPacketCount))
|
||||
|
|
@ -370,8 +372,10 @@ bool ServerController::isReinstallContainerRequired(DockerContainer container, c
|
|||
}
|
||||
|
||||
if (container == DockerContainer::WireGuard) {
|
||||
if (oldProtoConfig.value(config_key::port).toString(protocols::wireguard::defaultPort)
|
||||
!= newProtoConfig.value(config_key::port).toString(protocols::wireguard::defaultPort))
|
||||
if ((oldProtoConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress)
|
||||
!= newProtoConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress))
|
||||
|| (oldProtoConfig.value(config_key::port).toString(protocols::wireguard::defaultPort)
|
||||
!= newProtoConfig.value(config_key::port).toString(protocols::wireguard::defaultPort)))
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -607,6 +611,8 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential
|
|||
vars.append({ { "$SFTP_PASSWORD", sftpConfig.value(config_key::password).toString() } });
|
||||
|
||||
// Amnezia wireguard vars
|
||||
vars.append({ { "$AWG_SUBNET_IP",
|
||||
amneziaWireguarConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress) } });
|
||||
vars.append({ { "$AWG_SERVER_PORT", amneziaWireguarConfig.value(config_key::port).toString(protocols::awg::defaultPort) } });
|
||||
|
||||
vars.append({ { "$JUNK_PACKET_COUNT", amneziaWireguarConfig.value(config_key::junkPacketCount).toString() } });
|
||||
|
|
|
|||
5
client/images/controls/external-link.svg
Normal file
5
client/images/controls/external-link.svg
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M18 13V19C18 19.5304 17.7893 20.0391 17.4142 20.4142C17.0391 20.7893 16.5304 21 16 21H5C4.46957 21 3.96086 20.7893 3.58579 20.4142C3.21071 20.0391 3 19.5304 3 19V8C3 7.46957 3.21071 6.96086 3.58579 6.58579C3.96086 6.21071 4.46957 6 5 6H11" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M15 3H21V9" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M10 14L21 3" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 644 B |
|
|
@ -1,7 +1,6 @@
|
|||
#include "xrayprotocol.h"
|
||||
|
||||
#include "utilities.h"
|
||||
#include "containers/containers_defs.h"
|
||||
#include "core/networkUtilities.h"
|
||||
|
||||
#include <QCryptographicHash>
|
||||
|
|
@ -22,9 +21,8 @@ XrayProtocol::XrayProtocol(const QJsonObject &configuration, QObject *parent):
|
|||
|
||||
XrayProtocol::~XrayProtocol()
|
||||
{
|
||||
qDebug() << "XrayProtocol::~XrayProtocol()";
|
||||
XrayProtocol::stop();
|
||||
QThread::msleep(200);
|
||||
m_xrayProcess.close();
|
||||
}
|
||||
|
||||
ErrorCode XrayProtocol::start()
|
||||
|
|
@ -36,10 +34,6 @@ ErrorCode XrayProtocol::start()
|
|||
return lastError();
|
||||
}
|
||||
|
||||
if (Utils::processIsRunning(Utils::executable(xrayExecPath(), true))) {
|
||||
Utils::killProcessByName(Utils::executable(xrayExecPath(), true));
|
||||
}
|
||||
|
||||
#ifdef QT_DEBUG
|
||||
m_xrayCfgFile.setAutoRemove(false);
|
||||
#endif
|
||||
|
|
@ -54,9 +48,16 @@ ErrorCode XrayProtocol::start()
|
|||
qDebug().noquote() << "XrayProtocol::start()"
|
||||
<< xrayExecPath() << args.join(" ");
|
||||
|
||||
m_xrayProcess.setProcessChannelMode(QProcess::MergedChannels);
|
||||
|
||||
|
||||
m_xrayProcess.setProcessChannelMode(QProcess::MergedChannels);
|
||||
m_xrayProcess.setProgram(xrayExecPath());
|
||||
|
||||
if (Utils::processIsRunning(Utils::executable("xray", false))) {
|
||||
qDebug().noquote() << "kill previos xray";
|
||||
Utils::killProcessByName(Utils::executable("xray", false));
|
||||
}
|
||||
|
||||
m_xrayProcess.setArguments(args);
|
||||
|
||||
connect(&m_xrayProcess, &QProcess::readyReadStandardOutput, this, [this]() {
|
||||
|
|
@ -68,13 +69,9 @@ ErrorCode XrayProtocol::start()
|
|||
connect(&m_xrayProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, [this](int exitCode, QProcess::ExitStatus exitStatus) {
|
||||
qDebug().noquote() << "XrayProtocol finished, exitCode, exitStatus" << exitCode << exitStatus;
|
||||
setConnectionState(Vpn::ConnectionState::Disconnected);
|
||||
if (exitStatus != QProcess::NormalExit) {
|
||||
emit protocolError(amnezia::ErrorCode::XrayExecutableCrashed);
|
||||
stop();
|
||||
}
|
||||
if (exitCode != 0) {
|
||||
emit protocolError(amnezia::ErrorCode::InternalError);
|
||||
stop();
|
||||
if ((exitStatus != QProcess::NormalExit) || (exitCode != 0)) {
|
||||
emit protocolError(amnezia::ErrorCode::XrayExecutableCrashed);
|
||||
emit setConnectionState(Vpn::ConnectionState::Error);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -177,14 +174,14 @@ void XrayProtocol::stop()
|
|||
IpcClient::Interface()->StartRoutingIpv6();
|
||||
#endif
|
||||
qDebug() << "XrayProtocol::stop()";
|
||||
m_xrayProcess.terminate();
|
||||
m_xrayProcess.disconnect();
|
||||
m_xrayProcess.kill();
|
||||
m_xrayProcess.waitForFinished(3000);
|
||||
if (m_t2sProcess) {
|
||||
m_t2sProcess->stop();
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
Utils::signalCtrl(m_xrayProcess.processId(), CTRL_C_EVENT);
|
||||
#endif
|
||||
setConnectionState(Vpn::ConnectionState::Disconnected);
|
||||
}
|
||||
|
||||
QString XrayProtocol::xrayExecPath()
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
<file>images/controls/edit-3.svg</file>
|
||||
<file>images/controls/eye-off.svg</file>
|
||||
<file>images/controls/eye.svg</file>
|
||||
<file>images/controls/external-link.svg</file>
|
||||
<file>images/controls/file-check-2.svg</file>
|
||||
<file>images/controls/file-cog-2.svg</file>
|
||||
<file>images/controls/folder-open.svg</file>
|
||||
|
|
@ -119,6 +120,7 @@
|
|||
<file>server_scripts/xray/run_container.sh</file>
|
||||
<file>server_scripts/xray/start.sh</file>
|
||||
<file>server_scripts/xray/template.json</file>
|
||||
<file>ui/qml/Components/AdLabel.qml</file>
|
||||
<file>ui/qml/Components/ConnectButton.qml</file>
|
||||
<file>ui/qml/Components/ConnectionTypeSelectionDrawer.qml</file>
|
||||
<file>ui/qml/Components/HomeContainersListView.qml</file>
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ echo $WIREGUARD_PSK > /opt/amnezia/awg/wireguard_psk.key
|
|||
cat > /opt/amnezia/awg/wg0.conf <<EOF
|
||||
[Interface]
|
||||
PrivateKey = $WIREGUARD_SERVER_PRIVATE_KEY
|
||||
Address = $WIREGUARD_SUBNET_IP/$WIREGUARD_SUBNET_CIDR
|
||||
Address = $AWG_SUBNET_IP/$WIREGUARD_SUBNET_CIDR
|
||||
ListenPort = $AWG_SERVER_PORT
|
||||
Jc = $JUNK_PACKET_COUNT
|
||||
Jmin = $JUNK_PACKET_MIN_SIZE
|
||||
|
|
|
|||
|
|
@ -17,12 +17,12 @@ iptables -A FORWARD -i wg0 -j ACCEPT
|
|||
iptables -A OUTPUT -o wg0 -j ACCEPT
|
||||
|
||||
# Allow forwarding traffic only from the VPN.
|
||||
iptables -A FORWARD -i wg0 -o eth0 -s $WIREGUARD_SUBNET_IP/$WIREGUARD_SUBNET_CIDR -j ACCEPT
|
||||
iptables -A FORWARD -i wg0 -o eth1 -s $WIREGUARD_SUBNET_IP/$WIREGUARD_SUBNET_CIDR -j ACCEPT
|
||||
iptables -A FORWARD -i wg0 -o eth0 -s $AWG_SUBNET_IP/$WIREGUARD_SUBNET_CIDR -j ACCEPT
|
||||
iptables -A FORWARD -i wg0 -o eth1 -s $AWG_SUBNET_IP/$WIREGUARD_SUBNET_CIDR -j ACCEPT
|
||||
|
||||
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
|
||||
|
||||
iptables -t nat -A POSTROUTING -s $WIREGUARD_SUBNET_IP/$WIREGUARD_SUBNET_CIDR -o eth0 -j MASQUERADE
|
||||
iptables -t nat -A POSTROUTING -s $WIREGUARD_SUBNET_IP/$WIREGUARD_SUBNET_CIDR -o eth1 -j MASQUERADE
|
||||
iptables -t nat -A POSTROUTING -s $AWG_SUBNET_IP/$WIREGUARD_SUBNET_CIDR -o eth0 -j MASQUERADE
|
||||
iptables -t nat -A POSTROUTING -s $AWG_SUBNET_IP/$WIREGUARD_SUBNET_CIDR -o eth1 -j MASQUERADE
|
||||
|
||||
tail -f /dev/null
|
||||
|
|
|
|||
|
|
@ -538,3 +538,13 @@ void Settings::toggleDevGatewayEnv(bool enabled)
|
|||
{
|
||||
m_isDevGatewayEnv = enabled;
|
||||
}
|
||||
|
||||
bool Settings::isHomeAdLabelVisible()
|
||||
{
|
||||
return value("Conf/homeAdLabelVisible", true).toBool();
|
||||
}
|
||||
|
||||
void Settings::disableHomeAdLabel()
|
||||
{
|
||||
setValue("Conf/homeAdLabelVisible", false);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -222,6 +222,9 @@ public:
|
|||
bool isDevGatewayEnv();
|
||||
void toggleDevGatewayEnv(bool enabled);
|
||||
|
||||
bool isHomeAdLabelVisible();
|
||||
void disableHomeAdLabel();
|
||||
|
||||
signals:
|
||||
void saveLogsChanged(bool enabled);
|
||||
void screenshotsEnabledChanged(bool enabled);
|
||||
|
|
|
|||
|
|
@ -10,16 +10,15 @@ FocusController::FocusController(QQmlApplicationEngine *engine, QObject *parent)
|
|||
m_focusChain {},
|
||||
m_focusedItem { nullptr },
|
||||
m_rootObjects {},
|
||||
m_defaultFocusItem { QSharedPointer<QQuickItem>() },
|
||||
m_defaultFocusItem { nullptr },
|
||||
m_lvfc { nullptr }
|
||||
{
|
||||
QObject::connect(m_engine.get(), &QQmlApplicationEngine::objectCreated, this,
|
||||
[this](QObject *object, const QUrl &url) {
|
||||
QQuickItem *newDefaultFocusItem = object->findChild<QQuickItem *>("defaultFocusItem");
|
||||
if (newDefaultFocusItem && m_defaultFocusItem != newDefaultFocusItem) {
|
||||
m_defaultFocusItem.reset(newDefaultFocusItem);
|
||||
}
|
||||
});
|
||||
QObject::connect(m_engine, &QQmlApplicationEngine::objectCreated, this, [this](QObject *object, const QUrl &url) {
|
||||
QQuickItem *newDefaultFocusItem = object->findChild<QQuickItem *>("defaultFocusItem");
|
||||
if (newDefaultFocusItem && m_defaultFocusItem != newDefaultFocusItem) {
|
||||
m_defaultFocusItem = newDefaultFocusItem;
|
||||
}
|
||||
});
|
||||
|
||||
QObject::connect(this, &FocusController::focusedItemChanged, this,
|
||||
[this]() { m_focusedItem->forceActiveFocus(Qt::TabFocusReason); });
|
||||
|
|
@ -65,7 +64,7 @@ void FocusController::setFocusItem(QQuickItem *item)
|
|||
|
||||
void FocusController::setFocusOnDefaultItem()
|
||||
{
|
||||
setFocusItem(m_defaultFocusItem.get());
|
||||
setFocusItem(m_defaultFocusItem);
|
||||
}
|
||||
|
||||
void FocusController::pushRootObject(QObject *object)
|
||||
|
|
|
|||
|
|
@ -42,11 +42,11 @@ private:
|
|||
void focusPreviousListViewItem();
|
||||
void dropListView();
|
||||
|
||||
QSharedPointer<QQmlApplicationEngine> m_engine; // Pointer to engine to get root object
|
||||
QList<QObject *> m_focusChain; // List of current objects to be focused
|
||||
QQuickItem *m_focusedItem; // Pointer to the active focus item
|
||||
QStack<QObject *> m_rootObjects;
|
||||
QSharedPointer<QQuickItem> m_defaultFocusItem;
|
||||
QQmlApplicationEngine *m_engine; // Pointer to engine to get root object
|
||||
QList<QObject *> m_focusChain; // List of current objects to be focused
|
||||
QQuickItem *m_focusedItem; // Pointer to the active focus item
|
||||
QStack<QObject *> m_rootObjects; // Pointer to stack of roots for focus chain
|
||||
QQuickItem *m_defaultFocusItem;
|
||||
|
||||
ListViewFocusController *m_lvfc; // ListView focus manager
|
||||
|
||||
|
|
|
|||
|
|
@ -321,3 +321,14 @@ bool SettingsController::isOnTv()
|
|||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool SettingsController::isHomeAdLabelVisible()
|
||||
{
|
||||
return m_settings->isHomeAdLabelVisible();
|
||||
}
|
||||
|
||||
void SettingsController::disableHomeAdLabel()
|
||||
{
|
||||
m_settings->disableHomeAdLabel();
|
||||
emit isHomeAdLabelVisibleChanged(false);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ public:
|
|||
Q_PROPERTY(QString gatewayEndpoint READ getGatewayEndpoint WRITE setGatewayEndpoint NOTIFY gatewayEndpointChanged)
|
||||
Q_PROPERTY(bool isDevGatewayEnv READ isDevGatewayEnv WRITE toggleDevGatewayEnv NOTIFY devGatewayEnvChanged)
|
||||
|
||||
Q_PROPERTY(bool isHomeAdLabelVisible READ isHomeAdLabelVisible NOTIFY isHomeAdLabelVisibleChanged)
|
||||
|
||||
public slots:
|
||||
void toggleAmneziaDns(bool enable);
|
||||
bool isAmneziaDnsEnabled();
|
||||
|
|
@ -89,6 +91,9 @@ public slots:
|
|||
|
||||
bool isOnTv();
|
||||
|
||||
bool isHomeAdLabelVisible();
|
||||
void disableHomeAdLabel();
|
||||
|
||||
signals:
|
||||
void primaryDnsChanged();
|
||||
void secondaryDnsChanged();
|
||||
|
|
@ -112,6 +117,8 @@ signals:
|
|||
void gatewayEndpointChanged(const QString &endpoint);
|
||||
void devGatewayEnvChanged(bool enabled);
|
||||
|
||||
void isHomeAdLabelVisibleChanged(bool visible);
|
||||
|
||||
private:
|
||||
QSharedPointer<ServersModel> m_serversModel;
|
||||
QSharedPointer<ContainersModel> m_containersModel;
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ QVariant ApiServicesModel::data(const QModelIndex &index, int role) const
|
|||
.arg(speed);
|
||||
} else if (serviceType == serviceType::amneziaFree){
|
||||
QString description = tr("VPN to access blocked sites in regions with high levels of Internet censorship. ");
|
||||
if (isServiceAvailable) {
|
||||
if (!isServiceAvailable) {
|
||||
description += tr("<p><a style=\"color: #EB5757;\">Not available in your region. If you have VPN enabled, disable it, return to the previous screen, and try again.</a>");
|
||||
}
|
||||
return description;
|
||||
|
|
@ -86,7 +86,7 @@ QVariant ApiServicesModel::data(const QModelIndex &index, int role) const
|
|||
}
|
||||
case IsServiceAvailableRole: {
|
||||
if (serviceType == serviceType::amneziaFree) {
|
||||
if (isServiceAvailable) {
|
||||
if (!isServiceAvailable) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ bool AwgConfigModel::setData(const QModelIndex &index, const QVariant &value, in
|
|||
}
|
||||
|
||||
switch (role) {
|
||||
case Roles::SubnetAddressRole: m_serverProtocolConfig.insert(config_key::subnet_address, value.toString()); break;
|
||||
case Roles::PortRole: m_serverProtocolConfig.insert(config_key::port, value.toString()); break;
|
||||
|
||||
case Roles::ClientMtuRole: m_clientProtocolConfig.insert(config_key::mtu, value.toString()); break;
|
||||
|
|
@ -58,6 +59,7 @@ QVariant AwgConfigModel::data(const QModelIndex &index, int role) const
|
|||
}
|
||||
|
||||
switch (role) {
|
||||
case Roles::SubnetAddressRole: return m_serverProtocolConfig.value(config_key::subnet_address).toString();
|
||||
case Roles::PortRole: return m_serverProtocolConfig.value(config_key::port).toString();
|
||||
|
||||
case Roles::ClientMtuRole: return m_clientProtocolConfig.value(config_key::mtu);
|
||||
|
|
@ -92,6 +94,7 @@ void AwgConfigModel::updateModel(const QJsonObject &config)
|
|||
m_serverProtocolConfig.insert(config_key::transport_proto,
|
||||
serverProtocolConfig.value(config_key::transport_proto).toString(defaultTransportProto));
|
||||
m_serverProtocolConfig[config_key::last_config] = serverProtocolConfig.value(config_key::last_config);
|
||||
m_serverProtocolConfig[config_key::subnet_address] = serverProtocolConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress);
|
||||
m_serverProtocolConfig[config_key::port] = serverProtocolConfig.value(config_key::port).toString(protocols::awg::defaultPort);
|
||||
m_serverProtocolConfig[config_key::junkPacketCount] =
|
||||
serverProtocolConfig.value(config_key::junkPacketCount).toString(protocols::awg::defaultJunkPacketCount);
|
||||
|
|
@ -168,6 +171,7 @@ QHash<int, QByteArray> AwgConfigModel::roleNames() const
|
|||
{
|
||||
QHash<int, QByteArray> roles;
|
||||
|
||||
roles[SubnetAddressRole] = "subnetAddress";
|
||||
roles[PortRole] = "port";
|
||||
|
||||
roles[ClientMtuRole] = "clientMtu";
|
||||
|
|
@ -197,6 +201,7 @@ AwgConfig::AwgConfig(const QJsonObject &serverProtocolConfig)
|
|||
clientJunkPacketMinSize = clientProtocolConfig.value(config_key::junkPacketMinSize).toString(protocols::awg::defaultJunkPacketMinSize);
|
||||
clientJunkPacketMaxSize = clientProtocolConfig.value(config_key::junkPacketMaxSize).toString(protocols::awg::defaultJunkPacketMaxSize);
|
||||
|
||||
subnetAddress = serverProtocolConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress);
|
||||
port = serverProtocolConfig.value(config_key::port).toString(protocols::awg::defaultPort);
|
||||
serverJunkPacketCount = serverProtocolConfig.value(config_key::junkPacketCount).toString(protocols::awg::defaultJunkPacketCount);
|
||||
serverJunkPacketMinSize = serverProtocolConfig.value(config_key::junkPacketMinSize).toString(protocols::awg::defaultJunkPacketMinSize);
|
||||
|
|
@ -216,7 +221,7 @@ AwgConfig::AwgConfig(const QJsonObject &serverProtocolConfig)
|
|||
|
||||
bool AwgConfig::hasEqualServerSettings(const AwgConfig &other) const
|
||||
{
|
||||
if (port != other.port || serverJunkPacketCount != other.serverJunkPacketCount
|
||||
if (subnetAddress != other.subnetAddress || port != other.port || serverJunkPacketCount != other.serverJunkPacketCount
|
||||
|| serverJunkPacketMinSize != other.serverJunkPacketMinSize || serverJunkPacketMaxSize != other.serverJunkPacketMaxSize
|
||||
|| serverInitPacketJunkSize != other.serverInitPacketJunkSize || serverResponsePacketJunkSize != other.serverResponsePacketJunkSize
|
||||
|| serverInitPacketMagicHeader != other.serverInitPacketMagicHeader
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ struct AwgConfig
|
|||
{
|
||||
AwgConfig(const QJsonObject &jsonConfig);
|
||||
|
||||
QString subnetAddress;
|
||||
QString port;
|
||||
|
||||
QString clientMtu;
|
||||
|
|
@ -43,7 +44,8 @@ class AwgConfigModel : public QAbstractListModel
|
|||
|
||||
public:
|
||||
enum Roles {
|
||||
PortRole = Qt::UserRole + 1,
|
||||
SubnetAddressRole = Qt::UserRole + 1,
|
||||
PortRole,
|
||||
|
||||
ClientMtuRole,
|
||||
ClientJunkPacketCountRole,
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ bool WireGuardConfigModel::setData(const QModelIndex &index, const QVariant &val
|
|||
}
|
||||
|
||||
switch (role) {
|
||||
case Roles::SubnetAddressRole: m_serverProtocolConfig.insert(config_key::subnet_address, value.toString()); break;
|
||||
case Roles::PortRole: m_serverProtocolConfig.insert(config_key::port, value.toString()); break;
|
||||
case Roles::ClientMtuRole: m_clientProtocolConfig.insert(config_key::mtu, value.toString()); break;
|
||||
}
|
||||
|
|
@ -36,6 +37,7 @@ QVariant WireGuardConfigModel::data(const QModelIndex &index, int role) const
|
|||
}
|
||||
|
||||
switch (role) {
|
||||
case Roles::SubnetAddressRole: return m_serverProtocolConfig.value(config_key::subnet_address).toString();
|
||||
case Roles::PortRole: return m_serverProtocolConfig.value(config_key::port).toString();
|
||||
case Roles::ClientMtuRole: return m_clientProtocolConfig.value(config_key::mtu);
|
||||
}
|
||||
|
|
@ -56,6 +58,7 @@ void WireGuardConfigModel::updateModel(const QJsonObject &config)
|
|||
m_serverProtocolConfig.insert(config_key::transport_proto,
|
||||
serverProtocolConfig.value(config_key::transport_proto).toString(defaultTransportProto));
|
||||
m_serverProtocolConfig[config_key::last_config] = serverProtocolConfig.value(config_key::last_config);
|
||||
m_serverProtocolConfig[config_key::subnet_address] = serverProtocolConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress);
|
||||
m_serverProtocolConfig[config_key::port] = serverProtocolConfig.value(config_key::port).toString(protocols::wireguard::defaultPort);
|
||||
|
||||
auto lastConfig = m_serverProtocolConfig.value(config_key::last_config).toString();
|
||||
|
|
@ -96,6 +99,7 @@ QHash<int, QByteArray> WireGuardConfigModel::roleNames() const
|
|||
{
|
||||
QHash<int, QByteArray> roles;
|
||||
|
||||
roles[SubnetAddressRole] = "subnetAddress";
|
||||
roles[PortRole] = "port";
|
||||
roles[ClientMtuRole] = "clientMtu";
|
||||
|
||||
|
|
@ -108,12 +112,13 @@ WgConfig::WgConfig(const QJsonObject &serverProtocolConfig)
|
|||
QJsonObject clientProtocolConfig = QJsonDocument::fromJson(lastConfig.toUtf8()).object();
|
||||
clientMtu = clientProtocolConfig[config_key::mtu].toString(protocols::wireguard::defaultMtu);
|
||||
|
||||
subnetAddress = serverProtocolConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress);
|
||||
port = serverProtocolConfig.value(config_key::port).toString(protocols::wireguard::defaultPort);
|
||||
}
|
||||
|
||||
bool WgConfig::hasEqualServerSettings(const WgConfig &other) const
|
||||
{
|
||||
if (port != other.port) {
|
||||
if (subnetAddress != other.subnetAddress || port != other.port) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ struct WgConfig
|
|||
{
|
||||
WgConfig(const QJsonObject &jsonConfig);
|
||||
|
||||
QString subnetAddress;
|
||||
QString port;
|
||||
QString clientMtu;
|
||||
|
||||
|
|
@ -24,7 +25,8 @@ class WireGuardConfigModel : public QAbstractListModel
|
|||
|
||||
public:
|
||||
enum Roles {
|
||||
PortRole = Qt::UserRole + 1,
|
||||
SubnetAddressRole = Qt::UserRole + 1,
|
||||
PortRole,
|
||||
ClientMtuRole
|
||||
};
|
||||
|
||||
|
|
|
|||
72
client/ui/qml/Components/AdLabel.qml
Normal file
72
client/ui/qml/Components/AdLabel.qml
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Shapes
|
||||
import Qt5Compat.GraphicalEffects
|
||||
|
||||
import Style 1.0
|
||||
|
||||
import "../Config"
|
||||
import "../Controls2"
|
||||
import "../Controls2/TextTypes"
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
property real contentHeight: ad.implicitHeight + ad.anchors.topMargin + ad.anchors.bottomMargin
|
||||
|
||||
border.width: 1
|
||||
border.color: AmneziaStyle.color.goldenApricot
|
||||
color: AmneziaStyle.color.transparent
|
||||
radius: 13
|
||||
|
||||
visible: GC.isDesktop() && ServersModel.isDefaultServerFromApi
|
||||
&& ServersModel.isDefaultServerDefaultContainerHasSplitTunneling && SettingsController.isHomeAdLabelVisible
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
|
||||
onClicked: function() {
|
||||
Qt.openUrlExternally(LanguageModel.getCurrentSiteUrl() + "/premium")
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: ad
|
||||
anchors.fill: parent
|
||||
anchors.margins: 16
|
||||
|
||||
Image {
|
||||
source: "qrc:/images/controls/amnezia.svg"
|
||||
sourceSize: Qt.size(36, 36)
|
||||
|
||||
layer {
|
||||
effect: ColorOverlay {
|
||||
color: AmneziaStyle.color.paleGray
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CaptionTextType {
|
||||
Layout.fillWidth: true
|
||||
Layout.rightMargin: 10
|
||||
Layout.leftMargin: 10
|
||||
|
||||
text: qsTr("Amnezia Premium - for access to any website")
|
||||
color: AmneziaStyle.color.pearlGray
|
||||
|
||||
lineHeight: 18
|
||||
font.pixelSize: 15
|
||||
}
|
||||
|
||||
ImageButtonType {
|
||||
image: "qrc:/images/controls/close.svg"
|
||||
imageColor: AmneziaStyle.color.paleGray
|
||||
|
||||
onClicked: function() {
|
||||
SettingsController.disableHomeAdLabel()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -12,7 +12,7 @@ Item {
|
|||
readonly property string drawerExpandedStateName: "expanded"
|
||||
readonly property string drawerCollapsedStateName: "collapsed"
|
||||
|
||||
readonly property bool isOpened: isExpandedStateActive() || (isCollapsedStateActive && (dragArea.drag.active === true))
|
||||
readonly property bool isOpened: isExpandedStateActive() || (isCollapsedStateActive() && (dragArea.drag.active === true))
|
||||
readonly property bool isClosed: isCollapsedStateActive() && (dragArea.drag.active === false)
|
||||
|
||||
property Component collapsedStateContent
|
||||
|
|
@ -123,7 +123,7 @@ Item {
|
|||
id: background
|
||||
|
||||
anchors.fill: parent
|
||||
color: root.isCollapsed ? AmneziaStyle.color.transparent : AmneziaStyle.color.translucentMidnightBlack
|
||||
color: root.isCollapsedStateActive() ? AmneziaStyle.color.transparent : AmneziaStyle.color.translucentMidnightBlack
|
||||
|
||||
Behavior on color {
|
||||
PropertyAnimation { duration: 200 }
|
||||
|
|
|
|||
|
|
@ -216,9 +216,7 @@ Item {
|
|||
ColumnLayout {
|
||||
id: header
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.fill: parent
|
||||
anchors.topMargin: 16
|
||||
|
||||
BackButtonType {
|
||||
|
|
@ -226,31 +224,21 @@ Item {
|
|||
backButtonImage: root.headerBackButtonImage
|
||||
backButtonFunction: function() { menu.closeTriggered() }
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
id: col
|
||||
anchors.top: header.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: 16
|
||||
|
||||
spacing: 16
|
||||
|
||||
Header2Type {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.leftMargin: 16
|
||||
anchors.rightMargin: 16
|
||||
Layout.leftMargin: 16
|
||||
Layout.rightMargin: 16
|
||||
Layout.bottomMargin: 16
|
||||
Layout.fillWidth: true
|
||||
|
||||
headerText: root.headerText
|
||||
|
||||
width: parent.width
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: listViewLoader
|
||||
sourceComponent: root.listView
|
||||
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ ListView {
|
|||
|
||||
property bool isFocusable: true
|
||||
|
||||
ScrollBar.vertical: ScrollBarType {}
|
||||
|
||||
ButtonGroup {
|
||||
id: buttonGroup
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,5 +26,6 @@ QtObject {
|
|||
readonly property color softGoldenApricot: Qt.rgba(251/255, 178/255, 106/255, 0.3)
|
||||
readonly property color mistyGray: Qt.rgba(215/255, 216/255, 219/255, 0.8)
|
||||
readonly property color cloudyGray: Qt.rgba(215/255, 216/255, 219/255, 0.65)
|
||||
readonly property color pearlGray: '#EAEAEC'
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Qt5Compat.GraphicalEffects
|
||||
|
||||
import SortFilterProxyModel 0.2
|
||||
|
||||
|
|
@ -42,8 +43,18 @@ PageType {
|
|||
objectName: "homeColumnLayout"
|
||||
|
||||
anchors.fill: parent
|
||||
anchors.topMargin: 34
|
||||
anchors.bottomMargin: 34
|
||||
anchors.topMargin: 12
|
||||
anchors.bottomMargin: 16
|
||||
|
||||
AdLabel {
|
||||
id: adLabel
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: adLabel.contentHeight
|
||||
Layout.leftMargin: 16
|
||||
Layout.rightMargin: 16
|
||||
Layout.bottomMargin: 22
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
id: loggingButton
|
||||
|
|
@ -86,7 +97,6 @@ PageType {
|
|||
objectName: "splitTunnelingButton"
|
||||
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
|
||||
Layout.bottomMargin: 34
|
||||
leftPadding: 16
|
||||
rightPadding: 16
|
||||
|
||||
|
|
@ -256,11 +266,11 @@ PageType {
|
|||
objectName: "rowLayoutLabel"
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
Layout.topMargin: 8
|
||||
Layout.bottomMargin: drawer.isCollapsed ? 44 : ServersModel.isDefaultServerFromApi ? 61 : 16
|
||||
Layout.bottomMargin: drawer.isCollapsedStateActive ? 44 : ServersModel.isDefaultServerFromApi ? 61 : 16
|
||||
spacing: 0
|
||||
|
||||
BasicButtonType {
|
||||
enabled: (ServersModel.defaultServerImagePathCollapsed !== "") && drawer.isCollapsed
|
||||
enabled: (ServersModel.defaultServerImagePathCollapsed !== "") && drawer.isCollapsedStateActive
|
||||
hoverEnabled: enabled
|
||||
|
||||
implicitHeight: 36
|
||||
|
|
@ -278,8 +288,9 @@ PageType {
|
|||
buttonTextLabel.font.pixelSize: 13
|
||||
buttonTextLabel.font.weight: 400
|
||||
|
||||
text: drawer.isCollapsed ? ServersModel.defaultServerDescriptionCollapsed : ServersModel.defaultServerDescriptionExpanded
|
||||
text: drawer.isCollapsedStateActive ? ServersModel.defaultServerDescriptionCollapsed : ServersModel.defaultServerDescriptionExpanded
|
||||
leftImageSource: ServersModel.defaultServerImagePathCollapsed
|
||||
leftImageColor: ""
|
||||
changeLeftImageSize: false
|
||||
|
||||
rightImageSource: hoverEnabled ? "qrc:/images/controls/chevron-down.svg" : ""
|
||||
|
|
@ -337,7 +348,6 @@ PageType {
|
|||
objectName: "containersListView"
|
||||
|
||||
rootWidth: root.width
|
||||
height: 500 // TODO: make calculated
|
||||
|
||||
Connections {
|
||||
objectName: "rowLayoutConnections"
|
||||
|
|
|
|||
|
|
@ -36,13 +36,13 @@ PageType {
|
|||
ListView {
|
||||
id: listview
|
||||
|
||||
property bool isFocusable: true
|
||||
|
||||
anchors.top: backButtonLayout.bottom
|
||||
anchors.bottom: parent.bottom
|
||||
|
||||
width: parent.width
|
||||
|
||||
property bool isFocusable: true
|
||||
|
||||
Keys.onTabPressed: {
|
||||
FocusController.nextKeyTabItem()
|
||||
}
|
||||
|
|
@ -76,7 +76,7 @@ PageType {
|
|||
implicitWidth: listview.width
|
||||
implicitHeight: col.implicitHeight
|
||||
|
||||
property alias portTextField: portTextField
|
||||
property alias vpnAddressSubnetTextField: vpnAddressSubnetTextField
|
||||
property bool isEnabled: ServersModel.isProcessedServerHasWriteAccess()
|
||||
|
||||
ColumnLayout {
|
||||
|
|
@ -98,12 +98,32 @@ PageType {
|
|||
}
|
||||
|
||||
TextFieldWithHeaderType {
|
||||
id: portTextField
|
||||
id: vpnAddressSubnetTextField
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 40
|
||||
|
||||
enabled: delegateItem.isEnabled
|
||||
|
||||
headerText: qsTr("VPN address subnet")
|
||||
textFieldText: subnetAddress
|
||||
|
||||
textField.onEditingFinished: {
|
||||
if (textFieldText !== subnetAddress) {
|
||||
subnetAddress = textFieldText
|
||||
}
|
||||
}
|
||||
|
||||
checkEmptyText: true
|
||||
}
|
||||
|
||||
TextFieldWithHeaderType {
|
||||
id: portTextField
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 16
|
||||
|
||||
enabled: delegateItem.isEnabled
|
||||
|
||||
headerText: qsTr("Port")
|
||||
textFieldText: port
|
||||
textField.maximumLength: 5
|
||||
|
|
@ -118,26 +138,6 @@ PageType {
|
|||
checkEmptyText: true
|
||||
}
|
||||
|
||||
TextFieldWithHeaderType {
|
||||
id: mtuTextField
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 16
|
||||
|
||||
headerText: qsTr("MTU")
|
||||
textFieldText: mtu
|
||||
textField.validator: IntValidator { bottom: 576; top: 65535 }
|
||||
|
||||
textField.onEditingFinished: {
|
||||
if (textFieldText === "") {
|
||||
textFieldText = "0"
|
||||
}
|
||||
if (textFieldText !== mtu) {
|
||||
mtu = textFieldText
|
||||
}
|
||||
}
|
||||
checkEmptyText: true
|
||||
}
|
||||
|
||||
TextFieldWithHeaderType {
|
||||
id: junkPacketCountTextField
|
||||
Layout.fillWidth: true
|
||||
|
|
@ -332,7 +332,8 @@ PageType {
|
|||
junkPacketMaxSizeTextField.errorText === "" &&
|
||||
junkPacketMinSizeTextField.errorText === "" &&
|
||||
junkPacketCountTextField.errorText === "" &&
|
||||
portTextField.errorText === ""
|
||||
portTextField.errorText === "" &&
|
||||
vpnAddressSubnetTextField.errorText === ""
|
||||
|
||||
text: qsTr("Save")
|
||||
|
||||
|
|
|
|||
|
|
@ -176,7 +176,6 @@ PageType {
|
|||
headerText: qsTr("Hash")
|
||||
|
||||
drawerParent: root
|
||||
parentFlickable: fl
|
||||
|
||||
listView: ListViewWithRadioButtonType {
|
||||
id: hashListView
|
||||
|
|
@ -225,7 +224,6 @@ PageType {
|
|||
headerText: qsTr("Cipher")
|
||||
|
||||
drawerParent: root
|
||||
parentFlickable: fl
|
||||
|
||||
listView: ListViewWithRadioButtonType {
|
||||
id: cipherListView
|
||||
|
|
|
|||
|
|
@ -16,8 +16,6 @@ import "../Components"
|
|||
PageType {
|
||||
id: root
|
||||
|
||||
defaultActiveFocusItem: listview.currentItem.mtuTextField.textField
|
||||
|
||||
Item {
|
||||
id: focusItem
|
||||
onFocusChanged: {
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ PageType {
|
|||
delegate: Item {
|
||||
id: delegateItem
|
||||
|
||||
property alias focusItemId: portTextField.textField
|
||||
property alias focusItemId: vpnAddressSubnetTextField
|
||||
property bool isEnabled: ServersModel.isProcessedServerHasWriteAccess()
|
||||
|
||||
implicitWidth: listview.width
|
||||
|
|
@ -83,12 +83,31 @@ PageType {
|
|||
}
|
||||
|
||||
TextFieldWithHeaderType {
|
||||
id: portTextField
|
||||
id: vpnAddressSubnetTextField
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 40
|
||||
|
||||
enabled: delegateItem.isEnabled
|
||||
|
||||
headerText: qsTr("VPN address subnet")
|
||||
textFieldText: subnetAddress
|
||||
|
||||
textField.onEditingFinished: {
|
||||
if (textFieldText !== subnetAddress) {
|
||||
subnetAddress = textFieldText
|
||||
}
|
||||
}
|
||||
|
||||
checkEmptyText: true
|
||||
}
|
||||
|
||||
TextFieldWithHeaderType {
|
||||
id: portTextField
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 16
|
||||
|
||||
enabled: delegateItem.isEnabled
|
||||
|
||||
headerText: qsTr("Port")
|
||||
textFieldText: port
|
||||
textField.maximumLength: 5
|
||||
|
|
@ -103,33 +122,14 @@ PageType {
|
|||
checkEmptyText: true
|
||||
}
|
||||
|
||||
TextFieldWithHeaderType {
|
||||
id: mtuTextField
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 16
|
||||
|
||||
headerText: qsTr("MTU")
|
||||
textFieldText: mtu
|
||||
textField.validator: IntValidator { bottom: 576; top: 65535 }
|
||||
|
||||
textField.onEditingFinished: {
|
||||
if (textFieldText === "") {
|
||||
textFieldText = "0"
|
||||
}
|
||||
if (textFieldText !== mtu) {
|
||||
mtu = textFieldText
|
||||
}
|
||||
}
|
||||
checkEmptyText: true
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
id: saveButton
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 24
|
||||
Layout.bottomMargin: 24
|
||||
|
||||
enabled: portTextField.errorText === ""
|
||||
enabled: portTextField.errorText === "" &&
|
||||
vpnAddressSubnetTextField.errorText === ""
|
||||
|
||||
text: qsTr("Save")
|
||||
|
||||
|
|
|
|||
|
|
@ -18,13 +18,13 @@ PageType {
|
|||
ListView {
|
||||
id: menuContent
|
||||
|
||||
property var selectedText
|
||||
property bool isFocusable: true
|
||||
|
||||
width: parent.width
|
||||
height: menuContent.contentItem.height
|
||||
height: parent.height
|
||||
|
||||
clip: true
|
||||
interactive: false
|
||||
interactive: true
|
||||
model: ApiCountryModel
|
||||
|
||||
ButtonGroup {
|
||||
|
|
@ -34,8 +34,8 @@ PageType {
|
|||
delegate: ColumnLayout {
|
||||
id: content
|
||||
|
||||
implicitWidth: parent.width
|
||||
implicitHeight: content.implicitHeight
|
||||
width: menuContent.width
|
||||
height: content.implicitHeight
|
||||
|
||||
RowLayout {
|
||||
VerticalRadioButton {
|
||||
|
|
|
|||
|
|
@ -221,15 +221,8 @@ PageType {
|
|||
SettingsController.clearSettings()
|
||||
PageController.goToPageHome()
|
||||
}
|
||||
|
||||
if (!GC.isMobile()) {
|
||||
// root.defaultActiveFocusItem.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
var noButtonFunction = function() {
|
||||
if (!GC.isMobile()) {
|
||||
// root.defaultActiveFocusItem.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
|
||||
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
||||
|
|
|
|||
|
|
@ -109,15 +109,8 @@ PageType {
|
|||
SettingsController.secondaryDns = "1.0.0.1"
|
||||
secondaryDns.textFieldText = SettingsController.secondaryDns
|
||||
PageController.showNotificationMessage(qsTr("Settings have been reset"))
|
||||
|
||||
if (!GC.isMobile()) {
|
||||
// defaultActiveFocusItem.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
var noButtonFunction = function() {
|
||||
if (!GC.isMobile()) {
|
||||
// defaultActiveFocusItem.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
|
||||
showQuestionDrawer(headerText, "", yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
||||
|
|
|
|||
|
|
@ -206,6 +206,32 @@ PageType {
|
|||
onClicked: { handler() }
|
||||
}
|
||||
}
|
||||
|
||||
footer: ColumnLayout {
|
||||
width: listView.width
|
||||
|
||||
BasicButtonType {
|
||||
id: siteLink2
|
||||
Layout.topMargin: 24
|
||||
Layout.bottomMargin: 16
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
implicitHeight: 32
|
||||
|
||||
defaultColor: AmneziaStyle.color.transparent
|
||||
hoveredColor: AmneziaStyle.color.translucentWhite
|
||||
pressedColor: AmneziaStyle.color.sheerWhite
|
||||
disabledColor: AmneziaStyle.color.mutedGray
|
||||
textColor: AmneziaStyle.color.goldenApricot
|
||||
|
||||
text: qsTr("Site Amnezia")
|
||||
|
||||
rightImageSource: "qrc:/images/controls/external-link.svg"
|
||||
|
||||
clickedFunc: function() {
|
||||
Qt.openUrlExternally(LanguageModel.getCurrentSiteUrl())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
property list<QtObject> variants: [
|
||||
|
|
|
|||
|
|
@ -355,6 +355,7 @@ PageType {
|
|||
serverSelectorListView.selectedIndex = 0
|
||||
}
|
||||
|
||||
serverSelectorListView.positionViewAtIndex(selectedIndex, ListView.Beginning)
|
||||
serverSelectorListView.triggerCurrentItem()
|
||||
}
|
||||
|
||||
|
|
@ -410,6 +411,7 @@ PageType {
|
|||
function onSeverSelectorIndexChanged() {
|
||||
var defaultContainer = proxyContainersModel.mapFromSource(ServersModel.getProcessedServerData("defaultContainer"))
|
||||
protocolSelectorListView.selectedIndex = defaultContainer
|
||||
protocolSelectorListView.positionViewAtIndex(selectedIndex, ListView.Beginning)
|
||||
protocolSelectorListView.triggerCurrentItem()
|
||||
}
|
||||
}
|
||||
|
|
@ -603,6 +605,7 @@ PageType {
|
|||
}
|
||||
|
||||
clip: true
|
||||
interactive: false
|
||||
reuseItems: true
|
||||
|
||||
delegate: Item {
|
||||
|
|
@ -667,7 +670,11 @@ PageType {
|
|||
ParagraphTextType {
|
||||
color: AmneziaStyle.color.mutedGray
|
||||
visible: creationDate
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumWidth: parent.width
|
||||
|
||||
maximumLineCount: 2
|
||||
wrapMode: Text.Wrap
|
||||
elide: Qt.ElideRight
|
||||
|
||||
text: qsTr("Creation date: %1").arg(creationDate)
|
||||
}
|
||||
|
|
@ -675,7 +682,11 @@ PageType {
|
|||
ParagraphTextType {
|
||||
color: AmneziaStyle.color.mutedGray
|
||||
visible: latestHandshake
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumWidth: parent.width
|
||||
|
||||
maximumLineCount: 2
|
||||
wrapMode: Text.Wrap
|
||||
elide: Qt.ElideRight
|
||||
|
||||
text: qsTr("Latest handshake: %1").arg(latestHandshake)
|
||||
}
|
||||
|
|
@ -683,7 +694,11 @@ PageType {
|
|||
ParagraphTextType {
|
||||
color: AmneziaStyle.color.mutedGray
|
||||
visible: dataReceived
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumWidth: parent.width
|
||||
|
||||
maximumLineCount: 2
|
||||
wrapMode: Text.Wrap
|
||||
elide: Qt.ElideRight
|
||||
|
||||
text: qsTr("Data received: %1").arg(dataReceived)
|
||||
}
|
||||
|
|
@ -691,7 +706,11 @@ PageType {
|
|||
ParagraphTextType {
|
||||
color: AmneziaStyle.color.mutedGray
|
||||
visible: dataSent
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumWidth: parent.width
|
||||
|
||||
maximumLineCount: 2
|
||||
wrapMode: Text.Wrap
|
||||
elide: Qt.ElideRight
|
||||
|
||||
text: qsTr("Data sent: %1").arg(dataSent)
|
||||
}
|
||||
|
|
@ -699,7 +718,9 @@ PageType {
|
|||
ParagraphTextType {
|
||||
color: AmneziaStyle.color.mutedGray
|
||||
visible: allowedIps
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumWidth: parent.width
|
||||
|
||||
wrapMode: Text.Wrap
|
||||
|
||||
text: qsTr("Allowed IPs: %1").arg(allowedIps)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -348,7 +348,7 @@ PageType {
|
|||
objectName: "settingsTabButton"
|
||||
|
||||
isSelected: tabBar.currentIndex === 2
|
||||
image: "qrc:/images/controls/settings-2.svg"
|
||||
image: "qrc:/images/controls/settings.svg"
|
||||
clickedFunc: function () {
|
||||
tabBarStackView.goToTabBarPage(PageEnum.PageSettings)
|
||||
tabBar.currentIndex = 2
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ IpcProcessTun2Socks::IpcProcessTun2Socks(QObject *parent) :
|
|||
IpcProcessTun2SocksSource(parent),
|
||||
m_t2sProcess(QSharedPointer<QProcess>(new QProcess()))
|
||||
{
|
||||
connect(m_t2sProcess.data(), &QProcess::stateChanged, this, &IpcProcessTun2Socks::stateChanged);
|
||||
qDebug() << "IpcProcessTun2Socks::IpcProcessTun2Socks()";
|
||||
|
||||
}
|
||||
|
|
@ -23,8 +22,10 @@ IpcProcessTun2Socks::~IpcProcessTun2Socks()
|
|||
|
||||
void IpcProcessTun2Socks::start()
|
||||
{
|
||||
connect(m_t2sProcess.data(), &QProcess::stateChanged, this, &IpcProcessTun2Socks::stateChanged);
|
||||
qDebug() << "IpcProcessTun2Socks::start()";
|
||||
m_t2sProcess->setProgram(amnezia::permittedProcessPath(static_cast<amnezia::PermittedProcess>(amnezia::PermittedProcess::Tun2Socks)));
|
||||
|
||||
QString XrayConStr = "socks5://127.0.0.1:10808";
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
|
|
@ -41,7 +42,11 @@ void IpcProcessTun2Socks::start()
|
|||
|
||||
m_t2sProcess->setArguments(arguments);
|
||||
|
||||
Utils::killProcessByName(m_t2sProcess->program());
|
||||
if (Utils::processIsRunning(Utils::executable("tun2socks", false))) {
|
||||
qDebug().noquote() << "kill previos tun2socks";
|
||||
Utils::killProcessByName(Utils::executable("tun2socks", false));
|
||||
}
|
||||
|
||||
m_t2sProcess->start();
|
||||
|
||||
connect(m_t2sProcess.data(), &QProcess::readyReadStandardOutput, this, [this]() {
|
||||
|
|
@ -54,12 +59,10 @@ void IpcProcessTun2Socks::start()
|
|||
connect(m_t2sProcess.data(), QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, [this](int exitCode, QProcess::ExitStatus exitStatus) {
|
||||
qDebug().noquote() << "tun2socks finished, exitCode, exiStatus" << exitCode << exitStatus;
|
||||
emit setConnectionState(Vpn::ConnectionState::Disconnected);
|
||||
if (exitStatus != QProcess::NormalExit){
|
||||
stop();
|
||||
}
|
||||
if (exitCode !=0 ){
|
||||
stop();
|
||||
if ((exitStatus != QProcess::NormalExit) || (exitCode != 0)) {
|
||||
emit setConnectionState(Vpn::ConnectionState::Error);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
m_t2sProcess->start();
|
||||
|
|
@ -69,6 +72,8 @@ void IpcProcessTun2Socks::start()
|
|||
void IpcProcessTun2Socks::stop()
|
||||
{
|
||||
qDebug() << "IpcProcessTun2Socks::stop()";
|
||||
m_t2sProcess->close();
|
||||
m_t2sProcess->disconnect();
|
||||
m_t2sProcess->kill();
|
||||
m_t2sProcess->waitForFinished(3000);
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -152,21 +152,29 @@ bool RouterLinux::routeDeleteList(const QString &gw, const QStringList &ips)
|
|||
return cnt;
|
||||
}
|
||||
|
||||
bool RouterLinux::isServiceActive(const QString &serviceName) {
|
||||
QProcess process;
|
||||
process.start("systemctl", { "is-active", "--quiet", serviceName });
|
||||
process.waitForFinished();
|
||||
|
||||
return process.exitCode() == 0;
|
||||
}
|
||||
|
||||
void RouterLinux::flushDns()
|
||||
{
|
||||
QProcess p;
|
||||
p.setProcessChannelMode(QProcess::MergedChannels);
|
||||
|
||||
//check what the dns manager use
|
||||
if (QFileInfo::exists("/usr/bin/nscd")
|
||||
|| QFileInfo::exists("/usr/sbin/nscd")
|
||||
|| QFileInfo::exists("/usr/lib/systemd/system/nscd.service"))
|
||||
{
|
||||
if (isServiceActive("nscd.service")) {
|
||||
qDebug() << "Restarting nscd.service";
|
||||
p.start("systemctl", { "restart", "nscd" });
|
||||
}
|
||||
else
|
||||
{
|
||||
} else if (isServiceActive("systemd-resolved.service")) {
|
||||
qDebug() << "Restarting systemd-resolved.service";
|
||||
p.start("systemctl", { "restart", "systemd-resolved" });
|
||||
} else {
|
||||
qDebug() << "No suitable DNS manager found.";
|
||||
return;
|
||||
}
|
||||
|
||||
p.waitForFinished();
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ private:
|
|||
RouterLinux(RouterLinux const &) = delete;
|
||||
RouterLinux& operator= (RouterLinux const&) = delete;
|
||||
|
||||
bool isServiceActive(const QString &serviceName);
|
||||
QList<Route> m_addedRoutes;
|
||||
DnsUtilsLinux *m_dnsUtil;
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue