qml: fix issues with 2fa, simplify terms and conditions retrieval code
This commit is contained in:
@@ -28,10 +28,8 @@ class Plugin(TrustedCoinPlugin):
|
|||||||
class QSignalObject(PluginQObject):
|
class QSignalObject(PluginQObject):
|
||||||
canSignWithoutServerChanged = pyqtSignal()
|
canSignWithoutServerChanged = pyqtSignal()
|
||||||
_canSignWithoutServer = False
|
_canSignWithoutServer = False
|
||||||
termsAndConditionsChanged = pyqtSignal()
|
termsAndConditionsRetrieved = pyqtSignal([str], arguments=['message'])
|
||||||
_termsAndConditions = ''
|
termsAndConditionsError = pyqtSignal([str], arguments=['message'])
|
||||||
termsAndConditionsErrorChanged = pyqtSignal()
|
|
||||||
_termsAndConditionsError = ''
|
|
||||||
otpError = pyqtSignal([str], arguments=['message'])
|
otpError = pyqtSignal([str], arguments=['message'])
|
||||||
otpSuccess = pyqtSignal()
|
otpSuccess = pyqtSignal()
|
||||||
disclaimerChanged = pyqtSignal()
|
disclaimerChanged = pyqtSignal()
|
||||||
@@ -76,14 +74,6 @@ class Plugin(TrustedCoinPlugin):
|
|||||||
def otpSubmit(self, otp):
|
def otpSubmit(self, otp):
|
||||||
self._plugin.on_otp(otp)
|
self._plugin.on_otp(otp)
|
||||||
|
|
||||||
@pyqtProperty(str, notify=termsAndConditionsChanged)
|
|
||||||
def termsAndConditions(self):
|
|
||||||
return self._termsAndConditions
|
|
||||||
|
|
||||||
@pyqtProperty(str, notify=termsAndConditionsErrorChanged)
|
|
||||||
def termsAndConditionsError(self):
|
|
||||||
return self._termsAndConditionsError
|
|
||||||
|
|
||||||
@pyqtProperty(str, notify=remoteKeyStateChanged)
|
@pyqtProperty(str, notify=remoteKeyStateChanged)
|
||||||
def remoteKeyState(self):
|
def remoteKeyState(self):
|
||||||
return self._remoteKeyState
|
return self._remoteKeyState
|
||||||
@@ -122,14 +112,11 @@ class Plugin(TrustedCoinPlugin):
|
|||||||
self.plugin.logger.debug('TOS')
|
self.plugin.logger.debug('TOS')
|
||||||
tos = server.get_terms_of_service()
|
tos = server.get_terms_of_service()
|
||||||
except ErrorConnectingServer as e:
|
except ErrorConnectingServer as e:
|
||||||
self._termsAndConditionsError = _('Error connecting to server')
|
self.termsAndConditionsError.emit(_('Error connecting to server'))
|
||||||
self.termsAndConditionsErrorChanged.emit()
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self._termsAndConditionsError = '%s: %s' % (_('Error'), repr(e))
|
self.termsAndConditionsError.emit('%s: %s' % (_('Error'), repr(e)))
|
||||||
self.termsAndConditionsErrorChanged.emit()
|
|
||||||
else:
|
else:
|
||||||
self._termsAndConditions = tos
|
self.termsAndConditionsRetrieved.emit(tos)
|
||||||
self.termsAndConditionsChanged.emit()
|
|
||||||
finally:
|
finally:
|
||||||
self._busy = False
|
self._busy = False
|
||||||
self.busyChanged.emit()
|
self.busyChanged.emit()
|
||||||
@@ -143,7 +130,11 @@ class Plugin(TrustedCoinPlugin):
|
|||||||
@pyqtSlot(str)
|
@pyqtSlot(str)
|
||||||
def createKeystore(self, email):
|
def createKeystore(self, email):
|
||||||
self.remoteKeyState = ''
|
self.remoteKeyState = ''
|
||||||
|
self._otpSecret = ''
|
||||||
|
self.otpSecretChanged.emit()
|
||||||
|
|
||||||
xprv1, xpub1, xprv2, xpub2, xpub3, short_id = self.plugin.create_keys()
|
xprv1, xpub1, xprv2, xpub2, xpub3, short_id = self.plugin.create_keys()
|
||||||
|
|
||||||
def create_remote_key_task():
|
def create_remote_key_task():
|
||||||
try:
|
try:
|
||||||
self.plugin.logger.debug('create remote key')
|
self.plugin.logger.debug('create remote key')
|
||||||
@@ -179,6 +170,7 @@ class Plugin(TrustedCoinPlugin):
|
|||||||
self.logger.error("unexpected trustedcoin xpub3: expected {}, received {}".format(xpub3, _xpub3))
|
self.logger.error("unexpected trustedcoin xpub3: expected {}, received {}".format(xpub3, _xpub3))
|
||||||
self.remoteKeyError.emit('Unexpected trustedcoin xpub3')
|
self.remoteKeyError.emit('Unexpected trustedcoin xpub3')
|
||||||
return
|
return
|
||||||
|
self.remoteKeyState = 'new'
|
||||||
self._otpSecret = otp_secret
|
self._otpSecret = otp_secret
|
||||||
self.otpSecretChanged.emit()
|
self.otpSecretChanged.emit()
|
||||||
self._shortId = short_id
|
self._shortId = short_id
|
||||||
@@ -198,12 +190,15 @@ class Plugin(TrustedCoinPlugin):
|
|||||||
def resetOtpSecret(self):
|
def resetOtpSecret(self):
|
||||||
self.remoteKeyState = ''
|
self.remoteKeyState = ''
|
||||||
xprv1, xpub1, xprv2, xpub2, xpub3, short_id = self.plugin.create_keys()
|
xprv1, xpub1, xprv2, xpub2, xpub3, short_id = self.plugin.create_keys()
|
||||||
|
|
||||||
def reset_otp_task():
|
def reset_otp_task():
|
||||||
try:
|
try:
|
||||||
|
# TODO: move reset request to UI agnostic plugin section
|
||||||
self.plugin.logger.debug('reset_otp')
|
self.plugin.logger.debug('reset_otp')
|
||||||
r = server.get_challenge(short_id)
|
r = server.get_challenge(short_id)
|
||||||
challenge = r.get('challenge')
|
challenge = r.get('challenge')
|
||||||
message = 'TRUSTEDCOIN CHALLENGE: ' + challenge
|
message = 'TRUSTEDCOIN CHALLENGE: ' + challenge
|
||||||
|
|
||||||
def f(xprv):
|
def f(xprv):
|
||||||
rootnode = BIP32Node.from_xkey(xprv)
|
rootnode = BIP32Node.from_xkey(xprv)
|
||||||
key = rootnode.subkey_at_private_derivation((0, 0)).eckey
|
key = rootnode.subkey_at_private_derivation((0, 0)).eckey
|
||||||
@@ -220,6 +215,7 @@ class Plugin(TrustedCoinPlugin):
|
|||||||
self.remoteKeyState = 'error'
|
self.remoteKeyState = 'error'
|
||||||
self.remoteKeyError.emit(f'Error: {str(e)}')
|
self.remoteKeyError.emit(f'Error: {str(e)}')
|
||||||
else:
|
else:
|
||||||
|
self.remoteKeyState = 'reset'
|
||||||
self._otpSecret = otp_secret
|
self._otpSecret = otp_secret
|
||||||
self.otpSecretChanged.emit()
|
self.otpSecretChanged.emit()
|
||||||
finally:
|
finally:
|
||||||
@@ -260,7 +256,6 @@ class Plugin(TrustedCoinPlugin):
|
|||||||
t = threading.Thread(target=check_otp_task, daemon=True)
|
t = threading.Thread(target=check_otp_task, daemon=True)
|
||||||
t.start()
|
t.start()
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, *args):
|
def __init__(self, *args):
|
||||||
super().__init__(*args)
|
super().__init__(*args)
|
||||||
|
|
||||||
@@ -269,7 +264,6 @@ class Plugin(TrustedCoinPlugin):
|
|||||||
if not isinstance(wallet, self.wallet_class):
|
if not isinstance(wallet, self.wallet_class):
|
||||||
return
|
return
|
||||||
self.logger.debug(f'plugin enabled for wallet "{str(wallet)}"')
|
self.logger.debug(f'plugin enabled for wallet "{str(wallet)}"')
|
||||||
#wallet.handler_2fa = HandlerTwoFactor(self, window)
|
|
||||||
if wallet.can_sign_without_server():
|
if wallet.can_sign_without_server():
|
||||||
self.so._canSignWithoutServer = True
|
self.so._canSignWithoutServer = True
|
||||||
self.so.canSignWithoutServerChanged.emit()
|
self.so.canSignWithoutServerChanged.emit()
|
||||||
@@ -279,12 +273,6 @@ class Plugin(TrustedCoinPlugin):
|
|||||||
_('Therefore, two-factor authentication is disabled.')
|
_('Therefore, two-factor authentication is disabled.')
|
||||||
])
|
])
|
||||||
self.logger.info(msg)
|
self.logger.info(msg)
|
||||||
#action = lambda: window.show_message(msg)
|
|
||||||
#else:
|
|
||||||
#action = partial(self.settings_dialog, window)
|
|
||||||
#button = StatusBarButton(read_QIcon("trustedcoin-status.png"),
|
|
||||||
#_("TrustedCoin"), action)
|
|
||||||
#window.statusBar().addPermanentWidget(button)
|
|
||||||
self.start_request_thread(wallet)
|
self.start_request_thread(wallet)
|
||||||
|
|
||||||
@hook
|
@hook
|
||||||
|
|||||||
@@ -12,10 +12,6 @@ WizardComponent {
|
|||||||
|
|
||||||
property bool otpVerified: false
|
property bool otpVerified: false
|
||||||
|
|
||||||
function apply() {
|
|
||||||
wizard_data['trustedcoin_new_otp_secret'] = requestNewSecret.checked
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
|
||||||
@@ -40,7 +36,7 @@ WizardComponent {
|
|||||||
|
|
||||||
QRImage {
|
QRImage {
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
visible: plugin.remoteKeyState == ''
|
visible: plugin.remoteKeyState == 'new' || plugin.remoteKeyState == 'reset'
|
||||||
qrdata: encodeURI('otpauth://totp/Electrum 2FA ' + wizard_data['wallet_name']
|
qrdata: encodeURI('otpauth://totp/Electrum 2FA ' + wizard_data['wallet_name']
|
||||||
+ '?secret=' + plugin.otpSecret + '&digits=6')
|
+ '?secret=' + plugin.otpSecret + '&digits=6')
|
||||||
render: plugin.otpSecret
|
render: plugin.otpSecret
|
||||||
|
|||||||
@@ -10,9 +10,10 @@ import "../../../gui/qml/components/controls"
|
|||||||
WizardComponent {
|
WizardComponent {
|
||||||
valid: !plugin ? false
|
valid: !plugin ? false
|
||||||
: email.text.length > 0 // TODO: validate email address
|
: email.text.length > 0 // TODO: validate email address
|
||||||
&& plugin.termsAndConditions
|
&& tosShown
|
||||||
|
|
||||||
property QtObject plugin
|
property QtObject plugin
|
||||||
|
property bool tosShown: false
|
||||||
|
|
||||||
onAccept: {
|
onAccept: {
|
||||||
wizard_data['2fa_email'] = email.text
|
wizard_data['2fa_email'] = email.text
|
||||||
@@ -21,7 +22,9 @@ WizardComponent {
|
|||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
Label { text: qsTr('Terms and conditions') }
|
Label {
|
||||||
|
text: qsTr('Terms and conditions')
|
||||||
|
}
|
||||||
|
|
||||||
TextHighlightPane {
|
TextHighlightPane {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
@@ -39,7 +42,6 @@ WizardComponent {
|
|||||||
width: parent.width
|
width: parent.width
|
||||||
rightPadding: constants.paddingSmall
|
rightPadding: constants.paddingSmall
|
||||||
wrapMode: Text.Wrap
|
wrapMode: Text.Wrap
|
||||||
text: plugin ? plugin.termsAndConditions : ''
|
|
||||||
}
|
}
|
||||||
ScrollIndicator.vertical: ScrollIndicator { }
|
ScrollIndicator.vertical: ScrollIndicator { }
|
||||||
}
|
}
|
||||||
@@ -51,7 +53,9 @@ WizardComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Label { text: qsTr('Email') }
|
Label {
|
||||||
|
text: qsTr('Email')
|
||||||
|
}
|
||||||
|
|
||||||
TextField {
|
TextField {
|
||||||
id: email
|
id: email
|
||||||
@@ -64,4 +68,15 @@ WizardComponent {
|
|||||||
plugin = AppController.plugin('trustedcoin')
|
plugin = AppController.plugin('trustedcoin')
|
||||||
plugin.fetchTermsAndConditions()
|
plugin.fetchTermsAndConditions()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: plugin
|
||||||
|
function onTermsAndConditionsRetrieved(message) {
|
||||||
|
termsText.text = message
|
||||||
|
tosShown = true
|
||||||
|
}
|
||||||
|
function onTermsAndConditionsError(message) {
|
||||||
|
termsText.text = message
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user