Warning, /utilities/keysmith/src/contents/ui/AddAccount.qml is written in an unsupported language. File is not indexed.
0001 /*
0002 * SPDX-License-Identifier: GPL-3.0-or-later
0003 * SPDX-FileCopyrightText: 2020-2021 Johan Ouwerkerk <jm.ouwerkerk@gmail.com>
0004 * SPDX-FileCopyrightText: 2020 Carl Schwan <carl@carlschwan.eu>
0005 */
0006
0007 import QtQuick
0008 import QtQuick.Layouts
0009 import QtQuick.Controls as QQC2
0010 import org.kde.kirigami as Kirigami
0011 import org.kde.kirigamiaddons.formcard 1 as FormCard
0012
0013 import Keysmith.Application as Application
0014 import Keysmith.Models as Models
0015 import Keysmith.Validators as Validators
0016
0017 FormCard.FormCardPage {
0018 id: root
0019
0020 required property Application.AddAccountViewModel vm
0021
0022 title: i18nc("@title:window", "Add new account")
0023
0024 property bool detailsEnabled: false
0025
0026 property bool secretAcceptable: accountSecret.acceptableInput
0027 property bool tokenTypeAcceptable: hotpRadio.checked || totpRadio.checked
0028 property bool hotpDetailsAcceptable: hotpDetails.acceptable || vm.input.type === Models.ValidatedAccountInput.Totp
0029 property bool totpDetailsAcceptable: totpDetails.acceptable || vm.input.type === Models.ValidatedAccountInput.Hotp
0030 property bool tokenDetailsAcceptable: hotpDetailsAcceptable && totpDetailsAcceptable
0031 property bool acceptable: accountName.acceptable && secretAcceptable && tokenTypeAcceptable && tokenDetailsAcceptable
0032
0033 topPadding: Kirigami.Units.gridUnit
0034 bottomPadding: Kirigami.Units.gridUnit
0035
0036 data: Connections {
0037 target: vm.input
0038 function onTypeChanged() {
0039 root.detailsEnabled = false;
0040 }
0041 }
0042
0043 actions: [
0044 Kirigami.Action {
0045 text: i18nc("@action:button cancel and dismiss the add account form", "Cancel")
0046 icon.name: "edit-undo"
0047 onTriggered: {
0048 vm.cancelled();
0049 }
0050 },
0051 Kirigami.Action {
0052 text: i18nc("@action:button Dismiss the error page and quit Keysmith", "Quit")
0053 icon.name: "application-exit"
0054 enabled: vm.quitEnabled
0055 visible: vm.quitEnabled
0056 onTriggered: {
0057 Qt.quit();
0058 }
0059 },
0060 Kirigami.Action {
0061 text: i18nc("@action:button", "Add")
0062 icon.name: "answer-correct"
0063 enabled: acceptable
0064 onTriggered: {
0065 vm.accepted();
0066 }
0067 }
0068 ]
0069
0070 Component.onCompleted: accountName.forceActiveFocus()
0071
0072 AccountNameForm {
0073 id: accountName
0074 Layout.fillWidth: true
0075 accounts: vm.accounts
0076 validateAccountAvailability: vm.validateAvailability
0077 validatedInput: vm.input
0078 }
0079
0080 FormCard.FormHeader {
0081 title: i18nc("@label:chooser", "Account type:")
0082 }
0083
0084 FormCard.FormCard {
0085 id: requiredDetails
0086
0087 FormCard.FormRadioDelegate {
0088 id: totpRadio
0089 checked: vm.input.type === Models.ValidatedAccountInput.Totp
0090 text: i18nc("@option:radio", "Time-based OTP")
0091 onCheckedChanged: {
0092 if (checked) {
0093 vm.input.type = Models.ValidatedAccountInput.Totp;
0094 }
0095 }
0096 }
0097
0098 FormCard.FormRadioDelegate {
0099 id: hotpRadio
0100 checked: vm.input.type === Models.ValidatedAccountInput.Hotp
0101 text: i18nc("@option:radio", "Hash-based OTP")
0102 onCheckedChanged: {
0103 if (checked) {
0104 vm.input.type = Models.ValidatedAccountInput.Hotp;
0105 }
0106 }
0107 }
0108
0109 FormCard.FormDelegateSeparator { below: hotpRadio }
0110
0111 FormCard.FormTextFieldDelegate {
0112 id: accountSecret
0113 placeholderText: i18n("Token secret")
0114 text: vm.input.secret
0115 echoMode: TextInput.Password
0116 label: i18nc("@label:textbox", "Secret key:")
0117 validator: Validators.Base32SecretValidator {
0118 id: secretValidator
0119 }
0120 inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhNoPredictiveText | Qt.ImhSensitiveData | Qt.ImhHiddenText
0121 onTextChanged: {
0122 if (acceptableInput) {
0123 vm.input.secret = text;
0124 }
0125 }
0126 }
0127
0128 FormCard.FormDelegateSeparator { above: toggleDetails }
0129
0130 FormCard.FormButtonDelegate {
0131 id: toggleDetails
0132 text: i18nc("Button to reveal form for configuring additional token details", "Details")
0133 enabled: !root.detailsEnabled && (hotpRadio.checked || totpRadio.checked)
0134 visible: enabled
0135 onClicked: root.detailsEnabled = true;
0136 }
0137 }
0138
0139 FormCard.FormHeader {
0140 title: i18nc("@title:group", "HOTP Details:")
0141 visible: hotpDetails.visible
0142 }
0143
0144 HOTPDetailsForm {
0145 id: hotpDetails
0146
0147 visible: enabled
0148 validatedInput: root.vm.input
0149 enabled: root.detailsEnabled && vm.input.type === Models.ValidatedAccountInput.Hotp
0150 }
0151
0152 FormCard.FormHeader {
0153 title: i18nc("@label", "TOTP Details:")
0154 visible: totpDetails.visible
0155 }
0156
0157 TOTPDetailsForm {
0158 id: totpDetails
0159
0160 visible: enabled
0161 validatedInput: root.vm.input
0162 enabled: root.detailsEnabled && vm.input.type === Models.ValidatedAccountInput.Totp
0163 }
0164 }