Skip to content
File

Blob: tests/worker/helpers/auth.ts

typescript58 lines
1import { controlRequest, cookiePairFor, fetchWorker } from "@tests/worker/helpers/http";
2 
3export interface OidcLoginResult {
4 loginResponse: Response;
5 authorizationUrl: URL;
6 callbackUrl: URL;
7 callbackResponse: Response;
8 sessionCookie: string;
9 transactionCookie: string;
10}
11 
12async function requiredHeader(response: Response, name: string): Promise<string> {
13 const value = response.headers.get(name);
14 if (!value) {
15 throw new Error(`Missing ${name} header on ${response.status}: ${await response.clone().text()}`);
16 }
17 return value;
18}
19 
20export async function startOidcLogin(returnTo = "/"): Promise<{
21 loginResponse: Response;
22 authorizationUrl: URL;
23 transactionCookie: string;
24}> {
25 const loginResponse = await fetchWorker(
26 controlRequest(`/api/v1/auth/oidc/login?return_to=${encodeURIComponent(returnTo)}`, { redirect: "manual" }),
27 );
28 const authorizationUrl = new URL(await requiredHeader(loginResponse, "location"));
29 return {
30 loginResponse,
31 authorizationUrl,
32 transactionCookie: cookiePairFor(loginResponse, "__Host-dab_oidc_tx"),
33 };
34}
35 
36export async function completeOidcLogin(returnTo = "/"): Promise<OidcLoginResult> {
37 const { loginResponse, authorizationUrl, transactionCookie } = await startOidcLogin(returnTo);
38 const providerResponse = await fetch(authorizationUrl, { redirect: "manual" });
39 const callbackUrl = new URL(await requiredHeader(providerResponse, "location"));
40 const callbackResponse = await fetchWorker(
41 controlRequest(callbackUrl.toString(), {
42 headers: {
43 accept: "application/json",
44 cookie: transactionCookie,
45 },
46 }),
47 );
48 
49 return {
50 loginResponse,
51 authorizationUrl,
52 callbackUrl,
53 callbackResponse,
54 sessionCookie: cookiePairFor(callbackResponse, "__Host-dab_session"),
55 transactionCookie,
56 };
57}