New start page and AmneziaFree support (#865)
New start page and AmneziaFree support
This commit is contained in:
parent
01413e5a4c
commit
843156cf1b
443 changed files with 11759 additions and 2758 deletions
80
client/ui/models/apiCountryModel.cpp
Normal file
80
client/ui/models/apiCountryModel.cpp
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
#include "apiCountryModel.h"
|
||||
|
||||
#include <QJsonObject>
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
Logger logger("ApiCountryModel");
|
||||
|
||||
namespace configKey
|
||||
{
|
||||
constexpr char serverCountryCode[] = "server_country_code";
|
||||
constexpr char serverCountryName[] = "server_country_name";
|
||||
}
|
||||
}
|
||||
|
||||
ApiCountryModel::ApiCountryModel(QObject *parent) : QAbstractListModel(parent)
|
||||
{
|
||||
}
|
||||
|
||||
int ApiCountryModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
return m_countries.size();
|
||||
}
|
||||
|
||||
QVariant ApiCountryModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid() || index.row() < 0 || index.row() >= static_cast<int>(rowCount()))
|
||||
return QVariant();
|
||||
|
||||
QJsonObject countryInfo = m_countries.at(index.row()).toObject();
|
||||
|
||||
switch (role) {
|
||||
case CountryCodeRole: {
|
||||
return countryInfo.value(configKey::serverCountryCode).toString();
|
||||
}
|
||||
case CountryNameRole: {
|
||||
return countryInfo.value(configKey::serverCountryName).toString();
|
||||
}
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void ApiCountryModel::updateModel(const QJsonArray &data, const QString ¤tCountryCode)
|
||||
{
|
||||
beginResetModel();
|
||||
|
||||
m_countries = data;
|
||||
for (int i = 0; i < m_countries.size(); i++) {
|
||||
if (m_countries.at(i).toObject().value(configKey::serverCountryCode).toString() == currentCountryCode) {
|
||||
m_currentIndex = i;
|
||||
emit currentIndexChanged(m_currentIndex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
int ApiCountryModel::getCurrentIndex()
|
||||
{
|
||||
return m_currentIndex;
|
||||
}
|
||||
|
||||
void ApiCountryModel::setCurrentIndex(const int i)
|
||||
{
|
||||
m_currentIndex = i;
|
||||
emit currentIndexChanged(m_currentIndex);
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> ApiCountryModel::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roles;
|
||||
roles[CountryNameRole] = "countryName";
|
||||
roles[CountryCodeRole] = "countryCode";
|
||||
return roles;
|
||||
}
|
||||
42
client/ui/models/apiCountryModel.h
Normal file
42
client/ui/models/apiCountryModel.h
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
#ifndef APICOUNTRYMODEL_H
|
||||
#define APICOUNTRYMODEL_H
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QJsonArray>
|
||||
|
||||
class ApiCountryModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Roles {
|
||||
CountryNameRole = Qt::UserRole + 1,
|
||||
CountryCodeRole
|
||||
};
|
||||
|
||||
explicit ApiCountryModel(QObject *parent = nullptr);
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
Q_PROPERTY(int currentIndex READ getCurrentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged)
|
||||
|
||||
public slots:
|
||||
void updateModel(const QJsonArray &data, const QString ¤tCountryCode);
|
||||
|
||||
int getCurrentIndex();
|
||||
void setCurrentIndex(const int i);
|
||||
|
||||
signals:
|
||||
void currentIndexChanged(const int index);
|
||||
|
||||
protected:
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
private:
|
||||
QJsonArray m_countries;
|
||||
int m_currentIndex;
|
||||
};
|
||||
|
||||
#endif // APICOUNTRYMODEL_H
|
||||
203
client/ui/models/apiServicesModel.cpp
Normal file
203
client/ui/models/apiServicesModel.cpp
Normal file
|
|
@ -0,0 +1,203 @@
|
|||
#include "apiServicesModel.h"
|
||||
|
||||
#include <QJsonObject>
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
Logger logger("ApiServicesModel");
|
||||
|
||||
namespace configKey
|
||||
{
|
||||
constexpr char userCountryCode[] = "user_country_code";
|
||||
constexpr char services[] = "services";
|
||||
constexpr char serviceInfo[] = "service_info";
|
||||
constexpr char serviceType[] = "service_type";
|
||||
constexpr char serviceProtocol[] = "service_protocol";
|
||||
|
||||
constexpr char name[] = "name";
|
||||
constexpr char price[] = "price";
|
||||
constexpr char speed[] = "speed";
|
||||
constexpr char timelimit[] = "timelimit";
|
||||
constexpr char region[] = "region";
|
||||
|
||||
constexpr char availableCountries[] = "available_countries";
|
||||
|
||||
constexpr char storeEndpoint[] = "store_endpoint";
|
||||
}
|
||||
|
||||
namespace serviceType
|
||||
{
|
||||
constexpr char amneziaFree[] = "amnezia-free";
|
||||
constexpr char amneziaPremium[] = "amnezia-premium";
|
||||
}
|
||||
}
|
||||
|
||||
ApiServicesModel::ApiServicesModel(QObject *parent) : QAbstractListModel(parent)
|
||||
{
|
||||
}
|
||||
|
||||
int ApiServicesModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
return m_services.size();
|
||||
}
|
||||
|
||||
QVariant ApiServicesModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid() || index.row() < 0 || index.row() >= static_cast<int>(rowCount()))
|
||||
return QVariant();
|
||||
|
||||
QJsonObject service = m_services.at(index.row()).toObject();
|
||||
QJsonObject serviceInfo = service.value(configKey::serviceInfo).toObject();
|
||||
auto serviceType = service.value(configKey::serviceType).toString();
|
||||
|
||||
switch (role) {
|
||||
case NameRole: {
|
||||
return serviceInfo.value(configKey::name).toString();
|
||||
}
|
||||
case CardDescriptionRole: {
|
||||
auto speed = serviceInfo.value(configKey::speed).toString();
|
||||
if (serviceType == serviceType::amneziaPremium) {
|
||||
return tr("Classic VPN for comfortable work, downloading large files and watching videos. "
|
||||
"Works for any sites. Speed up to %1 MBit/s")
|
||||
.arg(speed);
|
||||
} else {
|
||||
return tr("VPN to access blocked sites in regions with high levels of Internet censorship. ");
|
||||
}
|
||||
}
|
||||
case ServiceDescriptionRole: {
|
||||
if (serviceType == serviceType::amneziaPremium) {
|
||||
return tr("Amnezia Premium - A classic VPN for comfortable work, downloading large files, and watching videos in high resolution. "
|
||||
"It works for all websites, even in countries with the highest level of internet censorship.");
|
||||
} else {
|
||||
return tr("Amnezia Free is a free VPN to bypass blocking in countries with high levels of internet censorship");
|
||||
}
|
||||
}
|
||||
case SpeedRole: {
|
||||
auto speed = serviceInfo.value(configKey::speed).toString();
|
||||
return tr("%1 MBit/s").arg(speed);
|
||||
}
|
||||
case WorkPeriodRole: {
|
||||
auto timelimit = serviceInfo.value(configKey::timelimit).toString();
|
||||
if (timelimit == "0") {
|
||||
return "";
|
||||
}
|
||||
return tr("%1 days").arg(timelimit);
|
||||
}
|
||||
case RegionRole: {
|
||||
return serviceInfo.value(configKey::region).toString();
|
||||
}
|
||||
case FeaturesRole: {
|
||||
if (serviceType == serviceType::amneziaPremium) {
|
||||
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/free\" style=\"color: #FBB26A;\">more details on the website.</a>");
|
||||
}
|
||||
}
|
||||
case PriceRole: {
|
||||
auto price = serviceInfo.value(configKey::price).toString();
|
||||
if (price == "free") {
|
||||
return tr("Free");
|
||||
}
|
||||
return tr("%1 $/month").arg(price);
|
||||
}
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void ApiServicesModel::updateModel(const QJsonObject &data)
|
||||
{
|
||||
beginResetModel();
|
||||
|
||||
m_countryCode = data.value(configKey::userCountryCode).toString();
|
||||
m_services = data.value(configKey::services).toArray();
|
||||
if (m_services.isEmpty()) {
|
||||
QJsonObject service;
|
||||
service.insert(configKey::serviceInfo, data.value(configKey::serviceInfo));
|
||||
service.insert(configKey::serviceType, data.value(configKey::serviceType));
|
||||
|
||||
m_services.push_back(service);
|
||||
m_selectedServiceIndex = 0;
|
||||
}
|
||||
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
void ApiServicesModel::setServiceIndex(const int index)
|
||||
{
|
||||
m_selectedServiceIndex = index;
|
||||
}
|
||||
|
||||
QJsonObject ApiServicesModel::getSelectedServiceInfo()
|
||||
{
|
||||
QJsonObject service = m_services.at(m_selectedServiceIndex).toObject();
|
||||
return service.value(configKey::serviceInfo).toObject();
|
||||
}
|
||||
|
||||
QString ApiServicesModel::getSelectedServiceType()
|
||||
{
|
||||
QJsonObject service = m_services.at(m_selectedServiceIndex).toObject();
|
||||
return service.value(configKey::serviceType).toString();
|
||||
}
|
||||
|
||||
QString ApiServicesModel::getSelectedServiceProtocol()
|
||||
{
|
||||
QJsonObject service = m_services.at(m_selectedServiceIndex).toObject();
|
||||
return service.value(configKey::serviceProtocol).toString();
|
||||
}
|
||||
|
||||
QString ApiServicesModel::getSelectedServiceName()
|
||||
{
|
||||
auto modelIndex = index(m_selectedServiceIndex, 0);
|
||||
return data(modelIndex, ApiServicesModel::Roles::NameRole).toString();
|
||||
}
|
||||
|
||||
QJsonArray ApiServicesModel::getSelectedServiceCountries()
|
||||
{
|
||||
QJsonObject service = m_services.at(m_selectedServiceIndex).toObject();
|
||||
return service.value(configKey::availableCountries).toArray();
|
||||
}
|
||||
|
||||
QString ApiServicesModel::getCountryCode()
|
||||
{
|
||||
return m_countryCode;
|
||||
}
|
||||
|
||||
QString ApiServicesModel::getStoreEndpoint()
|
||||
{
|
||||
QJsonObject service = m_services.at(m_selectedServiceIndex).toObject();
|
||||
return service.value(configKey::storeEndpoint).toString();
|
||||
}
|
||||
|
||||
QVariant ApiServicesModel::getSelectedServiceData(const QString roleString)
|
||||
{
|
||||
QModelIndex modelIndex = index(m_selectedServiceIndex);
|
||||
auto roles = roleNames();
|
||||
for (auto it = roles.begin(); it != roles.end(); it++) {
|
||||
if (QString(it.value()) == roleString) {
|
||||
return data(modelIndex, it.key());
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> ApiServicesModel::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roles;
|
||||
roles[NameRole] = "name";
|
||||
roles[CardDescriptionRole] = "cardDescription";
|
||||
roles[ServiceDescriptionRole] = "serviceDescription";
|
||||
roles[SpeedRole] = "speed";
|
||||
roles[WorkPeriodRole] = "workPeriod";
|
||||
roles[RegionRole] = "region";
|
||||
roles[FeaturesRole] = "features";
|
||||
roles[PriceRole] = "price";
|
||||
|
||||
return roles;
|
||||
}
|
||||
56
client/ui/models/apiServicesModel.h
Normal file
56
client/ui/models/apiServicesModel.h
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
#ifndef APISERVICESMODEL_H
|
||||
#define APISERVICESMODEL_H
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QJsonArray>
|
||||
|
||||
class ApiServicesModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Roles {
|
||||
NameRole = Qt::UserRole + 1,
|
||||
CardDescriptionRole,
|
||||
ServiceDescriptionRole,
|
||||
SpeedRole,
|
||||
WorkPeriodRole,
|
||||
RegionRole,
|
||||
FeaturesRole,
|
||||
PriceRole
|
||||
};
|
||||
|
||||
explicit ApiServicesModel(QObject *parent = nullptr);
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
public slots:
|
||||
void updateModel(const QJsonObject &data);
|
||||
|
||||
void setServiceIndex(const int index);
|
||||
|
||||
QJsonObject getSelectedServiceInfo();
|
||||
QString getSelectedServiceType();
|
||||
QString getSelectedServiceProtocol();
|
||||
QString getSelectedServiceName();
|
||||
QJsonArray getSelectedServiceCountries();
|
||||
|
||||
QString getCountryCode();
|
||||
|
||||
QString getStoreEndpoint();
|
||||
|
||||
QVariant getSelectedServiceData(const QString roleString);
|
||||
|
||||
protected:
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
private:
|
||||
QString m_countryCode;
|
||||
QJsonArray m_services;
|
||||
|
||||
int m_selectedServiceIndex;
|
||||
};
|
||||
|
||||
#endif // APISERVICESMODEL_H
|
||||
|
|
@ -94,6 +94,26 @@ bool ContainersModel::isServiceContainer(const int containerIndex)
|
|||
return qvariant_cast<amnezia::ServiceType>(data(index(containerIndex), ServiceTypeRole) == ServiceType::Other);
|
||||
}
|
||||
|
||||
bool ContainersModel::hasInstalledServices()
|
||||
{
|
||||
for (const auto &container : m_containers.keys()) {
|
||||
if (ContainerProps::containerService(container) == ServiceType::Other) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ContainersModel::hasInstalledProtocols()
|
||||
{
|
||||
for (const auto &container : m_containers.keys()) {
|
||||
if (ContainerProps::containerService(container) == ServiceType::Vpn) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> ContainersModel::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roles;
|
||||
|
|
|
|||
|
|
@ -54,6 +54,9 @@ public slots:
|
|||
bool isSupportedByCurrentPlatform(const int containerIndex);
|
||||
bool isServiceContainer(const int containerIndex);
|
||||
|
||||
bool hasInstalledServices();
|
||||
bool hasInstalledProtocols();
|
||||
|
||||
protected:
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
|
|
|
|||
|
|
@ -103,3 +103,12 @@ QString LanguageModel::getCurrentLanguageName()
|
|||
{
|
||||
return m_availableLanguages[getCurrentLanguageIndex()].name;
|
||||
}
|
||||
|
||||
QString LanguageModel::getCurrentSiteUrl()
|
||||
{
|
||||
auto language = static_cast<LanguageSettings::AvailableLanguageEnum>(getCurrentLanguageIndex());
|
||||
switch (language) {
|
||||
case LanguageSettings::AvailableLanguageEnum::Russian: return "https://storage.googleapis.com/kldscp/amnezia.org";
|
||||
default: return "https://amnezia.org";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ public slots:
|
|||
int getCurrentLanguageIndex();
|
||||
int getLineHeightAppend();
|
||||
QString getCurrentLanguageName();
|
||||
QString getCurrentSiteUrl();
|
||||
|
||||
signals:
|
||||
void updateTranslations(const QLocale &locale);
|
||||
|
|
|
|||
|
|
@ -1,8 +1,31 @@
|
|||
#include "servers_model.h"
|
||||
|
||||
#include "core/controllers/serverController.h"
|
||||
#include "core/enums/apiEnums.h"
|
||||
#include "core/networkUtilities.h"
|
||||
|
||||
#ifdef Q_OS_IOS
|
||||
#include <AmneziaVPN-Swift.h>
|
||||
#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
namespace configKey
|
||||
{
|
||||
constexpr char apiConfig[] = "api_config";
|
||||
constexpr char serviceInfo[] = "service_info";
|
||||
constexpr char availableCountries[] = "available_countries";
|
||||
constexpr char serverCountryCode[] = "server_country_code";
|
||||
constexpr char serverCountryName[] = "server_country_name";
|
||||
constexpr char userCountryCode[] = "user_country_code";
|
||||
constexpr char serviceType[] = "service_type";
|
||||
constexpr char serviceProtocol[] = "service_protocol";
|
||||
|
||||
constexpr char publicKeyInfo[] = "public_key";
|
||||
constexpr char endDate[] = "end_date";
|
||||
}
|
||||
}
|
||||
|
||||
ServersModel::ServersModel(std::shared_ptr<Settings> settings, QObject *parent) : m_settings(settings), QAbstractListModel(parent)
|
||||
{
|
||||
m_isAmneziaDnsEnabled = m_settings->useAmneziaDns();
|
||||
|
|
@ -63,6 +86,7 @@ QVariant ServersModel::data(const QModelIndex &index, int role) const
|
|||
}
|
||||
|
||||
const QJsonObject server = m_servers.at(index.row()).toObject();
|
||||
const auto apiConfig = server.value(configKey::apiConfig).toObject();
|
||||
const auto configVersion = server.value(config_key::configVersion).toInt();
|
||||
switch (role) {
|
||||
case NameRole: {
|
||||
|
|
@ -98,8 +122,23 @@ QVariant ServersModel::data(const QModelIndex &index, int role) const
|
|||
case HasInstalledContainers: {
|
||||
return serverHasInstalledContainers(index.row());
|
||||
}
|
||||
case IsServerFromApiRole: {
|
||||
return server.value(config_key::configVersion).toInt();
|
||||
case IsServerFromTelegramApiRole: {
|
||||
return server.value(config_key::configVersion).toInt() == ApiConfigSources::Telegram;
|
||||
}
|
||||
case IsServerFromGatewayApiRole: {
|
||||
return server.value(config_key::configVersion).toInt() == ApiConfigSources::AmneziaGateway;
|
||||
}
|
||||
case ApiConfigRole: {
|
||||
return apiConfig;
|
||||
}
|
||||
case IsCountrySelectionAvailableRole: {
|
||||
return !apiConfig.value(configKey::availableCountries).toArray().isEmpty();
|
||||
}
|
||||
case ApiAvailableCountriesRole: {
|
||||
return apiConfig.value(configKey::availableCountries).toArray();
|
||||
}
|
||||
case ApiServerCountryCodeRole: {
|
||||
return apiConfig.value(configKey::serverCountryCode).toString();
|
||||
}
|
||||
case HasAmneziaDns: {
|
||||
QString primaryDns = server.value(config_key::dns1).toString();
|
||||
|
|
@ -146,10 +185,13 @@ const QString ServersModel::getDefaultServerName()
|
|||
QString ServersModel::getServerDescription(const QJsonObject &server, const int index) const
|
||||
{
|
||||
const auto configVersion = server.value(config_key::configVersion).toInt();
|
||||
const auto apiConfig = server.value(configKey::apiConfig).toObject();
|
||||
|
||||
QString description;
|
||||
|
||||
if (configVersion) {
|
||||
if (configVersion && !apiConfig.value(configKey::serverCountryCode).toString().isEmpty()) {
|
||||
return apiConfig.value(configKey::serverCountryName).toString();
|
||||
} else if (configVersion) {
|
||||
return server.value(config_key::description).toString();
|
||||
} else if (data(index, HasWriteAccessRole).toBool()) {
|
||||
if (m_isAmneziaDnsEnabled && isAmneziaDnsContainerInstalled(index)) {
|
||||
|
|
@ -208,6 +250,12 @@ void ServersModel::setProcessedServerIndex(const int index)
|
|||
{
|
||||
m_processedServerIndex = index;
|
||||
updateContainersModel();
|
||||
if (data(index, IsServerFromGatewayApiRole).toBool()) {
|
||||
if (data(index, IsCountrySelectionAvailableRole).toBool()) {
|
||||
emit updateApiLanguageModel();
|
||||
}
|
||||
emit updateApiServicesModel();
|
||||
}
|
||||
emit processedServerIndexChanged(m_processedServerIndex);
|
||||
}
|
||||
|
||||
|
|
@ -233,7 +281,8 @@ bool ServersModel::isDefaultServerCurrentlyProcessed()
|
|||
|
||||
bool ServersModel::isDefaultServerFromApi()
|
||||
{
|
||||
return qvariant_cast<bool>(data(m_defaultServerIndex, IsServerFromApiRole));
|
||||
return data(m_defaultServerIndex, IsServerFromTelegramApiRole).toBool()
|
||||
|| data(m_defaultServerIndex, IsServerFromGatewayApiRole).toBool();
|
||||
}
|
||||
|
||||
bool ServersModel::isProcessedServerHasWriteAccess()
|
||||
|
|
@ -315,7 +364,12 @@ QHash<int, QByteArray> ServersModel::roleNames() const
|
|||
roles[DefaultContainerRole] = "defaultContainer";
|
||||
roles[HasInstalledContainers] = "hasInstalledContainers";
|
||||
|
||||
roles[IsServerFromApiRole] = "isServerFromApi";
|
||||
roles[IsServerFromTelegramApiRole] = "isServerFromTelegramApi";
|
||||
roles[IsServerFromGatewayApiRole] = "isServerFromGatewayApi";
|
||||
roles[ApiConfigRole] = "apiConfig";
|
||||
roles[IsCountrySelectionAvailableRole] = "isCountrySelectionAvailable";
|
||||
roles[ApiAvailableCountriesRole] = "apiAvailableCountries";
|
||||
roles[ApiServerCountryCodeRole] = "apiServerCountryCode";
|
||||
return roles;
|
||||
}
|
||||
|
||||
|
|
@ -399,8 +453,7 @@ void ServersModel::addContainerConfig(const int containerIndex, const QJsonObjec
|
|||
|
||||
auto defaultContainer = server.value(config_key::defaultContainer).toString();
|
||||
if (ContainerProps::containerFromString(defaultContainer) == DockerContainer::None
|
||||
&& ContainerProps::containerService(container) != ServiceType::Other
|
||||
&& ContainerProps::isSupportedByCurrentPlatform(container)) {
|
||||
&& ContainerProps::containerService(container) != ServiceType::Other && ContainerProps::isSupportedByCurrentPlatform(container)) {
|
||||
server.insert(config_key::defaultContainer, ContainerProps::containerToString(container));
|
||||
}
|
||||
|
||||
|
|
@ -565,7 +618,7 @@ void ServersModel::toggleAmneziaDns(bool enabled)
|
|||
|
||||
bool ServersModel::isServerFromApiAlreadyExists(const quint16 crc)
|
||||
{
|
||||
for (const auto &server : qAsConst(m_servers)) {
|
||||
for (const auto &server : std::as_const(m_servers)) {
|
||||
if (static_cast<quint16>(server.toObject().value(config_key::crc).toInt()) == crc) {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -573,6 +626,19 @@ bool ServersModel::isServerFromApiAlreadyExists(const quint16 crc)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool ServersModel::isServerFromApiAlreadyExists(const QString &userCountryCode, const QString &serviceType, const QString &serviceProtocol)
|
||||
{
|
||||
for (const auto &server : std::as_const(m_servers)) {
|
||||
const auto apiConfig = server.toObject().value(configKey::apiConfig).toObject();
|
||||
if (apiConfig.value(configKey::userCountryCode).toString() == userCountryCode
|
||||
&& apiConfig.value(configKey::serviceType).toString() == serviceType
|
||||
&& apiConfig.value(configKey::serviceProtocol).toString() == serviceProtocol) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ServersModel::serverHasInstalledContainers(const int serverIndex) const
|
||||
{
|
||||
QJsonObject server = m_servers.at(serverIndex).toObject();
|
||||
|
|
@ -621,14 +687,89 @@ bool ServersModel::isDefaultServerDefaultContainerHasSplitTunneling()
|
|||
auto containers = server.value(config_key::containers).toArray();
|
||||
for (auto i = 0; i < containers.size(); i++) {
|
||||
auto container = containers.at(i).toObject();
|
||||
if (container.value(config_key::container).toString() != ContainerProps::containerToString(defaultContainer)) {
|
||||
continue;
|
||||
}
|
||||
if (defaultContainer == DockerContainer::Awg || defaultContainer == DockerContainer::WireGuard) {
|
||||
auto containerConfig = container.value(ContainerProps::containerTypeToString(defaultContainer)).toObject();
|
||||
return !(containerConfig.value(config_key::last_config).toString().contains("AllowedIPs = 0.0.0.0/0, ::/0"));
|
||||
QJsonObject serverProtocolConfig = container.value(ContainerProps::containerTypeToString(defaultContainer)).toObject();
|
||||
QString clientProtocolConfigString = serverProtocolConfig.value(config_key::last_config).toString();
|
||||
QJsonObject clientProtocolConfig = QJsonDocument::fromJson(clientProtocolConfigString.toUtf8()).object();
|
||||
return (clientProtocolConfigString.contains("AllowedIPs") && !clientProtocolConfigString.contains("AllowedIPs = 0.0.0.0/0, ::/0"))
|
||||
|| (!clientProtocolConfig.value(config_key::allowed_ips).toArray().isEmpty()
|
||||
&& !clientProtocolConfig.value(config_key::allowed_ips).toArray().contains("0.0.0.0/0"));
|
||||
} else if (defaultContainer == DockerContainer::Cloak || defaultContainer == DockerContainer::OpenVpn
|
||||
|| defaultContainer == DockerContainer::ShadowSocks) {
|
||||
auto containerConfig = container.value(ContainerProps::containerTypeToString(DockerContainer::OpenVpn)).toObject();
|
||||
return !(containerConfig.value(config_key::last_config).toString().contains("redirect-gateway"));
|
||||
auto serverProtocolConfig = container.value(ContainerProps::containerTypeToString(DockerContainer::OpenVpn)).toObject();
|
||||
QString clientProtocolConfigString = serverProtocolConfig.value(config_key::last_config).toString();
|
||||
return !clientProtocolConfigString.isEmpty() && !clientProtocolConfigString.contains("redirect-gateway");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ServersModel::isServerFromApi(const int serverIndex)
|
||||
{
|
||||
return data(serverIndex, IsServerFromTelegramApiRole).toBool() || data(serverIndex, IsServerFromGatewayApiRole).toBool();
|
||||
}
|
||||
|
||||
bool ServersModel::isApiKeyExpired(const int serverIndex)
|
||||
{
|
||||
auto serverConfig = m_servers.at(serverIndex).toObject();
|
||||
auto apiConfig = serverConfig.value(configKey::apiConfig).toObject();
|
||||
|
||||
auto publicKeyInfo = apiConfig.value(configKey::publicKeyInfo).toObject();
|
||||
const QString endDate = publicKeyInfo.value(configKey::endDate).toString();
|
||||
if (endDate.isEmpty()) {
|
||||
publicKeyInfo.insert(configKey::endDate, QDateTime::currentDateTimeUtc().addDays(1).toString(Qt::ISODate));
|
||||
apiConfig.insert(configKey::publicKeyInfo, publicKeyInfo);
|
||||
serverConfig.insert(configKey::apiConfig, apiConfig);
|
||||
editServer(serverConfig, serverIndex);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
auto endDateDateTime = QDateTime::fromString(endDate, Qt::ISODate).toUTC();
|
||||
if (endDateDateTime < QDateTime::currentDateTimeUtc()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ServersModel::removeApiConfig(const int serverIndex)
|
||||
{
|
||||
auto serverConfig = getServerConfig(serverIndex);
|
||||
|
||||
#ifdef Q_OS_IOS
|
||||
QString vpncName = QString("%1 (%2) %3")
|
||||
.arg(serverConfig[config_key::description].toString())
|
||||
.arg(serverConfig[config_key::hostName].toString())
|
||||
.arg(serverConfig[config_key::vpnproto].toString());
|
||||
|
||||
AmneziaVPN::removeVPNC(vpncName.toStdString());
|
||||
#endif
|
||||
|
||||
serverConfig.remove(config_key::dns1);
|
||||
serverConfig.remove(config_key::dns2);
|
||||
serverConfig.remove(config_key::containers);
|
||||
serverConfig.remove(config_key::hostName);
|
||||
|
||||
auto apiConfig = serverConfig.value(configKey::apiConfig).toObject();
|
||||
apiConfig.remove(configKey::publicKeyInfo);
|
||||
serverConfig.insert(configKey::apiConfig, apiConfig);
|
||||
|
||||
serverConfig.insert(config_key::defaultContainer, ContainerProps::containerToString(DockerContainer::None));
|
||||
|
||||
editServer(serverConfig, serverIndex);
|
||||
}
|
||||
|
||||
const QString ServersModel::getDefaultServerImagePathCollapsed()
|
||||
{
|
||||
const auto server = m_servers.at(m_defaultServerIndex).toObject();
|
||||
const auto apiConfig = server.value(configKey::apiConfig).toObject();
|
||||
const auto countryCode = apiConfig.value(configKey::serverCountryCode).toString();
|
||||
|
||||
if (countryCode.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
return QString("qrc:/countriesFlags/images/flagKit/%1.svg").arg(countryCode);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
#include <QAbstractListModel>
|
||||
|
||||
#include "settings.h"
|
||||
#include "core/controllers/serverController.h"
|
||||
#include "settings.h"
|
||||
|
||||
class ServersModel : public QAbstractListModel
|
||||
{
|
||||
|
|
@ -30,7 +30,13 @@ public:
|
|||
DefaultContainerRole,
|
||||
|
||||
HasInstalledContainers,
|
||||
IsServerFromApiRole,
|
||||
|
||||
IsServerFromTelegramApiRole,
|
||||
IsServerFromGatewayApiRole,
|
||||
ApiConfigRole,
|
||||
IsCountrySelectionAvailableRole,
|
||||
ApiAvailableCountriesRole,
|
||||
ApiServerCountryCodeRole,
|
||||
|
||||
HasAmneziaDns
|
||||
};
|
||||
|
|
@ -49,8 +55,10 @@ public:
|
|||
Q_PROPERTY(QString defaultServerName READ getDefaultServerName NOTIFY defaultServerNameChanged)
|
||||
Q_PROPERTY(QString defaultServerDefaultContainerName READ getDefaultServerDefaultContainerName NOTIFY defaultServerDefaultContainerChanged)
|
||||
Q_PROPERTY(QString defaultServerDescriptionCollapsed READ getDefaultServerDescriptionCollapsed NOTIFY defaultServerDefaultContainerChanged)
|
||||
Q_PROPERTY(QString defaultServerImagePathCollapsed READ getDefaultServerImagePathCollapsed NOTIFY defaultServerDefaultContainerChanged)
|
||||
Q_PROPERTY(QString defaultServerDescriptionExpanded READ getDefaultServerDescriptionExpanded NOTIFY defaultServerDefaultContainerChanged)
|
||||
Q_PROPERTY(bool isDefaultServerDefaultContainerHasSplitTunneling READ isDefaultServerDefaultContainerHasSplitTunneling NOTIFY defaultServerDefaultContainerChanged)
|
||||
Q_PROPERTY(bool isDefaultServerDefaultContainerHasSplitTunneling READ isDefaultServerDefaultContainerHasSplitTunneling NOTIFY
|
||||
defaultServerDefaultContainerChanged)
|
||||
Q_PROPERTY(bool isDefaultServerFromApi READ isDefaultServerFromApi NOTIFY defaultServerIndexChanged)
|
||||
|
||||
Q_PROPERTY(int processedIndex READ getProcessedServerIndex WRITE setProcessedServerIndex NOTIFY processedServerIndexChanged)
|
||||
|
|
@ -60,6 +68,7 @@ public slots:
|
|||
const int getDefaultServerIndex();
|
||||
const QString getDefaultServerName();
|
||||
const QString getDefaultServerDescriptionCollapsed();
|
||||
const QString getDefaultServerImagePathCollapsed();
|
||||
const QString getDefaultServerDescriptionExpanded();
|
||||
const QString getDefaultServerDefaultContainerName();
|
||||
bool isDefaultServerCurrentlyProcessed();
|
||||
|
|
@ -101,6 +110,7 @@ public slots:
|
|||
QPair<QString, QString> getDnsPair(const int serverIndex);
|
||||
|
||||
bool isServerFromApiAlreadyExists(const quint16 crc);
|
||||
bool isServerFromApiAlreadyExists(const QString &userCountryCode, const QString &serviceType, const QString &serviceProtocol);
|
||||
|
||||
QVariant getDefaultServerData(const QString roleString);
|
||||
|
||||
|
|
@ -108,6 +118,10 @@ public slots:
|
|||
|
||||
bool isDefaultServerDefaultContainerHasSplitTunneling();
|
||||
|
||||
bool isServerFromApi(const int serverIndex);
|
||||
bool isApiKeyExpired(const int serverIndex);
|
||||
void removeApiConfig(const int serverIndex);
|
||||
|
||||
protected:
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
|
|
@ -121,6 +135,9 @@ signals:
|
|||
void defaultServerContainersUpdated(const QJsonArray &containers);
|
||||
void defaultServerDefaultContainerChanged(const int containerIndex);
|
||||
|
||||
void updateApiLanguageModel();
|
||||
void updateApiServicesModel();
|
||||
|
||||
private:
|
||||
ServerCredentials serverCredentials(int index) const;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue