mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-06-21 02:01:03 +07:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 40cc856ece | |||
| c551d759bb | |||
| d00d409cda | |||
| c897963bac | |||
| b591dd7445 | |||
| a45bb5ea4f |
@@ -10,10 +10,10 @@ env:
|
||||
|
||||
jobs:
|
||||
Build-Linux-Ubuntu:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: 4-core
|
||||
|
||||
env:
|
||||
QT_VERSION: 6.9.2
|
||||
QT_VERSION: 6.8.3
|
||||
QIF_VERSION: 4.7
|
||||
PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }}
|
||||
PROD_S3_ENDPOINT: ${{ secrets.PROD_S3_ENDPOINT }}
|
||||
@@ -30,13 +30,15 @@ jobs:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
host: 'linux'
|
||||
target: 'desktop'
|
||||
arch: 'gcc_64'
|
||||
arch: 'linux_gcc_64'
|
||||
modules: 'qtremoteobjects qt5compat qtshadertools'
|
||||
dir: ${{ runner.temp }}
|
||||
setup-python: 'true'
|
||||
tools: 'tools_ifw'
|
||||
set-env: 'true'
|
||||
extra: '--external 7z --base ${{ env.QT_MIRROR }}'
|
||||
aqtversion: '==3.3.0'
|
||||
py7zrversion: '==0.22.*'
|
||||
extra: '--base ${{ env.QT_MIRROR }}'
|
||||
|
||||
- name: 'Get sources'
|
||||
uses: actions/checkout@v4
|
||||
@@ -51,8 +53,8 @@ jobs:
|
||||
echo "VERSION=$VERSION" >> $GITHUB_ENV
|
||||
echo "Version: $VERSION"
|
||||
|
||||
- name: 'Setup ccache'
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
# - name: 'Setup ccache'
|
||||
# uses: hendrikmuhs/ccache-action@v1.2
|
||||
|
||||
- name: 'Build project'
|
||||
run: |
|
||||
@@ -91,7 +93,7 @@ jobs:
|
||||
runs-on: windows-latest
|
||||
|
||||
env:
|
||||
QT_VERSION: 6.9.2
|
||||
QT_VERSION: 6.10.1
|
||||
QIF_VERSION: 4.7
|
||||
BUILD_ARCH: 64
|
||||
PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }}
|
||||
@@ -117,8 +119,8 @@ jobs:
|
||||
echo "VERSION=$VERSION" >> $GITHUB_ENV
|
||||
echo "Version: $VERSION"
|
||||
|
||||
- name: 'Setup ccache'
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
# - name: 'Setup ccache'
|
||||
# uses: hendrikmuhs/ccache-action@v1.2
|
||||
|
||||
- name: 'Install Qt'
|
||||
uses: jurplel/install-qt-action@v3
|
||||
@@ -126,13 +128,15 @@ jobs:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
host: 'windows'
|
||||
target: 'desktop'
|
||||
arch: 'win64_msvc2019_64'
|
||||
arch: 'win64_msvc2022_64'
|
||||
modules: 'qtremoteobjects qt5compat qtshadertools'
|
||||
dir: ${{ runner.temp }}
|
||||
setup-python: 'true'
|
||||
tools: 'tools_ifw'
|
||||
set-env: 'true'
|
||||
extra: '--external 7z --base ${{ env.QT_MIRROR }}'
|
||||
aqtversion: '==3.3.0'
|
||||
py7zrversion: '==0.22.*'
|
||||
extra: '--base ${{ env.QT_MIRROR }}'
|
||||
|
||||
- name: 'Setup mvsc'
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
@@ -158,7 +162,7 @@ jobs:
|
||||
shell: cmd
|
||||
run: |
|
||||
set BUILD_ARCH=${{ env.BUILD_ARCH }}
|
||||
set QT_BIN_DIR="${{ runner.temp }}\\Qt\\${{ env.QT_VERSION }}\\msvc2019_64\\bin"
|
||||
set QT_BIN_DIR="${{ runner.temp }}\\Qt\\${{ env.QT_VERSION }}\\msvc2022_64\\bin"
|
||||
set QIF_BIN_DIR="${{ runner.temp }}\\Qt\\Tools\\QtInstallerFramework\\${{ env.QIF_VERSION }}\\bin"
|
||||
set WIX_BIN_DIR=%USERPROFILE%\.dotnet\tools
|
||||
call deploy\\build_windows.bat
|
||||
@@ -195,7 +199,7 @@ jobs:
|
||||
runs-on: macos-latest
|
||||
|
||||
env:
|
||||
QT_VERSION: 6.9.2
|
||||
QT_VERSION: 6.10.1
|
||||
CC: cc
|
||||
CXX: c++
|
||||
PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }}
|
||||
@@ -254,8 +258,8 @@ jobs:
|
||||
submodules: 'true'
|
||||
fetch-depth: 10
|
||||
|
||||
- name: 'Setup ccache'
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
# - name: 'Setup ccache'
|
||||
# uses: hendrikmuhs/ccache-action@v1.2
|
||||
|
||||
- name: 'Install dependencies'
|
||||
run: pip install jsonschema jinja2
|
||||
@@ -346,8 +350,8 @@ jobs:
|
||||
submodules: 'true'
|
||||
fetch-depth: 10
|
||||
|
||||
- name: 'Setup ccache'
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
# - name: 'Setup ccache'
|
||||
# uses: hendrikmuhs/ccache-action@v1.2
|
||||
|
||||
- name: 'Build project'
|
||||
run: |
|
||||
@@ -374,7 +378,7 @@ jobs:
|
||||
runs-on: macos-latest
|
||||
|
||||
env:
|
||||
QT_VERSION: 6.9.2
|
||||
QT_VERSION: 6.10.1
|
||||
|
||||
MAC_TEAM_ID: ${{ secrets.MAC_TEAM_ID }}
|
||||
|
||||
@@ -412,15 +416,11 @@ jobs:
|
||||
arch: 'clang_64'
|
||||
modules: 'qtremoteobjects qt5compat qtshadertools'
|
||||
dir: ${{ runner.temp }}
|
||||
#setup-python: 'true'
|
||||
#set-env: 'true'
|
||||
#extra: '--external 7z --base ${{ env.QT_MIRROR }}'
|
||||
setup-python: 'true'
|
||||
set-env: 'true'
|
||||
aqtversion: '==3.3.0'
|
||||
py7zrversion: '==0.22.*'
|
||||
extra: '--base ${{ env.QT_MIRROR }}'
|
||||
cache: 'true'
|
||||
|
||||
- name: 'Get sources'
|
||||
uses: actions/checkout@v4
|
||||
@@ -435,8 +435,8 @@ jobs:
|
||||
echo "VERSION=$VERSION" >> $GITHUB_ENV
|
||||
echo "Version: $VERSION"
|
||||
|
||||
- name: 'Setup ccache'
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
# - name: 'Setup ccache'
|
||||
# uses: hendrikmuhs/ccache-action@v1.2
|
||||
|
||||
- name: 'Build project'
|
||||
run: |
|
||||
@@ -467,7 +467,7 @@ jobs:
|
||||
runs-on: macos-latest
|
||||
|
||||
env:
|
||||
QT_VERSION: 6.9.2
|
||||
QT_VERSION: 6.10.1
|
||||
|
||||
MAC_TEAM_ID: ${{ secrets.MAC_TEAM_ID }}
|
||||
|
||||
@@ -519,8 +519,8 @@ jobs:
|
||||
submodules: 'true'
|
||||
fetch-depth: 10
|
||||
|
||||
- name: 'Setup ccache'
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
# - name: 'Setup ccache'
|
||||
# uses: hendrikmuhs/ccache-action@v1.2
|
||||
|
||||
- name: 'Build project'
|
||||
run: |
|
||||
@@ -537,7 +537,7 @@ jobs:
|
||||
# ------------------------------------------------------
|
||||
|
||||
Build-Android:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: 4-core
|
||||
|
||||
env:
|
||||
ANDROID_BUILD_PLATFORM: android-36
|
||||
@@ -629,15 +629,15 @@ jobs:
|
||||
echo "VERSION=$VERSION" >> $GITHUB_ENV
|
||||
echo "Version: $VERSION"
|
||||
|
||||
- name: 'Setup ccache'
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
# - name: 'Setup ccache'
|
||||
# uses: hendrikmuhs/ccache-action@v1.2
|
||||
|
||||
- name: 'Setup Java'
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '17'
|
||||
cache: 'gradle'
|
||||
# cache: 'gradle'
|
||||
|
||||
- name: 'Setup Android NDK'
|
||||
id: setup-ndk
|
||||
|
||||
+7
-5
@@ -1,7 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.25.0 FATAL_ERROR)
|
||||
|
||||
set(PROJECT AmneziaVPN)
|
||||
set(AMNEZIAVPN_VERSION 4.8.12.5)
|
||||
set(AMNEZIAVPN_VERSION 4.8.12.8)
|
||||
|
||||
project(${PROJECT} VERSION ${AMNEZIAVPN_VERSION}
|
||||
DESCRIPTION "AmneziaVPN"
|
||||
@@ -12,7 +12,7 @@ string(TIMESTAMP CURRENT_DATE "%Y-%m-%d")
|
||||
set(RELEASE_DATE "${CURRENT_DATE}")
|
||||
|
||||
set(APP_MAJOR_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH})
|
||||
set(APP_ANDROID_VERSION_CODE 2101)
|
||||
set(APP_ANDROID_VERSION_CODE 2104)
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
||||
set(MZ_PLATFORM_NAME "linux")
|
||||
@@ -24,6 +24,8 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Android")
|
||||
set(MZ_PLATFORM_NAME "android")
|
||||
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "iOS")
|
||||
set(MZ_PLATFORM_NAME "ios")
|
||||
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "tvOS")
|
||||
set(MZ_PLATFORM_NAME "ios")
|
||||
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Emscripten")
|
||||
set(MZ_PLATFORM_NAME "wasm")
|
||||
endif()
|
||||
@@ -33,7 +35,7 @@ set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
if(APPLE)
|
||||
if(IOS)
|
||||
if(IOS OR CMAKE_SYSTEM_NAME STREQUAL "tvOS")
|
||||
set(CMAKE_OSX_ARCHITECTURES "arm64")
|
||||
elseif(MACOS_NE)
|
||||
set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64")
|
||||
@@ -44,7 +46,7 @@ endif()
|
||||
|
||||
add_subdirectory(client)
|
||||
|
||||
if(NOT IOS AND NOT ANDROID AND NOT MACOS_NE)
|
||||
if(NOT IOS AND NOT ANDROID AND NOT MACOS_NE AND NOT CMAKE_SYSTEM_NAME STREQUAL "tvOS")
|
||||
add_subdirectory(service)
|
||||
|
||||
include(${CMAKE_SOURCE_DIR}/deploy/installer/config.cmake)
|
||||
@@ -52,7 +54,7 @@ endif()
|
||||
|
||||
set(AMNEZIA_STAGE_DIR "${CMAKE_BINARY_DIR}/stage")
|
||||
|
||||
if(WIN32 AND NOT IOS AND NOT ANDROID AND NOT MACOS_NE)
|
||||
if(WIN32 AND NOT IOS AND NOT ANDROID AND NOT MACOS_NE AND NOT CMAKE_SYSTEM_NAME STREQUAL "tvOS")
|
||||
file(TO_CMAKE_PATH "${AMNEZIA_STAGE_DIR}" AMNEZIA_STAGE_DIR_CMAKE)
|
||||
|
||||
set(CPACK_GENERATOR "WIX")
|
||||
|
||||
@@ -33,7 +33,7 @@ add_definitions(-DDEV_S3_ENDPOINT="$ENV{DEV_S3_ENDPOINT}")
|
||||
add_definitions(-DFREE_V2_ENDPOINT="$ENV{FREE_V2_ENDPOINT}")
|
||||
add_definitions(-DPREM_V1_ENDPOINT="$ENV{PREM_V1_ENDPOINT}")
|
||||
|
||||
if(WIN32 OR (APPLE AND NOT IOS) OR (LINUX AND NOT ANDROID))
|
||||
if(WIN32 OR (APPLE AND NOT IOS AND NOT CMAKE_SYSTEM_NAME STREQUAL "tvOS") OR (LINUX AND NOT ANDROID))
|
||||
set(PACKAGES ${PACKAGES} Widgets)
|
||||
endif()
|
||||
|
||||
@@ -46,7 +46,7 @@ set(LIBS ${LIBS}
|
||||
Qt6::Core5Compat Qt6::Concurrent
|
||||
)
|
||||
|
||||
if(WIN32 OR (APPLE AND NOT IOS) OR (LINUX AND NOT ANDROID))
|
||||
if(WIN32 OR (APPLE AND NOT IOS AND NOT CMAKE_SYSTEM_NAME STREQUAL "tvOS") OR (LINUX AND NOT ANDROID))
|
||||
set(LIBS ${LIBS} Qt6::Widgets)
|
||||
endif()
|
||||
|
||||
@@ -56,7 +56,7 @@ target_include_directories(${PROJECT} PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
|
||||
)
|
||||
|
||||
if(WIN32 OR (APPLE AND NOT IOS AND NOT MACOS_NE) OR (LINUX AND NOT ANDROID))
|
||||
if(WIN32 OR (APPLE AND NOT IOS AND NOT MACOS_NE AND NOT CMAKE_SYSTEM_NAME STREQUAL "tvOS") OR (LINUX AND NOT ANDROID))
|
||||
qt_add_repc_replicas(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}/../ipc/ipc_interface.rep)
|
||||
qt_add_repc_replicas(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}/../ipc/ipc_process_interface.rep)
|
||||
qt_add_repc_replicas(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}/../ipc/ipc_process_tun2socks.rep)
|
||||
@@ -176,7 +176,7 @@ if(LINUX AND NOT ANDROID)
|
||||
link_directories(${CMAKE_CURRENT_LIST_DIR}/platforms/linux)
|
||||
endif()
|
||||
|
||||
if(WIN32 OR (APPLE AND NOT IOS AND NOT MACOS_NE) OR (LINUX AND NOT ANDROID))
|
||||
if(WIN32 OR (APPLE AND NOT IOS AND NOT MACOS_NE AND NOT CMAKE_SYSTEM_NAME STREQUAL "tvOS") OR (LINUX AND NOT ANDROID))
|
||||
add_compile_definitions(AMNEZIA_DESKTOP)
|
||||
endif()
|
||||
|
||||
@@ -184,7 +184,8 @@ if(ANDROID)
|
||||
include(cmake/android.cmake)
|
||||
endif()
|
||||
|
||||
if(IOS)
|
||||
if(IOS OR CMAKE_SYSTEM_NAME STREQUAL "tvOS")
|
||||
option(AMNEZIA_IOS_ENABLE_APPLETV_TARGET "Enable Apple TV target settings for iOS/Xcode projects" OFF)
|
||||
include(cmake/ios.cmake)
|
||||
include(cmake/ios-arch-fixup.cmake)
|
||||
elseif(APPLE AND MACOS_NE)
|
||||
@@ -206,11 +207,11 @@ if(WIN32)
|
||||
endif()
|
||||
elseif(LINUX)
|
||||
set(DEPLOY_PLATFORM_PATH "linux/client")
|
||||
elseif(APPLE AND NOT IOS)
|
||||
elseif(APPLE AND NOT IOS AND NOT CMAKE_SYSTEM_NAME STREQUAL "tvOS")
|
||||
set(DEPLOY_PLATFORM_PATH "macos")
|
||||
endif()
|
||||
|
||||
if(NOT IOS AND NOT ANDROID AND NOT MACOS_NE)
|
||||
if(NOT IOS AND NOT ANDROID AND NOT MACOS_NE AND NOT CMAKE_SYSTEM_NAME STREQUAL "tvOS")
|
||||
add_custom_command(
|
||||
TARGET ${PROJECT} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E $<IF:$<CONFIG:Debug>,copy_directory,true>
|
||||
|
||||
@@ -61,10 +61,10 @@ AmneziaApplication::AmneziaApplication(int &argc, char *argv[]) : AMNEZIA_BASE_C
|
||||
AmneziaApplication::~AmneziaApplication()
|
||||
{
|
||||
#ifdef AMNEZIA_DESKTOP
|
||||
if (m_vpnConnection) {
|
||||
QMetaObject::invokeMethod(m_vpnConnection.get(), "disconnectSlots", Qt::QueuedConnection);
|
||||
QMetaObject::invokeMethod(m_vpnConnection.get(), "disconnectFromVpn", Qt::QueuedConnection);
|
||||
QThread::msleep(2000);
|
||||
if (m_vpnConnection && m_vpnConnectionThread.isRunning()) {
|
||||
QMetaObject::invokeMethod(m_vpnConnection.get(), "disconnectSlots", Qt::BlockingQueuedConnection);
|
||||
|
||||
QMetaObject::invokeMethod(m_vpnConnection.get(), "disconnectFromVpn", Qt::BlockingQueuedConnection);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -77,7 +77,6 @@ AmneziaApplication::~AmneziaApplication()
|
||||
}
|
||||
|
||||
if (m_engine) {
|
||||
QObject::disconnect(m_engine, 0, 0, 0);
|
||||
delete m_engine;
|
||||
}
|
||||
}
|
||||
@@ -251,7 +250,7 @@ bool AmneziaApplication::parseCommands()
|
||||
return true;
|
||||
}
|
||||
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(MACOS_NE)
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(Q_OS_TVOS) && !defined(MACOS_NE)
|
||||
void AmneziaApplication::startLocalServer() {
|
||||
const QString serverName("AmneziaVPNInstance");
|
||||
QLocalServer::removeServer(serverName);
|
||||
@@ -272,7 +271,7 @@ void AmneziaApplication::startLocalServer() {
|
||||
bool AmneziaApplication::eventFilter(QObject *watched, QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::Close) {
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) || defined(Q_OS_TVOS)
|
||||
quit();
|
||||
#else
|
||||
if (m_forceQuit) {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <QQmlApplicationEngine>
|
||||
#include <QQmlContext>
|
||||
#include <QThread>
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) || defined(Q_OS_TVOS)
|
||||
#include <QGuiApplication>
|
||||
#else
|
||||
#include <QApplication>
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#define amnApp (static_cast<AmneziaApplication *>(QCoreApplication::instance()))
|
||||
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) || defined(Q_OS_TVOS)
|
||||
#define AMNEZIA_BASE_CLASS QGuiApplication
|
||||
#else
|
||||
#define AMNEZIA_BASE_CLASS QApplication
|
||||
@@ -37,7 +37,7 @@ public:
|
||||
void loadFonts();
|
||||
bool parseCommands();
|
||||
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(MACOS_NE)
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(Q_OS_TVOS) && !defined(MACOS_NE)
|
||||
void startLocalServer();
|
||||
#endif
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ if(WIN32)
|
||||
set(OPENSSL_LIB_SSL_PATH "${OPENSSL_ROOT_DIR}/windows/win32/libssl.lib")
|
||||
set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_ROOT_DIR}/windows/win32/libcrypto.lib")
|
||||
endif()
|
||||
elseif(APPLE AND NOT IOS)
|
||||
elseif(APPLE AND NOT IOS AND NOT CMAKE_SYSTEM_NAME STREQUAL "tvOS")
|
||||
if(MACOS_NE)
|
||||
set(LIBSSH_LIB_PATH "${LIBSSH_ROOT_DIR}/macos/universal2/libssh.a")
|
||||
set(ZLIB_LIB_PATH "${LIBSSH_ROOT_DIR}/macos/universal2/libz.a")
|
||||
@@ -39,6 +39,24 @@ elseif(APPLE AND NOT IOS)
|
||||
set(OPENSSL_INCLUDE_DIR "${OPENSSL_ROOT_DIR}/macos/include")
|
||||
set(OPENSSL_LIB_SSL_PATH "${OPENSSL_ROOT_DIR}/macos/lib/libssl.a")
|
||||
set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_ROOT_DIR}/macos/lib/libcrypto.a")
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "tvOS")
|
||||
set(TVOS_3RD_ROOT "$ENV{HOME}/Qt_tv/3rd-tvos")
|
||||
execute_process(
|
||||
COMMAND xcrun --sdk appletvos --show-sdk-path
|
||||
OUTPUT_VARIABLE TVOS_SDK_PATH
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
set(LIBSSH_ROOT_DIR "${TVOS_3RD_ROOT}/libssh/0.10.6/appletvos-arm64")
|
||||
set(OPENSSL_ROOT_DIR "${TVOS_3RD_ROOT}/openssl/3.0.13/appletvos-arm64")
|
||||
set(OPENSSL_LIBRARIES_DIR "${OPENSSL_ROOT_DIR}/lib")
|
||||
|
||||
set(LIBSSH_INCLUDE_DIR "${LIBSSH_ROOT_DIR}")
|
||||
set(LIBSSH_LIB_PATH "${LIBSSH_ROOT_DIR}/lib/libssh.a")
|
||||
set(ZLIB_LIB_PATH "${TVOS_SDK_PATH}/usr/lib/libz.tbd")
|
||||
set(OPENSSL_INCLUDE_DIR "${OPENSSL_ROOT_DIR}/include")
|
||||
set(OPENSSL_LIB_SSL_PATH "${OPENSSL_ROOT_DIR}/lib/libssl.a")
|
||||
set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_ROOT_DIR}/lib/libcrypto.a")
|
||||
elseif(IOS)
|
||||
set(LIBSSH_INCLUDE_DIR "${LIBSSH_ROOT_DIR}/ios/arm64")
|
||||
set(LIBSSH_LIB_PATH "${LIBSSH_ROOT_DIR}/ios/arm64/libssh.a")
|
||||
@@ -63,8 +81,10 @@ elseif(LINUX)
|
||||
set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_ROOT_DIR}/linux/x86_64/libcrypto.a")
|
||||
endif()
|
||||
|
||||
file(COPY ${OPENSSL_LIB_SSL_PATH} ${OPENSSL_LIB_CRYPTO_PATH}
|
||||
DESTINATION ${OPENSSL_LIBRARIES_DIR})
|
||||
if(NOT CMAKE_SYSTEM_NAME STREQUAL "tvOS")
|
||||
file(COPY ${OPENSSL_LIB_SSL_PATH} ${OPENSSL_LIB_CRYPTO_PATH}
|
||||
DESTINATION ${OPENSSL_LIBRARIES_DIR})
|
||||
endif()
|
||||
|
||||
set(OPENSSL_USE_STATIC_LIBS TRUE)
|
||||
|
||||
|
||||
@@ -39,5 +39,7 @@ while(IOS_TARGETS)
|
||||
set_target_properties(${TARGET_NAME} PROPERTIES
|
||||
XCODE_ATTRIBUTE_ARCHS[sdk=iphoneos*] "arm64"
|
||||
XCODE_ATTRIBUTE_ARCHS[sdk=iphonesimulator*] "x86_64"
|
||||
XCODE_ATTRIBUTE_ARCHS[sdk=appletvos*] "arm64"
|
||||
XCODE_ATTRIBUTE_ARCHS[sdk=appletvsimulator*] "arm64"
|
||||
)
|
||||
endwhile()
|
||||
endwhile()
|
||||
|
||||
+142
-27
@@ -1,6 +1,20 @@
|
||||
message("Client iOS build")
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 13.0)
|
||||
set(APPLE_PROJECT_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH})
|
||||
set(AMNEZIA_IOS_APPLETV ${AMNEZIA_IOS_ENABLE_APPLETV_TARGET})
|
||||
|
||||
if(AMNEZIA_IOS_APPLETV)
|
||||
message("Apple TV target mode is ON")
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 17.0)
|
||||
set(QT_NO_SET_DEFAULT_IOS_LAUNCH_SCREEN TRUE)
|
||||
set(QT_NO_ADD_IOS_LAUNCH_SCREEN_TO_BUNDLE TRUE)
|
||||
set(IOS_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/ios/app/Info-tvOS.plist.in)
|
||||
set(IOS_LAUNCHSCREEN_STORYBOARD ${CMAKE_CURRENT_SOURCE_DIR}/ios/app/tvOS/AmneziaVPNLaunchScreen.storyboard)
|
||||
else()
|
||||
message("Apple TV target mode is OFF")
|
||||
set(IOS_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/ios/app/Info.plist.in)
|
||||
set(IOS_LAUNCHSCREEN_STORYBOARD ${CMAKE_CURRENT_SOURCE_DIR}/ios/app/AmneziaVPNLaunchScreen.storyboard)
|
||||
endif()
|
||||
|
||||
|
||||
enable_language(OBJC)
|
||||
@@ -10,13 +24,23 @@ enable_language(Swift)
|
||||
find_package(Qt6 REQUIRED COMPONENTS ShaderTools)
|
||||
set(LIBS ${LIBS} Qt6::ShaderTools)
|
||||
|
||||
find_library(FW_AUTHENTICATIONSERVICES AuthenticationServices)
|
||||
find_library(FW_UIKIT UIKit)
|
||||
find_library(FW_AVFOUNDATION AVFoundation)
|
||||
find_library(FW_FOUNDATION Foundation)
|
||||
find_library(FW_STOREKIT StoreKit)
|
||||
find_library(FW_USERNOTIFICATIONS UserNotifications)
|
||||
find_library(FW_NETWORKEXTENSION NetworkExtension)
|
||||
if(AMNEZIA_IOS_APPLETV)
|
||||
# Use framework linker flags directly for tvOS to avoid iPhoneOS SDK absolute paths.
|
||||
set(FW_AUTHENTICATIONSERVICES "-framework AuthenticationServices")
|
||||
set(FW_UIKIT "-framework UIKit")
|
||||
set(FW_AVFOUNDATION "-framework AVFoundation")
|
||||
set(FW_FOUNDATION "-framework Foundation")
|
||||
set(FW_STOREKIT "-framework StoreKit")
|
||||
set(FW_USERNOTIFICATIONS "-framework UserNotifications")
|
||||
else()
|
||||
find_library(FW_AUTHENTICATIONSERVICES AuthenticationServices)
|
||||
find_library(FW_UIKIT UIKit)
|
||||
find_library(FW_AVFOUNDATION AVFoundation)
|
||||
find_library(FW_FOUNDATION Foundation)
|
||||
find_library(FW_STOREKIT StoreKit)
|
||||
find_library(FW_USERNOTIFICATIONS UserNotifications)
|
||||
find_library(FW_NETWORKEXTENSION NetworkExtension)
|
||||
endif()
|
||||
|
||||
set(LIBS ${LIBS}
|
||||
${FW_AUTHENTICATIONSERVICES}
|
||||
@@ -25,9 +49,12 @@ set(LIBS ${LIBS}
|
||||
${FW_FOUNDATION}
|
||||
${FW_STOREKIT}
|
||||
${FW_USERNOTIFICATIONS}
|
||||
${FW_NETWORKEXTENSION}
|
||||
)
|
||||
|
||||
if(NOT AMNEZIA_IOS_APPLETV)
|
||||
set(LIBS ${LIBS} ${FW_NETWORKEXTENSION})
|
||||
endif()
|
||||
|
||||
|
||||
set(HEADERS ${HEADERS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/ios_controller.h
|
||||
@@ -57,7 +84,7 @@ target_include_directories(${PROJECT} PRIVATE ${Qt6Gui_PRIVATE_INCLUDE_DIRS})
|
||||
|
||||
set_target_properties(${PROJECT} PROPERTIES
|
||||
XCODE_LINK_BUILD_PHASE_MODE KNOWN_LOCATION
|
||||
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/ios/app/Info.plist.in
|
||||
MACOSX_BUNDLE_INFO_PLIST ${IOS_INFO_PLIST}
|
||||
MACOSX_BUNDLE_ICON_FILE "AppIcon"
|
||||
MACOSX_BUNDLE_INFO_STRING "AmneziaVPN"
|
||||
MACOSX_BUNDLE_BUNDLE_NAME "AmneziaVPN"
|
||||
@@ -66,7 +93,6 @@ set_target_properties(${PROJECT} PROPERTIES
|
||||
MACOSX_BUNDLE_LONG_VERSION_STRING "${APPLE_PROJECT_VERSION}-${CMAKE_PROJECT_VERSION_TWEAK}"
|
||||
MACOSX_BUNDLE_SHORT_VERSION_STRING "${APPLE_PROJECT_VERSION}"
|
||||
XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "${BUILD_IOS_APP_IDENTIFIER}"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CMAKE_CURRENT_SOURCE_DIR}/ios/app/main.entitlements"
|
||||
XCODE_ATTRIBUTE_MARKETING_VERSION "${APPLE_PROJECT_VERSION}"
|
||||
XCODE_ATTRIBUTE_CURRENT_PROJECT_VERSION "${CMAKE_PROJECT_VERSION_TWEAK}"
|
||||
XCODE_ATTRIBUTE_PRODUCT_NAME "AmneziaVPN"
|
||||
@@ -74,13 +100,36 @@ set_target_properties(${PROJECT} PROPERTIES
|
||||
XCODE_GENERATE_SCHEME TRUE
|
||||
XCODE_ATTRIBUTE_ENABLE_BITCODE "NO"
|
||||
XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME "AppIcon"
|
||||
XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "1,2"
|
||||
XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY ON
|
||||
XCODE_LINK_BUILD_PHASE_MODE KNOWN_LOCATION
|
||||
XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/Frameworks"
|
||||
XCODE_EMBED_APP_EXTENSIONS networkextension
|
||||
)
|
||||
|
||||
if(AMNEZIA_IOS_APPLETV)
|
||||
set_target_properties(${PROJECT} PROPERTIES
|
||||
XCODE_ATTRIBUTE_SUPPORTED_PLATFORMS "appletvos appletvsimulator"
|
||||
XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "3"
|
||||
XCODE_ATTRIBUTE_TVOS_DEPLOYMENT_TARGET "${CMAKE_OSX_DEPLOYMENT_TARGET}"
|
||||
XCODE_ATTRIBUTE_SDKROOT "appletvos"
|
||||
XCODE_ATTRIBUTE_SDKROOT[sdk=appletvos*] "appletvos"
|
||||
XCODE_ATTRIBUTE_SDKROOT[sdk=appletvsimulator*] "appletvsimulator"
|
||||
XCODE_ATTRIBUTE_LIBRARY_SEARCH_PATHS "$(inherited) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)"
|
||||
XCODE_ATTRIBUTE_LIBRARY_SEARCH_PATHS[sdk=appletvos*] "$(inherited) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)"
|
||||
XCODE_ATTRIBUTE_LIBRARY_SEARCH_PATHS[sdk=appletvsimulator*] "$(inherited) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)"
|
||||
XCODE_ATTRIBUTE_EXCLUDED_LIBRARY_SEARCH_PATHS "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS*.sdk/usr/lib/swift"
|
||||
XCODE_ATTRIBUTE_EXCLUDED_FRAMEWORK_SEARCH_PATHS "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS*.sdk/System/Library/Frameworks"
|
||||
)
|
||||
set_target_properties(${PROJECT} PROPERTIES
|
||||
QT_IOS_PERMISSIONS ""
|
||||
)
|
||||
else()
|
||||
set_target_properties(${PROJECT} PROPERTIES
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CMAKE_CURRENT_SOURCE_DIR}/ios/app/main.entitlements"
|
||||
XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "1,2"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(DEFINED DEPLOY)
|
||||
set_target_properties(${PROJECT} PROPERTIES
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Apple Distribution"
|
||||
@@ -111,6 +160,59 @@ target_compile_options(${PROJECT} PRIVATE
|
||||
-DVPN_NE_BUNDLEID=\"${BUILD_IOS_APP_IDENTIFIER}.network-extension\"
|
||||
)
|
||||
|
||||
if(AMNEZIA_IOS_APPLETV)
|
||||
# qscnetworkreachability plugin links IOKit, which is unavailable on tvOS.
|
||||
qt_import_plugins(${PROJECT}
|
||||
NO_DEFAULT
|
||||
INCLUDE
|
||||
QIOSIntegrationPlugin
|
||||
QJpegPlugin
|
||||
QSvgPlugin
|
||||
QGifPlugin
|
||||
QICOPlugin
|
||||
QSvgIconPlugin
|
||||
QSecureTransportBackendPlugin
|
||||
EXCLUDE
|
||||
QSCNetworkReachabilityNetworkInformationPlugin
|
||||
QDarwinCameraPermissionPlugin
|
||||
)
|
||||
|
||||
# Static tvOS Qt build doesn't auto-link these plugin archives into the
|
||||
# Xcode target, but the app entry point lives in QIOSIntegrationPlugin.
|
||||
set(_amnezia_tvos_static_plugins
|
||||
Qt6::QIOSIntegrationPlugin
|
||||
Qt6::QIOSIntegrationPlugin_init
|
||||
Qt6::QJpegPlugin
|
||||
Qt6::QJpegPlugin_init
|
||||
Qt6::QSvgPlugin
|
||||
Qt6::QSvgPlugin_init
|
||||
Qt6::QGifPlugin
|
||||
Qt6::QGifPlugin_init
|
||||
Qt6::QICOPlugin
|
||||
Qt6::QICOPlugin_init
|
||||
Qt6::QSvgIconPlugin
|
||||
Qt6::QSvgIconPlugin_init
|
||||
Qt6::QSecureTransportBackendPlugin
|
||||
Qt6::QSecureTransportBackendPlugin_init
|
||||
)
|
||||
foreach(_amnezia_tvos_static_plugin IN LISTS _amnezia_tvos_static_plugins)
|
||||
if(TARGET ${_amnezia_tvos_static_plugin})
|
||||
target_link_libraries(${PROJECT} PRIVATE ${_amnezia_tvos_static_plugin})
|
||||
endif()
|
||||
endforeach()
|
||||
unset(_amnezia_tvos_static_plugin)
|
||||
unset(_amnezia_tvos_static_plugins)
|
||||
|
||||
# Qt 6.9.2 iOS package links IOKit via Qt6::Core interface, but tvOS SDK
|
||||
# does not provide IOKit. Strip this single framework for Apple TV builds.
|
||||
get_target_property(_qtcore_iface_libs Qt6::Core INTERFACE_LINK_LIBRARIES)
|
||||
if(_qtcore_iface_libs)
|
||||
string(REPLACE "-framework IOKit;" "" _qtcore_iface_libs "${_qtcore_iface_libs}")
|
||||
string(REPLACE ";-framework IOKit" "" _qtcore_iface_libs "${_qtcore_iface_libs}")
|
||||
set_property(TARGET Qt6::Core PROPERTY INTERFACE_LINK_LIBRARIES "${_qtcore_iface_libs}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(WG_APPLE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/3rd/amneziawg-apple/Sources)
|
||||
|
||||
target_sources(${PROJECT} PRIVATE
|
||||
@@ -123,25 +225,38 @@ target_sources(${PROJECT} PRIVATE
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/VPNCController.swift
|
||||
)
|
||||
|
||||
target_sources(${PROJECT} PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/AmneziaVPNLaunchScreen.storyboard
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/Media.xcassets
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/PrivacyInfo.xcprivacy
|
||||
)
|
||||
if(IOS_LAUNCHSCREEN_STORYBOARD)
|
||||
target_sources(${PROJECT} PRIVATE
|
||||
${IOS_LAUNCHSCREEN_STORYBOARD}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/Media.xcassets
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/PrivacyInfo.xcprivacy
|
||||
)
|
||||
|
||||
set_property(TARGET ${PROJECT} APPEND PROPERTY RESOURCE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/AmneziaVPNLaunchScreen.storyboard
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/Media.xcassets
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/PrivacyInfo.xcprivacy
|
||||
)
|
||||
set_property(TARGET ${PROJECT} APPEND PROPERTY RESOURCE
|
||||
${IOS_LAUNCHSCREEN_STORYBOARD}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/Media.xcassets
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/PrivacyInfo.xcprivacy
|
||||
)
|
||||
else()
|
||||
target_sources(${PROJECT} PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/Media.xcassets
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/PrivacyInfo.xcprivacy
|
||||
)
|
||||
|
||||
set_property(TARGET ${PROJECT} APPEND PROPERTY RESOURCE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/Media.xcassets
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/PrivacyInfo.xcprivacy
|
||||
)
|
||||
endif()
|
||||
|
||||
add_subdirectory(ios/networkextension)
|
||||
add_dependencies(${PROJECT} networkextension)
|
||||
|
||||
set_property(TARGET ${PROJECT} PROPERTY XCODE_EMBED_FRAMEWORKS
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/apple/OpenVPNAdapter-ios/OpenVPNAdapter.framework"
|
||||
)
|
||||
|
||||
set(CMAKE_XCODE_ATTRIBUTE_FRAMEWORK_SEARCH_PATHS ${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/apple/OpenVPNAdapter-ios/)
|
||||
target_link_libraries("networkextension" PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/apple/OpenVPNAdapter-ios/OpenVPNAdapter.framework")
|
||||
if(NOT AMNEZIA_IOS_APPLETV)
|
||||
set_property(TARGET ${PROJECT} PROPERTY XCODE_EMBED_FRAMEWORKS
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/apple/OpenVPNAdapter-ios/OpenVPNAdapter.framework"
|
||||
)
|
||||
|
||||
set(CMAKE_XCODE_ATTRIBUTE_FRAMEWORK_SEARCH_PATHS ${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/apple/OpenVPNAdapter-ios/)
|
||||
target_link_libraries("networkextension" PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/apple/OpenVPNAdapter-ios/OpenVPNAdapter.framework")
|
||||
endif()
|
||||
|
||||
@@ -39,7 +39,7 @@ set(HEADERS ${HEADERS}
|
||||
${CLIENT_ROOT_DIR}/mozilla/controllerimpl.h
|
||||
)
|
||||
|
||||
if(NOT IOS AND NOT MACOS_NE)
|
||||
if(NOT IOS AND NOT MACOS_NE AND NOT CMAKE_SYSTEM_NAME STREQUAL "tvOS")
|
||||
set(HEADERS ${HEADERS}
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/QRCodeReaderBase.h
|
||||
)
|
||||
@@ -89,14 +89,14 @@ set(SOURCES ${SOURCES}
|
||||
${CLIENT_ROOT_DIR}/mozilla/shared/leakdetector.cpp
|
||||
)
|
||||
|
||||
if(NOT IOS AND NOT MACOS_NE)
|
||||
if(NOT IOS AND NOT MACOS_NE AND NOT CMAKE_SYSTEM_NAME STREQUAL "tvOS")
|
||||
set(SOURCES ${SOURCES}
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/QRCodeReaderBase.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
# Include native macOS platform helpers (dock/status-item)
|
||||
if(APPLE AND NOT IOS)
|
||||
if(APPLE AND NOT IOS AND NOT CMAKE_SYSTEM_NAME STREQUAL "tvOS")
|
||||
list(APPEND HEADERS
|
||||
${CLIENT_ROOT_DIR}/platforms/macos/macosutils.h
|
||||
${CLIENT_ROOT_DIR}/platforms/macos/macosstatusicon.h
|
||||
@@ -175,7 +175,7 @@ if(WIN32)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WIN32 OR (APPLE AND NOT IOS AND NOT MACOS_NE) OR (LINUX AND NOT ANDROID))
|
||||
if(WIN32 OR (APPLE AND NOT IOS AND NOT MACOS_NE AND NOT CMAKE_SYSTEM_NAME STREQUAL "tvOS") OR (LINUX AND NOT ANDROID))
|
||||
message("Client desktop build")
|
||||
add_compile_definitions(AMNEZIA_DESKTOP)
|
||||
|
||||
|
||||
@@ -1,17 +1,13 @@
|
||||
#include "openvpn_configurator.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QCoreApplication>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QProcess>
|
||||
#include <QString>
|
||||
#include <QTemporaryDir>
|
||||
#include <QTemporaryFile>
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
||||
#include <QGuiApplication>
|
||||
#else
|
||||
#include <QApplication>
|
||||
#endif
|
||||
|
||||
#include "core/networkUtilities.h"
|
||||
#include "containers/containers_defs.h"
|
||||
@@ -165,7 +161,7 @@ QString OpenVpnConfigurator::processConfigWithLocalSettings(const QPair<QString,
|
||||
QString dnsConf = QString("\nscript-security 2\n"
|
||||
"up %1/update-resolv-conf.sh\n"
|
||||
"down %1/update-resolv-conf.sh\n")
|
||||
.arg(qApp->applicationDirPath());
|
||||
.arg(QCoreApplication::applicationDirPath());
|
||||
|
||||
config.append(dnsConf);
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "ssh_configurator.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QCoreApplication>
|
||||
#include <QObject>
|
||||
#include <QProcess>
|
||||
#include <QString>
|
||||
@@ -8,11 +9,6 @@
|
||||
#include <QTemporaryFile>
|
||||
#include <QThread>
|
||||
#include <qtimer.h>
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) || defined(MACOS_NE)
|
||||
#include <QGuiApplication>
|
||||
#else
|
||||
#include <QApplication>
|
||||
#endif
|
||||
|
||||
#include "core/server_defs.h"
|
||||
#include "utilities.h"
|
||||
@@ -24,7 +20,7 @@ SshConfigurator::SshConfigurator(std::shared_ptr<Settings> settings, const QShar
|
||||
|
||||
QString SshConfigurator::convertOpenSShKey(const QString &key)
|
||||
{
|
||||
#if !defined(Q_OS_IOS) && !defined(MACOS_NE)
|
||||
#if !defined(Q_OS_IOS) && !defined(Q_OS_TVOS) && !defined(MACOS_NE)
|
||||
QProcess p;
|
||||
p.setProcessChannelMode(QProcess::MergedChannels);
|
||||
|
||||
@@ -70,13 +66,13 @@ QString SshConfigurator::convertOpenSShKey(const QString &key)
|
||||
// DEAD CODE.
|
||||
void SshConfigurator::openSshTerminal(const ServerCredentials &credentials)
|
||||
{
|
||||
#if !defined(Q_OS_IOS) && !defined(MACOS_NE)
|
||||
#if !defined(Q_OS_IOS) && !defined(Q_OS_TVOS) && !defined(MACOS_NE)
|
||||
QProcess *p = new QProcess();
|
||||
p->setProcessChannelMode(QProcess::SeparateChannels);
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
p->setProcessEnvironment(prepareEnv());
|
||||
p->setProgram(qApp->applicationDirPath() + "\\cygwin\\putty.exe");
|
||||
p->setProgram(QCoreApplication::applicationDirPath() + "\\cygwin\\putty.exe");
|
||||
|
||||
if (credentials.secretData.contains("PRIVATE KEY")) {
|
||||
// todo: connect by key
|
||||
@@ -100,10 +96,10 @@ QProcessEnvironment SshConfigurator::prepareEnv()
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
pathEnvVar.clear();
|
||||
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "\\cygwin;");
|
||||
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "\\openvpn;");
|
||||
pathEnvVar.prepend(QDir::toNativeSeparators(QCoreApplication::applicationDirPath()) + "\\cygwin;");
|
||||
pathEnvVar.prepend(QDir::toNativeSeparators(QCoreApplication::applicationDirPath()) + "\\openvpn;");
|
||||
#elif defined(Q_OS_MACX) && !defined(MACOS_NE)
|
||||
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "/Contents/MacOS");
|
||||
pathEnvVar.prepend(QDir::toNativeSeparators(QCoreApplication::applicationDirPath()) + "/Contents/MacOS");
|
||||
#endif
|
||||
|
||||
env.insert("PATH", pathEnvVar);
|
||||
|
||||
@@ -127,7 +127,8 @@ QMap<DockerContainer, QString> ContainerProps::containerDescriptions()
|
||||
QObject::tr("WireGuard - popular VPN protocol with high performance, high speed and low power "
|
||||
"consumption.") },
|
||||
{ DockerContainer::Awg,
|
||||
QObject::tr("AmneziaWG Legacy is a outdated version of AmneziaWG protocol. To upgrade, install AmneziaWG and recreate users.") },
|
||||
QObject::tr("AmneziaWG is a special protocol from Amnezia based on WireGuard. "
|
||||
"It provides high connection speed and ensures stable operation even in the most challenging network conditions.") },
|
||||
{ DockerContainer::Awg2,
|
||||
QObject::tr("AmneziaWG is a special protocol from Amnezia based on WireGuard. "
|
||||
"It provides high connection speed and ensures stable operation even in the most challenging network conditions.") },
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include "platforms/android/android_controller.h"
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_IOS)
|
||||
#if defined(Q_OS_IOS) || defined(Q_OS_TVOS)
|
||||
#include "platforms/ios/ios_controller.h"
|
||||
#include <AmneziaVPN-Swift.h>
|
||||
#endif
|
||||
@@ -154,9 +154,6 @@ void CoreController::initControllers()
|
||||
m_apiConfigsController.reset(new ApiConfigsController(m_serversModel, m_apiServicesModel, m_settings));
|
||||
m_engine->rootContext()->setContextProperty("ApiConfigsController", m_apiConfigsController.get());
|
||||
|
||||
m_apiPremV1MigrationController.reset(new ApiPremV1MigrationController(m_serversModel, m_settings, this));
|
||||
m_engine->rootContext()->setContextProperty("ApiPremV1MigrationController", m_apiPremV1MigrationController.get());
|
||||
|
||||
m_apiNewsController.reset(new ApiNewsController(m_newsModel, m_settings, m_serversModel, this));
|
||||
m_engine->rootContext()->setContextProperty("ApiNewsController", m_apiNewsController.get());
|
||||
}
|
||||
@@ -199,7 +196,7 @@ void CoreController::initAndroidController()
|
||||
|
||||
void CoreController::initAppleController()
|
||||
{
|
||||
#ifdef Q_OS_IOS
|
||||
#if defined(Q_OS_IOS) || defined(Q_OS_TVOS)
|
||||
IosController::Instance()->initialize();
|
||||
connect(IosController::Instance(), &IosController::importConfigFromOutside, this, [this](QString data) {
|
||||
emit m_pageController->goToPageHome();
|
||||
@@ -231,14 +228,12 @@ void CoreController::initSignalHandlers()
|
||||
initAutoConnectHandler();
|
||||
initAmneziaDnsToggledHandler();
|
||||
initPrepareConfigHandler();
|
||||
initImportPremiumV2VpnKeyHandler();
|
||||
initShowMigrationDrawerHandler();
|
||||
initStrictKillSwitchHandler();
|
||||
}
|
||||
|
||||
void CoreController::initNotificationHandler()
|
||||
{
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(Q_OS_TVOS)
|
||||
m_notificationHandler.reset(NotificationHandler::create(nullptr));
|
||||
|
||||
connect(m_vpnConnection.get(), &VpnConnection::connectionStateChanged, m_notificationHandler.get(),
|
||||
@@ -253,7 +248,7 @@ void CoreController::initNotificationHandler()
|
||||
|
||||
auto* trayHandler = qobject_cast<SystemTrayNotificationHandler*>(m_notificationHandler.get());
|
||||
connect(this, &CoreController::websiteUrlChanged, trayHandler, &SystemTrayNotificationHandler::updateWebsiteUrl);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void CoreController::updateTranslator(const QLocale &locale)
|
||||
@@ -382,25 +377,6 @@ void CoreController::initPrepareConfigHandler()
|
||||
});
|
||||
}
|
||||
|
||||
void CoreController::initImportPremiumV2VpnKeyHandler()
|
||||
{
|
||||
connect(m_apiPremV1MigrationController.get(), &ApiPremV1MigrationController::importPremiumV2VpnKey, this, [this](const QString &vpnKey) {
|
||||
m_importController->extractConfigFromData(vpnKey);
|
||||
m_importController->importConfig();
|
||||
|
||||
emit m_apiPremV1MigrationController->migrationFinished();
|
||||
});
|
||||
}
|
||||
|
||||
void CoreController::initShowMigrationDrawerHandler()
|
||||
{
|
||||
QTimer::singleShot(1000, this, [this]() {
|
||||
if (m_apiPremV1MigrationController->isPremV1MigrationReminderActive() && m_apiPremV1MigrationController->hasConfigsToMigration()) {
|
||||
m_apiPremV1MigrationController->showMigrationDrawer();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void CoreController::initStrictKillSwitchHandler()
|
||||
{
|
||||
connect(m_settingsController.get(), &SettingsController::strictKillSwitchEnabledChanged, m_vpnConnection.get(),
|
||||
|
||||
@@ -5,13 +5,12 @@
|
||||
#include <QQmlContext>
|
||||
#include <QThread>
|
||||
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(Q_OS_TVOS)
|
||||
#include "ui/systemtray_notificationhandler.h"
|
||||
#endif
|
||||
|
||||
#include "ui/controllers/api/apiConfigsController.h"
|
||||
#include "ui/controllers/api/apiSettingsController.h"
|
||||
#include "ui/controllers/api/apiPremV1MigrationController.h"
|
||||
#include "ui/controllers/api/apiNewsController.h"
|
||||
#include "ui/controllers/appSplitTunnelingController.h"
|
||||
#include "ui/controllers/allowedDnsController.h"
|
||||
@@ -50,7 +49,7 @@
|
||||
#include "ui/models/sites_model.h"
|
||||
#include "ui/models/newsModel.h"
|
||||
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(Q_OS_TVOS)
|
||||
#include "ui/notificationhandler.h"
|
||||
#endif
|
||||
|
||||
@@ -93,8 +92,6 @@ private:
|
||||
void initAutoConnectHandler();
|
||||
void initAmneziaDnsToggledHandler();
|
||||
void initPrepareConfigHandler();
|
||||
void initImportPremiumV2VpnKeyHandler();
|
||||
void initShowMigrationDrawerHandler();
|
||||
void initStrictKillSwitchHandler();
|
||||
|
||||
QQmlApplicationEngine *m_engine {}; // TODO use parent child system here?
|
||||
@@ -102,7 +99,7 @@ private:
|
||||
QSharedPointer<VpnConnection> m_vpnConnection;
|
||||
QSharedPointer<QTranslator> m_translator;
|
||||
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(Q_OS_TVOS)
|
||||
QScopedPointer<NotificationHandler> m_notificationHandler;
|
||||
#endif
|
||||
|
||||
@@ -122,7 +119,6 @@ private:
|
||||
|
||||
QScopedPointer<ApiSettingsController> m_apiSettingsController;
|
||||
QScopedPointer<ApiConfigsController> m_apiConfigsController;
|
||||
QScopedPointer<ApiPremV1MigrationController> m_apiPremV1MigrationController;
|
||||
QScopedPointer<ApiNewsController> m_apiNewsController;
|
||||
|
||||
QSharedPointer<ContainersModel> m_containersModel;
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#if defined(Q_OS_MAC) && !defined(Q_OS_IOS) && !defined(MACOS_NE)
|
||||
#if defined(Q_OS_MAC) && !defined(Q_OS_IOS) && !defined(Q_OS_TVOS) && !defined(MACOS_NE)
|
||||
#include <sys/param.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/socket.h>
|
||||
@@ -404,7 +404,7 @@ QPair<QString, QNetworkInterface> NetworkUtilities::getGatewayAndIface()
|
||||
close(sock);
|
||||
return { gateway_address, QNetworkInterface::interfaceFromName(interface) };
|
||||
#endif
|
||||
#if defined(Q_OS_MAC) && !defined(Q_OS_IOS) && !defined(MACOS_NE)
|
||||
#if defined(Q_OS_MAC) && !defined(Q_OS_IOS) && !defined(Q_OS_TVOS) && !defined(MACOS_NE)
|
||||
QString gateway;
|
||||
int index = -1;
|
||||
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleAllowMixedLocalizations</key>
|
||||
<true/>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>${QT_INTERNAL_DOLLAR_VAR}{PRODUCT_NAME}</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false/>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array/>
|
||||
<key>UIRequiresFullScreen</key>
|
||||
<true/>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>AmneziaVPNLaunchScreen</string>
|
||||
<key>UIUserInterfaceStyle</key>
|
||||
<string>Light</string>
|
||||
<key>com.wireguard.ios.app_group_id</key>
|
||||
<string>group.org.amnezia.AmneziaVPN</string>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<false/>
|
||||
<key>NSAllowsLocalNetworking</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder.AppleTV.Storyboard" version="3.0" toolsVersion="13122.16" targetRuntime="AppleTV" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<scene sceneID="tne-QT-ifu">
|
||||
<objects>
|
||||
<viewController id="BYZ-38-t0r" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
|
||||
<rect key="frame" x="0.0" y="0.0" width="1920" height="1080"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<viewLayoutGuide key="safeArea" id="wu6-TO-1qx"/>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
||||
@@ -1,6 +1,13 @@
|
||||
enable_language(Swift)
|
||||
|
||||
set(CLIENT_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
|
||||
set(AMNEZIA_IOS_APPLETV ${AMNEZIA_IOS_ENABLE_APPLETV_TARGET})
|
||||
|
||||
if(AMNEZIA_IOS_APPLETV)
|
||||
message("Network Extension tvOS mode is ON")
|
||||
else()
|
||||
message("Network Extension tvOS mode is OFF")
|
||||
endif()
|
||||
|
||||
add_executable(networkextension)
|
||||
set_target_properties(networkextension PROPERTIES
|
||||
@@ -28,6 +35,23 @@ set_target_properties(networkextension PROPERTIES
|
||||
XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/../../Frameworks"
|
||||
)
|
||||
|
||||
if(AMNEZIA_IOS_APPLETV)
|
||||
set_target_properties(networkextension PROPERTIES
|
||||
XCODE_ATTRIBUTE_SUPPORTED_PLATFORMS "appletvos appletvsimulator"
|
||||
XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "3"
|
||||
XCODE_ATTRIBUTE_TVOS_DEPLOYMENT_TARGET "${CMAKE_OSX_DEPLOYMENT_TARGET}"
|
||||
XCODE_ATTRIBUTE_SDKROOT "appletvos"
|
||||
XCODE_ATTRIBUTE_SDKROOT[sdk=appletvos*] "appletvos"
|
||||
XCODE_ATTRIBUTE_SDKROOT[sdk=appletvsimulator*] "appletvsimulator"
|
||||
XCODE_ATTRIBUTE_LIBRARY_SEARCH_PATHS "$(inherited) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)"
|
||||
XCODE_ATTRIBUTE_LIBRARY_SEARCH_PATHS[sdk=appletvos*] "$(inherited) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)"
|
||||
XCODE_ATTRIBUTE_LIBRARY_SEARCH_PATHS[sdk=appletvsimulator*] "$(inherited) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)"
|
||||
XCODE_ATTRIBUTE_EXCLUDED_LIBRARY_SEARCH_PATHS "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS*.sdk/usr/lib/swift"
|
||||
XCODE_ATTRIBUTE_EXCLUDED_FRAMEWORK_SEARCH_PATHS "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS*.sdk/System/Library/Frameworks"
|
||||
LINKER_LANGUAGE Swift
|
||||
)
|
||||
endif()
|
||||
|
||||
if(DEPLOY)
|
||||
set_target_properties(networkextension PROPERTIES
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Apple Distribution"
|
||||
@@ -45,38 +69,49 @@ endif()
|
||||
set_target_properties(networkextension PROPERTIES
|
||||
XCODE_ATTRIBUTE_SWIFT_VERSION "5.0"
|
||||
XCODE_ATTRIBUTE_CLANG_ENABLE_MODULES "YES"
|
||||
XCODE_ATTRIBUTE_SWIFT_OBJC_BRIDGING_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/WireGuardNetworkExtension-Bridging-Header.h"
|
||||
XCODE_ATTRIBUTE_SWIFT_OPTIMIZATION_LEVEL "-Onone"
|
||||
XCODE_ATTRIBUTE_SWIFT_PRECOMPILE_BRIDGING_HEADER "NO"
|
||||
)
|
||||
|
||||
set_target_properties(networkextension PROPERTIES
|
||||
XCODE_ATTRIBUTE_SWIFT_OBJC_BRIDGING_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/WireGuardNetworkExtension-Bridging-Header.h"
|
||||
)
|
||||
|
||||
set_target_properties("networkextension" PROPERTIES
|
||||
XCODE_ATTRIBUTE_DEVELOPMENT_TEAM "X7UJ388FXK"
|
||||
)
|
||||
|
||||
find_library(FW_ASSETS_LIBRARY AssetsLibrary)
|
||||
find_library(FW_MOBILE_CORE MobileCoreServices)
|
||||
find_library(FW_UI_KIT UIKit)
|
||||
find_library(FW_LIBRESOLV libresolv.9.tbd)
|
||||
|
||||
target_link_libraries(networkextension PRIVATE ${FW_ASSETS_LIBRARY})
|
||||
target_link_libraries(networkextension PRIVATE ${FW_MOBILE_CORE})
|
||||
target_link_libraries(networkextension PRIVATE ${FW_UI_KIT})
|
||||
target_link_libraries(networkextension PRIVATE ${FW_LIBRESOLV})
|
||||
if(NOT AMNEZIA_IOS_APPLETV)
|
||||
target_link_libraries(networkextension PRIVATE ${FW_UI_KIT})
|
||||
target_link_libraries(networkextension PRIVATE ${FW_LIBRESOLV})
|
||||
else()
|
||||
target_link_libraries(networkextension PRIVATE -lresolv)
|
||||
endif()
|
||||
|
||||
target_compile_options(networkextension PRIVATE -DGROUP_ID=\"${BUILD_IOS_GROUP_IDENTIFIER}\")
|
||||
target_compile_options(networkextension PRIVATE -DNETWORK_EXTENSION=1)
|
||||
|
||||
set(WG_APPLE_SOURCE_DIR ${CLIENT_ROOT_DIR}/3rd/amneziawg-apple/Sources)
|
||||
|
||||
target_sources(networkextension PRIVATE
|
||||
set(NE_COMMON_SOURCES
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/NELogController.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/Log.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/LogRecord.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider.swift
|
||||
)
|
||||
|
||||
set(NE_WIREGUARD_SOURCES
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/WireGuardAdapter.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/PacketTunnelSettingsGenerator.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/DNSResolver.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardNetworkExtension/ErrorNotifier.swift
|
||||
${WG_APPLE_SOURCE_DIR}/Shared/Keychain.swift
|
||||
${WG_APPLE_SOURCE_DIR}/Shared/Model/TunnelConfiguration+WgQuickConfig.swift
|
||||
${WG_APPLE_SOURCE_DIR}/Shared/FileManager+Extension.swift
|
||||
${WG_APPLE_SOURCE_DIR}/Shared/Model/NETunnelProviderProtocol+Extension.swift
|
||||
${WG_APPLE_SOURCE_DIR}/Shared/Model/TunnelConfiguration+WgQuickConfig.swift
|
||||
${WG_APPLE_SOURCE_DIR}/Shared/Model/String+ArrayConversion.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/TunnelConfiguration.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/IPAddressRange.swift
|
||||
@@ -84,24 +119,50 @@ target_sources(networkextension PRIVATE
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/DNSServer.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/InterfaceConfiguration.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/PeerConfiguration.swift
|
||||
${WG_APPLE_SOURCE_DIR}/Shared/FileManager+Extension.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKitC/x25519.c
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/Array+ConcurrentMap.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/IPAddress+AddrInfo.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/PrivateKey.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/HevSocksTunnel.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/NELogController.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/Log.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/LogRecord.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider+WireGuard.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider+OpenVPN.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider+Xray.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/WGConfig.swift
|
||||
)
|
||||
|
||||
set(NE_XRAY_SOURCES
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/HevSocksTunnel.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider+Xray.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/XrayConfig.swift
|
||||
)
|
||||
|
||||
set(NE_OPENVPN_SOURCES
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider+OpenVPN.swift
|
||||
)
|
||||
|
||||
set(NE_APPLE_GLUE_SOURCES
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/iosglue.mm
|
||||
)
|
||||
|
||||
if(AMNEZIA_IOS_APPLETV)
|
||||
list(APPEND NE_APPLE_GLUE_SOURCES
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/tvos_cgo_stubs.c
|
||||
)
|
||||
endif()
|
||||
|
||||
target_sources(networkextension PRIVATE ${NE_COMMON_SOURCES})
|
||||
|
||||
if(NOT AMNEZIA_IOS_APPLETV)
|
||||
target_sources(networkextension PRIVATE
|
||||
${NE_WIREGUARD_SOURCES}
|
||||
${NE_OPENVPN_SOURCES}
|
||||
${NE_XRAY_SOURCES}
|
||||
${NE_APPLE_GLUE_SOURCES}
|
||||
)
|
||||
else()
|
||||
target_sources(networkextension PRIVATE
|
||||
${NE_WIREGUARD_SOURCES}
|
||||
${NE_APPLE_GLUE_SOURCES}
|
||||
)
|
||||
endif()
|
||||
|
||||
target_sources(networkextension PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/PrivacyInfo.xcprivacy
|
||||
)
|
||||
@@ -113,7 +174,7 @@ set_property(TARGET networkextension APPEND PROPERTY RESOURCE
|
||||
## Build wireguard-go-version.h
|
||||
execute_process(
|
||||
COMMAND go list -m golang.zx2c4.com/wireguard
|
||||
WORKING_DIRECTORY ${CLIENT_ROOT_DIR}/3rd/wireguard-apple/Sources/WireGuardKitGo
|
||||
WORKING_DIRECTORY ${WG_APPLE_SOURCE_DIR}/WireGuardKitGo
|
||||
OUTPUT_VARIABLE WG_VERSION_FULL
|
||||
)
|
||||
string(REGEX REPLACE ".*v\([0-9.]*\).*" "\\1" WG_VERSION_STRING 1.1.1)
|
||||
@@ -122,9 +183,46 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/wireguard-go-version.h.in
|
||||
target_sources(networkextension PRIVATE
|
||||
${CMAKE_CURRENT_BINARY_DIR}/wireguard-go-version.h)
|
||||
|
||||
if(AMNEZIA_IOS_APPLETV)
|
||||
set(WG_TVOS_LIB_DIR ${CMAKE_CURRENT_BINARY_DIR}/WireGuardKitGo-appletvos)
|
||||
set(WG_TVOS_TMP_DIR ${CMAKE_CURRENT_BINARY_DIR}/WireGuardKitGo-appletvos-tmp)
|
||||
execute_process(
|
||||
COMMAND make clean
|
||||
WORKING_DIRECTORY ${WG_APPLE_SOURCE_DIR}/WireGuardKitGo
|
||||
OUTPUT_QUIET
|
||||
ERROR_QUIET
|
||||
)
|
||||
execute_process(
|
||||
COMMAND make build
|
||||
PLATFORM_NAME=appletvos
|
||||
GOOS_appletvos=ios
|
||||
GOFLAGS=-tags=netgo
|
||||
ARCHS=arm64
|
||||
DEPLOYMENT_TARGET_CLANG_FLAG_NAME=mtvos-version-min
|
||||
DEPLOYMENT_TARGET_CLANG_ENV_NAME=TVOS_DEPLOYMENT_TARGET
|
||||
TVOS_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}
|
||||
CONFIGURATION_BUILD_DIR=${WG_TVOS_LIB_DIR}
|
||||
CONFIGURATION_TEMP_DIR=${WG_TVOS_TMP_DIR}
|
||||
WORKING_DIRECTORY ${WG_APPLE_SOURCE_DIR}/WireGuardKitGo
|
||||
RESULT_VARIABLE WG_TVOS_BUILD_RESULT
|
||||
)
|
||||
if(NOT WG_TVOS_BUILD_RESULT EQUAL 0)
|
||||
message(FATAL_ERROR "Failed to build tvOS WireGuard Go bridge (libwg-go.a)")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_include_directories(networkextension PRIVATE ${CLIENT_ROOT_DIR})
|
||||
target_include_directories(networkextension PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
target_link_libraries(networkextension PRIVATE ${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/wireguard/ios/arm64/libwg-go.a)
|
||||
|
||||
target_link_libraries(networkextension PRIVATE ${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/xray/HevSocks5Tunnel.xcframework)
|
||||
if(NOT AMNEZIA_IOS_APPLETV)
|
||||
target_link_directories(networkextension PRIVATE
|
||||
${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/wireguard/ios/arm64
|
||||
)
|
||||
target_link_libraries(networkextension PRIVATE ${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/wireguard/ios/arm64/libwg-go.a)
|
||||
target_link_libraries(networkextension PRIVATE ${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/xray/HevSocks5Tunnel.xcframework)
|
||||
else()
|
||||
target_link_directories(networkextension PRIVATE
|
||||
${WG_TVOS_LIB_DIR}
|
||||
)
|
||||
target_link_libraries(networkextension PRIVATE ${WG_TVOS_LIB_DIR}/libwg-go.a)
|
||||
endif()
|
||||
|
||||
+3
-3
@@ -12,11 +12,11 @@
|
||||
#include "Windows.h"
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_IOS)
|
||||
#if defined(Q_OS_IOS) || defined(Q_OS_TVOS)
|
||||
#include "platforms/ios/QtAppDelegate-C-Interface.h"
|
||||
#endif
|
||||
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(MACOS_NE)
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(Q_OS_TVOS) && !defined(MACOS_NE)
|
||||
bool isAnotherInstanceRunning()
|
||||
{
|
||||
QLocalSocket socket;
|
||||
@@ -47,7 +47,7 @@ int main(int argc, char *argv[])
|
||||
AmneziaApplication app(argc, argv);
|
||||
OsSignalHandler::setup();
|
||||
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(MACOS_NE)
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(Q_OS_TVOS) && !defined(MACOS_NE)
|
||||
if (isAnotherInstanceRunning()) {
|
||||
QTimer::singleShot(1000, &app, [&]() { app.quit(); });
|
||||
return app.exec();
|
||||
|
||||
@@ -3,7 +3,9 @@ import NetworkExtension
|
||||
import Network
|
||||
import os
|
||||
import Darwin
|
||||
#if !os(tvOS)
|
||||
import OpenVPNAdapter
|
||||
#endif
|
||||
|
||||
enum TunnelProtoType: String {
|
||||
case wireguard, openvpn, xray
|
||||
@@ -38,8 +40,10 @@ struct Constants {
|
||||
|
||||
class PacketTunnelProvider: NEPacketTunnelProvider {
|
||||
var wgAdapter: WireGuardAdapter?
|
||||
#if !os(tvOS)
|
||||
var ovpnAdapter: OpenVPNAdapter?
|
||||
private lazy var openVPNPacketFlowAdapter = PacketTunnelFlowAdapter(flow: packetFlow)
|
||||
#endif
|
||||
private let pathMonitorQueue = DispatchQueue(label: Constants.processQueueName + ".path-monitor")
|
||||
private let pathMonitor = NWPathMonitor()
|
||||
private var didReceiveInitialPathUpdate = false
|
||||
@@ -49,7 +53,9 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
|
||||
var splitTunnelType: Int?
|
||||
var splitTunnelSites: [String]?
|
||||
|
||||
#if !os(tvOS)
|
||||
let vpnReachability = OpenVPNReachability()
|
||||
#endif
|
||||
|
||||
var startHandler: ((Error?) -> Void)?
|
||||
var stopHandler: (() -> Void)?
|
||||
@@ -57,9 +63,11 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
|
||||
|
||||
var activeIfaceIdx: UInt32 = 0
|
||||
|
||||
#if !os(tvOS)
|
||||
func openVPNPacketFlow() -> OpenVPNAdapterPacketFlow {
|
||||
openVPNPacketFlowAdapter
|
||||
}
|
||||
#endif
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
@@ -206,9 +214,21 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
|
||||
errorNotifier: errorNotifier,
|
||||
completionHandler: completionHandler)
|
||||
case .openvpn:
|
||||
#if os(tvOS)
|
||||
completionHandler(NSError(domain: "org.amnezia.ne",
|
||||
code: -1002,
|
||||
userInfo: [NSLocalizedDescriptionKey: "OpenVPN backend is not available for tvOS in this build"]))
|
||||
#else
|
||||
startOpenVPN(completionHandler: completionHandler)
|
||||
#endif
|
||||
case .xray:
|
||||
#if os(tvOS)
|
||||
completionHandler(NSError(domain: "org.amnezia.ne",
|
||||
code: -1003,
|
||||
userInfo: [NSLocalizedDescriptionKey: "Xray backend is not available for tvOS in this build"]))
|
||||
#else
|
||||
startXray(completionHandler: completionHandler)
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
@@ -225,10 +245,18 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
|
||||
stopWireguard(with: reason,
|
||||
completionHandler: completionHandler)
|
||||
case .openvpn:
|
||||
#if os(tvOS)
|
||||
completionHandler()
|
||||
#else
|
||||
stopOpenVPN(with: reason,
|
||||
completionHandler: completionHandler)
|
||||
#endif
|
||||
case .xray:
|
||||
#if os(tvOS)
|
||||
completionHandler()
|
||||
#else
|
||||
stopXray(completionHandler: completionHandler)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,7 +270,11 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
|
||||
case .wireguard:
|
||||
handleWireguardStatusMessage(messageData, completionHandler: completionHandler)
|
||||
case .openvpn:
|
||||
#if !os(tvOS)
|
||||
handleOpenVPNStatusMessage(messageData, completionHandler: completionHandler)
|
||||
#else
|
||||
completionHandler?(nil)
|
||||
#endif
|
||||
case .xray:
|
||||
break;
|
||||
}
|
||||
@@ -260,7 +292,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
|
||||
|
||||
private func handle(networkChange changePath: Network.NWPath, completion: @escaping (Error?) -> Void) {
|
||||
updateActiveInterfaceIndex(for: changePath)
|
||||
wg_log(.info, message: "Tunnel restarted.")
|
||||
neLog(.info, message: "Tunnel restarted.")
|
||||
startTunnel(options: nil, completionHandler: completion)
|
||||
}
|
||||
}
|
||||
@@ -311,16 +343,17 @@ private extension PacketTunnelProvider {
|
||||
}
|
||||
|
||||
extension WireGuardLogLevel {
|
||||
var osLogLevel: OSLogType {
|
||||
switch self {
|
||||
case .verbose:
|
||||
return .debug
|
||||
case .error:
|
||||
return .error
|
||||
var osLogLevel: OSLogType {
|
||||
switch self {
|
||||
case .verbose:
|
||||
return .debug
|
||||
case .error:
|
||||
return .error
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if !os(tvOS)
|
||||
final class PacketTunnelFlowAdapter: NSObject, OpenVPNAdapterPacketFlow {
|
||||
private let flow: NEPacketTunnelFlow
|
||||
|
||||
@@ -339,6 +372,7 @@ final class PacketTunnelFlowAdapter: NSObject, OpenVPNAdapterPacketFlow {
|
||||
flow.writePackets(packets, withProtocols: protocols)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
extension NEProviderStopReason {
|
||||
var amneziaDescription: String {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#if !MACOS_NE
|
||||
#if !MACOS_NE && !TARGET_OS_TV
|
||||
#include "QRCodeReaderBase.h"
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@@ -959,6 +959,10 @@ void IosController::sendVpnExtensionMessage(NSDictionary* message, std::function
|
||||
}
|
||||
|
||||
bool IosController::shareText(const QStringList& filesToSend) {
|
||||
#if defined(Q_OS_TVOS)
|
||||
Q_UNUSED(filesToSend)
|
||||
return false;
|
||||
#else
|
||||
NSMutableArray *sharingItems = [NSMutableArray new];
|
||||
|
||||
for (int i = 0; i < filesToSend.size(); i++) {
|
||||
@@ -967,7 +971,7 @@ bool IosController::shareText(const QStringList& filesToSend) {
|
||||
}
|
||||
#if !MACOS_NE
|
||||
UIViewController *qtController = getViewController();
|
||||
if (!qtController) return;
|
||||
if (!qtController) return false;
|
||||
|
||||
UIActivityViewController *activityController = [[UIActivityViewController alloc] initWithActivityItems:sharingItems applicationActivities:nil];
|
||||
#endif
|
||||
@@ -991,23 +995,25 @@ bool IosController::shareText(const QStringList& filesToSend) {
|
||||
wait.exec();
|
||||
|
||||
return isAccepted;
|
||||
#endif
|
||||
}
|
||||
|
||||
QString IosController::openFile() {
|
||||
#if !MACOS_NE
|
||||
#if defined(Q_OS_TVOS)
|
||||
return QString();
|
||||
#elif !MACOS_NE
|
||||
UIDocumentPickerViewController *documentPicker = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:@[@"public.item"] inMode:UIDocumentPickerModeOpen];
|
||||
|
||||
DocumentPickerDelegate *documentPickerDelegate = [[DocumentPickerDelegate alloc] init];
|
||||
documentPicker.delegate = documentPickerDelegate;
|
||||
|
||||
UIViewController *qtController = getViewController();
|
||||
if (!qtController) return;
|
||||
if (!qtController) return QString();
|
||||
|
||||
[qtController presentViewController:documentPicker animated:YES completion:nil];
|
||||
|
||||
#endif
|
||||
__block QString filePath;
|
||||
#if !MACOS_NE
|
||||
#if !MACOS_NE && !defined(Q_OS_TVOS)
|
||||
documentPickerDelegate.documentPickerClosedCallback = ^(NSString *path) {
|
||||
if (path) {
|
||||
filePath = QString::fromUtf8(path.UTF8String);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#import <NetworkExtension/NetworkExtension.h>
|
||||
#import <NetworkExtension/NETunnelProviderSession.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
#include <TargetConditionals.h>
|
||||
|
||||
#if !MACOS_NE
|
||||
#include <UIKit/UIKit.h>
|
||||
@@ -21,7 +22,7 @@ class IosController;
|
||||
@end
|
||||
|
||||
typedef void (^DocumentPickerClosedCallback)(NSString *path);
|
||||
#if !MACOS_NE
|
||||
#if !MACOS_NE && !TARGET_OS_TV
|
||||
@interface DocumentPickerDelegate : NSObject <UIDocumentPickerDelegate>
|
||||
|
||||
@property (nonatomic, copy) DocumentPickerClosedCallback documentPickerClosedCallback;
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
@end
|
||||
|
||||
#if !MACOS_NE
|
||||
#if !MACOS_NE && !TARGET_OS_TV
|
||||
@implementation DocumentPickerDelegate
|
||||
|
||||
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray<NSURL *> *)urls {
|
||||
|
||||
@@ -7,6 +7,24 @@
|
||||
#import <UserNotifications/UserNotifications.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#if defined(Q_OS_TVOS)
|
||||
|
||||
IOSNotificationHandler::IOSNotificationHandler(QObject* parent) : NotificationHandler(parent) {}
|
||||
|
||||
IOSNotificationHandler::~IOSNotificationHandler() {}
|
||||
|
||||
void IOSNotificationHandler::notify(NotificationHandler::Message type,
|
||||
const QString& title,
|
||||
const QString& message,
|
||||
int timerMsec) {
|
||||
Q_UNUSED(type)
|
||||
Q_UNUSED(title)
|
||||
Q_UNUSED(message)
|
||||
Q_UNUSED(timerMsec)
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#if !MACOS_NE
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@@ -172,3 +190,5 @@ void IOSNotificationHandler::notify(NotificationHandler::Message type, const QSt
|
||||
}];
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // Q_OS_TVOS
|
||||
|
||||
@@ -190,7 +190,7 @@ namespace amnezia
|
||||
|
||||
constexpr char defaultPort[] = "51820";
|
||||
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) || defined(MACOS_NE)
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) || defined(Q_OS_TVOS) || defined(MACOS_NE)
|
||||
constexpr char defaultMtu[] = "1280";
|
||||
#else
|
||||
constexpr char defaultMtu[] = "1376";
|
||||
@@ -210,7 +210,7 @@ namespace amnezia
|
||||
namespace awg
|
||||
{
|
||||
constexpr char defaultPort[] = "55424";
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) || defined(MACOS_NE)
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) || defined(Q_OS_TVOS) || defined(MACOS_NE)
|
||||
constexpr char defaultMtu[] = "1280";
|
||||
#else
|
||||
constexpr char defaultMtu[] = "1376";
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "core/errorstrings.h"
|
||||
#include "vpnprotocol.h"
|
||||
|
||||
#if defined(Q_OS_WINDOWS) || defined(Q_OS_MACX) and !defined MACOS_NE || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
|
||||
#if defined(Q_OS_WINDOWS) || (defined(Q_OS_MACX) && !defined(Q_OS_IOS) && !defined(Q_OS_TVOS) && !defined(MACOS_NE)) || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
|
||||
#include "openvpnovercloakprotocol.h"
|
||||
#include "openvpnprotocol.h"
|
||||
#include "shadowsocksvpnprotocol.h"
|
||||
@@ -114,7 +114,7 @@ VpnProtocol *VpnProtocol::factory(DockerContainer container, const QJsonObject &
|
||||
#if defined(Q_OS_WINDOWS)
|
||||
case DockerContainer::Ipsec: return new Ikev2Protocol(configuration);
|
||||
#endif
|
||||
#if defined(Q_OS_WINDOWS) || defined(Q_OS_MACX) and !defined MACOS_NE || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
|
||||
#if defined(Q_OS_WINDOWS) || (defined(Q_OS_MACX) && !defined(Q_OS_IOS) && !defined(Q_OS_TVOS) && !defined(MACOS_NE)) || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
|
||||
case DockerContainer::OpenVpn: return new OpenVpnProtocol(configuration);
|
||||
case DockerContainer::Cloak: return new OpenVpnOverCloakProtocol(configuration);
|
||||
case DockerContainer::ShadowSocks: return new ShadowSocksVpnProtocol(configuration);
|
||||
|
||||
@@ -247,9 +247,6 @@
|
||||
<file>ui/qml/Pages2/PageSettingsApiNativeConfigs.qml</file>
|
||||
<file>ui/qml/Pages2/PageSettingsApiDevices.qml</file>
|
||||
<file>images/controls/monitor.svg</file>
|
||||
<file>ui/qml/Components/ApiPremV1MigrationDrawer.qml</file>
|
||||
<file>ui/qml/Components/ApiPremV1SubListDrawer.qml</file>
|
||||
<file>ui/qml/Components/OtpCodeDrawer.qml</file>
|
||||
<file>ui/qml/Components/AwgTextField.qml</file>
|
||||
<file>ui/qml/Pages2/PageSettingsApiSubscriptionKey.qml</file>
|
||||
<file>ui/qml/Components/SmartScroll.qml</file>
|
||||
|
||||
@@ -1,133 +0,0 @@
|
||||
#include "apiPremV1MigrationController.h"
|
||||
|
||||
#include <QEventLoop>
|
||||
#include <QTimer>
|
||||
|
||||
#include "core/api/apiDefs.h"
|
||||
#include "core/api/apiUtils.h"
|
||||
#include "core/controllers/gatewayController.h"
|
||||
|
||||
ApiPremV1MigrationController::ApiPremV1MigrationController(const QSharedPointer<ServersModel> &serversModel,
|
||||
const std::shared_ptr<Settings> &settings, QObject *parent)
|
||||
: QObject(parent), m_serversModel(serversModel), m_settings(settings)
|
||||
{
|
||||
}
|
||||
|
||||
bool ApiPremV1MigrationController::hasConfigsToMigration()
|
||||
{
|
||||
QJsonArray vpnKeys;
|
||||
|
||||
auto serversCount = m_serversModel->getServersCount();
|
||||
for (size_t i = 0; i < serversCount; i++) {
|
||||
auto serverConfigObject = m_serversModel->getServerConfig(i);
|
||||
|
||||
if (apiUtils::getConfigType(serverConfigObject) != apiDefs::ConfigType::AmneziaPremiumV1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
QString vpnKey = apiUtils::getPremiumV1VpnKey(serverConfigObject);
|
||||
vpnKeys.append(vpnKey);
|
||||
}
|
||||
|
||||
if (!vpnKeys.isEmpty()) {
|
||||
GatewayController gatewayController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv(), apiDefs::requestTimeoutMsecs,
|
||||
m_settings->isStrictKillSwitchEnabled());
|
||||
QJsonObject apiPayload;
|
||||
|
||||
apiPayload["configs"] = vpnKeys;
|
||||
QByteArray responseBody;
|
||||
ErrorCode errorCode = gatewayController.post(QString("%1v1/prem-v1/is-active-subscription"), apiPayload, responseBody);
|
||||
|
||||
auto migrationsStatus = QJsonDocument::fromJson(responseBody).object();
|
||||
for (const auto &migrationStatus : migrationsStatus) {
|
||||
if (migrationStatus == "not_found") {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ApiPremV1MigrationController::getSubscriptionList(const QString &email)
|
||||
{
|
||||
GatewayController gatewayController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv(), apiDefs::requestTimeoutMsecs,
|
||||
m_settings->isStrictKillSwitchEnabled());
|
||||
QJsonObject apiPayload;
|
||||
|
||||
apiPayload[apiDefs::key::email] = email;
|
||||
QByteArray responseBody;
|
||||
ErrorCode errorCode = gatewayController.post(QString("%1v1/prem-v1/subscription-list"), apiPayload, responseBody);
|
||||
|
||||
if (errorCode == ErrorCode::NoError) {
|
||||
m_email = email;
|
||||
m_subscriptionsModel = QJsonDocument::fromJson(responseBody).array();
|
||||
if (m_subscriptionsModel.isEmpty()) {
|
||||
emit noSubscriptionToMigrate();
|
||||
return;
|
||||
}
|
||||
|
||||
emit subscriptionsModelChanged();
|
||||
} else {
|
||||
emit errorOccurred(ErrorCode::ApiMigrationError);
|
||||
}
|
||||
}
|
||||
|
||||
QJsonArray ApiPremV1MigrationController::getSubscriptionModel()
|
||||
{
|
||||
return m_subscriptionsModel;
|
||||
}
|
||||
|
||||
void ApiPremV1MigrationController::sendMigrationCode(const int subscriptionIndex)
|
||||
{
|
||||
QEventLoop wait;
|
||||
QTimer::singleShot(1000, &wait, &QEventLoop::quit);
|
||||
wait.exec(QEventLoop::ExcludeUserInputEvents);
|
||||
|
||||
GatewayController gatewayController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv(), apiDefs::requestTimeoutMsecs,
|
||||
m_settings->isStrictKillSwitchEnabled());
|
||||
QJsonObject apiPayload;
|
||||
|
||||
apiPayload[apiDefs::key::email] = m_email;
|
||||
QByteArray responseBody;
|
||||
ErrorCode errorCode = gatewayController.post(QString("%1v1/prem-v1/migration-code"), apiPayload, responseBody);
|
||||
|
||||
if (errorCode == ErrorCode::NoError) {
|
||||
m_subscriptionIndex = subscriptionIndex;
|
||||
emit otpSuccessfullySent();
|
||||
} else {
|
||||
emit errorOccurred(ErrorCode::ApiMigrationError);
|
||||
}
|
||||
}
|
||||
|
||||
void ApiPremV1MigrationController::migrate(const QString &migrationCode)
|
||||
{
|
||||
GatewayController gatewayController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv(), apiDefs::requestTimeoutMsecs,
|
||||
m_settings->isStrictKillSwitchEnabled());
|
||||
QJsonObject apiPayload;
|
||||
|
||||
apiPayload[apiDefs::key::email] = m_email;
|
||||
apiPayload[apiDefs::key::orderId] = m_subscriptionsModel.at(m_subscriptionIndex).toObject().value(apiDefs::key::id).toString();
|
||||
apiPayload[apiDefs::key::migrationCode] = migrationCode;
|
||||
QByteArray responseBody;
|
||||
ErrorCode errorCode = gatewayController.post(QString("%1v1/prem-v1/migrate"), apiPayload, responseBody);
|
||||
|
||||
if (errorCode == ErrorCode::NoError) {
|
||||
auto responseObject = QJsonDocument::fromJson(responseBody).object();
|
||||
QString premiumV2VpnKey = responseObject.value(apiDefs::key::config).toString();
|
||||
|
||||
emit importPremiumV2VpnKey(premiumV2VpnKey);
|
||||
} else {
|
||||
emit errorOccurred(ErrorCode::ApiMigrationError);
|
||||
}
|
||||
}
|
||||
|
||||
bool ApiPremV1MigrationController::isPremV1MigrationReminderActive()
|
||||
{
|
||||
return m_settings->isPremV1MigrationReminderActive();
|
||||
}
|
||||
|
||||
void ApiPremV1MigrationController::disablePremV1MigrationReminder()
|
||||
{
|
||||
m_settings->disablePremV1MigrationReminder();
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
#ifndef APIPREMV1MIGRATIONCONTROLLER_H
|
||||
#define APIPREMV1MIGRATIONCONTROLLER_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "ui/models/servers_model.h"
|
||||
|
||||
class ApiPremV1MigrationController : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ApiPremV1MigrationController(const QSharedPointer<ServersModel> &serversModel, const std::shared_ptr<Settings> &settings,
|
||||
QObject *parent = nullptr);
|
||||
|
||||
Q_PROPERTY(QJsonArray subscriptionsModel READ getSubscriptionModel NOTIFY subscriptionsModelChanged)
|
||||
|
||||
public slots:
|
||||
bool hasConfigsToMigration();
|
||||
void getSubscriptionList(const QString &email);
|
||||
QJsonArray getSubscriptionModel();
|
||||
void sendMigrationCode(const int subscriptionIndex);
|
||||
void migrate(const QString &migrationCode);
|
||||
|
||||
bool isPremV1MigrationReminderActive();
|
||||
void disablePremV1MigrationReminder();
|
||||
|
||||
signals:
|
||||
void subscriptionsModelChanged();
|
||||
|
||||
void otpSuccessfullySent();
|
||||
|
||||
void importPremiumV2VpnKey(const QString &vpnKey);
|
||||
|
||||
void errorOccurred(ErrorCode errorCode);
|
||||
|
||||
void showMigrationDrawer();
|
||||
void migrationFinished();
|
||||
|
||||
void noSubscriptionToMigrate();
|
||||
|
||||
private:
|
||||
QSharedPointer<ServersModel> m_serversModel;
|
||||
std::shared_ptr<Settings> m_settings;
|
||||
|
||||
QJsonArray m_subscriptionsModel;
|
||||
int m_subscriptionIndex;
|
||||
QString m_email;
|
||||
};
|
||||
|
||||
#endif // APIPREMV1MIGRATIONCONTROLLER_H
|
||||
@@ -1,11 +1,5 @@
|
||||
#include "connectionController.h"
|
||||
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) || defined(MACOS_NE)
|
||||
#include <QGuiApplication>
|
||||
#else
|
||||
#include <QApplication>
|
||||
#endif
|
||||
|
||||
#include "utilities.h"
|
||||
#include "core/controllers/vpnConfigurationController.h"
|
||||
#include "version.h"
|
||||
@@ -33,7 +27,7 @@ ConnectionController::ConnectionController(const QSharedPointer<ServersModel> &s
|
||||
|
||||
void ConnectionController::openConnection()
|
||||
{
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(MACOS_NE)
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(Q_OS_TVOS) && !defined(MACOS_NE)
|
||||
if (!Utils::processIsRunning(Utils::executable(SERVICE_NAME, false), true))
|
||||
{
|
||||
emit connectionErrorOccurred(ErrorCode::AmneziaServiceNotRunning);
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#ifdef Q_OS_ANDROID
|
||||
#include "platforms/android/android_controller.h"
|
||||
#endif
|
||||
#if defined(Q_OS_IOS) || defined(MACOS_NE)
|
||||
#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) || defined(MACOS_NE)
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#endif
|
||||
|
||||
@@ -602,14 +602,14 @@ bool ImportController::decodeQrCode(const QString &code)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined Q_OS_ANDROID || defined Q_OS_IOS
|
||||
#if defined Q_OS_ANDROID || defined Q_OS_IOS || defined(Q_OS_TVOS)
|
||||
void ImportController::startDecodingQr()
|
||||
{
|
||||
m_qrCodeChunks.clear();
|
||||
m_totalQrCodeChunksCount = 0;
|
||||
m_receivedQrCodeChunksCount = 0;
|
||||
|
||||
#if defined(Q_OS_IOS) || defined(MACOS_NE)
|
||||
#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) || defined(MACOS_NE)
|
||||
m_isQrCodeProcessed = true;
|
||||
#endif
|
||||
#if defined Q_OS_ANDROID
|
||||
|
||||
@@ -38,7 +38,7 @@ public slots:
|
||||
QString getConfigFileName();
|
||||
QString getMaliciousWarningText();
|
||||
|
||||
#if defined Q_OS_ANDROID || defined Q_OS_IOS
|
||||
#if defined Q_OS_ANDROID || defined Q_OS_IOS || defined(Q_OS_TVOS)
|
||||
void startDecodingQr();
|
||||
bool parseQrCodeChunk(const QString &code);
|
||||
|
||||
@@ -70,7 +70,7 @@ private:
|
||||
|
||||
void processAmneziaConfig(QJsonObject &config);
|
||||
|
||||
#if defined Q_OS_ANDROID || defined Q_OS_IOS
|
||||
#if defined Q_OS_ANDROID || defined Q_OS_IOS || defined(Q_OS_TVOS)
|
||||
void stopDecodingQr();
|
||||
#endif
|
||||
|
||||
@@ -83,7 +83,7 @@ private:
|
||||
ConfigTypes m_configType;
|
||||
QString m_maliciousWarningText;
|
||||
|
||||
#if defined Q_OS_ANDROID || defined Q_OS_IOS
|
||||
#if defined Q_OS_ANDROID || defined Q_OS_IOS || defined(Q_OS_TVOS)
|
||||
QMap<int, QByteArray> m_qrCodeChunks;
|
||||
bool m_isQrCodeProcessed;
|
||||
int m_totalQrCodeChunksCount;
|
||||
|
||||
@@ -451,6 +451,13 @@ ErrorCode InstallController::getAlreadyInstalledContainers(const ServerCredentia
|
||||
containerConfig[config_key::transportPacketMagicHeader] =
|
||||
serverConfigMap.value(config_key::transportPacketMagicHeader);
|
||||
|
||||
// hack to parse i1-i5 from commented lines in server config
|
||||
containerConfig[config_key::specialJunk1] = serverConfigMap.value(QString("# ") + config_key::specialJunk1);
|
||||
containerConfig[config_key::specialJunk2] = serverConfigMap.value(QString("# ") + config_key::specialJunk2);
|
||||
containerConfig[config_key::specialJunk3] = serverConfigMap.value(QString("# ") + config_key::specialJunk3);
|
||||
containerConfig[config_key::specialJunk4] = serverConfigMap.value(QString("# ") + config_key::specialJunk4);
|
||||
containerConfig[config_key::specialJunk5] = serverConfigMap.value(QString("# ") + config_key::specialJunk5);
|
||||
|
||||
if (container == DockerContainer::Awg2) {
|
||||
containerConfig[config_key::protocolVersion] = "2";
|
||||
containerConfig[config_key::cookieReplyPacketJunkSize] =
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
#define INSTALLCONTROLLER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QProcess>
|
||||
#if !defined(Q_OS_IOS) && !defined(Q_OS_TVOS)
|
||||
#include <QProcess>
|
||||
#endif
|
||||
|
||||
#include "containers/containers_defs.h"
|
||||
#include "core/defs.h"
|
||||
@@ -111,7 +113,7 @@ private:
|
||||
|
||||
QString m_privateKeyPassphrase;
|
||||
|
||||
#ifndef Q_OS_IOS
|
||||
#if !defined(Q_OS_IOS) && !defined(Q_OS_TVOS)
|
||||
QList<QSharedPointer<QProcess>> m_sftpMountProcesses;
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
#include "pageController.h"
|
||||
#include "utils/converter.h"
|
||||
#include "core/errorstrings.h"
|
||||
#include <QCoreApplication>
|
||||
#if defined(MACOS_NE)
|
||||
#include "platforms/ios/ios_controller.h"
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) || defined(MACOS_NE)
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) || defined(Q_OS_TVOS) || defined(MACOS_NE)
|
||||
#include <QGuiApplication>
|
||||
#else
|
||||
#include <QApplication>
|
||||
@@ -14,7 +15,7 @@
|
||||
#ifdef Q_OS_ANDROID
|
||||
#include "platforms/android/android_controller.h"
|
||||
#endif
|
||||
#if defined Q_OS_MAC
|
||||
#if defined(Q_OS_MACX) && !defined(Q_OS_TVOS)
|
||||
#include "ui/macos_util.h"
|
||||
#endif
|
||||
|
||||
@@ -27,7 +28,7 @@ PageController::PageController(const QSharedPointer<ServersModel> &serversModel,
|
||||
AndroidController::instance()->setNavigationBarColor(initialPageNavigationBarColor);
|
||||
#endif
|
||||
|
||||
#if defined Q_OS_MACX
|
||||
#if defined(Q_OS_MACX) && !defined(Q_OS_TVOS)
|
||||
connect(this, &PageController::raiseMainWindow, []() {
|
||||
setDockIconVisible(true);
|
||||
});
|
||||
@@ -64,7 +65,7 @@ QString PageController::getPagePath(PageLoader::PageEnum page)
|
||||
void PageController::closeWindow()
|
||||
{
|
||||
// On mobile platforms, quit app on close; on desktop, just hide window
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) || defined(Q_OS_TVOS)
|
||||
qApp->quit();
|
||||
#else
|
||||
emit hideMainWindow();
|
||||
@@ -118,7 +119,7 @@ void PageController::showOnStartup()
|
||||
} else {
|
||||
#if defined(Q_OS_WIN) || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
|
||||
emit hideMainWindow();
|
||||
#elif defined(Q_OS_MACX)
|
||||
#elif defined(Q_OS_MACX) && !defined(Q_OS_TVOS)
|
||||
setDockIconVisible(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include "platforms/android/android_controller.h"
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_IOS) || defined(MACOS_NE)
|
||||
#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) || defined(MACOS_NE)
|
||||
#include <AmneziaVPN-Swift.h>
|
||||
#endif
|
||||
|
||||
@@ -57,6 +57,8 @@ QString getPlatformName()
|
||||
return "Windows";
|
||||
#elif defined(Q_OS_ANDROID)
|
||||
return "Android";
|
||||
#elif defined(Q_OS_TVOS)
|
||||
return "tvOS";
|
||||
#elif defined(Q_OS_LINUX)
|
||||
return "Linux";
|
||||
#elif defined(Q_OS_MACX)
|
||||
@@ -109,7 +111,7 @@ bool SettingsController::isLoggingEnabled()
|
||||
void SettingsController::toggleLogging(bool enable)
|
||||
{
|
||||
m_settings->setSaveLogs(enable);
|
||||
#if defined(Q_OS_IOS)
|
||||
#if defined(Q_OS_IOS) || defined(Q_OS_TVOS)
|
||||
AmneziaVPN::toggleLogging(enable);
|
||||
#endif
|
||||
if (enable == true) {
|
||||
@@ -193,7 +195,7 @@ void SettingsController::restoreAppConfigFromData(const QByteArray &data)
|
||||
if (ok) {
|
||||
QJsonObject newConfigData = QJsonDocument::fromJson(data).object();
|
||||
|
||||
#if defined(Q_OS_WINDOWS) || defined(Q_OS_LINUX) || defined(Q_OS_MACX)
|
||||
#if defined(Q_OS_WINDOWS) || defined(Q_OS_LINUX) || (defined(Q_OS_MACX) && !defined(Q_OS_TVOS))
|
||||
bool autoStart = false;
|
||||
if (newConfigData.contains("Conf/autoStart")) {
|
||||
autoStart = newConfigData["Conf/autoStart"].toBool();
|
||||
@@ -230,7 +232,7 @@ void SettingsController::restoreAppConfigFromData(const QByteArray &data)
|
||||
m_sitesModel->setRouteMode(siteSplitTunnelingRouteMode);
|
||||
m_sitesModel->toggleSplitTunneling(siteSplittunnelingEnabled);
|
||||
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) || defined(Q_OS_TVOS)
|
||||
m_settings->setAutoConnect(false);
|
||||
m_settings->setStartMinimized(false);
|
||||
m_settings->setKillSwitchEnabled(false);
|
||||
@@ -269,7 +271,7 @@ void SettingsController::clearSettings()
|
||||
|
||||
emit changeSettingsFinished(tr("All settings have been reset to default values"));
|
||||
|
||||
#if defined(Q_OS_IOS) || defined(MACOS_NE)
|
||||
#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) || defined(MACOS_NE)
|
||||
AmneziaVPN::clearSettings();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include "platforms/android/android_controller.h"
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_IOS) || defined(MACOS_NE)
|
||||
#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) || defined(MACOS_NE)
|
||||
#include "platforms/ios/ios_controller.h"
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#endif
|
||||
@@ -31,7 +31,7 @@ void SystemController::saveFile(const QString &fileName, const QString &data)
|
||||
return;
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_IOS
|
||||
#if defined(Q_OS_IOS) || defined(Q_OS_TVOS)
|
||||
QUrl fileUrl = QDir::tempPath() + "/" + fileName;
|
||||
QFile file(fileUrl.toString());
|
||||
#else
|
||||
@@ -43,7 +43,7 @@ void SystemController::saveFile(const QString &fileName, const QString &data)
|
||||
file.write(data.toUtf8());
|
||||
file.close();
|
||||
|
||||
#ifdef Q_OS_IOS
|
||||
#if defined(Q_OS_IOS) || defined(Q_OS_TVOS)
|
||||
QStringList filesToSend;
|
||||
filesToSend.append(fileUrl.toString());
|
||||
// todo check if save successful
|
||||
@@ -98,7 +98,7 @@ QString SystemController::getFileName(const QString &acceptLabel, const QString
|
||||
return AndroidController::instance()->openFile(nameFilter);
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_IOS
|
||||
#if defined(Q_OS_IOS) || defined(Q_OS_TVOS)
|
||||
|
||||
fileName = IosController::Instance()->openFile();
|
||||
if (fileName.isEmpty()) {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <QDebug>
|
||||
#include "notificationhandler.h"
|
||||
|
||||
#if defined(Q_OS_IOS)
|
||||
#if defined(Q_OS_IOS) || defined(Q_OS_TVOS)
|
||||
# include "platforms/ios/iosnotificationhandler.h"
|
||||
#else
|
||||
# include "systemtray_notificationhandler.h"
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
// static
|
||||
NotificationHandler* NotificationHandler::create(QObject* parent) {
|
||||
#if defined(Q_OS_IOS)
|
||||
#if defined(Q_OS_IOS) || defined(Q_OS_TVOS)
|
||||
return new IOSNotificationHandler(parent);
|
||||
#else
|
||||
return new SystemTrayNotificationHandler(parent);
|
||||
|
||||
@@ -58,7 +58,7 @@ QString Autostart::appPath() {
|
||||
return QCoreApplication::applicationFilePath() + " --autostart";
|
||||
}
|
||||
|
||||
#elif defined Q_OS_MACX
|
||||
#elif defined(Q_OS_MACX) && !defined(Q_OS_TVOS)
|
||||
|
||||
bool Autostart::isAutostart() {
|
||||
QProcess process;
|
||||
|
||||
@@ -1,194 +0,0 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
|
||||
import QtCore
|
||||
|
||||
import PageEnum 1.0
|
||||
import Style 1.0
|
||||
|
||||
import "./"
|
||||
import "../Controls2"
|
||||
import "../Controls2/TextTypes"
|
||||
import "../Config"
|
||||
import "../Components"
|
||||
|
||||
DrawerType2 {
|
||||
id: root
|
||||
|
||||
expandedHeight: parent.height * 0.9
|
||||
|
||||
Connections {
|
||||
target: ApiPremV1MigrationController
|
||||
|
||||
function onErrorOccurred(error, goToPageHome) {
|
||||
PageController.showErrorMessage(error)
|
||||
root.closeTriggered()
|
||||
}
|
||||
}
|
||||
|
||||
expandedStateContent: Item {
|
||||
implicitHeight: root.expandedHeight
|
||||
|
||||
ListViewType {
|
||||
id: listView
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
model: 1 // fake model to force the ListView to be created without a model
|
||||
snapMode: ListView.NoSnap
|
||||
|
||||
header: ColumnLayout {
|
||||
width: listView.width
|
||||
|
||||
Header2Type {
|
||||
id: header
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 20
|
||||
Layout.leftMargin: 16
|
||||
Layout.rightMargin: 16
|
||||
|
||||
headerText: qsTr("Switch to the new Amnezia Premium subscription")
|
||||
}
|
||||
}
|
||||
|
||||
delegate: ColumnLayout {
|
||||
width: listView.width
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.leftMargin: 16
|
||||
anchors.rightMargin: 16
|
||||
|
||||
ParagraphTextType {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 24
|
||||
Layout.bottomMargin: 24
|
||||
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
textFormat: Text.RichText
|
||||
text: {
|
||||
var str = qsTr("We'll preserve all remaining days of your current subscription and give you an extra month as a thank you. ")
|
||||
str += qsTr("This new subscription type will be actively developed with more locations and features added regularly. Currently available:")
|
||||
str += "<ul style='margin-left: -16px;'>"
|
||||
str += qsTr("<li>20 locations (with more coming soon)</li>")
|
||||
str += qsTr("<li>Easier switching between countries in the app</li>")
|
||||
str += qsTr("<li>Personal dashboard to manage your subscription</li>")
|
||||
str += "</ul>"
|
||||
str += qsTr("Old keys will be deactivated after switching.")
|
||||
}
|
||||
}
|
||||
|
||||
TextFieldWithHeaderType {
|
||||
id: emailLabel
|
||||
Layout.fillWidth: true
|
||||
|
||||
borderColor: AmneziaStyle.color.mutedGray
|
||||
headerTextColor: AmneziaStyle.color.paleGray
|
||||
|
||||
headerText: qsTr("Email")
|
||||
textField.placeholderText: qsTr("mail@example.com")
|
||||
|
||||
|
||||
textField.onFocusChanged: {
|
||||
textField.text = textField.text.replace(/^\s+|\s+$/g, '')
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: ApiPremV1MigrationController
|
||||
|
||||
function onNoSubscriptionToMigrate() {
|
||||
emailLabel.errorText = qsTr("No old format subscriptions for a given email")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CaptionTextType {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 16
|
||||
|
||||
color: AmneziaStyle.color.mutedGray
|
||||
|
||||
text: qsTr("Enter the email you used for your current subscription")
|
||||
}
|
||||
|
||||
ApiPremV1SubListDrawer {
|
||||
id: apiPremV1SubListDrawer
|
||||
parent: root
|
||||
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
OtpCodeDrawer {
|
||||
id: otpCodeDrawer
|
||||
parent: root
|
||||
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
id: yesButton
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 32
|
||||
|
||||
text: qsTr("Continue")
|
||||
|
||||
clickedFunc: function() {
|
||||
PageController.showBusyIndicator(true)
|
||||
ApiPremV1MigrationController.getSubscriptionList(emailLabel.textField.text)
|
||||
PageController.showBusyIndicator(false)
|
||||
}
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
id: noButton
|
||||
Layout.fillWidth: true
|
||||
|
||||
defaultColor: AmneziaStyle.color.transparent
|
||||
hoveredColor: AmneziaStyle.color.translucentWhite
|
||||
pressedColor: AmneziaStyle.color.sheerWhite
|
||||
disabledColor: AmneziaStyle.color.mutedGray
|
||||
textColor: AmneziaStyle.color.paleGray
|
||||
borderWidth: 1
|
||||
|
||||
text: qsTr("Remind me later")
|
||||
|
||||
clickedFunc: function() {
|
||||
root.closeTriggered()
|
||||
}
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.topMargin: 32
|
||||
Layout.bottomMargin: 32
|
||||
implicitHeight: 32
|
||||
|
||||
defaultColor: "transparent"
|
||||
hoveredColor: AmneziaStyle.color.translucentWhite
|
||||
pressedColor: AmneziaStyle.color.sheerWhite
|
||||
textColor: AmneziaStyle.color.vibrantRed
|
||||
|
||||
text: qsTr("Don't remind me again")
|
||||
|
||||
clickedFunc: function() {
|
||||
var headerText = qsTr("No more reminders? You can always switch to the new format in the server settings")
|
||||
var yesButtonText = qsTr("Continue")
|
||||
var noButtonText = qsTr("Cancel")
|
||||
|
||||
var yesButtonFunction = function() {
|
||||
ApiPremV1MigrationController.disablePremV1MigrationReminder()
|
||||
root.closeTriggered()
|
||||
}
|
||||
var noButtonFunction = function() {
|
||||
}
|
||||
|
||||
showQuestionDrawer(headerText, "", yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
|
||||
import Style 1.0
|
||||
|
||||
import "../Controls2"
|
||||
import "../Controls2/TextTypes"
|
||||
import "../Config"
|
||||
|
||||
DrawerType2 {
|
||||
id: root
|
||||
|
||||
Connections {
|
||||
target: ApiPremV1MigrationController
|
||||
|
||||
function onSubscriptionsModelChanged() {
|
||||
if (ApiPremV1MigrationController.subscriptionsModel.length > 1) {
|
||||
root.openTriggered()
|
||||
} else {
|
||||
sendMigrationCode(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function sendMigrationCode(index) {
|
||||
PageController.showBusyIndicator(true)
|
||||
ApiPremV1MigrationController.sendMigrationCode(index)
|
||||
root.closeTriggered()
|
||||
PageController.showBusyIndicator(false)
|
||||
}
|
||||
|
||||
expandedHeight: parent.height * 0.9
|
||||
|
||||
expandedStateContent: Item {
|
||||
implicitHeight: root.expandedHeight
|
||||
|
||||
ListViewType {
|
||||
id: listView
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
model: ApiPremV1MigrationController.subscriptionsModel
|
||||
|
||||
header: ColumnLayout {
|
||||
width: listView.width
|
||||
|
||||
Header2Type {
|
||||
id: header
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 20
|
||||
Layout.leftMargin: 16
|
||||
Layout.rightMargin: 16
|
||||
|
||||
headerText: qsTr("Choose Subscription")
|
||||
}
|
||||
}
|
||||
|
||||
delegate: Item {
|
||||
implicitWidth: listView.width
|
||||
implicitHeight: delegateContent.implicitHeight
|
||||
|
||||
ColumnLayout {
|
||||
id: delegateContent
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
LabelWithButtonType {
|
||||
id: server
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: qsTr("Order ID: ") + modelData.id
|
||||
|
||||
descriptionText: qsTr("Purchase Date: ") + Qt.formatDateTime(new Date(modelData.created_at), "dd.MM.yyyy hh:mm")
|
||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||
|
||||
clickedFunction: function() {
|
||||
sendMigrationCode(index)
|
||||
}
|
||||
}
|
||||
|
||||
DividerType {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
|
||||
import Style 1.0
|
||||
|
||||
import "../Controls2"
|
||||
import "../Controls2/TextTypes"
|
||||
|
||||
import "../Config"
|
||||
|
||||
DrawerType2 {
|
||||
id: root
|
||||
|
||||
Connections {
|
||||
target: ApiPremV1MigrationController
|
||||
|
||||
function onOtpSuccessfullySent() {
|
||||
root.openTriggered()
|
||||
}
|
||||
}
|
||||
|
||||
expandedHeight: parent.height * 0.6
|
||||
|
||||
expandedStateContent: Item {
|
||||
implicitHeight: root.expandedHeight
|
||||
|
||||
ColumnLayout {
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.leftMargin: 16
|
||||
anchors.rightMargin: 16
|
||||
spacing: 0
|
||||
|
||||
Header2Type {
|
||||
id: header
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 20
|
||||
|
||||
headerText: qsTr("OTP code was sent to your email")
|
||||
}
|
||||
|
||||
TextFieldWithHeaderType {
|
||||
id: otpFiled
|
||||
|
||||
borderColor: AmneziaStyle.color.mutedGray
|
||||
headerTextColor: AmneziaStyle.color.paleGray
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 16
|
||||
headerText: qsTr("OTP Code")
|
||||
textField.maximumLength: 30
|
||||
checkEmptyText: true
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
id: saveButton
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 16
|
||||
|
||||
text: qsTr("Continue")
|
||||
|
||||
clickedFunc: function() {
|
||||
PageController.showBusyIndicator(true)
|
||||
ApiPremV1MigrationController.migrate(otpFiled.textField.text)
|
||||
PageController.showBusyIndicator(false)
|
||||
root.closeTriggered()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -48,30 +48,6 @@ PageType {
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
|
||||
target: ApiPremV1MigrationController
|
||||
|
||||
function onMigrationFinished() {
|
||||
apiPremV1MigrationDrawer.closeTriggered()
|
||||
|
||||
var headerText = qsTr("You've successfully switched to the new Amnezia Premium subscription!")
|
||||
var descriptionText = qsTr("Old keys will no longer work. Please use your new subscription key to connect. \nThank you for staying with us!")
|
||||
var yesButtonText = qsTr("Continue")
|
||||
var noButtonText = ""
|
||||
|
||||
var yesButtonFunction = function() {
|
||||
}
|
||||
var noButtonFunction = function() {
|
||||
}
|
||||
|
||||
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
||||
}
|
||||
|
||||
function onShowMigrationDrawer() {
|
||||
apiPremV1MigrationDrawer.openTriggered()
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
objectName: "homeColumnItem"
|
||||
@@ -500,9 +476,4 @@ PageType {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ApiPremV1MigrationDrawer {
|
||||
id: apiPremV1MigrationDrawer
|
||||
anchors.fill: parent
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,7 +101,6 @@ PageType {
|
||||
remove,
|
||||
clear,
|
||||
reset,
|
||||
switch_to_premium,
|
||||
]
|
||||
|
||||
QtObject {
|
||||
@@ -237,16 +236,4 @@ PageType {
|
||||
}
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: switch_to_premium
|
||||
|
||||
property bool isVisible: ServersModel.getProcessedServerData("isServerFromTelegramApi") && ServersModel.processedServerIsPremium
|
||||
readonly property string title: qsTr("Switch to the new Amnezia Premium subscription")
|
||||
readonly property string description: ""
|
||||
readonly property var tColor: AmneziaStyle.color.vibrantRed
|
||||
readonly property var clickedHandler: function() {
|
||||
PageController.goToPageHome()
|
||||
ApiPremV1MigrationController.showMigrationDrawer()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ bool Utils::processIsRunning(const QString &fileName, const bool fullFlag)
|
||||
CloseHandle(hSnapshot);
|
||||
return false;
|
||||
|
||||
#elif defined(Q_OS_IOS) || defined(Q_OS_ANDROID) || defined(MACOS_NE)
|
||||
#elif defined(Q_OS_IOS) || defined(Q_OS_TVOS) || defined(Q_OS_ANDROID) || defined(MACOS_NE)
|
||||
return false;
|
||||
#else
|
||||
QProcess process;
|
||||
@@ -250,7 +250,7 @@ bool Utils::killProcessByName(const QString &name)
|
||||
|
||||
CloseHandle(hSnapshot);
|
||||
return success;
|
||||
#elif defined Q_OS_IOS || defined(Q_OS_ANDROID)
|
||||
#elif defined(Q_OS_IOS) || defined(Q_OS_TVOS) || defined(Q_OS_ANDROID)
|
||||
return false;
|
||||
#else
|
||||
return QProcess::execute("pkill", { name }) == 0;
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_IOS) || defined(MACOS_NE)
|
||||
#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) || defined(MACOS_NE)
|
||||
#include "platforms/ios/ios_controller.h"
|
||||
#endif
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
VpnConnection::VpnConnection(std::shared_ptr<Settings> settings, QObject *parent)
|
||||
: QObject(parent), m_settings(settings), m_checkTimer(new QTimer(this))
|
||||
{
|
||||
#if defined(Q_OS_IOS) || defined(MACOS_NE)
|
||||
#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) || defined(MACOS_NE)
|
||||
m_checkTimer.setInterval(1000);
|
||||
connect(IosController::Instance(), &IosController::connectionStateChanged, this, &VpnConnection::onConnectionStateChanged);
|
||||
connect(IosController::Instance(), &IosController::bytesChanged, this, &VpnConnection::onBytesChanged);
|
||||
@@ -131,7 +131,7 @@ void VpnConnection::onConnectionStateChanged(Vpn::ConnectionState state)
|
||||
});
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_IOS) || defined(MACOS_NE)
|
||||
#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) || defined(MACOS_NE)
|
||||
if (state == Vpn::ConnectionState::Connected ||
|
||||
state == Vpn::ConnectionState::Connecting ||
|
||||
state == Vpn::ConnectionState::Reconnecting) {
|
||||
@@ -290,7 +290,7 @@ void VpnConnection::connectToVpn(int serverIndex, const ServerCredentials &crede
|
||||
|
||||
appendSplitTunnelingConfig();
|
||||
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(MACOS_NE)
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(Q_OS_TVOS) && !defined(MACOS_NE)
|
||||
m_vpnProtocol.reset(VpnProtocol::factory(container, m_vpnConfiguration));
|
||||
if (!m_vpnProtocol) {
|
||||
emit connectionStateChanged(Vpn::ConnectionState::Error);
|
||||
@@ -302,7 +302,7 @@ void VpnConnection::connectToVpn(int serverIndex, const ServerCredentials &crede
|
||||
createAndroidConnections();
|
||||
|
||||
m_vpnProtocol.reset(androidVpnProtocol);
|
||||
#elif defined Q_OS_IOS || defined(MACOS_NE)
|
||||
#elif defined(Q_OS_IOS) || defined(Q_OS_TVOS) || defined(MACOS_NE)
|
||||
Proto proto = ContainerProps::defaultProtocol(container);
|
||||
IosController::Instance()->connectVpn(proto, m_vpnConfiguration);
|
||||
connect(&m_checkTimer, &QTimer::timeout, IosController::Instance(), &IosController::checkStatus);
|
||||
@@ -539,7 +539,7 @@ QString VpnConnection::bytesPerSecToText(quint64 bytes)
|
||||
|
||||
void VpnConnection::disconnectFromVpn()
|
||||
{
|
||||
#if defined(Q_OS_IOS) || defined(MACOS_NE)
|
||||
#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) || defined(MACOS_NE)
|
||||
// iOS/macOS NE use IosController directly; m_vpnProtocol is not set there.
|
||||
IosController::Instance()->disconnectVpn();
|
||||
disconnect(&m_checkTimer, &QTimer::timeout, IosController::Instance(), &IosController::checkStatus);
|
||||
|
||||
Reference in New Issue
Block a user