Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Attempt empty password for keystore unlock before prompting for pass #548

Closed
wants to merge 0 commits into from
Closed

[WIP] Attempt empty password for keystore unlock before prompting for pass #548

wants to merge 0 commits into from

Conversation

aitrean
Copy link
Contributor

@aitrean aitrean commented Dec 11, 2017

Closes MyEtherWallet/MyEtherWallet#423

Hi guys. Since Henry and James were having so much fun with MEW I thought I'd try my hand at a few of your issues - if that's alright. This solution is for issue MyEtherWallet/MyEtherWallet#423 which I tested against some keystore files I generated with ethereumjs-wallet. It's working, however, there is a 1 - 2 second pause when we decrypt an empty-password encoded file. There doesn't seem to be any indicator that the wallet is being generated either, so there is a 1 -2 second period where it doesn't look like the UI is responsive. In V3, it looks like you guys use a notifier to indicate the file has been received, but I'm not seeing that notification in this build. Is that an issue?

@james-prado james-prado changed the title Attempt empty password for keystore unlock before prompting for pass [WIP] Attempt empty password for keystore unlock before prompting for pass Dec 11, 2017
@aitrean
Copy link
Contributor Author

aitrean commented Dec 11, 2017

Looking at it again, the pause between uploading a password-empty encrypted file and loading the wallet can be more significant than just 1 - 2 seconds, up to 30 seconds sometimes. It looks like a lot of this time is waiting for the ethereumjs-wallet to generate the wallet with the empty passphrase. I can see similar wait time in your live version when I upload a password-empty encrypted keystore, but here it just looks unresponsive since we immediately try the empty passphrase. Perhaps a UI indicator would help to indicate the wallet is loading?

@dternyak
Copy link
Contributor

Thanks for your contribution and interest @aitrean!

Great point about the UI being un-responsive while decrypt is taking place. Unfortunately, the call itself is synchronous, and thus blocks the UI, so we aren't able to show a loading indicator (or at the very least, the loading indicator would be blocked as well).

Let me do some research and decide if there is a way to ensure the UI is responsive while we attempt to decrypt the wallet.

We definitely don't want to hurt overall UX by trying to fix a relatively un-common use-case.

@HenryNguyen5
Copy link

You could use setTimeout with 0 ms to push the sync call onto the event loop, preventing the UI from being blocked. And then place a spinner component while it's waiting

@dternyak
Copy link
Contributor

dternyak commented Dec 11, 2017

In this case, we'd be showing a spinner to all users (while the decryption runs) who have uploaded a keystore, which is probably not the desired UX.

Perhaps the alternative is to prevent the UI from being blocked, but also don't show any loading indicator, and simply login if the empty passphrase succeeds? This lets the more common user flow where users do input a password continue to function, while still providing a convenience to users who don't have a password.

@aitrean
Copy link
Contributor Author

aitrean commented Dec 11, 2017

@HenryNguyen5 I'll look into that

@dternyak Perhaps I'm misunderstanding, but would a spinner on the unblocked UI be detrimental to users with real passwords? Files encrypted with real passwords immediately reject the blank password, so they wouldn't see the spinner. Also, if you only unblock the UI, it will look like the interface didn't acknowledge your file change. If not a spinner, what about those notifications you have in the bottom of your live version when a file gets uploaded? I don't see them in this build.

@dternyak
Copy link
Contributor

@aitrean Got it - as long as the existing flow for users with passwords doesn't change (e.g. they don't briefly see a loading indicator and then immediately disappear) that approach should be fine 👍

@dternyak
Copy link
Contributor

The issue is that there are encrypted keystores with empty passphrases, so I don't believe you can just check with isPassRequired -- you actually have to attempt the decrypt with an empty passphrase, which would block, requiring you to show a loading indicator to all users.

@HenryNguyen5
Copy link

Another (arguably cleaner and more scalable) solution would be to use webworkers for decryption tasks as it's CPU heavy

@aitrean
Copy link
Contributor Author

aitrean commented Dec 11, 2017

@dternyak Gotcha. I like Henry's idea to use a webworker for handling the ethereumjs library decryption behaviour. To address the ultra-brief spinner appearance on password-encrypted files, could we set up a timer to wait for a webworker? If the webworker doesn't signal within x seconds, load the spinner so that the user doesn't think the UI has ignored them.

@dternyak
Copy link
Contributor

@aitrean I haven't worked with web workers much before, but I think this should work in theory. @wbobeirne I think you may have had some web worker experience iirc - do you happen any thoughts?

@wbobeirne
Copy link
Contributor

It definitely is a good use case for workers, but it's not exactly a very trivial refactor. Workers take in completely different files, so this would mean adding a new loader to webpack, and splitting out our decrypting logic into their own files that then get output and loaded in separately. I think all of this could be reasonably be tucked away into a wrapper async function, so there'd be little change on the component side.

I think this'd be a great way to go, as it'd also close out #219.

yield put(showNotification('danger', translate('ERROR_6')));
if (password !== '') {
yield put(showNotification('danger', translate('ERROR_6')));
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even if the password is blank, it could throw for other reasons (Invalid file?) We should ideally check if the password is blank and if it's a certain type of error.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Woops! I should have seen that. Thanks for the feedback!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, testing this issue again without my changes, I see that there's no error at all for incorrect file uploads. I can upload jpgs to the keystore and it will give me an unlock button. Can't find this issue logged. Shall I open one?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, please do 👍

@aitrean aitrean closed this Dec 28, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants