diff --git a/client/resources.qrc b/client/resources.qrc
index 4c63383c..1baf993b 100644
--- a/client/resources.qrc
+++ b/client/resources.qrc
@@ -222,5 +222,6 @@
server_scripts/awg/configure_container.sh
server_scripts/awg/run_container.sh
server_scripts/awg/Dockerfile
+ ui/qml/Pages2/PageShareFullAccess.qml
diff --git a/client/ui/controllers/pageController.h b/client/ui/controllers/pageController.h
index 20c3bbed..f7e697fb 100644
--- a/client/ui/controllers/pageController.h
+++ b/client/ui/controllers/pageController.h
@@ -51,7 +51,9 @@ namespace PageLoader
PageProtocolWireGuardSettings,
PageProtocolAwgSettings,
PageProtocolIKev2Settings,
- PageProtocolRaw
+ PageProtocolRaw,
+
+ PageShareFullAccess
};
Q_ENUM_NS(PageEnum)
diff --git a/client/ui/models/clientManagementModel.cpp b/client/ui/models/clientManagementModel.cpp
index c4c4fb7a..f53794d5 100644
--- a/client/ui/models/clientManagementModel.cpp
+++ b/client/ui/models/clientManagementModel.cpp
@@ -4,6 +4,19 @@
#include
#include "core/servercontroller.h"
+#include "logger.h"
+
+namespace
+{
+ Logger logger("ClientManagementModel");
+
+ namespace configKey {
+ constexpr char clientId[] = "clientId";
+ constexpr char clientName[] = "clientName";
+ constexpr char container[] = "container";
+ constexpr char userData[] = "userData";
+ }
+}
ClientManagementModel::ClientManagementModel(std::shared_ptr settings, QObject *parent)
: m_settings(settings), QAbstractListModel(parent)
@@ -23,13 +36,13 @@ QVariant ClientManagementModel::data(const QModelIndex &index, int role) const
}
auto client = m_clientsTable.at(index.row()).toObject();
- auto userData = client.value("userData").toObject();
+ auto userData = client.value(configKey::userData).toObject();
switch (role) {
- case UserNameRole: return userData.value("clientName").toString();
+ case ClientNameRole: return userData.value(configKey::clientName).toString();
case ContainerNameRole:
return ContainerProps::containerHumanNames().value(
- static_cast(userData.value("container").toInt()));
+ static_cast(userData.value(configKey::container).toInt()));
}
return QVariant();
@@ -40,17 +53,13 @@ ErrorCode ClientManagementModel::updateModel(DockerContainer container, ServerCr
ServerController serverController(m_settings);
ErrorCode error = ErrorCode::NoError;
- QString stdOut;
- auto cbReadStdOut = [&](const QString &data, libssh::Client &) {
- stdOut += data + "\n";
- return ErrorCode::NoError;
- };
const QString clientsTableFile =
QString("/opt/amnezia/%1/clientsTable").arg(ContainerProps::containerTypeToString(container));
const QByteArray clientsTableString =
serverController.getTextFileFromContainer(container, credentials, clientsTableFile, &error);
if (error != ErrorCode::NoError) {
+ logger.error() << "Failed to get the clientsTable file from the server";
return error;
}
@@ -62,75 +71,21 @@ ErrorCode ClientManagementModel::updateModel(DockerContainer container, ServerCr
if (container == DockerContainer::OpenVpn || container == DockerContainer::ShadowSocks
|| container == DockerContainer::Cloak) {
- const QString getOpenVpnClientsList =
- "sudo docker exec -i $CONTAINER_NAME bash -c 'ls /opt/amnezia/openvpn/pki/issued'";
- QString script = serverController.replaceVars(getOpenVpnClientsList,
- serverController.genVarsForScript(credentials, container));
- error = serverController.runScript(credentials, script, cbReadStdOut);
- if (error != ErrorCode::NoError) {
- return error;
- }
-
- if (!stdOut.isEmpty()) {
- QStringList certsIds = stdOut.split("\n", Qt::SkipEmptyParts);
- certsIds.removeAll("AmneziaReq.crt");
-
- for (auto &openvpnCertId : certsIds) {
- openvpnCertId.replace(".crt", "");
- if (!isClientExists(openvpnCertId)) {
- QJsonObject client;
- client["userId"] = openvpnCertId;
-
- QJsonObject userData;
- userData["clientName"] = QString("Client %1").arg(count);
- userData["container"] = container;
- client["userData"] = userData;
-
- m_clientsTable.push_back(client);
-
- count++;
- }
- }
- }
+ error = getOpenVpnClients(serverController, container, credentials, count);
} else if (container == DockerContainer::WireGuard || container == DockerContainer::Awg) {
- const QString wireGuardConfigFile =
- QString("opt/amnezia/%1/wg0.conf").arg(container == DockerContainer::WireGuard ? "wireguard" : "awg");
- const QString wireguardConfigString =
- serverController.getTextFileFromContainer(container, credentials, wireGuardConfigFile, &error);
- if (error != ErrorCode::NoError) {
- return error;
- }
-
- auto configLines = wireguardConfigString.split("\n", Qt::SkipEmptyParts);
- QStringList wireguardKeys;
- for (const auto &line : configLines) {
- auto configPair = line.split(" = ", Qt::SkipEmptyParts);
- if (configPair.front() == "PublicKey") {
- wireguardKeys.push_back(configPair.back());
- }
- }
-
- for (auto &wireguardKey : wireguardKeys) {
- if (!isClientExists(wireguardKey)) {
- QJsonObject client;
- client["userId"] = wireguardKey;
-
- QJsonObject userData;
- userData["clientName"] = QString("Client %1").arg(count);
- userData["container"] = container;
- client["userData"] = userData;
-
- m_clientsTable.push_back(client);
-
- count++;
- }
- }
+ error = getWireGuardClients(serverController, container, credentials, count);
+ }
+ if (error != ErrorCode::NoError) {
+ return error;
}
const QByteArray newClientsTableString = QJsonDocument(m_clientsTable).toJson();
if (clientsTableString != newClientsTableString) {
error = serverController.uploadTextFileToContainer(container, credentials, newClientsTableString,
clientsTableFile);
+ if (error != ErrorCode::NoError) {
+ logger.error() << "Failed to upload the clientsTable file to the server";
+ }
}
}
@@ -138,12 +93,95 @@ ErrorCode ClientManagementModel::updateModel(DockerContainer container, ServerCr
return error;
}
+ErrorCode ClientManagementModel::getOpenVpnClients(ServerController &serverController, DockerContainer container, ServerCredentials credentials, int &count)
+{
+ ErrorCode error = ErrorCode::NoError;
+ QString stdOut;
+ auto cbReadStdOut = [&](const QString &data, libssh::Client &) {
+ stdOut += data + "\n";
+ return ErrorCode::NoError;
+ };
+
+ const QString getOpenVpnClientsList =
+ "sudo docker exec -i $CONTAINER_NAME bash -c 'ls /opt/amnezia/openvpn/pki/issued'";
+ QString script = serverController.replaceVars(getOpenVpnClientsList,
+ serverController.genVarsForScript(credentials, container));
+ error = serverController.runScript(credentials, script, cbReadStdOut);
+ if (error != ErrorCode::NoError) {
+ logger.error() << "Failed to retrieve the list of issued certificates on the server";
+ return error;
+ }
+
+ if (!stdOut.isEmpty()) {
+ QStringList certsIds = stdOut.split("\n", Qt::SkipEmptyParts);
+ certsIds.removeAll("AmneziaReq.crt");
+
+ for (auto &openvpnCertId : certsIds) {
+ openvpnCertId.replace(".crt", "");
+ if (!isClientExists(openvpnCertId)) {
+ QJsonObject client;
+ client[configKey::clientId] = openvpnCertId;
+
+ QJsonObject userData;
+ userData[configKey::clientName] = QString("Client %1").arg(count);
+ userData[configKey::container] = container;
+ client[configKey::userData] = userData;
+
+ m_clientsTable.push_back(client);
+
+ count++;
+ }
+ }
+ }
+ return error;
+}
+
+ErrorCode ClientManagementModel::getWireGuardClients(ServerController &serverController, DockerContainer container, ServerCredentials credentials, int &count)
+{
+ ErrorCode error = ErrorCode::NoError;
+
+ const QString wireGuardConfigFile =
+ QString("opt/amnezia/%1/wg0.conf").arg(container == DockerContainer::WireGuard ? "wireguard" : "awg");
+ const QString wireguardConfigString =
+ serverController.getTextFileFromContainer(container, credentials, wireGuardConfigFile, &error);
+ if (error != ErrorCode::NoError) {
+ logger.error() << "Failed to get the wg conf file from the server";
+ return error;
+ }
+
+ auto configLines = wireguardConfigString.split("\n", Qt::SkipEmptyParts);
+ QStringList wireguardKeys;
+ for (const auto &line : configLines) {
+ auto configPair = line.split(" = ", Qt::SkipEmptyParts);
+ if (configPair.front() == "PublicKey") {
+ wireguardKeys.push_back(configPair.back());
+ }
+ }
+
+ for (auto &wireguardKey : wireguardKeys) {
+ if (!isClientExists(wireguardKey)) {
+ QJsonObject client;
+ client[configKey::clientId] = wireguardKey;
+
+ QJsonObject userData;
+ userData[configKey::clientName] = QString("Client %1").arg(count);
+ userData[configKey::container] = container;
+ client[configKey::userData] = userData;
+
+ m_clientsTable.push_back(client);
+
+ count++;
+ }
+ }
+ return error;
+}
+
bool ClientManagementModel::isClientExists(const QString &clientId)
{
for (const QJsonValue &value : qAsConst(m_clientsTable)) {
if (value.isObject()) {
QJsonObject obj = value.toObject();
- if (obj.contains("userId") && obj["userId"].toString() == clientId) {
+ if (obj.contains(configKey::clientId) && obj[configKey::clientId].toString() == clientId) {
return true;
}
}
@@ -155,39 +193,38 @@ ErrorCode ClientManagementModel::appendClient(const QString &clientId, const QSt
const DockerContainer container, ServerCredentials credentials)
{
ErrorCode error;
- if (m_clientsTable.empty()) {
- error = updateModel(container, credentials);
- if (error != ErrorCode::NoError) {
- return error;
+
+ error = updateModel(container, credentials);
+ if (error != ErrorCode::NoError) {
+ return error;
+ }
+
+ for (int i = 0; i < m_clientsTable.size(); i++) {
+ if (m_clientsTable.at(i).toObject().value(configKey::clientId) == clientId) {
+ return renameClient(i, clientName, container, credentials);
}
+ }
- for (int i = 0; i < m_clientsTable.size(); i++) {
- if (m_clientsTable.at(i).toObject().value("userId") == (clientId)) {
- error = renameClient(i, clientName, container, credentials);
- if (error != ErrorCode::NoError) {
- return error;
- }
- }
- }
- } else {
- beginResetModel();
- QJsonObject client;
- client["userId"] = clientId;
+ beginResetModel();
+ QJsonObject client;
+ client[configKey::clientId] = clientId;
- QJsonObject userData;
- userData["clientName"] = clientName;
- userData["container"] = container;
- client["userData"] = userData;
- m_clientsTable.push_back(client);
- endResetModel();
+ QJsonObject userData;
+ userData[configKey::clientName] = clientName;
+ userData[configKey::container] = container;
+ client[configKey::userData] = userData;
+ m_clientsTable.push_back(client);
+ endResetModel();
- const QByteArray clientsTableString = QJsonDocument(m_clientsTable).toJson();
+ const QByteArray clientsTableString = QJsonDocument(m_clientsTable).toJson();
- ServerController serverController(m_settings);
- const QString clientsTableFile =
- QString("/opt/amnezia/%1/clientsTable").arg(ContainerProps::containerTypeToString(container));
+ ServerController serverController(m_settings);
+ const QString clientsTableFile =
+ QString("/opt/amnezia/%1/clientsTable").arg(ContainerProps::containerTypeToString(container));
- error = serverController.uploadTextFileToContainer(container, credentials, clientsTableString, clientsTableFile);
+ error = serverController.uploadTextFileToContainer(container, credentials, clientsTableString, clientsTableFile);
+ if (error != ErrorCode::NoError) {
+ logger.error() << "Failed to upload the clientsTable file to the server";
}
return error;
@@ -197,9 +234,9 @@ ErrorCode ClientManagementModel::renameClient(const int row, const QString &clie
ServerCredentials credentials)
{
auto client = m_clientsTable.at(row).toObject();
- auto userData = client["userData"].toObject();
- userData["clientName"] = clientName;
- client["userData"] = userData;
+ auto userData = client[configKey::userData].toObject();
+ userData[configKey::clientName] = clientName;
+ client[configKey::userData] = userData;
m_clientsTable.replace(row, client);
emit dataChanged(index(row, 0), index(row, 0));
@@ -212,6 +249,9 @@ ErrorCode ClientManagementModel::renameClient(const int row, const QString &clie
ErrorCode error =
serverController.uploadTextFileToContainer(container, credentials, clientsTableString, clientsTableFile);
+ if (error != ErrorCode::NoError) {
+ logger.error() << "Failed to upload the clientsTable file to the server";
+ }
return error;
}
@@ -232,7 +272,7 @@ ErrorCode ClientManagementModel::revokeOpenVpn(const int row, const DockerContai
ServerCredentials credentials)
{
auto client = m_clientsTable.at(row).toObject();
- QString clientId = client.value("userId").toString();
+ QString clientId = client.value(configKey::clientId).toString();
const QString getOpenVpnCertData = QString("sudo docker exec -i $CONTAINER_NAME bash -c '"
"cd /opt/amnezia/openvpn ;\\"
@@ -246,6 +286,7 @@ ErrorCode ClientManagementModel::revokeOpenVpn(const int row, const DockerContai
serverController.replaceVars(getOpenVpnCertData, serverController.genVarsForScript(credentials, container));
ErrorCode error = serverController.runScript(credentials, script);
if (error != ErrorCode::NoError) {
+ logger.error() << "Failed to revoke the certificate";
return error;
}
@@ -259,6 +300,7 @@ ErrorCode ClientManagementModel::revokeOpenVpn(const int row, const DockerContai
QString("/opt/amnezia/%1/clientsTable").arg(ContainerProps::containerTypeToString(container));
error = serverController.uploadTextFileToContainer(container, credentials, clientsTableString, clientsTableFile);
if (error != ErrorCode::NoError) {
+ logger.error() << "Failed to upload the clientsTable file to the server";
return error;
}
@@ -276,11 +318,12 @@ ErrorCode ClientManagementModel::revokeWireGuard(const int row, const DockerCont
const QString wireguardConfigString =
serverController.getTextFileFromContainer(container, credentials, wireGuardConfigFile, &error);
if (error != ErrorCode::NoError) {
+ logger.error() << "Failed to get the wg conf file from the server";
return error;
}
auto client = m_clientsTable.at(row).toObject();
- QString clientId = client.value("userId").toString();
+ QString clientId = client.value(configKey::clientId).toString();
auto configSections = wireguardConfigString.split("[", Qt::SkipEmptyParts);
for (auto §ion : configSections) {
@@ -293,6 +336,7 @@ ErrorCode ClientManagementModel::revokeWireGuard(const int row, const DockerCont
newWireGuardConfig.insert(0, "[");
error = serverController.uploadTextFileToContainer(container, credentials, newWireGuardConfig, wireGuardConfigFile);
if (error != ErrorCode::NoError) {
+ logger.error() << "Failed to upload the wg conf file to the server";
return error;
}
@@ -306,6 +350,7 @@ ErrorCode ClientManagementModel::revokeWireGuard(const int row, const DockerCont
QString("/opt/amnezia/%1/clientsTable").arg(ContainerProps::containerTypeToString(container));
error = serverController.uploadTextFileToContainer(container, credentials, clientsTableString, clientsTableFile);
if (error != ErrorCode::NoError) {
+ logger.error() << "Failed to upload the clientsTable file to the server";
return error;
}
@@ -315,6 +360,7 @@ ErrorCode ClientManagementModel::revokeWireGuard(const int row, const DockerCont
serverController.replaceVars(script.arg(wireGuardConfigFile),
serverController.genVarsForScript(credentials, container)));
if (error != ErrorCode::NoError) {
+ logger.error() << "Failed to execute the command 'wg syncconf' on the server";
return error;
}
@@ -324,7 +370,7 @@ ErrorCode ClientManagementModel::revokeWireGuard(const int row, const DockerCont
QHash ClientManagementModel::roleNames() const
{
QHash roles;
- roles[UserNameRole] = "userName";
+ roles[ClientNameRole] = "clientName";
roles[ContainerNameRole] = "containerName";
return roles;
}
diff --git a/client/ui/models/clientManagementModel.h b/client/ui/models/clientManagementModel.h
index c51ce816..25089b66 100644
--- a/client/ui/models/clientManagementModel.h
+++ b/client/ui/models/clientManagementModel.h
@@ -4,7 +4,7 @@
#include
#include
-#include "protocols/protocols_defs.h"
+#include "core/servercontroller.h"
#include "settings.h"
class ClientManagementModel : public QAbstractListModel
@@ -29,7 +29,7 @@ class ClientManagementModel : public QAbstractListModel
public:
enum Roles {
- UserNameRole = Qt::UserRole + 1,
+ ClientNameRole = Qt::UserRole + 1,
ContainerNameRole,
};
@@ -55,6 +55,9 @@ private:
ErrorCode revokeOpenVpn(const int row, const DockerContainer container, ServerCredentials credentials);
ErrorCode revokeWireGuard(const int row, const DockerContainer container, ServerCredentials credentials);
+ ErrorCode getOpenVpnClients(ServerController &serverController, DockerContainer container, ServerCredentials credentials, int &count);
+ ErrorCode getWireGuardClients(ServerController &serverController, DockerContainer container, ServerCredentials credentials, int &count);
+
QJsonArray m_clientsTable;
std::shared_ptr m_settings;
diff --git a/client/ui/qml/Pages2/PageShare.qml b/client/ui/qml/Pages2/PageShare.qml
index 01813703..cb847583 100644
--- a/client/ui/qml/Pages2/PageShare.qml
+++ b/client/ui/qml/Pages2/PageShare.qml
@@ -18,7 +18,6 @@ PageType {
enum ConfigType {
AmneziaConnection,
- AmneziaFullAccess,
OpenVpn,
WireGuard
}
@@ -46,24 +45,16 @@ PageType {
PageController.showBusyIndicator(true)
switch (type) {
- case PageShare.ConfigType.AmneziaConnection: ExportController.generateConnectionConfig(userNameTextField.textFieldText); break;
- case PageShare.ConfigType.AmneziaFullAccess: {
- if (Qt.platform.os === "android") {
- ExportController.generateFullAccessConfigAndroid();
- } else {
- ExportController.generateFullAccessConfig();
- }
- break;
- }
+ case PageShare.ConfigType.AmneziaConnection: ExportController.generateConnectionConfig(clientNameTextField.textFieldText); break;
case PageShare.ConfigType.OpenVpn: {
- ExportController.generateOpenVpnConfig(userNameTextField.textFieldText)
+ ExportController.generateOpenVpnConfig(clientNameTextField.textFieldText)
shareConnectionDrawer.configCaption = qsTr("Save OpenVPN config")
shareConnectionDrawer.configExtension = ".ovpn"
shareConnectionDrawer.configFileName = "amnezia_for_openvpn"
break;
}
case PageShare.ConfigType.WireGuard: {
- ExportController.generateWireGuardConfig(userNameTextField.textFieldText)
+ ExportController.generateWireGuardConfig(clientNameTextField.textFieldText)
shareConnectionDrawer.configCaption = qsTr("Save WireGuard config")
shareConnectionDrawer.configExtension = ".conf"
shareConnectionDrawer.configFileName = "amnezia_for_wireguard"
@@ -129,6 +120,51 @@ PageType {
Layout.topMargin: 24
headerText: qsTr("Share VPN Access")
+
+ actionButtonImage: "qrc:/images/controls/more-vertical.svg"
+ actionButtonFunction: function() {
+ shareFullAccessDrawer.open()
+ }
+
+ DrawerType {
+ id: shareFullAccessDrawer
+
+ width: root.width
+ height: root.height * 0.45
+
+
+ ColumnLayout {
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.topMargin: 16
+
+ spacing: 0
+
+ Header2Type {
+ Layout.fillWidth: true
+ Layout.bottomMargin: 16
+ Layout.leftMargin: 16
+ Layout.rightMargin: 16
+
+ headerText: qsTr("Share full access to the server and VPN")
+ descriptionText: qsTr("Use for your own devices, or share with those you trust to manage the server.")
+ }
+
+
+ LabelWithButtonType {
+ Layout.fillWidth: true
+
+ text: qsTr("Share")
+ rightImageSource: "qrc:/images/controls/chevron-right.svg"
+
+ clickedFunction: function() {
+ PageController.goToPage(PageEnum.PageShareFullAccess)
+ shareFullAccessDrawer.close()
+ }
+ }
+ }
+ }
}
Rectangle {
@@ -189,7 +225,7 @@ PageType {
}
TextFieldWithHeaderType {
- id: userNameTextField
+ id: clientNameTextField
Layout.fillWidth: true
Layout.topMargin: 16
@@ -242,11 +278,6 @@ PageType {
serverSelector.severSelectorIndexChanged()
}
- //full access label
-// if (accessTypeSelector.currentIndex !== 0) {
-// shareConnectionDrawer.headerText = qsTr("Accessing ") + serverSelector.text
-// shareConnectionDrawer.configContentHeaderText = qsTr("File with accessing settings to ") + serverSelector.text
-// }
serverSelector.menuVisible = false
}
@@ -419,7 +450,7 @@ PageType {
}
ListView {
- id: usersListView
+ id: clientsListView
Layout.fillWidth: true
Layout.preferredHeight: childrenRect.height
@@ -431,7 +462,7 @@ PageType {
interactive: false
delegate: Item {
- implicitWidth: usersListView.width
+ implicitWidth: clientsListView.width
implicitHeight: delegateContent.implicitHeight
ColumnLayout {
@@ -447,19 +478,19 @@ PageType {
LabelWithButtonType {
Layout.fillWidth: true
- text: userName
+ text: clientName
descriptionText: containerName
rightImageSource: "qrc:/images/controls/chevron-right.svg"
clickedFunction: function() {
- userInfoDrower.open()
+ clientInfoDrawer.open()
}
}
DividerType {}
DrawerType {
- id: userInfoDrower
+ id: clientInfoDrawer
width: root.width
height: root.height * 0.45
@@ -478,7 +509,7 @@ PageType {
Layout.fillWidth: true
Layout.bottomMargin: 24
- headerText: userName
+ headerText: clientName
descriptionText: serverSelector.text + ", " + containerName
}
@@ -507,7 +538,7 @@ PageType {
onVisibleChanged: {
if (clientNameEditDrawer.visible) {
- clientName.textField.forceActiveFocus()
+ clientNameEditor.textField.forceActiveFocus()
}
}
@@ -520,11 +551,10 @@ PageType {
anchors.rightMargin: 16
TextFieldWithHeaderType {
- id: clientName
-
+ id: clientNameEditor
Layout.fillWidth: true
headerText: qsTr("Client name")
- textFieldText: userName
+ textFieldText: clientName
}
BasicButtonType {
@@ -533,10 +563,10 @@ PageType {
text: qsTr("Save")
onClicked: {
- if (clientName.textFieldText !== userName) {
+ if (clientNameEditor.textFieldText !== clientName) {
PageController.showBusyIndicator(true)
ExportController.renameClient(index,
- clientName.textFieldText,
+ clientNameEditor.textFieldText,
ContainersModel.getCurrentlyProcessedContainerIndex(),
ServersModel.getCurrentlyProcessedServerCredentials())
PageController.showBusyIndicator(false)
@@ -561,14 +591,14 @@ PageType {
text: qsTr("Revoke")
onClicked: function() {
- questionDrawer.headerText = qsTr("Revoke the config for a user - ") + userName + "?"
+ questionDrawer.headerText = qsTr("Revoke the config for a user - ") + clientName + "?"
questionDrawer.descriptionText = qsTr("The user will no longer be able to connect to your server.")
questionDrawer.yesButtonText = qsTr("Continue")
questionDrawer.noButtonText = qsTr("Cancel")
questionDrawer.yesButtonFunction = function() {
questionDrawer.close()
- userInfoDrower.close()
+ clientInfoDrawer.close()
root.revokeConfig(index)
}
questionDrawer.noButtonFunction = function() {
diff --git a/client/ui/qml/Pages2/PageShareFullAccess.qml b/client/ui/qml/Pages2/PageShareFullAccess.qml
new file mode 100644
index 00000000..e59c57ef
--- /dev/null
+++ b/client/ui/qml/Pages2/PageShareFullAccess.qml
@@ -0,0 +1,155 @@
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
+import QtQuick.Dialogs
+
+import SortFilterProxyModel 0.2
+
+import PageEnum 1.0
+import ContainerProps 1.0
+
+import "./"
+import "../Controls2"
+import "../Controls2/TextTypes"
+import "../Components"
+
+PageType {
+ id: root
+
+ BackButtonType {
+ id: backButton
+
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.topMargin: 20
+ }
+
+ FlickableType {
+ anchors.top: backButton.bottom
+ anchors.bottom: parent.bottom
+ contentHeight: content.height
+
+ ColumnLayout {
+ id: content
+
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.right: parent.right
+
+ anchors.rightMargin: 16
+ anchors.leftMargin: 16
+
+ spacing: 0
+
+ HeaderType {
+ Layout.fillWidth: true
+ Layout.topMargin: 24
+
+ headerText: qsTr("Full access to the server and VPN")
+ }
+
+ ParagraphTextType {
+ Layout.fillWidth: true
+ Layout.topMargin: 24
+ Layout.bottomMargin: 24
+
+ text: qsTr("We recommend that you use full access to the server only for your own additional devices.\n") +
+ qsTr("If you share full access with other people, they can remove and add protocols and services to the server, which will cause the VPN to work incorrectly for all users. ")
+ color: "#878B91"
+ }
+
+ DropDownType {
+ id: serverSelector
+
+ signal severSelectorIndexChanged
+ property int currentIndex: 0
+
+ Layout.fillWidth: true
+ Layout.topMargin: 16
+
+ drawerHeight: 0.4375
+
+ descriptionText: qsTr("Server")
+ headerText: qsTr("Server")
+
+ listView: ListViewWithRadioButtonType {
+ id: serverSelectorListView
+
+ rootWidth: root.width
+ imageSource: "qrc:/images/controls/check.svg"
+
+ model: SortFilterProxyModel {
+ id: proxyServersModel
+ sourceModel: ServersModel
+ filters: [
+ ValueFilter {
+ roleName: "hasWriteAccess"
+ value: true
+ }
+ ]
+ }
+
+ currentIndex: 0
+
+ clickedFunction: function() {
+ handler()
+
+ if (serverSelector.currentIndex !== serverSelectorListView.currentIndex) {
+ serverSelector.currentIndex = serverSelectorListView.currentIndex
+ }
+
+ shareConnectionDrawer.headerText = qsTr("Accessing ") + serverSelector.text
+ shareConnectionDrawer.configContentHeaderText = qsTr("File with accessing settings to ") + serverSelector.text
+ serverSelector.menuVisible = false
+ }
+
+ Component.onCompleted: {
+ handler()
+ }
+
+ function handler() {
+ serverSelector.text = selectedText
+ ServersModel.currentlyProcessedIndex = proxyServersModel.mapToSource(currentIndex)
+ }
+ }
+ }
+
+ BasicButtonType {
+ Layout.fillWidth: true
+ Layout.topMargin: 40
+
+ text: qsTr("Share")
+ imageSource: "qrc:/images/controls/share-2.svg"
+
+ onClicked: function() {
+ shareConnectionDrawer.headerText = qsTr("Connection to ") + serverSelector.text
+ shareConnectionDrawer.configContentHeaderText = qsTr("File with connection settings to ") + serverSelector.text
+
+ shareConnectionDrawer.needCloseButton = false
+
+ shareConnectionDrawer.open()
+ shareConnectionDrawer.contentVisible = false
+ PageController.showBusyIndicator(true)
+
+ if (Qt.platform.os === "android") {
+ ExportController.generateFullAccessConfigAndroid();
+ } else {
+ ExportController.generateFullAccessConfig();
+ }
+
+ PageController.showBusyIndicator(false)
+
+ shareConnectionDrawer.needCloseButton = true
+ PageController.showTopCloseButton(true)
+
+ shareConnectionDrawer.contentVisible = true
+ }
+ }
+
+ ShareConnectionDrawer {
+ id: shareConnectionDrawer
+ }
+ }
+ }
+}