mirror of
https://github.com/simstudioai/sim.git
synced 2026-09-24 15:45:35 +08:00
test(table): pin the executor auth pairing on the table read route (#6603)
* test(table): pin the executor auth pairing on the table read route fetchTableSchema reaches GET /api/table/[tableId] with a legacy type:'internal' token, which only works while that route authenticates through checkSessionOrInternalAuth. Its sibling table routes already moved to the delegation policy, which rejects that token outright, so migrating this one without moving the caller in the same change would break every table tool on an Agent block. Assert the route still authenticates through the legacy path so that migration fails here first, and record on the caller why it is deliberately not on buildExecutorDelegationHeaders yet. * test(table): assert the Bearer header reaches the legacy verifier Address review: the pairing test sent no Authorization header and its name claimed to verify token acceptance, which is pinned separately in lib/auth/internal.test.ts. Send a representative header, assert it reaches checkSessionOrInternalAuth unmodified, and scope the name and docs to what this guard actually covers — the route's choice of verifier.
This commit is contained in:
@@ -55,7 +55,7 @@ vi.mock('@/app/api/table/utils', () => ({
|
||||
tableLockErrorResponse: () => null,
|
||||
}))
|
||||
|
||||
import { PATCH } from '@/app/api/table/[tableId]/route'
|
||||
import { GET, PATCH } from '@/app/api/table/[tableId]/route'
|
||||
|
||||
const TABLE = {
|
||||
id: 'tbl_1',
|
||||
@@ -162,3 +162,47 @@ describe('PATCH /api/table/[tableId] folder moves', () => {
|
||||
expect(mockRenameTable).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
||||
/**
|
||||
* Pins which auth path this route hands a Bearer token to.
|
||||
*
|
||||
* `fetchTableSchema` in `@/tools/schema-enrichers` reaches this route with a legacy
|
||||
* `type: 'internal'` token from the deprecated `buildAuthHeaders`. Only
|
||||
* `checkSessionOrInternalAuth` accepts that token; the delegation policy the sibling
|
||||
* table routes use rejects it outright. Migrating this route without moving that caller
|
||||
* to `buildExecutorDelegationHeaders` in the same change breaks every table tool on an
|
||||
* Agent block, so this fails first and names the caller.
|
||||
*
|
||||
* Scope: this pins the *route's* choice of verifier. That the legacy token is actually
|
||||
* valid for that verifier — and rejected by the delegation one — is pinned separately in
|
||||
* `@/lib/auth/internal.test.ts`. Both halves are needed; neither implies the other.
|
||||
*/
|
||||
describe('GET /api/table/[tableId] executor auth pairing', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
hybridAuthMockFns.mockCheckSessionOrInternalAuth.mockResolvedValue({
|
||||
success: true,
|
||||
userId: 'user-1',
|
||||
authType: 'internal_jwt',
|
||||
})
|
||||
mockCheckAccess.mockResolvedValue({ ok: true, table: TABLE })
|
||||
mockGetLimits.mockResolvedValue({ maxRowsPerTable: 1000 })
|
||||
})
|
||||
|
||||
it('routes a Bearer token to the legacy verifier fetchTableSchema mints for', async () => {
|
||||
const request = new NextRequest('http://localhost:3000/api/table/tbl_1?workspaceId=workspace-1')
|
||||
request.headers.set('authorization', 'Bearer legacy-internal-token')
|
||||
|
||||
const response = await GET(request, routeContext)
|
||||
|
||||
expect(response.status).toBe(200)
|
||||
expect(hybridAuthMockFns.mockCheckSessionOrInternalAuth).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
headers: expect.objectContaining({ get: expect.any(Function) }),
|
||||
}),
|
||||
expect.anything()
|
||||
)
|
||||
const [forwarded] = hybridAuthMockFns.mockCheckSessionOrInternalAuth.mock.calls[0]
|
||||
expect(forwarded.headers.get('authorization')).toBe('Bearer legacy-internal-token')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -7,6 +7,19 @@ import type { WorkflowToolExecutionContext } from '@/tools/types'
|
||||
|
||||
const logger = createLogger('SchemaEnrichers')
|
||||
|
||||
/**
|
||||
* Reads a table's schema as the acting user.
|
||||
*
|
||||
* Deliberately still on the deprecated `buildAuthHeaders`, unlike its siblings in this
|
||||
* file: `GET /api/table/[tableId]` authenticates through `checkSessionOrInternalAuth`,
|
||||
* which accepts a legacy `type: 'internal'` token and rejects an executor delegation.
|
||||
* Swapping this to `buildExecutorDelegationHeaders` before that route migrates would
|
||||
* break every table tool on an Agent block. The route's own test pins the pairing.
|
||||
*
|
||||
* Unlike the workflow and knowledge enrichers, a failure here is loud — this runs as a
|
||||
* tool-level `toolEnrichment`, so `createLLMToolSchema` surfaces it as a
|
||||
* `ToolSchemaEnrichmentError` naming the tool rather than degrading the schema silently.
|
||||
*/
|
||||
async function fetchTableSchema(
|
||||
tableId: string,
|
||||
context: WorkflowToolExecutionContext
|
||||
|
||||
Reference in New Issue
Block a user