Skip to content

Commit 0a6377d

Browse files
feat(MK8S-196): simplify authRequired — return error if not logged in, drop OidcClient and userManager export
1 parent ceb21b0 commit 0a6377d

File tree

2 files changed

+15
-103
lines changed

2 files changed

+15
-103
lines changed

shell-ui/src/auth/AuthProvider.tsx

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,6 @@ export type UserData = {
160160
export function useAuth(): {
161161
userData?: UserData;
162162
getToken: () => Promise<string | null>;
163-
userManager: UserManager | undefined;
164163
} {
165164
try {
166165
const auth = useOauth2Auth(); // todo add support for OAuth2Proxy
@@ -217,7 +216,6 @@ export function useAuth(): {
217216
return {
218217
userData: undefined,
219218
getToken: () => Promise.resolve(null),
220-
userManager: auth?.userManager,
221219
};
222220
}
223221

@@ -235,13 +233,11 @@ export function useAuth(): {
235233
return user?.access_token;
236234
});
237235
},
238-
userManager: auth.userManager,
239236
};
240237
} catch (e) {
241238
return {
242239
userData: undefined,
243240
getToken: () => Promise.resolve('null'),
244-
userManager: undefined,
245241
};
246242
}
247243
}

shell-ui/src/mcp/MCPRegistrar.tsx

Lines changed: 15 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
11
import '@mcp-b/global';
22
import { ComponentWithFederatedImports } from '@scality/module-federation';
3-
import { OidcClient } from 'oidc-client-ts';
43
import { useEffect } from 'react';
54

65
declare const __webpack_public_path__: string;
76
import { ErrorBoundary } from 'react-error-boundary';
8-
import {
9-
getAbsoluteRedirectUrl,
10-
useAuth,
11-
} from '../auth/AuthProvider';
7+
import { useAuth } from '../auth/AuthProvider';
128
import {
139
FederatedModuleInfo,
14-
OIDCConfig,
1510
useConfigRetriever,
1611
} from '../initFederation/ConfigurationProviders';
1712
import { useDeployedApps } from '../initFederation/UIListProvider';
@@ -22,17 +17,15 @@ export const _InternalMCPRegistrar = ({
2217
moduleExports,
2318
mcpToolsModuleInfo,
2419
selfConfiguration,
25-
authConfig,
2620
}: {
2721
moduleExports: Record<string, { tools: MCPToolDefinition[] }>;
2822
mcpToolsModuleInfo: FederatedModuleInfo;
2923
selfConfiguration: Record<string, unknown>;
30-
authConfig: OIDCConfig | null;
3124
}) => {
32-
const { userManager } = useAuth();
25+
const { getToken } = useAuth();
3326

3427
useEffect(() => {
35-
if (!navigator.modelContext || !userManager) return;
28+
if (!navigator.modelContext) return;
3629

3730
const tools = moduleExports[mcpToolsModuleInfo.module]?.tools ?? [];
3831
const registeredNames: string[] = [];
@@ -44,93 +37,21 @@ export const _InternalMCPRegistrar = ({
4437
inputSchema: tool.inputSchema,
4538
execute: async (params: unknown, client: ModelContextClient) => {
4639
if (tool.authRequired) {
47-
let user = await userManager.getUser();
48-
49-
if (!user || user.expired) {
50-
user = await userManager.signinSilent().catch(() => null);
51-
}
52-
53-
if (!user || user.expired) {
54-
if (!authConfig) {
55-
return {
56-
success: false,
57-
error: {
58-
code: 'AUTH_REQUIRED',
59-
message: 'Authentication required but no OIDC configuration is available',
60-
},
61-
};
62-
}
63-
64-
const oidcClient = new OidcClient({
65-
authority: authConfig.providerUrl,
66-
client_id: authConfig.clientId,
67-
redirect_uri: getAbsoluteRedirectUrl(authConfig.redirectUrl),
68-
response_type: authConfig.responseType || 'code',
69-
scope: authConfig.scopes,
70-
});
71-
72-
// connector_id is passed as extraQueryParams rather than via MetadataServiceCtor
73-
// (which is UserManager-only). The effect on the final auth URL is identical.
74-
const signinRequest = await oidcClient.createSigninRequest({
75-
...(authConfig.defaultDexConnector && {
76-
extraQueryParams: { connector_id: authConfig.defaultDexConnector },
77-
}),
78-
});
79-
const authUrl = signinRequest.url;
80-
81-
const authenticated = await client.requestUserInteraction(
82-
(_innerClient: ModelContextClient) => {
83-
return new Promise<boolean>((resolve) => {
84-
const modal = document.createElement('div');
85-
modal.className = 'mcp-auth-modal';
86-
modal.style.cssText =
87-
'position:fixed;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,0.5);z-index:9999';
88-
modal.innerHTML = `
89-
<div style="background:#fff;padding:2rem;border-radius:8px;max-width:400px;text-align:center">
90-
<h3 style="margin:0 0 1rem">Authentication Required</h3>
91-
<p style="margin:0 0 1.5rem">This action requires you to sign in.</p>
92-
<a href="${authUrl}" target="_blank" style="display:inline-block;padding:0.5rem 1.5rem;background:#0066cc;color:#fff;border-radius:4px;text-decoration:none;margin-bottom:1rem">Sign in to continue</a>
93-
<br/>
94-
<button id="mcp-cancel-auth" style="margin-top:0.5rem;padding:0.4rem 1rem;cursor:pointer">Cancel</button>
95-
</div>
96-
`;
97-
document.body.appendChild(modal);
98-
99-
const onUserLoaded = () => {
100-
modal.remove();
101-
userManager.events.removeUserLoaded(onUserLoaded);
102-
resolve(true);
103-
};
104-
userManager.events.addUserLoaded(onUserLoaded);
105-
106-
modal
107-
.querySelector('#mcp-cancel-auth')
108-
?.addEventListener('click', () => {
109-
userManager.events.removeUserLoaded(onUserLoaded);
110-
modal.remove();
111-
resolve(false);
112-
});
113-
});
40+
const token = await getToken();
41+
if (!token) {
42+
return {
43+
success: false,
44+
error: {
45+
code: 'AUTH_REQUIRED',
46+
message:
47+
'You must log in to the browser window prior to performing this action.',
11448
},
115-
);
116-
117-
if (!authenticated) {
118-
return {
119-
success: false,
120-
error: {
121-
code: 'AUTH_REQUIRED',
122-
message: 'Authentication required to perform this action',
123-
},
124-
};
125-
}
49+
};
12650
}
12751
}
12852

12953
const context: ToolContext = {
130-
getToken: async () => {
131-
const user = await userManager.getUser();
132-
return user?.access_token ?? '';
133-
},
54+
getToken,
13455
selfConfiguration,
13556
};
13657

@@ -149,7 +70,7 @@ export const _InternalMCPRegistrar = ({
14970
navigator.modelContext?.unregisterTool?.(name),
15071
);
15172
};
152-
}, [moduleExports, mcpToolsModuleInfo, userManager, selfConfiguration, authConfig]);
73+
}, [moduleExports, mcpToolsModuleInfo, getToken, selfConfiguration]);
15374

15475
return null;
15576
};
@@ -194,18 +115,13 @@ export const MCPRegistrar = () => {
194115
const selfConfiguration =
195116
(runtimeConfig?.spec?.selfConfiguration as Record<string, unknown>) ??
196117
{};
197-
const auth = runtimeConfig?.spec?.auth;
198-
const authConfig =
199-
auth && (auth as { kind: string }).kind === 'OIDC'
200-
? (auth as unknown as OIDCConfig)
201-
: null;
202118
const remoteEntryUrl = app.url + buildConfig.spec.remoteEntryPath;
203119

204120
return [
205121
<ErrorBoundary key={app.name} FallbackComponent={() => null}>
206122
<ComponentWithFederatedImports
207123
componentWithInjectedImports={_InternalMCPRegistrar}
208-
componentProps={{ mcpToolsModuleInfo, selfConfiguration, authConfig }}
124+
componentProps={{ mcpToolsModuleInfo, selfConfiguration }}
209125
renderOnError={null}
210126
federatedImports={[{ ...mcpToolsModuleInfo, remoteEntryUrl }]}
211127
/>

0 commit comments

Comments
 (0)