Skip to content

Commit 3d6dd1d

Browse files
committed
fix(mcp): prefer preregistered clients over stored registrations and tighten issuer boundary test
1 parent 1dd4a94 commit 3d6dd1d

2 files changed

Lines changed: 14 additions & 10 deletions

File tree

‎apps/sim/lib/credential-groups/__integration__/hubspot-mcp.integration.ts‎

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -408,17 +408,20 @@ describe.each(SHARED_CLIENTS)('$name shared member connector', (connector) => {
408408
row: await getOrCreateOauthRow({ mcpServerId: mcpServer.id, organizationId: org }),
409409
preregistered: await loadPreregisteredClient(mcpServer.id),
410410
})
411-
if (phase === 'legacy refresh')
411+
if (phase === 'code exchange') await provider.saveCodeVerifier('fixture-verifier')
412+
else
412413
await provider.saveTokens({
413414
access_token: 'fixture-access',
414415
refresh_token: 'fixture-refresh',
415416
token_type: 'Bearer',
416417
})
417418
const disclosed: string[] = []
419+
const reached = new Set<string>()
418420
const fetchFn: typeof fetch = async (request, init) => {
419421
const url = new URL(
420422
typeof request === 'string' ? request : request instanceof URL ? request : request.url
421423
)
424+
if (url.origin === substitute) reached.add(url.pathname)
422425
const sent = `${new Headers(init?.headers).get('authorization') ?? ''} ${String(init?.body ?? '')}`
423426
if (
424427
url.origin === substitute &&
@@ -450,13 +453,15 @@ describe.each(SHARED_CLIENTS)('$name shared member connector', (connector) => {
450453
return Response.json({ access_token: 'substitute-access', token_type: 'Bearer' })
451454
throw new Error(`Unexpected OAuth fixture request: ${url.origin}${url.pathname}`)
452455
}
453-
await oauth
454-
.mcpAuthGuarded(provider, {
455-
serverUrl: connector.url,
456-
fetchFn,
457-
...(phase === 'code exchange' ? { authorizationCode: 'fixture-code' } : {}),
458-
})
459-
.catch(() => undefined)
456+
const attempt = oauth.mcpAuthGuarded(provider, {
457+
serverUrl: connector.url,
458+
fetchFn,
459+
...(phase === 'code exchange' ? { authorizationCode: 'fixture-code' } : {}),
460+
})
461+
if (phase === 'code exchange')
462+
await expect(attempt).rejects.toThrow(/Existing OAuth client information is required/)
463+
else await expect(attempt).rejects.toBeInstanceOf(McpOauthRedirectRequired)
464+
expect(reached.has('/.well-known/oauth-authorization-server')).toBe(true)
460465
expect(disclosed).toEqual([])
461466
}
462467
)

‎apps/sim/lib/mcp/oauth/provider.ts‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,6 @@ export class SimMcpOauthProvider implements OAuthClientProvider {
114114
}
115115

116116
clientInformation(): OAuthClientInformationMixed | undefined {
117-
if (this.row.clientInformation) return this.row.clientInformation
118117
if (this.preregistered) {
119118
return {
120119
client_id: this.preregistered.clientId,
@@ -128,7 +127,7 @@ export class SimMcpOauthProvider implements OAuthClientProvider {
128127
issuer: this.preregistered.issuer ?? this.row.tokens?.issuer,
129128
}
130129
}
131-
return undefined
130+
return this.row.clientInformation ?? undefined
132131
}
133132

134133
async saveClientInformation(info: OAuthClientInformationMixed): Promise<void> {

0 commit comments

Comments
 (0)