Turns out it is not needed to check whether an action is enabled before
triggerin it: the trigger is automatically suppressed if the action is
not yet enabled.
An app::Navigation class is introduced with an API very similar to the
Kirigami.PageRouter in QML. This new class is responsible for pusing
populated view model classes from C++ into QML ownership and triggering
appropriate navigation events. On the QML side a signal handler
forwards these calls to the Kirigami.PageRouter to perform the actual
navigation in the UI.
This construct paves the way for moving state transition and related
logic out of QML and towards C++, since this logic is currently mostly
concerned with page navigation in Keysmith. Ultimately that transition
should make the QML (page) views more easily re-usable.
Replace existing manual manipulation of the application page stack with
a more declarative setup using Kirigami.PageRouter. This change does
not yet address the control flow: pages are not yet properly decoupled.
With this change the user now gets appropriate error feedback when trying to unlock their accounts using an incorrect password.
Additionally password entry is temporarily suspended in the UI while key derivation (etc.) is in progress.
This should help convey the idea that "something is happening", or rather avoid the impression that "nothing happens" or "this is broken" when in fact key derivation may simply be slow depending on the machine.
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: #14
This change implements necessary control flow to pick up on accounts being passed to Keysmith via commandline options.
This change covers UX only for the happy flow case in which the received account is a valid otpauth:// URI.
If such an URI is passed to Keysmith, then the Add Account form is automatically pushed on the page stack and pre-populated with data received from the commandline.
With this UX, if the account is valid the user may either accept it immediately or tweak settings (most likely account name/issuer) to make it valid.
Issues: #7, #14
Users may now cancel adding an account and dismiss the page.
This change is particularly relevant in the context of an account that is being added via URI passed on the commandline: the user may now explicitly reject it.
Additionally quitting Keysmith from the add account form is now also supported, hidden behding a boolean flag.
This will be useful for the initial page when receiving an account via URI from the commandline: the user may reject the account and quit Keysmith via a single action.
Issues: #7, #14
This page is a bit of a bodge for the fact that the current Accounts model must be 'unlocked' before it can be used.
In turn, this means that it is not straightforward to check that an account is still 'available' when presenting the user with the option to add an account received via URI from the commandline.
The solution implemented here is to check and let the user recover after unlocking, if necessary.
Issues: #7, #14
This new component can be used to inject an interstitial page, letting the user know something went wrong and allowing them to decide whether to continue or to quit Keysmith.
This is especially useful when Keysmith was launched automatically from some other context (i.e. another app) without the user necessarily being fully aware of it.
Issues: #7, #14
With this change AccountNameValidator can now be used without having a functional Accounts model.
This allows the existing AddAccount page to be re-used for context without a valid Accounts model, e.g. when receiving accounts via URI from the commandline.
Issues: #7, #14
With this change top-level QML code may pass a (populated) ValidatedAccountInput object to pre-populate fields in the add account forms.
Issues: #7, #14
Previously a user could accidentally trigger an additional 'add account' action even when the action (button) was not visible in the UI.
This oversight is now fixed.
- Introduce re-usable account name + issuer form. This will help to support overriding account name/issuer when adding accounts via OTP token URI/QR code
- Move common settings out of TokenDetailsForm into AddAccount.qml
Issues: #7
This change prepares the UI for supporting alternative and more complex flows for adding accounts.
All parameters are now collated into a single "validated input" object which is more convenient to pass around between views
This makes it possible to support back- and forth navigation between "basic" and "advanced/details" forms for adding accounts.
Additionally it provides a fundamental building block for adding alternative ways to add accounts (e.g. via OTP token URI/QR code).
Issues: #7
With this the AccountStorage module now fully supports some HOTP/TOTP parameters which are uncommon (but still part of HOTP/TOTP specifications).
- Better types for offset, tokenLength. Make this consistent throughout
- Finish support for offset, checksum parameters for HOTP tokens in AccountStorage
- Finish support for hashing algorithm, epoch parameters for TOTP tokens in AccountStorage
- Better API for creating oath::Algorithm instances
- Code formatting (break up long lines)
Issues: #7
With this change account storage and model work with accounts for which an issuer is recorded.
This is a prerequisite for fully supporting otpauth:// URIs (necessary for QR code support) in Keysmith.
Issues: #7, #13
See-Also: https://github.com/google/google-authenticator/wiki/Key-Uri-Format
- Increase height
- Make the left edge sit flush with the edge of the list item
- Fix colour contrast when a list item is being highlighted (pressed/checked)
Turns out that SwipeListItem (and derivatives) absolutely must have an `id` value of `listItem`.
With this change the account list entries now display a proper flood fill effect when pressed on Android.
In some cases Keysmith may be suspended and animations/timers are no longer updated.
With this change, the application now detects when it is being 'woken' from suspend and refreshes the UI.
- Refactor code to have delegates per account-type & simplify code
- Rework layouting in terms of anchors
- Fix positioning of account name and token labels to be vertically
centered
- Make health indicator/token life timer for TOTP accounts sit flush
with the bottom of the TOTP delegate UI itself and extend along the
whole width. This resolves issue #11
With this change Keysmith now prompts the user to either:
- setup a new password
- supply an existing password (if detected)
Additionally the organisation/structure of the QML is cleaned up a bit.
All QML pages are dedicated QML files and a few signals are introduced
to provide slightly better encapsulation/decouple interdependencies.
Delegate recycling causes a bug when removing an account and then adding
it back: the old, stale UI for the account is reused instead of a new one.
In combination with 'alive' guard property on the UI for account entries,
this results in the account entry becoming frozen in the old stale state.
(Incorrect helath indicators, tokens that do not update and buttons that no
longer respond anymore.)
After triggering the removal of an account from storage in the UI, it may
be possible for the UI not to fully reflect this change for a while yet.
During this short time window, it is possible for an operation to occur on
an already deleted account object which is a use-after-free bug.
In particular signals from animations and timers in the QML UI might still
trigger which causes a slot to be invoked that accesses the underlying
account object.
This change introduces a guard property called 'alive' which is flipped
when the account removal operation is triggered. Slots are updated to
check for the alive status of the UI before proceeding with other logic.