Skip to content

Commit 12c865b

Browse files
fix(slack): continue shared legacy webhook fanout
1 parent fc02c3c commit 12c865b

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
@@ -1036,6 +1036,88 @@ describe('Webhook Trigger API Route', () => {
10361036
expect(dispatchResolvedWebhookTargetMock).not.toHaveBeenCalled()
10371037
})
10381038

1039+
it('continues past a missing credential to another valid legacy credential', async () => {
1040+
testData.webhooks.push(
1041+
{
1042+
id: 'missing-legacy-slack-webhook',
1043+
provider: 'slack',
1044+
path: 'shared-legacy-slack-path',
1045+
routingKey: 'missing-credential',
1046+
isActive: true,
1047+
providerConfig: {
1048+
triggerId: 'slack_webhook',
1049+
credentialId: 'missing-credential',
1050+
ingressMode: 'legacy_custom_bot',
1051+
},
1052+
workflowId: 'test-workflow-id',
1053+
},
1054+
{
1055+
id: 'valid-legacy-slack-webhook',
1056+
provider: 'slack',
1057+
path: 'shared-legacy-slack-path',
1058+
routingKey: 'valid-credential',
1059+
isActive: true,
1060+
providerConfig: {
1061+
triggerId: 'slack_webhook',
1062+
credentialId: 'valid-credential',
1063+
ingressMode: 'legacy_custom_bot',
1064+
},
1065+
workflowId: 'test-workflow-id',
1066+
}
1067+
)
1068+
verifySlackCustomBotCredentialRequestMock.mockImplementation(
1069+
async ({ credentialId }: { credentialId: string }) =>
1070+
credentialId === 'missing-credential' ? new NextResponse(null, { status: 404 }) : null
1071+
)
1072+
1073+
const response = await POST(createMockRequest('POST', { type: 'event_callback' }), {
1074+
params: Promise.resolve({ path: 'shared-legacy-slack-path' }),
1075+
})
1076+
1077+
expect(response.status).toBe(200)
1078+
expect(dispatchSlackCustomBotCredentialMock).toHaveBeenCalledOnce()
1079+
expect(dispatchSlackCustomBotCredentialMock).toHaveBeenCalledWith(
1080+
expect.objectContaining({ credentialId: 'valid-credential' })
1081+
)
1082+
})
1083+
1084+
it('continues to a direct webhook when every legacy credential is unavailable', async () => {
1085+
testData.webhooks.push(
1086+
{
1087+
id: 'missing-legacy-slack-webhook',
1088+
provider: 'slack',
1089+
path: 'shared-direct-path',
1090+
routingKey: 'missing-credential',
1091+
isActive: true,
1092+
providerConfig: {
1093+
triggerId: 'slack_webhook',
1094+
credentialId: 'missing-credential',
1095+
ingressMode: 'legacy_custom_bot',
1096+
},
1097+
workflowId: 'test-workflow-id',
1098+
},
1099+
{
1100+
id: 'direct-webhook',
1101+
provider: 'generic',
1102+
path: 'shared-direct-path',
1103+
isActive: true,
1104+
providerConfig: { requireAuth: false },
1105+
workflowId: 'test-workflow-id',
1106+
}
1107+
)
1108+
verifySlackCustomBotCredentialRequestMock.mockResolvedValueOnce(
1109+
new NextResponse(null, { status: 404 })
1110+
)
1111+
1112+
const response = await POST(createMockRequest('POST', { type: 'event_callback' }), {
1113+
params: Promise.resolve({ path: 'shared-direct-path' }),
1114+
})
1115+
1116+
expect(response.status).toBe(200)
1117+
expect(dispatchSlackCustomBotCredentialMock).not.toHaveBeenCalled()
1118+
expect(dispatchResolvedWebhookTargetMock).toHaveBeenCalledOnce()
1119+
})
1120+
10391121
it('propagates a legacy fan-out failure when no target queues successfully', async () => {
10401122
testData.webhooks.push({
10411123
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
@@ -228,7 +228,6 @@ async function handleWebhookDelivery(
228228
requestId,
229229
})
230230
if (authError) {
231-
if (authError.status === 404) return authError
232231
firstLegacySlackAuthError ??= authError
233232
continue
234233
}
@@ -244,7 +243,11 @@ async function handleWebhookDelivery(
244243
legacySlackDispatchResults.push(...dispatchResults)
245244
}
246245

247-
if (legacySlackCredentialIds.size > 0 && !authenticatedLegacySlackAlias) {
246+
if (
247+
legacySlackCredentialIds.size > 0 &&
248+
!authenticatedLegacySlackAlias &&
249+
directWebhooksForPath.length === 0
250+
) {
248251
return (
249252
firstLegacySlackAuthError ??
250253
new NextResponse('Unauthorized - Invalid Slack signature', { status: 401 })

0 commit comments

Comments
 (0)