Compare commits

...

35 Commits

Author SHA1 Message Date
vladimir.kuznetsov f309a358c3 Merge branch 'update_server_scripts' of github.com:amnezia-vpn/amnezia-client into feature/new-awg-docker-container 2024-02-24 14:41:08 +05:00
vladimir.kuznetsov be0ec37738 Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into HEAD 2024-02-24 14:40:14 +05:00
vladimir.kuznetsov 179c6093ce Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into feature/new-awg-docker-container 2024-02-24 14:37:26 +05:00
vladimir.kuznetsov 10933ce466 added backward compatibility for the old awg container 2024-02-24 14:34:47 +05:00
pokamest 13aadbda64 Merge pull request #637 from amnezia-vpn/bugfix/connection-drawer-close-button
fixed connection drawer close button
2024-02-23 09:56:52 -08:00
agalehaga c7c7c8eb01 added export awg native format (#635)
add export awg native format
2024-02-23 17:55:59 +00:00
vladimir.kuznetsov b1e5bba33f fixed connection drawer close button 2024-02-23 22:51:46 +05:00
pokamest 474e7c6d62 Merge pull request #634 from amnezia-vpn/update/gh_actions_qt_update
Update Qt in deploy.yml
2024-02-22 06:02:04 -08:00
pokamest 794ec921b8 Update Qt in deploy.yml 2024-02-22 13:28:37 +00:00
pokamest b674240362 Merge pull request #632 from amnezia-vpn/refactoring/changing-settings-item-location
moving settings item to other settings page
2024-02-22 05:02:13 -08:00
pokamest a768c7c451 Merge pull request #633 from rodionos/patch-1
MacOS build: increase image size to 256Mb
2024-02-22 04:58:21 -08:00
Sergei Rodionov 28d2a4ec2c MacOS build: increase image size to 256Mb
In my case, using Qt 6.6.2, the size of the AmneziaVPN.dmg file is 226Mb so a higher image size is needed for the hdiutil command.
2024-02-22 13:57:58 +03:00
vladimir.kuznetsov cd9cdd24ec Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into feature/new-awg-docker-container 2024-02-22 15:49:41 +05:00
Shehab Ahmed 9f1210d18f changed the location of Auto connect item from settings connections page to settings application page 2024-02-22 02:31:51 +02:00
pokamest 3012559627 Merge pull request #630 from amnezia-vpn/feature/api-containers-listview
for api servers, removed the ability to select a container
2024-02-21 11:03:18 -08:00
vladimir.kuznetsov b3ed57aee7 for api servers, removed the ability to select a container 2024-02-21 23:41:47 +05:00
vladimir.kuznetsov 144ed3c988 updated the paths to awg files and interfaces to match the new docker container 2024-02-21 19:06:16 +05:00
pokamest 89d0a8107d Merge pull request #620 from amnezia-vpn/translations/fix-for-pr618
Fix translation for #618
2024-02-21 06:03:12 -08:00
Andrey Zaharow 6c0b71bd1b Fix translation on About Page (#618)
Fix About Page
2024-02-21 14:01:53 +00:00
Nethius 61abf74b2d feature/page-home-split-tunneling (#540)
Added split tunneling button on home page
2024-02-21 11:27:27 +00:00
pokamest 21fdf02921 Merge pull request #625 from amnezia-vpn/bugfix/default-server-default-container-update
fixed the use of defaultServerDefaultContainerChanged
2024-02-21 03:22:09 -08:00
vladimir.kuznetsov e046b6df04 Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into update_server_scripts 2024-02-21 15:00:54 +05:00
vladimir.kuznetsov 7a245d80ee fixed the use of defaultServerDefaultContainerChanged 2024-02-21 13:06:39 +05:00
KsZnak da85922f23 Update amneziavpn_zh_CN.ts (#617)
Update amneziavpn_zh_CN.ts
2024-02-20 20:49:26 +00:00
pokamest a5356b6319 Merge pull request #623 from amnezia-vpn/update/Arabic-translation
updated the Arabic translation for fixing some sentences
2024-02-20 12:47:41 -08:00
KsZnak 3828891b9b Update amneziavpn_fa_IR.ts (#622)
Update amneziavpn_fa_IR.ts
2024-02-20 20:46:23 +00:00
pokamest 15d866ce04 WG/AWG ipv6 fix (#621)
WG/AWG ipv6 fix
2024-02-20 19:05:36 +00:00
Shehab Ahmed 560eb3d620 updated the Arabic translation for fixing some sentences 2024-02-20 20:37:19 +02:00
Andrey Zaharow ac894254cc Fix translation for #618 2024-02-20 00:23:20 +01:00
pokamest 17e3fbde25 Merge pull request #616 from amnezia-vpn/bugfix/cursor-changing-fix
Fix cursor change when hover over elements
2024-02-19 12:20:46 -08:00
Andrey Zaharow ee11a8410c Fix cursor change when hover over elements 2024-02-19 18:28:29 +01:00
pokamest ff5c51cfd9 Merge pull request #615 from amnezia-vpn/KsZnak-patch-1
Update amneziavpn_ru.ts
2024-02-19 07:10:49 -08:00
Nethius b3943ae5e3 serversModel cleanup (#599) 2024-02-19 14:54:15 +00:00
KsZnak dc9069f1f4 Update_2_amneziavpn_ru.ts
Add new change
2024-02-19 13:37:40 +02:00
root 548959752c rename interface and config file name to awg0
change base docker image to amneziavpn/amneziawg-go:latest
2024-02-15 11:07:09 +07:00
62 changed files with 803 additions and 432 deletions
+7 -7
View File
@@ -14,8 +14,8 @@ jobs:
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
env: env:
QT_VERSION: 6.5.1 QT_VERSION: 6.6.2
QIF_VERSION: 4.6 QIF_VERSION: 4.7
steps: steps:
- name: 'Install Qt' - name: 'Install Qt'
@@ -72,8 +72,8 @@ jobs:
runs-on: windows-latest runs-on: windows-latest
env: env:
QT_VERSION: 6.5.1 QT_VERSION: 6.6.2
QIF_VERSION: 4.6 QIF_VERSION: 4.7
BUILD_ARCH: 64 BUILD_ARCH: 64
steps: steps:
@@ -134,7 +134,7 @@ jobs:
runs-on: macos-13 runs-on: macos-13
env: env:
QT_VERSION: 6.5.2 QT_VERSION: 6.6.2
CC: cc CC: cc
CXX: c++ CXX: c++
@@ -227,7 +227,7 @@ jobs:
env: env:
# Keep compat with MacOS 10.15 aka Catalina by Qt 6.4 # Keep compat with MacOS 10.15 aka Catalina by Qt 6.4
QT_VERSION: 6.4.3 QT_VERSION: 6.4.3
QIF_VERSION: 4.6 QIF_VERSION: 4.7
steps: steps:
- name: 'Setup xcode' - name: 'Setup xcode'
@@ -286,7 +286,7 @@ jobs:
env: env:
ANDROID_BUILD_PLATFORM: android-34 ANDROID_BUILD_PLATFORM: android-34
QT_VERSION: 6.6.1 QT_VERSION: 6.6.2
QT_MODULES: 'qtremoteobjects qt5compat qtimageformats qtshadertools' QT_MODULES: 'qtremoteobjects qt5compat qtimageformats qtshadertools'
steps: steps:
+3
View File
@@ -131,3 +131,6 @@ client/3rd/ShadowSocks/ss_ios.xcconfig
# UML generated pics # UML generated pics
out/ out/
# CMake files
CMakeFiles/
+9
View File
@@ -15,6 +15,15 @@ set(PACKAGES
Core5Compat Concurrent LinguistTools Core5Compat Concurrent LinguistTools
) )
execute_process(
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
COMMAND git rev-parse --short HEAD
OUTPUT_VARIABLE GIT_COMMIT_HASH
OUTPUT_STRIP_TRAILING_WHITESPACE
)
add_definitions(-DGIT_COMMIT_HASH="${GIT_COMMIT_HASH}")
if(IOS) if(IOS)
set(PACKAGES ${PACKAGES} Multimedia) set(PACKAGES ${PACKAGES} Multimedia)
endif() endif()
+7 -1
View File
@@ -286,10 +286,16 @@ void AmneziaApplication::initModels()
m_containersModel.reset(new ContainersModel(this)); m_containersModel.reset(new ContainersModel(this));
m_engine->rootContext()->setContextProperty("ContainersModel", m_containersModel.get()); m_engine->rootContext()->setContextProperty("ContainersModel", m_containersModel.get());
m_defaultServerContainersModel.reset(new ContainersModel(this));
m_engine->rootContext()->setContextProperty("DefaultServerContainersModel", m_defaultServerContainersModel.get());
m_serversModel.reset(new ServersModel(m_settings, this)); m_serversModel.reset(new ServersModel(m_settings, this));
m_engine->rootContext()->setContextProperty("ServersModel", m_serversModel.get()); m_engine->rootContext()->setContextProperty("ServersModel", m_serversModel.get());
connect(m_serversModel.get(), &ServersModel::containersUpdated, m_containersModel.get(), connect(m_serversModel.get(), &ServersModel::containersUpdated, m_containersModel.get(),
&ContainersModel::updateModel); &ContainersModel::updateModel);
connect(m_serversModel.get(), &ServersModel::defaultServerContainersUpdated, m_defaultServerContainersModel.get(),
&ContainersModel::updateModel);
m_serversModel->resetModel();
m_languageModel.reset(new LanguageModel(m_settings, this)); m_languageModel.reset(new LanguageModel(m_settings, this));
m_engine->rootContext()->setContextProperty("LanguageModel", m_languageModel.get()); m_engine->rootContext()->setContextProperty("LanguageModel", m_languageModel.get());
@@ -333,7 +339,7 @@ void AmneziaApplication::initModels()
connect(m_configurator.get(), &VpnConfigurator::newVpnConfigCreated, this, connect(m_configurator.get(), &VpnConfigurator::newVpnConfigCreated, this,
[this](const QString &clientId, const QString &clientName, const DockerContainer container, [this](const QString &clientId, const QString &clientName, const DockerContainer container,
ServerCredentials credentials) { ServerCredentials credentials) {
m_serversModel->reloadContainerConfig(); m_serversModel->reloadDefaultServerContainerConfig();
m_clientManagementModel->appendClient(clientId, clientName, container, credentials); m_clientManagementModel->appendClient(clientId, clientName, container, credentials);
emit m_configurator->clientModelUpdated(); emit m_configurator->clientModelUpdated();
}); });
+1
View File
@@ -92,6 +92,7 @@ private:
QCommandLineParser m_parser; QCommandLineParser m_parser;
QSharedPointer<ContainersModel> m_containersModel; QSharedPointer<ContainersModel> m_containersModel;
QSharedPointer<ContainersModel> m_defaultServerContainersModel;
QSharedPointer<ServersModel> m_serversModel; QSharedPointer<ServersModel> m_serversModel;
QSharedPointer<LanguageModel> m_languageModel; QSharedPointer<LanguageModel> m_languageModel;
QSharedPointer<ProtocolsModel> m_protocolsModel; QSharedPointer<ProtocolsModel> m_protocolsModel;
+30 -12
View File
@@ -13,26 +13,29 @@
#include <openssl/x509.h> #include <openssl/x509.h>
#include "containers/containers_defs.h" #include "containers/containers_defs.h"
#include "core/controllers/serverController.h"
#include "core/scripts_registry.h" #include "core/scripts_registry.h"
#include "core/server_defs.h" #include "core/server_defs.h"
#include "core/controllers/serverController.h"
#include "settings.h" #include "settings.h"
#include "utilities.h" #include "utilities.h"
WireguardConfigurator::WireguardConfigurator(std::shared_ptr<Settings> settings, bool isAwg, QObject *parent) WireguardConfigurator::WireguardConfigurator(std::shared_ptr<Settings> settings, bool isAwg, QObject *parent)
: ConfiguratorBase(settings, parent), m_isAwg(isAwg) : ConfiguratorBase(settings, parent), m_isAwg(isAwg)
{ {
m_serverConfigPath = m_isAwg ? amnezia::protocols::awg::serverConfigPath m_serverConfigPath =
: amnezia::protocols::wireguard::serverConfigPath; m_isAwg ? amnezia::protocols::awg::serverConfigPath : amnezia::protocols::wireguard::serverConfigPath;
m_serverPublicKeyPath = m_isAwg ? amnezia::protocols::awg::serverPublicKeyPath m_serverPublicKeyPath =
: amnezia::protocols::wireguard::serverPublicKeyPath; m_isAwg ? amnezia::protocols::awg::serverPublicKeyPath : amnezia::protocols::wireguard::serverPublicKeyPath;
m_serverPskKeyPath = m_isAwg ? amnezia::protocols::awg::serverPskKeyPath m_serverPskKeyPath =
: amnezia::protocols::wireguard::serverPskKeyPath; m_isAwg ? amnezia::protocols::awg::serverPskKeyPath : amnezia::protocols::wireguard::serverPskKeyPath;
m_configTemplate = m_isAwg ? ProtocolScriptType::awg_template m_configTemplate = m_isAwg ? ProtocolScriptType::awg_template : ProtocolScriptType::wireguard_template;
: ProtocolScriptType::wireguard_template;
m_protocolName = m_isAwg ? config_key::awg : config_key::wireguard; m_protocolName = m_isAwg ? config_key::awg : config_key::wireguard;
m_defaultPort = m_isAwg ? protocols::wireguard::defaultPort : protocols::awg::defaultPort; m_defaultPort = m_isAwg ? protocols::wireguard::defaultPort : protocols::awg::defaultPort;
m_interfaceName = m_isAwg ? protocols::awg::interfaceName : protocols::wireguard::interfaceName;
m_wgBinaryName = m_isAwg ? protocols::awg::wgBinaryName : protocols::wireguard::wgBinaryName;
m_wgQuickBinaryName = m_isAwg ? protocols::awg::wgQuickBinaryName : protocols::wireguard::wgQuickBinaryName;
} }
WireguardConfigurator::ConnectionData WireguardConfigurator::genClientKeys() WireguardConfigurator::ConnectionData WireguardConfigurator::genClientKeys()
@@ -84,6 +87,20 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
ErrorCode e = ErrorCode::NoError; ErrorCode e = ErrorCode::NoError;
ServerController serverController(m_settings); ServerController serverController(m_settings);
if (container == DockerContainer::Awg) {
if (serverController.isNewAwgContainer(credentials)) {
m_serverConfigPath = amnezia::protocols::awg::serverConfigPath;
m_interfaceName = protocols::awg::interfaceName;
m_wgBinaryName = protocols::awg::wgBinaryName;
m_wgQuickBinaryName = protocols::awg::wgQuickBinaryName;
} else {
m_serverConfigPath = "/opt/amnezia/awg/wg0.conf";
m_interfaceName = protocols::wireguard::interfaceName;
m_wgBinaryName = protocols::wireguard::wgBinaryName;
m_wgQuickBinaryName = protocols::wireguard::wgQuickBinaryName;
}
}
// Get list of already created clients (only IP addresses) // Get list of already created clients (only IP addresses)
QString nextIpNumber; QString nextIpNumber;
{ {
@@ -167,8 +184,8 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
return connData; return connData;
} }
QString script = QString("sudo docker exec -i $CONTAINER_NAME bash -c 'wg syncconf wg0 <(wg-quick strip %1)'") QString script = QString("sudo docker exec -i $CONTAINER_NAME bash -c '%4 syncconf %2 <(%3 strip %1)'")
.arg(m_serverConfigPath); .arg(m_serverConfigPath, m_interfaceName, m_wgQuickBinaryName, m_wgBinaryName);
e = serverController.runScript( e = serverController.runScript(
credentials, serverController.replaceVars(script, serverController.genVarsForScript(credentials, container))); credentials, serverController.replaceVars(script, serverController.genVarsForScript(credentials, container)));
@@ -177,7 +194,8 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
} }
QString WireguardConfigurator::genWireguardConfig(const ServerCredentials &credentials, DockerContainer container, QString WireguardConfigurator::genWireguardConfig(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &containerConfig, QString &clientId, ErrorCode *errorCode) const QJsonObject &containerConfig, QString &clientId,
ErrorCode *errorCode)
{ {
ServerController serverController(m_settings); ServerController serverController(m_settings);
QString scriptData = amnezia::scriptData(m_configTemplate, container); QString scriptData = amnezia::scriptData(m_configTemplate, container);
@@ -44,6 +44,9 @@ private:
amnezia::ProtocolScriptType m_configTemplate; amnezia::ProtocolScriptType m_configTemplate;
QString m_protocolName; QString m_protocolName;
QString m_defaultPort; QString m_defaultPort;
QString m_interfaceName;
QString m_wgBinaryName;
QString m_wgQuickBinaryName;
}; };
#endif // WIREGUARD_CONFIGURATOR_H #endif // WIREGUARD_CONFIGURATOR_H
+31 -1
View File
@@ -855,7 +855,16 @@ ErrorCode ServerController::getAlreadyInstalledContainers(const ServerCredential
containerConfig.insert(config_key::transport_proto, transportProto); containerConfig.insert(config_key::transport_proto, transportProto);
if (protocol == Proto::Awg) { if (protocol == Proto::Awg) {
QString serverConfig = getTextFileFromContainer(container, credentials, protocols::awg::serverConfigPath, &errorCode); QString serverConfigPath;
if (container == DockerContainer::Awg) {
if (isNewAwgContainer(credentials)) {
serverConfigPath = amnezia::protocols::awg::serverConfigPath;
} else {
serverConfigPath = "/opt/amnezia/awg/wg0.conf";
}
}
QString serverConfig = getTextFileFromContainer(container, credentials, serverConfigPath, &errorCode);
QMap<QString, QString> serverConfigMap; QMap<QString, QString> serverConfigMap;
auto serverConfigLines = serverConfig.split("\n"); auto serverConfigLines = serverConfig.split("\n");
@@ -960,3 +969,24 @@ ErrorCode ServerController::getDecryptedPrivateKey(const ServerCredentials &cred
auto error = m_sshClient.getDecryptedPrivateKey(credentials, decryptedPrivateKey, callback); auto error = m_sshClient.getDecryptedPrivateKey(credentials, decryptedPrivateKey, callback);
return error; return error;
} }
bool ServerController::isNewAwgContainer(const ServerCredentials &credentials)
{
QString stdOut;
auto cbReadStdOut = [&](const QString &data, libssh::Client &) {
stdOut += data + "\n";
return ErrorCode::NoError;
};
auto cbReadStdErr = [&](const QString &data, libssh::Client &) {
stdOut += data + "\n";
return ErrorCode::NoError;
};
QString script = QString("sudo docker exec -i $CONTAINER_NAME bash -c 'type awg'");
runScript(credentials, replaceVars(script, genVarsForScript(credentials, DockerContainer::Awg)), cbReadStdOut, cbReadStdErr);
return stdOut.contains("/usr/bin/awg");
}
@@ -62,6 +62,8 @@ public:
ErrorCode getDecryptedPrivateKey(const ServerCredentials &credentials, QString &decryptedPrivateKey, ErrorCode getDecryptedPrivateKey(const ServerCredentials &credentials, QString &decryptedPrivateKey,
const std::function<QString()> &callback); const std::function<QString()> &callback);
bool isNewAwgContainer(const ServerCredentials &credentials);
private: private:
ErrorCode installDockerWorker(const ServerCredentials &credentials, DockerContainer container); ErrorCode installDockerWorker(const ServerCredentials &credentials, DockerContainer container);
ErrorCode prepareHostWorker(const ServerCredentials &credentials, DockerContainer container, ErrorCode prepareHostWorker(const ServerCredentials &credentials, DockerContainer container,
@@ -0,0 +1,6 @@
<svg width="19" height="18" viewBox="0 0 19 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="0.5" width="18" height="18" rx="5" fill="white"/>
<path d="M8.49219 13.5L8.49219 9.44141L14.0191 4.99484" stroke="#0E0E11" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M4.47363 5.49805L6.98828 8.0127" stroke="#0E0E11" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M14.4727 9.5L14.4727 4.5033L9.50195 4.5033" stroke="#0E0E11" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 511 B

+3
View File
@@ -124,7 +124,10 @@ void LocalSocketController::activate(const QJsonObject &rawConfig) {
// json.insert("hopindex", QJsonValue((double)hop.m_hopindex)); // json.insert("hopindex", QJsonValue((double)hop.m_hopindex));
json.insert("privateKey", wgConfig.value(amnezia::config_key::client_priv_key)); json.insert("privateKey", wgConfig.value(amnezia::config_key::client_priv_key));
json.insert("deviceIpv4Address", wgConfig.value(amnezia::config_key::client_ip)); json.insert("deviceIpv4Address", wgConfig.value(amnezia::config_key::client_ip));
// todo review wg ipv6
#ifndef Q_OS_WINDOWS
json.insert("deviceIpv6Address", "dead::1"); json.insert("deviceIpv6Address", "dead::1");
#endif
json.insert("serverPublicKey", wgConfig.value(amnezia::config_key::server_pub_key)); json.insert("serverPublicKey", wgConfig.value(amnezia::config_key::server_pub_key));
json.insert("serverPskKey", wgConfig.value(amnezia::config_key::psk_key)); json.insert("serverPskKey", wgConfig.value(amnezia::config_key::psk_key));
json.insert("serverIpv4AddrIn", wgConfig.value(amnezia::config_key::hostName)); json.insert("serverIpv4AddrIn", wgConfig.value(amnezia::config_key::hostName));
+8 -1
View File
@@ -152,6 +152,9 @@ namespace amnezia
constexpr char serverPublicKeyPath[] = "/opt/amnezia/wireguard/wireguard_server_public_key.key"; constexpr char serverPublicKeyPath[] = "/opt/amnezia/wireguard/wireguard_server_public_key.key";
constexpr char serverPskKeyPath[] = "/opt/amnezia/wireguard/wireguard_psk.key"; constexpr char serverPskKeyPath[] = "/opt/amnezia/wireguard/wireguard_psk.key";
constexpr char interfaceName[] = "wg0";
constexpr char wgBinaryName[] = "wg";
constexpr char wgQuickBinaryName[] = "wg-quick";
} }
namespace sftp namespace sftp
@@ -164,7 +167,7 @@ namespace amnezia
{ {
constexpr char defaultPort[] = "55424"; constexpr char defaultPort[] = "55424";
constexpr char serverConfigPath[] = "/opt/amnezia/awg/wg0.conf"; constexpr char serverConfigPath[] = "/opt/amnezia/awg/awg0.conf";
constexpr char serverPublicKeyPath[] = "/opt/amnezia/awg/wireguard_server_public_key.key"; constexpr char serverPublicKeyPath[] = "/opt/amnezia/awg/wireguard_server_public_key.key";
constexpr char serverPskKeyPath[] = "/opt/amnezia/awg/wireguard_psk.key"; constexpr char serverPskKeyPath[] = "/opt/amnezia/awg/wireguard_psk.key";
@@ -177,6 +180,10 @@ namespace amnezia
constexpr char defaultResponsePacketMagicHeader[] = "3288052141"; constexpr char defaultResponsePacketMagicHeader[] = "3288052141";
constexpr char defaultTransportPacketMagicHeader[] = "2528465083"; constexpr char defaultTransportPacketMagicHeader[] = "2528465083";
constexpr char defaultUnderloadPacketMagicHeader[] = "1766607858"; constexpr char defaultUnderloadPacketMagicHeader[] = "1766607858";
constexpr char interfaceName[] = "awg0";
constexpr char wgBinaryName[] = "awg";
constexpr char wgQuickBinaryName[] = "awg-quick";
} }
} // namespace protocols } // namespace protocols
+2
View File
@@ -224,6 +224,8 @@
<file>ui/qml/Pages2/PageShareFullAccess.qml</file> <file>ui/qml/Pages2/PageShareFullAccess.qml</file>
<file>images/controls/close.svg</file> <file>images/controls/close.svg</file>
<file>images/controls/search.svg</file> <file>images/controls/search.svg</file>
<file>ui/qml/Components/HomeSplitTunnelingDrawer.qml</file>
<file>images/controls/split-tunneling.svg</file>
<file>ui/qml/Controls2/DrawerType2.qml</file> <file>ui/qml/Controls2/DrawerType2.qml</file>
</qresource> </qresource>
</RCC> </RCC>
+1 -1
View File
@@ -1,4 +1,4 @@
FROM amneziavpn/amnezia-wg:latest FROM amneziavpn/amneziawg-go:latest
LABEL maintainer="AmneziaVPN" LABEL maintainer="AmneziaVPN"
@@ -1,15 +1,15 @@
mkdir -p /opt/amnezia/awg mkdir -p /opt/amnezia/awg
cd /opt/amnezia/awg cd /opt/amnezia/awg
WIREGUARD_SERVER_PRIVATE_KEY=$(wg genkey) WIREGUARD_SERVER_PRIVATE_KEY=$(awg genkey)
echo $WIREGUARD_SERVER_PRIVATE_KEY > /opt/amnezia/awg/wireguard_server_private_key.key echo $WIREGUARD_SERVER_PRIVATE_KEY > /opt/amnezia/awg/wireguard_server_private_key.key
WIREGUARD_SERVER_PUBLIC_KEY=$(echo $WIREGUARD_SERVER_PRIVATE_KEY | wg pubkey) WIREGUARD_SERVER_PUBLIC_KEY=$(echo $WIREGUARD_SERVER_PRIVATE_KEY | awg pubkey)
echo $WIREGUARD_SERVER_PUBLIC_KEY > /opt/amnezia/awg/wireguard_server_public_key.key echo $WIREGUARD_SERVER_PUBLIC_KEY > /opt/amnezia/awg/wireguard_server_public_key.key
WIREGUARD_PSK=$(wg genpsk) WIREGUARD_PSK=$(awg genpsk)
echo $WIREGUARD_PSK > /opt/amnezia/awg/wireguard_psk.key echo $WIREGUARD_PSK > /opt/amnezia/awg/wireguard_psk.key
cat > /opt/amnezia/awg/wg0.conf <<EOF cat > /opt/amnezia/awg/awg0.conf <<EOF
[Interface] [Interface]
PrivateKey = $WIREGUARD_SERVER_PRIVATE_KEY PrivateKey = $WIREGUARD_SERVER_PRIVATE_KEY
Address = $WIREGUARD_SUBNET_IP/$WIREGUARD_SUBNET_CIDR Address = $WIREGUARD_SUBNET_IP/$WIREGUARD_SUBNET_CIDR
+7 -7
View File
@@ -6,19 +6,19 @@ echo "Container startup"
#ifconfig eth0:0 $SERVER_IP_ADDRESS netmask 255.255.255.255 up #ifconfig eth0:0 $SERVER_IP_ADDRESS netmask 255.255.255.255 up
# kill daemons in case of restart # kill daemons in case of restart
wg-quick down /opt/amnezia/awg/wg0.conf awg-quick down /opt/amnezia/awg/awg0.conf
# start daemons if configured # start daemons if configured
if [ -f /opt/amnezia/awg/wg0.conf ]; then (wg-quick up /opt/amnezia/awg/wg0.conf); fi if [ -f /opt/amnezia/awg/awg0.conf ]; then (awg-quick up /opt/amnezia/awg/awg0.conf); fi
# Allow traffic on the TUN interface. # Allow traffic on the TUN interface.
iptables -A INPUT -i wg0 -j ACCEPT iptables -A INPUT -i awg0 -j ACCEPT
iptables -A FORWARD -i wg0 -j ACCEPT iptables -A FORWARD -i awg0 -j ACCEPT
iptables -A OUTPUT -o wg0 -j ACCEPT iptables -A OUTPUT -o awg0 -j ACCEPT
# Allow forwarding traffic only from the VPN. # 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 awg0 -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 awg0 -o eth1 -s $WIREGUARD_SUBNET_IP/$WIREGUARD_SUBNET_CIDR -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
+9 -8
View File
@@ -997,6 +997,11 @@ And if you don&apos;t like the app, all the more support it - the donation will
<source>https://amnezia.org</source> <source>https://amnezia.org</source>
<translation></translation> <translation></translation>
</message> </message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="176"/>
<source>Software version: %1</source>
<translation>%1 :إصدار البرنامج</translation>
</message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="192"/> <location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="192"/>
<source>Check for updates</source> <source>Check for updates</source>
@@ -1139,7 +1144,7 @@ And if you don&apos;t like the app, all the more support it - the donation will
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsBackup.qml" line="122"/> <location filename="../ui/qml/Pages2/PageSettingsBackup.qml" line="122"/>
<source>Restore from backup</source> <source>Restore from backup</source>
<translation>استرجاع من ملف احتياطي</translation> <translation>استرجاع من ملف يحتوي علي نسخة احتياطية</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsBackup.qml" line="125"/> <location filename="../ui/qml/Pages2/PageSettingsBackup.qml" line="125"/>
@@ -1339,7 +1344,7 @@ And if you don&apos;t like the app, all the more support it - the donation will
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsLogging.qml" line="128"/> <location filename="../ui/qml/Pages2/PageSettingsLogging.qml" line="128"/>
<source>Save logs to file</source> <source>Save logs to file</source>
<translation>احفظ السجلات لملف</translation> <translation>احفظ السجلات في ملف</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsLogging.qml" line="146"/> <location filename="../ui/qml/Pages2/PageSettingsLogging.qml" line="146"/>
@@ -1942,7 +1947,8 @@ It&apos;s okay as long as it&apos;s from someone you trust.</source>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardTextKey.qml" line="40"/> <location filename="../ui/qml/Pages2/PageSetupWizardTextKey.qml" line="40"/>
<source>A line that starts with vpn://...</source> <source>A line that starts with vpn://...</source>
<translation>سطر يبدأ ب vpn://...</translation> <translatorcomment>يجب ان تٌكتب بهذه الطريقة حتي بوجود الخطأ كي تظهر بشكل صحيح داخل التطبيق</translatorcomment>
<translation>سطر يبدأ ب ...//:vpn</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardTextKey.qml" line="51"/> <location filename="../ui/qml/Pages2/PageSetupWizardTextKey.qml" line="51"/>
@@ -2998,11 +3004,6 @@ While it offers a blend of security, stability, and speed, it&apos;s essential t
</context> </context>
<context> <context>
<name>SettingsController</name> <name>SettingsController</name>
<message>
<location filename="../ui/controllers/settingsController.cpp" line="31"/>
<source>Software version</source>
<translation>إصدار البرنامج</translation>
</message>
<message> <message>
<location filename="../ui/controllers/settingsController.cpp" line="139"/> <location filename="../ui/controllers/settingsController.cpp" line="139"/>
<source>Backup file is corrupted</source> <source>Backup file is corrupted</source>
+62 -46
View File
@@ -144,7 +144,7 @@
</message> </message>
<message> <message>
<source>Reconnect via VPN Procotol: </source> <source>Reconnect via VPN Procotol: </source>
<translation type="vanished">Переподключение через VPN протокол: </translation> <translation type="vanished">پروتکل VPN را متصل مجدد کنید" </translation>
</message> </message>
</context> </context>
<context> <context>
@@ -371,7 +371,7 @@ Already installed containers were found on the server. All installed containers
</message> </message>
<message> <message>
<source>All users who you shared a connection with will no longer be able to connect to it.</source> <source>All users who you shared a connection with will no longer be able to connect to it.</source>
<translation type="vanished">Все пользователи, с которыми вы поделились этим VPN-протоколом, больше не смогут к нему подключаться.</translation> <translation type="vanished">همه کاربرانی که با آنها این پروتکل VPN را به اشتراک گذاشتهاید دیگر نمیتوانند به آن متصل شوند.</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageProtocolAwgSettings.qml" line="280"/> <location filename="../ui/qml/Pages2/PageProtocolAwgSettings.qml" line="280"/>
@@ -604,7 +604,7 @@ Already installed containers were found on the server. All installed containers
</message> </message>
<message> <message>
<source>All users who you shared a connection with will no longer be able to connect to it.</source> <source>All users who you shared a connection with will no longer be able to connect to it.</source>
<translation type="vanished">Все пользователи, с которыми вы поделились этим VPN-протоколом, больше не смогут к нему подключаться.</translation> <translation type="vanished">همه کاربرانی که با آن این پروتکل VPN را به اشتراک گذاشتهاید دیگر نمیتوانند به آن متصل شوند.</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageProtocolOpenVpnSettings.qml" line="369"/> <location filename="../ui/qml/Pages2/PageProtocolOpenVpnSettings.qml" line="369"/>
@@ -656,7 +656,7 @@ Already installed containers were found on the server. All installed containers
</message> </message>
<message> <message>
<source>All users who you shared a connection with will no longer be able to connect to it.</source> <source>All users who you shared a connection with will no longer be able to connect to it.</source>
<translation type="obsolete">Все пользователи, с которыми вы поделились этим VPN-протоколом, больше не смогут к нему подключаться.</translation> <translation type="obsolete">همه کاربرانی که با آن این پروتکل VPN را به اشتراک گذاشتهاید دیگر نمیتوانند به آن متصل شوند.</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageProtocolRaw.qml" line="180"/> <location filename="../ui/qml/Pages2/PageProtocolRaw.qml" line="180"/>
@@ -697,7 +697,7 @@ Already installed containers were found on the server. All installed containers
<name>PageServerContainers</name> <name>PageServerContainers</name>
<message> <message>
<source>Continue</source> <source>Continue</source>
<translation type="obsolete">Продолжить</translation> <translation type="obsolete">ادامه دهید</translation>
</message> </message>
</context> </context>
<context> <context>
@@ -848,12 +848,12 @@ Already installed containers were found on the server. All installed containers
<message> <message>
<location filename="../ui/qml/Pages2/PageServiceTorWebsiteSettings.qml" line="94"/> <location filename="../ui/qml/Pages2/PageServiceTorWebsiteSettings.qml" line="94"/>
<source>Use &lt;a href=&quot;https://www.torproject.org/download/&quot; style=&quot;color: #FBB26A;&quot;&gt;Tor Browser&lt;/a&gt; to open this URL. </source> <source>Use &lt;a href=&quot;https://www.torproject.org/download/&quot; style=&quot;color: #FBB26A;&quot;&gt;Tor Browser&lt;/a&gt; to open this URL. </source>
<translation type="unfinished"></translation> <translation>استفاده &lt;a href=&quot;https://www.torproject.org/download/&quot; style=&quot;color: #FBB26A;&quot;&gt;Tor Browser&lt;/a&gt; برای باز کردن این نشانی.</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageServiceTorWebsiteSettings.qml" line="103"/> <location filename="../ui/qml/Pages2/PageServiceTorWebsiteSettings.qml" line="103"/>
<source>After creating your onion site, it takes a few minutes for the Tor network to make it available for use.</source> <source>After creating your onion site, it takes a few minutes for the Tor network to make it available for use.</source>
<translation type="unfinished"></translation> <translation>پس از ایجاد سایت پیاز خود، چند دقیقه طول میکشد تا شبکه تور آن را برای استفاده فراهم کند.</translation>
</message> </message>
<message> <message>
<source>Use &lt;a href=&quot;https://www.torproject.org/download/&quot; style=&quot;color: #FBB26A;&quot;&gt;Tor Browser&lt;/a&gt; to open this url.</source> <source>Use &lt;a href=&quot;https://www.torproject.org/download/&quot; style=&quot;color: #FBB26A;&quot;&gt;Tor Browser&lt;/a&gt; to open this url.</source>
@@ -870,7 +870,7 @@ Already installed containers were found on the server. All installed containers
</message> </message>
<message> <message>
<source>When configuring WordPress set the this address as domain.</source> <source>When configuring WordPress set the this address as domain.</source>
<translation type="vanished">При настройке WordPress укажите этот onion адрес в качестве домена.</translation> <translation type="vanished">هنگام تنظیم وردپرس، این آدرس پیاز را به عنوان دامنه مشخص کنید.</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageServiceTorWebsiteSettings.qml" line="126"/> <location filename="../ui/qml/Pages2/PageServiceTorWebsiteSettings.qml" line="126"/>
@@ -940,7 +940,7 @@ Already installed containers were found on the server. All installed containers
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="56"/> <location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="56"/>
<source>Support Amnezia</source> <source>Support Amnezia</source>
<translation type="unfinished"></translation> <translation>پشتیبانی از Amnezia</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="71"/> <location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="71"/>
@@ -1022,6 +1022,11 @@ Already installed containers were found on the server. All installed containers
<source>https://amnezia.org</source> <source>https://amnezia.org</source>
<translation>https://amnezia.org</translation> <translation>https://amnezia.org</translation>
</message> </message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="176"/>
<source>Software version: %1</source>
<translation>%1 :نسخه نرمافزار</translation>
</message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="192"/> <location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="192"/>
<source>Check for updates</source> <source>Check for updates</source>
@@ -1215,7 +1220,7 @@ Already installed containers were found on the server. All installed containers
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="86"/> <location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="86"/>
<source>When AmneziaDNS is not used or installed</source> <source>When AmneziaDNS is not used or installed</source>
<translation type="unfinished"></translation> <translation>وقتی AmneziaDNS استفاده نشده یا نصب نشده است.</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="120"/> <location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="120"/>
@@ -1251,7 +1256,7 @@ Already installed containers were found on the server. All installed containers
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsDns.qml" line="35"/> <location filename="../ui/qml/Pages2/PageSettingsDns.qml" line="35"/>
<source>Default server does not support custom dns</source> <source>Default server does not support custom dns</source>
<translation type="unfinished"></translation> <translation>سرور پیشفرض از دیاناس سفارشی پشتیبانی نمیکند.</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsDns.qml" line="53"/> <location filename="../ui/qml/Pages2/PageSettingsDns.qml" line="53"/>
@@ -1433,27 +1438,27 @@ Already installed containers were found on the server. All installed containers
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="139"/> <location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="139"/>
<source>Reboot server</source> <source>Reboot server</source>
<translation type="unfinished"></translation> <translation>سرور را دوباره راهاندازی کنید.</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="143"/> <location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="143"/>
<source>Do you want to reboot the server?</source> <source>Do you want to reboot the server?</source>
<translation type="unfinished"></translation> <translation>آیا میخواهید سرور را دوباره راهاندازی کنید؟</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="144"/> <location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="144"/>
<source>The reboot process may take approximately 30 seconds. Are you sure you wish to proceed?</source> <source>The reboot process may take approximately 30 seconds. Are you sure you wish to proceed?</source>
<translation type="unfinished"></translation> <translation>فرآیند راهاندازی ممکن است حدود ۳۰ ثانیه طول بکشد. آیا مطمئن هستید که میخواهید ادامه دهید؟</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="175"/> <location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="175"/>
<source>Do you want to remove the server from application?</source> <source>Do you want to remove the server from application?</source>
<translation type="unfinished"></translation> <translation>آیا میخواهید سرور را از برنامه حذف کنید؟</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="206"/> <location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="206"/>
<source>Do you want to clear server from Amnezia software?</source> <source>Do you want to clear server from Amnezia software?</source>
<translation type="unfinished"></translation> <translation>آیا میخواهید سرور را از نرمافزار Amnezia پاک کنید؟</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="171"/> <location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="171"/>
@@ -1536,7 +1541,7 @@ Already installed containers were found on the server. All installed containers
</message> </message>
<message> <message>
<source>All users who you shared a connection with will no longer be able to connect to it.</source> <source>All users who you shared a connection with will no longer be able to connect to it.</source>
<translation type="vanished">Все пользователи, которым вы поделились VPN, больше не смогут к нему подключаться.</translation> <translation type="vanished">تمام کاربرانی که با آن VPN را به اشتراک گذاشتهاید، دیگر نمیتوانند به آن متصل شوند.</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsServerProtocol.qml" line="118"/> <location filename="../ui/qml/Pages2/PageSettingsServerProtocol.qml" line="118"/>
@@ -1562,7 +1567,7 @@ Already installed containers were found on the server. All installed containers
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="29"/> <location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="29"/>
<source>Default server does not support split tunneling function</source> <source>Default server does not support split tunneling function</source>
<translation type="unfinished"></translation> <translation>سرور پیشفرض از عملکرد تونلسازی تقسیم شده پشتیبانی نمیکند.</translation>
</message> </message>
<message> <message>
<source>Addresses from the list should be accessed via VPN</source> <source>Addresses from the list should be accessed via VPN</source>
@@ -1609,17 +1614,17 @@ Already installed containers were found on the server. All installed containers
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="59"/> <location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="59"/>
<source>Only the sites listed here will be accessed through the VPN</source> <source>Only the sites listed here will be accessed through the VPN</source>
<translation type="unfinished"></translation> <translation>تنها سایتهای موجود در اینجا از طریق VPN دسترسی داده خواهند شد.</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="254"/> <location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="254"/>
<source>website or IP</source> <source>website or IP</source>
<translation type="unfinished"></translation> <translation>وبسایت یا آدرس IP</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="298"/> <location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="298"/>
<source>Import / Export Sites</source> <source>Import / Export Sites</source>
<translation type="unfinished"></translation> <translation>وارد کردن / صادر کردن وبسایتها</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="304"/> <location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="304"/>
@@ -1716,7 +1721,7 @@ It&apos;s okay as long as it&apos;s from someone you trust.</source>
<name>PageSetupWizardCredentials</name> <name>PageSetupWizardCredentials</name>
<message> <message>
<source>Server connection</source> <source>Server connection</source>
<translation type="vanished">Подключение к серверу</translation> <translation type="vanished">اتصال به سرور</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="51"/> <location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="51"/>
@@ -1823,12 +1828,12 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<translation>سرور در حال حاضر به نرمافزار اضافه شده است</translation> <translation>سرور در حال حاضر به نرمافزار اضافه شده است</translation>
</message> </message>
<message> <message>
<source>Amnesia has detected that your server is currently </source> <source>Amnezia has detected that your server is currently </source>
<translation type="vanished">Amnesia обнаружила, что ваш сервер в настоящее время </translation> <translation type="vanished">Amnezia has detected that your server is currently </translation>
</message> </message>
<message> <message>
<source>busy installing other software. Amnesia installation </source> <source>busy installing other software. Amnezia installation </source>
<translation type="vanished">занят установкой других протоколов или сервисов. Установка Amnesia </translation> <translation type="vanished">busy installing other software. Amnezia installation</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardInstalling.qml" line="67"/> <location filename="../ui/qml/Pages2/PageSetupWizardInstalling.qml" line="67"/>
@@ -2019,7 +2024,7 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
</message> </message>
<message> <message>
<source>VPN Access</source> <source>VPN Access</source>
<translation type="vanished">VPN-Доступ</translation> <translation type="vanished">دسترسی VPN</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="220"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="220"/>
@@ -2028,11 +2033,11 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
</message> </message>
<message> <message>
<source>VPN access without the ability to manage the server</source> <source>VPN access without the ability to manage the server</source>
<translation type="vanished">Доступ к VPN, без возможности управления сервером</translation> <translation type="vanished">دسترسی به VPN بدون امکان مدیریت سرور</translation>
</message> </message>
<message> <message>
<source>Access to server management. The user with whom you share full access to the connection will be able to add and remove your protocols and services to the server, as well as change settings.</source> <source>Access to server management. The user with whom you share full access to the connection will be able to add and remove your protocols and services to the server, as well as change settings.</source>
<translation type="vanished">Доступ к управлению сервером. Пользователь, с которым вы делитесь полным доступом к соединению, сможет добавлять и удалять ваши протоколы и службы на сервере, а также изменять настройки.</translation> <translation type="vanished">دسترسی به مدیریت سرور. کاربری که با او دسترسی کامل به اتصال را به اشتراک میگذارید، میتواند پروتکلها و سرویسهای شما را در سرور اضافه و حذف کند، همچنین تنظیمات را تغییر دهد.</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="280"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="280"/>
@@ -2132,7 +2137,7 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="584"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="584"/>
<source>Creation date: </source> <source>Creation date: </source>
<translation type="unfinished"></translation> <translation>تاریخ ایجاد:</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="598"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="598"/>
@@ -2157,7 +2162,7 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="671"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="671"/>
<source>Revoke the config for a user - %1?</source> <source>Revoke the config for a user - %1?</source>
<translation type="unfinished"></translation> <translation> لغو پیکربندی برای یک کاربر %1؟</translation>
</message> </message>
<message> <message>
<source>Revoke the config for a user - </source> <source>Revoke the config for a user - </source>
@@ -2732,17 +2737,17 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<message> <message>
<location filename="../containers/containers_defs.cpp" line="101"/> <location filename="../containers/containers_defs.cpp" line="101"/>
<source>ShadowSocks - masks VPN traffic, making it similar to normal web traffic, but it may be recognized by analysis systems in some highly censored regions.</source> <source>ShadowSocks - masks VPN traffic, making it similar to normal web traffic, but it may be recognized by analysis systems in some highly censored regions.</source>
<translation type="unfinished"></translation> <translation>شدوساکس - ترافیک VPN را پنهان می کند، به طوری که مشابه ترافیک وب عادی می شود، اما ممکن است توسط سیستم های تجزیه و تحلیل در برخی از مناطق با سانسور شدید شناسایی شود.</translation>
</message> </message>
<message> <message>
<location filename="../containers/containers_defs.cpp" line="104"/> <location filename="../containers/containers_defs.cpp" line="104"/>
<source>OpenVPN over Cloak - OpenVPN with VPN masquerading as web traffic and protection against active-probing detection. Ideal for bypassing blocking in regions with the highest levels of censorship.</source> <source>OpenVPN over Cloak - OpenVPN with VPN masquerading as web traffic and protection against active-probing detection. Ideal for bypassing blocking in regions with the highest levels of censorship.</source>
<translation type="unfinished"></translation> <translation>OpenVPN روی Cloak - OpenVPN با VPN که به عنوان ترافیک وب پنهان میشود و مقاومت در برابر تشخیص فعال از طریق پیشرفته. ایدهآل برای دور زدن مسدود کردن در مناطق با بالاترین سطوح سانسور</translation>
</message> </message>
<message> <message>
<location filename="../containers/containers_defs.cpp" line="122"/> <location filename="../containers/containers_defs.cpp" line="122"/>
<source>Create a file vault on your server to securely store and transfer files.</source> <source>Create a file vault on your server to securely store and transfer files.</source>
<translation type="unfinished"></translation> <translation>ساختن یک گنجانده فایل بر روی سرور شما برای ذخیره و انتقال ایمن فایلها</translation>
</message> </message>
<message> <message>
<location filename="../containers/containers_defs.cpp" line="155"/> <location filename="../containers/containers_defs.cpp" line="155"/>
@@ -2764,7 +2769,23 @@ If there is a extreme level of Internet censorship in your region, we advise you
* Not recognised by DPI analysis systems * Not recognised by DPI analysis systems
* Works over TCP network protocol, 443 port. * Works over TCP network protocol, 443 port.
</source> </source>
<translation type="unfinished"></translation> <translation>این ترکیبی از پروتکل OpenVPN و پلاگین Cloak به طور خاص برای محافظت در برابر مسدود کردن طراحی شده است.
OpenVPN ارتباط امن VPN را با رمزگذاری تمام ترافیک اینترنتی بین مشتری و سرور فراهم میکند.
Cloak OpenVPN را از شناسایی و مسدود کردن محافظت میکند.
Cloak میتواند اطلاعات فراداده بسته را تغییر دهد تا ترافیک VPN را به طور کامل به عنوان ترافیک وب عادی پنهان کند و همچنین VPN را از شناسایی توسط Active Probing محافظت کند. این باعث میشود این سیستم بسیار مقاوم در برابر شناسایی شود.
فوراً پس از دریافت اولین بسته داده، Cloak اتصال ورودی را تأیید میکند. اگر تأیید اعتبار ناموفق باشد، پلاگین سرور را به عنوان یک وبسایت جعلی پنهان میکند و VPN شما برای سیستمهای تجزیه و تحلیل غیر قابل دسترسی میشود.
اگر در منطقه شما سطح بسیار بالایی از سانسور اینترنت وجود دارد، به شما توصیه میشود که از اولین اتصال فقط از OpenVPN over Cloak استفاده کنید.
در دسترس در AmneziaVPN بر روی تمام پلتفرمها
مصرف بالای برق در دستگاههای تلفن همراه
تنظیمات انعطاف پذیر
توسط سیستمهای تجزیه و تحلیل DPI شناخته نمیشود
بر روی پروتکل شبکه TCP، پورت 443 کار میکند.</translation>
</message> </message>
<message> <message>
<location filename="../containers/containers_defs.cpp" line="174"/> <location filename="../containers/containers_defs.cpp" line="174"/>
@@ -3091,11 +3112,6 @@ This means that AmneziaWG keeps the fast performance of the original while addin
</context> </context>
<context> <context>
<name>SettingsController</name> <name>SettingsController</name>
<message>
<location filename="../ui/controllers/settingsController.cpp" line="27"/>
<source>Software version</source>
<translation>نسخه نرمافزار</translation>
</message>
<message> <message>
<location filename="../ui/controllers/settingsController.cpp" line="148"/> <location filename="../ui/controllers/settingsController.cpp" line="148"/>
<source>All settings have been reset to default values</source> <source>All settings have been reset to default values</source>
@@ -3233,7 +3249,7 @@ This means that AmneziaWG keeps the fast performance of the original while addin
<message> <message>
<location filename="../ui/qml/Controls2/TextFieldWithHeaderType.qml" line="105"/> <location filename="../ui/qml/Controls2/TextFieldWithHeaderType.qml" line="105"/>
<source>The field can&apos;t be empty</source> <source>The field can&apos;t be empty</source>
<translation>Поле не может быть пустым</translation> <translation>این فیلد نمیتواند خالی باشد.</translation>
</message> </message>
</context> </context>
<context> <context>
@@ -3321,23 +3337,23 @@ This means that AmneziaWG keeps the fast performance of the original while addin
</message> </message>
<message> <message>
<source>High</source> <source>High</source>
<translation type="vanished">Высокий</translation> <translation type="vanished">بالایی</translation>
</message> </message>
<message> <message>
<source>Medium</source> <source>Medium</source>
<translation type="vanished">Средний</translation> <translation type="vanished">متوسط</translation>
</message> </message>
<message> <message>
<source>Many foreign websites and VPN providers are blocked</source> <source>Many foreign websites and VPN providers are blocked</source>
<translation type="vanished">Многие иностранные сайты и VPN-провайдеры заблокированы</translation> <translation type="vanished">بسیاری از وبسایتها و ارائهدهندگان VPN خارجی مسدود شدهاند.</translation>
</message> </message>
<message> <message>
<source>Some foreign sites are blocked, but VPN providers are not blocked</source> <source>Some foreign sites are blocked, but VPN providers are not blocked</source>
<translation type="vanished">Некоторые иностранные сайты заблокированы, но VPN-провайдеры не блокируются</translation> <translation type="vanished">بعضی از وبسایتهای خارجی مسدود شدهاند، اما ارائهدهندگان VPN مسدود نمیشوند.</translation>
</message> </message>
<message> <message>
<source>I just want to increase the level of privacy</source> <source>I just want to increase the level of privacy</source>
<translation type="vanished">Хочу просто повысить уровень приватности</translation> <translation type="vanished">من فقط میخواهم سطح حریم خصوصی خود را افزایش دهم.</translation>
</message> </message>
</context> </context>
<context> <context>
+8 -8
View File
@@ -938,7 +938,7 @@ Already installed containers were found on the server. All installed containers
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="56"/> <location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="56"/>
<source>Support Amnezia</source> <source>Support Amnezia</source>
<translation type="unfinished"></translation> <translation type="unfinished">Поддержите Amnezia</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="71"/> <location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="71"/>
@@ -1020,6 +1020,11 @@ Already installed containers were found on the server. All installed containers
<source>https://amnezia.org</source> <source>https://amnezia.org</source>
<translation>https://amnezia.org</translation> <translation>https://amnezia.org</translation>
</message> </message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="176"/>
<source>Software version: %1</source>
<translation>Версия ПО: %1</translation>
</message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="192"/> <location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="192"/>
<source>Check for updates</source> <source>Check for updates</source>
@@ -1202,7 +1207,7 @@ Already installed containers were found on the server. All installed containers
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="70"/> <location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="70"/>
<source>When AmneziaDNS is installed on the server</source> <source>If AmneziaDNS is installed on the server</source>
<translation>Если он уставновлен на сервере</translation> <translation>Если он уставновлен на сервере</translation>
</message> </message>
<message> <message>
@@ -2808,7 +2813,7 @@ While it offers a blend of security, stability, and speed, it&apos;s essential t
<translation>OpenVPN - популярный VPN-протокол, с гибкой настройкой. Имеет собственный протокол безопасности с SSL/TLS для обмена ключами.</translation> <translation>OpenVPN - популярный VPN-протокол, с гибкой настройкой. Имеет собственный протокол безопасности с SSL/TLS для обмена ключами.</translation>
</message> </message>
<message> <message>
<source>ShadowSocks - masks VPN traffic, making it similar to normal web traffic, but it may be recognised by analysis systems in some highly censored regions.</source> <source>ShadowSocks - masks VPN traffic, making it similar to normal web traffic, but it may be recognized by analysis systems in some highly censored regions.</source>
<translation type="vanished">ShadowSocks - маскирует VPN-трафик под обычный веб-трафик, но распознается системами анализа в некоторых регионах с высоким уровнем цензуры.</translation> <translation type="vanished">ShadowSocks - маскирует VPN-трафик под обычный веб-трафик, но распознается системами анализа в некоторых регионах с высоким уровнем цензуры.</translation>
</message> </message>
<message> <message>
@@ -3058,11 +3063,6 @@ This means that AmneziaWG keeps the fast performance of the original while addin
</context> </context>
<context> <context>
<name>SettingsController</name> <name>SettingsController</name>
<message>
<location filename="../ui/controllers/settingsController.cpp" line="27"/>
<source>Software version</source>
<translation>Версия ПО</translation>
</message>
<message> <message>
<location filename="../ui/controllers/settingsController.cpp" line="148"/> <location filename="../ui/controllers/settingsController.cpp" line="148"/>
<source>All settings have been reset to default values</source> <source>All settings have been reset to default values</source>
+48 -40
View File
@@ -200,7 +200,7 @@ Already installed containers were found on the server. All installed containers
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="305"/> <location filename="../ui/controllers/installController.cpp" line="305"/>
<source>Server &apos;%1&apos; was rebooted</source> <source>Server &apos;%1&apos; was rebooted</source>
<translation type="unfinished"></translation> <translation type="unfinished"> &apos;%1&apos; </translation>
</message> </message>
<message> <message>
<location filename="../ui/controllers/installController.cpp" line="314"/> <location filename="../ui/controllers/installController.cpp" line="314"/>
@@ -891,10 +891,10 @@ Already installed containers were found on the server. All installed containers
<message> <message>
<location filename="../ui/qml/Pages2/PageServiceTorWebsiteSettings.qml" line="103"/> <location filename="../ui/qml/Pages2/PageServiceTorWebsiteSettings.qml" line="103"/>
<source>After creating your onion site, it takes a few minutes for the Tor network to make it available for use.</source> <source>After creating your onion site, it takes a few minutes for the Tor network to make it available for use.</source>
<translation type="unfinished"></translation> <translation>使Tor网络上可用</translation>
</message> </message>
<message> <message>
<source>Use &lt;a href=&quot;https://www.torproject.org/download/&quot; style=&quot;color: #FBB26A;&quot;&gt;Tor Browser&lt;/a&gt; to open this url.</source> <source>Use &lt;a href=&quot;https://www.torproject.org/download/&quot; style=&quot;color: #FBB26A;&quot;&gt;Tor Browser&lt;/a&gt; to open this URL.</source>
<translation type="vanished"> &lt;a href=&quot;https://www.torproject.org/download/&quot; style=&quot;color: #FBB26A;&quot;&gt;Tor 浏览器&lt;/a&gt; 打开上面网址</translation> <translation type="vanished"> &lt;a href=&quot;https://www.torproject.org/download/&quot; style=&quot;color: #FBB26A;&quot;&gt;Tor 浏览器&lt;/a&gt; 打开上面网址</translation>
</message> </message>
<message> <message>
@@ -984,7 +984,7 @@ And if you don&apos;t like the app, all the more support it - the donation will
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="56"/> <location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="56"/>
<source>Support Amnezia</source> <source>Support Amnezia</source>
<translation type="unfinished"></translation> <translation>Amnezia</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="71"/> <location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="71"/>
@@ -1067,6 +1067,11 @@ And if you don&apos;t like the app, all the more support it - the donation will
<source>https://amnezia.org</source> <source>https://amnezia.org</source>
<translation></translation> <translation></translation>
</message> </message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="176"/>
<source>Software version: %1</source>
<translation>: %1</translation>
</message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="192"/> <location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="192"/>
<source>Check for updates</source> <source>Check for updates</source>
@@ -1261,7 +1266,7 @@ And if you don&apos;t like the app, all the more support it - the donation will
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="86"/> <location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="86"/>
<source>When AmneziaDNS is not used or installed</source> <source>When AmneziaDNS is not used or installed</source>
<translation type="unfinished"></translation> <translation>使AmneziaDNS时</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="120"/> <location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="120"/>
@@ -1479,12 +1484,12 @@ And if you don&apos;t like the app, all the more support it - the donation will
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="143"/> <location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="143"/>
<source>Do you want to reboot the server?</source> <source>Do you want to reboot the server?</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="206"/> <location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="206"/>
<source>Do you want to clear server from Amnezia software?</source> <source>Do you want to clear server from Amnezia software?</source>
<translation type="unfinished"></translation> <translation>Amnezia软件吗</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="92"/> <location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="92"/>
@@ -1520,12 +1525,12 @@ And if you don&apos;t like the app, all the more support it - the donation will
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="139"/> <location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="139"/>
<source>Reboot server</source> <source>Reboot server</source>
<translation type="unfinished"></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="144"/> <location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="144"/>
<source>The reboot process may take approximately 30 seconds. Are you sure you wish to proceed?</source> <source>The reboot process may take approximately 30 seconds. Are you sure you wish to proceed?</source>
<translation type="unfinished"></translation> <translation> 30</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="171"/> <location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="171"/>
@@ -1535,7 +1540,7 @@ And if you don&apos;t like the app, all the more support it - the donation will
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="175"/> <location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="175"/>
<source>Do you want to remove the server from application?</source> <source>Do you want to remove the server from application?</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<source>Remove server?</source> <source>Remove server?</source>
@@ -1706,17 +1711,17 @@ And if you don&apos;t like the app, all the more support it - the donation will
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="59"/> <location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="59"/>
<source>Only the sites listed here will be accessed through the VPN</source> <source>Only the sites listed here will be accessed through the VPN</source>
<translation type="unfinished"></translation> <translation>VPN访问</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="254"/> <location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="254"/>
<source>website or IP</source> <source>website or IP</source>
<translation type="unfinished"></translation> <translation>IP</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="298"/> <location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="298"/>
<source>Import / Export Sites</source> <source>Import / Export Sites</source>
<translation type="unfinished"></translation> <translation>/</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="304"/> <location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="304"/>
@@ -2138,12 +2143,12 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="120"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="120"/>
<source>ShadowSocks native format</source> <source>ShadowSocks native format</source>
<translation type="unfinished"></translation> <translation>ShadowSocks原生格式</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="125"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="125"/>
<source>Cloak native format</source> <source>Cloak native format</source>
<translation type="unfinished"></translation> <translation>Cloak原生格式</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="150"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="150"/>
@@ -2153,18 +2158,18 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="178"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="178"/>
<source>Share full access to the server and VPN</source> <source>Share full access to the server and VPN</source>
<translation type="unfinished"></translation> <translation>VPN的完全访问权限</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="179"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="179"/>
<source>Use for your own devices, or share with those you trust to manage the server.</source> <source>Use for your own devices, or share with those you trust to manage the server.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="231"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="231"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="486"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="486"/>
<source>Users</source> <source>Users</source>
<translation type="unfinished"></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="251"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="251"/>
@@ -2199,17 +2204,17 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="668"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="668"/>
<source>Revoke</source> <source>Revoke</source>
<translation type="unfinished"></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="671"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="671"/>
<source>Revoke the config for a user - %1?</source> <source>Revoke the config for a user - %1?</source>
<translation type="unfinished"></translation> <translation>- %1?</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="672"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="672"/>
<source>The user will no longer be able to connect to your server.</source> <source>The user will no longer be able to connect to your server.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="673"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="673"/>
@@ -2295,12 +2300,12 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="34"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="34"/>
<source>Config revoked</source> <source>Config revoked</source>
<translation type="unfinished"></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="262"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="262"/>
<source>User name</source> <source>User name</source>
<translation type="unfinished"></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="429"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="429"/>
@@ -2320,7 +2325,7 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<message> <message>
<location filename="../ui/qml/Pages2/PageShareFullAccess.qml" line="49"/> <location filename="../ui/qml/Pages2/PageShareFullAccess.qml" line="49"/>
<source>Full access to the server and VPN</source> <source>Full access to the server and VPN</source>
<translation type="unfinished"></translation> <translation>VPN的完全访问权限</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShareFullAccess.qml" line="57"/> <location filename="../ui/qml/Pages2/PageShareFullAccess.qml" line="57"/>
@@ -2331,7 +2336,7 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<message> <message>
<location filename="../ui/qml/Pages2/PageShareFullAccess.qml" line="58"/> <location filename="../ui/qml/Pages2/PageShareFullAccess.qml" line="58"/>
<source>If you share full access with other people, they can remove and add protocols and services to the server, which will cause the VPN to work incorrectly for all users. </source> <source>If you share full access with other people, they can remove and add protocols and services to the server, which will cause the VPN to work incorrectly for all users. </source>
<translation type="unfinished"></translation> <translation>访VPN对所有用户的工作出现问题</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShareFullAccess.qml" line="73"/> <location filename="../ui/qml/Pages2/PageShareFullAccess.qml" line="73"/>
@@ -2822,7 +2827,7 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<message> <message>
<location filename="../core/errorstrings.cpp" line="62"/> <location filename="../core/errorstrings.cpp" line="62"/>
<source>The config does not contain any containers and credentials for connecting to the server</source> <source>The config does not contain any containers and credentials for connecting to the server</source>
<translation type="unfinished"></translation> <translation></translation>
</message> </message>
<message> <message>
<source>The config does not contain any containers and credentiaks for connecting to the server</source> <source>The config does not contain any containers and credentiaks for connecting to the server</source>
@@ -2831,7 +2836,7 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<message> <message>
<location filename="../core/errorstrings.cpp" line="69"/> <location filename="../core/errorstrings.cpp" line="69"/>
<source>Internal error</source> <source>Internal error</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../containers/containers_defs.cpp" line="88"/> <location filename="../containers/containers_defs.cpp" line="88"/>
@@ -2862,17 +2867,17 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<message> <message>
<location filename="../containers/containers_defs.cpp" line="101"/> <location filename="../containers/containers_defs.cpp" line="101"/>
<source>ShadowSocks - masks VPN traffic, making it similar to normal web traffic, but it may be recognized by analysis systems in some highly censored regions.</source> <source>ShadowSocks - masks VPN traffic, making it similar to normal web traffic, but it may be recognized by analysis systems in some highly censored regions.</source>
<translation type="unfinished"></translation> <translation>ShadowSocks - VPN流量使</translation>
</message> </message>
<message> <message>
<location filename="../containers/containers_defs.cpp" line="104"/> <location filename="../containers/containers_defs.cpp" line="104"/>
<source>OpenVPN over Cloak - OpenVPN with VPN masquerading as web traffic and protection against active-probing detection. Ideal for bypassing blocking in regions with the highest levels of censorship.</source> <source>OpenVPN over Cloak - OpenVPN with masquerading as web traffic and protection against active-probing detection. Ideal for bypassing blocking in regions with the highest levels of censorship.</source>
<translation type="unfinished"></translation> <translation type="unfinished">OpenVPN over Cloak - OpenVPN与VPN结合Web流量</translation>
</message> </message>
<message> <message>
<location filename="../containers/containers_defs.cpp" line="122"/> <location filename="../containers/containers_defs.cpp" line="122"/>
<source>Create a file vault on your server to securely store and transfer files.</source> <source>Create a file vault on your server to securely store and transfer files.</source>
<translation type="unfinished"></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../containers/containers_defs.cpp" line="155"/> <location filename="../containers/containers_defs.cpp" line="155"/>
@@ -2907,15 +2912,23 @@ WireGuard is very susceptible to blocking due to its distinct packet signatures.
* Minimum number of settings * Minimum number of settings
* Easily recognised by DPI analysis systems, susceptible to blocking * Easily recognised by DPI analysis systems, susceptible to blocking
* Works over UDP network protocol.</source> * Works over UDP network protocol.</source>
<translation type="unfinished"></translation> <translation>VPN协议
WireGuard提供稳定的VPN连接使OpenVPN相比WireGuard具有较低的延迟和更好的数据传输吞吐量
WireGuard非常容易被阻挡VPN协议不同使WireGuard数据包的一致签名模式更容易被高级深度数据包检测DPI
AmneziaVPN上适用于所有平台
DPI分析系统识别
UDP网络协议运行</translation>
</message> </message>
<message> <message>
<source>ShadowSocks - masks VPN traffic, making it similar to normal web traffic, but is recognised by analysis systems in some highly censored regions.</source> <source>ShadowSocks - masks VPN traffic, making it similar to normal web traffic, but is recognised by analysis systems in some highly censored regions.</source>
<translation type="vanished">ShadowSocks - VPN 使 Web </translation> <translation type="vanished">ShadowSocks - VPN 使 Web </translation>
</message> </message>
<message> <message>
<source>OpenVPN over Cloak - OpenVPN with VPN masquerading as web traffic and protection against active-probbing detection. Ideal for bypassing blocking in regions with the highest levels of censorship.</source> <source>OpenVPN over Cloak - OpenVPN with VPN masquerading as web traffic and protection against active-probing detection. Ideal for bypassing blocking in regions with the highest levels of censorship.</source>
<translation type="vanished">OpenVPN over Cloak - OpenVPN VPN </translation> <translation type="vanished">OpenVPN over Cloak - OpenVPN与VPN结合Web流量</translation>
</message> </message>
<message> <message>
<location filename="../containers/containers_defs.cpp" line="108"/> <location filename="../containers/containers_defs.cpp" line="108"/>
@@ -3198,11 +3211,6 @@ While it offers a blend of security, stability, and speed, it&apos;s essential t
</context> </context>
<context> <context>
<name>SettingsController</name> <name>SettingsController</name>
<message>
<location filename="../ui/controllers/settingsController.cpp" line="27"/>
<source>Software version</source>
<translation></translation>
</message>
<message> <message>
<location filename="../ui/controllers/settingsController.cpp" line="132"/> <location filename="../ui/controllers/settingsController.cpp" line="132"/>
<source>Backup file is corrupted</source> <source>Backup file is corrupted</source>
@@ -3246,7 +3254,7 @@ While it offers a blend of security, stability, and speed, it&apos;s essential t
<message> <message>
<location filename="../ui/qml/Components/ShareConnectionDrawer.qml" line="128"/> <location filename="../ui/qml/Components/ShareConnectionDrawer.qml" line="128"/>
<source>Copy config string</source> <source>Copy config string</source>
<translation type="unfinished"></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Components/ShareConnectionDrawer.qml" line="150"/> <location filename="../ui/qml/Components/ShareConnectionDrawer.qml" line="150"/>
+2 -3
View File
@@ -136,8 +136,7 @@ void ApiController::updateServerConfigFromApi()
auto defaultContainer = apiConfig.value(config_key::defaultContainer).toString(); auto defaultContainer = apiConfig.value(config_key::defaultContainer).toString();
serverConfig.insert(config_key::defaultContainer, defaultContainer); serverConfig.insert(config_key::defaultContainer, defaultContainer);
m_serversModel->editServer(serverConfig); m_serversModel->editServer(serverConfig, m_serversModel->getDefaultServerIndex());
emit m_serversModel->defaultContainerChanged(ContainerProps::containerFromString(defaultContainer));
} else { } else {
qDebug() << reply->error(); qDebug() << reply->error();
qDebug() << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute); qDebug() << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
@@ -164,5 +163,5 @@ void ApiController::clearApiConfig()
serverConfig.insert(config_key::defaultContainer, ContainerProps::containerToString(DockerContainer::None)); serverConfig.insert(config_key::defaultContainer, ContainerProps::containerToString(DockerContainer::None));
m_serversModel->editServer(serverConfig); m_serversModel->editServer(serverConfig, m_serversModel->getDefaultServerIndex());
} }
@@ -33,7 +33,7 @@ void ConnectionController::openConnection()
int serverIndex = m_serversModel->getDefaultServerIndex(); int serverIndex = m_serversModel->getDefaultServerIndex();
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex); ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
DockerContainer container = m_serversModel->getDefaultContainer(serverIndex); DockerContainer container = qvariant_cast<DockerContainer>(m_serversModel->data(serverIndex, ServersModel::Roles::DefaultContainerRole));
const QJsonObject &containerConfig = m_containersModel->getContainerConfig(container); const QJsonObject &containerConfig = m_containersModel->getContainerConfig(container);
if (container == DockerContainer::None) { if (container == DockerContainer::None) {
+47 -7
View File
@@ -8,6 +8,7 @@
#include <QImage> #include <QImage>
#include <QStandardPaths> #include <QStandardPaths>
#include "configurators/awg_configurator.h"
#include "configurators/cloak_configurator.h" #include "configurators/cloak_configurator.h"
#include "configurators/openvpn_configurator.h" #include "configurators/openvpn_configurator.h"
#include "configurators/shadowsocks_configurator.h" #include "configurators/shadowsocks_configurator.h"
@@ -45,7 +46,7 @@ void ExportController::generateFullAccessConfig()
{ {
clearPreviousConfig(); clearPreviousConfig();
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex(); int serverIndex = m_serversModel->getProcessedServerIndex();
QJsonObject config = m_settings->server(serverIndex); QJsonObject config = m_settings->server(serverIndex);
QJsonArray containers = config.value(config_key::containers).toArray(); QJsonArray containers = config.value(config_key::containers).toArray();
@@ -99,7 +100,7 @@ void ExportController::generateConnectionConfig(const QString &clientName)
{ {
clearPreviousConfig(); clearPreviousConfig();
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex(); int serverIndex = m_serversModel->getProcessedServerIndex();
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex); ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex()); DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex());
@@ -155,7 +156,7 @@ void ExportController::generateOpenVpnConfig(const QString &clientName)
{ {
clearPreviousConfig(); clearPreviousConfig();
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex(); int serverIndex = m_serversModel->getProcessedServerIndex();
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex); ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex()); DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex());
@@ -193,7 +194,7 @@ void ExportController::generateWireGuardConfig(const QString &clientName)
{ {
clearPreviousConfig(); clearPreviousConfig();
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex(); int serverIndex = m_serversModel->getProcessedServerIndex();
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex); ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex()); DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex());
@@ -228,11 +229,50 @@ void ExportController::generateWireGuardConfig(const QString &clientName)
emit exportConfigChanged(); emit exportConfigChanged();
} }
void ExportController::generateAwgConfig(const QString &clientName)
{
clearPreviousConfig();
int serverIndex = m_serversModel->getProcessedServerIndex();
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex());
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
containerConfig.insert(config_key::container, ContainerProps::containerToString(container));
QString clientId;
ErrorCode errorCode = ErrorCode::NoError;
QString config = m_configurator->awgConfigurator->genAwgConfig(credentials, container, containerConfig,
clientId, &errorCode);
if (errorCode) {
emit exportErrorOccurred(errorString(errorCode));
return;
}
config = m_configurator->processConfigWithExportSettings(serverIndex, container, Proto::Awg, config);
auto configJson = QJsonDocument::fromJson(config.toUtf8()).object();
QStringList lines = configJson.value(config_key::config).toString().replace("\r", "").split("\n");
for (const QString &line : lines) {
m_config.append(line + "\n");
}
qrcodegen::QrCode qr = qrcodegen::QrCode::encodeText(m_config.toUtf8(), qrcodegen::QrCode::Ecc::LOW);
m_qrCodes << svgToBase64(QString::fromStdString(toSvgString(qr, 1)));
errorCode = m_clientManagementModel->appendClient(clientId, clientName, container, credentials);
if (errorCode) {
emit exportErrorOccurred(errorString(errorCode));
return;
}
emit exportConfigChanged();
}
void ExportController::generateShadowSocksConfig() void ExportController::generateShadowSocksConfig()
{ {
clearPreviousConfig(); clearPreviousConfig();
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex(); int serverIndex = m_serversModel->getProcessedServerIndex();
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex); ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex()); DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex());
@@ -268,7 +308,7 @@ void ExportController::generateCloakConfig()
{ {
clearPreviousConfig(); clearPreviousConfig();
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex(); int serverIndex = m_serversModel->getProcessedServerIndex();
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex); ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex()); DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex());
@@ -328,7 +368,7 @@ void ExportController::updateClientManagementModel(const DockerContainer contain
void ExportController::revokeConfig(const int row, const DockerContainer container, ServerCredentials credentials) void ExportController::revokeConfig(const int row, const DockerContainer container, ServerCredentials credentials)
{ {
ErrorCode errorCode = m_clientManagementModel->revokeClient(row, container, credentials, ErrorCode errorCode = m_clientManagementModel->revokeClient(row, container, credentials,
m_serversModel->getCurrentlyProcessedServerIndex()); m_serversModel->getProcessedServerIndex());
if (errorCode != ErrorCode::NoError) { if (errorCode != ErrorCode::NoError) {
emit exportErrorOccurred(errorString(errorCode)); emit exportErrorOccurred(errorString(errorCode));
} }
+1
View File
@@ -34,6 +34,7 @@ public slots:
void generateConnectionConfig(const QString &clientName); void generateConnectionConfig(const QString &clientName);
void generateOpenVpnConfig(const QString &clientName); void generateOpenVpnConfig(const QString &clientName);
void generateWireGuardConfig(const QString &clientName); void generateWireGuardConfig(const QString &clientName);
void generateAwgConfig(const QString &clientName);
void generateShadowSocksConfig(); void generateShadowSocksConfig();
void generateCloakConfig(); void generateCloakConfig();
+14 -14
View File
@@ -176,7 +176,7 @@ void InstallController::installServer(DockerContainer container, QJsonObject &co
void InstallController::installContainer(DockerContainer container, QJsonObject &config) void InstallController::installContainer(DockerContainer container, QJsonObject &config)
{ {
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex(); int serverIndex = m_serversModel->getProcessedServerIndex();
ServerCredentials serverCredentials = ServerCredentials serverCredentials =
qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole)); qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
@@ -238,7 +238,7 @@ bool InstallController::isServerAlreadyExists()
void InstallController::scanServerForInstalledContainers() void InstallController::scanServerForInstalledContainers()
{ {
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex(); int serverIndex = m_serversModel->getProcessedServerIndex();
ServerCredentials serverCredentials = ServerCredentials serverCredentials =
qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole)); qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
@@ -267,7 +267,7 @@ void InstallController::scanServerForInstalledContainers()
void InstallController::updateContainer(QJsonObject config) void InstallController::updateContainer(QJsonObject config)
{ {
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex(); int serverIndex = m_serversModel->getProcessedServerIndex();
ServerCredentials serverCredentials = ServerCredentials serverCredentials =
qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole)); qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
@@ -283,8 +283,8 @@ void InstallController::updateContainer(QJsonObject config)
m_serversModel->updateContainerConfig(container, config); m_serversModel->updateContainerConfig(container, config);
m_protocolModel->updateModel(config); m_protocolModel->updateModel(config);
if ((serverIndex == m_serversModel->getDefaultServerIndex()) auto defaultContainer = qvariant_cast<DockerContainer>(m_serversModel->data(serverIndex, ServersModel::Roles::DefaultContainerRole));
&& (container == m_serversModel->getDefaultContainer(serverIndex))) { if ((serverIndex == m_serversModel->getDefaultServerIndex()) && (container == defaultContainer)) {
emit currentContainerUpdated(); emit currentContainerUpdated();
} else { } else {
emit updateContainerFinished(tr("Settings updated successfully")); emit updateContainerFinished(tr("Settings updated successfully"));
@@ -296,27 +296,27 @@ void InstallController::updateContainer(QJsonObject config)
emit installationErrorOccurred(errorString(errorCode)); emit installationErrorOccurred(errorString(errorCode));
} }
void InstallController::rebootCurrentlyProcessedServer() void InstallController::rebootProcessedServer()
{ {
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex(); int serverIndex = m_serversModel->getProcessedServerIndex();
QString serverName = m_serversModel->data(serverIndex, ServersModel::Roles::NameRole).toString(); QString serverName = m_serversModel->data(serverIndex, ServersModel::Roles::NameRole).toString();
m_serversModel->rebootServer(); m_serversModel->rebootServer();
emit rebootCurrentlyProcessedServerFinished(tr("Server '%1' was rebooted").arg(serverName)); emit rebootProcessedServerFinished(tr("Server '%1' was rebooted").arg(serverName));
} }
void InstallController::removeCurrentlyProcessedServer() void InstallController::removeProcessedServer()
{ {
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex(); int serverIndex = m_serversModel->getProcessedServerIndex();
QString serverName = m_serversModel->data(serverIndex, ServersModel::Roles::NameRole).toString(); QString serverName = m_serversModel->data(serverIndex, ServersModel::Roles::NameRole).toString();
m_serversModel->removeServer(); m_serversModel->removeServer();
emit removeCurrentlyProcessedServerFinished(tr("Server '%1' was removed").arg(serverName)); emit removeProcessedServerFinished(tr("Server '%1' was removed").arg(serverName));
} }
void InstallController::removeAllContainers() void InstallController::removeAllContainers()
{ {
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex(); int serverIndex = m_serversModel->getProcessedServerIndex();
QString serverName = m_serversModel->data(serverIndex, ServersModel::Roles::NameRole).toString(); QString serverName = m_serversModel->data(serverIndex, ServersModel::Roles::NameRole).toString();
ErrorCode errorCode = m_serversModel->removeAllContainers(); ErrorCode errorCode = m_serversModel->removeAllContainers();
@@ -329,7 +329,7 @@ void InstallController::removeAllContainers()
void InstallController::removeCurrentlyProcessedContainer() void InstallController::removeCurrentlyProcessedContainer()
{ {
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex(); int serverIndex = m_serversModel->getProcessedServerIndex();
QString serverName = m_serversModel->data(serverIndex, ServersModel::Roles::NameRole).toString(); QString serverName = m_serversModel->data(serverIndex, ServersModel::Roles::NameRole).toString();
int container = m_containersModel->getCurrentlyProcessedContainerIndex(); int container = m_containersModel->getCurrentlyProcessedContainerIndex();
@@ -377,7 +377,7 @@ void InstallController::mountSftpDrive(const QString &port, const QString &passw
QString mountPath; QString mountPath;
QString cmd; QString cmd;
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex(); int serverIndex = m_serversModel->getProcessedServerIndex();
ServerCredentials serverCredentials = ServerCredentials serverCredentials =
qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole)); qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
QString hostname = serverCredentials.hostName; QString hostname = serverCredentials.hostName;
+4 -4
View File
@@ -30,8 +30,8 @@ public slots:
void updateContainer(QJsonObject config); void updateContainer(QJsonObject config);
void removeCurrentlyProcessedServer(); void removeProcessedServer();
void rebootCurrentlyProcessedServer(); void rebootProcessedServer();
void removeAllContainers(); void removeAllContainers();
void removeCurrentlyProcessedContainer(); void removeCurrentlyProcessedContainer();
@@ -54,8 +54,8 @@ signals:
void scanServerFinished(bool isInstalledContainerFound); void scanServerFinished(bool isInstalledContainerFound);
void rebootCurrentlyProcessedServerFinished(const QString &finishedMessage); void rebootProcessedServerFinished(const QString &finishedMessage);
void removeCurrentlyProcessedServerFinished(const QString &finishedMessage); void removeProcessedServerFinished(const QString &finishedMessage);
void removeAllContainersFinished(const QString &finishedMessage); void removeAllContainersFinished(const QString &finishedMessage);
void removeCurrentlyProcessedContainerFinished(const QString &finishedMessage); void removeCurrentlyProcessedContainerFinished(const QString &finishedMessage);
+1 -1
View File
@@ -28,7 +28,7 @@ SettingsController::SettingsController(const QSharedPointer<ServersModel> &serve
m_sitesModel(sitesModel), m_sitesModel(sitesModel),
m_settings(settings) m_settings(settings)
{ {
m_appVersion = QString("%1: %2 (%3)").arg(tr("Software version"), QString(APP_VERSION), __DATE__); m_appVersion = QString("%1 (%2, %3)").arg(QString(APP_VERSION), __DATE__, GIT_COMMIT_HASH);
#ifdef Q_OS_ANDROID #ifdef Q_OS_ANDROID
if (!m_settings->isScreenshotsEnabled()) { if (!m_settings->isScreenshotsEnabled()) {
+32 -12
View File
@@ -10,7 +10,8 @@ namespace
{ {
Logger logger("ClientManagementModel"); Logger logger("ClientManagementModel");
namespace configKey { namespace configKey
{
constexpr char clientId[] = "clientId"; constexpr char clientId[] = "clientId";
constexpr char clientName[] = "clientName"; constexpr char clientName[] = "clientName";
constexpr char container[] = "container"; constexpr char container[] = "container";
@@ -61,7 +62,6 @@ void ClientManagementModel::migration(const QByteArray &clientsTableString)
m_clientsTable.push_back(client); m_clientsTable.push_back(client);
} }
} }
ErrorCode ClientManagementModel::updateModel(DockerContainer container, ServerCredentials credentials) ErrorCode ClientManagementModel::updateModel(DockerContainer container, ServerCredentials credentials)
@@ -121,7 +121,8 @@ ErrorCode ClientManagementModel::updateModel(DockerContainer container, ServerCr
return error; return error;
} }
ErrorCode ClientManagementModel::getOpenVpnClients(ServerController &serverController, DockerContainer container, ServerCredentials credentials, int &count) ErrorCode ClientManagementModel::getOpenVpnClients(ServerController &serverController, DockerContainer container,
ServerCredentials credentials, int &count)
{ {
ErrorCode error = ErrorCode::NoError; ErrorCode error = ErrorCode::NoError;
QString stdOut; QString stdOut;
@@ -163,12 +164,13 @@ ErrorCode ClientManagementModel::getOpenVpnClients(ServerController &serverContr
return error; return error;
} }
ErrorCode ClientManagementModel::getWireGuardClients(ServerController &serverController, DockerContainer container, ServerCredentials credentials, int &count) ErrorCode ClientManagementModel::getWireGuardClients(ServerController &serverController, DockerContainer container,
ServerCredentials credentials, int &count)
{ {
ErrorCode error = ErrorCode::NoError; ErrorCode error = ErrorCode::NoError;
const QString wireGuardConfigFile = const QString wireGuardConfigFile = DockerContainer::WireGuard ? amnezia::protocols::wireguard::serverConfigPath
QString("opt/amnezia/%1/wg0.conf").arg(container == DockerContainer::WireGuard ? "wireguard" : "awg"); : amnezia::protocols::awg::serverConfigPath;
const QString wireguardConfigString = const QString wireguardConfigString =
serverController.getTextFileFromContainer(container, credentials, wireGuardConfigFile, &error); serverController.getTextFileFromContainer(container, credentials, wireGuardConfigFile, &error);
if (error != ErrorCode::NoError) { if (error != ErrorCode::NoError) {
@@ -314,13 +316,16 @@ ErrorCode ClientManagementModel::revokeClient(const int row, const DockerContain
QJsonArray containers = server.value(config_key::containers).toArray(); QJsonArray containers = server.value(config_key::containers).toArray();
for (auto i = 0; i < containers.size(); i++) { for (auto i = 0; i < containers.size(); i++) {
auto containerConfig = containers.at(i).toObject(); auto containerConfig = containers.at(i).toObject();
auto containerType = ContainerProps::containerFromString(containerConfig.value(config_key::container).toString()); auto containerType =
ContainerProps::containerFromString(containerConfig.value(config_key::container).toString());
if (containerType == container) { if (containerType == container) {
QJsonObject protocolConfig; QJsonObject protocolConfig;
if (container == DockerContainer::ShadowSocks || container == DockerContainer::Cloak) { if (container == DockerContainer::ShadowSocks || container == DockerContainer::Cloak) {
protocolConfig = containerConfig.value(ContainerProps::containerTypeToString(DockerContainer::OpenVpn)).toObject(); protocolConfig =
containerConfig.value(ContainerProps::containerTypeToString(DockerContainer::OpenVpn)).toObject();
} else { } else {
protocolConfig = containerConfig.value(ContainerProps::containerTypeToString(containerType)).toObject(); protocolConfig =
containerConfig.value(ContainerProps::containerTypeToString(containerType)).toObject();
} }
if (protocolConfig.value(config_key::last_config).toString().contains(clientId)) { if (protocolConfig.value(config_key::last_config).toString().contains(clientId)) {
@@ -379,8 +384,17 @@ ErrorCode ClientManagementModel::revokeWireGuard(const int row, const DockerCont
ErrorCode error; ErrorCode error;
ServerController serverController(m_settings); ServerController serverController(m_settings);
const QString wireGuardConfigFile = QString wireGuardConfigFile;
QString("/opt/amnezia/%1/wg0.conf").arg(container == DockerContainer::WireGuard ? "wireguard" : "awg"); if (container == DockerContainer::Awg) {
if (serverController.isNewAwgContainer(credentials)) {
wireGuardConfigFile = amnezia::protocols::awg::serverConfigPath;
} else {
wireGuardConfigFile = "/opt/amnezia/awg/wg0.conf";
}
} else {
wireGuardConfigFile = amnezia::protocols::wireguard::serverConfigPath;
}
const QString wireguardConfigString = const QString wireguardConfigString =
serverController.getTextFileFromContainer(container, credentials, wireGuardConfigFile, &error); serverController.getTextFileFromContainer(container, credentials, wireGuardConfigFile, &error);
if (error != ErrorCode::NoError) { if (error != ErrorCode::NoError) {
@@ -425,7 +439,13 @@ ErrorCode ClientManagementModel::revokeWireGuard(const int row, const DockerCont
return error; return error;
} }
const QString script = "sudo docker exec -i $CONTAINER_NAME bash -c 'wg syncconf wg0 <(wg-quick strip %1)'"; QString interfaceName =
DockerContainer::WireGuard ? protocols::wireguard::interfaceName : protocols::awg::interfaceName;
QString wgBinaryName = DockerContainer::WireGuard ? protocols::wireguard::wgBinaryName : protocols::awg::wgBinaryName;
QString wgQuickBinaryName =
DockerContainer::WireGuard ? protocols::wireguard::wgQuickBinaryName : protocols::awg::wgQuickBinaryName;
QString script = QString("sudo docker exec -i $CONTAINER_NAME bash -c '%4 syncconf %2 <(%3 strip %1)'")
.arg(wireGuardConfigFile, interfaceName, wgQuickBinaryName, wgBinaryName);
error = serverController.runScript( error = serverController.runScript(
credentials, credentials,
serverController.replaceVars(script.arg(wireGuardConfigFile), serverController.replaceVars(script.arg(wireGuardConfigFile),
+144 -111
View File
@@ -5,19 +5,13 @@
ServersModel::ServersModel(std::shared_ptr<Settings> settings, QObject *parent) ServersModel::ServersModel(std::shared_ptr<Settings> settings, QObject *parent)
: m_settings(settings), QAbstractListModel(parent) : m_settings(settings), QAbstractListModel(parent)
{ {
m_servers = m_settings->serversArray();
m_defaultServerIndex = m_settings->defaultServerIndex();
m_currentlyProcessedServerIndex = m_defaultServerIndex;
connect(this, &ServersModel::defaultServerIndexChanged, this, &ServersModel::defaultServerNameChanged); connect(this, &ServersModel::defaultServerIndexChanged, this, &ServersModel::defaultServerNameChanged);
connect(this, &ServersModel::defaultContainerChanged, this, &ServersModel::defaultServerDescriptionChanged);
connect(this, &ServersModel::defaultServerIndexChanged, this, [this](const int serverIndex) { connect(this, &ServersModel::defaultServerIndexChanged, this, [this](const int serverIndex) {
auto defaultContainer = ContainerProps::containerFromString(m_servers.at(serverIndex).toObject().value(config_key::defaultContainer).toString()); auto defaultContainer = ContainerProps::containerFromString(m_servers.at(serverIndex).toObject().value(config_key::defaultContainer).toString());
emit ServersModel::defaultContainerChanged(defaultContainer); emit ServersModel::defaultServerDefaultContainerChanged(defaultContainer);
}); emit ServersModel::defaultServerNameChanged();
connect(this, &ServersModel::currentlyProcessedServerIndexChanged, this, [this](const int serverIndex) { updateDefaultServerContainersModel();
auto defaultContainer = ContainerProps::containerFromString(m_servers.at(serverIndex).toObject().value(config_key::defaultContainer).toString());
emit ServersModel::defaultContainerChanged(defaultContainer);
}); });
} }
@@ -74,16 +68,14 @@ QVariant ServersModel::data(const QModelIndex &index, int role) const
return name; return name;
} }
case ServerDescriptionRole: { case ServerDescriptionRole: {
if (configVersion) { auto description = getServerDescription(server, index.row());
return server.value(config_key::description).toString(); return configVersion ? description : description + server.value(config_key::hostName).toString();
}
return server.value(config_key::hostName).toString();
} }
case HostNameRole: return server.value(config_key::hostName).toString(); case HostNameRole: return server.value(config_key::hostName).toString();
case CredentialsRole: return QVariant::fromValue(serverCredentials(index.row())); case CredentialsRole: return QVariant::fromValue(serverCredentials(index.row()));
case CredentialsLoginRole: return serverCredentials(index.row()).userName; case CredentialsLoginRole: return serverCredentials(index.row()).userName;
case IsDefaultRole: return index.row() == m_defaultServerIndex; case IsDefaultRole: return index.row() == m_defaultServerIndex;
case IsCurrentlyProcessedRole: return index.row() == m_currentlyProcessedServerIndex; case IsCurrentlyProcessedRole: return index.row() == m_processedServerIndex;
case HasWriteAccessRole: { case HasWriteAccessRole: {
auto credentials = serverCredentials(index.row()); auto credentials = serverCredentials(index.row());
return (!credentials.userName.isEmpty() && !credentials.secretData.isEmpty()); return (!credentials.userName.isEmpty() && !credentials.secretData.isEmpty());
@@ -95,6 +87,13 @@ QVariant ServersModel::data(const QModelIndex &index, int role) const
case DefaultContainerRole: { case DefaultContainerRole: {
return ContainerProps::containerFromString(server.value(config_key::defaultContainer).toString()); return ContainerProps::containerFromString(server.value(config_key::defaultContainer).toString());
} }
case IsServerFromApiRole: {
return server.value(config_key::configVersion).toInt();
}
case HasAmneziaDns: {
QString primaryDns = server.value(config_key::dns1).toString();
return primaryDns == protocols::dns::amneziaDnsIp;
}
} }
return QVariant(); return QVariant();
@@ -111,8 +110,9 @@ void ServersModel::resetModel()
beginResetModel(); beginResetModel();
m_servers = m_settings->serversArray(); m_servers = m_settings->serversArray();
m_defaultServerIndex = m_settings->defaultServerIndex(); m_defaultServerIndex = m_settings->defaultServerIndex();
m_currentlyProcessedServerIndex = m_defaultServerIndex; m_processedServerIndex = m_defaultServerIndex;
endResetModel(); endResetModel();
emit defaultServerIndexChanged(m_defaultServerIndex);
} }
void ServersModel::setDefaultServerIndex(const int index) void ServersModel::setDefaultServerIndex(const int index)
@@ -132,12 +132,7 @@ const QString ServersModel::getDefaultServerName()
return qvariant_cast<QString>(data(m_defaultServerIndex, NameRole)); return qvariant_cast<QString>(data(m_defaultServerIndex, NameRole));
} }
const QString ServersModel::getDefaultServerHostName() QString ServersModel::getServerDescription(const QJsonObject &server, const int index) const
{
return qvariant_cast<QString>(data(m_defaultServerIndex, HostNameRole));
}
QString ServersModel::getDefaultServerDescription(const QJsonObject &server)
{ {
const auto configVersion = server.value(config_key::configVersion).toInt(); const auto configVersion = server.value(config_key::configVersion).toInt();
@@ -145,13 +140,12 @@ QString ServersModel::getDefaultServerDescription(const QJsonObject &server)
if (configVersion) { if (configVersion) {
return server.value(config_key::description).toString(); return server.value(config_key::description).toString();
} else if (isDefaultServerHasWriteAccess()) { } else if (data(index, HasWriteAccessRole).toBool()) {
if (m_isAmneziaDnsEnabled if (m_isAmneziaDnsEnabled && isAmneziaDnsContainerInstalled(index)) {
&& isAmneziaDnsContainerInstalled(m_defaultServerIndex)) {
description += "Amnezia DNS | "; description += "Amnezia DNS | ";
} }
} else { } else {
if (isDefaultServerConfigContainsAmneziaDns()) { if (data(index, HasAmneziaDns).toBool()) {
description += "Amnezia DNS | "; description += "Amnezia DNS | ";
} }
} }
@@ -162,7 +156,7 @@ const QString ServersModel::getDefaultServerDescriptionCollapsed()
{ {
const QJsonObject server = m_servers.at(m_defaultServerIndex).toObject(); const QJsonObject server = m_servers.at(m_defaultServerIndex).toObject();
const auto configVersion = server.value(config_key::configVersion).toInt(); const auto configVersion = server.value(config_key::configVersion).toInt();
auto description = getDefaultServerDescription(server); auto description = getServerDescription(server, m_defaultServerIndex);
if (configVersion) { if (configVersion) {
return description; return description;
} }
@@ -176,7 +170,7 @@ const QString ServersModel::getDefaultServerDescriptionExpanded()
{ {
const QJsonObject server = m_servers.at(m_defaultServerIndex).toObject(); const QJsonObject server = m_servers.at(m_defaultServerIndex).toObject();
const auto configVersion = server.value(config_key::configVersion).toInt(); const auto configVersion = server.value(config_key::configVersion).toInt();
auto description = getDefaultServerDescription(server); auto description = getServerDescription(server, m_defaultServerIndex);
if (configVersion) { if (configVersion) {
return description; return description;
} }
@@ -199,26 +193,21 @@ bool ServersModel::hasServerWithWriteAccess()
return false; return false;
} }
void ServersModel::setCurrentlyProcessedServerIndex(const int index) void ServersModel::setProcessedServerIndex(const int index)
{ {
m_currentlyProcessedServerIndex = index; m_processedServerIndex = index;
updateContainersModel(); updateContainersModel();
emit currentlyProcessedServerIndexChanged(m_currentlyProcessedServerIndex); emit processedServerIndexChanged(m_processedServerIndex);
} }
int ServersModel::getCurrentlyProcessedServerIndex() int ServersModel::getProcessedServerIndex()
{ {
return m_currentlyProcessedServerIndex; return m_processedServerIndex;
} }
QString ServersModel::getCurrentlyProcessedServerHostName() const ServerCredentials ServersModel::getProcessedServerCredentials()
{ {
return qvariant_cast<QString>(data(m_currentlyProcessedServerIndex, HostNameRole)); return serverCredentials(m_processedServerIndex);
}
const ServerCredentials ServersModel::getCurrentlyProcessedServerCredentials()
{
return serverCredentials(m_currentlyProcessedServerIndex);
} }
const ServerCredentials ServersModel::getServerCredentials(const int index) const ServerCredentials ServersModel::getServerCredentials(const int index)
@@ -228,12 +217,17 @@ const ServerCredentials ServersModel::getServerCredentials(const int index)
bool ServersModel::isDefaultServerCurrentlyProcessed() bool ServersModel::isDefaultServerCurrentlyProcessed()
{ {
return m_defaultServerIndex == m_currentlyProcessedServerIndex; return m_defaultServerIndex == m_processedServerIndex;
} }
bool ServersModel::isCurrentlyProcessedServerHasWriteAccess() bool ServersModel::isDefaultServerFromApi()
{ {
return qvariant_cast<bool>(data(m_currentlyProcessedServerIndex, HasWriteAccessRole)); return qvariant_cast<bool>(data(m_defaultServerIndex, IsServerFromApiRole));
}
bool ServersModel::isProcessedServerHasWriteAccess()
{
return qvariant_cast<bool>(data(m_processedServerIndex, HasWriteAccessRole));
} }
bool ServersModel::isDefaultServerHasWriteAccess() bool ServersModel::isDefaultServerHasWriteAccess()
@@ -249,40 +243,42 @@ void ServersModel::addServer(const QJsonObject &server)
endResetModel(); endResetModel();
} }
void ServersModel::editServer(const QJsonObject &server) void ServersModel::editServer(const QJsonObject &server, const int serverIndex)
{ {
m_settings->editServer(m_currentlyProcessedServerIndex, server); m_settings->editServer(serverIndex, server);
m_servers.replace(m_currentlyProcessedServerIndex, m_settings->serversArray().at(m_currentlyProcessedServerIndex)); m_servers.replace(serverIndex, m_settings->serversArray().at(serverIndex));
emit dataChanged(index(m_currentlyProcessedServerIndex, 0), index(m_currentlyProcessedServerIndex, 0)); emit dataChanged(index(serverIndex, 0), index(serverIndex, 0));
if (serverIndex == m_defaultServerIndex) {
updateDefaultServerContainersModel();
}
updateContainersModel(); updateContainersModel();
if (serverIndex == m_defaultServerIndex) {
auto defaultContainer = qvariant_cast<DockerContainer>(getDefaultServerData("defaultContainer"));
emit defaultServerDefaultContainerChanged(defaultContainer);
}
} }
void ServersModel::removeServer() void ServersModel::removeServer()
{ {
beginResetModel(); beginResetModel();
m_settings->removeServer(m_currentlyProcessedServerIndex); m_settings->removeServer(m_processedServerIndex);
m_servers = m_settings->serversArray(); m_servers = m_settings->serversArray();
if (m_settings->defaultServerIndex() == m_currentlyProcessedServerIndex) { if (m_settings->defaultServerIndex() == m_processedServerIndex) {
setDefaultServerIndex(0); setDefaultServerIndex(0);
} else if (m_settings->defaultServerIndex() > m_currentlyProcessedServerIndex) { } else if (m_settings->defaultServerIndex() > m_processedServerIndex) {
setDefaultServerIndex(m_settings->defaultServerIndex() - 1); setDefaultServerIndex(m_settings->defaultServerIndex() - 1);
} }
if (m_settings->serversCount() == 0) { if (m_settings->serversCount() == 0) {
setDefaultServerIndex(-1); setDefaultServerIndex(-1);
} }
setCurrentlyProcessedServerIndex(m_defaultServerIndex); setProcessedServerIndex(m_defaultServerIndex);
endResetModel(); endResetModel();
} }
bool ServersModel::isDefaultServerConfigContainsAmneziaDns()
{
const QJsonObject server = m_servers.at(m_defaultServerIndex).toObject();
QString primaryDns = server.value(config_key::dns1).toString();
return primaryDns == protocols::dns::amneziaDnsIp;
}
QHash<int, QByteArray> ServersModel::roleNames() const QHash<int, QByteArray> ServersModel::roleNames() const
{ {
QHash<int, QByteArray> roles; QHash<int, QByteArray> roles;
@@ -290,6 +286,8 @@ QHash<int, QByteArray> ServersModel::roleNames() const
roles[NameRole] = "serverName"; roles[NameRole] = "serverName";
roles[NameRole] = "name"; roles[NameRole] = "name";
roles[ServerDescriptionRole] = "serverDescription"; roles[ServerDescriptionRole] = "serverDescription";
roles[CollapsedServerDescriptionRole] = "collapsedServerDescription";
roles[ExpandedServerDescriptionRole] = "expandedServerDescription";
roles[HostNameRole] = "hostName"; roles[HostNameRole] = "hostName";
@@ -304,6 +302,8 @@ QHash<int, QByteArray> ServersModel::roleNames() const
roles[ContainsAmneziaDnsRole] = "containsAmneziaDns"; roles[ContainsAmneziaDnsRole] = "containsAmneziaDns";
roles[DefaultContainerRole] = "defaultContainer"; roles[DefaultContainerRole] = "defaultContainer";
roles[IsServerFromApiRole] = "isServerFromApi";
return roles; return roles;
} }
@@ -322,28 +322,29 @@ ServerCredentials ServersModel::serverCredentials(int index) const
void ServersModel::updateContainersModel() void ServersModel::updateContainersModel()
{ {
auto containers = m_servers.at(m_currentlyProcessedServerIndex).toObject().value(config_key::containers).toArray(); auto containers = m_servers.at(m_processedServerIndex).toObject().value(config_key::containers).toArray();
emit containersUpdated(containers); emit containersUpdated(containers);
} }
void ServersModel::updateDefaultServerContainersModel()
{
auto containers = m_servers.at(m_defaultServerIndex).toObject().value(config_key::containers).toArray();
emit defaultServerContainersUpdated(containers);
}
QJsonObject ServersModel::getDefaultServerConfig() QJsonObject ServersModel::getDefaultServerConfig()
{ {
return m_servers.at(m_defaultServerIndex).toObject(); return m_servers.at(m_defaultServerIndex).toObject();
} }
QJsonObject ServersModel::getCurrentlyProcessedServerConfig() void ServersModel::reloadDefaultServerContainerConfig()
{ {
return m_servers.at(m_currentlyProcessedServerIndex).toObject(); QJsonObject server = m_servers.at(m_defaultServerIndex).toObject();
}
void ServersModel::reloadContainerConfig()
{
QJsonObject server = m_servers.at(m_currentlyProcessedServerIndex).toObject();
auto container = ContainerProps::containerFromString(server.value(config_key::defaultContainer).toString()); auto container = ContainerProps::containerFromString(server.value(config_key::defaultContainer).toString());
auto containers = server.value(config_key::containers).toArray(); auto containers = server.value(config_key::containers).toArray();
auto config = m_settings->containerConfig(m_currentlyProcessedServerIndex, container); auto config = m_settings->containerConfig(m_defaultServerIndex, container);
for (auto i = 0; i < containers.size(); i++) { for (auto i = 0; i < containers.size(); i++) {
auto c = ContainerProps::containerFromString(containers.at(i).toObject().value(config_key::container).toString()); auto c = ContainerProps::containerFromString(containers.at(i).toObject().value(config_key::container).toString());
if (c == container) { if (c == container) {
@@ -353,13 +354,13 @@ void ServersModel::reloadContainerConfig()
} }
server.insert(config_key::containers, containers); server.insert(config_key::containers, containers);
editServer(server); editServer(server, m_defaultServerIndex);
} }
void ServersModel::updateContainerConfig(const int containerIndex, const QJsonObject config) void ServersModel::updateContainerConfig(const int containerIndex, const QJsonObject config)
{ {
auto container = static_cast<DockerContainer>(containerIndex); auto container = static_cast<DockerContainer>(containerIndex);
QJsonObject server = m_servers.at(m_currentlyProcessedServerIndex).toObject(); QJsonObject server = m_servers.at(m_processedServerIndex).toObject();
auto containers = server.value(config_key::containers).toArray(); auto containers = server.value(config_key::containers).toArray();
for (auto i = 0; i < containers.size(); i++) { for (auto i = 0; i < containers.size(); i++) {
@@ -377,30 +378,25 @@ void ServersModel::updateContainerConfig(const int containerIndex, const QJsonOb
server.insert(config_key::defaultContainer, ContainerProps::containerToString(container)); server.insert(config_key::defaultContainer, ContainerProps::containerToString(container));
} }
editServer(server); editServer(server, m_processedServerIndex);
} }
void ServersModel::addContainerConfig(const int containerIndex, const QJsonObject config) void ServersModel::addContainerConfig(const int containerIndex, const QJsonObject config)
{ {
auto container = static_cast<DockerContainer>(containerIndex); auto container = static_cast<DockerContainer>(containerIndex);
QJsonObject server = m_servers.at(m_currentlyProcessedServerIndex).toObject(); QJsonObject server = m_servers.at(m_processedServerIndex).toObject();
auto containers = server.value(config_key::containers).toArray(); auto containers = server.value(config_key::containers).toArray();
containers.push_back(config); containers.push_back(config);
server.insert(config_key::containers, containers); server.insert(config_key::containers, containers);
bool isDefaultContainerChanged = false;
auto defaultContainer = server.value(config_key::defaultContainer).toString(); auto defaultContainer = server.value(config_key::defaultContainer).toString();
if ((ContainerProps::containerFromString(defaultContainer) == DockerContainer::None || ContainerProps::containerService(container) != ServiceType::Other)) { if ((ContainerProps::containerFromString(defaultContainer) == DockerContainer::None || ContainerProps::containerService(container) != ServiceType::Other)) {
server.insert(config_key::defaultContainer, ContainerProps::containerToString(container)); server.insert(config_key::defaultContainer, ContainerProps::containerToString(container));
isDefaultContainerChanged = true;
} }
editServer(server); editServer(server, m_processedServerIndex);
if (isDefaultContainerChanged) {
emit defaultContainerChanged(container);
}
} }
void ServersModel::setDefaultContainer(const int serverIndex, const int containerIndex) void ServersModel::setDefaultContainer(const int serverIndex, const int containerIndex)
@@ -408,18 +404,12 @@ void ServersModel::setDefaultContainer(const int serverIndex, const int containe
auto container = static_cast<DockerContainer>(containerIndex); auto container = static_cast<DockerContainer>(containerIndex);
QJsonObject s = m_servers.at(serverIndex).toObject(); QJsonObject s = m_servers.at(serverIndex).toObject();
s.insert(config_key::defaultContainer, ContainerProps::containerToString(container)); s.insert(config_key::defaultContainer, ContainerProps::containerToString(container));
editServer(s); //check editServer(s, serverIndex); //check
emit defaultContainerChanged(container);
} }
DockerContainer ServersModel::getDefaultContainer(const int serverIndex) const QString ServersModel::getDefaultServerDefaultContainerName()
{ {
return qvariant_cast<DockerContainer>(data(serverIndex, DefaultContainerRole)); auto defaultContainer = qvariant_cast<DockerContainer>(getDefaultServerData("defaultContainer"));
}
const QString ServersModel::getDefaultContainerName()
{
auto defaultContainer = getDefaultContainer(m_defaultServerIndex);
return ContainerProps::containerHumanNames().value(defaultContainer); return ContainerProps::containerHumanNames().value(defaultContainer);
} }
@@ -427,15 +417,14 @@ ErrorCode ServersModel::removeAllContainers()
{ {
ServerController serverController(m_settings); ServerController serverController(m_settings);
ErrorCode errorCode = ErrorCode errorCode =
serverController.removeAllContainers(m_settings->serverCredentials(m_currentlyProcessedServerIndex)); serverController.removeAllContainers(m_settings->serverCredentials(m_processedServerIndex));
if (errorCode == ErrorCode::NoError) { if (errorCode == ErrorCode::NoError) {
QJsonObject s = m_servers.at(m_currentlyProcessedServerIndex).toObject(); QJsonObject s = m_servers.at(m_processedServerIndex).toObject();
s.insert(config_key::containers, {}); s.insert(config_key::containers, {});
s.insert(config_key::defaultContainer, ContainerProps::containerToString(DockerContainer::None)); s.insert(config_key::defaultContainer, ContainerProps::containerToString(DockerContainer::None));
editServer(s); editServer(s, m_processedServerIndex);
emit defaultContainerChanged(DockerContainer::None);
} }
return errorCode; return errorCode;
} }
@@ -443,7 +432,7 @@ ErrorCode ServersModel::removeAllContainers()
ErrorCode ServersModel::rebootServer() ErrorCode ServersModel::rebootServer()
{ {
ServerController serverController(m_settings); ServerController serverController(m_settings);
auto credentials = m_settings->serverCredentials(m_currentlyProcessedServerIndex); auto credentials = m_settings->serverCredentials(m_processedServerIndex);
ErrorCode errorCode = serverController.rebootServer(credentials); ErrorCode errorCode = serverController.rebootServer(credentials);
return errorCode; return errorCode;
@@ -452,13 +441,13 @@ ErrorCode ServersModel::rebootServer()
ErrorCode ServersModel::removeContainer(const int containerIndex) ErrorCode ServersModel::removeContainer(const int containerIndex)
{ {
ServerController serverController(m_settings); ServerController serverController(m_settings);
auto credentials = m_settings->serverCredentials(m_currentlyProcessedServerIndex); auto credentials = m_settings->serverCredentials(m_processedServerIndex);
auto dockerContainer = static_cast<DockerContainer>(containerIndex); auto dockerContainer = static_cast<DockerContainer>(containerIndex);
ErrorCode errorCode = serverController.removeContainer(credentials, dockerContainer); ErrorCode errorCode = serverController.removeContainer(credentials, dockerContainer);
if (errorCode == ErrorCode::NoError) { if (errorCode == ErrorCode::NoError) {
QJsonObject server = m_servers.at(m_currentlyProcessedServerIndex).toObject(); QJsonObject server = m_servers.at(m_processedServerIndex).toObject();
auto containers = server.value(config_key::containers).toArray(); auto containers = server.value(config_key::containers).toArray();
for (auto it = containers.begin(); it != containers.end(); it++) { for (auto it = containers.begin(); it != containers.end(); it++) {
@@ -480,32 +469,37 @@ ErrorCode ServersModel::removeContainer(const int containerIndex)
server.insert(config_key::defaultContainer, ContainerProps::containerToString(defaultContainer)); server.insert(config_key::defaultContainer, ContainerProps::containerToString(defaultContainer));
} }
editServer(server); editServer(server, m_processedServerIndex);
emit defaultContainerChanged(defaultContainer);
} }
return errorCode; return errorCode;
} }
void ServersModel::clearCachedProfiles() void ServersModel::clearCachedProfiles()
{ {
const auto &containers = m_settings->containers(m_currentlyProcessedServerIndex); const auto &containers = m_settings->containers(m_processedServerIndex);
for (DockerContainer container : containers.keys()) { for (DockerContainer container : containers.keys()) {
m_settings->clearLastConnectionConfig(m_currentlyProcessedServerIndex, container); m_settings->clearLastConnectionConfig(m_processedServerIndex, container);
} }
m_servers.replace(m_currentlyProcessedServerIndex, m_settings->server(m_currentlyProcessedServerIndex)); m_servers.replace(m_processedServerIndex, m_settings->server(m_processedServerIndex));
if (m_processedServerIndex == m_defaultServerIndex) {
updateDefaultServerContainersModel();
}
updateContainersModel(); updateContainersModel();
} }
void ServersModel::clearCachedProfile(const DockerContainer container) void ServersModel::clearCachedProfile(const DockerContainer container)
{ {
m_settings->clearLastConnectionConfig(m_currentlyProcessedServerIndex, container); m_settings->clearLastConnectionConfig(m_processedServerIndex, container);
m_servers.replace(m_currentlyProcessedServerIndex, m_settings->server(m_currentlyProcessedServerIndex)); m_servers.replace(m_processedServerIndex, m_settings->server(m_processedServerIndex));
if (m_processedServerIndex == m_defaultServerIndex) {
updateDefaultServerContainersModel();
}
updateContainersModel(); updateContainersModel();
} }
bool ServersModel::isAmneziaDnsContainerInstalled(const int serverIndex) bool ServersModel::isAmneziaDnsContainerInstalled(const int serverIndex) const
{ {
QJsonObject server = m_servers.at(serverIndex).toObject(); QJsonObject server = m_servers.at(serverIndex).toObject();
auto containers = server.value(config_key::containers).toArray(); auto containers = server.value(config_key::containers).toArray();
@@ -544,16 +538,6 @@ void ServersModel::toggleAmneziaDns(bool enabled)
emit defaultServerDescriptionChanged(); emit defaultServerDescriptionChanged();
} }
bool ServersModel::isDefaultServerFromApi()
{
return m_settings->server(m_defaultServerIndex).value(config_key::configVersion).toInt();
}
bool ServersModel::isCurrentlyProcessedServerFromApi()
{
return m_settings->server(m_currentlyProcessedServerIndex).value(config_key::configVersion).toInt();
}
bool ServersModel::isServerFromApiAlreadyExists(const quint16 crc) bool ServersModel::isServerFromApiAlreadyExists(const quint16 crc)
{ {
for (const auto &server : qAsConst(m_servers)) { for (const auto &server : qAsConst(m_servers)) {
@@ -564,3 +548,52 @@ bool ServersModel::isServerFromApiAlreadyExists(const quint16 crc)
return false; return false;
} }
QVariant ServersModel::getDefaultServerData(const QString roleString)
{
auto roles = roleNames();
for (auto it = roles.begin(); it != roles.end(); it++) {
if (QString(it.value()) == roleString) {
return data(m_defaultServerIndex, it.key());
}
}
return {};
}
void ServersModel::setDefaultServerData(const QString roleString, const QVariant &value)
{
}
QVariant ServersModel::getProcessedServerData(const QString roleString)
{
auto roles = roleNames();
for (auto it = roles.begin(); it != roles.end(); it++) {
if (QString(it.value()) == roleString) {
return data(m_processedServerIndex, it.key());
}
}
return {};
}
void ServersModel::setProcessedServerData(const QString roleString, const QVariant &value)
{
}
bool ServersModel::isDefaultServerDefaultContainerHasSplitTunneling()
{
auto server = m_servers.at(m_defaultServerIndex).toObject();
auto defaultContainer = ContainerProps::containerFromString(server.value(config_key::defaultContainer).toString());
auto containerConfig = server.value(config_key::containers).toArray().at(defaultContainer).toObject();
auto protocolConfig = containerConfig.value(ContainerProps::containerTypeToString(defaultContainer)).toObject();
if (defaultContainer == DockerContainer::Awg || defaultContainer == DockerContainer::WireGuard) {
return !(protocolConfig.value(config_key::last_config).toString().contains("AllowedIPs = 0.0.0.0/0, ::/0"));
} else if (defaultContainer == DockerContainer::Cloak || defaultContainer == DockerContainer::OpenVpn || defaultContainer == DockerContainer::ShadowSocks) {
return !(protocolConfig.value(config_key::last_config).toString().contains("redirect-gateway"));
}
return false;
}
+37 -29
View File
@@ -12,7 +12,8 @@ public:
enum Roles { enum Roles {
NameRole = Qt::UserRole + 1, NameRole = Qt::UserRole + 1,
ServerDescriptionRole, ServerDescriptionRole,
CollapsedServerDescriptionRole,
ExpandedServerDescriptionRole,
HostNameRole, HostNameRole,
CredentialsRole, CredentialsRole,
@@ -25,7 +26,11 @@ public:
ContainsAmneziaDnsRole, ContainsAmneziaDnsRole,
DefaultContainerRole DefaultContainerRole,
IsServerFromApiRole,
HasAmneziaDns
}; };
ServersModel(std::shared_ptr<Settings> settings, QObject *parent = nullptr); ServersModel(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
@@ -40,47 +45,43 @@ public:
Q_PROPERTY(int defaultIndex READ getDefaultServerIndex WRITE setDefaultServerIndex NOTIFY defaultServerIndexChanged) Q_PROPERTY(int defaultIndex READ getDefaultServerIndex WRITE setDefaultServerIndex NOTIFY defaultServerIndexChanged)
Q_PROPERTY(QString defaultServerName READ getDefaultServerName NOTIFY defaultServerNameChanged) Q_PROPERTY(QString defaultServerName READ getDefaultServerName NOTIFY defaultServerNameChanged)
Q_PROPERTY(QString defaultServerHostName READ getDefaultServerHostName NOTIFY defaultServerIndexChanged) Q_PROPERTY(QString defaultServerDefaultContainerName READ getDefaultServerDefaultContainerName NOTIFY defaultServerDefaultContainerChanged)
Q_PROPERTY(QString defaultContainerName READ getDefaultContainerName NOTIFY defaultContainerChanged) Q_PROPERTY(QString defaultServerDescriptionCollapsed READ getDefaultServerDescriptionCollapsed NOTIFY defaultServerDefaultContainerChanged)
Q_PROPERTY(QString defaultServerDescriptionCollapsed READ getDefaultServerDescriptionCollapsed NOTIFY defaultServerDescriptionChanged) Q_PROPERTY(QString defaultServerDescriptionExpanded READ getDefaultServerDescriptionExpanded NOTIFY defaultServerDefaultContainerChanged)
Q_PROPERTY(QString defaultServerDescriptionExpanded READ getDefaultServerDescriptionExpanded NOTIFY defaultServerDescriptionChanged) Q_PROPERTY(bool isDefaultServerDefaultContainerHasSplitTunneling READ isDefaultServerDefaultContainerHasSplitTunneling NOTIFY defaultServerDefaultContainerChanged)
Q_PROPERTY(bool isDefaultServerFromApi READ isDefaultServerFromApi NOTIFY defaultServerIndexChanged)
Q_PROPERTY(int currentlyProcessedIndex READ getCurrentlyProcessedServerIndex WRITE setCurrentlyProcessedServerIndex Q_PROPERTY(int processedIndex READ getProcessedServerIndex WRITE setProcessedServerIndex NOTIFY processedServerIndexChanged)
NOTIFY currentlyProcessedServerIndexChanged)
public slots: public slots:
void setDefaultServerIndex(const int index); void setDefaultServerIndex(const int index);
const int getDefaultServerIndex(); const int getDefaultServerIndex();
const QString getDefaultServerName(); const QString getDefaultServerName();
const QString getDefaultServerHostName();
const QString getDefaultServerDescriptionCollapsed(); const QString getDefaultServerDescriptionCollapsed();
const QString getDefaultServerDescriptionExpanded(); const QString getDefaultServerDescriptionExpanded();
const QString getDefaultServerDefaultContainerName();
bool isDefaultServerCurrentlyProcessed(); bool isDefaultServerCurrentlyProcessed();
bool isDefaultServerFromApi();
bool isCurrentlyProcessedServerHasWriteAccess(); bool isProcessedServerHasWriteAccess();
bool isDefaultServerHasWriteAccess(); bool isDefaultServerHasWriteAccess();
bool hasServerWithWriteAccess(); bool hasServerWithWriteAccess();
const int getServersCount(); const int getServersCount();
void setCurrentlyProcessedServerIndex(const int index); void setProcessedServerIndex(const int index);
int getCurrentlyProcessedServerIndex(); int getProcessedServerIndex();
QString getCurrentlyProcessedServerHostName(); const ServerCredentials getProcessedServerCredentials();
const ServerCredentials getCurrentlyProcessedServerCredentials();
const ServerCredentials getServerCredentials(const int index); const ServerCredentials getServerCredentials(const int index);
void addServer(const QJsonObject &server); void addServer(const QJsonObject &server);
void editServer(const QJsonObject &server); void editServer(const QJsonObject &server, const int serverIndex);
void removeServer(); void removeServer();
bool isDefaultServerConfigContainsAmneziaDns();
bool isAmneziaDnsContainerInstalled(const int serverIndex);
QJsonObject getDefaultServerConfig(); QJsonObject getDefaultServerConfig();
QJsonObject getCurrentlyProcessedServerConfig();
void reloadContainerConfig(); void reloadDefaultServerContainerConfig();
void updateContainerConfig(const int containerIndex, const QJsonObject config); void updateContainerConfig(const int containerIndex, const QJsonObject config);
void addContainerConfig(const int containerIndex, const QJsonObject config); void addContainerConfig(const int containerIndex, const QJsonObject config);
@@ -92,42 +93,49 @@ public slots:
ErrorCode rebootServer(); ErrorCode rebootServer();
void setDefaultContainer(const int serverIndex, const int containerIndex); void setDefaultContainer(const int serverIndex, const int containerIndex);
DockerContainer getDefaultContainer(const int serverIndex);
const QString getDefaultContainerName();
QStringList getAllInstalledServicesName(const int serverIndex); QStringList getAllInstalledServicesName(const int serverIndex);
void toggleAmneziaDns(bool enabled); void toggleAmneziaDns(bool enabled);
bool isDefaultServerFromApi();
bool isCurrentlyProcessedServerFromApi();
bool isServerFromApiAlreadyExists(const quint16 crc); bool isServerFromApiAlreadyExists(const quint16 crc);
QVariant getDefaultServerData(const QString roleString);
void setDefaultServerData(const QString roleString, const QVariant &value);
QVariant getProcessedServerData(const QString roleString);
void setProcessedServerData(const QString roleString, const QVariant &value);
bool isDefaultServerDefaultContainerHasSplitTunneling();
protected: protected:
QHash<int, QByteArray> roleNames() const override; QHash<int, QByteArray> roleNames() const override;
signals: signals:
void currentlyProcessedServerIndexChanged(const int index); void processedServerIndexChanged(const int index);
void defaultServerIndexChanged(const int index); void defaultServerIndexChanged(const int index);
void defaultServerNameChanged(); void defaultServerNameChanged();
void defaultServerDescriptionChanged(); void defaultServerDescriptionChanged();
void containersUpdated(const QJsonArray &containers); void containersUpdated(const QJsonArray &containers);
void defaultContainerChanged(const int containerIndex); void defaultServerContainersUpdated(const QJsonArray &containers);
void defaultServerDefaultContainerChanged(const int containerIndex);
private: private:
ServerCredentials serverCredentials(int index) const; ServerCredentials serverCredentials(int index) const;
void updateContainersModel(); void updateContainersModel();
void updateDefaultServerContainersModel();
QString getDefaultServerDescription(const QJsonObject &server); QString getServerDescription(const QJsonObject &server, const int index) const;
bool isAmneziaDnsContainerInstalled(const int serverIndex) const;
QJsonArray m_servers; QJsonArray m_servers;
std::shared_ptr<Settings> m_settings; std::shared_ptr<Settings> m_settings;
int m_defaultServerIndex; int m_defaultServerIndex;
int m_currentlyProcessedServerIndex; int m_processedServerIndex;
bool m_isAmneziaDnsEnabled = m_settings->useAmneziaDns(); bool m_isAmneziaDnsEnabled = m_settings->useAmneziaDns();
}; };
+1
View File
@@ -113,6 +113,7 @@ void SitesModel::toggleSplitTunneling(bool enabled)
m_settings->setRouteMode(Settings::RouteMode::VpnAllSites); m_settings->setRouteMode(Settings::RouteMode::VpnAllSites);
} }
m_isSplitTunnelingEnabled = enabled; m_isSplitTunnelingEnabled = enabled;
emit splitTunnelingToggled();
} }
QVector<QPair<QString, QString> > SitesModel::getCurrentSites() QVector<QPair<QString, QString> > SitesModel::getCurrentSites()
+2
View File
@@ -22,6 +22,7 @@ public:
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
Q_PROPERTY(int routeMode READ getRouteMode WRITE setRouteMode NOTIFY routeModeChanged) Q_PROPERTY(int routeMode READ getRouteMode WRITE setRouteMode NOTIFY routeModeChanged)
Q_PROPERTY(bool isTunnelingEnabled READ isSplitTunnelingEnabled NOTIFY splitTunnelingToggled)
public slots: public slots:
bool addSite(const QString &hostname, const QString &ip); bool addSite(const QString &hostname, const QString &ip);
@@ -38,6 +39,7 @@ public slots:
signals: signals:
void routeModeChanged(); void routeModeChanged();
void splitTunnelingToggled();
protected: protected:
QHash<int, QByteArray> roleNames() const override; QHash<int, QByteArray> roleNames() const override;
+1 -1
View File
@@ -138,7 +138,7 @@ Button {
} }
onClicked: { onClicked: {
ServersModel.setCurrentlyProcessedServerIndex(ServersModel.defaultIndex) ServersModel.setProcessedServerIndex(ServersModel.defaultIndex)
ApiController.updateServerConfigFromApi() ApiController.updateServerConfigFromApi()
} }
} }
@@ -15,6 +15,7 @@ ListView {
id: menuContent id: menuContent
property var rootWidth property var rootWidth
property var selectedText
width: rootWidth width: rootWidth
height: menuContent.contentItem.height height: menuContent.contentItem.height
@@ -51,7 +52,7 @@ ListView {
showImage: !isInstalled showImage: !isInstalled
checkable: isInstalled && !ConnectionController.isConnected && isSupported checkable: isInstalled && !ConnectionController.isConnected && isSupported
checked: proxyContainersModel.mapToSource(index) === ServersModel.getDefaultContainer(ServersModel.defaultIndex) checked: proxyDefaultServerContainersModel.mapToSource(index) === ServersModel.getDefaultServerData("defaultContainer")
onClicked: { onClicked: {
if (ConnectionController.isConnected && isInstalled) { if (ConnectionController.isConnected && isInstalled) {
@@ -61,14 +62,14 @@ ListView {
if (checked) { if (checked) {
containersDropDown.close() containersDropDown.close()
ServersModel.setDefaultContainer(ServersModel.defaultIndex, proxyContainersModel.mapToSource(index)) ServersModel.setDefaultContainer(ServersModel.defaultIndex, proxyDefaultServerContainersModel.mapToSource(index))
} else { } else {
if (!isSupported && isInstalled) { if (!isSupported && isInstalled) {
PageController.showErrorMessage(qsTr("The selected protocol is not supported on the current platform")) PageController.showErrorMessage(qsTr("The selected protocol is not supported on the current platform"))
return return
} }
ContainersModel.setCurrentlyProcessedContainerIndex(proxyContainersModel.mapToSource(index)) ContainersModel.setCurrentlyProcessedContainerIndex(proxyDefaultServerContainersModel.mapToSource(index))
InstallController.setShouldCreateServer(false) InstallController.setShouldCreateServer(false)
PageController.goToPage(PageEnum.PageSetupWizardProtocolSettings) PageController.goToPage(PageEnum.PageSetupWizardProtocolSettings)
containersDropDown.close() containersDropDown.close()
@@ -0,0 +1,92 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import PageEnum 1.0
import "../Controls2"
import "../Controls2/TextTypes"
import "../Config"
DrawerType2 {
id: root
anchors.fill: parent
expandedHeight: parent.height * 0.7
expandedContent: ColumnLayout {
id: content
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
spacing: 0
Header2Type {
Layout.fillWidth: true
Layout.topMargin: 24
Layout.rightMargin: 16
Layout.leftMargin: 16
Layout.bottomMargin: 16
headerText: qsTr("Split tunneling")
descriptionText: qsTr("Allows you to connect to some sites or applications through a VPN connection and bypass others")
}
LabelWithButtonType {
Layout.fillWidth: true
Layout.topMargin: 16
visible: ServersModel.isDefaultServerDefaultContainerHasSplitTunneling && ServersModel.getDefaultServerData("isServerFromApi")
text: qsTr("Split tunneling on the server")
descriptionText: qsTr("Enabled \nCan't be disabled for current server")
rightImageSource: "qrc:/images/controls/chevron-right.svg"
clickedFunction: function() {
// PageController.goToPage(PageEnum.PageSettingsSplitTunneling)
// root.close()
}
}
DividerType {
visible: ServersModel.isDefaultServerDefaultContainerHasSplitTunneling && ServersModel.getDefaultServerData("isServerFromApi")
}
LabelWithButtonType {
Layout.fillWidth: true
Layout.topMargin: 16
enabled: ! ServersModel.isDefaultServerDefaultContainerHasSplitTunneling || !ServersModel.getDefaultServerData("isServerFromApi")
text: qsTr("Site-based split tunneling")
descriptionText: enabled && SitesModel.isTunnelingEnabled ? qsTr("Enabled") : qsTr("Disabled")
rightImageSource: "qrc:/images/controls/chevron-right.svg"
clickedFunction: function() {
PageController.goToPage(PageEnum.PageSettingsSplitTunneling)
root.close()
}
}
DividerType {
}
LabelWithButtonType {
Layout.fillWidth: true
visible: false
text: qsTr("App-based split tunneling")
rightImageSource: "qrc:/images/controls/chevron-right.svg"
clickedFunction: function() {
// PageController.goToPage(PageEnum.PageSetupWizardConfigSource)
root.close()
}
}
DividerType {
visible: false
}
}
}
@@ -107,13 +107,6 @@ DrawerType2 {
text: qsTr("Copy") text: qsTr("Copy")
imageSource: "qrc:/images/controls/copy.svg" imageSource: "qrc:/images/controls/copy.svg"
clickedFunc: function() {
configText.selectAll()
configText.copy()
configText.select(0, 0)
PageController.showNotificationMessage(qsTr("Copied"))
}
} }
BasicButtonType { BasicButtonType {
@@ -132,13 +125,6 @@ DrawerType2 {
text: qsTr("Copy config string") text: qsTr("Copy config string")
imageSource: "qrc:/images/controls/copy.svg" imageSource: "qrc:/images/controls/copy.svg"
clickedFunc: function() {
nativeConfigString.selectAll()
nativeConfigString.copy()
nativeConfigString.select(0, 0)
PageController.showNotificationMessage(qsTr("Copied"))
}
} }
BasicButtonType { BasicButtonType {
@@ -201,7 +187,7 @@ DrawerType2 {
anchors.topMargin: 16 anchors.topMargin: 16
backButtonFunction: function() { backButtonFunction: function() {
configContentDrawer.open() configContentDrawer.close()
} }
} }
+18 -1
View File
@@ -21,6 +21,8 @@ Button {
property int borderFocusedWidth: 1 property int borderFocusedWidth: 1
property string imageSource property string imageSource
property string rightImageSource
property string leftImageColor: textColor
property bool squareLeftSide: false property bool squareLeftSide: false
@@ -118,7 +120,7 @@ Button {
layer { layer {
enabled: true enabled: true
effect: ColorOverlay { effect: ColorOverlay {
color: textColor color: leftImageColor
} }
} }
} }
@@ -131,6 +133,21 @@ Button {
horizontalAlignment: Text.AlignLeft horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
} }
Image {
Layout.preferredHeight: 20
Layout.preferredWidth: 20
source: root.rightImageSource
visible: root.rightImageSource === "" ? false : true
layer {
enabled: true
effect: ColorOverlay {
color: textColor
}
}
}
} }
} }
+1
View File
@@ -84,6 +84,7 @@ Item {
id: emptyArea id: emptyArea
anchors.fill: parent anchors.fill: parent
enabled: root.isExpanded enabled: root.isExpanded
visible: enabled
onClicked: { onClicked: {
root.close() root.close()
} }
+51 -26
View File
@@ -34,8 +34,45 @@ PageType {
anchors.bottomMargin: drawer.collapsedHeight anchors.bottomMargin: drawer.collapsedHeight
ConnectButton { ConnectButton {
id: connectButton
anchors.centerIn: parent anchors.centerIn: parent
} }
BasicButtonType {
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: 34
leftPadding: 16
rightPadding: 16
implicitHeight: 36
defaultColor: "transparent"
hoveredColor: Qt.rgba(1, 1, 1, 0.08)
pressedColor: Qt.rgba(1, 1, 1, 0.12)
disabledColor: "#878B91"
textColor: "#878B91"
leftImageColor: "transparent"
borderWidth: 0
property bool isSplitTunnelingEnabled: SitesModel.isTunnelingEnabled ||
(ServersModel.isDefaultServerDefaultContainerHasSplitTunneling && ServersModel.getDefaultServerData("isServerFromApi"))
text: isSplitTunnelingEnabled ? qsTr("Split tunneling enabled") : qsTr("Split tunneling disabled")
imageSource: isSplitTunnelingEnabled ? "qrc:/images/controls/split-tunneling.svg" : ""
rightImageSource: "qrc:/images/controls/chevron-down.svg"
onClicked: {
homeSplitTunnelingDrawer.open()
}
HomeSplitTunnelingDrawer {
id: homeSplitTunnelingDrawer
parent: root
}
}
} }
@@ -156,7 +193,7 @@ PageType {
LabelTextType { LabelTextType {
id: expandedServersMenuDescription id: expandedServersMenuDescription
Layout.bottomMargin: 24 Layout.bottomMargin: ServersModel.isDefaultServerFromApi ? 69 : 24
Layout.fillWidth: true Layout.fillWidth: true
horizontalAlignment: Qt.AlignHCenter horizontalAlignment: Qt.AlignHCenter
verticalAlignment: Qt.AlignVCenter verticalAlignment: Qt.AlignVCenter
@@ -167,6 +204,9 @@ PageType {
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
spacing: 8 spacing: 8
visible: !ServersModel.isDefaultServerFromApi
onVisibleChanged: expandedServersMenuDescription.Layout
DropDownType { DropDownType {
id: containersDropDown id: containersDropDown
@@ -179,13 +219,12 @@ PageType {
rootButtonTextTopMargin: 8 rootButtonTextTopMargin: 8
rootButtonTextBottomMargin: 8 rootButtonTextBottomMargin: 8
text: ServersModel.defaultContainerName text: ServersModel.defaultServerDefaultContainerName
textColor: "#0E0E11" textColor: "#0E0E11"
headerText: qsTr("VPN protocol") headerText: qsTr("VPN protocol")
headerBackButtonImage: "qrc:/images/controls/arrow-left.svg" headerBackButtonImage: "qrc:/images/controls/arrow-left.svg"
rootButtonClickedFunction: function() { rootButtonClickedFunction: function() {
ServersModel.currentlyProcessedIndex = serversMenuContent.currentIndex
containersDropDown.open() containersDropDown.open()
} }
@@ -197,22 +236,23 @@ PageType {
Connections { Connections {
target: ServersModel target: ServersModel
function onCurrentlyProcessedServerIndexChanged() { function onDefaultServerIndexChanged() {
updateContainersModelFilters() updateContainersModelFilters()
} }
} }
function updateContainersModelFilters() { function updateContainersModelFilters() {
if (ServersModel.isCurrentlyProcessedServerHasWriteAccess()) { if (ServersModel.isDefaultServerHasWriteAccess()) {
proxyContainersModel.filters = ContainersModelFilters.getWriteAccessProtocolsListFilters() proxyDefaultServerContainersModel.filters = ContainersModelFilters.getWriteAccessProtocolsListFilters()
} else { } else {
proxyContainersModel.filters = ContainersModelFilters.getReadAccessProtocolsListFilters() proxyDefaultServerContainersModel.filters = ContainersModelFilters.getReadAccessProtocolsListFilters()
} }
} }
model: SortFilterProxyModel { model: SortFilterProxyModel {
id: proxyContainersModel id: proxyDefaultServerContainersModel
sourceModel: ContainersModel sourceModel: DefaultServerContainersModel
sorters: [ sorters: [
RoleSorter { roleName: "isInstalled"; sortOrder: Qt.DescendingOrder } RoleSorter { roleName: "isInstalled"; sortOrder: Qt.DescendingOrder }
] ]
@@ -308,21 +348,7 @@ PageType {
Layout.fillWidth: true Layout.fillWidth: true
text: name text: name
descriptionText: { descriptionText: serverDescription
var fullDescription = ""
if (hasWriteAccess) {
if (SettingsController.isAmneziaDnsEnabled()
&& ServersModel.isAmneziaDnsContainerInstalled(index)) {
fullDescription += "Amnezia DNS | "
}
} else {
if (containsAmneziaDns) {
fullDescription += "Amnezia DNS | "
}
}
return fullDescription += serverDescription
}
checked: index === serversMenuContent.currentIndex checked: index === serversMenuContent.currentIndex
checkable: !ConnectionController.isConnected checkable: !ConnectionController.isConnected
@@ -337,7 +363,6 @@ PageType {
serversMenuContent.currentIndex = index serversMenuContent.currentIndex = index
ServersModel.currentlyProcessedIndex = index
ServersModel.defaultIndex = index ServersModel.defaultIndex = index
} }
@@ -358,7 +383,7 @@ PageType {
z: 1 z: 1
onClicked: function() { onClicked: function() {
ServersModel.currentlyProcessedIndex = index ServersModel.processedIndex = index
PageController.goToPage(PageEnum.PageSettingsServerInfo) PageController.goToPage(PageEnum.PageSettingsServerInfo)
drawer.close() drawer.close()
} }
@@ -44,7 +44,7 @@ PageType {
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
enabled: ServersModel.isCurrentlyProcessedServerHasWriteAccess() enabled: ServersModel.isProcessedServerHasWriteAccess()
ListView { ListView {
@@ -43,7 +43,7 @@ PageType {
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
enabled: ServersModel.isCurrentlyProcessedServerHasWriteAccess() enabled: ServersModel.isProcessedServerHasWriteAccess()
ListView { ListView {
id: listview id: listview
@@ -44,7 +44,7 @@ PageType {
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
enabled: ServersModel.isCurrentlyProcessedServerHasWriteAccess() enabled: ServersModel.isProcessedServerHasWriteAccess()
ListView { ListView {
id: listview id: listview
+1 -1
View File
@@ -175,7 +175,7 @@ PageType {
width: parent.width width: parent.width
visible: ServersModel.isCurrentlyProcessedServerHasWriteAccess() visible: ServersModel.isProcessedServerHasWriteAccess()
text: qsTr("Remove ") + ContainersModel.getCurrentlyProcessedContainerName() text: qsTr("Remove ") + ContainersModel.getCurrentlyProcessedContainerName()
textColor: "#EB5757" textColor: "#EB5757"
@@ -43,7 +43,7 @@ PageType {
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
enabled: ServersModel.isCurrentlyProcessedServerHasWriteAccess() enabled: ServersModel.isProcessedServerHasWriteAccess()
ListView { ListView {
id: listview id: listview
@@ -49,7 +49,7 @@ PageType {
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
enabled: ServersModel.isCurrentlyProcessedServerHasWriteAccess() enabled: ServersModel.isProcessedServerHasWriteAccess()
ListView { ListView {
id: listview id: listview
@@ -88,7 +88,7 @@ PageType {
Layout.topMargin: 32 Layout.topMargin: 32
text: qsTr("Host") text: qsTr("Host")
descriptionText: ServersModel.getCurrentlyProcessedServerHostName() descriptionText: ServersModel.getProcessedServerData("HostName")
descriptionOnTop: true descriptionOnTop: true
+1 -1
View File
@@ -175,7 +175,7 @@ PageType {
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
text: SettingsController.getAppVersion() text: qsTr("Software version: %1").arg(SettingsController.getAppVersion())
color: "#878B91" color: "#878B91"
} }
@@ -84,6 +84,27 @@ PageType {
visible: !GC.isMobile() visible: !GC.isMobile()
} }
SwitcherType {
visible: !GC.isMobile()
Layout.fillWidth: true
Layout.margins: 16
text: qsTr("Auto connect")
descriptionText: qsTr("Connect to VPN on app start")
checked: SettingsController.isAutoConnectEnabled()
onCheckedChanged: {
if (checked !== SettingsController.isAutoConnectEnabled()) {
SettingsController.toggleAutoConnect(checked)
}
}
}
DividerType {
visible: !GC.isMobile()
}
SwitcherType { SwitcherType {
visible: !GC.isMobile() visible: !GC.isMobile()
@@ -41,27 +41,6 @@ PageType {
headerText: qsTr("Connection") headerText: qsTr("Connection")
} }
SwitcherType {
visible: !GC.isMobile()
Layout.fillWidth: true
Layout.margins: 16
text: qsTr("Auto connect")
descriptionText: qsTr("Connect to VPN on app start")
checked: SettingsController.isAutoConnectEnabled()
onCheckedChanged: {
if (checked !== SettingsController.isAutoConnectEnabled()) {
SettingsController.toggleAutoConnect(checked)
}
}
}
DividerType {
visible: !GC.isMobile()
}
SwitcherType { SwitcherType {
Layout.fillWidth: true Layout.fillWidth: true
Layout.margins: 16 Layout.margins: 16
+4 -2
View File
@@ -30,10 +30,12 @@ PageType {
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
contentHeight: content.height contentHeight: content.height
enabled: !ServersModel.isDefaultServerFromApi() property var isServerFromApi: ServersModel.getDefaultServerData("isServerFromApi")
enabled: !isServerFromApi
Component.onCompleted: { Component.onCompleted: {
if (ServersModel.isDefaultServerFromApi()) { if (isServerFromApi) {
PageController.showNotificationMessage(qsTr("Default server does not support custom dns")) PageController.showNotificationMessage(qsTr("Default server does not support custom dns"))
} }
} }
@@ -28,7 +28,7 @@ PageType {
PageController.showErrorMessage(message) PageController.showErrorMessage(message)
} }
function onRemoveCurrentlyProcessedServerFinished(finishedMessage) { function onRemoveProcessedServerFinished(finishedMessage) {
if (!ServersModel.getServersCount()) { if (!ServersModel.getServersCount()) {
PageController.replaceStartPage() PageController.replaceStartPage()
} else { } else {
@@ -38,7 +38,7 @@ PageType {
PageController.showNotificationMessage(finishedMessage) PageController.showNotificationMessage(finishedMessage)
} }
function onRebootCurrentlyProcessedServerFinished(finishedMessage) { function onRebootProcessedServerFinished(finishedMessage) {
PageController.showNotificationMessage(finishedMessage) PageController.showNotificationMessage(finishedMessage)
} }
@@ -64,8 +64,8 @@ PageType {
Connections { Connections {
target: ServersModel target: ServersModel
function onCurrentlyProcessedServerIndexChanged() { function onProcessedServerIndexChanged() {
content.isServerWithWriteAccess = ServersModel.isCurrentlyProcessedServerHasWriteAccess() content.isServerWithWriteAccess = ServersModel.isProcessedServerHasWriteAccess()
} }
} }
@@ -82,7 +82,7 @@ PageType {
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
property bool isServerWithWriteAccess: ServersModel.isCurrentlyProcessedServerHasWriteAccess() property bool isServerWithWriteAccess: ServersModel.isProcessedServerHasWriteAccess()
LabelWithButtonType { LabelWithButtonType {
visible: content.isServerWithWriteAccess visible: content.isServerWithWriteAccess
@@ -149,7 +149,7 @@ PageType {
if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) { if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) {
ConnectionController.closeConnection() ConnectionController.closeConnection()
} }
InstallController.rebootCurrentlyProcessedServer() InstallController.rebootProcessedServer()
PageController.showBusyIndicator(false) PageController.showBusyIndicator(false)
} }
var noButtonFunction = function() { var noButtonFunction = function() {
@@ -180,7 +180,7 @@ PageType {
if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) { if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) {
ConnectionController.closeConnection() ConnectionController.closeConnection()
} }
InstallController.removeCurrentlyProcessedServer() InstallController.removeProcessedServer()
PageController.showBusyIndicator(false) PageController.showBusyIndicator(false)
} }
var noButtonFunction = function() { var noButtonFunction = function() {
@@ -224,7 +224,7 @@ PageType {
} }
LabelWithButtonType { LabelWithButtonType {
visible: ServersModel.isCurrentlyProcessedServerFromApi() visible: ServersModel.getProcessedServerData("isServerFromApi")
Layout.fillWidth: true Layout.fillWidth: true
text: qsTr("Reset API config") text: qsTr("Reset API config")
@@ -249,7 +249,7 @@ PageType {
} }
DividerType { DividerType {
visible: ServersModel.isCurrentlyProcessedServerFromApi() visible: ServersModel.getProcessedServerData("isServerFromApi")
} }
} }
} }
@@ -63,7 +63,7 @@ PageType {
headerText: name headerText: name
descriptionText: { descriptionText: {
if (ServersModel.isCurrentlyProcessedServerHasWriteAccess()) { if (ServersModel.isProcessedServerHasWriteAccess()) {
return credentialsLogin + " · " + hostName return credentialsLogin + " · " + hostName
} else { } else {
return hostName return hostName
@@ -107,7 +107,7 @@ PageType {
width: parent.width width: parent.width
visible: ServersModel.isCurrentlyProcessedServerHasWriteAccess() visible: ServersModel.isProcessedServerHasWriteAccess()
text: qsTr("Remove ") + ContainersModel.getCurrentlyProcessedContainerName() text: qsTr("Remove ") + ContainersModel.getCurrentlyProcessedContainerName()
textColor: "#EB5757" textColor: "#EB5757"
@@ -38,13 +38,13 @@ PageType {
Connections { Connections {
target: ServersModel target: ServersModel
function onCurrentlyProcessedServerIndexChanged() { function onProcessedServerIndexChanged() {
settingsContainersListView.updateContainersModelFilters() settingsContainersListView.updateContainersModelFilters()
} }
} }
function updateContainersModelFilters() { function updateContainersModelFilters() {
if (ServersModel.isCurrentlyProcessedServerHasWriteAccess()) { if (ServersModel.isProcessedServerHasWriteAccess()) {
proxyContainersModel.filters = ContainersModelFilters.getWriteAccessProtocolsListFilters() proxyContainersModel.filters = ContainersModelFilters.getWriteAccessProtocolsListFilters()
} else { } else {
proxyContainersModel.filters = ContainersModelFilters.getReadAccessProtocolsListFilters() proxyContainersModel.filters = ContainersModelFilters.getReadAccessProtocolsListFilters()
@@ -38,13 +38,13 @@ PageType {
Connections { Connections {
target: ServersModel target: ServersModel
function onCurrentlyProcessedServerIndexChanged() { function onProcessedServerIndexChanged() {
settingsContainersListView.updateContainersModelFilters() settingsContainersListView.updateContainersModelFilters()
} }
} }
function updateContainersModelFilters() { function updateContainersModelFilters() {
if (ServersModel.isCurrentlyProcessedServerHasWriteAccess()) { if (ServersModel.isProcessedServerHasWriteAccess()) {
proxyContainersModel.filters = ContainersModelFilters.getWriteAccessServicesListFilters() proxyContainersModel.filters = ContainersModelFilters.getWriteAccessServicesListFilters()
} else { } else {
proxyContainersModel.filters = ContainersModelFilters.getReadAccessServicesListFilters() proxyContainersModel.filters = ContainersModelFilters.getReadAccessServicesListFilters()
@@ -87,7 +87,7 @@ PageType {
rightImageSource: "qrc:/images/controls/chevron-right.svg" rightImageSource: "qrc:/images/controls/chevron-right.svg"
clickedFunction: function() { clickedFunction: function() {
ServersModel.currentlyProcessedIndex = index ServersModel.processedIndex = index
PageController.goToPage(PageEnum.PageSettingsServerInfo) PageController.goToPage(PageEnum.PageSettingsServerInfo)
} }
} }
@@ -20,15 +20,23 @@ import "../Components"
PageType { PageType {
id: root id: root
property var isServerFromApi: ServersModel.getDefaultServerData("isServerFromApi")
defaultActiveFocusItem: website_ip_field.textField defaultActiveFocusItem: website_ip_field.textField
property bool pageEnabled: { property bool pageEnabled: {
return !ConnectionController.isConnected && !ServersModel.isDefaultServerFromApi() return !ConnectionController.isConnected && !isServerFromApi
} }
Component.onCompleted: { Component.onCompleted: {
if (ServersModel.isDefaultServerFromApi()) { if (ConnectionController.isConnected) {
PageController.showNotificationMessage(qsTr("Cannot change split tunneling settings during active connection"))
root.pageEnabled = false
} else if (ServersModel.isDefaultServerDefaultContainerHasSplitTunneling && isServerFromApi) {
PageController.showNotificationMessage(qsTr("Default server does not support split tunneling function")) PageController.showNotificationMessage(qsTr("Default server does not support split tunneling function"))
root.pageEnabled = false
} else {
root.pageEnabled = true
} }
} }
@@ -106,7 +114,7 @@ PageType {
Layout.fillWidth: true Layout.fillWidth: true
Layout.rightMargin: 16 Layout.rightMargin: 16
checked: SitesModel.isSplitTunnelingEnabled() checked: SitesModel.isTunnelingEnabled
onToggled: { onToggled: {
SitesModel.toggleSplitTunneling(checked) SitesModel.toggleSplitTunneling(checked)
selector.text = root.routeModesModel[getRouteModesModelIndex()].name selector.text = root.routeModesModel[getRouteModesModelIndex()].name
@@ -26,7 +26,7 @@ PageType {
function onInstallContainerFinished(finishedMessage, isServiceInstall) { function onInstallContainerFinished(finishedMessage, isServiceInstall) {
if (!ConnectionController.isConnected && !isServiceInstall) { if (!ConnectionController.isConnected && !isServiceInstall) {
ServersModel.setDefaultContainer(ServersModel.currentlyProcessedIndex, ContainersModel.getCurrentlyProcessedContainerIndex()) ServersModel.setDefaultContainer(ServersModel.processedIndex, ContainersModel.getCurrentlyProcessedContainerIndex())
} }
PageController.closePage() // close installing page PageController.closePage() // close installing page
@@ -42,7 +42,7 @@ PageType {
function onInstallServerFinished(finishedMessage) { function onInstallServerFinished(finishedMessage) {
if (!ConnectionController.isConnected) { if (!ConnectionController.isConnected) {
ServersModel.setDefaultServerIndex(ServersModel.getServersCount() - 1); ServersModel.setDefaultServerIndex(ServersModel.getServersCount() - 1);
ServersModel.currentlyProcessedIndex = ServersModel.defaultIndex ServersModel.processedIndex = ServersModel.defaultIndex
} }
PageController.goToStartPage() PageController.goToStartPage()
@@ -55,7 +55,7 @@ PageType {
function onServerAlreadyExists(serverIndex) { function onServerAlreadyExists(serverIndex) {
PageController.goToStartPage() PageController.goToStartPage()
ServersModel.currentlyProcessedIndex = serverIndex ServersModel.processedIndex = serverIndex
PageController.goToPage(PageEnum.PageSettingsServerInfo, false) PageController.goToPage(PageEnum.PageSettingsServerInfo, false)
PageController.showErrorMessage(qsTr("The server has already been added to the application")) PageController.showErrorMessage(qsTr("The server has already been added to the application"))
@@ -30,7 +30,7 @@ PageType {
function onImportFinished() { function onImportFinished() {
if (!ConnectionController.isConnected) { if (!ConnectionController.isConnected) {
ServersModel.setDefaultServerIndex(ServersModel.getServersCount() - 1); ServersModel.setDefaultServerIndex(ServersModel.getServersCount() - 1);
ServersModel.currentlyProcessedIndex = ServersModel.defaultIndex ServersModel.processedIndex = ServersModel.defaultIndex
} }
PageController.goToStartPage() PageController.goToStartPage()
+25 -7
View File
@@ -22,6 +22,7 @@ PageType {
AmneziaConnection, AmneziaConnection,
OpenVpn, OpenVpn,
WireGuard, WireGuard,
Awg,
ShadowSocks, ShadowSocks,
Cloak Cloak
} }
@@ -31,7 +32,7 @@ PageType {
PageController.showBusyIndicator(true) PageController.showBusyIndicator(true)
ExportController.revokeConfig(index, ExportController.revokeConfig(index,
ContainersModel.getCurrentlyProcessedContainerIndex(), ContainersModel.getCurrentlyProcessedContainerIndex(),
ServersModel.getCurrentlyProcessedServerCredentials()) ServersModel.getProcessedServerCredentials())
PageController.showBusyIndicator(false) PageController.showBusyIndicator(false)
PageController.showNotificationMessage(qsTr("Config revoked")) PageController.showNotificationMessage(qsTr("Config revoked"))
} }
@@ -48,7 +49,10 @@ PageType {
PageController.showBusyIndicator(true) PageController.showBusyIndicator(true)
switch (type) { switch (type) {
case PageShare.ConfigType.AmneziaConnection: ExportController.generateConnectionConfig(clientNameTextField.textFieldText); break; case PageShare.ConfigType.AmneziaConnection: {
ExportController.generateConnectionConfig(clientNameTextField.textFieldText);
break;
}
case PageShare.ConfigType.OpenVpn: { case PageShare.ConfigType.OpenVpn: {
ExportController.generateOpenVpnConfig(clientNameTextField.textFieldText) ExportController.generateOpenVpnConfig(clientNameTextField.textFieldText)
shareConnectionDrawer.configCaption = qsTr("Save OpenVPN config") shareConnectionDrawer.configCaption = qsTr("Save OpenVPN config")
@@ -63,6 +67,13 @@ PageType {
shareConnectionDrawer.configFileName = "amnezia_for_wireguard" shareConnectionDrawer.configFileName = "amnezia_for_wireguard"
break break
} }
case PageShare.ConfigType.Awg: {
ExportController.generateAwgConfig(clientNameTextField.textFieldText)
shareConnectionDrawer.configCaption = qsTr("Save AmneziaWG config")
shareConnectionDrawer.configExtension = ".conf"
shareConnectionDrawer.configFileName = "amnezia_for_awg"
break
}
case PageShare.ConfigType.ShadowSocks: { case PageShare.ConfigType.ShadowSocks: {
ExportController.generateShadowSocksConfig() ExportController.generateShadowSocksConfig()
shareConnectionDrawer.configCaption = qsTr("Save ShadowSocks config") shareConnectionDrawer.configCaption = qsTr("Save ShadowSocks config")
@@ -110,6 +121,11 @@ PageType {
property string name: qsTr("WireGuard native format") property string name: qsTr("WireGuard native format")
property var type: PageShare.ConfigType.WireGuard property var type: PageShare.ConfigType.WireGuard
} }
QtObject {
id: awgConnectionFormat
property string name: qsTr("AmneziaWG native format")
property var type: PageShare.ConfigType.Awg
}
QtObject { QtObject {
id: shadowSocksConnectionFormat id: shadowSocksConnectionFormat
property string name: qsTr("ShadowSocks native format") property string name: qsTr("ShadowSocks native format")
@@ -230,7 +246,7 @@ PageType {
accessTypeSelector.currentIndex = 1 accessTypeSelector.currentIndex = 1
PageController.showBusyIndicator(true) PageController.showBusyIndicator(true)
ExportController.updateClientManagementModel(ContainersModel.getCurrentlyProcessedContainerIndex(), ExportController.updateClientManagementModel(ContainersModel.getCurrentlyProcessedContainerIndex(),
ServersModel.getCurrentlyProcessedServerCredentials()) ServersModel.getProcessedServerCredentials())
PageController.showBusyIndicator(false) PageController.showBusyIndicator(false)
} }
} }
@@ -315,7 +331,7 @@ PageType {
function handler() { function handler() {
serverSelector.text = selectedText serverSelector.text = selectedText
ServersModel.currentlyProcessedIndex = proxyServersModel.mapToSource(currentIndex) ServersModel.processedIndex = proxyServersModel.mapToSource(currentIndex)
} }
} }
} }
@@ -365,7 +381,7 @@ PageType {
target: serverSelector target: serverSelector
function onSeverSelectorIndexChanged() { function onSeverSelectorIndexChanged() {
var defaultContainer = proxyContainersModel.mapFromSource(ServersModel.getDefaultContainer(ServersModel.currentlyProcessedIndex)) var defaultContainer = proxyContainersModel.mapFromSource(ServersModel.getProcessedServerData("defaultContainer"))
protocolSelectorListView.currentIndex = defaultContainer protocolSelectorListView.currentIndex = defaultContainer
protocolSelectorListView.triggerCurrentItem() protocolSelectorListView.triggerCurrentItem()
} }
@@ -388,7 +404,7 @@ PageType {
if (accessTypeSelector.currentIndex === 1) { if (accessTypeSelector.currentIndex === 1) {
PageController.showBusyIndicator(true) PageController.showBusyIndicator(true)
ExportController.updateClientManagementModel(ContainersModel.getCurrentlyProcessedContainerIndex(), ExportController.updateClientManagementModel(ContainersModel.getCurrentlyProcessedContainerIndex(),
ServersModel.getCurrentlyProcessedServerCredentials()) ServersModel.getProcessedServerCredentials())
PageController.showBusyIndicator(false) PageController.showBusyIndicator(false)
} }
} }
@@ -402,6 +418,8 @@ PageType {
root.connectionTypesModel.push(openVpnConnectionFormat) root.connectionTypesModel.push(openVpnConnectionFormat)
} else if (index === ContainerProps.containerFromString("amnezia-wireguard")) { } else if (index === ContainerProps.containerFromString("amnezia-wireguard")) {
root.connectionTypesModel.push(wireGuardConnectionFormat) root.connectionTypesModel.push(wireGuardConnectionFormat)
} else if (index === ContainerProps.containerFromString("amnezia-awg")) {
root.connectionTypesModel.push(awgConnectionFormat)
} else if (index === ContainerProps.containerFromString("amnezia-shadowsocks")) { } else if (index === ContainerProps.containerFromString("amnezia-shadowsocks")) {
root.connectionTypesModel.push(openVpnConnectionFormat) root.connectionTypesModel.push(openVpnConnectionFormat)
root.connectionTypesModel.push(shadowSocksConnectionFormat) root.connectionTypesModel.push(shadowSocksConnectionFormat)
@@ -654,7 +672,7 @@ PageType {
ExportController.renameClient(index, ExportController.renameClient(index,
clientNameEditor.textFieldText, clientNameEditor.textFieldText,
ContainersModel.getCurrentlyProcessedContainerIndex(), ContainersModel.getCurrentlyProcessedContainerIndex(),
ServersModel.getCurrentlyProcessedServerCredentials()) ServersModel.getProcessedServerCredentials())
PageController.showBusyIndicator(false) PageController.showBusyIndicator(false)
clientNameEditDrawer.close() clientNameEditDrawer.close()
} }
+1 -1
View File
@@ -111,7 +111,7 @@ PageType {
function handler() { function handler() {
serverSelector.text = selectedText serverSelector.text = selectedText
ServersModel.currentlyProcessedIndex = proxyServersModel.mapToSource(currentIndex) ServersModel.processedIndex = proxyServersModel.mapToSource(currentIndex)
} }
} }
} }
+5 -4
View File
@@ -44,6 +44,7 @@ PageType {
function onClosePage() { function onClosePage() {
tabBar.isServerInfoShow = tabBarStackView.currentItem.objectName !== PageController.getPagePath(PageEnum.PageSettingsServerInfo) tabBar.isServerInfoShow = tabBarStackView.currentItem.objectName !== PageController.getPagePath(PageEnum.PageSettingsServerInfo)
&& tabBarStackView.currentItem.objectName !== PageController.getPagePath(PageEnum.PageSettingsSplitTunneling)
if (tabBarStackView.depth <= 1) { if (tabBarStackView.depth <= 1) {
return return
@@ -60,7 +61,7 @@ PageType {
tabBarStackView.push(pagePath, { "objectName" : pagePath }, StackView.Immediate) tabBarStackView.push(pagePath, { "objectName" : pagePath }, StackView.Immediate)
} }
tabBar.isServerInfoShow = page === PageEnum.PageSettingsServerInfo || tabBar.isServerInfoShow tabBar.isServerInfoShow = page === PageEnum.PageSettingsServerInfo || PageEnum.PageSettingsSplitTunneling || tabBar.isServerInfoShow
} }
function onGoToStartPage() { function onGoToStartPage() {
@@ -108,7 +109,7 @@ PageType {
function onNoInstalledContainers() { function onNoInstalledContainers() {
PageController.setTriggeredBtConnectButton(true) PageController.setTriggeredBtConnectButton(true)
ServersModel.currentlyProcessedIndex = ServersModel.getDefaultServerIndex() ServersModel.processedIndex = ServersModel.getDefaultServerIndex()
InstallController.setShouldCreateServer(false) InstallController.setShouldCreateServer(false)
PageController.goToPage(PageEnum.PageSetupWizardEasy) PageController.goToPage(PageEnum.PageSetupWizardEasy)
} }
@@ -136,7 +137,7 @@ PageType {
Component.onCompleted: { Component.onCompleted: {
var pagePath = PageController.getPagePath(PageEnum.PageHome) var pagePath = PageController.getPagePath(PageEnum.PageHome)
ServersModel.currentlyProcessedIndex = ServersModel.defaultIndex ServersModel.processedIndex = ServersModel.defaultIndex
tabBarStackView.push(pagePath, { "objectName" : pagePath }) tabBarStackView.push(pagePath, { "objectName" : pagePath })
} }
} }
@@ -180,7 +181,7 @@ PageType {
image: "qrc:/images/controls/home.svg" image: "qrc:/images/controls/home.svg"
onClicked: { onClicked: {
tabBarStackView.goToTabBarPage(PageEnum.PageHome) tabBarStackView.goToTabBarPage(PageEnum.PageHome)
ServersModel.currentlyProcessedIndex = ServersModel.defaultIndex ServersModel.processedIndex = ServersModel.defaultIndex
tabBar.previousIndex = 0 tabBar.previousIndex = 0
} }
} }
+2 -1
View File
@@ -146,7 +146,8 @@ if [ "${MAC_CERT_PW+x}" ]; then
fi fi
echo "Building DMG installer..." echo "Building DMG installer..."
hdiutil create -size 120mb -volname AmneziaVPN -srcfolder $BUILD_DIR/installer/$APP_NAME.app -ov -format UDZO $DMG_FILENAME # Allow Terminal to make changes in Privacy & Security > App Management
hdiutil create -size 256mb -volname AmneziaVPN -srcfolder $BUILD_DIR/installer/$APP_NAME.app -ov -format UDZO $DMG_FILENAME
if [ "${MAC_CERT_PW+x}" ]; then if [ "${MAC_CERT_PW+x}" ]; then
echo "Signing DMG installer..." echo "Signing DMG installer..."