mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-05-08 14:33:23 +00:00
feat: add renewal for external-premium (#2485)
* feat: add renewal for external-premium * chore: bump version * chore: send subscription status for renewal link request
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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<QSslError> &ssl
|
||||
bool apiUtils::isPremiumServer(const QJsonObject &serverConfigObject)
|
||||
{
|
||||
static const QSet<apiDefs::ConfigType> 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 {};
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -23,6 +23,19 @@ namespace
|
||||
}
|
||||
|
||||
const int requestTimeoutMsecs = 12 * 1000; // 12 secs
|
||||
|
||||
QString getSubscriptionStatusForRenewal(const QSharedPointer<ApiAccountInfoModel> &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> &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<ErrorCode, QByteArray> result) {
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -61,6 +61,7 @@ private:
|
||||
QString subscriptionDescription;
|
||||
|
||||
bool isInAppPurchase = false;
|
||||
bool isRenewalAvailable = false;
|
||||
};
|
||||
|
||||
AccountInfoData m_accountInfoData;
|
||||
|
||||
@@ -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<int, QByteArray> ServersModel::roleNames() const
|
||||
roles[AdHeaderRole] = "adHeader";
|
||||
roles[AdDescriptionRole] = "adDescription";
|
||||
roles[AdEndpointRole] = "adEndpoint";
|
||||
roles[IsRenewalAvailableRole] = "isRenewalAvailable";
|
||||
|
||||
roles[IsSubscriptionExpiredRole] = "isSubscriptionExpired";
|
||||
roles[IsSubscriptionExpiringSoonRole] = "isSubscriptionExpiringSoon";
|
||||
|
||||
@@ -51,6 +51,7 @@ public:
|
||||
AdHeaderRole,
|
||||
AdDescriptionRole,
|
||||
AdEndpointRole,
|
||||
IsRenewalAvailableRole,
|
||||
|
||||
IsSubscriptionExpiredRole,
|
||||
IsSubscriptionExpiringSoonRole,
|
||||
|
||||
@@ -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,9 +95,14 @@ DrawerType2 {
|
||||
text: qsTr("Support")
|
||||
|
||||
clickedFunc: function() {
|
||||
PageController.showBusyIndicator(true)
|
||||
let result = ApiSettingsController.getAccountInfo(false)
|
||||
PageController.showBusyIndicator(false)
|
||||
if (result) {
|
||||
root.closeTriggered()
|
||||
PageController.goToPage(PageEnum.PageSettingsApiSupport)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user