From befadc0042ac31ad649dca02f31097cb387541cd Mon Sep 17 00:00:00 2001
From: Paul Carleton
Date: Fri, 16 May 2025 20:53:21 +0100
Subject: [PATCH] very wip draft auth spec support
---
client/src/App.tsx | 3 +-
client/src/components/AuthDebugger.tsx | 2 +-
client/src/components/OAuthFlowProgress.tsx | 25 +++++++++++++++++
client/src/lib/auth-types.ts | 3 ++
client/src/lib/oauth-state-machine.ts | 31 +++++++++++++++------
5 files changed, 53 insertions(+), 11 deletions(-)
diff --git a/client/src/App.tsx b/client/src/App.tsx
index cb411452..a30dcc9c 100644
--- a/client/src/App.tsx
+++ b/client/src/App.tsx
@@ -125,8 +125,9 @@ const App = () => {
isInitiatingAuth: false,
oauthTokens: null,
loading: true,
- oauthStep: "metadata_discovery",
+ oauthStep: "resource_metadata_discovery",
oauthMetadata: null,
+ resourceMetadata: null,
oauthClientInfo: null,
authorizationUrl: null,
authorizationCode: "",
diff --git a/client/src/components/AuthDebugger.tsx b/client/src/components/AuthDebugger.tsx
index 98d58e23..083fc39b 100644
--- a/client/src/components/AuthDebugger.tsx
+++ b/client/src/components/AuthDebugger.tsx
@@ -179,7 +179,7 @@ const AuthDebugger = ({
serverAuthProvider.clear();
updateAuthState({
oauthTokens: null,
- oauthStep: "metadata_discovery",
+ oauthStep: "resource_metadata_discovery",
latestError: null,
oauthClientInfo: null,
authorizationCode: "",
diff --git a/client/src/components/OAuthFlowProgress.tsx b/client/src/components/OAuthFlowProgress.tsx
index 396af142..8167afa6 100644
--- a/client/src/components/OAuthFlowProgress.tsx
+++ b/client/src/components/OAuthFlowProgress.tsx
@@ -79,6 +79,16 @@ export const OAuthFlowProgress = ({
null,
);
+ const steps: Array = [
+ "resource_metadata_discovery",
+ "metadata_discovery",
+ "client_registration",
+ "authorization_redirect",
+ "authorization_code",
+ "token_request",
+ "complete",
+ ];
+
const currentStepIdx = steps.findIndex((s) => s === authState.oauthStep);
useEffect(() => {
@@ -124,6 +134,21 @@ export const OAuthFlowProgress = ({
+
+ {authState.resourceMetadata && (
+
+
+ Retrieved OAuth Resource Metadata from {(new URL('/.well-known/oauth-protected-resource', serverUrl)).href}
+
+
+ {JSON.stringify(authState.resourceMetadata, null, 2)}
+
+
+ )}
+
Promise;
execute: (context: StateMachineContext) => Promise;
- nextStep: OAuthStep;
}
// State machine transitions
export const oauthTransitions: Record = {
- metadata_discovery: {
+ resource_metadata_discovery: {
canTransition: async () => true,
execute: async (context) => {
- const metadata = await discoverOAuthMetadata(context.serverUrl);
+ // TODO: use sdk
+ const url = new URL("/.well-known/oauth-protected-resource", context.serverUrl);
+ const response = await fetch(url);
+
+ const resourceMetadata = await response.json();
+ context.updateState({
+ resourceMetadata: resourceMetadata,
+ oauthStep: "metadata_discovery",
+ });
+ },
+ },
+
+ metadata_discovery: {
+ canTransition: async (context) => !!context.state.resourceMetadata,
+ execute: async (context) => {
+ // TODO: use sdk
+ let authServerUrl = context.serverUrl;
+ if (context.state.resourceMetadata?.authorization_servers?.[0]) {
+ authServerUrl = context.state.resourceMetadata.authorization_servers[0];
+ }
+ const metadata = await discoverOAuthMetadata(authServerUrl);
if (!metadata) {
throw new Error("Failed to discover OAuth metadata");
}
@@ -37,7 +56,6 @@ export const oauthTransitions: Record = {
oauthStep: "client_registration",
});
},
- nextStep: "client_registration",
},
client_registration: {
@@ -62,7 +80,6 @@ export const oauthTransitions: Record = {
oauthStep: "authorization_redirect",
});
},
- nextStep: "authorization_redirect",
},
authorization_redirect: {
@@ -93,7 +110,6 @@ export const oauthTransitions: Record = {
oauthStep: "authorization_code",
});
},
- nextStep: "authorization_code",
},
authorization_code: {
@@ -114,7 +130,6 @@ export const oauthTransitions: Record = {
oauthStep: "token_request",
});
},
- nextStep: "token_request",
},
token_request: {
@@ -144,7 +159,6 @@ export const oauthTransitions: Record = {
oauthStep: "complete",
});
},
- nextStep: "complete",
},
complete: {
@@ -152,7 +166,6 @@ export const oauthTransitions: Record = {
execute: async () => {
// No-op for complete state
},
- nextStep: "complete",
},
};