Files
EpicNext-Cms/src/lib/client-url.ts
T
openhands 7f39ba4257
CI / check (push) Successful in 28s
CI / release (push) Skipped
CI / deploy (push) Successful in 54s
fix: harden SSO ticket flow and revoke tickets on logout
Reuse the outstanding auth_ticket instead of minting a fresh one on every
/client load, so reloading the page or opening a second tab no longer
invalidates a game session that is still connecting. New tickets are minted
with a guard against the previously-read value so concurrent launches
converge on the same ticket.

Revoke the auth_ticket when signing out (toolbar, header and sign-out
everywhere) so a leaked ticket can no longer be replayed against the
emulator, and prevent SSO leakage via referral by setting no-referrer on the
client iframe. Strip all whitespace from the ticket prefix and build the
launch URL through a tested helper that handles query strings, existing sso
params and URL fragments correctly.
2026-08-29 20:54:06 +02:00

21 lines
778 B
TypeScript

/**
* Build the Nitro launch URL with the SSO ticket as the final query param.
*
* Any existing `sso` param is removed first (both from the query string and
* from a `#fragment`), the ticket is appended as the last query param, and a
* `#fragment` is kept after it so the ticket always reaches the server.
*/
export function buildClientLoginUrl(clientUrl: string, ticket: string): string {
const [pathPart = "", ...fragments] = clientUrl.split("#");
const fragment = fragments.join("#");
const path = pathPart
.replace(/([?&])sso=[^&#]*/gi, "$1")
.replace(/([?&])&+/g, "$1")
.replace(/[?&]$/, "");
const sep = path.includes("?") ? "&" : "?";
const query = `${path}${sep}sso=${encodeURIComponent(ticket)}`;
return fragment ? `${query}#${fragment}` : query;
}