Skip to content

Commit 8c78e18

Browse files
fix(slack): continue shared legacy webhook fanout
1 parent 99cce53 commit 8c78e18

2 files changed

Lines changed: 87 additions & 2 deletions

File tree

apps/sim/app/api/webhooks/trigger/[path]/route.test.ts

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,6 +767,88 @@ describe('Webhook Trigger API Route', () => {
767767
expect(dispatchResolvedWebhookTargetMock).not.toHaveBeenCalled()
768768
})
769769

770+
it('continues past a missing credential to another valid legacy credential', async () => {
771+
testData.webhooks.push(
772+
{
773+
id: 'missing-legacy-slack-webhook',
774+
provider: 'slack',
775+
path: 'shared-legacy-slack-path',
776+
routingKey: 'missing-credential',
777+
isActive: true,
778+
providerConfig: {
779+
triggerId: 'slack_webhook',
780+
credentialId: 'missing-credential',
781+
ingressMode: 'legacy_custom_bot',
782+
},
783+
workflowId: 'test-workflow-id',
784+
},
785+
{
786+
id: 'valid-legacy-slack-webhook',
787+
provider: 'slack',
788+
path: 'shared-legacy-slack-path',
789+
routingKey: 'valid-credential',
790+
isActive: true,
791+
providerConfig: {
792+
triggerId: 'slack_webhook',
793+
credentialId: 'valid-credential',
794+
ingressMode: 'legacy_custom_bot',
795+
},
796+
workflowId: 'test-workflow-id',
797+
}
798+
)
799+
verifySlackCustomBotCredentialRequestMock.mockImplementation(
800+
async ({ credentialId }: { credentialId: string }) =>
801+
credentialId === 'missing-credential' ? new NextResponse(null, { status: 404 }) : null
802+
)
803+
804+
const response = await POST(createMockRequest('POST', { type: 'event_callback' }), {
805+
params: Promise.resolve({ path: 'shared-legacy-slack-path' }),
806+
})
807+
808+
expect(response.status).toBe(200)
809+
expect(dispatchSlackCustomBotCredentialMock).toHaveBeenCalledOnce()
810+
expect(dispatchSlackCustomBotCredentialMock).toHaveBeenCalledWith(
811+
expect.objectContaining({ credentialId: 'valid-credential' })
812+
)
813+
})
814+
815+
it('continues to a direct webhook when every legacy credential is unavailable', async () => {
816+
testData.webhooks.push(
817+
{
818+
id: 'missing-legacy-slack-webhook',
819+
provider: 'slack',
820+
path: 'shared-direct-path',
821+
routingKey: 'missing-credential',
822+
isActive: true,
823+
providerConfig: {
824+
triggerId: 'slack_webhook',
825+
credentialId: 'missing-credential',
826+
ingressMode: 'legacy_custom_bot',
827+
},
828+
workflowId: 'test-workflow-id',
829+
},
830+
{
831+
id: 'direct-webhook',
832+
provider: 'generic',
833+
path: 'shared-direct-path',
834+
isActive: true,
835+
providerConfig: { requireAuth: false },
836+
workflowId: 'test-workflow-id',
837+
}
838+
)
839+
verifySlackCustomBotCredentialRequestMock.mockResolvedValueOnce(
840+
new NextResponse(null, { status: 404 })
841+
)
842+
843+
const response = await POST(createMockRequest('POST', { type: 'event_callback' }), {
844+
params: Promise.resolve({ path: 'shared-direct-path' }),
845+
})
846+
847+
expect(response.status).toBe(200)
848+
expect(dispatchSlackCustomBotCredentialMock).not.toHaveBeenCalled()
849+
expect(dispatchResolvedWebhookTargetMock).toHaveBeenCalledOnce()
850+
})
851+
770852
it('propagates a legacy fan-out failure when no target queues successfully', async () => {
771853
testData.webhooks.push({
772854
id: 'legacy-slack-webhook',

apps/sim/app/api/webhooks/trigger/[path]/route.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,6 @@ async function handleWebhookPost(
154154
requestId,
155155
})
156156
if (authError) {
157-
if (authError.status === 404) return authError
158157
firstLegacySlackAuthError ??= authError
159158
continue
160159
}
@@ -170,7 +169,11 @@ async function handleWebhookPost(
170169
legacySlackDispatchResults.push(...dispatchResults)
171170
}
172171

173-
if (legacySlackCredentialIds.size > 0 && !authenticatedLegacySlackAlias) {
172+
if (
173+
legacySlackCredentialIds.size > 0 &&
174+
!authenticatedLegacySlackAlias &&
175+
directWebhooksForPath.length === 0
176+
) {
174177
return (
175178
firstLegacySlackAuthError ??
176179
new NextResponse('Unauthorized - Invalid Slack signature', { status: 401 })

0 commit comments

Comments
 (0)