mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-06-23 02:00:20 +07:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1ea716a163 | |||
| 4551659c2a | |||
| c568bf8c24 | |||
| a412d91105 | |||
| ad01f23bbe | |||
| 656070b132 | |||
| c907f5ca36 | |||
| 94a13b2b54 |
@@ -23,7 +23,7 @@ namespace
|
|||||||
|
|
||||||
bool apiUtils::isSubscriptionExpired(const QString &subscriptionEndDate)
|
bool apiUtils::isSubscriptionExpired(const QString &subscriptionEndDate)
|
||||||
{
|
{
|
||||||
QDateTime now = QDateTime::currentDateTime();
|
QDateTime now = QDateTime::currentDateTimeUtc();
|
||||||
QDateTime endDate = QDateTime::fromString(subscriptionEndDate, Qt::ISODateWithMs);
|
QDateTime endDate = QDateTime::fromString(subscriptionEndDate, Qt::ISODateWithMs);
|
||||||
return endDate < now;
|
return endDate < now;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ ErrorCode GatewayController::get(const QString &endpoint, QByteArray &responseBo
|
|||||||
QNetworkRequest request;
|
QNetworkRequest request;
|
||||||
request.setTransferTimeout(m_requestTimeoutMsecs);
|
request.setTransferTimeout(m_requestTimeoutMsecs);
|
||||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||||
|
request.setRawHeader(QString("X-Client-Request-ID").toUtf8(), QUuid::createUuid().toString(QUuid::WithoutBraces).toUtf8());
|
||||||
|
|
||||||
request.setUrl(QString(endpoint).arg(m_proxyUrl.isEmpty() ? m_gatewayEndpoint : m_proxyUrl));
|
request.setUrl(QString(endpoint).arg(m_proxyUrl.isEmpty() ? m_gatewayEndpoint : m_proxyUrl));
|
||||||
|
|
||||||
@@ -122,6 +123,7 @@ ErrorCode GatewayController::post(const QString &endpoint, const QJsonObject api
|
|||||||
QNetworkRequest request;
|
QNetworkRequest request;
|
||||||
request.setTransferTimeout(m_requestTimeoutMsecs);
|
request.setTransferTimeout(m_requestTimeoutMsecs);
|
||||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||||
|
request.setRawHeader(QString("X-Client-Request-ID").toUtf8(), QUuid::createUuid().toString(QUuid::WithoutBraces).toUtf8());
|
||||||
|
|
||||||
request.setUrl(endpoint.arg(m_proxyUrl.isEmpty() ? m_gatewayEndpoint : m_proxyUrl));
|
request.setUrl(endpoint.arg(m_proxyUrl.isEmpty() ? m_gatewayEndpoint : m_proxyUrl));
|
||||||
|
|
||||||
|
|||||||
@@ -120,6 +120,7 @@ namespace amnezia
|
|||||||
ApiNotFoundError = 1109,
|
ApiNotFoundError = 1109,
|
||||||
ApiMigrationError = 1110,
|
ApiMigrationError = 1110,
|
||||||
ApiUpdateRequestError = 1111,
|
ApiUpdateRequestError = 1111,
|
||||||
|
ApiSubscriptionExpiredError = 1112,
|
||||||
|
|
||||||
// QFile errors
|
// QFile errors
|
||||||
OpenError = 1200,
|
OpenError = 1200,
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ QString errorString(ErrorCode code) {
|
|||||||
case (ErrorCode::ApiNotFoundError): errorMessage = QObject::tr("Error when retrieving configuration from API"); break;
|
case (ErrorCode::ApiNotFoundError): errorMessage = QObject::tr("Error when retrieving configuration from API"); break;
|
||||||
case (ErrorCode::ApiMigrationError): errorMessage = QObject::tr("A migration error has occurred. Please contact our technical support"); break;
|
case (ErrorCode::ApiMigrationError): errorMessage = QObject::tr("A migration error has occurred. Please contact our technical support"); break;
|
||||||
case (ErrorCode::ApiUpdateRequestError): errorMessage = QObject::tr("Please update the application to use this feature"); break;
|
case (ErrorCode::ApiUpdateRequestError): errorMessage = QObject::tr("Please update the application to use this feature"); break;
|
||||||
|
case (ErrorCode::ApiSubscriptionExpiredError): errorMessage = QObject::tr("Your Amnezia Premium subscription has expired.\n Please check your email for renewal instructions.\n If you haven't received an email, please contact our support."); break;
|
||||||
|
|
||||||
// QFile errors
|
// QFile errors
|
||||||
case(ErrorCode::OpenError): errorMessage = QObject::tr("QFile error: The file could not be opened"); break;
|
case(ErrorCode::OpenError): errorMessage = QObject::tr("QFile error: The file could not be opened"); break;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -29,6 +29,7 @@ namespace
|
|||||||
constexpr char uuid[] = "installation_uuid";
|
constexpr char uuid[] = "installation_uuid";
|
||||||
constexpr char osVersion[] = "os_version";
|
constexpr char osVersion[] = "os_version";
|
||||||
constexpr char appVersion[] = "app_version";
|
constexpr char appVersion[] = "app_version";
|
||||||
|
constexpr char appLanguage[] = "app_language";
|
||||||
|
|
||||||
constexpr char userCountryCode[] = "user_country_code";
|
constexpr char userCountryCode[] = "user_country_code";
|
||||||
constexpr char serverCountryCode[] = "server_country_code";
|
constexpr char serverCountryCode[] = "server_country_code";
|
||||||
@@ -43,6 +44,9 @@ namespace
|
|||||||
constexpr char authData[] = "auth_data";
|
constexpr char authData[] = "auth_data";
|
||||||
|
|
||||||
constexpr char config[] = "config";
|
constexpr char config[] = "config";
|
||||||
|
|
||||||
|
constexpr char subscription[] = "subscription";
|
||||||
|
constexpr char endDate[] = "end_date";
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ProtocolData
|
struct ProtocolData
|
||||||
@@ -163,7 +167,7 @@ namespace
|
|||||||
auto clientProtocolConfig =
|
auto clientProtocolConfig =
|
||||||
QJsonDocument::fromJson(serverProtocolConfig.value(config_key::last_config).toString().toUtf8()).object();
|
QJsonDocument::fromJson(serverProtocolConfig.value(config_key::last_config).toString().toUtf8()).object();
|
||||||
|
|
||||||
//TODO looks like this block can be removed after v1 configs EOL
|
// TODO looks like this block can be removed after v1 configs EOL
|
||||||
|
|
||||||
serverProtocolConfig[config_key::junkPacketCount] = clientProtocolConfig.value(config_key::junkPacketCount);
|
serverProtocolConfig[config_key::junkPacketCount] = clientProtocolConfig.value(config_key::junkPacketCount);
|
||||||
serverProtocolConfig[config_key::junkPacketMinSize] = clientProtocolConfig.value(config_key::junkPacketMinSize);
|
serverProtocolConfig[config_key::junkPacketMinSize] = clientProtocolConfig.value(config_key::junkPacketMinSize);
|
||||||
@@ -223,6 +227,19 @@ namespace
|
|||||||
|
|
||||||
return ErrorCode::NoError;
|
return ErrorCode::NoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isSubscriptionExpired(const QJsonObject &apiConfig)
|
||||||
|
{
|
||||||
|
auto subscription = apiConfig.value(configKey::subscription).toObject();
|
||||||
|
if (subscription.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto subscriptionEndDate = subscription.value(configKey::endDate).toString();
|
||||||
|
if (apiUtils::isSubscriptionExpired(subscriptionEndDate)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ApiConfigsController::ApiConfigsController(const QSharedPointer<ServersModel> &serversModel,
|
ApiConfigsController::ApiConfigsController(const QSharedPointer<ServersModel> &serversModel,
|
||||||
@@ -242,6 +259,11 @@ bool ApiConfigsController::exportNativeConfig(const QString &serverCountryCode,
|
|||||||
auto serverConfigObject = m_serversModel->getServerConfig(m_serversModel->getProcessedServerIndex());
|
auto serverConfigObject = m_serversModel->getServerConfig(m_serversModel->getProcessedServerIndex());
|
||||||
auto apiConfigObject = serverConfigObject.value(configKey::apiConfig).toObject();
|
auto apiConfigObject = serverConfigObject.value(configKey::apiConfig).toObject();
|
||||||
|
|
||||||
|
if (isSubscriptionExpired(apiConfigObject)) {
|
||||||
|
emit errorOccurred(ErrorCode::ApiSubscriptionExpiredError);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
GatewayRequestData gatewayRequestData { QSysInfo::productType(),
|
GatewayRequestData gatewayRequestData { QSysInfo::productType(),
|
||||||
QString(APP_VERSION),
|
QString(APP_VERSION),
|
||||||
m_settings->getInstallationUuid(true),
|
m_settings->getInstallationUuid(true),
|
||||||
@@ -277,6 +299,11 @@ bool ApiConfigsController::revokeNativeConfig(const QString &serverCountryCode)
|
|||||||
auto serverConfigObject = m_serversModel->getServerConfig(m_serversModel->getProcessedServerIndex());
|
auto serverConfigObject = m_serversModel->getServerConfig(m_serversModel->getProcessedServerIndex());
|
||||||
auto apiConfigObject = serverConfigObject.value(configKey::apiConfig).toObject();
|
auto apiConfigObject = serverConfigObject.value(configKey::apiConfig).toObject();
|
||||||
|
|
||||||
|
if (isSubscriptionExpired(apiConfigObject)) {
|
||||||
|
emit errorOccurred(ErrorCode::ApiSubscriptionExpiredError);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
GatewayRequestData gatewayRequestData { QSysInfo::productType(),
|
GatewayRequestData gatewayRequestData { QSysInfo::productType(),
|
||||||
QString(APP_VERSION),
|
QString(APP_VERSION),
|
||||||
m_settings->getInstallationUuid(true),
|
m_settings->getInstallationUuid(true),
|
||||||
@@ -322,6 +349,7 @@ bool ApiConfigsController::fillAvailableServices()
|
|||||||
{
|
{
|
||||||
QJsonObject apiPayload;
|
QJsonObject apiPayload;
|
||||||
apiPayload[configKey::osVersion] = QSysInfo::productType();
|
apiPayload[configKey::osVersion] = QSysInfo::productType();
|
||||||
|
apiPayload[configKey::appLanguage] = m_settings->getAppLanguage().name().split("_").first();
|
||||||
|
|
||||||
QByteArray responseBody;
|
QByteArray responseBody;
|
||||||
ErrorCode errorCode = executeRequest(QString("%1v1/services"), apiPayload, responseBody);
|
ErrorCode errorCode = executeRequest(QString("%1v1/services"), apiPayload, responseBody);
|
||||||
@@ -396,6 +424,11 @@ bool ApiConfigsController::updateServiceFromGateway(const int serverIndex, const
|
|||||||
auto serverConfig = m_serversModel->getServerConfig(serverIndex);
|
auto serverConfig = m_serversModel->getServerConfig(serverIndex);
|
||||||
auto apiConfig = serverConfig.value(configKey::apiConfig).toObject();
|
auto apiConfig = serverConfig.value(configKey::apiConfig).toObject();
|
||||||
|
|
||||||
|
if (isSubscriptionExpired(apiConfig)) {
|
||||||
|
emit errorOccurred(ErrorCode::ApiSubscriptionExpiredError);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
GatewayRequestData gatewayRequestData { QSysInfo::productType(),
|
GatewayRequestData gatewayRequestData { QSysInfo::productType(),
|
||||||
QString(APP_VERSION),
|
QString(APP_VERSION),
|
||||||
m_settings->getInstallationUuid(true),
|
m_settings->getInstallationUuid(true),
|
||||||
@@ -502,6 +535,11 @@ bool ApiConfigsController::deactivateDevice()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isSubscriptionExpired(apiConfigObject)) {
|
||||||
|
emit errorOccurred(ErrorCode::ApiSubscriptionExpiredError);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
GatewayRequestData gatewayRequestData { QSysInfo::productType(),
|
GatewayRequestData gatewayRequestData { QSysInfo::productType(),
|
||||||
QString(APP_VERSION),
|
QString(APP_VERSION),
|
||||||
m_settings->getInstallationUuid(true),
|
m_settings->getInstallationUuid(true),
|
||||||
@@ -536,6 +574,11 @@ bool ApiConfigsController::deactivateExternalDevice(const QString &uuid, const Q
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isSubscriptionExpired(apiConfigObject)) {
|
||||||
|
emit errorOccurred(ErrorCode::ApiSubscriptionExpiredError);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
GatewayRequestData gatewayRequestData { QSysInfo::productType(),
|
GatewayRequestData gatewayRequestData { QSysInfo::productType(),
|
||||||
QString(APP_VERSION),
|
QString(APP_VERSION),
|
||||||
uuid,
|
uuid,
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ namespace PageLoader
|
|||||||
PageSettingsApiDevices,
|
PageSettingsApiDevices,
|
||||||
PageSettingsApiSubscriptionKey,
|
PageSettingsApiSubscriptionKey,
|
||||||
PageSettingsKillSwitchExceptions,
|
PageSettingsKillSwitchExceptions,
|
||||||
|
|
||||||
PageServiceSftpSettings,
|
PageServiceSftpSettings,
|
||||||
PageServiceTorWebsiteSettings,
|
PageServiceTorWebsiteSettings,
|
||||||
PageServiceDnsSettings,
|
PageServiceDnsSettings,
|
||||||
@@ -125,6 +125,8 @@ signals:
|
|||||||
void goToPageViewConfig();
|
void goToPageViewConfig();
|
||||||
void goToPageSettingsServerServices();
|
void goToPageSettingsServerServices();
|
||||||
void goToPageSettingsBackup();
|
void goToPageSettingsBackup();
|
||||||
|
void goToShareConnectionPage(QString headerText, QString configContentHeaderText, QString configCaption, QString configExtension,
|
||||||
|
QString configFileName);
|
||||||
|
|
||||||
void closePage();
|
void closePage();
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ QVariant ApiAccountInfoModel::data(const QModelIndex &index, int role) const
|
|||||||
return tr("Active");
|
return tr("Active");
|
||||||
}
|
}
|
||||||
|
|
||||||
return apiUtils::isSubscriptionExpired(m_accountInfoData.subscriptionEndDate) ? tr("Inactive") : tr("Active");
|
return apiUtils::isSubscriptionExpired(m_accountInfoData.subscriptionEndDate) ? tr("<p><a style=\"color: #EB5757;\">Inactive</a>") : tr("Active");
|
||||||
}
|
}
|
||||||
case EndDateRole: {
|
case EndDateRole: {
|
||||||
if (m_accountInfoData.configType == apiDefs::ConfigType::AmneziaFreeV3) {
|
if (m_accountInfoData.configType == apiDefs::ConfigType::AmneziaFreeV3) {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ namespace
|
|||||||
constexpr char serviceInfo[] = "service_info";
|
constexpr char serviceInfo[] = "service_info";
|
||||||
constexpr char serviceType[] = "service_type";
|
constexpr char serviceType[] = "service_type";
|
||||||
constexpr char serviceProtocol[] = "service_protocol";
|
constexpr char serviceProtocol[] = "service_protocol";
|
||||||
|
constexpr char serviceDescription[] = "service_description";
|
||||||
|
|
||||||
constexpr char name[] = "name";
|
constexpr char name[] = "name";
|
||||||
constexpr char price[] = "price";
|
constexpr char price[] = "price";
|
||||||
@@ -22,6 +23,10 @@ namespace
|
|||||||
constexpr char timelimit[] = "timelimit";
|
constexpr char timelimit[] = "timelimit";
|
||||||
constexpr char region[] = "region";
|
constexpr char region[] = "region";
|
||||||
|
|
||||||
|
constexpr char description[] = "description";
|
||||||
|
constexpr char cardDescription[] = "card_description";
|
||||||
|
constexpr char features[] = "features";
|
||||||
|
|
||||||
constexpr char availableCountries[] = "available_countries";
|
constexpr char availableCountries[] = "available_countries";
|
||||||
|
|
||||||
constexpr char storeEndpoint[] = "store_endpoint";
|
constexpr char storeEndpoint[] = "store_endpoint";
|
||||||
@@ -65,11 +70,9 @@ QVariant ApiServicesModel::data(const QModelIndex &index, int role) const
|
|||||||
case CardDescriptionRole: {
|
case CardDescriptionRole: {
|
||||||
auto speed = apiServiceData.serviceInfo.speed;
|
auto speed = apiServiceData.serviceInfo.speed;
|
||||||
if (serviceType == serviceType::amneziaPremium) {
|
if (serviceType == serviceType::amneziaPremium) {
|
||||||
return tr("Amnezia Premium is classic VPN for seamless work, downloading large files, and watching videos. "
|
return apiServiceData.serviceInfo.cardDescription.arg(speed);
|
||||||
"Access all websites and online resources. Speeds up to %1 Mbps.")
|
|
||||||
.arg(speed);
|
|
||||||
} else if (serviceType == serviceType::amneziaFree) {
|
} else if (serviceType == serviceType::amneziaFree) {
|
||||||
QString description = tr("Amnezia Free provides unlimited, free access to a basic set of websites and apps, including Facebook, Instagram, Twitter (X), Discord, Telegram, and more. YouTube is not included in the free plan.");
|
QString description = apiServiceData.serviceInfo.cardDescription;
|
||||||
if (!isServiceAvailable) {
|
if (!isServiceAvailable) {
|
||||||
description += tr("<p><a style=\"color: #EB5757;\">Not available in your region. If you have VPN enabled, disable it, "
|
description += tr("<p><a style=\"color: #EB5757;\">Not available in your region. If you have VPN enabled, disable it, "
|
||||||
"return to the previous screen, and try again.</a>");
|
"return to the previous screen, and try again.</a>");
|
||||||
@@ -78,12 +81,7 @@ QVariant ApiServicesModel::data(const QModelIndex &index, int role) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case ServiceDescriptionRole: {
|
case ServiceDescriptionRole: {
|
||||||
if (serviceType == serviceType::amneziaPremium) {
|
return apiServiceData.serviceInfo.description;
|
||||||
return tr("Amnezia Premium is classic VPN for for seamless work, downloading large files, and watching videos. "
|
|
||||||
"Access all websites and online resources.");
|
|
||||||
} else {
|
|
||||||
return tr("Amnezia Free provides unlimited, free access to a basic set of websites and apps, including Facebook, Instagram, Twitter (X), Discord, Telegram, and more. YouTube is not included in the free plan.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
case IsServiceAvailableRole: {
|
case IsServiceAvailableRole: {
|
||||||
if (serviceType == serviceType::amneziaFree) {
|
if (serviceType == serviceType::amneziaFree) {
|
||||||
@@ -107,13 +105,7 @@ QVariant ApiServicesModel::data(const QModelIndex &index, int role) const
|
|||||||
return apiServiceData.serviceInfo.region;
|
return apiServiceData.serviceInfo.region;
|
||||||
}
|
}
|
||||||
case FeaturesRole: {
|
case FeaturesRole: {
|
||||||
if (serviceType == serviceType::amneziaPremium) {
|
return apiServiceData.serviceInfo.features;
|
||||||
return tr("");
|
|
||||||
} else {
|
|
||||||
return tr("VPN will open only popular sites blocked in your region, such as Instagram, Facebook, Twitter and others. "
|
|
||||||
"Other sites will be opened from your real IP address, "
|
|
||||||
"<a href=\"%1\" style=\"color: #FBB26A;\">more details on the website.</a>");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
case PriceRole: {
|
case PriceRole: {
|
||||||
auto price = apiServiceData.serviceInfo.price;
|
auto price = apiServiceData.serviceInfo.price;
|
||||||
@@ -125,6 +117,13 @@ QVariant ApiServicesModel::data(const QModelIndex &index, int role) const
|
|||||||
case EndDateRole: {
|
case EndDateRole: {
|
||||||
return QDateTime::fromString(apiServiceData.subscription.endDate, Qt::ISODate).toLocalTime().toString("d MMM yyyy");
|
return QDateTime::fromString(apiServiceData.subscription.endDate, Qt::ISODate).toLocalTime().toString("d MMM yyyy");
|
||||||
}
|
}
|
||||||
|
case OrderRole: {
|
||||||
|
if (serviceType == serviceType::amneziaPremium) {
|
||||||
|
return 0;
|
||||||
|
} else if (serviceType == serviceType::amneziaFree) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return QVariant();
|
return QVariant();
|
||||||
@@ -224,6 +223,7 @@ QHash<int, QByteArray> ApiServicesModel::roleNames() const
|
|||||||
roles[FeaturesRole] = "features";
|
roles[FeaturesRole] = "features";
|
||||||
roles[PriceRole] = "price";
|
roles[PriceRole] = "price";
|
||||||
roles[EndDateRole] = "endDate";
|
roles[EndDateRole] = "endDate";
|
||||||
|
roles[OrderRole] = "order";
|
||||||
|
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
@@ -234,6 +234,7 @@ ApiServicesModel::ApiServicesData ApiServicesModel::getApiServicesData(const QJs
|
|||||||
auto serviceType = data.value(configKey::serviceType).toString();
|
auto serviceType = data.value(configKey::serviceType).toString();
|
||||||
auto serviceProtocol = data.value(configKey::serviceProtocol).toString();
|
auto serviceProtocol = data.value(configKey::serviceProtocol).toString();
|
||||||
auto availableCountries = data.value(configKey::availableCountries).toArray();
|
auto availableCountries = data.value(configKey::availableCountries).toArray();
|
||||||
|
auto serviceDescription = data.value(configKey::serviceDescription).toObject();
|
||||||
|
|
||||||
auto subscriptionObject = data.value(configKey::subscription).toObject();
|
auto subscriptionObject = data.value(configKey::subscription).toObject();
|
||||||
|
|
||||||
@@ -244,6 +245,10 @@ ApiServicesModel::ApiServicesData ApiServicesModel::getApiServicesData(const QJs
|
|||||||
serviceData.serviceInfo.speed = serviceInfo.value(configKey::speed).toString();
|
serviceData.serviceInfo.speed = serviceInfo.value(configKey::speed).toString();
|
||||||
serviceData.serviceInfo.timeLimit = serviceInfo.value(configKey::timelimit).toString();
|
serviceData.serviceInfo.timeLimit = serviceInfo.value(configKey::timelimit).toString();
|
||||||
|
|
||||||
|
serviceData.serviceInfo.cardDescription = serviceDescription.value(configKey::cardDescription).toString();
|
||||||
|
serviceData.serviceInfo.description = serviceDescription.value(configKey::description).toString();
|
||||||
|
serviceData.serviceInfo.features = serviceDescription.value(configKey::features).toString();
|
||||||
|
|
||||||
serviceData.type = serviceType;
|
serviceData.type = serviceType;
|
||||||
serviceData.protocol = serviceProtocol;
|
serviceData.protocol = serviceProtocol;
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ public:
|
|||||||
RegionRole,
|
RegionRole,
|
||||||
FeaturesRole,
|
FeaturesRole,
|
||||||
PriceRole,
|
PriceRole,
|
||||||
EndDateRole
|
EndDateRole,
|
||||||
|
OrderRole
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit ApiServicesModel(QObject *parent = nullptr);
|
explicit ApiServicesModel(QObject *parent = nullptr);
|
||||||
@@ -58,6 +59,10 @@ private:
|
|||||||
QString region;
|
QString region;
|
||||||
QString price;
|
QString price;
|
||||||
|
|
||||||
|
QString description;
|
||||||
|
QString features;
|
||||||
|
QString cardDescription;
|
||||||
|
|
||||||
QJsonObject object;
|
QJsonObject object;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -7,17 +7,20 @@ import Style 1.0
|
|||||||
import "TextTypes"
|
import "TextTypes"
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
|
id: root
|
||||||
|
|
||||||
property string imageSource
|
property string imageSource
|
||||||
property string leftText
|
property string leftText
|
||||||
property var rightText
|
property var rightText
|
||||||
property bool isRightTextUndefined: rightText === undefined
|
property bool isRightTextUndefined: rightText === undefined
|
||||||
|
property int rightTextFormat: Text.PlainText
|
||||||
|
|
||||||
visible: !isRightTextUndefined
|
visible: !isRightTextUndefined
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
Layout.preferredHeight: 18
|
Layout.preferredHeight: 18
|
||||||
Layout.preferredWidth: 18
|
Layout.preferredWidth: 18
|
||||||
source: imageSource
|
source: root.imageSource
|
||||||
}
|
}
|
||||||
|
|
||||||
ListItemTitleType {
|
ListItemTitleType {
|
||||||
@@ -25,14 +28,15 @@ RowLayout {
|
|||||||
Layout.rightMargin: 10
|
Layout.rightMargin: 10
|
||||||
Layout.alignment: Qt.AlignRight
|
Layout.alignment: Qt.AlignRight
|
||||||
|
|
||||||
text: leftText
|
text: root.leftText
|
||||||
}
|
}
|
||||||
|
|
||||||
ParagraphTextType {
|
ParagraphTextType {
|
||||||
visible: rightText !== ""
|
visible: root.rightText !== ""
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignLeft
|
Layout.alignment: Qt.AlignLeft
|
||||||
|
|
||||||
text: isRightTextUndefined ? "" : rightText
|
text: root.isRightTextUndefined ? "" : root.rightText
|
||||||
|
textFormat: root.rightTextFormat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ PageType {
|
|||||||
readonly property string title: qsTr("Subscription Status")
|
readonly property string title: qsTr("Subscription Status")
|
||||||
readonly property string contentKey: "subscriptionStatus"
|
readonly property string contentKey: "subscriptionStatus"
|
||||||
readonly property string objectImageSource: "qrc:/images/controls/info.svg"
|
readonly property string objectImageSource: "qrc:/images/controls/info.svg"
|
||||||
|
readonly property bool isRichText: true
|
||||||
}
|
}
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
@@ -37,6 +38,7 @@ PageType {
|
|||||||
readonly property string title: qsTr("Valid Until")
|
readonly property string title: qsTr("Valid Until")
|
||||||
readonly property string contentKey: "endDate"
|
readonly property string contentKey: "endDate"
|
||||||
readonly property string objectImageSource: "qrc:/images/controls/history.svg"
|
readonly property string objectImageSource: "qrc:/images/controls/history.svg"
|
||||||
|
readonly property bool isRichText: false
|
||||||
}
|
}
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
@@ -45,6 +47,7 @@ PageType {
|
|||||||
readonly property string title: qsTr("Active Connections")
|
readonly property string title: qsTr("Active Connections")
|
||||||
readonly property string contentKey: "connectedDevices"
|
readonly property string contentKey: "connectedDevices"
|
||||||
readonly property string objectImageSource: "qrc:/images/controls/monitor.svg"
|
readonly property string objectImageSource: "qrc:/images/controls/monitor.svg"
|
||||||
|
readonly property bool isRichText: false
|
||||||
}
|
}
|
||||||
|
|
||||||
property var processedServer
|
property var processedServer
|
||||||
@@ -134,6 +137,7 @@ PageType {
|
|||||||
imageSource: objectImageSource
|
imageSource: objectImageSource
|
||||||
leftText: title
|
leftText: title
|
||||||
rightText: ApiAccountInfoModel.data(contentKey)
|
rightText: ApiAccountInfoModel.data(contentKey)
|
||||||
|
rightTextFormat: isRichText ? Text.RichText : Text.PlainText
|
||||||
|
|
||||||
visible: rightText !== ""
|
visible: rightText !== ""
|
||||||
}
|
}
|
||||||
@@ -214,9 +218,6 @@ PageType {
|
|||||||
ApiConfigsController.prepareVpnKeyExport()
|
ApiConfigsController.prepareVpnKeyExport()
|
||||||
|
|
||||||
PageController.showBusyIndicator(false)
|
PageController.showBusyIndicator(false)
|
||||||
|
|
||||||
// Navigate to PageShareConnection page
|
|
||||||
//PageController.goToPage(PageEnum.PageShareConnection)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,14 +53,6 @@ PageType {
|
|||||||
Layout.leftMargin: 16
|
Layout.leftMargin: 16
|
||||||
Layout.rightMargin: 16
|
Layout.rightMargin: 16
|
||||||
|
|
||||||
defaultColor: AmneziaStyle.color.paleGray
|
|
||||||
hoveredColor: AmneziaStyle.color.sheerWhite
|
|
||||||
pressedColor: AmneziaStyle.color.translucentWhite
|
|
||||||
disabledColor: AmneziaStyle.color.mutedGray
|
|
||||||
textColor: AmneziaStyle.color.black
|
|
||||||
leftImageColor: "black"
|
|
||||||
borderWidth: 1
|
|
||||||
|
|
||||||
text: qsTr("Copy key")
|
text: qsTr("Copy key")
|
||||||
leftImageSource: "qrc:/images/controls/copy.svg"
|
leftImageSource: "qrc:/images/controls/copy.svg"
|
||||||
|
|
||||||
@@ -194,7 +186,7 @@ PageType {
|
|||||||
font.pixelSize: 16
|
font.pixelSize: 16
|
||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
font.family: "PT Root UI VF"
|
font.family: "PT Root UI VF"
|
||||||
text: ApiConfigsController.vpnKey //|| ""
|
text: ApiConfigsController.vpnKey
|
||||||
wrapMode: Text.Wrap
|
wrapMode: Text.Wrap
|
||||||
background: Rectangle { color: AmneziaStyle.color.transparent }
|
background: Rectangle { color: AmneziaStyle.color.transparent }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -167,7 +167,8 @@ PageType {
|
|||||||
|
|
||||||
// Show service logs only if this is NOT a macOS build with
|
// Show service logs only if this is NOT a macOS build with
|
||||||
// Network-Extension (IsMacOsNeBuild is injected from C++ at run-time)
|
// Network-Extension (IsMacOsNeBuild is injected from C++ at run-time)
|
||||||
property list<QtObject> logTypes: IsMacOsNeBuild ? [
|
// or if this is NOT a mobile build
|
||||||
|
property list<QtObject> logTypes: (IsMacOsNeBuild || GC.isMobile()) ? [
|
||||||
clientLogs
|
clientLogs
|
||||||
] : [
|
] : [
|
||||||
clientLogs,
|
clientLogs,
|
||||||
@@ -214,15 +215,11 @@ PageType {
|
|||||||
}
|
}
|
||||||
readonly property var exportLogsHandler: function() {
|
readonly property var exportLogsHandler: function() {
|
||||||
var fileName = ""
|
var fileName = ""
|
||||||
if (GC.isMobile()) {
|
fileName = SystemController.getFileName(qsTr("Save"),
|
||||||
fileName = "AmneziaVPN-service.log"
|
qsTr("Logs files (*.log)"),
|
||||||
} else {
|
StandardPaths.standardLocations(StandardPaths.DocumentsLocation) + "/AmneziaVPN-service",
|
||||||
fileName = SystemController.getFileName(qsTr("Save"),
|
true,
|
||||||
qsTr("Logs files (*.log)"),
|
".log")
|
||||||
StandardPaths.standardLocations(StandardPaths.DocumentsLocation) + "/AmneziaVPN-service",
|
|
||||||
true,
|
|
||||||
".log")
|
|
||||||
}
|
|
||||||
if (fileName !== "") {
|
if (fileName !== "") {
|
||||||
PageController.showBusyIndicator(true)
|
PageController.showBusyIndicator(true)
|
||||||
SettingsController.exportServiceLogsFile(fileName)
|
SettingsController.exportServiceLogsFile(fileName)
|
||||||
|
|||||||
@@ -66,6 +66,8 @@ PageType {
|
|||||||
imageSource: imagePath
|
imageSource: imagePath
|
||||||
leftText: lText
|
leftText: lText
|
||||||
rightText: rText
|
rightText: rText
|
||||||
|
|
||||||
|
visible: isVisible
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ import QtQuick.Controls
|
|||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import QtQuick.Dialogs
|
import QtQuick.Dialogs
|
||||||
|
|
||||||
|
import SortFilterProxyModel 0.2
|
||||||
|
|
||||||
import PageEnum 1.0
|
import PageEnum 1.0
|
||||||
import Style 1.0
|
import Style 1.0
|
||||||
|
|
||||||
@@ -54,7 +56,15 @@ PageType {
|
|||||||
|
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
model: ApiServicesModel
|
model: SortFilterProxyModel {
|
||||||
|
id: proxyApiServicesModel
|
||||||
|
|
||||||
|
sourceModel: ApiServicesModel
|
||||||
|
sorters: RoleSorter {
|
||||||
|
roleName: "order"
|
||||||
|
sortOrder: Qt.AscendingOrder
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
delegate: ColumnLayout {
|
delegate: ColumnLayout {
|
||||||
|
|
||||||
@@ -78,7 +88,7 @@ PageType {
|
|||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (isServiceAvailable) {
|
if (isServiceAvailable) {
|
||||||
ApiServicesModel.setServiceIndex(index)
|
ApiServicesModel.setServiceIndex(proxyApiServicesModel.mapToSource(index))
|
||||||
PageController.goToPage(PageEnum.PageSetupWizardApiServiceInfo)
|
PageController.goToPage(PageEnum.PageSetupWizardApiServiceInfo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,40 +45,67 @@ PageType {
|
|||||||
function onGenerateConfig(type) {
|
function onGenerateConfig(type) {
|
||||||
PageController.showBusyIndicator(true)
|
PageController.showBusyIndicator(true)
|
||||||
|
|
||||||
|
var configCaption
|
||||||
|
var configExtension
|
||||||
|
var configFileName
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case PageShare.ConfigType.AmneziaConnection: {
|
case PageShare.ConfigType.AmneziaConnection: {
|
||||||
ExportController.generateConnectionConfig(clientNameTextField.textField.text);
|
ExportController.generateConnectionConfig(clientNameTextField.textField.text);
|
||||||
|
configCaption = qsTr("Save AmneziaVPN config")
|
||||||
|
configExtension = ".vpn"
|
||||||
|
configFileName = "amnezia_config"
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PageShare.ConfigType.OpenVpn: {
|
case PageShare.ConfigType.OpenVpn: {
|
||||||
ExportController.generateOpenVpnConfig(clientNameTextField.textField.text)
|
ExportController.generateOpenVpnConfig(clientNameTextField.textField.text)
|
||||||
|
configCaption = qsTr("Save OpenVPN config")
|
||||||
|
configExtension = ".ovpn"
|
||||||
|
configFileName = "amnezia_for_openvpn"
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case PageShare.ConfigType.WireGuard: {
|
case PageShare.ConfigType.WireGuard: {
|
||||||
ExportController.generateWireGuardConfig(clientNameTextField.textField.text)
|
ExportController.generateWireGuardConfig(clientNameTextField.textField.text)
|
||||||
|
configCaption = qsTr("Save WireGuard config")
|
||||||
|
configExtension = ".conf"
|
||||||
|
configFileName = "amnezia_for_wireguard"
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case PageShare.ConfigType.Awg: {
|
case PageShare.ConfigType.Awg: {
|
||||||
ExportController.generateAwgConfig(clientNameTextField.textField.text)
|
ExportController.generateAwgConfig(clientNameTextField.textField.text)
|
||||||
|
configCaption = qsTr("Save AmneziaWG config")
|
||||||
|
configExtension = ".conf"
|
||||||
|
configFileName = "amnezia_for_awg"
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case PageShare.ConfigType.ShadowSocks: {
|
case PageShare.ConfigType.ShadowSocks: {
|
||||||
ExportController.generateShadowSocksConfig()
|
ExportController.generateShadowSocksConfig()
|
||||||
|
configCaption = qsTr("Save Shadowsocks config")
|
||||||
|
configExtension = ".json"
|
||||||
|
configFileName = "amnezia_for_shadowsocks"
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case PageShare.ConfigType.Cloak: {
|
case PageShare.ConfigType.Cloak: {
|
||||||
ExportController.generateCloakConfig()
|
ExportController.generateCloakConfig()
|
||||||
|
configCaption = qsTr("Save Cloak config")
|
||||||
|
configExtension = ".json"
|
||||||
|
configFileName = "amnezia_for_cloak"
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case PageShare.ConfigType.Xray: {
|
case PageShare.ConfigType.Xray: {
|
||||||
ExportController.generateXrayConfig(clientNameTextField.textField.text)
|
ExportController.generateXrayConfig(clientNameTextField.textField.text)
|
||||||
|
configCaption = qsTr("Save XRay config")
|
||||||
|
configExtension = ".json"
|
||||||
|
configFileName = "amnezia_for_xray"
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PageController.showBusyIndicator(false)
|
PageController.showBusyIndicator(false)
|
||||||
|
|
||||||
PageController.goToPage(PageEnum.PageShareConnection)
|
var headerText = qsTr("Connection to ") + serverSelector.text
|
||||||
|
var configContentHeaderText = qsTr("File with connection settings to ") + serverSelector.text
|
||||||
|
PageController.goToShareConnectionPage(headerText, configContentHeaderText, configCaption, configExtension, configFileName)
|
||||||
}
|
}
|
||||||
|
|
||||||
function onExportErrorOccurred(error) {
|
function onExportErrorOccurred(error) {
|
||||||
|
|||||||
@@ -21,12 +21,6 @@ PageType {
|
|||||||
id: pageShareConnection
|
id: pageShareConnection
|
||||||
|
|
||||||
property string headerText
|
property string headerText
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
var serverName = ServersModel.getProcessedServerData("name") || ServersModel.getProcessedServerData("hostName") || "Server"
|
|
||||||
headerText = qsTr("Connection to ") + serverName
|
|
||||||
configContentHeaderText = qsTr("File with connection settings to ") + serverName
|
|
||||||
}
|
|
||||||
property string configContentHeaderText
|
property string configContentHeaderText
|
||||||
property string shareButtonText: qsTr("Share")
|
property string shareButtonText: qsTr("Share")
|
||||||
property string copyButtonText: qsTr("Copy")
|
property string copyButtonText: qsTr("Copy")
|
||||||
@@ -36,17 +30,17 @@ PageType {
|
|||||||
property string configCaption: qsTr("Save AmneziaVPN config")
|
property string configCaption: qsTr("Save AmneziaVPN config")
|
||||||
property string configFileName: "amnezia_config"
|
property string configFileName: "amnezia_config"
|
||||||
|
|
||||||
onVisibleChanged: {
|
// onVisibleChanged: {
|
||||||
configExtension = ".vpn"
|
// configExtension = ".vpn"
|
||||||
configCaption = qsTr("Save AmneziaVPN config")
|
// configCaption = qsTr("Save AmneziaVPN config")
|
||||||
configFileName = "amnezia_config"
|
// configFileName = "amnezia_config"
|
||||||
|
|
||||||
if (visible) {
|
// if (visible) {
|
||||||
var serverName = ServersModel.getProcessedServerData("name") || ServersModel.getProcessedServerData("hostName") || "Server"
|
// var serverName = ServersModel.getProcessedServerData("name") || ServersModel.getProcessedServerData("hostName") || "Server"
|
||||||
headerText = qsTr("Connection to ") + serverName
|
// headerText = qsTr("Connection to ") + serverName
|
||||||
configContentHeaderText = qsTr("File with connection settings to ") + serverName
|
// configContentHeaderText = qsTr("File with connection settings to ") + serverName
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
BackButtonType {
|
BackButtonType {
|
||||||
id: backButton
|
id: backButton
|
||||||
|
|||||||
@@ -37,6 +37,9 @@ PageType {
|
|||||||
ListViewType {
|
ListViewType {
|
||||||
id: listView
|
id: listView
|
||||||
|
|
||||||
|
property string headerText: ""
|
||||||
|
property string configContentHeaderText: ""
|
||||||
|
|
||||||
anchors.top: backButton.bottom
|
anchors.top: backButton.bottom
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
@@ -108,8 +111,8 @@ PageType {
|
|||||||
serverSelector.currentIndex = serverSelectorListView.currentIndex
|
serverSelector.currentIndex = serverSelectorListView.currentIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
shareConnectionPage.headerText = qsTr("Accessing ") + serverSelector.text
|
listView.headerText = qsTr("Accessing ") + serverSelector.text
|
||||||
shareConnectionPage.configContentHeaderText = qsTr("File with accessing settings to ") + serverSelector.text
|
listView.configContentHeaderText = qsTr("File with accessing settings to ") + serverSelector.text
|
||||||
serverSelector.closeTriggered()
|
serverSelector.closeTriggered()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,7 +159,7 @@ PageType {
|
|||||||
|
|
||||||
PageController.showBusyIndicator(false)
|
PageController.showBusyIndicator(false)
|
||||||
|
|
||||||
PageController.goToPage(PageEnum.PageShareConnection)
|
PageController.goToShareConnectionPage(listView.headerText, listView.configContentHeaderText, "", "", "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,6 +44,19 @@ PageType {
|
|||||||
tabBarStackView.push(pagePath, { "objectName" : pagePath }, StackView.PushTransition)
|
tabBarStackView.push(pagePath, { "objectName" : pagePath }, StackView.PushTransition)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onGoToShareConnectionPage(headerText, configContentHeaderText, configCaption, configExtension, configFileName) {
|
||||||
|
var pagePath = PageController.getPagePath(PageEnum.PageShareConnection)
|
||||||
|
tabBarStackView.push(pagePath,
|
||||||
|
{ "objectName" : pagePath,
|
||||||
|
"headerText" : headerText,
|
||||||
|
"configContentHeaderText" : configContentHeaderText,
|
||||||
|
"configCaption" : configCaption,
|
||||||
|
"configExtension" : configExtension,
|
||||||
|
"configFileName" : configFileName
|
||||||
|
},
|
||||||
|
StackView.PushTransition)
|
||||||
|
}
|
||||||
|
|
||||||
function onDisableControls(disabled) {
|
function onDisableControls(disabled) {
|
||||||
isControlsDisabled = disabled
|
isControlsDisabled = disabled
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ void IpcProcessTun2Socks::start()
|
|||||||
QString XrayConStr = "socks5://127.0.0.1:10808";
|
QString XrayConStr = "socks5://127.0.0.1:10808";
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
QStringList arguments({"-device", "tun://tun2", "-proxy", XrayConStr, "-tun-post-up",
|
QStringList arguments({"-device", "tun://tun2?guid={081A8A84-8D12-4DF5-B8C4-396D5B0053E4}", "-proxy", XrayConStr, "-tun-post-up",
|
||||||
QString("cmd /c netsh interface ip set address name=\"tun2\" static %1 255.255.255.255")
|
QString("cmd /c netsh interface ip set address name=\"tun2\" static %1 255.255.255.255")
|
||||||
.arg(amnezia::protocols::xray::defaultLocalAddr)});
|
.arg(amnezia::protocols::xray::defaultLocalAddr)});
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user