fix(executor): skip Response block formatting for internal JWT callers (#3551)

* fix(executor): skip Response block formatting for internal JWT callers

The workflow executor tool received `{error: true}` despite successful child
workflow execution when the child had a Response block. This happened because
`createHttpResponseFromBlock()` hijacked the response with raw user-defined
data, and the executor's `transformResponse` expected the standard
`{success, executionId, output, metadata}` wrapper.

Fix: skip Response block formatting when `authType === INTERNAL_JWT` since
Response blocks are designed for external API consumers, not internal
workflow-to-workflow calls. Also extract `AuthType` constants from magic
strings across all auth type comparisons in the codebase.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* test(executor): add route-level tests for Response block auth gating

Verify that internal JWT callers receive standard format while external
callers (API key, session) get Response block formatting. Tests the
server-side condition directly using workflowHasResponseBlock and
createHttpResponseFromBlock with AuthType constants.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(testing): add AuthType to all hybrid auth test mocks

Route code now imports AuthType from @/lib/auth/hybrid, so test mocks
must export it too. Added AuthTypeMock to @sim/testing and included it
in all 15 test files that mock the hybrid auth module.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Waleed
2026-03-12 16:56:02 -07:00
committed by GitHub
co-authored by Claude Opus 4.6
parent 4cb0f4a2b0
commit 72bb7e6945
30 changed files with 284 additions and 36 deletions
+1
View File
@@ -45,6 +45,7 @@ export * from './assertions'
export * from './builders'
export * from './factories'
export {
AuthTypeMock,
auditMock,
clearRedisMocks,
createEnvMock,
+12 -1
View File
@@ -6,12 +6,22 @@ import { vi } from 'vitest'
import type { MockUser } from './auth.mock'
import { defaultMockUser } from './auth.mock'
/**
* Auth type constants matching @/lib/auth/hybrid AuthType.
* Include this in vi.mock() factories so route code can reference AuthType.*.
*/
export const AuthTypeMock = {
SESSION: 'session',
API_KEY: 'api_key',
INTERNAL_JWT: 'internal_jwt',
} as const
interface HybridAuthResponse {
success: boolean
userId?: string
userName?: string | null
userEmail?: string | null
authType?: 'session' | 'api_key' | 'internal_jwt'
authType?: (typeof AuthTypeMock)[keyof typeof AuthTypeMock]
error?: string
}
@@ -46,6 +56,7 @@ export function mockHybridAuth(user: MockUser = defaultMockUser): MockHybridAuth
const mockCheckInternalAuth = vi.fn<() => Promise<HybridAuthResponse>>()
vi.doMock('@/lib/auth/hybrid', () => ({
AuthType: AuthTypeMock,
checkHybridAuth: mockCheckHybridAuth,
checkSessionOrInternalAuth: mockCheckSessionOrInternalAuth,
checkInternalAuth: mockCheckInternalAuth,
+1 -1
View File
@@ -64,7 +64,7 @@ export {
setupGlobalFetchMock,
} from './fetch.mock'
// Hybrid auth mocks
export { type MockHybridAuthResult, mockHybridAuth } from './hybrid-auth.mock'
export { AuthTypeMock, type MockHybridAuthResult, mockHybridAuth } from './hybrid-auth.mock'
// Logger mocks
export { clearLoggerMocks, createMockLogger, getLoggerCalls, loggerMock } from './logger.mock'
// Redis mocks