fix(indiekit): derive application URL from each request - #918
Merged
Conversation
`application.url ||= getUrl(request)` memoised into `Indiekit.config.application`, an object that outlives the request, so the first request a process ever received fixed the host used by every response after it. A health check, a container probe or a curl in a start script could set it before anyone opened a browser. `application.url` is documented as configurable for reverse proxies, defaulting to the request. Once `getUrl()` had written to it there was no way to tell the two apart, so the fallback became permanent. Read the configured value in the constructor, where it cannot yet have been overwritten, and derive from the request otherwise — matching how `collections`, `localeUsed`, `package` and `shortcuts` are assigned on the lines above. This affects more than styling. `application.url` builds the absolute asset URLs in the rendered page, and also the IndieAuth `client_id` and `redirect_uri` in `lib/indieauth.js`, so a latched host sent the sign-in flow to a different origin than the one being browsed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #906.
Indiekit.applicationUrl, as you suggested.Capturing it in the constructor is the part that does the work.
applicationisconfig.application, so the middleware writingapplication.urldestroys the value it later needs to consult — which is how||=lost the ability to tell "configured" from "cached from whoever asked first". A copy taken before any request arrives keeps them distinguishable, and the request-derived case now behaves likecollections,localeUsed,packageandshortcutson the lines above it.The impact is wider than the issue title suggests
I only framed this as missing CSS and JS. Tracing the readers,
application.urlalso builds the IndieAuthclient_idandredirect_uri:So a latched host doesn't only render an unstyled page — it sends the sign-in flow's
client_idandredirect_urito a different origin from the one being browsed, where the session cookie isn't shared. Same root cause, but it reaches authentication, not just presentation. It also feeds the JF2 feed URL (lib/controllers/feed.js:3) and image-resize URLs (frontend/lib/filters/url.js:66).Worth knowing rather than discovering later; happy to note it on the issue too.
Tests
Two, both written against the old code first and watched fail:
Hostheaders; asserts the second reflects its own host. Failed withactual: 'http://127.0.0.1:3000'where the second request sentlocalhost:3000, which is the bug reproduced in a unit test.configuration/application.mdis kept.packages/indiekit: 111 pass, 0 fail across 46 suites.prettier --checkclean,eslintclean on the changed files.One note on coverage: I didn't add a test for the constructor assignment itself. Nothing currently constructs
Indiekitin the unit tests, and its siblingsthis.localeandthis.mongodbUrlare unasserted for the same reason — the behaviour is covered at the middleware boundary instead. Say if you'd rather have one and I'll add it.Naming
lib/indieauth.js:87already declares a localconst applicationUrl. Different scope, no conflict, but flagging it since it's the same name a few files away.eslintalso reports a pre-existingimport-x/ordererror inpackages/indiekit/bin/cli.js, untouched by this branch.