amnezia-client/client/ui/qml/Pages2/PageSetupWizardCredentials.qml
lunardunno 059257fc58
Merge branch 'dev' into check_sudo_permissions (#1441)
* refactoring: improved the performance of secure_settings

* bugfix: fixed textFields on PageSetupWizardCredentials

* bugfix: fixed scrolling by keys on PageSettingsApiServerInfo

* chore: hide site links for ios (#1374)

* chore: fixed log output with split tunneling info

* chore: hide "open logs folder" button for mobule platforms

* chore: fixed again log output with split tunneling info

* chore: bump version

* Install apparmor (#1379)

Install apparmor

* chore: returned the backup page for androidTV

* Enable PFS for Windows IKEv2

* refactoring: moved api info pages from ServerInfo

* refactoring: moved gateway interaction functions to a separate class

* bugfix: fixed storeEndpoint parsing

* chore: returned links for mobile platforms

* Update VPN protocol descriptions

* Update VPN description texts

* feature: added pages for subscription settings feature

* feature: added page for export api native configs

* feature: added error handling and minor ui fixes

* refactor: update ios build configuration to use automatic code signing and prebuilt OpenVPNAdapter framework

* feat: remove OpenVPNAdapter submodule

* feat: remove ios openvpn script and associated cmake configuration

* Update README.md

* Update README_RU.md

* Update README.md

fix link

* feature: added share vpn key to subscription settings page

* bugfix: fixed possible crush on android

* add timeouts in ipc client init

* apply timeouts only for Windows

* apply format to file

* refactoring: simplified the validity check of the config before connection

- improved project structure

* bugfix: fixed visability of share drawer

* feature: added 409 error handling from server response

* chore: fixed android build

* chore: fixed qr code display

* Rewrite timeouts using waitForSource

* feature: added error messages handler

* feature: added issued configs info parsing

* feature: added functionality to revoke api configs

* chore: added links to instructions

* chore: fixed qr code with vpnkey processing

* chore: fixed native config post processing

* chore: added link to android tv instruction

* change node to IpcProcessTun2SocksReplica

* chore: minor ui fixes

* Update Windows OpenSSL  (#1426)

* Update Windows OpenSSL to 3.0.16 and add shared library for QSslSocket plugin

* chore: update link to submodule 3rd-prebuild

---------

Co-authored-by: vladimir.kuznetsov <nethiuswork@gmail.com>

* chore: added 404 handling for revoke configs

- added revoke before remove api server for premium v2

* chore: added log to see proxy decrypt errors

* chore: minor ui fix

* chore: bump version

* bugfix: fixed mobile controllers initialization (#1436)

* bugfix: fixed mobile controllers initialization

* chore: bump version

* Merge pull request #1440 from amnezia-vpn/feature/subscription-settings-page

feature/subscription settings page

---------

Co-authored-by: vladimir.kuznetsov <nethiuswork@gmail.com>
Co-authored-by: pokamest <pokamest@gmail.com>
Co-authored-by: Mykola Baibuz <mykola.baibuz@gmail.com>
Co-authored-by: Yaroslav Yashin <yaroslav.yashin@gmail.com>
Co-authored-by: KsZnak <ksu@amnezia.org>
Co-authored-by: Cyril Anisimov <CyAn84@gmail.com>
2025-03-01 16:08:52 +04:00

252 lines
7.3 KiB
QML

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import PageEnum 1.0
import Style 1.0
import "./"
import "../Controls2"
import "../Config"
import "../Controls2/TextTypes"
PageType {
id: root
BackButtonType {
id: backButton
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: 20
onFocusChanged: {
if (this.activeFocus) {
listView.positionViewAtBeginning()
}
}
}
ListView {
id: listView
anchors.top: backButton.bottom
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.left: parent.left
property bool isFocusable: true
Keys.onTabPressed: {
FocusController.nextKeyTabItem()
}
Keys.onBacktabPressed: {
FocusController.previousKeyTabItem()
}
Keys.onUpPressed: {
FocusController.nextKeyUpItem()
}
Keys.onDownPressed: {
FocusController.nextKeyDownItem()
}
Keys.onLeftPressed: {
FocusController.nextKeyLeftItem()
}
Keys.onRightPressed: {
FocusController.nextKeyRightItem()
}
ScrollBar.vertical: ScrollBarType {}
header: ColumnLayout {
width: listView.width
HeaderType {
Layout.fillWidth: true
Layout.leftMargin: 16
Layout.rightMargin: 16
Layout.bottomMargin: 16
headerText: qsTr("Configure your server")
}
}
model: inputFields
spacing: 16
clip: true
reuseItems: true
delegate: ColumnLayout {
width: listView.width
TextFieldWithHeaderType {
id: delegate
Layout.fillWidth: true
Layout.leftMargin: 16
Layout.rightMargin: 16
headerText: title
textField.echoMode: hideContent ? TextInput.Password : TextInput.Normal
textField.placeholderText: placeholderContent
textField.text: textField.text
rightButtonClickedOnEnter: true
clickedFunc: function () {
clickedHandler()
}
textField.onFocusChanged: {
textField.text = textField.text.replace(/^\s+|\s+$/g, '')
}
textField.onTextChanged: {
if (hideContent) {
buttonImageSource = textField.text !== "" ? (hideContent ? "qrc:/images/controls/eye.svg" : "qrc:/images/controls/eye-off.svg") : ""
}
}
}
}
footer: ColumnLayout {
width: listView.width
BasicButtonType {
id: continueButton
Layout.fillWidth: true
Layout.topMargin: 32
Layout.leftMargin: 16
Layout.rightMargin: 16
text: qsTr("Continue")
clickedFunc: function() {
if (!root.isCredentialsFilled()) {
return
}
InstallController.setShouldCreateServer(true)
var _hostname = listView.itemAtIndex(vars.hostnameIndex).children[0].textField.text
var _username = listView.itemAtIndex(vars.usernameIndex).children[0].textField.text
var _secretData = listView.itemAtIndex(vars.secretDataIndex).children[0].textField.text
InstallController.setProcessedServerCredentials(_hostname, _username, _secretData)
PageController.showBusyIndicator(true)
var isConnectionOpened = InstallController.checkSshConnection()
PageController.showBusyIndicator(false)
if (!isConnectionOpened) {
return
}
PageController.goToPage(PageEnum.PageSetupWizardEasy)
}
}
LabelTextType {
Layout.fillWidth: true
Layout.topMargin: 24
Layout.leftMargin: 16
Layout.rightMargin: 16
Layout.bottomMargin: 16
text: qsTr("All data you enter will remain strictly confidential and will not be shared or disclosed to the Amnezia or any third parties")
}
CardWithIconsType {
id: siteLink
Layout.fillWidth: true
Layout.leftMargin: 16
Layout.rightMargin: 16
Layout.bottomMargin: 16
headerText: qsTr("How to run your VPN server")
bodyText: qsTr("Where to get connection data, step-by-step instructions for buying a VPS")
rightImageSource: "qrc:/images/controls/chevron-right.svg"
leftImageSource: "qrc:/images/controls/help-circle.svg"
onClicked: {
Qt.openUrlExternally(LanguageModel.getCurrentSiteUrl() + "/starter-guide")
}
}
}
}
function isCredentialsFilled() {
var hasEmptyField = false
var hostnameItem = listView.itemAtIndex(vars.hostnameIndex).children[0]
if (hostnameItem.textField.text === "") {
hostnameItem.errorText = qsTr("Ip address cannot be empty")
hasEmptyField = true
} else if (!hostnameItem.textField.acceptableInput) {
hostnameItem.errorText = qsTr("Enter the address in the format 255.255.255.255:88")
}
var usernameItem = listView.itemAtIndex(vars.usernameIndex).children[0]
if (usernameItem.textField.text === "") {
usernameItem.errorText = qsTr("Login cannot be empty")
hasEmptyField = true
}
var secretDataItem = listView.itemAtIndex(vars.secretDataIndex).children[0]
if (secretDataItem.textField.text === "") {
secretDataItem.errorText = qsTr("Password/private key cannot be empty")
hasEmptyField = true
}
return !hasEmptyField
}
property list<QtObject> inputFields: [
hostnameObject,
usernameObject,
secretDataObject
]
QtObject {
id: hostnameObject
property string title: qsTr("Server IP address [:port]")
readonly property string placeholderContent: qsTr("255.255.255.255:22")
property bool hideContent: false
readonly property var clickedHandler: undefined
}
QtObject {
id: usernameObject
property string title: qsTr("SSH Username")
readonly property string placeholderContent: "root"
property bool hideContent: false
readonly property var clickedHandler: undefined
}
QtObject {
id: secretDataObject
property string title: qsTr("Password or SSH private key")
readonly property string placeholderContent: ""
property bool hideContent: true
readonly property var clickedHandler: function() {
hideContent = !hideContent
}
}
QtObject {
id: vars
readonly property int hostnameIndex: 0
readonly property int usernameIndex: 1
readonly property int secretDataIndex: 2
}
}