diff --git a/client/amneziaApplication.cpp b/client/amneziaApplication.cpp index 008cc345d2..7034ba17fe 100644 --- a/client/amneziaApplication.cpp +++ b/client/amneziaApplication.cpp @@ -119,7 +119,13 @@ void AmneziaApplication::init() win->setPersistentSceneGraph(true); win->setPersistentGraphics(true); #endif +#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) win->show(); +#else + if (!m_coreController || !m_coreController->pageController()->shouldStartMinimized()) { + win->show(); + } +#endif } }, Qt::QueuedConnection); diff --git a/client/core/configurators/xrayConfigurator.cpp b/client/core/configurators/xrayConfigurator.cpp index 25511fa27f..f927eafe1d 100644 --- a/client/core/configurators/xrayConfigurator.cpp +++ b/client/core/configurators/xrayConfigurator.cpp @@ -244,11 +244,7 @@ ErrorCode XrayConfigurator::applyServerSettingsToRemote(const ServerCredentials << "container=" << static_cast(container) << "host=" << credentials.hostName << "transport=" << srv.transport << "security=" << srv.security << "port=" << srv.port << "appendClient=" << appendNewClient; - QString flowValue = srv.flow; - if (flowValue.isEmpty() && srv.security == QLatin1String("reality")) { - flowValue = QStringLiteral("xtls-rprx-vision"); - } - + const QString flowValue = srv.flow; QString realityPublicKey; QString realityShortId; if (srv.security == QLatin1String("reality")) { diff --git a/client/core/controllers/connectionController.cpp b/client/core/controllers/connectionController.cpp index 607326c0fa..6894e28e14 100644 --- a/client/core/controllers/connectionController.cpp +++ b/client/core/controllers/connectionController.cpp @@ -106,7 +106,8 @@ ErrorCode ConnectionController::isConnectionSupported(const QString &serverId) c return ErrorCode::AmneziaServiceNotRunning; } - if (serverConfigUtils::isLegacyApiSubscription(m_serversRepository->serverKind(serverId))) { + const serverConfigUtils::ConfigType kind = m_serversRepository->serverKind(serverId); + if (serverConfigUtils::isLegacyApiSubscription(kind)) { return ErrorCode::LegacyApiV1NotSupportedError; } @@ -117,6 +118,9 @@ ErrorCode ConnectionController::isConnectionSupported(const QString &serverId) c } if (container == DockerContainer::None) { + if (serverConfigUtils::isApiV2Subscription(kind)) { + return ErrorCode::NoError; + } return ErrorCode::NoInstalledContainersError; } diff --git a/client/core/controllers/coreSignalHandlers.cpp b/client/core/controllers/coreSignalHandlers.cpp index ead4d733b9..daf5b8df4b 100644 --- a/client/core/controllers/coreSignalHandlers.cpp +++ b/client/core/controllers/coreSignalHandlers.cpp @@ -1,6 +1,7 @@ #include "coreSignalHandlers.h" #include +#include #include "core/utils/selfhosted/sshSession.h" #include "core/utils/errorCodes.h" @@ -144,7 +145,9 @@ void CoreSignalHandlers::initExportControllerHandler() }); connect(m_coreController->m_exportController, &ExportController::revokeClientRequested, this, [this](const QString &serverId, int row, DockerContainer container) { - m_coreController->m_usersController->revokeClient(serverId, row, container); + QtConcurrent::run([this, serverId, row, container]() { + m_coreController->m_usersController->revokeClient(serverId, row, container); + }); }); connect(m_coreController->m_exportController, &ExportController::renameClientRequested, this, [this](const QString &serverId, int row, const QString &clientName, DockerContainer container) { @@ -202,13 +205,15 @@ void CoreSignalHandlers::initAdminConfigRevokedHandler() { connect(m_coreController->m_installController, &InstallController::clientRevocationRequested, this, [this](const QString &serverId, const ContainerConfig &containerConfig, DockerContainer container) { - m_coreController->m_usersController->revokeClient(serverId, containerConfig, container); + QtConcurrent::run([this, serverId, containerConfig, container]() { + m_coreController->m_usersController->revokeClient(serverId, containerConfig, container); + }); }); connect(m_coreController->m_installController, &InstallController::clientAppendRequested, this, [this](const QString &serverId, const QString &clientId, const QString &clientName, DockerContainer container) { m_coreController->m_usersController->appendClient(serverId, clientId, clientName, container); - }); + }, Qt::DirectConnection); connect(m_coreController->m_usersController, &UsersController::adminConfigRevoked, m_coreController->m_installController, &InstallController::clearCachedProfile); @@ -285,6 +290,8 @@ void CoreSignalHandlers::initClientManagementModelUpdateHandler() m_coreController->m_clientManagementModel, &ClientManagementModel::updateModel); connect(m_coreController->m_usersController, &UsersController::clientRenamed, m_coreController->m_clientManagementModel, &ClientManagementModel::updateClientName); + connect(m_coreController->m_usersController, &UsersController::revokeFinished, + m_coreController->m_exportController, &ExportController::revokeFinished); } void CoreSignalHandlers::initSitesModelUpdateHandler() diff --git a/client/core/controllers/selfhosted/exportController.h b/client/core/controllers/selfhosted/exportController.h index e89ef73367..b52e943a4e 100644 --- a/client/core/controllers/selfhosted/exportController.h +++ b/client/core/controllers/selfhosted/exportController.h @@ -48,6 +48,7 @@ class ExportController : public QObject void appendClientRequested(const QString &serverId, const QString &clientId, const QString &clientName, DockerContainer container); void updateClientsRequested(const QString &serverId, DockerContainer container); void revokeClientRequested(const QString &serverId, int row, DockerContainer container); + void revokeFinished(ErrorCode errorCode); void renameClientRequested(const QString &serverId, int row, const QString &clientName, DockerContainer container); public slots: diff --git a/client/core/controllers/selfhosted/installController.cpp b/client/core/controllers/selfhosted/installController.cpp index f87f6dbd2c..3aacb2ece3 100644 --- a/client/core/controllers/selfhosted/installController.cpp +++ b/client/core/controllers/selfhosted/installController.cpp @@ -234,7 +234,9 @@ ErrorCode InstallController::updateServerConfig(const QString &serverId, DockerC } else if (container == DockerContainer::Telemt) { TelemtInstaller::uploadClientSettingsSnapshot(sshSession, credentials, container, newConfig); } - clearCachedProfile(serverId, container); + if (reinstallRequired) { + clearCachedProfile(serverId, container); + } adminConfig->updateContainerConfig(container, newConfig); m_serversRepository->editServer(serverId, adminConfig->toJson(), serverConfigUtils::ConfigType::SelfHostedAdmin); } diff --git a/client/core/controllers/selfhosted/usersController.cpp b/client/core/controllers/selfhosted/usersController.cpp index 7180cbb8f9..196ae1c262 100644 --- a/client/core/controllers/selfhosted/usersController.cpp +++ b/client/core/controllers/selfhosted/usersController.cpp @@ -698,7 +698,7 @@ ErrorCode UsersController::revokeXray(const int row, QString restartScript = QString("sudo docker restart $CONTAINER_NAME"); error = sshSession->runScript( - credentials, + credentials, sshSession->replaceVars(restartScript, amnezia::genBaseVars(credentials, container, QString(), QString())) ); if (error != ErrorCode::NoError) { @@ -758,14 +758,17 @@ ErrorCode UsersController::revokeClient(const QString &serverId, const int index ContainerConfig containerCfg = adminConfig->containerConfig(container); QString containerClientId = containerCfg.protocolConfig.clientId(); - if (!clientId.isEmpty() && !containerClientId.isEmpty() && containerClientId.contains(clientId)) { + const bool isAdminMatch = !clientId.isEmpty() && !containerClientId.isEmpty() && containerClientId.contains(clientId); + if (isAdminMatch) { emit adminConfigRevoked(serverId, container); } emit clientRevoked(index); - emit clientsUpdated(m_clientsTable); } + emit clientsUpdated(m_clientsTable); + emit revokeFinished(errorCode); + return errorCode; } diff --git a/client/core/controllers/selfhosted/usersController.h b/client/core/controllers/selfhosted/usersController.h index b52a3f5e5f..ca24438abd 100644 --- a/client/core/controllers/selfhosted/usersController.h +++ b/client/core/controllers/selfhosted/usersController.h @@ -37,6 +37,7 @@ class UsersController : public QObject void clientAdded(const QJsonObject &client); void clientRenamed(int row, const QString &newName); void clientRevoked(int row); + void revokeFinished(ErrorCode errorCode); void adminConfigRevoked(const QString &serverId, DockerContainer container); public slots: diff --git a/client/core/models/protocols/xrayProtocolConfig.cpp b/client/core/models/protocols/xrayProtocolConfig.cpp index ce5945a1e3..f9955d4fbb 100644 --- a/client/core/models/protocols/xrayProtocolConfig.cpp +++ b/client/core/models/protocols/xrayProtocolConfig.cpp @@ -466,6 +466,17 @@ XrayProtocolConfig XrayProtocolConfig::fromJson(const QJsonObject &json) } } } + const QJsonArray outbounds = parsed.value(protocols::xray::outbounds).toArray(); + if (!outbounds.isEmpty()) { + const QJsonObject settings = outbounds[0].toObject().value(protocols::xray::settings).toObject(); + const QJsonArray vnext = settings.value(protocols::xray::vnext).toArray(); + if (!vnext.isEmpty()) { + const QJsonArray users = vnext[0].toObject().value(protocols::xray::users).toArray(); + if (!users.isEmpty()) { + clientCfg.id = users[0].toObject().value(protocols::xray::id).toString(); + } + } + } c.clientConfig = clientCfg; } else { c.clientConfig = XrayClientConfig::fromJson(parsed); diff --git a/client/core/repositories/secureServersRepository.cpp b/client/core/repositories/secureServersRepository.cpp index 5521743daf..9d347a29af 100644 --- a/client/core/repositories/secureServersRepository.cpp +++ b/client/core/repositories/secureServersRepository.cpp @@ -208,8 +208,8 @@ QString SecureServersRepository::nextAvailableServerName() const int i = 0; QString candidate; do { - i++; - candidate = QStringLiteral("Server %1").arg(i); + ++i; + candidate = tr("Server") + QLatin1Char(' ') + QString::number(i); } while (usedNames.contains(candidate)); return candidate; diff --git a/client/ui/controllers/qml/pageController.cpp b/client/ui/controllers/qml/pageController.cpp index b51ece70b0..17112c0bba 100644 --- a/client/ui/controllers/qml/pageController.cpp +++ b/client/ui/controllers/qml/pageController.cpp @@ -128,6 +128,11 @@ void PageController::showOnStartup() } } +bool PageController::shouldStartMinimized() const +{ + return m_settingsController->isStartMinimizedEnabled(); +} + bool PageController::isTriggeredByConnectButton() { return m_isTriggeredByConnectButton; diff --git a/client/ui/controllers/qml/pageController.h b/client/ui/controllers/qml/pageController.h index 216328daf9..c6f9febb1d 100644 --- a/client/ui/controllers/qml/pageController.h +++ b/client/ui/controllers/qml/pageController.h @@ -123,6 +123,7 @@ public slots: void updateNavigationBarColor(const int color); void showOnStartup(); + bool shouldStartMinimized() const; bool isTriggeredByConnectButton(); void setTriggeredByConnectButton(bool trigger); diff --git a/client/ui/controllers/selfhosted/exportUiController.cpp b/client/ui/controllers/selfhosted/exportUiController.cpp index bbe1da570b..bab7d9a5ce 100644 --- a/client/ui/controllers/selfhosted/exportUiController.cpp +++ b/client/ui/controllers/selfhosted/exportUiController.cpp @@ -9,6 +9,13 @@ ExportUiController::ExportUiController(ExportController* exportController, QObje : QObject(parent), m_exportController(exportController) { + connect(m_exportController, &ExportController::revokeFinished, this, [this](ErrorCode errorCode) { + if (errorCode == ErrorCode::NoError) { + emit revokeConfigFinished(); + } else { + emit exportErrorOccurred(errorCode); + } + }); } void ExportUiController::generateFullAccessConfig(const QString &serverId) @@ -92,7 +99,6 @@ void ExportUiController::updateClientManagementModel(const QString &serverId, in void ExportUiController::revokeConfig(int row, const QString &serverId, int containerIndex) { m_exportController->revokeConfig(row, serverId, containerIndex); - emit revokeConfigFinished(); } void ExportUiController::renameClient(int row, const QString &clientName, const QString &serverId, int containerIndex) diff --git a/client/ui/controllers/selfhosted/installUiController.cpp b/client/ui/controllers/selfhosted/installUiController.cpp index 3b8b8513f5..8947f62b04 100644 --- a/client/ui/controllers/selfhosted/installUiController.cpp +++ b/client/ui/controllers/selfhosted/installUiController.cpp @@ -306,14 +306,17 @@ void InstallUiController::updateServerConfig(const QString &serverId, int contai || container == DockerContainer::Xray || container == DockerContainer::SSXray; if (asyncUpdate) { - emit serverIsBusy(true); + const bool emitBusy = container == DockerContainer::MtProxy || container == DockerContainer::Telemt; + if (emitBusy) + emit serverIsBusy(true); auto *watcher = new QFutureWatcher(this); const Proto protocolTypeCopy = protocolType; QObject::connect(watcher, &QFutureWatcher::finished, this, - [this, watcher, serverId, container, closePage, protocolTypeCopy]() { + [this, watcher, serverId, container, closePage, protocolTypeCopy, emitBusy]() { const ErrorCode errorCode = watcher->result(); watcher->deleteLater(); - emit serverIsBusy(false); + if (emitBusy) + emit serverIsBusy(false); if (errorCode == ErrorCode::NoError) { const ContainerConfig updatedConfig = diff --git a/client/ui/models/protocols/xrayConfigModel.cpp b/client/ui/models/protocols/xrayConfigModel.cpp index 93c1ce9026..72248a8e9d 100644 --- a/client/ui/models/protocols/xrayConfigModel.cpp +++ b/client/ui/models/protocols/xrayConfigModel.cpp @@ -272,7 +272,7 @@ void XrayConfigModel::updateModel(amnezia::DockerContainer container, const amne } if (!m_protocolConfig.serverConfig.isThirdPartyConfig) { - applyDefaultsToServerConfig(m_protocolConfig.serverConfig); + applyDefaultsToServerConfig(m_protocolConfig.serverConfig, false); } m_originalProtocolConfig = m_protocolConfig; @@ -283,7 +283,7 @@ void XrayConfigModel::updateModel(amnezia::DockerContainer container, const amne } } -void XrayConfigModel::applyDefaultsToServerConfig(amnezia::XrayServerConfig &config) +void XrayConfigModel::applyDefaultsToServerConfig(amnezia::XrayServerConfig &config, bool fillFlowDefault) { if (config.port.isEmpty()) { config.port = protocols::xray::defaultPort; @@ -306,7 +306,7 @@ void XrayConfigModel::applyDefaultsToServerConfig(amnezia::XrayServerConfig &con config.security = protocols::xray::defaultSecurity; } - if (config.flow.isEmpty()) { + if (fillFlowDefault && config.flow.isEmpty()) { config.flow = protocols::xray::defaultFlow; } diff --git a/client/ui/models/protocols/xrayConfigModel.h b/client/ui/models/protocols/xrayConfigModel.h index fee066107e..299cec4c39 100644 --- a/client/ui/models/protocols/xrayConfigModel.h +++ b/client/ui/models/protocols/xrayConfigModel.h @@ -137,7 +137,7 @@ public slots: amnezia::XrayProtocolConfig m_protocolConfig; amnezia::XrayProtocolConfig m_originalProtocolConfig; - void applyDefaultsToServerConfig(amnezia::XrayServerConfig& config); + void applyDefaultsToServerConfig(amnezia::XrayServerConfig& config, bool fillFlowDefault = true); }; #endif // XRAYCONFIGMODEL_H diff --git a/client/ui/qml/Pages2/PageShare.qml b/client/ui/qml/Pages2/PageShare.qml index 20db93b629..22aae4e8ec 100644 --- a/client/ui/qml/Pages2/PageShare.qml +++ b/client/ui/qml/Pages2/PageShare.qml @@ -91,6 +91,7 @@ PageType { } function onExportErrorOccurred(error) { + PageController.showBusyIndicator(false) PageController.showErrorMessage(error) } } diff --git a/client/ui/qml/main2.qml b/client/ui/qml/main2.qml index 18e8f87e8b..e938b04d84 100644 --- a/client/ui/qml/main2.qml +++ b/client/ui/qml/main2.qml @@ -53,7 +53,7 @@ Window { } } - visible: true + visible: !GC.isDesktop() width: GC.screenWidth height: GC.screenHeight minimumWidth: GC.isDesktop() ? 360 : 0