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.
50 lines
1.6 KiB
TypeScript
50 lines
1.6 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { buildClientLoginUrl } from "./client-url";
|
|
|
|
describe("buildClientLoginUrl", () => {
|
|
it("appends sso to a clean URL", () => {
|
|
expect(buildClientLoginUrl("https://game.hotel.nl", "Hotel-uuid")).toBe(
|
|
"https://game.hotel.nl?sso=Hotel-uuid",
|
|
);
|
|
});
|
|
|
|
it("uses & when a query string already exists", () => {
|
|
expect(
|
|
buildClientLoginUrl(
|
|
"https://game.hotel.nl/nitro?mode=nostrip&debug=1",
|
|
"Hotel-uuid",
|
|
),
|
|
).toBe("https://game.hotel.nl/nitro?mode=nostrip&debug=1&sso=Hotel-uuid");
|
|
});
|
|
|
|
it("replaces an existing sso param", () => {
|
|
expect(
|
|
buildClientLoginUrl("https://game.hotel.nl/nitro?sso=old&mode=1", "new"),
|
|
).toBe("https://game.hotel.nl/nitro?mode=1&sso=new");
|
|
expect(
|
|
buildClientLoginUrl("https://game.hotel.nl/nitro?sso=old", "new"),
|
|
).toBe("https://game.hotel.nl/nitro?sso=new");
|
|
});
|
|
|
|
it("keeps a fragment after the sso param", () => {
|
|
expect(
|
|
buildClientLoginUrl("https://game.hotel.nl/nitro#entry", "h-u"),
|
|
).toBe("https://game.hotel.nl/nitro?sso=h-u#entry");
|
|
expect(
|
|
buildClientLoginUrl("https://game.hotel.nl/nitro?sso=old#entry", "h-u"),
|
|
).toBe("https://game.hotel.nl/nitro?sso=h-u#entry");
|
|
});
|
|
|
|
it("leaves any existing non-sso fragment intact", () => {
|
|
expect(
|
|
buildClientLoginUrl("https://game.hotel.nl/nitro?tok=1#frag", "th"),
|
|
).toBe("https://game.hotel.nl/nitro?tok=1&sso=th#frag");
|
|
});
|
|
|
|
it("encodes the ticket value", () => {
|
|
expect(buildClientLoginUrl("https://game.hotel.nl/", "Ḟancy-ü")).toBe(
|
|
"https://game.hotel.nl/?sso=%E1%B8%9Eancy-%C3%BC",
|
|
);
|
|
});
|
|
});
|