From c39c8bf62b7286437571a6f2a93a39888cb63fed Mon Sep 17 00:00:00 2001 From: Justin Spahr-Summers Date: Thu, 6 Feb 2025 13:44:41 +0000 Subject: [PATCH] WIP start authorization flow --- src/client/auth/auth.ts | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/client/auth/auth.ts b/src/client/auth/auth.ts index 842abe9d..4758b1f6 100644 --- a/src/client/auth/auth.ts +++ b/src/client/auth/auth.ts @@ -1,3 +1,4 @@ +import pkceChallenge from "pkce-challenge"; import { z } from "zod"; export const OAuthMetadataSchema = z @@ -56,3 +57,28 @@ export async function discoverOAuthMetadata( return OAuthMetadataSchema.parse(await response.json()); } + +export async function startAuthorization( + serverUrl: string | URL, + { + metadata, + redirectUrl, + }: { metadata: OAuthMetadata; redirectUrl: string | URL }, +): Promise<{ authorizationUrl: URL; codeVerifier: string }> { + // Generate PKCE challenge + const challenge = await pkceChallenge(); + const codeVerifier = challenge.code_verifier; + const codeChallenge = challenge.code_challenge; + + const authorizationUrl = metadata?.authorization_endpoint + ? new URL(metadata?.authorization_endpoint) + : new URL("/authorize", serverUrl); + + // TODO: Validate that these parameters are listed as supported in the metadata, if present. + authorizationUrl.searchParams.set("response_type", "code"); + authorizationUrl.searchParams.set("code_challenge", codeChallenge); + authorizationUrl.searchParams.set("code_challenge_method", "S256"); + authorizationUrl.searchParams.set("redirect_uri", String(redirectUrl)); + + return { authorizationUrl, codeVerifier }; +}