diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 35e740b0..23df2d8f 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -190,7 +190,7 @@ jobs: - name: 'Install go' uses: actions/setup-go@v5 with: - go-version: '1.22.1' + go-version: '1.24' cache: false - name: 'Setup gomobile' diff --git a/CMakeLists.txt b/CMakeLists.txt index 0ccae139..b1246970 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.25.0 FATAL_ERROR) set(PROJECT AmneziaVPN) -project(${PROJECT} VERSION 4.8.4.4 +project(${PROJECT} VERSION 4.8.5.0 DESCRIPTION "AmneziaVPN" HOMEPAGE_URL "https://amnezia.org/" ) @@ -11,7 +11,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 2081) +set(APP_ANDROID_VERSION_CODE 2082) if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") set(MZ_PLATFORM_NAME "linux") diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 72adaf25..b3f775a0 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -31,10 +31,6 @@ add_definitions(-DDEV_AGW_PUBLIC_KEY="$ENV{DEV_AGW_PUBLIC_KEY}") add_definitions(-DDEV_AGW_ENDPOINT="$ENV{DEV_AGW_ENDPOINT}") add_definitions(-DDEV_S3_ENDPOINT="$ENV{DEV_S3_ENDPOINT}") -if(IOS) - set(PACKAGES ${PACKAGES} Multimedia) -endif() - if(WIN32 OR (APPLE AND NOT IOS) OR (LINUX AND NOT ANDROID)) set(PACKAGES ${PACKAGES} Widgets) endif() @@ -48,10 +44,6 @@ set(LIBS ${LIBS} Qt6::Core5Compat Qt6::Concurrent ) -if(IOS) - set(LIBS ${LIBS} Qt6::Multimedia) -endif() - if(WIN32 OR (APPLE AND NOT IOS) OR (LINUX AND NOT ANDROID)) set(LIBS ${LIBS} Qt6::Widgets) endif() diff --git a/client/core/controllers/coreController.cpp b/client/core/controllers/coreController.cpp index 82232c99..d8f199e9 100644 --- a/client/core/controllers/coreController.cpp +++ b/client/core/controllers/coreController.cpp @@ -1,5 +1,6 @@ #include "coreController.h" +#include #include #if defined(Q_OS_ANDROID) @@ -238,7 +239,23 @@ void CoreController::updateTranslator(const QLocale &locale) QCoreApplication::removeTranslator(m_translator.get()); } - QString strFileName = QString(":/translations/amneziavpn") + QLatin1String("_") + locale.name() + ".qm"; + QStringList availableTranslations; + QDirIterator it(":/translations", QStringList("amneziavpn_*.qm"), QDir::Files); + while (it.hasNext()) { + availableTranslations << it.next(); + } + + // This code allow to load translation for the language only, without country code + const QString lang = locale.name().split("_").first(); + const QString translationFilePrefix = QString(":/translations/amneziavpn_") + lang; + QString strFileName = QString(":/translations/amneziavpn_%1.qm").arg(locale.name()); + for (const QString &translation : availableTranslations) { + if (translation.contains(translationFilePrefix)) { + strFileName = translation; + break; + } + } + if (m_translator->load(strFileName)) { if (QCoreApplication::installTranslator(m_translator.get())) { m_settings->setAppLanguage(locale); diff --git a/client/core/controllers/serverController.cpp b/client/core/controllers/serverController.cpp index ee639ae9..d8c94f4d 100644 --- a/client/core/controllers/serverController.cpp +++ b/client/core/controllers/serverController.cpp @@ -757,10 +757,6 @@ ErrorCode ServerController::isServerPortBusy(const ServerCredentials &credential ErrorCode ServerController::isUserInSudo(const ServerCredentials &credentials, DockerContainer container) { - if (credentials.userName == "root") { - return ErrorCode::NoError; - } - QString stdOut; auto cbReadStdOut = [&](const QString &data, libssh::Client &) { stdOut += data + "\n"; @@ -774,8 +770,16 @@ ErrorCode ServerController::isUserInSudo(const ServerCredentials &credentials, D const QString scriptData = amnezia::scriptData(SharedScriptType::check_user_in_sudo); ErrorCode error = runScript(credentials, replaceVars(scriptData, genVarsForScript(credentials)), cbReadStdOut, cbReadStdErr); - if (!stdOut.contains("sudo")) + if (credentials.userName != "root" && stdOut.contains("sudo:") && !stdOut.contains("uname:") && stdOut.contains("not found")) + return ErrorCode::ServerSudoPackageIsNotPreinstalled; + if (credentials.userName != "root" && !stdOut.contains("sudo") && !stdOut.contains("wheel")) return ErrorCode::ServerUserNotInSudo; + if (stdOut.contains("can't cd to") || stdOut.contains("Permission denied") || stdOut.contains("No such file or directory")) + return ErrorCode::ServerUserDirectoryNotAccessible; + if (stdOut.contains("sudoers") || stdOut.contains("is not allowed to run sudo on")) + return ErrorCode::ServerUserNotAllowedInSudoers; + if (stdOut.contains("password is required")) + return ErrorCode::ServerUserPasswordRequired; return error; } diff --git a/client/core/defs.h b/client/core/defs.h index 6c85c65d..2e683314 100644 --- a/client/core/defs.h +++ b/client/core/defs.h @@ -54,6 +54,10 @@ namespace amnezia ServerCancelInstallation = 204, ServerUserNotInSudo = 205, ServerPacketManagerError = 206, + ServerSudoPackageIsNotPreinstalled = 207, + ServerUserDirectoryNotAccessible = 208, + ServerUserNotAllowedInSudoers = 209, + ServerUserPasswordRequired = 210, // Ssh connection errors SshRequestDeniedError = 300, diff --git a/client/core/errorstrings.cpp b/client/core/errorstrings.cpp index 2b9182cf..9dcd8065 100644 --- a/client/core/errorstrings.cpp +++ b/client/core/errorstrings.cpp @@ -20,8 +20,12 @@ QString errorString(ErrorCode code) { case(ErrorCode::ServerContainerMissingError): errorMessage = QObject::tr("Server error: Docker container missing"); break; case(ErrorCode::ServerDockerFailedError): errorMessage = QObject::tr("Server error: Docker failed"); break; case(ErrorCode::ServerCancelInstallation): errorMessage = QObject::tr("Installation canceled by user"); break; - case(ErrorCode::ServerUserNotInSudo): errorMessage = QObject::tr("The user does not have permission to use sudo"); break; - case(ErrorCode::ServerPacketManagerError): errorMessage = QObject::tr("Server error: Packet manager error"); break; + case(ErrorCode::ServerUserNotInSudo): errorMessage = QObject::tr("The user is not a member of the sudo group"); break; + case(ErrorCode::ServerPacketManagerError): errorMessage = QObject::tr("Server error: Package manager error"); break; + case(ErrorCode::ServerSudoPackageIsNotPreinstalled): errorMessage = QObject::tr("The sudo package is not pre-installed on the server"); break; + case(ErrorCode::ServerUserDirectoryNotAccessible): errorMessage = QObject::tr("The server user's home directory is not accessible"); break; + case(ErrorCode::ServerUserNotAllowedInSudoers): errorMessage = QObject::tr("Action not allowed in sudoers"); break; + case(ErrorCode::ServerUserPasswordRequired): errorMessage = QObject::tr("The user's password is required"); break; // Libssh errors case(ErrorCode::SshRequestDeniedError): errorMessage = QObject::tr("SSH request was denied"); break; diff --git a/client/server_scripts/check_user_in_sudo.sh b/client/server_scripts/check_user_in_sudo.sh index e7ee953c..685e6a18 100644 --- a/client/server_scripts/check_user_in_sudo.sh +++ b/client/server_scripts/check_user_in_sudo.sh @@ -1,2 +1,13 @@ -CUR_USER=$(whoami);\ -groups $CUR_USER \ No newline at end of file +if which apt-get > /dev/null 2>&1; then pm=$(which apt-get); opt="--version";\ +elif which dnf > /dev/null 2>&1; then pm=$(which dnf); opt="--version";\ +elif which yum > /dev/null 2>&1; then pm=$(which yum); opt="--version";\ +elif which pacman > /dev/null 2>&1; then pm=$(which pacman); opt="--version";\ +else pm="uname"; opt="-a";\ +fi;\ +CUR_USER=$(whoami 2>/dev/null || echo $HOME | sed 's/.*\///');\ +echo $LANG | grep -qE '^(en_US.UTF-8|C.UTF-8|C)$' || export LC_ALL=C;\ +sudo -K;\ +cd ~;\ +if [ "$CUR_USER" = "root" ] || ( groups "$CUR_USER" | grep -E '\<(sudo|wheel)\>' ); then \ + sudo -nu $CUR_USER $pm $opt > /dev/null; sudo -n $pm $opt > /dev/null;\ +fi diff --git a/client/server_scripts/prepare_host.sh b/client/server_scripts/prepare_host.sh index c6defdb0..1cc56a01 100644 --- a/client/server_scripts/prepare_host.sh +++ b/client/server_scripts/prepare_host.sh @@ -1,4 +1,4 @@ -CUR_USER=$(whoami);\ +CUR_USER=$(whoami 2>/dev/null || echo $HOME | sed 's/.*\///');\ sudo mkdir -p $DOCKERFILE_FOLDER;\ sudo chown $CUR_USER $DOCKERFILE_FOLDER;\ if ! sudo docker network ls | grep -q amnezia-dns-net; then sudo docker network create \ diff --git a/client/translations/amneziavpn_ar_EG.ts b/client/translations/amneziavpn_ar_EG.ts index 1d88eea0..773f5d05 100644 --- a/client/translations/amneziavpn_ar_EG.ts +++ b/client/translations/amneziavpn_ar_EG.ts @@ -3334,8 +3334,8 @@ Already installed containers were found on the server. All installed containers - The user does not have permission to use sudo - ليس لدي المستخدم الصلحيات لأستخدام sudo + The user is not a member of the sudo group + المستخدم ليس عضوًا في مجموعة sudo @@ -3399,7 +3399,7 @@ Already installed containers were found on the server. All installed containers - Server error: Packet manager error + Server error: Package manager error خطأ في الخادم: خطأ في مدير الحزم diff --git a/client/translations/amneziavpn_fa_IR.ts b/client/translations/amneziavpn_fa_IR.ts index c48606be..c1bfce7e 100644 --- a/client/translations/amneziavpn_fa_IR.ts +++ b/client/translations/amneziavpn_fa_IR.ts @@ -3468,8 +3468,8 @@ It's okay as long as it's from someone you trust. - The user does not have permission to use sudo - The user does not have permission to use sudo + The user is not a member of the sudo group + کاربر عضو گروه sudo نیست @@ -3590,8 +3590,8 @@ It's okay as long as it's from someone you trust. - Server error: Packet manager error - Server error: Packet manager error + Server error: Package manager error + خطای سرور: خطای مدیر بسته diff --git a/client/translations/amneziavpn_hi_IN.ts b/client/translations/amneziavpn_hi_IN.ts index db095d5c..a3fe2011 100644 --- a/client/translations/amneziavpn_hi_IN.ts +++ b/client/translations/amneziavpn_hi_IN.ts @@ -3434,13 +3434,13 @@ Already installed containers were found on the server. All installed containers - The user does not have permission to use sudo - उपयोगकर्ता के पास sudo का उपयोग करने की अनुमति नहीं है + The user is not a member of the sudo group + उपयोगकर्ता sudo समूह का सदस्य नहीं है - Server error: Packet manager error - सर्वर त्रुटि: पैकेट प्रबंधक त्रुटि + Server error: Package manager error + सर्वर त्रुटि: पैकेज प्रबंधक त्रुटि diff --git a/client/translations/amneziavpn_my_MM.ts b/client/translations/amneziavpn_my_MM.ts index 55243d1b..09819cfe 100644 --- a/client/translations/amneziavpn_my_MM.ts +++ b/client/translations/amneziavpn_my_MM.ts @@ -3330,8 +3330,8 @@ Already installed containers were found on the server. All installed containers - The user does not have permission to use sudo - ဤအသုံးပြုသူသည် sudo ကိုအသုံးပြုရန်ခွင့်ပြုချက်မရှိပါ + The user is not a member of the sudo group + ဤအသုံးပြုသူသည် sudo အုပ်စု၏အဖွဲ့ဝင်မဟုတ်ပါ @@ -3395,8 +3395,8 @@ Already installed containers were found on the server. All installed containers - Server error: Packet manager error - ဆာဗာ မှားယွင်းမှု: Packet Manager မှားယွင်းမှု + Server error: Package manager error + ဆာဗာ အမှား- Package manager အမှား diff --git a/client/translations/amneziavpn_ru_RU.ts b/client/translations/amneziavpn_ru_RU.ts index ddf6a212..c4ae0ffd 100644 --- a/client/translations/amneziavpn_ru_RU.ts +++ b/client/translations/amneziavpn_ru_RU.ts @@ -4038,13 +4038,13 @@ and will not be shared or disclosed to the Amnezia or any third parties - The user does not have permission to use sudo - У пользователя нет прав на использование sudo + The user is not a member of the sudo group + Пользователь не входит в группу sudo - Server error: Packet manager error - Ошибка сервера: ошибка менеджера пакетов + Server error: Package manager error + Ошибка сервера: Ошибка менеджера пакетов diff --git a/client/translations/amneziavpn_uk_UA.ts b/client/translations/amneziavpn_uk_UA.ts index 3709e30a..2875850c 100644 --- a/client/translations/amneziavpn_uk_UA.ts +++ b/client/translations/amneziavpn_uk_UA.ts @@ -3700,13 +3700,13 @@ and will not be shared or disclosed to the Amnezia or any third parties - The user does not have permission to use sudo - The user does not have permission to use sudo + The user is not a member of the sudo group + Користувач не входить до групи sudo - Server error: Packet manager error - + Server error: Package manager error + Помилка сервера: Помилка менеджера пакетів diff --git a/client/translations/amneziavpn_ur_PK.ts b/client/translations/amneziavpn_ur_PK.ts index 95419cba..e45ae5da 100644 --- a/client/translations/amneziavpn_ur_PK.ts +++ b/client/translations/amneziavpn_ur_PK.ts @@ -3433,8 +3433,8 @@ Already installed containers were found on the server. All installed containers - The user does not have permission to use sudo - صارف کو sudo استعمال کرنے کی اجازت نہیں ہے + The user is not a member of the sudo group + صارف sudo گروپ کا رکن نہیں ہے @@ -3498,7 +3498,7 @@ Already installed containers were found on the server. All installed containers - Server error: Packet manager error + Server error: Package manager error سرور خطا: پیکیج منیجر خطا diff --git a/client/translations/amneziavpn_zh_CN.ts b/client/translations/amneziavpn_zh_CN.ts index cd39c2a6..fa6a87d1 100644 --- a/client/translations/amneziavpn_zh_CN.ts +++ b/client/translations/amneziavpn_zh_CN.ts @@ -3675,13 +3675,13 @@ and will not be shared or disclosed to the Amnezia or any third parties - The user does not have permission to use sudo - 用户没有root权限 + The user is not a member of the sudo group + 用户不是 sudo 组的成员 - Server error: Packet manager error - + Server error: Package manager error + 服务器错误:包管理器错误 diff --git a/client/ui/controllers/api/apiConfigsController.cpp b/client/ui/controllers/api/apiConfigsController.cpp index b8696201..00e6ae3d 100644 --- a/client/ui/controllers/api/apiConfigsController.cpp +++ b/client/ui/controllers/api/apiConfigsController.cpp @@ -19,7 +19,7 @@ namespace constexpr char cloak[] = "cloak"; constexpr char awg[] = "awg"; - constexpr char apiEdnpoint[] = "api_endpoint"; + constexpr char apiEndpoint[] = "api_endpoint"; constexpr char accessToken[] = "api_key"; constexpr char certificate[] = "certificate"; constexpr char publicKey[] = "public_key"; @@ -251,7 +251,6 @@ bool ApiConfigsController::updateServiceFromGateway(const int serverIndex, const newServerConfig.insert(configKey::apiConfig, newApiConfig); newServerConfig.insert(configKey::authData, authData); - // newServerConfig.insert( m_serversModel->editServer(newServerConfig, serverIndex); if (reloadServiceConfig) { @@ -270,54 +269,37 @@ bool ApiConfigsController::updateServiceFromGateway(const int serverIndex, const bool ApiConfigsController::updateServiceFromTelegram(const int serverIndex) { - auto serverConfig = m_serversModel->getServerConfig(serverIndex); - auto installationUuid = m_settings->getInstallationUuid(true); - #ifdef Q_OS_IOS IosController::Instance()->requestInetAccess(); QThread::msleep(10); #endif - if (serverConfig.value(config_key::configVersion).toInt()) { - QNetworkRequest request; - request.setTransferTimeout(apiDefs::requestTimeoutMsecs); - request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); - request.setRawHeader("Authorization", "Api-Key " + serverConfig.value(configKey::accessToken).toString().toUtf8()); - QString endpoint = serverConfig.value(configKey::apiEdnpoint).toString(); - request.setUrl(endpoint); + GatewayController gatewayController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv(), apiDefs::requestTimeoutMsecs); - QString protocol = serverConfig.value(configKey::protocol).toString(); + auto serverConfig = m_serversModel->getServerConfig(serverIndex); + auto installationUuid = m_settings->getInstallationUuid(true); - ApiPayloadData apiPayloadData = generateApiPayloadData(protocol); + QString serviceProtocol = serverConfig.value(configKey::protocol).toString(); + ApiPayloadData apiPayloadData = generateApiPayloadData(serviceProtocol); - QJsonObject apiPayload = fillApiPayload(protocol, apiPayloadData); - apiPayload[configKey::uuid] = installationUuid; + QJsonObject apiPayload = fillApiPayload(serviceProtocol, apiPayloadData); + apiPayload[configKey::uuid] = installationUuid; + apiPayload[configKey::accessToken] = serverConfig.value(configKey::accessToken).toString(); + apiPayload[configKey::apiEndpoint] = serverConfig.value(configKey::apiEndpoint).toString(); - QByteArray requestBody = QJsonDocument(apiPayload).toJson(); + QByteArray responseBody; + ErrorCode errorCode = gatewayController.post(QString("%1v1/proxy_config"), apiPayload, responseBody); - QNetworkReply *reply = amnApp->networkManager()->post(request, requestBody); + if (errorCode == ErrorCode::NoError) { + fillServerConfig(serviceProtocol, apiPayloadData, responseBody, serverConfig); - QEventLoop wait; - connect(reply, &QNetworkReply::finished, &wait, &QEventLoop::quit); - - QList sslErrors; - connect(reply, &QNetworkReply::sslErrors, [this, &sslErrors](const QList &errors) { sslErrors = errors; }); - wait.exec(); - - auto errorCode = apiUtils::checkNetworkReplyErrors(sslErrors, reply); - if (errorCode != ErrorCode::NoError) { - reply->deleteLater(); - emit errorOccurred(errorCode); - return false; - } - - auto apiResponseBody = reply->readAll(); - reply->deleteLater(); - fillServerConfig(protocol, apiPayloadData, apiResponseBody, serverConfig); m_serversModel->editServer(serverConfig, serverIndex); emit updateServerFromApiFinished(); + return true; + } else { + emit errorOccurred(errorCode); + return false; } - return true; } bool ApiConfigsController::deactivateDevice() diff --git a/client/ui/controllers/importController.cpp b/client/ui/controllers/importController.cpp index 4ca12e21..be66d8f3 100644 --- a/client/ui/controllers/importController.cpp +++ b/client/ui/controllers/importController.cpp @@ -56,7 +56,7 @@ namespace } else if ((config.contains(xrayConfigPatternInbound)) && (config.contains(xrayConfigPatternOutbound))) { return ConfigTypes::Xray; } else if (config.contains(openVpnConfigPatternCli) - && (config.contains(openVpnConfigPatternDriver1) || config.contains(openVpnConfigPatternDriver2))) { + && (config.contains(openVpnConfigPatternDriver1) || config.contains(openVpnConfigPatternDriver2))) { return ConfigTypes::OpenVpn; } return ConfigTypes::Invalid; @@ -94,6 +94,8 @@ bool ImportController::extractConfigFromFile(const QString &fileName) bool ImportController::extractConfigFromData(QString data) { + m_maliciousWarningText.clear(); + QString config = data; QString prefix; QString errormsg; @@ -658,6 +660,7 @@ void ImportController::checkForMaliciousStrings(const QJsonObject &serverConfig) if ((containerName == ContainerProps::containerToString(DockerContainer::OpenVpn)) || (containerName == ContainerProps::containerToString(DockerContainer::Cloak)) || (containerName == ContainerProps::containerToString(DockerContainer::ShadowSocks))) { + QString protocolConfig = containerConfig[ProtocolProps::protoToString(Proto::OpenVpn)].toObject()[config_key::last_config].toString(); QString protocolConfigJson = QJsonDocument::fromJson(protocolConfig.toUtf8()).object()[config_key::config].toString(); @@ -679,8 +682,11 @@ void ImportController::checkForMaliciousStrings(const QJsonObject &serverConfig) } } + m_maliciousWarningText = tr("This configuration contains an OpenVPN setup. OpenVPN configurations can include malicious " + "scripts, so only add it if you fully trust the provider of this config. "); + if (maliciousStrings.size() >= dangerousTagsMaxCount) { - m_maliciousWarningText = tr("In the imported configuration, potentially dangerous lines were found:"); + m_maliciousWarningText.push_back(tr("
In the imported configuration, potentially dangerous lines were found:")); for (const auto &string : maliciousStrings) { m_maliciousWarningText.push_back(QString("
%1").arg(string)); } diff --git a/client/ui/models/languageModel.cpp b/client/ui/models/languageModel.cpp index 0041fdd0..09755e06 100644 --- a/client/ui/models/languageModel.cpp +++ b/client/ui/models/languageModel.cpp @@ -1,13 +1,11 @@ #include "languageModel.h" -LanguageModel::LanguageModel(std::shared_ptr settings, QObject *parent) - : m_settings(settings), QAbstractListModel(parent) +LanguageModel::LanguageModel(std::shared_ptr settings, QObject *parent) : m_settings(settings), QAbstractListModel(parent) { QMetaEnum metaEnum = QMetaEnum::fromType(); for (int i = 0; i < metaEnum.keyCount(); i++) { - m_availableLanguages.push_back( - LanguageModelData {getLocalLanguageName(static_cast(i)), - static_cast(i) }); + m_availableLanguages.push_back(LanguageModelData { getLocalLanguageName(static_cast(i)), + static_cast(i) }); } } @@ -50,8 +48,7 @@ QString LanguageModel::getLocalLanguageName(const LanguageSettings::AvailableLan case LanguageSettings::AvailableLanguageEnum::Burmese: strLanguage = "မြန်မာဘာသာ"; break; case LanguageSettings::AvailableLanguageEnum::Urdu: strLanguage = "اُرْدُوْ"; break; case LanguageSettings::AvailableLanguageEnum::Hindi: strLanguage = "हिन्दी"; break; - default: - break; + default: break; } return strLanguage; @@ -104,11 +101,12 @@ QString LanguageModel::getCurrentLanguageName() return m_availableLanguages[getCurrentLanguageIndex()].name; } -QString LanguageModel::getCurrentSiteUrl() +QString LanguageModel::getCurrentSiteUrl(const QString &path) { auto language = static_cast(getCurrentLanguageIndex()); switch (language) { - case LanguageSettings::AvailableLanguageEnum::Russian: return "https://storage.googleapis.com/amnezia/amnezia.org"; - default: return "https://amnezia.org"; + case LanguageSettings::AvailableLanguageEnum::Russian: + return "https://storage.googleapis.com/amnezia/amnezia.org" + (path.isEmpty() ? "" : (QString("?m-path=/%1").arg(path))); + default: return QString("https://amnezia.org") + (path.isEmpty() ? "" : (QString("/%1").arg(path))); } } diff --git a/client/ui/models/languageModel.h b/client/ui/models/languageModel.h index 2c80880a..d1a2e7d5 100644 --- a/client/ui/models/languageModel.h +++ b/client/ui/models/languageModel.h @@ -59,7 +59,7 @@ public slots: int getCurrentLanguageIndex(); int getLineHeightAppend(); QString getCurrentLanguageName(); - QString getCurrentSiteUrl(); + QString getCurrentSiteUrl(const QString &path = ""); signals: void updateTranslations(const QLocale &locale); diff --git a/client/ui/qml/Components/AdLabel.qml b/client/ui/qml/Components/AdLabel.qml index 91e1a42c..3ef0fc69 100644 --- a/client/ui/qml/Components/AdLabel.qml +++ b/client/ui/qml/Components/AdLabel.qml @@ -29,7 +29,7 @@ Rectangle { cursorShape: Qt.PointingHandCursor onClicked: function() { - Qt.openUrlExternally(LanguageModel.getCurrentSiteUrl() + "/premium") + Qt.openUrlExternally(LanguageModel.getCurrentSiteUrl("premium")) } } diff --git a/client/ui/qml/Pages2/PageSettingsAbout.qml b/client/ui/qml/Pages2/PageSettingsAbout.qml index 37327313..6342ce66 100644 --- a/client/ui/qml/Pages2/PageSettingsAbout.qml +++ b/client/ui/qml/Pages2/PageSettingsAbout.qml @@ -252,7 +252,7 @@ PageType { text: qsTr("Privacy Policy") clickedFunc: function() { - Qt.openUrlExternally(LanguageModel.getCurrentSiteUrl() + "/policy") + Qt.openUrlExternally(LanguageModel.getCurrentSiteUrl("policy")) } } } diff --git a/client/ui/qml/Pages2/PageSetupWizardCredentials.qml b/client/ui/qml/Pages2/PageSetupWizardCredentials.qml index ca7e3a7c..cdafa47f 100644 --- a/client/ui/qml/Pages2/PageSetupWizardCredentials.qml +++ b/client/ui/qml/Pages2/PageSetupWizardCredentials.qml @@ -175,7 +175,7 @@ PageType { leftImageSource: "qrc:/images/controls/help-circle.svg" onClicked: { - Qt.openUrlExternally(LanguageModel.getCurrentSiteUrl() + "/starter-guide") + Qt.openUrlExternally(LanguageModel.getCurrentSiteUrl("starter-guide")) } } } diff --git a/client/ui/qml/Pages2/PageSetupWizardEasy.qml b/client/ui/qml/Pages2/PageSetupWizardEasy.qml index 353eeb32..ae04f635 100644 --- a/client/ui/qml/Pages2/PageSetupWizardEasy.qml +++ b/client/ui/qml/Pages2/PageSetupWizardEasy.qml @@ -78,7 +78,7 @@ PageType { height: containers.contentItem.height spacing: 16 - currentIndex: 1 + currentIndex: 0 clip: true interactive: false model: proxyContainersModel