-
Bug
-
Resolution: Unresolved
-
Normal
-
None
-
None
-
None
-
macOS with Safari
When attempting to import a MusicBrainz release into Picard so that it can be used for tagging files, the "tagger" button on MusicBrainz pages silently fails when browsed to with Safari. This can be tested with any Mac by having Picard open, going to any release page in Safari, appending ?tport=8000 to the URL, and attempting to use the green "tagger" button.
The data load is successful with other browsers (e.g., I had no issues with Firefox).
Some searching suggests that Safari automatically shunts localhost URLs to HTTPS; unfortunately, the workaround described in that link is no longer valid, at least when I tested today. App/browser testing tool BrowserStack describes this phenomenon as a known issue, but their workarounds are not applicable to us.
[PICARD-3040] Safari blocks data load via localhost URL
I tried to test this issue on my mac, but unfortunately macOS 12.7.6 with Safari 17.6 seems to be the newest version I can use. And I cannot reproduce the issue here. This is specific to macOS 15 Sequoia?
julian45 bitmap Can you test, if "Submit cluster as release" works? Cluster some files on the left pane, open the cluster context menu and select "Submit cluster as release". It should open the add release workflow in your web browser with relevant data prefilled. For getting the data into the browser it initially opens a local URL where Picard returns a HTML form with the metadata.
See https://picard-docs.musicbrainz.org/en/usage/submit_cluster_as_release.html
IMO, the best option of the ones provided would be a custom protocol handler.
julian45 The problem with this is that it will be difficult to make universally available. It'll work rather well on macOS, as it is set in the apps as part of the Info.plist file. It breaks when running from source.
On Linux this depends on a .desktop file being installed for the app, so this breaks when users are running from source or install via "pip", or have their custom .desktop file and didn't add the protocol, or have multiple versions of Picard and the desktop file is launching then a different one.
On Windows this needs to be set in the registry. This could be handled by the installer, but again it breaks with the portable version. Which means on Windows the portable version might need to offer an option to modify the registry.
Other platforms? Probably out of luck.
Also MusicBrainz.org then needs a way to decide which protocol to use (for older versions of Picard). It also removes the ability to detect whether Picard is available from within the website (as https://github.com/phw/musicbrainz-magic-tagger-button does).
Then if everything is working it would still not be usable for the add release workflow. So we need to hope that at least this still works in Safari.
Overall it is a very restricted solution unfortunately
IMO, the best option of the ones provided would be a custom protocol handler. Although most browsers would, at least for the first use, prompt a user to confirm whether they want to open picard:// links in Picard, and that would technically be a new behavior for Picard users to deal with, this is how most apps that do browser->app interaction work in my experience (e.g., following a Zoom link in the browser -> passing meeting info to the desktop client), so it's not like we would be going down an untrodden path with the protocol handler approach.
As for other options:
- SSL cert: manual cert trust is rather thorny and, as you've said, modern browsers could give users the impression that this process is insecure.
- Embedded browser: as you've indicated, would only really be suitable for the OAuth flow, if even that.
- Browser extension: not really a good option IMO, but seems to be the best remaining alternative of the ones presented. See, e.g., Zotero Connector for a possible reference.
I investigated a bit, and I think we need to separate the different use cases we have, as they require different interaction. All is related to what Picard currently handles as browser integration, which is essentially a HTTP server Picard is running (if not disabled in options). Depending on the use case different solutions might be feasible.
Let's first look at the solutions I currently see:
- Generate and serve a SSL certificate to support HTTPS in the browser integration. This will be a self-signed certificate for localhost. It needs to be investigated whether this satisfies Safari. zas has created a proof-of-concept Python HTTP server which auto generates the certificate. Downsides:
- Additional complexity (but Picard already includes openssl, so it shouldn't add much to the package really)
- Unclear whether this solves the Safari issue
- Users might need to deal with certificate warnings, which in modern browsers are making the impression that the process is insecure. We might need to inform users on this and offer support in setting up the browser properly to accept the certificate.
- Custom protocol handler, e.g. to call e.g. "picard://somehost/openalbum?id...". This should avoid the Safari issues, but has a few downsides:
- Registering a protocol handler is platform specific, and might even be needed to be configured in the browser. Also it might depend on the installation method and not be available for all forms of installation.
- MusicBrainz website wouldn't be able to detect whether to use http URLs or custom protocol automatically. Probably needs a new parameter.
- It is only suitable for cases where the response doesn't matter (as there is no defined protocol on how the browser would reveive a response, it is a one way communication).
- Only calls where all the parameters are part of the URL (so in HTTP words only GET), but this actually is all Picard currently needs
- Embedded browser using Qt Web Engine: Have Picard open the URL not in a browser but in a own application window opening the URL with Qt Web Engine. Downsides:
- Not suited for general MusicBrainz browsing. Might be an option for just the OAuth flow.
- Adds additionally, rather heavy dependency on QtWebEngine.
- Browser extension: Not really sure about this, but bringing it up for brainstorming. Could a browser extension help with doing the proper calls?
The different use cases Picard currently has for the browser integration are.
- Tagger button: This is a call to either the /openalbum or /opennat endpoint in Picard. This is a simple GET request, the response is not relevant and usually not seen by the user. Possible solutions:
- SSL certificate
- Custom protocol handler
- Authentication: If the browser integration is active Picard can since version 2.13 use it to finish the OAuth flow. Without browser integration it falls back to out-of-bound token, which requires the user to manually copy the token. But this is supposed to get removed in the new MB OAuth implementation, so we need to move forward. Possible solutions:
- SSL certificate
- Custom protocol handler
- Embedded browser
- Add release: The /add endpoint returns an HTML form to provide the data needed for the editor form seeding.
- Maybe nothing. As this is called first as a standalone page it should still be possible to serve it via http, even if the form submission then opens MusicBrainz via https. Needs to be tested.
- SSL certificate
- Detect whether browser integration is active: This is a minor case, but if running Picard responds on "/" with a simple message. This is used by the MusicBrainz Magic Tagger Button user script to detect, whether the tagger buttons on MusciBrainz.org need to be enabled or disabled.
- Maybe still works even on Safari, needs testing
- SSL certificate
Overall none of the solutions is really great, but we should be able to get something working.
The custom URL scheme handler might work. I think Qt provides something for this.
But I'm not sure whether custom URL scheme would also work as a oauth callback.
> Does anything on https://stackoverflow.com/questions/46394682/safari-keeps-forcing-https-on-localhost help?
It looks like a different issue altogether as the request isn't being redirected, just blocked outright. (There actually is a setting to force-upgrade such content to HTTPS, but it's not enabled by default.)
I did attempt the top solution there, but those files/services don't even exist on my machine.
Maybe it would be possible to register a custom picard URL scheme for macOS? https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app
Otherwise, I'm not sure. Websockets would likely have the same mixed content restrictions. We'd probably have to host something on musicbrainz.org.
Clearly a mixed content blocking issue, but it seems Safari doesn't have an exception mechanism...
https://developer.mozilla.org/en-US/docs/Web/Security/Mixed_content
There's another StackOverflow page about that: https://stackoverflow.com/questions/47207364/safari-is-forcing-https-on-everything-when-i-dont-want-it-to
And I'm not sure we want Picard to become an https server (it would imply certificates management, perhaps doable, but expiration & renewal will be a pain to manage on an installable app). What other options do we have?
Does anything on https://stackoverflow.com/questions/46394682/safari-keeps-forcing-https-on-localhost help?
outsidecontext I can confirm the "Add Cluster as Release" plugin works fine with Safari 18.3. There's no issue submitting data from a insecure HTTP page to a secure HTTPS page, only loading insecure content from an HTTPS page.
I realized there is a way to workaround the issue in musicbrainz-server: instead of loading the tagger URL as an image, we can just let it open in a new tab for Safari users. You could even serve some JavaScript from Picard that calls window.close() automatically. The only problem is that it won't switch you to Picard automatically (it will stay in the browser), and the tab opening/closing will be visible to the user.
If the custom protocol solution works out then that is definitely much nicer.