Skip to content

Commit d758e8b

Browse files
authored
Merge branch 'main' into main
2 parents 9e47d7d + f22aa1f commit d758e8b

File tree

11 files changed

+819
-601
lines changed

11 files changed

+819
-601
lines changed

client/src/App.tsx

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ import {
3434
useDraggablePane,
3535
useDraggableSidebar,
3636
} from "./lib/hooks/useDraggablePane";
37-
import { StdErrNotification } from "./lib/notificationTypes";
3837

3938
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
4039
import { Button } from "@/components/ui/button";
@@ -106,9 +105,6 @@ const App = () => {
106105
>(getInitialTransportType);
107106
const [logLevel, setLogLevel] = useState<LoggingLevel>("debug");
108107
const [notifications, setNotifications] = useState<ServerNotification[]>([]);
109-
const [stdErrNotifications, setStdErrNotifications] = useState<
110-
StdErrNotification[]
111-
>([]);
112108
const [roots, setRoots] = useState<Root[]>([]);
113109
const [env, setEnv] = useState<Record<string, string>>({});
114110

@@ -224,12 +220,6 @@ const App = () => {
224220
onNotification: (notification) => {
225221
setNotifications((prev) => [...prev, notification as ServerNotification]);
226222
},
227-
onStdErrNotification: (notification) => {
228-
setStdErrNotifications((prev) => [
229-
...prev,
230-
notification as StdErrNotification,
231-
]);
232-
},
233223
onPendingRequest: (request, resolve, reject) => {
234224
setPendingSampleRequests((prev) => [
235225
...prev,
@@ -757,10 +747,6 @@ const App = () => {
757747
setLogLevel(level);
758748
};
759749

760-
const clearStdErrNotifications = () => {
761-
setStdErrNotifications([]);
762-
};
763-
764750
const AuthDebuggerWrapper = () => (
765751
<TabsContent value="auth">
766752
<AuthDebugger
@@ -829,11 +815,9 @@ const App = () => {
829815
setOauthScope={setOauthScope}
830816
onConnect={connectMcpServer}
831817
onDisconnect={disconnectMcpServer}
832-
stdErrNotifications={stdErrNotifications}
833818
logLevel={logLevel}
834819
sendLogLevelRequest={sendLogLevelRequest}
835820
loggingSupported={!!serverCapabilities?.logging || false}
836-
clearStdErrNotifications={clearStdErrNotifications}
837821
/>
838822
<div
839823
onMouseDown={handleSidebarDragStart}

client/src/components/AuthDebugger.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { AuthDebuggerState, EMPTY_DEBUGGER_STATE } from "../lib/auth-types";
66
import { OAuthFlowProgress } from "./OAuthFlowProgress";
77
import { OAuthStateMachine } from "../lib/oauth-state-machine";
88
import { SESSION_KEYS } from "../lib/constants";
9+
import { validateRedirectUrl } from "@/utils/urlValidation";
910

1011
export interface AuthDebuggerProps {
1112
serverUrl: string;
@@ -163,6 +164,23 @@ const AuthDebugger = ({
163164
currentState.oauthStep === "authorization_code" &&
164165
currentState.authorizationUrl
165166
) {
167+
// Validate the URL before redirecting
168+
try {
169+
validateRedirectUrl(currentState.authorizationUrl);
170+
} catch (error) {
171+
updateAuthState({
172+
...currentState,
173+
isInitiatingAuth: false,
174+
latestError:
175+
error instanceof Error ? error : new Error(String(error)),
176+
statusMessage: {
177+
type: "error",
178+
message: `Invalid authorization URL: ${error instanceof Error ? error.message : String(error)}`,
179+
},
180+
});
181+
return;
182+
}
183+
166184
// Store the current auth state before redirecting
167185
sessionStorage.setItem(
168186
SESSION_KEYS.AUTH_DEBUGGER_STATE,

client/src/components/OAuthFlowProgress.tsx

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import { Button } from "./ui/button";
44
import { DebugInspectorOAuthClientProvider } from "@/lib/auth";
55
import { useEffect, useMemo, useState } from "react";
66
import { OAuthClientInformation } from "@modelcontextprotocol/sdk/shared/auth.js";
7+
import { validateRedirectUrl } from "@/utils/urlValidation";
8+
import { useToast } from "@/lib/hooks/useToast";
79

810
interface OAuthStepProps {
911
label: string;
@@ -71,6 +73,7 @@ export const OAuthFlowProgress = ({
7173
updateAuthState,
7274
proceedToNextStep,
7375
}: OAuthFlowProgressProps) => {
76+
const { toast } = useToast();
7477
const provider = useMemo(
7578
() => new DebugInspectorOAuthClientProvider(serverUrl),
7679
[serverUrl],
@@ -239,16 +242,32 @@ export const OAuthFlowProgress = ({
239242
<p className="text-xs break-all">
240243
{authState.authorizationUrl}
241244
</p>
242-
<a
243-
href={authState.authorizationUrl}
244-
target="_blank"
245-
rel="noopener noreferrer"
245+
<button
246+
onClick={() => {
247+
try {
248+
validateRedirectUrl(authState.authorizationUrl!);
249+
window.open(
250+
authState.authorizationUrl!,
251+
"_blank",
252+
"noopener noreferrer",
253+
);
254+
} catch (error) {
255+
toast({
256+
title: "Invalid URL",
257+
description:
258+
error instanceof Error
259+
? error.message
260+
: "The authorization URL is not valid",
261+
variant: "destructive",
262+
});
263+
}
264+
}}
246265
className="flex items-center text-blue-500 hover:text-blue-700"
247266
aria-label="Open authorization URL in new tab"
248267
title="Open authorization URL"
249268
>
250269
<ExternalLink className="h-4 w-4" />
251-
</a>
270+
</button>
252271
</div>
253272
<p className="text-xs text-muted-foreground mt-2">
254273
Click the link to authorize in your browser. After
@@ -354,7 +373,21 @@ export const OAuthFlowProgress = ({
354373
authState.authorizationUrl && (
355374
<Button
356375
variant="outline"
357-
onClick={() => window.open(authState.authorizationUrl!, "_blank")}
376+
onClick={() => {
377+
try {
378+
validateRedirectUrl(authState.authorizationUrl!);
379+
window.open(authState.authorizationUrl!, "_blank");
380+
} catch (error) {
381+
toast({
382+
title: "Invalid URL",
383+
description:
384+
error instanceof Error
385+
? error.message
386+
: "The authorization URL is not valid",
387+
variant: "destructive",
388+
});
389+
}
390+
}}
358391
>
359392
Open in New Tab
360393
</Button>

client/src/components/Sidebar.tsx

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import {
2424
SelectTrigger,
2525
SelectValue,
2626
} from "@/components/ui/select";
27-
import { StdErrNotification } from "@/lib/notificationTypes";
2827
import {
2928
LoggingLevel,
3029
LoggingLevelSchema,
@@ -62,8 +61,6 @@ interface SidebarProps {
6261
setOauthScope: (scope: string) => void;
6362
onConnect: () => void;
6463
onDisconnect: () => void;
65-
stdErrNotifications: StdErrNotification[];
66-
clearStdErrNotifications: () => void;
6764
logLevel: LoggingLevel;
6865
sendLogLevelRequest: (level: LoggingLevel) => void;
6966
loggingSupported: boolean;
@@ -93,8 +90,6 @@ const Sidebar = ({
9390
setOauthScope,
9491
onConnect,
9592
onDisconnect,
96-
stdErrNotifications,
97-
clearStdErrNotifications,
9893
logLevel,
9994
sendLogLevelRequest,
10095
loggingSupported,
@@ -268,6 +263,7 @@ const Sidebar = ({
268263
placeholder="Command"
269264
value={command}
270265
onChange={(e) => setCommand(e.target.value)}
266+
onBlur={(e) => setCommand(e.target.value.trim())}
271267
className="font-mono"
272268
/>
273269
</div>
@@ -760,36 +756,6 @@ const Sidebar = ({
760756
</Select>
761757
</div>
762758
)}
763-
764-
{stdErrNotifications.length > 0 && (
765-
<>
766-
<div className="mt-4 border-t border-gray-200 pt-4">
767-
<div className="flex justify-between items-center">
768-
<h3 className="text-sm font-medium">
769-
Error output from MCP server
770-
</h3>
771-
<Button
772-
variant="outline"
773-
size="sm"
774-
onClick={clearStdErrNotifications}
775-
className="h-8 px-2"
776-
>
777-
Clear
778-
</Button>
779-
</div>
780-
<div className="mt-2 max-h-80 overflow-y-auto">
781-
{stdErrNotifications.map((notification, index) => (
782-
<div
783-
key={index}
784-
className="text-sm text-red-500 font-mono py-2 border-b border-gray-200 last:border-b-0"
785-
>
786-
{notification.params.content}
787-
</div>
788-
))}
789-
</div>
790-
</div>
791-
</>
792-
)}
793759
</div>
794760
</div>
795761
</div>

0 commit comments

Comments
 (0)