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

Add Safari support #454

Open
skibitsky opened this issue Dec 5, 2020 · 10 comments
Open

Add Safari support #454

skibitsky opened this issue Dec 5, 2020 · 10 comments

Comments

@skibitsky
Copy link

skibitsky commented Dec 5, 2020

Hello,

Apple recently added support for Web Extensions in Safari which probably makes porting Hypothesis from Chrome/Firefox easier than ever before.

Apple also provides a converter tool.

@dpinney
Copy link

dpinney commented Jan 25, 2021

I see someone has succeeded in running the converter: https://github.com/edwang09/hypothesis_extension#note-for-safari

Some changes were needed in the javascript code, but the built extensions has been working for me (with the safari setting to trust unsigned extensions).

Looks like Apple requires a developer account ($100/year) to get the extension distributed through their app store, which is kind of a drag.

@ChristinWhite
Copy link

I'm considering switching to Firefox or Brave primarily to use Hypothes.is but I was also wondering about Safari's web extensions converter and might be game to work on it and send a pull request if I get it working and you guys are open to it.

@andymatuschak
Copy link

You can't login when running the built extensions because they've been built using the Chrome extension's OAuth key, which has a redirect URL using the Chrome extension's scheme (chrome-extension://) rather than the Safari extension's.

To make this work, you either need to run your own hypothesis server locally with the appropriate redirect URL for your Safari extension, or we need to persuade the Hypothes.is admins to add an official OAuth key for the Safari extension.

@ChristinWhite
Copy link

Honestly, between Hypothes.is and SingleFile I finally just switched to Vivaldi, I still vastly prefer the UX of Safari but they seem to be doing everything they possibly can to make it harder to create (and use) extensions with each major release and I'm tired of it.

@andymatuschak
Copy link

andymatuschak commented Nov 4, 2021

I spent some time looking into this again today because I believe this issue has become much more important. With the new support for Safari Web Extensions in iOS Safari, there is now, for the first time, a viable path to using hypothes.is on mobile devices (without copy/paste workarounds unrealistic for continuous use).

Unfortunately, the situation is much more complicated than I'd originally thought. The core problem is that Safari Web Extensions do not have a stable URL scheme. In Chrome, extensions vend content from chrome-extension://SOME-UUID, and that UUID is stable once a Google Play key has been generated. But in Safari, the safari-web-extension://UUID URL changes on each build. This means there's no way to configure an OAuth client with a valid redirect URL.

There is a potential solution, but it's substantially more onerous. It relies on the fact that Safari Web Extensions are always distributed with a first-class app—i.e. which would appear on the iOS home screen, or in the macOS /Applications directory. That app can register a stable URL scheme. By default, when running the Safari converter linked above, the app is just a simple screen displaying a button which opens the Safari settings so that the user can enable the extension. But we control that UI, and we can modify it to present the hypothes.is login flow—i.e. not in the browser, but in the app, where we have a stable URL scheme.

At a high level, the plan would be:

  1. Add "sign up" and "login" buttons to the containing app, opening the Hypothes.is OAuth URLs as appropriate using ASWebAuthenticationSession
  2. The containing app registers as an OAuth client with some stable URL extension scheme and listens for the login redirect with the auth code.
  3. It makes that code available to the extension JS.

A few more complications in the details:

Complications to step 2: I had misread the backend code and thought it only supported response_mode=web_message, i.e. communicating via postMessage, rather than a redirect, which would have caused problems. @robertknight kindly corrected me below; this won't be an issue.

Complications to step 3
Making the authorization code available to the extension JS is not trivial. On iOS, the containing app cannot directly message the extension JS. Instead, it can store the data securely in its container, and wait for the extension JS to request it, presumably on page load, using browser.runtime.sendNativeMessage. The native app extension binary can listen for that message and respond with the authorization code loaded from the container. The result can then be stored via the hypothesis client's AuthService, which may need to expose new API for this purpose. Note that the native app extension binary is distinct from the containing app—it doesn't have any UI of its own, and it runs when the extension is in use in Safari, as opposed to when the user launches the app from the home screen.

I'm not sure of the details of hypothes.is's expiration policies, but OAuth access codes usually expire rapidly, so it will probably be necessary to exchange the auth code for access and refresh tokens (or maybe just a refresh token) in the context of the containing app, and to store those instead of the access code.

One last complication: the Sign up and Login buttons exposed in the sidebar UI will need to point to the containing app's URL scheme, in case the user signs out and tries to sign in again from within the context of Safari. The containing app will need to listen for requests to open those URLs and perform the login flow as described above, then, probably, do-si-do back to Safari afterwards.


In all, this represents a fair amount of work—and more than I feel inclined to do at the moment—but it's nice to see that it's at least possible. Happy to chat more with anyone who's feeling inclined to push this along.

@robertknight
Copy link
Member

robertknight commented Nov 4, 2021

Hypothes.is's OAuth flow doesn't actually execute a real redirect.

The Hypothesis backend supports both the standard redirect-based method of returning the authorization code to the caller and postMessage. This is controlled by the response_mode parameter in the initial form submission that happens after the popup appears. The Hypothesis client currently uses the postMessage method because it has been more convenient up to this point, but if there was an environment where it was more convenient to use a redirect, we could use that instead.

If there is some pattern that the Safari team recommend for extensions which use OAuth to acquire an access token, then hopefully we could make that work. It sounds like you might know what that should look like?

@andymatuschak
Copy link

Ah, I'm sorry to have misread! Now I see the relevant code in the backend for non-web_message requests. Great, step 2 becomes much simpler: iOS/macOS offer a standard API which will present UI appropriately for OAuth login flows and use saved credentials from Safari if available. We can use that here if we omit response_mode from the request. Will update my message above for clarity. 👍

@dpinney
Copy link

dpinney commented Nov 9, 2022

I just discovered raindrop.io, which has great Safari integration, so I moved over to that and deleted all my hypothes.is bookmarklets. 🤷‍♂️

@gpolitis
Copy link

Just wanted to share a workaround that works for me : have hypothes.is automatically loaded via a Userscript. In order to achieve that you need a usercript manager for Safari like this one and a script to load hypothes.is like this one.

@dpinney
Copy link

dpinney commented Jan 24, 2024

Good point about user scripts. I got it kind of 75% working, but ultimately cross-origin restrictions stopped it from loading on a lot of pages. Since I tried this last year, I see there's a dev setting in Safari to disable cross-origin restrictions, so it might work great now. But it might also be a security problem since there's not a way to whitelist on hypothes.is. Dunno.

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

No branches or pull requests

6 participants