mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-06-20 02:00:55 +07:00
update: ui to set/change password and hint
This commit is contained in:
@@ -311,20 +311,20 @@ void SecureAppSettingsRepository::setFileEncryption(bool enabled)
|
||||
|
||||
QString SecureAppSettingsRepository::getPassword() const
|
||||
{
|
||||
return m_settings->getPassword();
|
||||
return value("Sec/password", "").toString();
|
||||
}
|
||||
void SecureAppSettingsRepository::setPassword(const QString &pwd)
|
||||
{
|
||||
m_settings->setPassword(pwd);
|
||||
setValue("Sec/password", pwd);
|
||||
}
|
||||
|
||||
QString SecureAppSettingsRepository::getHint() const
|
||||
{
|
||||
return m_settings->getHint();
|
||||
return value("Sec/hint", "").toString();
|
||||
}
|
||||
void SecureAppSettingsRepository::setHint(const QString &hint)
|
||||
{
|
||||
m_settings->setHint(hint);
|
||||
setValue("Sec/hint", hint);
|
||||
}
|
||||
|
||||
bool SecureAppSettingsRepository::isAutoConnect() const
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2 12C2 12 5 5 12 5C19 5 22 12 22 12C22 12 19 19 12 19C5 19 2 12 2 12Z" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M12 15C13.6569 15 15 13.6569 15 12C15 10.3431 13.6569 9 12 9C10.3431 9 9 10.3431 9 12C9 13.6569 10.3431 15 12 15Z" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 474 B |
@@ -0,0 +1,6 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M9.88061 9.87891C9.58587 10.1536 9.34946 10.4848 9.18549 10.8528C9.02152 11.2208 8.93336 11.618 8.92625 12.0208C8.91914 12.4236 8.99324 12.8237 9.14412 13.1973C9.29501 13.5708 9.51959 13.9102 9.80446 14.1951C10.0893 14.4799 10.4287 14.7045 10.8022 14.8554C11.1758 15.0063 11.5759 15.0804 11.9787 15.0733C12.3815 15.0662 12.7788 14.978 13.1468 14.814C13.5148 14.6501 13.846 14.4137 14.1206 14.1189" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M10.7305 5.08C11.1518 5.02751 11.5759 5.00079 12.0005 5C19.0005 5 22.0005 12 22.0005 12C21.5534 12.9571 20.9927 13.8569 20.3305 14.68" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M6.61 6.60938C4.62125 7.964 3.02987 9.82463 2 11.9994C2 11.9994 5 18.9994 12 18.9994C13.9159 19.0045 15.7908 18.4445 17.39 17.3894" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M2 2L22 22" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg width="10" height="11" viewBox="0 0 10 11" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2.5 5V3C2.5 2.33696 2.76339 1.70107 3.23223 1.23223C3.70107 0.763392 4.33696 0.5 5 0.5C5.66304 0.5 6.29893 0.763392 6.76777 1.23223C7.23661 1.70107 7.5 2.33696 7.5 3V5M1.5 5H8.5C9.05229 5 9.5 5.44772 9.5 6V9.5C9.5 10.0523 9.05229 10.5 8.5 10.5H1.5C0.947715 10.5 0.5 10.0523 0.5 9.5V6C0.5 5.44772 0.947715 5 1.5 5Z" stroke="#EB5757" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 494 B |
@@ -0,0 +1,3 @@
|
||||
<svg width="10" height="11" viewBox="0 0 10 11" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2.5 5.00252V3.00252C2.49938 2.38254 2.72914 1.78445 3.14469 1.32435C3.56023 0.864252 4.13191 0.574969 4.74875 0.512663C5.36559 0.450356 5.98357 0.61947 6.48274 0.987175C6.9819 1.35488 7.32663 1.89494 7.45 2.50252M1.5 5.00252H8.5C9.05229 5.00252 9.5 5.45023 9.5 6.00252V9.50252C9.5 10.0548 9.05229 10.5025 8.5 10.5025H1.5C0.947715 10.5025 0.5 10.0548 0.5 9.50252V6.00252C0.5 5.45023 0.947715 5.00252 1.5 5.00252Z" stroke="#5CAEE7" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 592 B |
@@ -21,6 +21,8 @@
|
||||
<file>controls/delete.svg</file>
|
||||
<file>controls/download.svg</file>
|
||||
<file>controls/edit-3.svg</file>
|
||||
<file>controls/eye-off-new.svg</file>
|
||||
<file>controls/eye-new.svg</file>
|
||||
<file>controls/eye-off.svg</file>
|
||||
<file>controls/eye.svg</file>
|
||||
<file>controls/external-link.svg</file>
|
||||
@@ -36,6 +38,8 @@
|
||||
<file>controls/home.svg</file>
|
||||
<file>controls/infinity.svg</file>
|
||||
<file>controls/info.svg</file>
|
||||
<file>controls/lock-locked.svg</file>
|
||||
<file>controls/lock-unlocked.svg</file>
|
||||
<file>controls/mail.svg</file>
|
||||
<file>controls/map-pin.svg</file>
|
||||
<file>controls/more-vertical.svg</file>
|
||||
|
||||
@@ -316,26 +316,6 @@ void SecureQSettings::setSecTag(const QString &tag, const QByteArray &data)
|
||||
}
|
||||
}
|
||||
|
||||
void SecureQSettings::setPassword(const QString &pwd)
|
||||
{
|
||||
m_password = pwd;
|
||||
}
|
||||
|
||||
void SecureQSettings::setHint(const QString &hint)
|
||||
{
|
||||
m_hint = hint;
|
||||
}
|
||||
|
||||
QString SecureQSettings::getPassword() const
|
||||
{
|
||||
return m_password;
|
||||
}
|
||||
|
||||
QString SecureQSettings::getHint() const
|
||||
{
|
||||
return m_hint;
|
||||
}
|
||||
|
||||
static QString opensslErrString()
|
||||
{
|
||||
unsigned long e = ERR_get_error();
|
||||
|
||||
@@ -57,9 +57,6 @@ private:
|
||||
"Conf/", "Servers/",
|
||||
};
|
||||
|
||||
mutable QString m_password;
|
||||
mutable QString m_hint;
|
||||
|
||||
mutable QByteArray m_key;
|
||||
mutable QByteArray m_iv;
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ namespace PageLoader
|
||||
PageSettingsSplitTunneling,
|
||||
PageSettingsAppSplitTunneling,
|
||||
PageSettingsKillSwitch,
|
||||
PageSettingsAppEncryption,
|
||||
PageSettingsAppPassword,
|
||||
PageSettingsAppPasswordConfirm,
|
||||
PageSettingsApiServerInfo,
|
||||
|
||||
@@ -148,6 +148,7 @@ signals:
|
||||
void startMinimizedChanged();
|
||||
|
||||
void fileEncryptionStateChanged();
|
||||
void changingPassword();
|
||||
|
||||
private:
|
||||
SettingsController* m_settingsController;
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Qt5Compat.GraphicalEffects
|
||||
|
||||
import Style 1.0
|
||||
|
||||
import "../Controls2"
|
||||
import "../Controls2/TextTypes"
|
||||
|
||||
import "../Config"
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
property string textColor: AmneziaStyle.color.paleGray
|
||||
|
||||
property string textString
|
||||
property int textFormat: Text.PlainText
|
||||
|
||||
property string iconPath
|
||||
property real iconWidth: 16
|
||||
property real iconHeight: 16
|
||||
|
||||
color: AmneziaStyle.color.onyxBlack
|
||||
radius: 32
|
||||
implicitHeight: iconHeight + 8
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: 16
|
||||
Layout.rightMargin: 16
|
||||
Layout.bottomMargin: 16
|
||||
|
||||
RowLayout {
|
||||
id: content
|
||||
width: parent.width
|
||||
anchors.fill: parent
|
||||
|
||||
anchors.leftMargin: content.width / 4
|
||||
anchors.rightMargin: content.width / 4
|
||||
anchors.topMargin: 4
|
||||
anchors.bottomMargin: 4
|
||||
|
||||
spacing: 0
|
||||
|
||||
Image {
|
||||
Layout.alignment: Qt.AlignTop
|
||||
|
||||
width: iconWidth
|
||||
height: iconHeight
|
||||
|
||||
source: iconPath
|
||||
}
|
||||
|
||||
CaptionTextType {
|
||||
id: supportingText
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: 8
|
||||
|
||||
text: textString
|
||||
textFormat: root.textFormat
|
||||
color: textColor
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
|
||||
import Style 1.0
|
||||
|
||||
import "../Controls2"
|
||||
import "../Controls2/TextTypes"
|
||||
|
||||
import "../Config"
|
||||
|
||||
DrawerType2 {
|
||||
id: root
|
||||
objectName: "passwordDrawer"
|
||||
|
||||
property var securedFunc
|
||||
|
||||
expandedStateContent: ColumnLayout {
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: 16
|
||||
anchors.leftMargin: 16
|
||||
anchors.rightMargin: 16
|
||||
|
||||
Header2TextType {
|
||||
Layout.fillWidth: true
|
||||
Layout.bottomMargin: 8
|
||||
|
||||
text: qsTr("Enter password to continue")
|
||||
}
|
||||
|
||||
TextFieldWithHeaderType {
|
||||
id: passwordField
|
||||
|
||||
property bool hideContent: true
|
||||
|
||||
Layout.fillWidth: true
|
||||
|
||||
headerText: qsTr("Password")
|
||||
textField.echoMode: hideContent ? TextInput.Password : TextInput.Normal
|
||||
textField.text: textField.text
|
||||
|
||||
rightButtonClickedOnEnter: true
|
||||
|
||||
clickedFunc: function () {
|
||||
hideContent = !hideContent
|
||||
buttonImageSource = textField.text !== "" ? (hideContent ? "qrc:/images/controls/eye.svg" : "qrc:/images/controls/eye-off.svg") : ""
|
||||
}
|
||||
|
||||
textField.onFocusChanged: {
|
||||
textField.text = textField.text.replace(/^\s+|\s+$/g, '')
|
||||
}
|
||||
|
||||
textField.onTextChanged: {
|
||||
buttonImageSource = textField.text !== "" ? (hideContent ? "qrc:/images/controls/eye.svg" : "qrc:/images/controls/eye-off.svg") : ""
|
||||
}
|
||||
}
|
||||
|
||||
LabelTextType {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 8
|
||||
Layout.bottomMargin: 16
|
||||
|
||||
text: SettingsController.getHint()
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
id: doneButton
|
||||
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: qsTr("Done")
|
||||
|
||||
clickedFunc: function() {
|
||||
if (passwordField.textField.text !== SettingsController.getPassword()) {
|
||||
passwordField.errorText = qsTr("Incorrect password")
|
||||
return
|
||||
}
|
||||
|
||||
if (root.securedFunc && typeof root.securedFunc === "function") {
|
||||
root.securedFunc()
|
||||
}
|
||||
|
||||
root.closeTriggered()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
|
||||
import PageEnum 1.0
|
||||
import Style 1.0
|
||||
|
||||
import "./"
|
||||
import "../Controls2"
|
||||
import "../Config"
|
||||
import "../Controls2/TextTypes"
|
||||
import "../Components"
|
||||
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
property bool isChangingPassword: false
|
||||
|
||||
Connections {
|
||||
target: SettingsController
|
||||
|
||||
function onFileEncryptionStateChanged() {
|
||||
PageController.showBusyIndicator(true)
|
||||
PageController.closePage()
|
||||
PageController.goToPage(PageEnum.PageSettingsAppEncryption)
|
||||
PageController.showBusyIndicator(false)
|
||||
}
|
||||
}
|
||||
|
||||
BackButtonType {
|
||||
id: backButton
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: 20
|
||||
|
||||
onFocusChanged: {
|
||||
if (this.activeFocus) {
|
||||
listView.positionViewAtBeginning()
|
||||
}
|
||||
}
|
||||
|
||||
backButtonFunction: function() {
|
||||
PageController.closePage()
|
||||
if (root.isChangingPassword) {
|
||||
root.isChangingPassword = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ListViewType {
|
||||
id: listView
|
||||
|
||||
anchors.top: backButton.bottom
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.right: parent.right
|
||||
anchors.left: parent.left
|
||||
|
||||
header: ColumnLayout {
|
||||
width: listView.width
|
||||
|
||||
BaseHeaderType {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: 16
|
||||
Layout.rightMargin: 16
|
||||
Layout.bottomMargin: 16
|
||||
|
||||
headerText: qsTr("File encryption")
|
||||
descriptionText: qsTr("For encrypting backups, configuration files, subscription keys, and logs")
|
||||
}
|
||||
|
||||
EncryptionIndicator {
|
||||
id: indicator
|
||||
|
||||
textString: SettingsController.isFileEncryptionEnabled() ? qsTr("Password set. Encryption on") : qsTr("Password not set. Encryption off")
|
||||
iconPath: SettingsController.isFileEncryptionEnabled() ? "qrc:/images/controls/lock-locked.svg" : "qrc:/images/controls/lock-unlocked.svg"
|
||||
}
|
||||
|
||||
|
||||
BasicButtonType {
|
||||
id: switchEncryptionButton
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 16
|
||||
Layout.leftMargin: 16
|
||||
Layout.rightMargin: 16
|
||||
|
||||
text: SettingsController.isFileEncryptionEnabled() ? qsTr("Turn off encryption") : qsTr("Turn on encryption")
|
||||
|
||||
clickedFunc: function() {
|
||||
SettingsController.isFileEncryptionEnabled() ? SettingsController.toggleFileEncryption(false)
|
||||
: SettingsController.toggleFileEncryption(true)
|
||||
}
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
id: changePasswordButton
|
||||
|
||||
hoveredColor: AmneziaStyle.color.slateGray
|
||||
defaultColor: AmneziaStyle.color.midnightBlack
|
||||
textColor: AmneziaStyle.color.paleGray
|
||||
borderWidth: 1
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 8
|
||||
Layout.leftMargin: 16
|
||||
Layout.rightMargin: 16
|
||||
|
||||
text: qsTr("Change password")
|
||||
|
||||
signal changingPassword
|
||||
|
||||
clickedFunc: function() {
|
||||
passwordDrawer.openTriggered()
|
||||
}
|
||||
}
|
||||
|
||||
PasswordDrawer {
|
||||
id: passwordDrawer
|
||||
|
||||
parent: root
|
||||
|
||||
anchors.fill: parent
|
||||
expandedHeight: root.height * 0.45
|
||||
|
||||
securedFunc: function() {
|
||||
root.isChangingPassword = true
|
||||
|
||||
PageController.showBusyIndicator(true)
|
||||
PageController.closePage()
|
||||
PageController.goToPage(PageEnum.PageSettingsAppPassword)
|
||||
PageController.showBusyIndicator(false)
|
||||
|
||||
SettingsController.changingPassword()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
spacing: 16
|
||||
|
||||
footer: ColumnLayout {
|
||||
width: listView.width
|
||||
|
||||
// TODO: add text
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
|
||||
import PageEnum 1.0
|
||||
import Style 1.0
|
||||
|
||||
import "./"
|
||||
import "../Controls2"
|
||||
import "../Config"
|
||||
import "../Controls2/TextTypes"
|
||||
import "../Components"
|
||||
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
property bool isChangingPassword: false
|
||||
|
||||
Connections {
|
||||
target: SettingsController
|
||||
|
||||
function onChangingPassword() {
|
||||
root.isChangingPassword = true
|
||||
}
|
||||
}
|
||||
|
||||
BackButtonType {
|
||||
id: backButton
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: 20
|
||||
|
||||
onFocusChanged: {
|
||||
if (this.activeFocus) {
|
||||
listView.positionViewAtBeginning()
|
||||
}
|
||||
}
|
||||
|
||||
backButtonFunction: function() {
|
||||
PageController.closePage()
|
||||
if (root.isChangingPassword) {
|
||||
root.isChangingPassword = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ListViewType {
|
||||
id: listView
|
||||
|
||||
anchors.top: backButton.bottom
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.right: parent.right
|
||||
anchors.left: parent.left
|
||||
|
||||
header: ColumnLayout {
|
||||
width: listView.width
|
||||
|
||||
BaseHeaderType {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: 16
|
||||
Layout.rightMargin: 16
|
||||
Layout.bottomMargin: 16
|
||||
|
||||
headerText: root.isChangingPassword ? qsTr("Password changing") : qsTr("File encryption")
|
||||
descriptionText: root.isChangingPassword ? qsTr("Files encrypted with old password will stay encrypted with old password")
|
||||
: qsTr("For encrypting backups, configuration files, subscription keys, and logs")
|
||||
}
|
||||
}
|
||||
|
||||
model: inputFields
|
||||
spacing: 16
|
||||
|
||||
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()
|
||||
buttonImageSource = textField.text !== "" ? imageSource : ""
|
||||
}
|
||||
|
||||
textField.onFocusChanged: {
|
||||
textField.text = textField.text.replace(/^\s+|\s+$/g, '')
|
||||
}
|
||||
|
||||
textField.onTextChanged: {
|
||||
buttonImageSource = textField.text !== "" ? imageSource : ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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.isPasswordProperlyFilled()) {
|
||||
return
|
||||
}
|
||||
|
||||
var _password = listView.itemAtIndex(vars.passwordIndex).children[0].textField.text
|
||||
var _hint = listView.itemAtIndex(vars.hintIndex).children[0].textField.text
|
||||
|
||||
SettingsController.setPassword(_password)
|
||||
SettingsController.setHint(_hint)
|
||||
|
||||
PageController.goToPage(PageEnum.PageSettingsAppPasswordConfirm)
|
||||
if (root.isChangingPassword) {
|
||||
SettingsController.changingPassword()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isPasswordProperlyFilled() {
|
||||
var tooShort = false
|
||||
|
||||
var secretDataItem = listView.itemAtIndex(vars.passwordIndex).children[0]
|
||||
if (secretDataItem.textField.text === "") {
|
||||
secretDataItem.errorText = qsTr("Password cannot be empty")
|
||||
tooShort = true
|
||||
} else if (secretDataItem.textField.text.length < 4) {
|
||||
secretDataItem.errorText = qsTr("Password too short")
|
||||
tooShort = true
|
||||
}
|
||||
|
||||
return !tooShort
|
||||
}
|
||||
|
||||
property list<QtObject> inputFields: [
|
||||
passwordObject,
|
||||
hintObject
|
||||
]
|
||||
|
||||
QtObject {
|
||||
id: passwordObject
|
||||
|
||||
property string title: root.isChangingPassword ? qsTr("New password") : qsTr("Set encryption password")
|
||||
readonly property string placeholderContent: ""
|
||||
property string imageSource: "qrc:/images/controls/eye-new.svg"
|
||||
property bool hideContent: true
|
||||
readonly property var clickedHandler: function() {
|
||||
hideContent = !hideContent
|
||||
imageSource = hideContent ? "qrc:/images/controls/eye-new.svg" : "qrc:/images/controls/eye-off-new.svg"
|
||||
}
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: hintObject
|
||||
|
||||
property string title: qsTr("Hint for password")
|
||||
readonly property string placeholderContent: ""
|
||||
property string imageSource: ""
|
||||
property bool hideContent: false
|
||||
readonly property var clickedHandler: undefined
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: vars
|
||||
|
||||
readonly property int passwordIndex: 0
|
||||
readonly property int hintIndex: 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
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
|
||||
|
||||
property bool isChangingPassword: false
|
||||
|
||||
Connections {
|
||||
target: SettingsController
|
||||
|
||||
function onChangingPassword() {
|
||||
root.isChangingPassword = true
|
||||
}
|
||||
}
|
||||
|
||||
BackButtonType {
|
||||
id: backButton
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: 20
|
||||
|
||||
onFocusChanged: {
|
||||
if (this.activeFocus) {
|
||||
listView.positionViewAtBeginning()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ListViewType {
|
||||
id: listView
|
||||
|
||||
anchors.top: backButton.bottom
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.right: parent.right
|
||||
anchors.left: parent.left
|
||||
|
||||
header: ColumnLayout {
|
||||
width: listView.width
|
||||
|
||||
BaseHeaderType {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: 16
|
||||
Layout.rightMargin: 16
|
||||
|
||||
headerText: root.isChangingPassword ? qsTr("Confirm new password") : qsTr("Confirm password")
|
||||
descriptionText: qsTr("If you forget your password, you'll have to reset all app settings to reset it."
|
||||
+ " Encrypted files will remain encrypted")
|
||||
}
|
||||
}
|
||||
|
||||
model: 1 // fake model
|
||||
spacing: 16
|
||||
|
||||
delegate: ColumnLayout {
|
||||
width: listView.width
|
||||
|
||||
TextFieldWithHeaderType {
|
||||
id: delegate
|
||||
|
||||
property bool hideContent: true
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 16
|
||||
Layout.leftMargin: 16
|
||||
Layout.rightMargin: 16
|
||||
|
||||
headerText: root.isChangingPassword ? qsTr("Enter new password one more time") : qsTr("Enter password one more time")
|
||||
textField.echoMode: hideContent ? TextInput.Password : TextInput.Normal
|
||||
textField.placeholderText: ""
|
||||
textField.text: textField.text
|
||||
|
||||
rightButtonClickedOnEnter: true
|
||||
|
||||
clickedFunc: function () {
|
||||
hideContent = !hideContent
|
||||
buttonImageSource = textField.text !== "" ? (hideContent ? "qrc:/images/controls/eye.svg" : "qrc:/images/controls/eye-off.svg") : ""
|
||||
}
|
||||
|
||||
textField.onFocusChanged: {
|
||||
textField.text = textField.text.replace(/^\s+|\s+$/g, '')
|
||||
}
|
||||
|
||||
textField.onTextChanged: {
|
||||
buttonImageSource = textField.text !== "" ? (hideContent ? "qrc:/images/controls/eye.svg" : "qrc:/images/controls/eye-off.svg") : ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
footer: ColumnLayout {
|
||||
width: listView.width
|
||||
|
||||
LabelTextType {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 16
|
||||
Layout.leftMargin: 16
|
||||
Layout.rightMargin: 16
|
||||
Layout.bottomMargin: 24
|
||||
|
||||
text: SettingsController.getHint()
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
id: continueButton
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: 16
|
||||
Layout.rightMargin: 16
|
||||
|
||||
text: root.isChangingPassword ? qsTr("Save new password") : qsTr("Turn on encryption")
|
||||
|
||||
clickedFunc: function() {
|
||||
if (!root.isPasswordProperlyFilled()) {
|
||||
return
|
||||
}
|
||||
|
||||
PageController.closePage()
|
||||
PageController.goToPage(PageEnum.PageSettings)
|
||||
PageController.goToPage(PageEnum.PageSettingsAppEncryption)
|
||||
SettingsController.toggleFileEncryption(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isPasswordProperlyFilled() {
|
||||
var notMatch = false
|
||||
|
||||
var secretDataItem = listView.itemAtIndex(0).children[0]
|
||||
if (secretDataItem.textField.text !== SettingsController.getPassword()) {
|
||||
secretDataItem.errorText = qsTr("Passwords not match")
|
||||
notMatch = true
|
||||
}
|
||||
|
||||
return !notMatch
|
||||
}
|
||||
}
|
||||
@@ -213,6 +213,23 @@ PageType {
|
||||
|
||||
DividerType {}
|
||||
|
||||
LabelWithButtonType {
|
||||
id: labelWithButtonAppPassword
|
||||
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: qsTr("File encryption")
|
||||
descriptionText: qsTr("For encrypting backups, configuration files, subscription keys, and logs")
|
||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||
|
||||
clickedFunction: function() {
|
||||
SettingsController.getPassword() === "" ? PageController.goToPage(PageEnum.PageSettingsAppPassword)
|
||||
: PageController.goToPage(PageEnum.PageSettingsAppEncryption)
|
||||
}
|
||||
}
|
||||
|
||||
DividerType {}
|
||||
|
||||
LabelWithButtonType {
|
||||
id: labelWithButtonLogging
|
||||
|
||||
|
||||
@@ -7,11 +7,13 @@
|
||||
<file>Components/HomeContainersListView.qml</file>
|
||||
<file>Components/HomeSplitTunnelingDrawer.qml</file>
|
||||
<file>Components/InstalledAppsDrawer.qml</file>
|
||||
<file>Components/PasswordDrawer.qml</file>
|
||||
<file>Components/ChangelogDrawer.qml</file>
|
||||
<file>Components/QuestionDrawer.qml</file>
|
||||
<file>Components/SelectLanguageDrawer.qml</file>
|
||||
<file>Components/ServersListView.qml</file>
|
||||
<file>Components/SettingsContainersListView.qml</file>
|
||||
<file>Components/EncryptionIndicator.qml</file>
|
||||
<file>Components/BenefitRow.qml</file>
|
||||
<file>Components/BenefitsPanel.qml</file>
|
||||
<file>Components/SubscriptionExpiredDrawer.qml</file>
|
||||
@@ -87,6 +89,9 @@
|
||||
<file>Pages2/PageSettingsApiServerInfo.qml</file>
|
||||
<file>Pages2/PageSettingsApplication.qml</file>
|
||||
<file>Pages2/PageSettingsAppSplitTunneling.qml</file>
|
||||
<file>Pages2/PageSettingsAppEncryption.qml</file>
|
||||
<file>Pages2/PageSettingsAppPassword.qml</file>
|
||||
<file>Pages2/PageSettingsAppPasswordConfirm.qml</file>
|
||||
<file>Pages2/PageSettingsBackup.qml</file>
|
||||
<file>Pages2/PageSettingsConnection.qml</file>
|
||||
<file>Pages2/PageSettingsDns.qml</file>
|
||||
|
||||
Reference in New Issue
Block a user