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

Feat/70 wallet locked warnings in content scripts API #174

Closed
wants to merge 35 commits into from

Conversation

caudurodev
Copy link
Contributor

@caudurodev caudurodev commented May 16, 2022

This PR aims to always request the user log in before attempting to make requests to the extension via content scripts API. If the user is not logged in the expected behavior is that the extension popup will open with account create or password screens as well as warning message in the currently opened tab.

This PR also modifies e2e tests affected by this change as well as attempts to address flaky tests that used timeouts, replacing them with events to avoid different behavior in different computational environments.

The user will be able to make requests successfully if the following conditions are met:

  • wallet is created
  • wallet is unlocked
  • current website is authorized

otherwise the popup will request one of the above be corrected.

This PR does not address the issue of queuing requests if the user is logged out - we do not remember previous requests until the user finally succeeds in logging in.

Notes:

  • please review the blocked methods in the ProxyEmeris.ts file to see if you agree the chosen methods should request authentication before being processed (I don't yet know exactly what all methods do in detail)
  • I have edited the flow so that the wallet needs to be unlocked before a website can be whitelisted - this is done in the popup. Let me know if there are issues around this.

Future enhancements: blocking API unauthorized requests could be handled more elegantly via Proxy traps, decorators or interceptors instead of directly in each function. I implemented it this way for simplicity since we require some methods to be functional and others not when the user is logged out, this way we have a simple way of adding blockers in a more granular way.

Addresses issues #70 #44 #59

@github-actions
Copy link

github-actions bot commented May 16, 2022

Visit the preview URL for this PR (updated for commit 51bec06):

https://emeris-extension--pr174-feat-70-unlock-warni-1esjoq9m.web.app

(expires Mon, 06 Jun 2022 09:15:10 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

@caudurodev caudurodev force-pushed the feat/70-unlock-warnings branch 3 times, most recently from 9c5b506 to 6cff6dc Compare May 18, 2022 13:36
@caudurodev caudurodev marked this pull request as ready for review May 18, 2022 13:48
@caudurodev caudurodev marked this pull request as draft May 18, 2022 14:23
@caudurodev caudurodev marked this pull request as ready for review May 18, 2022 14:52
Copy link
Contributor

@Dawntraoz Dawntraoz left a comment

Choose a reason for hiding this comment

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

Demeris submodule should be updated, is pointing to an old commit in this PR. In the Readme there is a command to do it.

e2e/helpers.ts Outdated Show resolved Hide resolved
e2e/accounts.spec.ts Outdated Show resolved Hide resolved
e2e/cosmjs.spec.ts Outdated Show resolved Hide resolved
e2e/cosmjs.spec.ts Outdated Show resolved Hide resolved
e2e/cosmjs.spec.ts Outdated Show resolved Hide resolved
e2e/locked-wallet.spec.ts Outdated Show resolved Hide resolved
e2e/locked-wallet.spec.ts Outdated Show resolved Hide resolved
playwright.config.ts Outdated Show resolved Hide resolved
'Wallet not ready for requests. Please create/unlock wallet and whitelist current URL before making requests.',
);
this.enable();
return false;
Copy link
Contributor

Choose a reason for hiding this comment

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

why return false here? can't we just proceed after the user accepts the page?

Copy link
Contributor Author

@caudurodev caudurodev May 19, 2022

Choose a reason for hiding this comment

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

No, because the user needs to generally needs to unlock / create their wallet, then enable the website, then can make requests. This is the simplified approach where the popup needs to be opened each time a request is made and the next step is requested from the user.

I tried to keep the running queue of possible requests in memory, but it ended up too complicated and bad UX. For example:

  • User requests signing, but has no wallet. Requests needed to proceed:
  1. create a wallet, store mnemonic, backup later, etc (can terminate interaction in different places)
  2. whitelist website
  3. finally proceed with signing
  • User requests signing, has wallet but is locked. Requests needed to proceed:
  1. enter wallet password
  2. whitelist website
  3. finally proceed with signing

etc.

I attempted to queue these requests but it just became very complex as I had to detect the extension closing and checking the queue for more requests and then re-opening it. I think this initial approach is simpler for now. But we can discuss how to keep the queue and keep requesting user interaction as it's quite complex.

Copy link
Contributor

Choose a reason for hiding this comment

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

why does the user need to create a wallet to enable a website?

Copy link
Contributor

Choose a reason for hiding this comment

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

what do you mean by queue requests? where? can we not just await this.enable()?

Copy link
Contributor Author

@caudurodev caudurodev May 19, 2022

Choose a reason for hiding this comment

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

why does the user need to create a wallet to enable a website?

Because it would be a security issue to whitelist without first unlocking your extension. Or is your question about differentiating account creation from wallet creation? Can you create an account without a wallet?

what do you mean by queue requests? where? can we not just await this.enable()?

because this would cause all requests to queue in the current implementation. Each time you made a request the queue would increase until finally unlocked.

Copy link
Contributor

Choose a reason for hiding this comment

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

Can you create an account without a wallet?

you can set a password without creating a wallet.

Copy link
Contributor

Choose a reason for hiding this comment

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

the requests don't reach the Emeris.ts queue as they are send after the showPopupIfNotEnabled function. or am I missunderstanding sth? and keeping the couple of requests in the JS memory is not a problem is it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Might be simpler to discuss in a call @faboweb ?

@@ -109,6 +128,7 @@ export class ProxyEmeris implements IEmeris {
return response.data as boolean;
}
async supportedChains(): Promise<string[]> {
if (!(await this.showPopupIfNotEnabled())) return;
Copy link
Contributor

Choose a reason for hiding this comment

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

this now also fails when the user doesn't have an account created yet. does that make sense?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure - Like I mentioned in the PR description I don't know what all methods do so if this needs to be unblocked let me know as it's easy to just remove.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've removed the block for now.

Copy link
Contributor

Choose a reason for hiding this comment

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

as the supported chains are likely also encrypted, I guess we still need to check if a password is set and the wallet is unlocked

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, blocked it again.

@caudurodev caudurodev force-pushed the feat/70-unlock-warnings branch from 98a24dc to 421cb6b Compare May 30, 2022 08:52
@clockworkgr
Copy link
Collaborator

I am very confused by this...

Why do we need to manually unlock before making requests?

There are 2 separate "exception flows" here....One is directed to the developer of the 3rd party app writing the extension integration and one towards the app user/extension owner. First one should throw errors for the dev to handle. Second one should be as frictionless as possible.

Cases should be as follows:

No wallet created: Any request made should throw with "No wallet found" -> app dev responsibility to notify the user
Wallet exists but locked: Any request should trigger unlock flow automatically then handle the request:
If a request OTHER than enable is made on a non-whitelisted website -> throw "App not whitelisted" error -> app dev responsibility to not allow the user to make requests until enable() has succeeded

@faboweb
Copy link
Contributor

faboweb commented May 31, 2022

No wallet created: Any request made should throw with "No wallet found" -> app dev responsibility to notify the user

apart from whitelisting which is independent of wallet creation

@caudurodev caudurodev closed this Jun 8, 2022
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.

4 participants