import type { Cookies } from "@sveltejs/kit"; import { CURRENT_DID_KEY } from "$lib/auth/accounts"; import { open } from "$lib/server/sealed"; import { githubEnv } from "./env"; import { GITHUB_TOKEN_COOKIE } from "./cookies"; interface GitHubSession { token: string; did: string; exp: number; } // session is bound to opening account to prevent cross-account token reuse export const sessionActor = async ( cookies: Cookies, platform?: App.Platform ): Promise<{ token: string; did: string } | null> => { const session = await open( cookies.get(GITHUB_TOKEN_COOKIE), githubEnv(platform).secret ); const did = cookies.get(CURRENT_DID_KEY); if (!session?.token || !did || !session.did || session.exp <= Date.now() || session.did !== did) return null; return { token: session.token, did: session.did }; }; export const sessionToken = async ( cookies: Cookies, platform?: App.Platform ): Promise => (await sessionActor(cookies, platform))?.token ?? null; const jwtPayload = (jwt: string): Record | null => { const parts = jwt.split("."); if (parts.length !== 3) return null; try { const json = atob(parts[1].replaceAll("-", "+").replaceAll("_", "/")); const value: unknown = JSON.parse(json); return value !== null && typeof value === "object" && !Array.isArray(value) ? (value as Record) : null; } catch { return null; } }; // unverified claim; downstream migrator verifies jwt signature export const claimedServiceAuthDid = (authorization: string | null): string | null => { if (!authorization?.startsWith("Bearer ")) return null; const iss = jwtPayload(authorization.slice("Bearer ".length))?.iss; return typeof iss === "string" && iss ? iss : null; };