diff --git a/CMakeLists.txt b/CMakeLists.txt index e9146dfd1..13af39cf6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.25.0 FATAL_ERROR) set(PROJECT AmneziaVPN) -set(AMNEZIAVPN_VERSION 4.8.15.0) +set(AMNEZIAVPN_VERSION 4.8.15.1) project(${PROJECT} VERSION ${AMNEZIAVPN_VERSION} DESCRIPTION "AmneziaVPN" diff --git a/client/core/api/apiDefs.h b/client/core/api/apiDefs.h index ebcdced3b..2c2fd00f6 100644 --- a/client/core/api/apiDefs.h +++ b/client/core/api/apiDefs.h @@ -10,7 +10,6 @@ namespace apiDefs AmneziaFreeV3, AmneziaPremiumV1, AmneziaPremiumV2, - AmneziaTrialV2, SelfHosted, ExternalPremium, ExternalTrial @@ -57,6 +56,7 @@ namespace apiDefs constexpr QLatin1String maxDeviceCount("max_device_count"); constexpr QLatin1String subscriptionEndDate("subscription_end_date"); constexpr QLatin1String subscriptionExpiredByServer("subscription_expired_by_server"); + constexpr QLatin1String subscriptionStatus("subscription_status"); constexpr QLatin1String subscription("subscription"); constexpr QLatin1String endDate("end_date"); constexpr QLatin1String issuedConfigs("issued_configs"); @@ -83,6 +83,7 @@ namespace apiDefs constexpr QLatin1String serviceInfo("service_info"); constexpr QLatin1String isAdVisible("is_ad_visible"); + constexpr QLatin1String isRenewalAvailable("is_renewal_available"); constexpr QLatin1String adHeader("ad_header"); constexpr QLatin1String adDescription("ad_description"); constexpr QLatin1String adEndpoint("ad_endpoint"); diff --git a/client/core/api/apiUtils.cpp b/client/core/api/apiUtils.cpp index 3d6cb3352..5ed46d1f1 100644 --- a/client/core/api/apiUtils.cpp +++ b/client/core/api/apiUtils.cpp @@ -101,7 +101,6 @@ apiDefs::ConfigType apiUtils::getConfigType(const QJsonObject &serverConfigObjec }; case apiDefs::ConfigSource::AmneziaGateway: { constexpr QLatin1String servicePremium("amnezia-premium"); - constexpr QLatin1String serviceTrial("amnezia-trial"); constexpr QLatin1String serviceFree("amnezia-free"); constexpr QLatin1String serviceExternalPremium("external-premium"); constexpr QLatin1String serviceExternalTrial("external-trial"); @@ -111,8 +110,6 @@ apiDefs::ConfigType apiUtils::getConfigType(const QJsonObject &serverConfigObjec if (serviceType == servicePremium) { return apiDefs::ConfigType::AmneziaPremiumV2; - } else if (serviceType == serviceTrial) { - return apiDefs::ConfigType::AmneziaTrialV2; } else if (serviceType == serviceFree) { return apiDefs::ConfigType::AmneziaFreeV3; } else if (serviceType == serviceExternalPremium) { @@ -198,8 +195,7 @@ amnezia::ErrorCode apiUtils::checkNetworkReplyErrors(const QList &ssl bool apiUtils::isPremiumServer(const QJsonObject &serverConfigObject) { static const QSet premiumTypes = { apiDefs::ConfigType::AmneziaPremiumV1, apiDefs::ConfigType::AmneziaPremiumV2, - apiDefs::ConfigType::AmneziaTrialV2, apiDefs::ConfigType::ExternalPremium, - apiDefs::ConfigType::ExternalTrial }; + apiDefs::ConfigType::ExternalPremium, apiDefs::ConfigType::ExternalTrial }; return premiumTypes.contains(getConfigType(serverConfigObject)); } @@ -244,8 +240,8 @@ QString apiUtils::getPremiumV1VpnKey(const QJsonObject &serverConfigObject) QString apiUtils::getPremiumV2VpnKey(const QJsonObject &serverConfigObject) { auto configType = apiUtils::getConfigType(serverConfigObject); - if (configType != apiDefs::ConfigType::AmneziaPremiumV2 && configType != apiDefs::ConfigType::AmneziaTrialV2 - && configType != apiDefs::ConfigType::ExternalPremium && configType != apiDefs::ConfigType::ExternalTrial) { + if (configType != apiDefs::ConfigType::AmneziaPremiumV2 && configType != apiDefs::ConfigType::ExternalPremium + && configType != apiDefs::ConfigType::ExternalTrial) { return {}; } diff --git a/client/core/api/apiUtils.h b/client/core/api/apiUtils.h index 819242a5f..ba2a0103b 100644 --- a/client/core/api/apiUtils.h +++ b/client/core/api/apiUtils.h @@ -13,7 +13,7 @@ namespace apiUtils bool isSubscriptionExpired(const QString &subscriptionEndDate); - bool isSubscriptionExpiringSoon(const QString &subscriptionEndDate, int withinDays = 10); + bool isSubscriptionExpiringSoon(const QString &subscriptionEndDate, int withinDays = 30); bool isPremiumServer(const QJsonObject &serverConfigObject); diff --git a/client/ui/controllers/api/apiSettingsController.cpp b/client/ui/controllers/api/apiSettingsController.cpp index d96437666..9ba2262fc 100644 --- a/client/ui/controllers/api/apiSettingsController.cpp +++ b/client/ui/controllers/api/apiSettingsController.cpp @@ -23,6 +23,19 @@ namespace } const int requestTimeoutMsecs = 12 * 1000; // 12 secs + + QString getSubscriptionStatusForRenewal(const QSharedPointer &accountInfoModel) + { + if (!accountInfoModel.isNull() && accountInfoModel->data(QStringLiteral("isSubscriptionExpired")).toBool()) { + return QStringLiteral("expired"); + } + + if (!accountInfoModel.isNull() && accountInfoModel->data(QStringLiteral("isSubscriptionExpiringSoon")).toBool()) { + return QStringLiteral("expire_soon"); + } + + return QStringLiteral("active"); + } } ApiSettingsController::ApiSettingsController(const QSharedPointer &serversModel, @@ -105,6 +118,7 @@ void ApiSettingsController::getRenewalLink() apiPayload[configKey::authData] = authData; apiPayload[apiDefs::key::cliVersion] = QString(APP_VERSION); apiPayload[apiDefs::key::appLanguage] = m_settings->getAppLanguage().name().split("_").first(); + apiPayload[apiDefs::key::subscriptionStatus] = getSubscriptionStatusForRenewal(m_apiAccountInfoModel); auto future = gatewayController->postAsync(QString("%1v1/renewal_link"), apiPayload); future.then(this, [this, gatewayController](QPair result) { diff --git a/client/ui/models/api/apiAccountInfoModel.cpp b/client/ui/models/api/apiAccountInfoModel.cpp index 81112bb0f..13b19cfc7 100644 --- a/client/ui/models/api/apiAccountInfoModel.cpp +++ b/client/ui/models/api/apiAccountInfoModel.cpp @@ -54,14 +54,11 @@ QVariant ApiAccountInfoModel::data(const QModelIndex &index, int role) const } case IsComponentVisibleRole: { return m_accountInfoData.configType == apiDefs::ConfigType::AmneziaPremiumV2 - || m_accountInfoData.configType == apiDefs::ConfigType::AmneziaTrialV2 || m_accountInfoData.configType == apiDefs::ConfigType::ExternalPremium || m_accountInfoData.configType == apiDefs::ConfigType::ExternalTrial; } case IsSubscriptionRenewalAvailableRole: { - return m_accountInfoData.configType == apiDefs::ConfigType::AmneziaPremiumV2 - || m_accountInfoData.configType == apiDefs::ConfigType::AmneziaTrialV2 - || m_accountInfoData.configType == apiDefs::ConfigType::ExternalTrial; + return m_accountInfoData.isRenewalAvailable; } case HasExpiredWorkerRole: { for (int i = 0; i < m_issuedConfigsInfo.size(); i++) { @@ -133,6 +130,7 @@ void ApiAccountInfoModel::updateModel(const QJsonObject &accountInfoObject, cons accountInfoData.isInAppPurchase = apiConfig.value(apiDefs::key::isInAppPurchase).toBool(false); accountInfoData.subscriptionDescription = accountInfoObject.value(apiDefs::key::subscriptionDescription).toString(); + accountInfoData.isRenewalAvailable = accountInfoObject.value(apiDefs::key::isRenewalAvailable).toBool(false); for (const auto &protocol : accountInfoObject.value(apiDefs::key::supportedProtocols).toArray()) { accountInfoData.supportedProtocols.push_back(protocol.toString()); diff --git a/client/ui/models/api/apiAccountInfoModel.h b/client/ui/models/api/apiAccountInfoModel.h index fec24cb2d..b3f2270d7 100644 --- a/client/ui/models/api/apiAccountInfoModel.h +++ b/client/ui/models/api/apiAccountInfoModel.h @@ -61,6 +61,7 @@ private: QString subscriptionDescription; bool isInAppPurchase = false; + bool isRenewalAvailable = false; }; AccountInfoData m_accountInfoData; diff --git a/client/ui/models/servers_model.cpp b/client/ui/models/servers_model.cpp index eadc12e31..510c16170 100644 --- a/client/ui/models/servers_model.cpp +++ b/client/ui/models/servers_model.cpp @@ -179,6 +179,9 @@ QVariant ServersModel::data(const QModelIndex &index, int role) const case AdEndpointRole: { return apiConfig.value(apiDefs::key::serviceInfo).toObject().value(apiDefs::key::adEndpoint).toString(); } + case IsRenewalAvailableRole: { + return apiConfig.value(apiDefs::key::serviceInfo).toObject().value(apiDefs::key::isRenewalAvailable).toBool(false); + } case IsSubscriptionExpiredRole: { if (configVersion != apiDefs::ConfigSource::AmneziaGateway) { return false; @@ -473,6 +476,7 @@ QHash ServersModel::roleNames() const roles[AdHeaderRole] = "adHeader"; roles[AdDescriptionRole] = "adDescription"; roles[AdEndpointRole] = "adEndpoint"; + roles[IsRenewalAvailableRole] = "isRenewalAvailable"; roles[IsSubscriptionExpiredRole] = "isSubscriptionExpired"; roles[IsSubscriptionExpiringSoonRole] = "isSubscriptionExpiringSoon"; diff --git a/client/ui/models/servers_model.h b/client/ui/models/servers_model.h index 5264b35ba..548711a27 100644 --- a/client/ui/models/servers_model.h +++ b/client/ui/models/servers_model.h @@ -51,6 +51,7 @@ public: AdHeaderRole, AdDescriptionRole, AdEndpointRole, + IsRenewalAvailableRole, IsSubscriptionExpiredRole, IsSubscriptionExpiringSoonRole, diff --git a/client/ui/qml/Components/SubscriptionExpiredDrawer.qml b/client/ui/qml/Components/SubscriptionExpiredDrawer.qml index 230bc7db1..0d29cf75e 100644 --- a/client/ui/qml/Components/SubscriptionExpiredDrawer.qml +++ b/client/ui/qml/Components/SubscriptionExpiredDrawer.qml @@ -12,11 +12,10 @@ import "../Controls2/TextTypes" DrawerType2 { id: root - property bool isRenewalActionAvailable: false + property bool isRenewalAvailable: false onOpened: { - isRenewalActionAvailable = ApiAccountInfoModel.data("isSubscriptionRenewalAvailable") - && !ApiAccountInfoModel.data("isInAppPurchase") + isRenewalAvailable = ServersModel.getProcessedServerData("isRenewalAvailable") && !ApiAccountInfoModel.data("isInAppPurchase") } expandedStateContent: ColumnLayout { @@ -44,13 +43,13 @@ DrawerType2 { anchors.left: parent.left anchors.right: parent.right - text: qsTr("Amnezia Premium subscription has expired") + text: ServersModel.getProcessedServerData("name") + qsTr(" subscription has expired") horizontalAlignment: Text.AlignLeft } } ParagraphTextType { - visible: root.isRenewalActionAvailable + visible: root.isRenewalAvailable Layout.fillWidth: true Layout.topMargin: 8 @@ -62,7 +61,7 @@ DrawerType2 { } BasicButtonType { - visible: root.isRenewalActionAvailable + visible: root.isRenewalAvailable Layout.fillWidth: true Layout.topMargin: 16 @@ -96,8 +95,13 @@ DrawerType2 { text: qsTr("Support") clickedFunc: function() { - root.closeTriggered() - PageController.goToPage(PageEnum.PageSettingsApiSupport) + PageController.showBusyIndicator(true) + let result = ApiSettingsController.getAccountInfo(false) + PageController.showBusyIndicator(false) + if (result) { + root.closeTriggered() + PageController.goToPage(PageEnum.PageSettingsApiSupport) + } } } }