Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions apps/sim/app/api/mcp/oauth/callback/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export const GET = withRouteHandler(async (request: NextRequest) => {

if (errorParam) {
logger.warn(`MCP OAuth callback received error: ${errorParam}`)
if (initialRow) await clearState(initialRow.id).catch(() => {})
if (initialRow) await clearState(initialRow.id, 'callback:provider_error').catch(() => {})
return respond(`Authorization failed: ${errorParam}`, false, 'provider_error', stateRowServerId)
}
if (!state || !code) {
Expand Down Expand Up @@ -157,7 +157,7 @@ export const GET = withRouteHandler(async (request: NextRequest) => {
}

// Burn state before token exchange so a replayed callback cannot reuse it.
await clearState(row.id)
await clearState(row.id, 'callback:burn-before-exchange')

const preregistered = await loadPreregisteredClient(server.id)
const provider = new SimMcpOauthProvider({ row, preregistered })
Expand Down
4 changes: 2 additions & 2 deletions apps/sim/lib/mcp/oauth/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export class SimMcpOauthProvider implements OAuthClientProvider {

async state(): Promise<string> {
const state = generateId()
await saveState(this.row.id, state)
await saveState(this.row.id, state, 'provider.state')
return state
}

Expand Down Expand Up @@ -140,7 +140,7 @@ export class SimMcpOauthProvider implements OAuthClientProvider {
}
if (scope === 'all' || scope === 'verifier') {
await clearVerifier(this.row.id)
await clearState(this.row.id)
await clearState(this.row.id, `invalidateCredentials:${scope}`)
this.row.codeVerifier = null
}
}
Expand Down
6 changes: 4 additions & 2 deletions apps/sim/lib/mcp/oauth/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,12 +192,13 @@ export async function saveCodeVerifier(rowId: string, verifier: string): Promise
.where(eq(mcpServerOauth.id, rowId))
}

export async function saveState(rowId: string, state: string): Promise<void> {
export async function saveState(rowId: string, state: string, context = 'unknown'): Promise<void> {
const now = new Date()
await db
.update(mcpServerOauth)
.set({ state: hashState(state), stateCreatedAt: now, updatedAt: now })
.where(eq(mcpServerOauth.id, rowId))
logger.info('MCP OAuth authorization state saved', { rowId, context })
Comment thread
waleedlatif1 marked this conversation as resolved.
}

export async function clearTokens(rowId: string): Promise<void> {
Expand All @@ -221,11 +222,12 @@ export async function clearVerifier(rowId: string): Promise<void> {
.where(eq(mcpServerOauth.id, rowId))
}

export async function clearState(rowId: string): Promise<void> {
export async function clearState(rowId: string, context = 'unknown'): Promise<void> {
await db
.update(mcpServerOauth)
.set({ state: null, stateCreatedAt: null, updatedAt: new Date() })
.where(eq(mcpServerOauth.id, rowId))
logger.info('MCP OAuth authorization state cleared', { rowId, context })
}

/**
Expand Down
Loading