11/**
22 * @vitest -environment node
33 */
4- import { resetDbChainMock } from '@sim/testing'
4+ import { mcpServers } from '@sim/db/schema'
5+ import { queueTableRows , resetDbChainMock } from '@sim/testing'
56import type { NextRequest } from 'next/server'
67import { afterAll , beforeEach , describe , expect , it , vi } from 'vitest'
78
8- const { mockPerformDeleteMcpServer } = vi . hoisted ( ( ) => ( {
9+ const { mockCanWrite, mockPerformDeleteMcpServer } = vi . hoisted ( ( ) => ( {
10+ mockCanWrite : vi . fn ( ) ,
911 mockPerformDeleteMcpServer : vi . fn ( ) ,
1012} ) )
1113
@@ -21,6 +23,7 @@ vi.mock('@/lib/mcp/middleware', () => ({
2123 userName : string
2224 userEmail : string
2325 workspaceId : string
26+ canWrite : boolean
2427 requestId : string
2528 }
2629 ) => Promise < Response >
@@ -31,6 +34,7 @@ vi.mock('@/lib/mcp/middleware', () => ({
3134 userName : 'Test User' ,
3235 userEmail : 'test@example.com' ,
3336 workspaceId : 'workspace-1' ,
37+ canWrite : mockCanWrite ( ) ,
3438 requestId : 'request-1' ,
3539 } ) ,
3640} ) )
@@ -40,7 +44,13 @@ vi.mock('@/lib/mcp/orchestration', () => ({
4044 performDeleteMcpServer : mockPerformDeleteMcpServer ,
4145} ) )
4246
43- import { DELETE } from '@/app/api/mcp/servers/route'
47+ import { DELETE , GET } from '@/app/api/mcp/servers/route'
48+
49+ function createListRequest ( ) {
50+ return new Request ( 'http://localhost:3000/api/mcp/servers?workspaceId=workspace-1' , {
51+ method : 'GET' ,
52+ } ) as NextRequest
53+ }
4454
4555function createDeleteRequest ( serverId = 'server-1' ) {
4656 return new Request (
@@ -87,3 +97,44 @@ describe('MCP servers DELETE route', () => {
8797 expect ( body ) . toEqual ( { success : false , error : 'Failed to delete MCP server' } )
8898 } )
8999} )
100+
101+ describe ( 'MCP servers GET route' , ( ) => {
102+ beforeEach ( ( ) => {
103+ vi . clearAllMocks ( )
104+ resetDbChainMock ( )
105+ mockCanWrite . mockReturnValue ( false )
106+ queueTableRows ( mcpServers , [
107+ {
108+ id : 'server-1' ,
109+ workspaceId : 'workspace-1' ,
110+ name : 'Private server' ,
111+ headers : { Authorization : 'Bearer secret-token' } ,
112+ oauthClientSecret : 'oauth-secret' ,
113+ } ,
114+ ] )
115+ } )
116+
117+ afterAll ( ( ) => {
118+ resetDbChainMock ( )
119+ } )
120+
121+ it ( 'does not expose authentication header values to read-only users' , async ( ) => {
122+ const response = await GET ( createListRequest ( ) )
123+ const body = await response . json ( )
124+
125+ expect ( response . status ) . toBe ( 200 )
126+ expect ( body . data . servers [ 0 ] ) . not . toHaveProperty ( 'headers' )
127+ expect ( body . data . servers [ 0 ] ) . not . toHaveProperty ( 'oauthClientSecret' )
128+ expect ( body . data . servers [ 0 ] . hasOauthClientSecret ) . toBe ( true )
129+ } )
130+
131+ it ( 'retains configured headers for users who can manage the server' , async ( ) => {
132+ mockCanWrite . mockReturnValue ( true )
133+
134+ const response = await GET ( createListRequest ( ) )
135+ const body = await response . json ( )
136+
137+ expect ( response . status ) . toBe ( 200 )
138+ expect ( body . data . servers [ 0 ] . headers ) . toEqual ( { Authorization : 'Bearer secret-token' } )
139+ } )
140+ } )
0 commit comments