Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 54e69c4fe4 | |||
| f97c84c7f9 | |||
| ae5ac16611 | |||
| 6b6f5802bf | |||
| a14e8ec0aa |
@@ -65,13 +65,6 @@ jobs:
|
|||||||
path: deploy/AppDir
|
path: deploy/AppDir
|
||||||
retention-days: 7
|
retention-days: 7
|
||||||
|
|
||||||
- name: 'Upload translations artifact'
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: AmneziaVPN_translations
|
|
||||||
path: client/translations
|
|
||||||
retention-days: 7
|
|
||||||
|
|
||||||
# ------------------------------------------------------
|
# ------------------------------------------------------
|
||||||
|
|
||||||
Build-Windows:
|
Build-Windows:
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.25.0 FATAL_ERROR)
|
|||||||
|
|
||||||
set(PROJECT AmneziaVPN)
|
set(PROJECT AmneziaVPN)
|
||||||
|
|
||||||
project(${PROJECT} VERSION 4.6.1.0
|
project(${PROJECT} VERSION 4.6.0.3
|
||||||
DESCRIPTION "AmneziaVPN"
|
DESCRIPTION "AmneziaVPN"
|
||||||
HOMEPAGE_URL "https://amnezia.org/"
|
HOMEPAGE_URL "https://amnezia.org/"
|
||||||
)
|
)
|
||||||
@@ -11,7 +11,7 @@ string(TIMESTAMP CURRENT_DATE "%Y-%m-%d")
|
|||||||
set(RELEASE_DATE "${CURRENT_DATE}")
|
set(RELEASE_DATE "${CURRENT_DATE}")
|
||||||
|
|
||||||
set(APP_MAJOR_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH})
|
set(APP_MAJOR_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH})
|
||||||
set(APP_ANDROID_VERSION_CODE 56)
|
set(APP_ANDROID_VERSION_CODE 55)
|
||||||
|
|
||||||
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
||||||
set(MZ_PLATFORM_NAME "linux")
|
set(MZ_PLATFORM_NAME "linux")
|
||||||
|
|||||||
@@ -6,26 +6,6 @@
|
|||||||
|
|
||||||
Amnezia is an open-source VPN client, with a key feature that enables you to deploy your own VPN server on your server.
|
Amnezia is an open-source VPN client, with a key feature that enables you to deploy your own VPN server on your server.
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
<a href="https://github.com/amnezia-vpn/amnezia-client/releases/download/4.6.0.3/AmneziaVPN_4.6.0.3_x64.exe"><img src="https://github.com/amnezia-vpn/amnezia-client/blob/dev/metadata/img-readme/win.png" width="150" style="max-width: 100%;"></a>
|
|
||||||
<a href="https://github.com/amnezia-vpn/amnezia-client/releases/download/4.6.0.3/AmneziaVPN_4.6.0.3.dmg"><img src="https://github.com/amnezia-vpn/amnezia-client/blob/dev/metadata/img-readme/mac.png" width="150" style="max-width: 100%;"></a>
|
|
||||||
<a href="https://github.com/amnezia-vpn/amnezia-client/releases/download/4.6.0.3/AmneziaVPN_Linux_4.6.0.3.tar.zip"><img src="https://github.com/amnezia-vpn/amnezia-client/blob/dev/metadata/img-readme/lin.png" width="150" style="max-width: 100%;"></a>
|
|
||||||
<a href="https://github.com/amnezia-vpn/amnezia-client/releases/tag/4.6.0.3"><img src="https://github.com/amnezia-vpn/amnezia-client/blob/dev/metadata/img-readme/andr.png" width="150" style="max-width: 100%;"></a>
|
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
<a href="https://play.google.com/store/search?q=amnezia+vpn&c=apps"><img src="https://github.com/amnezia-vpn/amnezia-client/blob/dev/metadata/img-readme/play.png" width="150" style="max-width: 100%;"></a>
|
|
||||||
<a href="https://apps.apple.com/us/app/amneziavpn/id1600529900"><img src="https://github.com/amnezia-vpn/amnezia-client/blob/dev/metadata/img-readme/apl.png" width="150" style="max-width: 100%;"></a>
|
|
||||||
|
|
||||||
|
|
||||||
[All releases](https://github.com/amnezia-vpn/amnezia-client/releases)
|
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- Very easy to use - enter your IP address, SSH login, and password, and Amnezia will automatically install VPN docker containers to your server and connect to the VPN.
|
- Very easy to use - enter your IP address, SSH login, and password, and Amnezia will automatically install VPN docker containers to your server and connect to the VPN.
|
||||||
@@ -36,12 +16,12 @@ Amnezia is an open-source VPN client, with a key feature that enables you to dep
|
|||||||
|
|
||||||
## Links
|
## Links
|
||||||
|
|
||||||
- [https://amnezia.org](https://amnezia.org) - project website
|
[https://amnezia.org](https://amnezia.org) - project website
|
||||||
- [https://www.reddit.com/r/AmneziaVPN](https://www.reddit.com/r/AmneziaVPN) - Reddit
|
[https://www.reddit.com/r/AmneziaVPN](https://www.reddit.com/r/AmneziaVPN) - Reddit
|
||||||
- [https://t.me/amnezia_vpn_en](https://t.me/amnezia_vpn_en) - Telegram support channel (English)
|
[https://t.me/amnezia_vpn_en](https://t.me/amnezia_vpn_en) - Telegram support channel (English)
|
||||||
- [https://t.me/amnezia_vpn_ir](https://t.me/amnezia_vpn_ir) - Telegram support channel (Farsi)
|
[https://t.me/amnezia_vpn_ir](https://t.me/amnezia_vpn_ir) - Telegram support channel (Farsi)
|
||||||
- [https://t.me/amnezia_vpn_mm](https://t.me/amnezia_vpn_mm) - Telegram support channel (Myanmar)
|
[https://t.me/amnezia_vpn_mm](https://t.me/amnezia_vpn_mm) - Telegram support channel (Myanmar)
|
||||||
- [https://t.me/amnezia_vpn](https://t.me/amnezia_vpn) - Telegram support channel (Russian)
|
[https://t.me/amnezia_vpn](https://t.me/amnezia_vpn) - Telegram support channel (Russian)
|
||||||
|
|
||||||
## Tech
|
## Tech
|
||||||
|
|
||||||
@@ -66,19 +46,6 @@ git submodule update --init --recursive
|
|||||||
|
|
||||||
Want to contribute? Welcome!
|
Want to contribute? Welcome!
|
||||||
|
|
||||||
### Help with translations
|
|
||||||
|
|
||||||
Download the most actual translation files.
|
|
||||||
|
|
||||||
Go to ["Actions" tab](https://github.com/amnezia-vpn/amnezia-client/actions?query=is%3Asuccess+branch%3Adev), click on the first line.
|
|
||||||
Then scroll down to the "Artifacts" section and download "AmneziaVPN_translations".
|
|
||||||
|
|
||||||
Unzip this file.
|
|
||||||
Each *.ts file contains strings for one corresponding language.
|
|
||||||
|
|
||||||
Translate or correct some strings in one or multiple *.ts files and commit them back to this repository into the ``client/translations`` folder.
|
|
||||||
You can do it via a web-interface or any other method you're familiar with.
|
|
||||||
|
|
||||||
### Building sources and deployment
|
### Building sources and deployment
|
||||||
|
|
||||||
Check deploy folder for build scripts.
|
Check deploy folder for build scripts.
|
||||||
@@ -154,11 +121,9 @@ The Android app has the following requirements:
|
|||||||
* Android platform SDK 33
|
* Android platform SDK 33
|
||||||
* CMake 3.25.0
|
* CMake 3.25.0
|
||||||
|
|
||||||
After you have installed QT, QT Creator, and Android Studio, you need to configure QT Creator correctly.
|
After you have installed QT, QT Creator, and Android Studio, you need to configure QT Creator correctly. Click in the top menu bar on `QT Creator` -> `Preferences` -> `Devices` and select the tab `Android`.
|
||||||
|
* set path to JDK 11
|
||||||
- Click in the top menu bar on `QT Creator` -> `Preferences` -> `Devices` and select the tab `Android`.
|
* set path to Android SDK ($ANDROID_HOME)
|
||||||
- Set path to JDK 11
|
|
||||||
- Set path to Android SDK (`$ANDROID_HOME`)
|
|
||||||
|
|
||||||
In case you get errors regarding missing SDK or 'SDK manager not running', you cannot fix them by correcting the paths. If you have some spare GBs on your disk, you can let QT Creator install all requirements by choosing an empty folder for `Android SDK location` and clicking on `Set Up SDK`. Be aware: This will install a second Android SDK and NDK on your machine!
|
In case you get errors regarding missing SDK or 'SDK manager not running', you cannot fix them by correcting the paths. If you have some spare GBs on your disk, you can let QT Creator install all requirements by choosing an empty folder for `Android SDK location` and clicking on `Set Up SDK`. Be aware: This will install a second Android SDK and NDK on your machine!
|
||||||
Double-check that the right CMake version is configured: Click on `QT Creator` -> `Preferences` and click on the side menu on `Kits`. Under the center content view's `Kits` tab, you'll find an entry for `CMake Tool`. If the default selected CMake version is lower than 3.25.0, install on your system CMake >= 3.25.0 and choose `System CMake at <path>` from the drop-down list. If this entry is missing, you either have not installed CMake yet or QT Creator hasn't found the path to it. In that case, click in the preferences window on the side menu item `CMake`, then on the tab `Tools` in the center content view, and finally on the button `Add` to set the path to your installed CMake.
|
Double-check that the right CMake version is configured: Click on `QT Creator` -> `Preferences` and click on the side menu on `Kits`. Under the center content view's `Kits` tab, you'll find an entry for `CMake Tool`. If the default selected CMake version is lower than 3.25.0, install on your system CMake >= 3.25.0 and choose `System CMake at <path>` from the drop-down list. If this entry is missing, you either have not installed CMake yet or QT Creator hasn't found the path to it. In that case, click in the preferences window on the side menu item `CMake`, then on the tab `Tools` in the center content view, and finally on the button `Add` to set the path to your installed CMake.
|
||||||
@@ -180,9 +145,8 @@ GPL v3.0
|
|||||||
## Donate
|
## Donate
|
||||||
|
|
||||||
Patreon: [https://www.patreon.com/amneziavpn](https://www.patreon.com/amneziavpn)
|
Patreon: [https://www.patreon.com/amneziavpn](https://www.patreon.com/amneziavpn)
|
||||||
|
USDT BEP20: 0x6abD576765a826f87D1D95183438f9408C901bE4
|
||||||
USDT BEP20: 0x6abD576765a826f87D1D95183438f9408C901bE4 <br>
|
USDT TRC20: TELAitazF1MZGmiNjTcnxDjEiH5oe7LC9d
|
||||||
USDT TRC20: TELAitazF1MZGmiNjTcnxDjEiH5oe7LC9d <br>
|
|
||||||
XMR: 48spms39jt1L2L5vyw2RQW6CXD6odUd4jFu19GZcDyKKQV9U88wsJVjSbL4CfRys37jVMdoaWVPSvezCQPhHXUW5UKLqUp3
|
XMR: 48spms39jt1L2L5vyw2RQW6CXD6odUd4jFu19GZcDyKKQV9U88wsJVjSbL4CfRys37jVMdoaWVPSvezCQPhHXUW5UKLqUp3
|
||||||
|
|
||||||
## Acknowledgments
|
## Acknowledgments
|
||||||
|
|||||||
@@ -161,15 +161,13 @@ void AmneziaApplication::init()
|
|||||||
m_engine->load(url);
|
m_engine->load(url);
|
||||||
m_systemController->setQmlRoot(m_engine->rootObjects().value(0));
|
m_systemController->setQmlRoot(m_engine->rootObjects().value(0));
|
||||||
|
|
||||||
bool enabled = m_settings->isSaveLogs();
|
|
||||||
#ifndef Q_OS_ANDROID
|
#ifndef Q_OS_ANDROID
|
||||||
if (enabled) {
|
if (m_settings->isSaveLogs()) {
|
||||||
if (!Logger::init()) {
|
if (!Logger::init()) {
|
||||||
qWarning() << "Initialization of debug subsystem failed";
|
qWarning() << "Initialization of debug subsystem failed";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
Logger::setServiceLogsEnabled(enabled);
|
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
if (m_parser.isSet("a"))
|
if (m_parser.isSet("a"))
|
||||||
|
|||||||
@@ -11,9 +11,6 @@
|
|||||||
<uses-feature android:name="android.hardware.camera" android:required="false" />
|
<uses-feature android:name="android.hardware.camera" android:required="false" />
|
||||||
<uses-feature android:name="android.hardware.camera.any" android:required="false" />
|
<uses-feature android:name="android.hardware.camera.any" android:required="false" />
|
||||||
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
|
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
|
||||||
<!-- for TV -->
|
|
||||||
<uses-feature android:name="android.software.leanback" android:required="false" />
|
|
||||||
<uses-feature android:name="android.hardware.touchscreen" android:required="false" />
|
|
||||||
|
|
||||||
<!-- The following comment will be replaced upon deployment with default features based on the dependencies
|
<!-- The following comment will be replaced upon deployment with default features based on the dependencies
|
||||||
of the application. Remove the comment if you do not require these default features. -->
|
of the application. Remove the comment if you do not require these default features. -->
|
||||||
@@ -34,11 +31,9 @@
|
|||||||
android:label="-- %%INSERT_APP_NAME%% --"
|
android:label="-- %%INSERT_APP_NAME%% --"
|
||||||
android:icon="@mipmap/icon"
|
android:icon="@mipmap/icon"
|
||||||
android:roundIcon="@mipmap/icon_round"
|
android:roundIcon="@mipmap/icon_round"
|
||||||
android:banner="@mipmap/ic_banner"
|
|
||||||
android:theme="@style/NoActionBar"
|
android:theme="@style/NoActionBar"
|
||||||
android:fullBackupContent="@xml/backup_content"
|
android:fullBackupContent="@xml/backup_content"
|
||||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||||
android:hasFragileUserData="false"
|
|
||||||
tools:targetApi="s">
|
tools:targetApi="s">
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
@@ -52,7 +47,6 @@
|
|||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
|
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<background android:drawable="@color/ic_banner_background"/>
|
|
||||||
<foreground android:drawable="@mipmap/ic_banner_foreground"/>
|
|
||||||
</adaptive-icon>
|
|
||||||
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 12 KiB |
@@ -1,4 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<resources>
|
|
||||||
<color name="ic_banner_background">#1E1E1F</color>
|
|
||||||
</resources>
|
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
package org.amnezia.vpn
|
package org.amnezia.vpn
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.app.AlertDialog
|
import android.app.AlertDialog
|
||||||
import android.app.NotificationManager
|
import android.app.NotificationManager
|
||||||
import android.content.BroadcastReceiver
|
import android.content.BroadcastReceiver
|
||||||
@@ -231,10 +230,7 @@ class AmneziaActivity : QtActivity() {
|
|||||||
override fun onStop() {
|
override fun onStop() {
|
||||||
Log.d(TAG, "Stop Amnezia activity")
|
Log.d(TAG, "Stop Amnezia activity")
|
||||||
doUnbindService()
|
doUnbindService()
|
||||||
mainScope.launch {
|
QtAndroidController.onServiceDisconnected()
|
||||||
qtInitialized.await()
|
|
||||||
QtAndroidController.onServiceDisconnected()
|
|
||||||
}
|
|
||||||
super.onStop()
|
super.onStop()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -546,7 +542,7 @@ class AmneziaActivity : QtActivity() {
|
|||||||
}
|
}
|
||||||
}.also {
|
}.also {
|
||||||
startActivityForResult(it, OPEN_FILE_ACTION_CODE, ActivityResultHandler(
|
startActivityForResult(it, OPEN_FILE_ACTION_CODE, ActivityResultHandler(
|
||||||
onAny = {
|
onSuccess = {
|
||||||
val uri = it?.data?.toString() ?: ""
|
val uri = it?.data?.toString() ?: ""
|
||||||
Log.d(TAG, "Open file: $uri")
|
Log.d(TAG, "Open file: $uri")
|
||||||
mainScope.launch {
|
mainScope.launch {
|
||||||
@@ -560,12 +556,8 @@ class AmneziaActivity : QtActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
@SuppressLint("UnsupportedChromeOsCameraSystemFeature")
|
|
||||||
fun isCameraPresent(): Boolean = applicationContext.packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA)
|
fun isCameraPresent(): Boolean = applicationContext.packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA)
|
||||||
|
|
||||||
@Suppress("unused")
|
|
||||||
fun isOnTv(): Boolean = applicationContext.packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK)
|
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
fun startQrCodeReader() {
|
fun startQrCodeReader() {
|
||||||
Log.v(TAG, "Start camera")
|
Log.v(TAG, "Start camera")
|
||||||
|
|||||||
@@ -88,24 +88,16 @@ class NetworkState(
|
|||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
connectivityManager.registerBestMatchingNetworkCallback(networkRequest, networkCallback, handler)
|
connectivityManager.registerBestMatchingNetworkCallback(networkRequest, networkCallback, handler)
|
||||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
val numberAttempts = 3
|
try {
|
||||||
var attemptCount = 0
|
connectivityManager.requestNetwork(networkRequest, networkCallback, handler)
|
||||||
while(true) {
|
} catch (e: SecurityException) {
|
||||||
try {
|
Log.e(TAG, "Failed to bind network listener: $e")
|
||||||
|
// Android 11 bug: https://issuetracker.google.com/issues/175055271
|
||||||
|
if (e.message?.startsWith("Package android does not belong to") == true) {
|
||||||
|
delay(1000)
|
||||||
connectivityManager.requestNetwork(networkRequest, networkCallback, handler)
|
connectivityManager.requestNetwork(networkRequest, networkCallback, handler)
|
||||||
break
|
} else {
|
||||||
} catch (e: SecurityException) {
|
throw e
|
||||||
Log.e(TAG, "Failed to bind network listener: $e")
|
|
||||||
// Android 11 bug: https://issuetracker.google.com/issues/175055271
|
|
||||||
if (e.message?.startsWith("Package android does not belong to") == true) {
|
|
||||||
if (++attemptCount > numberAttempts) {
|
|
||||||
throw e
|
|
||||||
}
|
|
||||||
delay(1000)
|
|
||||||
continue
|
|
||||||
} else {
|
|
||||||
throw e
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -119,21 +119,18 @@ QString OpenVpnConfigurator::processConfigWithLocalSettings(const QPair<QString,
|
|||||||
|
|
||||||
if (!m_settings->isSitesSplitTunnelingEnabled()) {
|
if (!m_settings->isSitesSplitTunnelingEnabled()) {
|
||||||
config.append("\nredirect-gateway def1 ipv6 bypass-dhcp\n");
|
config.append("\nredirect-gateway def1 ipv6 bypass-dhcp\n");
|
||||||
|
|
||||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
|
||||||
// Prevent ipv6 leak
|
// Prevent ipv6 leak
|
||||||
config.append("ifconfig-ipv6 fd15:53b6:dead::2/64 fd15:53b6:dead::1\n");
|
config.append("ifconfig-ipv6 fd15:53b6:dead::2/64 fd15:53b6:dead::1\n");
|
||||||
#endif
|
|
||||||
config.append("block-ipv6\n");
|
config.append("block-ipv6\n");
|
||||||
} else if (m_settings->routeMode() == Settings::VpnOnlyForwardSites) {
|
} else if (m_settings->routeMode() == Settings::VpnOnlyForwardSites) {
|
||||||
|
|
||||||
// no redirect-gateway
|
// no redirect-gateway
|
||||||
} else if (m_settings->routeMode() == Settings::VpnAllExceptSites) {
|
} else if (m_settings->routeMode() == Settings::VpnAllExceptSites) {
|
||||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
#ifndef Q_OS_ANDROID
|
||||||
config.append("\nredirect-gateway ipv6 !ipv4 bypass-dhcp\n");
|
config.append("\nredirect-gateway ipv6 !ipv4 bypass-dhcp\n");
|
||||||
|
#endif
|
||||||
// Prevent ipv6 leak
|
// Prevent ipv6 leak
|
||||||
config.append("ifconfig-ipv6 fd15:53b6:dead::2/64 fd15:53b6:dead::1\n");
|
config.append("ifconfig-ipv6 fd15:53b6:dead::2/64 fd15:53b6:dead::1\n");
|
||||||
#endif
|
|
||||||
config.append("block-ipv6\n");
|
config.append("block-ipv6\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ QMap<DockerContainer, QString> ContainerProps::containerHumanNames()
|
|||||||
{ DockerContainer::Awg, "AmneziaWG" },
|
{ DockerContainer::Awg, "AmneziaWG" },
|
||||||
{ DockerContainer::Xray, "XRay" },
|
{ DockerContainer::Xray, "XRay" },
|
||||||
{ DockerContainer::Ipsec, QObject::tr("IPsec") },
|
{ DockerContainer::Ipsec, QObject::tr("IPsec") },
|
||||||
{ DockerContainer::SSXray, "Shadowsocks"},
|
{ DockerContainer::SSXray, "ShadowSocks"},
|
||||||
|
|
||||||
{ DockerContainer::TorWebSite, QObject::tr("Website in Tor network") },
|
{ DockerContainer::TorWebSite, QObject::tr("Website in Tor network") },
|
||||||
{ DockerContainer::Dns, QObject::tr("AmneziaDNS") },
|
{ DockerContainer::Dns, QObject::tr("AmneziaDNS") },
|
||||||
@@ -286,8 +286,8 @@ bool ContainerProps::isSupportedByCurrentPlatform(DockerContainer c)
|
|||||||
case DockerContainer::OpenVpn: return true;
|
case DockerContainer::OpenVpn: return true;
|
||||||
case DockerContainer::Awg: return true;
|
case DockerContainer::Awg: return true;
|
||||||
case DockerContainer::Xray: return true;
|
case DockerContainer::Xray: return true;
|
||||||
case DockerContainer::Cloak: return true;
|
case DockerContainer::Cloak:
|
||||||
case DockerContainer::SSXray: return true;
|
return true;
|
||||||
// case DockerContainer::ShadowSocks: return true;
|
// case DockerContainer::ShadowSocks: return true;
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -569,7 +569,6 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential
|
|||||||
|
|
||||||
// Xray vars
|
// Xray vars
|
||||||
vars.append({ { "$XRAY_SITE_NAME", xrayConfig.value(config_key::site).toString(protocols::xray::defaultSite) } });
|
vars.append({ { "$XRAY_SITE_NAME", xrayConfig.value(config_key::site).toString(protocols::xray::defaultSite) } });
|
||||||
vars.append({ { "$XRAY_SERVER_PORT", xrayConfig.value(config_key::port).toString(protocols::xray::defaultPort) } });
|
|
||||||
|
|
||||||
// Wireguard vars
|
// Wireguard vars
|
||||||
vars.append({ { "$WIREGUARD_SUBNET_IP",
|
vars.append({ { "$WIREGUARD_SUBNET_IP",
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ namespace amnezia
|
|||||||
|
|
||||||
// import and install errors
|
// import and install errors
|
||||||
ImportInvalidConfigError = 900,
|
ImportInvalidConfigError = 900,
|
||||||
|
ImportQrDecodingError = 901,
|
||||||
|
|
||||||
// Android errors
|
// Android errors
|
||||||
AndroidError = 1000,
|
AndroidError = 1000,
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ QString errorString(ErrorCode code) {
|
|||||||
case (ErrorCode::AddressPoolError): errorMessage = QObject::tr("VPN pool error: no available addresses"); break;
|
case (ErrorCode::AddressPoolError): errorMessage = QObject::tr("VPN pool error: no available addresses"); break;
|
||||||
|
|
||||||
case (ErrorCode::ImportInvalidConfigError): errorMessage = QObject::tr("The config does not contain any containers and credentials for connecting to the server"); break;
|
case (ErrorCode::ImportInvalidConfigError): errorMessage = QObject::tr("The config does not contain any containers and credentials for connecting to the server"); break;
|
||||||
|
case (ErrorCode::ImportQrDecodingError): errorMessage = QObject::tr("Failed to decode qr-code"); break;
|
||||||
|
|
||||||
// Android errors
|
// Android errors
|
||||||
case (ErrorCode::AndroidError): errorMessage = QObject::tr("VPN connection error"); break;
|
case (ErrorCode::AndroidError): errorMessage = QObject::tr("VPN connection error"); break;
|
||||||
|
|||||||
@@ -91,7 +91,6 @@ target_sources(networkextension PRIVATE
|
|||||||
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider+OpenVPN.swift
|
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider+OpenVPN.swift
|
||||||
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider+Xray.swift
|
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider+Xray.swift
|
||||||
${CLIENT_ROOT_DIR}/platforms/ios/WGConfig.swift
|
${CLIENT_ROOT_DIR}/platforms/ios/WGConfig.swift
|
||||||
${CLIENT_ROOT_DIR}/platforms/ios/XrayConfig.swift
|
|
||||||
${CLIENT_ROOT_DIR}/platforms/ios/iosglue.mm
|
${CLIENT_ROOT_DIR}/platforms/ios/iosglue.mm
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -33,10 +33,6 @@ void debugMessageHandler(QtMsgType type, const QMessageLogContext& context, cons
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Skip annoying messages from Qt
|
// Skip annoying messages from Qt
|
||||||
if (msg.contains("OpenType support missing for")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (msg.startsWith("Unknown property") || msg.startsWith("Could not create pixmap") || msg.startsWith("Populating font") || msg.startsWith("stale focus object")) {
|
if (msg.startsWith("Unknown property") || msg.startsWith("Could not create pixmap") || msg.startsWith("Populating font") || msg.startsWith("stale focus object")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -99,29 +95,6 @@ void Logger::deInit()
|
|||||||
m_file.close();
|
m_file.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Logger::setServiceLogsEnabled(bool enabled) {
|
|
||||||
#ifdef AMNEZIA_DESKTOP
|
|
||||||
IpcClient *m_IpcClient = new IpcClient;
|
|
||||||
|
|
||||||
if (!m_IpcClient->isSocketConnected()) {
|
|
||||||
if (!IpcClient::init(m_IpcClient)) {
|
|
||||||
qWarning() << "Error occurred when init IPC client";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_IpcClient->Interface()) {
|
|
||||||
m_IpcClient->Interface()->setLogsEnabled(enabled);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
qWarning() << "Error occurred setting up service logs";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString Logger::userLogsDir()
|
QString Logger::userLogsDir()
|
||||||
{
|
{
|
||||||
return QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/log";
|
return QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/log";
|
||||||
@@ -164,9 +137,7 @@ bool Logger::openLogsFolder()
|
|||||||
bool Logger::openServiceLogsFolder()
|
bool Logger::openServiceLogsFolder()
|
||||||
{
|
{
|
||||||
QString path = Utils::systemLogPath();
|
QString path = Utils::systemLogPath();
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
path = "file:///" + path;
|
path = "file:///" + path;
|
||||||
#endif
|
|
||||||
QDesktopServices::openUrl(QUrl::fromLocalFile(path));
|
QDesktopServices::openUrl(QUrl::fromLocalFile(path));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -209,7 +180,8 @@ void Logger::clearServiceLogs()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_IpcClient->Interface()) {
|
if (m_IpcClient->Interface()) {
|
||||||
m_IpcClient->Interface()->clearLogs();
|
m_IpcClient->Interface()->setLogsEnabled(false);
|
||||||
|
m_IpcClient->Interface()->cleanUp();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
qWarning() << "Error occurred cleaning up service logs";
|
qWarning() << "Error occurred cleaning up service logs";
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ public:
|
|||||||
|
|
||||||
static bool init();
|
static bool init();
|
||||||
static void deInit();
|
static void deInit();
|
||||||
static bool setServiceLogsEnabled(bool enabled);
|
|
||||||
static bool openLogsFolder();
|
static bool openLogsFolder();
|
||||||
static bool openServiceLogsFolder();
|
static bool openServiceLogsFolder();
|
||||||
static QString appLogFileNamePath();
|
static QString appLogFileNamePath();
|
||||||
|
|||||||
@@ -179,11 +179,6 @@ bool AndroidController::isCameraPresent()
|
|||||||
return callActivityMethod<jboolean>("isCameraPresent", "()Z");
|
return callActivityMethod<jboolean>("isCameraPresent", "()Z");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AndroidController::isOnTv()
|
|
||||||
{
|
|
||||||
return callActivityMethod<jboolean>("isOnTv", "()Z");
|
|
||||||
}
|
|
||||||
|
|
||||||
void AndroidController::startQrReaderActivity()
|
void AndroidController::startQrReaderActivity()
|
||||||
{
|
{
|
||||||
callActivityMethod("startQrCodeReader", "()V");
|
callActivityMethod("startQrCodeReader", "()V");
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ public:
|
|||||||
void saveFile(const QString &fileName, const QString &data);
|
void saveFile(const QString &fileName, const QString &data);
|
||||||
QString openFile(const QString &filter);
|
QString openFile(const QString &filter);
|
||||||
bool isCameraPresent();
|
bool isCameraPresent();
|
||||||
bool isOnTv();
|
|
||||||
void startQrReaderActivity();
|
void startQrReaderActivity();
|
||||||
void setSaveLogs(bool enabled);
|
void setSaveLogs(bool enabled);
|
||||||
void exportLogsFile(const QString &fileName);
|
void exportLogsFile(const QString &fileName);
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import WireGuardKitGo
|
|||||||
|
|
||||||
enum XrayErrors: Error {
|
enum XrayErrors: Error {
|
||||||
case noXrayConfig
|
case noXrayConfig
|
||||||
case xrayConfigIsWrong
|
|
||||||
case cantSaveXrayConfig
|
case cantSaveXrayConfig
|
||||||
case cantParseListenAndPort
|
case cantParseListenAndPort
|
||||||
case cantSaveHevSocksConfig
|
case cantSaveHevSocksConfig
|
||||||
@@ -27,14 +26,14 @@ extension PacketTunnelProvider {
|
|||||||
// Xray configuration
|
// Xray configuration
|
||||||
guard let protocolConfiguration = self.protocolConfiguration as? NETunnelProviderProtocol,
|
guard let protocolConfiguration = self.protocolConfiguration as? NETunnelProviderProtocol,
|
||||||
let providerConfiguration = protocolConfiguration.providerConfiguration,
|
let providerConfiguration = protocolConfiguration.providerConfiguration,
|
||||||
let configData = providerConfiguration[Constants.xrayConfigKey] as? Data else {
|
let xrayConfigData = providerConfiguration[Constants.xrayConfigKey] as? Data else {
|
||||||
xrayLog(.error, message: "Can't get xray configuration")
|
xrayLog(.error, message: "Can't get xray configuration")
|
||||||
completionHandler(XrayErrors.noXrayConfig)
|
completionHandler(XrayErrors.noXrayConfig)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tunnel settings
|
// Tunnel settings
|
||||||
let ipv6Enabled = false
|
let ipv6Enabled = true
|
||||||
let hideVPNIcon = false
|
let hideVPNIcon = false
|
||||||
|
|
||||||
let settings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "254.1.1.1")
|
let settings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "254.1.1.1")
|
||||||
@@ -58,29 +57,12 @@ extension PacketTunnelProvider {
|
|||||||
return settings
|
return settings
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
let dns = ["8.8.4.4","1.1.1.1"]
|
||||||
|
settings.dnsSettings = NEDNSSettings(servers: dns)
|
||||||
|
|
||||||
do {
|
do {
|
||||||
let xrayConfig = try JSONDecoder().decode(XrayConfig.self,
|
let port = 10808
|
||||||
from: configData)
|
let address = "::1"
|
||||||
|
|
||||||
var dnsArray = [String]()
|
|
||||||
if let dns1 = xrayConfig.dns1 {
|
|
||||||
dnsArray.append(dns1)
|
|
||||||
}
|
|
||||||
if let dns2 = xrayConfig.dns2 {
|
|
||||||
dnsArray.append(dns2)
|
|
||||||
}
|
|
||||||
|
|
||||||
settings.dnsSettings = !dnsArray.isEmpty
|
|
||||||
? NEDNSSettings(servers: dnsArray)
|
|
||||||
: NEDNSSettings(servers: ["1.1.1.1"])
|
|
||||||
|
|
||||||
let xrayConfigData = xrayConfig.config.data(using: .utf8)
|
|
||||||
|
|
||||||
guard let xrayConfigData else {
|
|
||||||
xrayLog(.error, message: "Can't encode config to data")
|
|
||||||
completionHandler(XrayErrors.xrayConfigIsWrong)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let jsonDict = try JSONSerialization.jsonObject(with: xrayConfigData,
|
let jsonDict = try JSONSerialization.jsonObject(with: xrayConfigData,
|
||||||
options: []) as? [String: Any]
|
options: []) as? [String: Any]
|
||||||
@@ -91,9 +73,6 @@ extension PacketTunnelProvider {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let port = 10808
|
|
||||||
let address = "::1"
|
|
||||||
|
|
||||||
if var inboundsArray = jsonDict["inbounds"] as? [[String: Any]], !inboundsArray.isEmpty {
|
if var inboundsArray = jsonDict["inbounds"] as? [[String: Any]], !inboundsArray.isEmpty {
|
||||||
inboundsArray[0]["port"] = port
|
inboundsArray[0]["port"] = port
|
||||||
inboundsArray[0]["listen"] = address
|
inboundsArray[0]["listen"] = address
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
import Foundation
|
|
||||||
|
|
||||||
struct XrayConfig: Decodable {
|
|
||||||
let dns1: String?
|
|
||||||
let dns2: String?
|
|
||||||
let config: String
|
|
||||||
}
|
|
||||||
@@ -73,7 +73,6 @@ private:
|
|||||||
bool setupWireGuard();
|
bool setupWireGuard();
|
||||||
bool setupAwg();
|
bool setupAwg();
|
||||||
bool setupXray();
|
bool setupXray();
|
||||||
bool setupSSXray();
|
|
||||||
|
|
||||||
bool startOpenVPN(const QString &config);
|
bool startOpenVPN(const QString &config);
|
||||||
bool startWireGuard(const QString &jsonConfig);
|
bool startWireGuard(const QString &jsonConfig);
|
||||||
|
|||||||
@@ -219,9 +219,6 @@ bool IosController::connectVpn(amnezia::Proto proto, const QJsonObject& configur
|
|||||||
if (proto == amnezia::Proto::Xray) {
|
if (proto == amnezia::Proto::Xray) {
|
||||||
return setupXray();
|
return setupXray();
|
||||||
}
|
}
|
||||||
if (proto == amnezia::Proto::SSXray) {
|
|
||||||
return setupSSXray();
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -511,36 +508,9 @@ bool IosController::setupXray()
|
|||||||
{
|
{
|
||||||
QJsonObject config = m_rawConfig[ProtocolProps::key_proto_config_data(amnezia::Proto::Xray)].toObject();
|
QJsonObject config = m_rawConfig[ProtocolProps::key_proto_config_data(amnezia::Proto::Xray)].toObject();
|
||||||
QJsonDocument xrayConfigDoc(config);
|
QJsonDocument xrayConfigDoc(config);
|
||||||
|
|
||||||
QString xrayConfigStr(xrayConfigDoc.toJson(QJsonDocument::Compact));
|
QString xrayConfigStr(xrayConfigDoc.toJson(QJsonDocument::Compact));
|
||||||
|
|
||||||
QJsonObject finalConfig;
|
return startXray(xrayConfigStr);
|
||||||
finalConfig.insert(config_key::dns1, m_rawConfig[config_key::dns1].toString());
|
|
||||||
finalConfig.insert(config_key::dns2, m_rawConfig[config_key::dns2].toString());
|
|
||||||
finalConfig.insert(config_key::config, xrayConfigStr);
|
|
||||||
|
|
||||||
QJsonDocument finalConfigDoc(finalConfig);
|
|
||||||
QString finalConfigStr(finalConfigDoc.toJson(QJsonDocument::Compact));
|
|
||||||
|
|
||||||
return startXray(finalConfigStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IosController::setupSSXray()
|
|
||||||
{
|
|
||||||
QJsonObject config = m_rawConfig[ProtocolProps::key_proto_config_data(amnezia::Proto::SSXray)].toObject();
|
|
||||||
QJsonDocument ssXrayConfigDoc(config);
|
|
||||||
|
|
||||||
QString ssXrayConfigStr(ssXrayConfigDoc.toJson(QJsonDocument::Compact));
|
|
||||||
|
|
||||||
QJsonObject finalConfig;
|
|
||||||
finalConfig.insert(config_key::dns1, m_rawConfig[config_key::dns1]);
|
|
||||||
finalConfig.insert(config_key::dns2, m_rawConfig[config_key::dns2]);
|
|
||||||
finalConfig.insert(config_key::config, ssXrayConfigStr);
|
|
||||||
|
|
||||||
QJsonDocument finalConfigDoc(finalConfig);
|
|
||||||
QString finalConfigStr(finalConfigDoc.toJson(QJsonDocument::Compact));
|
|
||||||
|
|
||||||
return startXray(finalConfigStr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IosController::setupAwg()
|
bool IosController::setupAwg()
|
||||||
|
|||||||
@@ -65,14 +65,14 @@ QString ProtocolProps::transportProtoToString(TransportProto proto, Proto p)
|
|||||||
QMap<amnezia::Proto, QString> ProtocolProps::protocolHumanNames()
|
QMap<amnezia::Proto, QString> ProtocolProps::protocolHumanNames()
|
||||||
{
|
{
|
||||||
return { { Proto::OpenVpn, "OpenVPN" },
|
return { { Proto::OpenVpn, "OpenVPN" },
|
||||||
{ Proto::ShadowSocks, "Shadowsocks" },
|
{ Proto::ShadowSocks, "ShadowSocks" },
|
||||||
{ Proto::Cloak, "Cloak" },
|
{ Proto::Cloak, "Cloak" },
|
||||||
{ Proto::WireGuard, "WireGuard" },
|
{ Proto::WireGuard, "WireGuard" },
|
||||||
{ Proto::Awg, "AmneziaWG" },
|
{ Proto::Awg, "AmneziaWG" },
|
||||||
{ Proto::Ikev2, "IKEv2" },
|
{ Proto::Ikev2, "IKEv2" },
|
||||||
{ Proto::L2tp, "L2TP" },
|
{ Proto::L2tp, "L2TP" },
|
||||||
{ Proto::Xray, "XRay" },
|
{ Proto::Xray, "XRay" },
|
||||||
{ Proto::SSXray, "Shadowsocks"},
|
{ Proto::SSXray, "ShadowSocks"},
|
||||||
|
|
||||||
|
|
||||||
{ Proto::TorWebSite, "Website in Tor network" },
|
{ Proto::TorWebSite, "Website in Tor network" },
|
||||||
@@ -159,7 +159,6 @@ bool ProtocolProps::defaultPortChangeable(Proto p)
|
|||||||
case Proto::Dns: return false;
|
case Proto::Dns: return false;
|
||||||
case Proto::Sftp: return true;
|
case Proto::Sftp: return true;
|
||||||
case Proto::Socks5Proxy: return true;
|
case Proto::Socks5Proxy: return true;
|
||||||
case Proto::Xray: return true;
|
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,16 @@
|
|||||||
<file>images/tray/default.png</file>
|
<file>images/tray/default.png</file>
|
||||||
<file>images/tray/error.png</file>
|
<file>images/tray/error.png</file>
|
||||||
<file>images/arrow_left.png</file>
|
<file>images/arrow_left.png</file>
|
||||||
|
<file>fonts/Lato-Black.ttf</file>
|
||||||
|
<file>fonts/Lato-BlackItalic.ttf</file>
|
||||||
|
<file>fonts/Lato-Bold.ttf</file>
|
||||||
|
<file>fonts/Lato-BoldItalic.ttf</file>
|
||||||
|
<file>fonts/Lato-Italic.ttf</file>
|
||||||
|
<file>fonts/Lato-Light.ttf</file>
|
||||||
|
<file>fonts/Lato-LightItalic.ttf</file>
|
||||||
|
<file>fonts/Lato-Regular.ttf</file>
|
||||||
|
<file>fonts/Lato-Thin.ttf</file>
|
||||||
|
<file>fonts/Lato-ThinItalic.ttf</file>
|
||||||
<file>images/AmneziaVPN.png</file>
|
<file>images/AmneziaVPN.png</file>
|
||||||
<file>images/share.png</file>
|
<file>images/share.png</file>
|
||||||
<file>server_scripts/remove_container.sh</file>
|
<file>server_scripts/remove_container.sh</file>
|
||||||
@@ -85,6 +95,7 @@
|
|||||||
<file>server_scripts/check_user_in_sudo.sh</file>
|
<file>server_scripts/check_user_in_sudo.sh</file>
|
||||||
<file>ui/qml/Controls2/BasicButtonType.qml</file>
|
<file>ui/qml/Controls2/BasicButtonType.qml</file>
|
||||||
<file>ui/qml/Controls2/TextFieldWithHeaderType.qml</file>
|
<file>ui/qml/Controls2/TextFieldWithHeaderType.qml</file>
|
||||||
|
<file>fonts/pt-root-ui_vf.ttf</file>
|
||||||
<file>ui/qml/Controls2/LabelWithButtonType.qml</file>
|
<file>ui/qml/Controls2/LabelWithButtonType.qml</file>
|
||||||
<file>images/controls/arrow-right.svg</file>
|
<file>images/controls/arrow-right.svg</file>
|
||||||
<file>images/controls/chevron-right.svg</file>
|
<file>images/controls/chevron-right.svg</file>
|
||||||
@@ -228,7 +239,6 @@
|
|||||||
<file>images/controls/alert-circle.svg</file>
|
<file>images/controls/alert-circle.svg</file>
|
||||||
<file>images/controls/file-check-2.svg</file>
|
<file>images/controls/file-check-2.svg</file>
|
||||||
<file>ui/qml/Controls2/WarningType.qml</file>
|
<file>ui/qml/Controls2/WarningType.qml</file>
|
||||||
<file>fonts/pt-root-ui_vf.ttf</file>
|
|
||||||
<file>ui/qml/Modules/Style/qmldir</file>
|
<file>ui/qml/Modules/Style/qmldir</file>
|
||||||
<file>ui/qml/Modules/Style/AmneziaStyle.qml</file>
|
<file>ui/qml/Modules/Style/AmneziaStyle.qml</file>
|
||||||
<file>ui/qml/Pages2/PageServiceSocksProxySettings.qml</file>
|
<file>ui/qml/Pages2/PageServiceSocksProxySettings.qml</file>
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ cat > /opt/amnezia/xray/server.json <<EOF
|
|||||||
},
|
},
|
||||||
"inbounds": [
|
"inbounds": [
|
||||||
{
|
{
|
||||||
"port": "$XRAY_SERVER_PORT",
|
"port": 443,
|
||||||
"protocol": "vless",
|
"protocol": "vless",
|
||||||
"settings": {
|
"settings": {
|
||||||
"clients": [
|
"clients": [
|
||||||
@@ -44,7 +44,7 @@ cat > /opt/amnezia/xray/server.json <<EOF
|
|||||||
"network": "tcp",
|
"network": "tcp",
|
||||||
"security": "reality",
|
"security": "reality",
|
||||||
"realitySettings": {
|
"realitySettings": {
|
||||||
"dest": "$XRAY_SITE_NAME:$XRAY_SERVER_PORT",
|
"dest": "$XRAY_SITE_NAME:443",
|
||||||
"serverNames": [
|
"serverNames": [
|
||||||
"$XRAY_SITE_NAME"
|
"$XRAY_SITE_NAME"
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ sudo docker run -d \
|
|||||||
--log-driver none \
|
--log-driver none \
|
||||||
--restart always \
|
--restart always \
|
||||||
--cap-add=NET_ADMIN \
|
--cap-add=NET_ADMIN \
|
||||||
-p $XRAY_SERVER_PORT:$XRAY_SERVER_PORT/tcp \
|
-p 443:443/tcp \
|
||||||
--name $CONTAINER_NAME $CONTAINER_NAME
|
--name $CONTAINER_NAME $CONTAINER_NAME
|
||||||
|
|
||||||
sudo docker network connect amnezia-dns-net $CONTAINER_NAME
|
sudo docker network connect amnezia-dns-net $CONTAINER_NAME
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
"vnext": [
|
"vnext": [
|
||||||
{
|
{
|
||||||
"address": "$SERVER_IP_ADDRESS",
|
"address": "$SERVER_IP_ADDRESS",
|
||||||
"port": "$XRAY_SERVER_PORT",
|
"port": 443,
|
||||||
"users": [
|
"users": [
|
||||||
{
|
{
|
||||||
"id": "$XRAY_CLIENT_ID",
|
"id": "$XRAY_CLIENT_ID",
|
||||||
|
|||||||
@@ -226,8 +226,6 @@ void Settings::setSaveLogs(bool enabled)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
Logger::setServiceLogsEnabled(enabled);
|
|
||||||
|
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
setLogEnableDate(QDateTime::currentDateTime());
|
setLogEnableDate(QDateTime::currentDateTime());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,13 +36,13 @@ ConnectionController::ConnectionController(const QSharedPointer<ServersModel> &s
|
|||||||
|
|
||||||
void ConnectionController::openConnection()
|
void ConnectionController::openConnection()
|
||||||
{
|
{
|
||||||
// #if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
||||||
// if (!Utils::processIsRunning(Utils::executable(SERVICE_NAME, false), true))
|
if (!Utils::processIsRunning(Utils::executable(SERVICE_NAME, false), true))
|
||||||
// {
|
{
|
||||||
// emit connectionErrorOccurred(ErrorCode::AmneziaServiceNotRunning);
|
emit connectionErrorOccurred(ErrorCode::AmneziaServiceNotRunning);
|
||||||
// return;
|
return;
|
||||||
// }
|
}
|
||||||
// #endif
|
#endif
|
||||||
|
|
||||||
int serverIndex = m_serversModel->getDefaultServerIndex();
|
int serverIndex = m_serversModel->getDefaultServerIndex();
|
||||||
QJsonObject serverConfig = m_serversModel->getServerConfig(serverIndex);
|
QJsonObject serverConfig = m_serversModel->getServerConfig(serverIndex);
|
||||||
|
|||||||
@@ -197,19 +197,7 @@ bool ImportController::extractConfigFromData(QString data)
|
|||||||
|
|
||||||
bool ImportController::extractConfigFromQr(const QByteArray &data)
|
bool ImportController::extractConfigFromQr(const QByteArray &data)
|
||||||
{
|
{
|
||||||
QJsonObject dataObj = QJsonDocument::fromJson(data).object();
|
return extractConfigFromData(data.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals));
|
||||||
if (!dataObj.isEmpty()) {
|
|
||||||
m_config = dataObj;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray ba_uncompressed = qUncompress(data);
|
|
||||||
if (!ba_uncompressed.isEmpty()) {
|
|
||||||
m_config = QJsonDocument::fromJson(ba_uncompressed).object();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ImportController::getConfig()
|
QString ImportController::getConfig()
|
||||||
@@ -240,9 +228,9 @@ void ImportController::processNativeWireGuardConfig()
|
|||||||
auto containerConfig = container.value(ContainerProps::containerTypeToString(DockerContainer::WireGuard)).toObject();
|
auto containerConfig = container.value(ContainerProps::containerTypeToString(DockerContainer::WireGuard)).toObject();
|
||||||
auto protocolConfig = QJsonDocument::fromJson(containerConfig.value(config_key::last_config).toString().toUtf8()).object();
|
auto protocolConfig = QJsonDocument::fromJson(containerConfig.value(config_key::last_config).toString().toUtf8()).object();
|
||||||
|
|
||||||
QString junkPacketCount = QString::number(QRandomGenerator::global()->bounded(2, 5));
|
QString junkPacketCount = QString::number(QRandomGenerator::global()->bounded(3, 10));
|
||||||
QString junkPacketMinSize = QString::number(10);
|
QString junkPacketMinSize = QString::number(50);
|
||||||
QString junkPacketMaxSize = QString::number(50);
|
QString junkPacketMaxSize = QString::number(1000);
|
||||||
protocolConfig[config_key::junkPacketCount] = junkPacketCount;
|
protocolConfig[config_key::junkPacketCount] = junkPacketCount;
|
||||||
protocolConfig[config_key::junkPacketMinSize] = junkPacketMinSize;
|
protocolConfig[config_key::junkPacketMinSize] = junkPacketMinSize;
|
||||||
protocolConfig[config_key::junkPacketMaxSize] = junkPacketMaxSize;
|
protocolConfig[config_key::junkPacketMaxSize] = junkPacketMaxSize;
|
||||||
@@ -533,8 +521,12 @@ void ImportController::startDecodingQr()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImportController::stopDecodingQr()
|
void ImportController::stopDecodingQr(const QByteArray &data)
|
||||||
{
|
{
|
||||||
|
if (!extractConfigFromQr(data)) {
|
||||||
|
emit qrDecodingError(ErrorCode::ImportQrDecodingError);
|
||||||
|
return;
|
||||||
|
}
|
||||||
emit qrDecodingFinished();
|
emit qrDecodingFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -571,25 +563,27 @@ bool ImportController::parseQrCodeChunk(const QString &code)
|
|||||||
data.append(m_qrCodeChunks.value(i));
|
data.append(m_qrCodeChunks.value(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ok = extractConfigFromQr(data);
|
data = qUncompress(data);
|
||||||
if (ok) {
|
auto format = checkConfigFormat(data);
|
||||||
m_isQrCodeProcessed = false;
|
if (format == ConfigTypes::Invalid) {
|
||||||
qDebug() << "stopDecodingQr";
|
|
||||||
stopDecodingQr();
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
qDebug() << "error while extracting data from qr";
|
qDebug() << "error while extracting data from qr";
|
||||||
m_qrCodeChunks.clear();
|
m_qrCodeChunks.clear();
|
||||||
m_totalQrCodeChunksCount = 0;
|
m_totalQrCodeChunksCount = 0;
|
||||||
m_receivedQrCodeChunksCount = 0;
|
m_receivedQrCodeChunksCount = 0;
|
||||||
|
} else {
|
||||||
|
qDebug() << "stopDecodingQr";
|
||||||
|
m_isQrCodeProcessed = false;
|
||||||
|
stopDecodingQr(data);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
bool ok = extractConfigFromQr(ba);
|
auto data = code.toUtf8();
|
||||||
if (ok) {
|
auto format = checkConfigFormat(data);
|
||||||
m_isQrCodeProcessed = false;
|
if (format != ConfigTypes::Invalid) {
|
||||||
qDebug() << "stopDecodingQr";
|
qDebug() << "stopDecodingQr";
|
||||||
stopDecodingQr();
|
m_isQrCodeProcessed = false;
|
||||||
|
stopDecodingQr(data);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,6 +61,10 @@ signals:
|
|||||||
|
|
||||||
void restoreAppConfig(const QByteArray &data);
|
void restoreAppConfig(const QByteArray &data);
|
||||||
|
|
||||||
|
#if defined Q_OS_ANDROID || defined Q_OS_IOS
|
||||||
|
void qrDecodingError(ErrorCode errorCode);
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QJsonObject extractOpenVpnConfig(const QString &data);
|
QJsonObject extractOpenVpnConfig(const QString &data);
|
||||||
QJsonObject extractWireGuardConfig(const QString &data);
|
QJsonObject extractWireGuardConfig(const QString &data);
|
||||||
@@ -69,7 +73,7 @@ private:
|
|||||||
void checkForMaliciousStrings(const QJsonObject &protocolConfig);
|
void checkForMaliciousStrings(const QJsonObject &protocolConfig);
|
||||||
|
|
||||||
#if defined Q_OS_ANDROID || defined Q_OS_IOS
|
#if defined Q_OS_ANDROID || defined Q_OS_IOS
|
||||||
void stopDecodingQr();
|
void stopDecodingQr(const QByteArray &data);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QSharedPointer<ServersModel> m_serversModel;
|
QSharedPointer<ServersModel> m_serversModel;
|
||||||
|
|||||||
@@ -85,9 +85,9 @@ void InstallController::install(DockerContainer container, int port, TransportPr
|
|||||||
containerConfig.insert(config_key::transport_proto, ProtocolProps::transportProtoToString(transportProto, protocol));
|
containerConfig.insert(config_key::transport_proto, ProtocolProps::transportProtoToString(transportProto, protocol));
|
||||||
|
|
||||||
if (container == DockerContainer::Awg) {
|
if (container == DockerContainer::Awg) {
|
||||||
QString junkPacketCount = QString::number(QRandomGenerator::global()->bounded(2, 5));
|
QString junkPacketCount = QString::number(QRandomGenerator::global()->bounded(3, 10));
|
||||||
QString junkPacketMinSize = QString::number(10);
|
QString junkPacketMinSize = QString::number(50);
|
||||||
QString junkPacketMaxSize = QString::number(50);
|
QString junkPacketMaxSize = QString::number(1000);
|
||||||
|
|
||||||
int s1 = QRandomGenerator::global()->bounded(15, 150);
|
int s1 = QRandomGenerator::global()->bounded(15, 150);
|
||||||
int s2 = QRandomGenerator::global()->bounded(15, 150);
|
int s2 = QRandomGenerator::global()->bounded(15, 150);
|
||||||
|
|||||||
@@ -92,9 +92,9 @@ int LanguageModel::getCurrentLanguageIndex()
|
|||||||
|
|
||||||
int LanguageModel::getLineHeightAppend()
|
int LanguageModel::getLineHeightAppend()
|
||||||
{
|
{
|
||||||
auto language = static_cast<LanguageSettings::AvailableLanguageEnum>(getCurrentLanguageIndex());
|
int langIndex = getCurrentLanguageIndex();
|
||||||
switch (language) {
|
switch (langIndex) {
|
||||||
case LanguageSettings::AvailableLanguageEnum::Burmese: return 10; break;
|
case 5: return 10; break; // Burmese
|
||||||
default: return 0; break;
|
default: return 0; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ DrawerType2 {
|
|||||||
property bool isAppSplitTinnelingEnabled: Qt.platform.os === "windows" || Qt.platform.os === "android"
|
property bool isAppSplitTinnelingEnabled: Qt.platform.os === "windows" || Qt.platform.os === "android"
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
expandedHeight: parent.height * 0.9
|
expandedHeight: parent.height * 0.7
|
||||||
|
|
||||||
expandedContent: ColumnLayout {
|
expandedContent: ColumnLayout {
|
||||||
id: content
|
id: content
|
||||||
|
|||||||
@@ -93,11 +93,20 @@ ListView {
|
|||||||
PageController.goToPage(PageEnum.PageProtocolRaw)
|
PageController.goToPage(PageEnum.PageProtocolRaw)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
case ContainerEnum.Sftp: {
|
||||||
|
SftpConfigModel.updateModel(config)
|
||||||
|
PageController.goToPage(PageEnum.PageServiceSftpSettings)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case ContainerEnum.TorWebSite: {
|
||||||
|
PageController.goToPage(PageEnum.PageServiceTorWebsiteSettings)
|
||||||
|
break
|
||||||
|
}
|
||||||
case ContainerEnum.Dns: {
|
case ContainerEnum.Dns: {
|
||||||
PageController.goToPage(PageEnum.PageServiceDnsSettings)
|
PageController.goToPage(PageEnum.PageServiceDnsSettings)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
default: {
|
default: { // go to the settings page of the container with multiple protocols
|
||||||
ProtocolsModel.updateModel(config)
|
ProtocolsModel.updateModel(config)
|
||||||
PageController.goToPage(PageEnum.PageSettingsServerProtocol)
|
PageController.goToPage(PageEnum.PageSettingsServerProtocol)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,8 +32,6 @@ Button {
|
|||||||
|
|
||||||
property var clickedFunc
|
property var clickedFunc
|
||||||
|
|
||||||
property alias buttonTextLabel: buttonText
|
|
||||||
|
|
||||||
implicitHeight: 56
|
implicitHeight: 56
|
||||||
|
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
@@ -142,8 +140,6 @@ Button {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ButtonTextType {
|
ButtonTextType {
|
||||||
id: buttonText
|
|
||||||
|
|
||||||
color: textColor
|
color: textColor
|
||||||
text: root.text
|
text: root.text
|
||||||
visible: root.text === "" ? false : true
|
visible: root.text === "" ? false : true
|
||||||
|
|||||||
@@ -20,8 +20,7 @@ Menu {
|
|||||||
MenuItem {
|
MenuItem {
|
||||||
text: qsTr("&Paste")
|
text: qsTr("&Paste")
|
||||||
shortcut: StandardKey.Paste
|
shortcut: StandardKey.Paste
|
||||||
// Fix calling paste from clipboard when launching app on android
|
enabled: textObj.canPaste
|
||||||
enabled: Qt.platform.os === "android" ? true : textObj.canPaste
|
|
||||||
onTriggered: textObj.paste()
|
onTriggered: textObj.paste()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -102,8 +102,7 @@ Switch {
|
|||||||
contentItem: ColumnLayout {
|
contentItem: ColumnLayout {
|
||||||
id: content
|
id: content
|
||||||
|
|
||||||
anchors.top: parent.top
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
|
||||||
ListItemTitleType {
|
ListItemTitleType {
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ Text {
|
|||||||
lineHeightMode: Text.FixedHeight
|
lineHeightMode: Text.FixedHeight
|
||||||
|
|
||||||
color: AmneziaStyle.color.white
|
color: AmneziaStyle.color.white
|
||||||
font.pixelSize: 32
|
font.pixelSize: 36
|
||||||
font.weight: 700
|
font.weight: 700
|
||||||
font.family: "PT Root UI VF"
|
font.family: "PT Root UI VF"
|
||||||
font.letterSpacing: -1.0
|
font.letterSpacing: -1.08
|
||||||
|
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,7 +85,6 @@ PageType {
|
|||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
id: splitTunnelingButton
|
id: splitTunnelingButton
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
|
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
|
||||||
Layout.bottomMargin: 34
|
Layout.bottomMargin: 34
|
||||||
leftPadding: 16
|
leftPadding: 16
|
||||||
@@ -101,10 +100,6 @@ PageType {
|
|||||||
leftImageColor: AmneziaStyle.color.transparent
|
leftImageColor: AmneziaStyle.color.transparent
|
||||||
borderWidth: 0
|
borderWidth: 0
|
||||||
|
|
||||||
buttonTextLabel.lineHeight: 20
|
|
||||||
buttonTextLabel.font.pixelSize: 14
|
|
||||||
buttonTextLabel.font.weight: 500
|
|
||||||
|
|
||||||
property bool isSplitTunnelingEnabled: SitesModel.isTunnelingEnabled || AppSplitTunnelingModel.isTunnelingEnabled ||
|
property bool isSplitTunnelingEnabled: SitesModel.isTunnelingEnabled || AppSplitTunnelingModel.isTunnelingEnabled ||
|
||||||
(ServersModel.isDefaultServerDefaultContainerHasSplitTunneling && ServersModel.getDefaultServerData("isServerFromApi"))
|
(ServersModel.isDefaultServerDefaultContainerHasSplitTunneling && ServersModel.getDefaultServerData("isServerFromApi"))
|
||||||
|
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ PageType {
|
|||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 16
|
Layout.topMargin: 16
|
||||||
|
|
||||||
headerText: qsTr("Jc - Junk packet count")
|
headerText: "Jc - Junk packet count"
|
||||||
textFieldText: junkPacketCount
|
textFieldText: junkPacketCount
|
||||||
textField.validator: IntValidator { bottom: 0 }
|
textField.validator: IntValidator { bottom: 0 }
|
||||||
parentFlickable: fl
|
parentFlickable: fl
|
||||||
@@ -168,7 +168,7 @@ PageType {
|
|||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 16
|
Layout.topMargin: 16
|
||||||
|
|
||||||
headerText: qsTr("Jmin - Junk packet minimum size")
|
headerText: "Jmin - Junk packet minimum size"
|
||||||
textFieldText: junkPacketMinSize
|
textFieldText: junkPacketMinSize
|
||||||
textField.validator: IntValidator { bottom: 0 }
|
textField.validator: IntValidator { bottom: 0 }
|
||||||
parentFlickable: fl
|
parentFlickable: fl
|
||||||
@@ -189,7 +189,7 @@ PageType {
|
|||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 16
|
Layout.topMargin: 16
|
||||||
|
|
||||||
headerText: qsTr("Jmax - Junk packet maximum size")
|
headerText: "Jmax - Junk packet maximum size"
|
||||||
textFieldText: junkPacketMaxSize
|
textFieldText: junkPacketMaxSize
|
||||||
textField.validator: IntValidator { bottom: 0 }
|
textField.validator: IntValidator { bottom: 0 }
|
||||||
parentFlickable: fl
|
parentFlickable: fl
|
||||||
@@ -210,7 +210,7 @@ PageType {
|
|||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 16
|
Layout.topMargin: 16
|
||||||
|
|
||||||
headerText: qsTr("S1 - Init packet junk size")
|
headerText: "S1 - Init packet junk size"
|
||||||
textFieldText: initPacketJunkSize
|
textFieldText: initPacketJunkSize
|
||||||
textField.validator: IntValidator { bottom: 0 }
|
textField.validator: IntValidator { bottom: 0 }
|
||||||
parentFlickable: fl
|
parentFlickable: fl
|
||||||
@@ -231,7 +231,7 @@ PageType {
|
|||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 16
|
Layout.topMargin: 16
|
||||||
|
|
||||||
headerText: qsTr("S2 - Response packet junk size")
|
headerText: "S2 - Response packet junk size"
|
||||||
textFieldText: responsePacketJunkSize
|
textFieldText: responsePacketJunkSize
|
||||||
textField.validator: IntValidator { bottom: 0 }
|
textField.validator: IntValidator { bottom: 0 }
|
||||||
parentFlickable: fl
|
parentFlickable: fl
|
||||||
@@ -252,7 +252,7 @@ PageType {
|
|||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 16
|
Layout.topMargin: 16
|
||||||
|
|
||||||
headerText: qsTr("H1 - Init packet magic header")
|
headerText: "H1 - Init packet magic header"
|
||||||
textFieldText: initPacketMagicHeader
|
textFieldText: initPacketMagicHeader
|
||||||
textField.validator: IntValidator { bottom: 0 }
|
textField.validator: IntValidator { bottom: 0 }
|
||||||
parentFlickable: fl
|
parentFlickable: fl
|
||||||
@@ -273,7 +273,7 @@ PageType {
|
|||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 16
|
Layout.topMargin: 16
|
||||||
|
|
||||||
headerText: qsTr("H2 - Response packet magic header")
|
headerText: "H2 - Response packet magic header"
|
||||||
textFieldText: responsePacketMagicHeader
|
textFieldText: responsePacketMagicHeader
|
||||||
textField.validator: IntValidator { bottom: 0 }
|
textField.validator: IntValidator { bottom: 0 }
|
||||||
parentFlickable: fl
|
parentFlickable: fl
|
||||||
@@ -294,7 +294,7 @@ PageType {
|
|||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 16
|
Layout.topMargin: 16
|
||||||
|
|
||||||
headerText: qsTr("H4 - Transport packet magic header")
|
headerText: "H4 - Transport packet magic header"
|
||||||
textFieldText: transportPacketMagicHeader
|
textFieldText: transportPacketMagicHeader
|
||||||
textField.validator: IntValidator { bottom: 0 }
|
textField.validator: IntValidator { bottom: 0 }
|
||||||
parentFlickable: fl
|
parentFlickable: fl
|
||||||
@@ -316,7 +316,7 @@ PageType {
|
|||||||
Layout.topMargin: 16
|
Layout.topMargin: 16
|
||||||
parentFlickable: fl
|
parentFlickable: fl
|
||||||
|
|
||||||
headerText: qsTr("H3 - Underload packet magic header")
|
headerText: "H3 - Underload packet magic header"
|
||||||
textFieldText: underloadPacketMagicHeader
|
textFieldText: underloadPacketMagicHeader
|
||||||
textField.validator: IntValidator { bottom: 0 }
|
textField.validator: IntValidator { bottom: 0 }
|
||||||
|
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ PageType {
|
|||||||
Layout.rightMargin: 16
|
Layout.rightMargin: 16
|
||||||
Layout.leftMargin: 16
|
Layout.leftMargin: 16
|
||||||
|
|
||||||
headerText: "AmneziaDNS"
|
headerText: "Amnezia DNS"
|
||||||
descriptionText: qsTr("A DNS service is installed on your server, and it is only accessible via VPN.\n") +
|
descriptionText: qsTr("A DNS service is installed on your server, and it is only accessible via VPN.\n") +
|
||||||
qsTr("The DNS address is the same as the address of your server. You can configure DNS in the settings, under the connections tab.")
|
qsTr("The DNS address is the same as the address of your server. You can configure DNS in the settings, under the connections tab.")
|
||||||
}
|
}
|
||||||
@@ -82,7 +82,7 @@ PageType {
|
|||||||
var yesButtonFunction = function() {
|
var yesButtonFunction = function() {
|
||||||
if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected
|
if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected
|
||||||
&& SettingsController.isAmneziaDnsEnabled()) {
|
&& SettingsController.isAmneziaDnsEnabled()) {
|
||||||
PageController.showNotificationMessage(qsTr("Cannot remove AmneziaDNS from running server"))
|
PageController.showNotificationMessage(qsTr("Cannot remove Amnezia DNS from running server"))
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
PageController.goToPage(PageEnum.PageDeinstalling)
|
PageController.goToPage(PageEnum.PageDeinstalling)
|
||||||
@@ -104,6 +104,8 @@ PageType {
|
|||||||
enabled: false
|
enabled: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DividerType {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ PageType {
|
|||||||
|
|
||||||
onFocusChanged: {
|
onFocusChanged: {
|
||||||
if (focus) {
|
if (focus) {
|
||||||
listview.currentItem.listViewFocusItem.forceActiveFocus()
|
listview.currentItem.focusItem.forceActiveFocus()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ PageType {
|
|||||||
implicitWidth: listview.width
|
implicitWidth: listview.width
|
||||||
implicitHeight: col.implicitHeight
|
implicitHeight: col.implicitHeight
|
||||||
|
|
||||||
property alias listViewFocusItem: hostLabel.rightButton
|
property alias focusItem: hostLabel.rightButton
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: col
|
id: col
|
||||||
@@ -233,7 +233,7 @@ PageType {
|
|||||||
PageController.showBusyIndicator(true)
|
PageController.showBusyIndicator(true)
|
||||||
InstallController.mountSftpDrive(port, password, username)
|
InstallController.mountSftpDrive(port, password, username)
|
||||||
PageController.showBusyIndicator(false)
|
PageController.showBusyIndicator(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ParagraphTextType {
|
ParagraphTextType {
|
||||||
@@ -290,12 +290,48 @@ PageType {
|
|||||||
text: qsTr("Detailed instructions")
|
text: qsTr("Detailed instructions")
|
||||||
|
|
||||||
parentFlickable: fl
|
parentFlickable: fl
|
||||||
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
KeyNavigation.tab: removeButton
|
||||||
|
|
||||||
clickedFunc: function() {
|
clickedFunc: function() {
|
||||||
// Qt.openUrlExternally("https://github.com/amnezia-vpn/desktop-client/releases/latest")
|
// Qt.openUrlExternally("https://github.com/amnezia-vpn/desktop-client/releases/latest")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BasicButtonType {
|
||||||
|
id: removeButton
|
||||||
|
Layout.topMargin: 24
|
||||||
|
Layout.bottomMargin: 16
|
||||||
|
Layout.leftMargin: 8
|
||||||
|
implicitHeight: 32
|
||||||
|
|
||||||
|
defaultColor: AmneziaStyle.color.transparent
|
||||||
|
hoveredColor: AmneziaStyle.color.blackHovered
|
||||||
|
pressedColor: AmneziaStyle.color.blackPressed
|
||||||
|
textColor: AmneziaStyle.color.red
|
||||||
|
|
||||||
|
parentFlickable: fl
|
||||||
|
Keys.onTabPressed: lastItemTabClicked()
|
||||||
|
|
||||||
|
text: qsTr("Remove SFTP and all data stored there")
|
||||||
|
|
||||||
|
clickedFunc: function() {
|
||||||
|
var headerText = qsTr("Remove SFTP and all data stored there?")
|
||||||
|
var yesButtonText = qsTr("Continue")
|
||||||
|
var noButtonText = qsTr("Cancel")
|
||||||
|
|
||||||
|
var yesButtonFunction = function() {
|
||||||
|
PageController.goToPage(PageEnum.PageDeinstalling)
|
||||||
|
InstallController.removeProcessedContainer()
|
||||||
|
}
|
||||||
|
var noButtonFunction = function() {
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
removeButton.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
showQuestionDrawer(headerText, "", yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ PageType {
|
|||||||
rightImageSource: "qrc:/images/controls/copy.svg"
|
rightImageSource: "qrc:/images/controls/copy.svg"
|
||||||
rightImageColor: AmneziaStyle.color.white
|
rightImageColor: AmneziaStyle.color.white
|
||||||
|
|
||||||
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
KeyNavigation.tab: removeButton
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
GC.copyToClipBoard(descriptionText)
|
GC.copyToClipBoard(descriptionText)
|
||||||
@@ -127,6 +127,41 @@ PageType {
|
|||||||
|
|
||||||
text: qsTr("When configuring WordPress set the this onion address as domain.")
|
text: qsTr("When configuring WordPress set the this onion address as domain.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BasicButtonType {
|
||||||
|
id: removeButton
|
||||||
|
Layout.topMargin: 24
|
||||||
|
Layout.bottomMargin: 16
|
||||||
|
Layout.leftMargin: 8
|
||||||
|
implicitHeight: 32
|
||||||
|
|
||||||
|
defaultColor: AmneziaStyle.color.transparent
|
||||||
|
hoveredColor: AmneziaStyle.color.blackHovered
|
||||||
|
pressedColor: AmneziaStyle.color.blackPressed
|
||||||
|
textColor: AmneziaStyle.color.red
|
||||||
|
|
||||||
|
text: qsTr("Remove website")
|
||||||
|
|
||||||
|
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
||||||
|
|
||||||
|
clickedFunc: function() {
|
||||||
|
var headerText = qsTr("The site with all data will be removed from the tor network.")
|
||||||
|
var yesButtonText = qsTr("Continue")
|
||||||
|
var noButtonText = qsTr("Cancel")
|
||||||
|
|
||||||
|
var yesButtonFunction = function() {
|
||||||
|
PageController.goToPage(PageEnum.PageDeinstalling)
|
||||||
|
InstallController.removeProcessedContainer()
|
||||||
|
}
|
||||||
|
var noButtonFunction = function() {
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
removeButton.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
showQuestionDrawer(headerText, "", yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -276,7 +276,7 @@ PageType {
|
|||||||
|
|
||||||
if (Qt.platform.os === "windows") {
|
if (Qt.platform.os === "windows") {
|
||||||
var fileName = SystemController.getFileName(qsTr("Open executable file"),
|
var fileName = SystemController.getFileName(qsTr("Open executable file"),
|
||||||
qsTr("Executable files (*.*)"))
|
qsTr("Executable file (*.*)"))
|
||||||
if (fileName !== "") {
|
if (fileName !== "") {
|
||||||
AppSplitTunnelingController.addApp(fileName)
|
AppSplitTunnelingController.addApp(fileName)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,8 +51,6 @@ PageType {
|
|||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
HeaderType {
|
HeaderType {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.leftMargin: 16
|
Layout.leftMargin: 16
|
||||||
|
|||||||
@@ -105,7 +105,6 @@ PageType {
|
|||||||
case ProtocolEnum.WireGuard: WireGuardConfigModel.updateModel(ProtocolsModel.getConfig()); break;
|
case ProtocolEnum.WireGuard: WireGuardConfigModel.updateModel(ProtocolsModel.getConfig()); break;
|
||||||
case ProtocolEnum.Awg: AwgConfigModel.updateModel(ProtocolsModel.getConfig()); break;
|
case ProtocolEnum.Awg: AwgConfigModel.updateModel(ProtocolsModel.getConfig()); break;
|
||||||
case ProtocolEnum.Xray: XrayConfigModel.updateModel(ProtocolsModel.getConfig()); break;
|
case ProtocolEnum.Xray: XrayConfigModel.updateModel(ProtocolsModel.getConfig()); break;
|
||||||
case ProtocolEnum.Sftp: SftpConfigModel.updateModel(ProtocolsModel.getConfig()); break;
|
|
||||||
case ProtocolEnum.Ipsec: Ikev2ConfigModel.updateModel(ProtocolsModel.getConfig()); break;
|
case ProtocolEnum.Ipsec: Ikev2ConfigModel.updateModel(ProtocolsModel.getConfig()); break;
|
||||||
case ProtocolEnum.Socks5Proxy: Socks5ProxyConfigModel.updateModel(ProtocolsModel.getConfig()); break;
|
case ProtocolEnum.Socks5Proxy: Socks5ProxyConfigModel.updateModel(ProtocolsModel.getConfig()); break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,10 @@ PageType {
|
|||||||
PageController.closePage()
|
PageController.closePage()
|
||||||
PageController.goToPage(PageEnum.PageSetupWizardViewConfig)
|
PageController.goToPage(PageEnum.PageSetupWizardViewConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onQrDecodingError() {
|
||||||
|
PageController.closePage()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultActiveFocusItem: focusItem
|
defaultActiveFocusItem: focusItem
|
||||||
|
|||||||
@@ -202,7 +202,7 @@ PageType {
|
|||||||
parent: root
|
parent: root
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
expandedHeight: root.height
|
expandedHeight: root.height * 0.45
|
||||||
onClosed: {
|
onClosed: {
|
||||||
if (!GC.isMobile()) {
|
if (!GC.isMobile()) {
|
||||||
clientNameTextField.textField.forceActiveFocus()
|
clientNameTextField.textField.forceActiveFocus()
|
||||||
@@ -210,7 +210,6 @@ PageType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
expandedContent: ColumnLayout {
|
expandedContent: ColumnLayout {
|
||||||
id: shareFullAccessDrawerContent
|
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
@@ -218,10 +217,6 @@ PageType {
|
|||||||
|
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
onImplicitHeightChanged: {
|
|
||||||
shareFullAccessDrawer.expandedHeight = shareFullAccessDrawerContent.implicitHeight + 32
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: shareFullAccessDrawer
|
target: shareFullAccessDrawer
|
||||||
enabled: !GC.isMobile()
|
enabled: !GC.isMobile()
|
||||||
|
|||||||
@@ -214,8 +214,8 @@ PageType {
|
|||||||
startY: 0
|
startY: 0
|
||||||
|
|
||||||
PathLine { x: width; y: 0 }
|
PathLine { x: width; y: 0 }
|
||||||
PathLine { x: width; y: tabBar.height - 1 }
|
PathLine { x: width; y: height - 1 }
|
||||||
PathLine { x: 0; y: tabBar.height - 1 }
|
PathLine { x: 0; y: height - 1 }
|
||||||
PathLine { x: 0; y: 0 }
|
PathLine { x: 0; y: 0 }
|
||||||
|
|
||||||
strokeWidth: 1
|
strokeWidth: 1
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ class IpcInterface
|
|||||||
|
|
||||||
SLOT( void cleanUp() );
|
SLOT( void cleanUp() );
|
||||||
SLOT( void setLogsEnabled(bool enabled) );
|
SLOT( void setLogsEnabled(bool enabled) );
|
||||||
SLOT( void clearLogs() );
|
|
||||||
|
|
||||||
SLOT( bool createTun(const QString &dev, const QString &subnet) );
|
SLOT( bool createTun(const QString &dev, const QString &subnet) );
|
||||||
SLOT( bool deleteTun(const QString &dev) );
|
SLOT( bool deleteTun(const QString &dev) );
|
||||||
|
|||||||
@@ -162,10 +162,6 @@ void IpcServer::cleanUp()
|
|||||||
Logger::cleanUp();
|
Logger::cleanUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
void IpcServer::clearLogs() {
|
|
||||||
Logger::clearLogs();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IpcServer::createTun(const QString &dev, const QString &subnet)
|
bool IpcServer::createTun(const QString &dev, const QString &subnet)
|
||||||
{
|
{
|
||||||
return Router::createTun(dev, subnet);
|
return Router::createTun(dev, subnet);
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ public:
|
|||||||
virtual bool checkAndInstallDriver() override;
|
virtual bool checkAndInstallDriver() override;
|
||||||
virtual QStringList getTapList() override;
|
virtual QStringList getTapList() override;
|
||||||
virtual void cleanUp() override;
|
virtual void cleanUp() override;
|
||||||
virtual void clearLogs() override;
|
|
||||||
virtual void setLogsEnabled(bool enabled) override;
|
virtual void setLogsEnabled(bool enabled) override;
|
||||||
virtual bool createTun(const QString &dev, const QString &subnet) override;
|
virtual bool createTun(const QString &dev, const QString &subnet) override;
|
||||||
virtual bool deleteTun(const QString &dev) override;
|
virtual bool deleteTun(const QString &dev) override;
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 9.3 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 339 KiB |
|
Before Width: | Height: | Size: 11 KiB |
@@ -46,6 +46,8 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
Utils::initializePath(Utils::systemLogPath());
|
Utils::initializePath(Utils::systemLogPath());
|
||||||
|
|
||||||
|
Logger::init();
|
||||||
|
|
||||||
if (argc >= 2) {
|
if (argc >= 2) {
|
||||||
qInfo() << "Started as console application";
|
qInfo() << "Started as console application";
|
||||||
return runApplication(argc, argv);
|
return runApplication(argc, argv);
|
||||||
|
|||||||