Fix Fanbox: download panel no longer appears (#334) - #335
Conversation
…eoding86#334) The download panel stopped appearing on Fanbox posts. The content-script parser fetched https://api.fanbox.cc/post.info directly, but the page runs on *.fanbox.cc while the api is on api.fanbox.cc, making it a cross-origin credentialed request. Under manifest v2 the blocking webRequest handler rewrote the response Access-Control-Allow-Origin / -Allow-Credentials headers to satisfy CORS; the manifest v3 migration dropped that and declarativeNetRequest cannot echo a dynamic origin for a credentialed request, so getResource() threw and the UI never mounted (issues leoding86#268, leoding86#334). Delegate the api request to the background service worker, which runs with the extension host permissions, isn't subject to page CORS, and still sends the Fanbox session cookie via credentials: include. - add FanboxService.postInfo() in the background - route FanboxPostParser.parseContext() through fanbox:postInfo messaging
Firefox implements the manifest v3 background as an event page and does not support background.service_worker, so loading the built extension failed with "background.service_worker is currently disabled. Add background.scripts." Transform the manifest during the Firefox build to convert background.service_worker into background.scripts. All real initialization runs at the top level of Bootstrap.js (which executes in both a service worker and an event page); the only service-worker-specific hook (self.oninstall -> onBooted) calls an empty method and sets an unused self.application, so nothing is lost.
The background post.info fetch is CORS-free but Fanbox rejected it with HTTP 400 because the extension background sends Origin: moz-extension://... (or chrome-extension://...), which the api does not accept. MV2's blocking webRequest used to rewrite this header. Add a declarativeNetRequest rule that sets Origin/Referer to https://www.fanbox.cc on requests to api.fanbox.cc. It is scoped with excludedInitiatorDomains: [fanbox.cc] so it only touches the extension's own background request and never Fanbox's own SPA calls (whose real page origin must be preserved for their CORS to keep working).
Fanbox now nests the post data under body.post instead of putting the post fields (user, type, body, coverImageUrl, ...) directly on body. Unwrap it, falling back to body for older responses, so standardContext gets the fields it expects.
Fraetor
left a comment
There was a problem hiding this comment.
The code looks sensible. How are you building it? I get errors when following the existing instructions in the readme, likely due to my npm/node version being way newer than it expects.
That will build it (though unsigned and you will have to load temporarily each time in about:debugging If you want an XPI do the following: In zip Then if using Firefox Developer edition:
And load the XPI via If you are using the normal version of Firefox you'd need to sign up for a Mozilla Developer account and generate credentials at https://addons.mozilla.org/developers/addon/api/key/ Then using the current version of node (you can run
This will when finished output a signed XPI in |
Fixes #334 (also the recurring form of #268).
Problem
On Fanbox posts the toolbar icon stays active (URL recognized) but the download panel never appears. The panel only mounts after
Application.urlchangeHandlersuccessfully callsadapter.getResource(), and for Fanbox that path was throwing.Root causes
MV3 CORS regression.
FanboxPostParserfetchedhttps://api.fanbox.cc/post.infodirectly from the content script. The page runs on*.fanbox.ccbut the API is onapi.fanbox.cc, so it's a cross-origin credentialed request. Under MV2 the blockingwebRequesthandler rewrote the responseAccess-Control-Allow-Origin/-Allow-Credentialsheaders; the MV3 migration dropped that, anddeclarativeNetRequestcan't echo a dynamic origin for a credentialed request. SogetResource()threw on CORS (matches the CORS/JSON errors reported in The application pop-up / option bar doesn't appear in Fanbox #268).Fanbox changed the
post.inforesponse shape. The post fields (user,type,body,coverImageUrl, …) are now nested underbody.postinstead of sitting directly onbody, sostandardContext()hitcontext.user=undefined.Origin required by the API. Once the request runs from the background it's CORS-free, but Fanbox rejected it with HTTP 400 because the background sender's
Originismoz-extension://…/chrome-extension://….Changes
post.infofrom the background service worker (FanboxService.postInfo, actionfanbox:postInfo). The background runs with host permissions, isn't subject to page CORS, and still sends the session cookie viacredentials: 'include'(needed for supporter-only posts).body.postinFanboxPostParser, falling back tobodyfor older responses.Origin/Referertohttps://www.fanbox.ccon requests toapi.fanbox.cc, scoped withexcludedInitiatorDomains: ["fanbox.cc"]so it only touches the extension's own background request and never Fanbox's own SPA calls.background.scriptsinstead ofbackground.service_worker(Firefox implements MV3 backgrounds as event pages;background.service_workerfails to load). All initialization already runs at the top level ofBootstrap.js, so nothing is lost.Testing
Built and loaded on Firefox 153. Verified the panel now appears on Fanbox posts (regular and supporter-only), the post parses, and downloads complete in Download Manager download mode.
Not included / out of scope
Legacy download mode (
downloadMode: 1, which zips inside the content script) has separate, pre-existing Firefox-MV3 content-script CSP problems (JSZip'sFunction('return this')()is CSP-blocked, and injected library globals aren't visible in Firefox's content-script sandbox). Those are intentionally left out of this PR; Download Manager mode is unaffected and works.Pixiv Omnia while the button works, doesn't support Fanbox, it should be removed, unless at some point work is done to add Fanbox support to Pixiv Omnia.