Skip to content

Commit b57a91d

Browse files
fix(slack): reject oversized app creation links
1 parent 95f7565 commit b57a91d

3 files changed

Lines changed: 29 additions & 10 deletions

File tree

‎apps/sim/app/workspace/[workspaceId]/integrations/components/connect-slack-bot-modal/connect-slack-bot-modal.tsx‎

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ import { SlackIcon } from '@/components/icons'
1818
import { SlackAppManifest } from '@/components/integrations/slack-app-manifest'
1919
import { resourceScopeFields, resourceScopeFromOwner } from '@/lib/core/resource-scope'
2020
import { getBaseUrl } from '@/lib/core/utils/urls'
21-
import { buildSlackAppCreationUrl, getSlackAppNameError } from '@/lib/integrations/slack-manifest'
21+
import {
22+
buildSlackAppCreationUrl,
23+
getSlackAppNameError,
24+
SLACK_APP_CREATION_URL_MAX_LENGTH,
25+
} from '@/lib/integrations/slack-manifest'
2226
import { SLACK_CUSTOM_BOT_PROVIDER_ID } from '@/lib/oauth/types'
2327
import {
2428
useCreateScopedCredential,
@@ -205,6 +209,12 @@ export function ConnectSlackBotModal({
205209
searchOnly,
206210
])
207211

212+
const createAppUrl = buildSlackAppCreationUrl(manifestJson)
213+
const creationUrlError =
214+
createAppUrl.length > SLACK_APP_CREATION_URL_MAX_LENGTH
215+
? 'This app configuration is too large to open in Slack. Shorten or remove slash commands.'
216+
: null
217+
208218
const capabilityIds = [...selected]
209219
const setCapabilityIds = (next: string[]) => setSelected(new Set(next))
210220

@@ -271,7 +281,12 @@ export function ConnectSlackBotModal({
271281
fallback, which collides for a second bot in the same workspace. */}
272282
<Wizard.Step
273283
title={searchOnly ? 'Name your Slack app' : 'Configure your bot'}
274-
canAdvance={appName.trim().length > 0 && !nameError && !manifestConfigurationError}
284+
canAdvance={
285+
appName.trim().length > 0 &&
286+
!nameError &&
287+
!manifestConfigurationError &&
288+
!creationUrlError
289+
}
275290
>
276291
<StepConfigure
277292
searchOnly={searchOnly}
@@ -284,13 +299,17 @@ export function ConnectSlackBotModal({
284299
descriptionError={descriptionError}
285300
slashCommands={slashCommands}
286301
onSlashCommandsChange={setSlashCommands}
287-
slashCommandsError={slashCommandsError}
302+
slashCommandsError={slashCommandsError ?? creationUrlError}
288303
capabilityIds={capabilityIds}
289304
onCapabilityIdsChange={setCapabilityIds}
290305
/>
291306
</Wizard.Step>
292307
<Wizard.Step title={isReconnect ? 'Open your app in Slack' : 'Create the app in Slack'}>
293-
<StepCreate manifestJson={manifestJson} reconnect={isReconnect} />
308+
<StepCreate
309+
manifestJson={manifestJson}
310+
createAppUrl={createAppUrl}
311+
reconnect={isReconnect}
312+
/>
294313
</Wizard.Step>
295314
<Wizard.Step title='Install and paste your Bot Token' canAdvance={botToken.trim().length > 0}>
296315
<StepToken value={botToken} onChange={setBotToken} reconnect={isReconnect} />
@@ -496,9 +515,10 @@ function SlashCommandsEditor({ commands, onChange, error }: SlashCommandsEditorP
496515

497516
interface StepCreateProps {
498517
manifestJson: string
518+
createAppUrl: string
499519
reconnect: boolean
500520
}
501-
function StepCreate({ manifestJson, reconnect }: StepCreateProps) {
521+
function StepCreate({ manifestJson, createAppUrl, reconnect }: StepCreateProps) {
502522
if (reconnect) {
503523
return (
504524
<SubStepList>
@@ -528,10 +548,7 @@ function StepCreate({ manifestJson, reconnect }: StepCreateProps) {
528548
<SubStep n={1}>
529549
<div>Open Slack with the manifest for your selected permissions already filled in:</div>
530550
<div className='mt-2'>
531-
<SlackAppManifest
532-
manifest={manifestJson}
533-
createAppUrl={buildSlackAppCreationUrl(manifestJson)}
534-
/>
551+
<SlackAppManifest manifest={manifestJson} createAppUrl={createAppUrl} />
535552
</div>
536553
</SubStep>
537554
<SubStep n={2}>

‎apps/sim/lib/api/contracts/knowledge/slack.ts‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { z } from 'zod'
22
import { organizationIdSchema } from '@/lib/api/contracts/primitives'
33
import { defineRouteContract } from '@/lib/api/contracts/types'
4+
import { SLACK_APP_CREATION_URL_MAX_LENGTH } from '@/lib/integrations/slack-manifest'
45

56
export const slackSearchOrganizationQuerySchema = z.object({ organizationId: organizationIdSchema })
67
export const slackSearchInstallationSchema = z.object({
@@ -71,7 +72,7 @@ export const prepareSlackSearchContract = defineRouteContract({
7172
existingApp: z
7273
.object({ appId: z.string().min(1).max(200), teamId: z.string().min(1).max(200) })
7374
.nullable(),
74-
createAppUrl: z.string().url().max(30_000),
75+
createAppUrl: z.string().url().max(SLACK_APP_CREATION_URL_MAX_LENGTH),
7576
}),
7677
},
7778
})

‎apps/sim/lib/integrations/slack-manifest.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
const SLACK_APP_NAME_MAX_LENGTH = 35
2+
export const SLACK_APP_CREATION_URL_MAX_LENGTH = 30_000
23

34
/** Opens Slack's app creation flow with the generated manifest already filled in. */
45
export function buildSlackAppCreationUrl(manifest: string): string {

0 commit comments

Comments
 (0)