32 lines1,500 bytesCodeBlame

Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.

Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look1import { redirect } from "react-router";
2
3import type { Route } from "./+types/auth-github";
4import { STATE_COOKIE, cookie } from "../lib/github";
5import { callbackUrl, githubSignIn } from "../lib/github.server";
6import { getViewer, nextPath } from "../lib/session.server";
7
8/**
9 * Sends the browser to GitHub to sign in, sign up or (with `?link=1`)
10 * link GitHub to the signed-in account. The state GitHub will send back is
11 * kept in a short-lived cookie, so only this browser can finish the trip.
12 * An invite code (`?invite=`) rides along for a new account.
13 */
14export async function loader({ request, context }: Route.LoaderArgs) {
15 const url = new URL(request.url);
16 const viewer = getViewer(context);
17 const link = url.searchParams.get("link") === "1";
18 if (link && !viewer) throw redirect(`/login?next=${encodeURIComponent("/settings#github")}`);
19 if (!link && viewer) throw redirect(nextPath(request));
20 const invite = url.searchParams.get("invite")?.trim().slice(0, 100) || null;
21 const started = await githubSignIn.start({
22 purpose: link ? "link" : "sign_in",
23 user: link ? viewer : null,
24 redirectUri: callbackUrl(request),
25 next: link ? (url.searchParams.has("next") ? nextPath(request) : "/settings#github") : nextPath(request),
26 inviteCode: invite,
27 });
28 if (!started.ok) throw redirect(link ? "/settings#github" : "/login");
29 throw redirect(started.value.authorizeUrl, {
30 headers: { "set-cookie": cookie(STATE_COOKIE, started.value.state, 600) },
31 });
32}