fix(frontend): a page opened at a //path boots, and the account-switch copy reads right in Hungarian

Every address-bar writer glued `pathname + query`, so a path of `//evil.com/x` named another host:
history refused it (SecurityError) and the first nav mirror threw the app into its crash screen. One
builder, `hrefHere`, now makes the address from the URL itself and stays on this origin.
This commit is contained in:
2026-10-21 02:51:48 +02:00
parent ef99f7b5c7
commit 3c6c23507b
6 changed files with 63 additions and 15 deletions
+17 -10
View File
@@ -208,8 +208,20 @@ export function urlWithParams(updates: Record<string, string | null>): string {
if (v == null) params.delete(k);
else params.set(k, v);
}
const qs = params.toString();
return `${window.location.pathname}${qs ? `?${qs}` : ""}${window.location.hash}`;
return hrefHere(params);
}
/** This page's address with its query replaced by `query` and its fragment by `hash` — what every
* address-bar writer hands to `history`. Built on the URL itself, never by gluing `pathname` in front:
* a path opened as `//evil.com/x` would read as a link to ANOTHER host, `history.replaceState` refuses
* that (SecurityError), and the first nav mirror to write threw the whole app into its crash screen.
* Relative where that is safe, so the address stays as it was typed; the full href when the path
* starts with `//`. */
export function hrefHere(query: URLSearchParams, hash: string = window.location.hash): string {
const url = new URL(window.location.href);
url.search = query.toString();
url.hash = hash;
return url.pathname.startsWith("//") ? url.href : `${url.pathname}${url.search}${url.hash}`;
}
/** Remove specific TRANSIENT params (one-time auth/admin links: ?link, ?oauth, ?admin, ?access, ?verify,
@@ -226,12 +238,7 @@ export function clearParams(...keys: string[]): void {
}
}
if (!changed) return;
const qs = params.toString();
window.history.replaceState(
window.history.state,
"",
// Same fragment rule as urlWithParams: this strips QUERY keys only, so a `#verify=…`/`#reset=…`
// token that has not been consumed yet must survive. Welcome's own cleanup is what clears it.
`${window.location.pathname}${qs ? `?${qs}` : ""}${window.location.hash}`,
);
// Same fragment rule as urlWithParams: this strips QUERY keys only, so a `#verify=…`/`#reset=…`
// token that has not been consumed yet must survive. Welcome's own cleanup is what clears it.
window.history.replaceState(window.history.state, "", hrefHere(params));
}