fix: make sure to display password setup page again when appropriate
The feature to accept accounts from the command line via otpauth:// URI inadvertently broke the initial password setup flow. With this change password setup and unlocking should now work correctly again in all cases/flows. Issues: #14master
parent
5c6c9020d8
commit
8d1a88b8df
|
@ -23,8 +23,6 @@ Kirigami.ApplicationWindow {
|
|||
property Models.ValidatedAccountInput validatedInput: Models.ValidatedAccountInput {}
|
||||
property Models.PasswordRequestModel passwordRequest: Keysmith.passwordRequest()
|
||||
|
||||
property Component passwordRequestPage: passwordRequest.previouslyDefined ? unlockAccountsPage : setupPasswordPage
|
||||
|
||||
Component {
|
||||
id: setupPasswordPage
|
||||
SetupPassword {
|
||||
|
@ -63,11 +61,13 @@ Kirigami.ApplicationWindow {
|
|||
}
|
||||
onCancelled: {
|
||||
root.addAccountConfirmed = false;
|
||||
popAddAccountPage(passwordRequestPage);
|
||||
popAddAccountPage();
|
||||
pushPasswordPage();
|
||||
}
|
||||
onNewAccount: {
|
||||
root.addAccountConfirmed = true;
|
||||
popAddAccountPage(passwordRequestPage);
|
||||
popAddAccountPage();
|
||||
pushPasswordPage();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -95,7 +95,8 @@ Kirigami.ApplicationWindow {
|
|||
title: i18nc("@title:window", "Invalid account")
|
||||
error: i18nc("@info:label", "The account you are trying to add is invalid. You can either quit the app, or continue without adding the account.")
|
||||
onDismissed: {
|
||||
popAddAccountPage(passwordRequestPage);
|
||||
popAddAccountPage();
|
||||
pushPasswordPage();
|
||||
}
|
||||
onQuit: {
|
||||
pageStack.pop();
|
||||
|
@ -152,6 +153,17 @@ Kirigami.ApplicationWindow {
|
|||
}
|
||||
}
|
||||
|
||||
function pushPasswordPage() {
|
||||
/*
|
||||
* Sanity check that the password request has been resolved already.
|
||||
* If it is not yet clear which type of password request is needed, then signals should still
|
||||
* fire once this becomes clear and the request is fully resolved.
|
||||
*/
|
||||
if (passwordRequest.previouslyDefined || passwordRequest.firstRun) {
|
||||
pageStack.push(passwordRequest.previouslyDefined ? unlockAccountsPage : setupPasswordPage);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO maybe have a onPasswordProvided handler to push a "progress" page to provide visual feedback for devices
|
||||
* where key derivation is slow?
|
||||
|
@ -171,17 +183,22 @@ Kirigami.ApplicationWindow {
|
|||
pageStack.push(accountsOverviewPage);
|
||||
}
|
||||
}
|
||||
onPreviouslyDefinedChanged: {
|
||||
onPasswordExists: {
|
||||
/*
|
||||
* Ignore if there is an account from the commandline to process: in that case password unlocking/setup is
|
||||
* Ignore if there is an account from the commandline to process: in that case password unlocking is
|
||||
* deferred until after account confirmation/rejection by the user
|
||||
*/
|
||||
if (!addAccountRequested) {
|
||||
/*
|
||||
* Cannot rely on passwordRequestPage property binding having been updated already here, work around
|
||||
* by repeating the passwordRequestPage property binding expression instead.
|
||||
*/
|
||||
pageStack.push(passwordRequest.previouslyDefined ? unlockAccountsPage : setupPasswordPage);
|
||||
pushPasswordPage();
|
||||
}
|
||||
}
|
||||
onNewPasswordNeeded: {
|
||||
/*
|
||||
* Ignore if there is an account from the commandline to process: in that case password setup is deferred
|
||||
* until after account confirmation/rejection by the user
|
||||
*/
|
||||
if (!addAccountRequested) {
|
||||
pushPasswordPage();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -220,6 +237,12 @@ Kirigami.ApplicationWindow {
|
|||
if (addAccountRequested) {
|
||||
root.validatedInput.reset();
|
||||
CommandLine.handleNewAccount(root.validatedInput);
|
||||
} else {
|
||||
/*
|
||||
* In case password request resolves more quickly than the UI, make sure to check if it has been resolved
|
||||
* yet and prompt for passwords.
|
||||
*/
|
||||
pushPasswordPage();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,13 +15,20 @@ namespace model
|
|||
QObject(parent), m_secret(secret), m_previous(false), m_haveKey(false), m_havePassword(false)
|
||||
{
|
||||
QObject::connect(m_secret, &accounts::AccountSecret::existingPasswordNeeded, this, &PasswordRequest::setPreviouslyDefined);
|
||||
QObject::connect(m_secret, &accounts::AccountSecret::newPasswordNeeded, this, &PasswordRequest::setNewPasswordNeeded);
|
||||
QObject::connect(m_secret, &accounts::AccountSecret::passwordAvailable, this, &PasswordRequest::setPasswordAvailable);
|
||||
QObject::connect(m_secret, &accounts::AccountSecret::keyAvailable, this, &PasswordRequest::setKeyAvailable);
|
||||
m_previous = secret->isExistingPasswordRequested();
|
||||
m_firstRun = secret->isNewPasswordRequested();
|
||||
m_haveKey = secret->isKeyAvailable();
|
||||
m_havePassword = secret->isPasswordAvailable();
|
||||
}
|
||||
|
||||
bool PasswordRequest::firstRun(void) const
|
||||
{
|
||||
return m_firstRun;
|
||||
}
|
||||
|
||||
bool PasswordRequest::previouslyDefined(void) const
|
||||
{
|
||||
return m_previous;
|
||||
|
@ -109,9 +116,21 @@ namespace model
|
|||
{
|
||||
if (!m_previous) {
|
||||
m_previous = true;
|
||||
Q_EMIT passwordRequestChanged();
|
||||
Q_EMIT passwordExists();
|
||||
} else {
|
||||
qCDebug(logger) << "Ignored signal: already marked password for existing secrets";
|
||||
}
|
||||
}
|
||||
|
||||
void PasswordRequest::setNewPasswordNeeded(void)
|
||||
{
|
||||
if (!m_firstRun) {
|
||||
m_firstRun = true;
|
||||
Q_EMIT passwordRequestChanged();
|
||||
Q_EMIT newPasswordNeeded();
|
||||
} else {
|
||||
qCDebug(logger) << "Ignored signal: already marked password for first run/setup of secrets";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,11 +12,13 @@ namespace model
|
|||
class PasswordRequest: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool previouslyDefined READ previouslyDefined NOTIFY passwordExists)
|
||||
Q_PROPERTY(bool firstRun READ firstRun NOTIFY passwordRequestChanged)
|
||||
Q_PROPERTY(bool previouslyDefined READ previouslyDefined NOTIFY passwordRequestChanged)
|
||||
Q_PROPERTY(bool keyAvailable READ keyAvailable NOTIFY derivedKey)
|
||||
Q_PROPERTY(bool passwordProvided READ passwordProvided NOTIFY passwordAccepted)
|
||||
public:
|
||||
explicit PasswordRequest(accounts::AccountSecret *secret, QObject *parent = nullptr);
|
||||
bool firstRun(void) const;
|
||||
bool previouslyDefined(void) const;
|
||||
bool keyAvailable(void) const;
|
||||
bool passwordProvided(void) const;
|
||||
|
@ -24,16 +26,20 @@ namespace model
|
|||
Q_INVOKABLE bool providePassword(QString password);
|
||||
Q_INVOKABLE bool provideBothPasswords(QString password, QString other);
|
||||
Q_SIGNALS:
|
||||
void passwordRequestChanged(void);
|
||||
void passwordExists(void);
|
||||
void newPasswordNeeded(void);
|
||||
void passwordAccepted(void);
|
||||
void derivedKey(void);
|
||||
private Q_SLOTS:
|
||||
void setKeyAvailable(void);
|
||||
void setPasswordAvailable(void);
|
||||
void setPreviouslyDefined(void);
|
||||
void setNewPasswordNeeded(void);
|
||||
private:
|
||||
accounts::AccountSecret * m_secret;
|
||||
private:
|
||||
bool m_firstRun;
|
||||
bool m_previous;
|
||||
bool m_haveKey;
|
||||
bool m_havePassword;
|
||||
|
|
Loading…
Reference in New Issue