rewrite the JSON-escaped form of the upstream origin too

Gitea's inline script carries `appUrl: 'https:\/\/gitea.example.com\/'`, and
rewriteAbsolute only matched the literal `https://` form. So appUrl survived
pointing at the real host while every visible link was rewritten correctly.

The failure was quiet rather than obvious: the page rendered, and only the URLs
Gitea's JS BUILDS from appUrl went wrong — cross-origin to the real host,
answered with its login HTML. The heatmap reported "Unexpected token '<'" while
parsing JSON, and the event worker failed the same way.

Third instance of the same class today, after the asset paths and appSubUrl: a
URL hiding in a shape the rewriter did not think to look for. All three were
found by loading the page, none by the tests — and all three now have a test
written against a live sample rather than an imagined one.
This commit is contained in:
officer
2026-08-19 09:33:09 +00:00
parent 47e3983f7e
commit 413b7ac0e9
2 changed files with 25 additions and 3 deletions
+10
View File
@@ -71,6 +71,16 @@ describe('absolute URLs built from ROOT_URL', () => {
expect(rewriteHtml('<a href="http://localhost:3000/explore">', BASE, ORIGINS)).toContain(`${BASE}/explore`);
});
test('the JSON-ESCAPED form, which is how appUrl appears in Gitea\'s inline script', () => {
// `appUrl: 'https:\\/\\/gitea.officer.dev\\/'`. Missed at first, and the failure was quiet: the page
// rendered fine while every URL Gitea's JS built from appUrl went cross-origin to the real host and
// came back as its login HTML — so the heatmap reported "Unexpected token '<'" parsing JSON.
const real = String.raw`appUrl: 'https:\/\/gitea.officer.dev\/',`;
const out = rewriteHtml(real, BASE, ORIGINS);
expect(out).toContain(String.raw`'\/api\/gitea\/_web\/'`);
expect(out).not.toContain('gitea.officer.dev');
});
test('an unrelated host is left alone', () => {
const html = '<a href="https://github.com/some/repo">';
expect(rewriteHtml(html, BASE, ORIGINS)).toBe(html);