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

Redirect to browser.blockstack.org not working anymore in Safari and Firefox #558

Open
jehunter5811 opened this Issue Oct 29, 2018 · 17 comments

Comments

Projects
None yet
9 participants
@jehunter5811
Copy link

jehunter5811 commented Oct 29, 2018

I believe this was the issue was was fixed to support redirect to the web app browser for Firefox: #521

And here's the issue for Safari:
#481

@larrysalibra

This comment has been minimized.

Copy link
Member

larrysalibra commented Nov 14, 2018

We only redirect to browser.blockstack.org for firefox and safari on mobile platforms. Is that what's broken for you?

@jehunter5811

This comment has been minimized.

Copy link

jehunter5811 commented Nov 14, 2018

@larrysalibra Nope it's on desktop. Thanks for the clarification. Not sure what the solution is, but that's not a good experience at all for users not running a local browser instance. This is the error a Safari user gets:

screen shot 2018-11-14 at 9 06 04 am

I didn't include the full authRequest token, but that's on the page also. A user coming to Graphite who has 0 knowledge of Blockstack will have no idea how to sign into Graphite.

@MichaelFedora

This comment has been minimized.

Copy link

MichaelFedora commented Dec 15, 2018

This is still an issue. browser.blockstack.org is unusable (in desktop firefox) until this is fixed... simply goes

blockstack.js: generating v1.1.0 auth request
openUriUsingFirefox
protocol handler detected

and then nothing happens. (for helloblockstack.com, lioapp.io with v1.2.0, and graphitedocs with v1.3.0).

Chromium based browsers do work, as it goes like this instead:

blockstack.js: generating v1.1.0 auth request
openUriWithTimeoutHack
protocol handler not detected
Navigated to https://blockstack.org/auth?...

Seems that the firefox uri thing is broken, which also breaks my extension... I hope this can get solved soon.


after doing some more digging, your custom uri handler for firefox is basically broken. The IFrame seems to go wherever you want despite not even supporting blockstack: protocol handlers. I agree with kenliao in #521 that it would be better to just intercept, or at least use web+blockstack: or ext+blockstack: protocols which are actually supportable.

@zone117x

This comment has been minimized.

Copy link
Member

zone117x commented Dec 16, 2018

Was brainstorming some more work arounds but came to dead end -

  • Launch custom protocol (which if the local app is installed, it will be opened)
  • Verify it worked with a GET or jsonp style resource request to the local app server like http://localhost:8888/installation-test.js

But looks like Firefox doesn't allows an https site to request from a http://localhost or a self-signed https://localhost resource :(

We should implement the Blockstack Browser as web browser extensions.

@MichaelFedora @yknl Regarding using web+blockstack: - this is referring to using the navigator.registerProtocolHandler API right? If so doesn't that have to be ran on the same origin as the registration target?

As in you can't run

navigator.registerProtocolHandler("web+blockstack", "https://blockstack.org/auth?=%s", "Blockstack");`

on say graphitedocs.com. I get the error Uncaught DOMException: Failed to execute 'registerProtocolHandler' on 'Navigator': Can only register custom handler in the document's origin.

@MichaelFedora

This comment has been minimized.

Copy link

MichaelFedora commented Dec 16, 2018

So for web+blockstack, yes that's how it would do it, but it would be registered by browser.blockstack.org or, alternatively, an extension. Not every blockstack app, haha.

(if it couldn't be registered by the browser, then it would be by blockstack.org and would be handled ala blockstack.org/auth as per usual).

@zone117x

This comment has been minimized.

Copy link
Member

zone117x commented Jan 3, 2019

@MichaelFedora Given how the navigator.registerProtocolHandler API works I'm unclear how it will help the situation. Any ideas?

@zone117x

This comment has been minimized.

Copy link
Member

zone117x commented Jan 3, 2019

I question the future viability of doing browser based detection at all. Firefox, Edge, and Safari no longer support protocol detection. So are we just going this for Chrome now?

When a browser update breaks protocol detection, we have to manually find out and fix, then all blockstack.js webapps must update - right? Lets say Chrome breaks detection and 90% of people are auto updated. It will take some time for the majority of webapps using blockstack.js to update. All the while we are sending users down a broken auth flow.

Proposal:
I recall other usages of protocol handlers that use a graceful fallback (like Steam games, Apple appstore, idk). We trigger the protocol handler, then 500ms later the modal displays something like "If Blockstack auth did not open, CLICK HERE". These none-authenticated browser tabs are already left open and unused in most cases right?

@hstove

This comment has been minimized.

Copy link
Contributor

hstove commented Jan 3, 2019

Yeah, I wish we could do something like that. It would make the problem much easier to solve.

The issue is that, on Safari, they don't have a protocol detection API, so you have to just try the redirect to blockstack://.... Once you do that, if the user doesn't have the native app installed, the entire page is just one big error that says "we don't know how to handle this protocol". You can't change the UI or do anything until the user refreshes the page.

@zone117x

This comment has been minimized.

Copy link
Member

zone117x commented Jan 3, 2019

@hstove Has anyone done testing and exhausted the available methods of performing the protocol launch, to ensure there are no ways to maintain an open page? It's been a while since I've implemented one of these protocol redirection pages - but there are lots of methods that may leave a page open like:

  • html meta content refresh <meta http-equiv="refresh" content="5;url=blockstack://example.com/" />
  • iframes
  • iframes with redirects on timeouts
@zone117x

This comment has been minimized.

Copy link
Member

zone117x commented Jan 3, 2019

Discussed with @hstove about using a protocol redirect "ping" of sorts to detect the capability 100% of the time. The proposal:

  • Web app tab A performs a protocol redirect for the propose of a ping (rather than auth). The url would be something like blockstack://echo?redirectURL=https://testapp.com/echoReply?uniqueID=12345
  • Auth app (if installed) does nothing but open the redirect url (web app tab B) as an echo reply.
  • Tab B uses cross-window communication to tell tab A that the protocol handler is available.
  • Tab B then redirects back to the localhost auth flow.
@yknl

This comment has been minimized.

Copy link
Collaborator

yknl commented Jan 3, 2019

Would the protocol redirect ping trigger the prompt in browsers like Safari? Is there going to be several tabs getting opened from this detection?

@zone117x

This comment has been minimized.

Copy link
Member

zone117x commented Jan 3, 2019

I think there are probably ways to trigger the protocol opening without a blank tab using iframes or some other technique.
But regardless, the "tab B" in this example is going to be another useless tab (in addition to the first one we already have).
EDIT: No additional tabs are left open since we can use tab B (the redirect ping tab) to return back to the authorization page).

@yknl

This comment has been minimized.

Copy link
Collaborator

yknl commented Jan 3, 2019

Would be great to see how this works in a quick prototype of some sort.

@MichaelFedora

This comment has been minimized.

Copy link

MichaelFedora commented Jan 3, 2019

I like the idea of a blockstack://echo command as a stricter test then just "does it not error out," but I agree that a quick prototype would be good to see that it is possible and works well.

The "if blockstack browser didn't launch click here" also would work well but for web extensions (like mine) it would always be interrupted and make the user experience quite annoying, unfortunately.

@zone117x I think I'd have to create a prototype in order to demonstrate the navigator.registerProtocolHandler effectively, but your solution seems a lot easier.

@zone117x

This comment has been minimized.

Copy link
Member

zone117x commented Jan 4, 2019

Prototype of new protocol detection method as described #558 (comment)

Changes:

Benefits of this approach:

  • Should work on all browsers and unlikely to be broken by any given browser.
  • Fixes Safari prompt about unknown protocol when auth-browser is not installed. Uses an iframe technique rather than window.location to launch the protocol uri.
  • Minor: if using private browsing or your non-default web browser, then the ping-back will fail and auth can still progress through http.
  • In theory this should work on mobile as well. No more browser user-agent detection code.

Good & bad:

  • If something prevents the protocol handler from pinging back to the webapp before the timeout (like a "Open Blockstack?" prompt or just slow computer) then the original tab will redirect to the http auth. I think this could also be considered good. In the situation of some unknown failure condition, user login will still be able to progress. And in the case of this false-positive (where the redirect happened but the protocol handler did launch) that original tab was already useless anyway with the current approach.

Downside:

  • Requires a minor wait/timeout before redirecting to the http/web auth.
  • The window redirection dance is a bit odd.
@aulneau

This comment has been minimized.

Copy link
Contributor

aulneau commented Jan 4, 2019

This is awesome! My initial reaction to using localStorage is that I wonder if we could not use it?

Have you seen the postMessage api? maybe we can use that instead. It'd be great to be able to test this when people are using blockstack within webworkers/node/etc (trying to avoid window), too.

As you pointed out, the timeout feels a bit iffy. I feel like there is a better way (maybe not though) to go about it. Will have to think about it.

All in all this is great, but yeah we should consider and heavily test this. I'm super happy there's progress!!

@zone117x

This comment has been minimized.

Copy link
Member

zone117x commented Jan 5, 2019

window.postMessage unfortunately only works between windows/tabs that have a relationship through iframes or popups (window.open) which I can't think of anyway to leverage due to the decouplization caused by using protocol handler + launching URIs through the OS.

window.localStorage luckily has an onchange event so we don't have to poll, and my prototype code already cleans up storage after itself. It's also using a unique ID for the storage key.

Regarding webworkers - I don't think any apps are performing auth in webworkers (if so we can add some additional code to communicate back to the window object).

Proper support for our APIs in nodejs (protocol auth and others) I think is an another issue (I agree needs attention). For plug-and-play support we need to be using runtime detection and/or better npm packaging (see my pull #581).

The timeout is a compromise that I wish we had a better solution for, but it is the main mechanism behind this approach. I think a timeout of 1-2 seconds is acceptable for users without the auth-browser installed, and I think the false-positives of an unintended http auth redirect are not significantly more harmful than the existing approach which leaves a stale unauthenticated tab.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment