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.
This commit is contained in:
1 parent
ca59a1065f
commit
7f39ba4257
7 files changed
+231
-28
No files matched your search
@@ -1,7 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { LogOut } from "lucide-react";
|
||||
import { signOut } from "next-auth/react";
|
||||
import {
|
||||
type ReactNode,
|
||||
useCallback,
|
||||
@@ -10,7 +9,9 @@ import {
|
||||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
import { signOutAndRevokeTicket } from "@/actions/sessions";
|
||||
import Link from "@/components/link";
|
||||
import { buildClientLoginUrl } from "@/lib/client-url";
|
||||
|
||||
function ToolbarBtn({
|
||||
onClick,
|
||||
@@ -94,9 +95,7 @@ export function ClientView({
|
||||
return () => document.removeEventListener("fullscreenchange", onChange);
|
||||
}, []);
|
||||
|
||||
const base = clientUrl.replace(/(\?|&)sso=[^&]*/, "");
|
||||
const sep = base.includes("?") ? "&" : "?";
|
||||
const clientSrc = `${base}${sep}sso=${encodeURIComponent(ticket)}`;
|
||||
const clientSrc = buildClientLoginUrl(clientUrl, ticket);
|
||||
|
||||
const toolbarRef = useRef<HTMLDivElement>(null);
|
||||
const dragRef = useRef({ startX: 0, startY: 0, startTop: 0, startLeft: 0 });
|
||||
@@ -361,7 +360,7 @@ export function ClientView({
|
||||
</svg>
|
||||
</div>
|
||||
<ToolbarBtn
|
||||
onClick={() => signOut({ callbackUrl: "/" })}
|
||||
onClick={() => void signOutAndRevokeTicket()}
|
||||
title="Logout"
|
||||
>
|
||||
<LogOut size={14} />
|
||||
@@ -382,6 +381,7 @@ export function ClientView({
|
||||
}`}
|
||||
title={hotelName}
|
||||
allow="autoplay; gamepad; fullscreen"
|
||||
referrerPolicy="no-referrer"
|
||||
loading="eager"
|
||||
/>
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user