Skip to content

[Feat] Create the Slack app from a pasted app configuration token#417

Merged
brunobergher merged 6 commits into
developfrom
feat/slack-config-token-app-creation
Jul 16, 2026
Merged

[Feat] Create the Slack app from a pasted app configuration token#417
brunobergher merged 6 commits into
developfrom
feat/slack-config-token-app-creation

Conversation

@mrubens

@mrubens mrubens commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Why this PR exists

  • I am a maintainer / this is internal Roomote work

What changed

Slack setup used to open a prefilled manifest in Slack's UI and then flip into manual mode so the user could copy three secrets across. From the user's chair, setup goes from "create app in one tab, hunt through Slack settings, three copy-pastes, save, connect" to "click Generate on one Slack page, paste one token, approve the install."

  • The Slack setup step (wizard, bootstrap, and Settings → Communications) now shows one App configuration token field with a link to api.slack.com/apps and two lines of instructions.
  • A new admin-gated tRPC command (slack.createAppFromManifest, plus a setup-token-gated setupBootstrap.createSlackAppFromManifest variant for the bootstrap wizard) builds the manifest with the existing buildSlackAppManifest({ publicOrigin }), POSTs it to Slack's apps.manifest.create, and on success upserts R_SLACK_CLIENT_ID, R_SLACK_CLIENT_SECRET, and R_SLACK_SIGNING_SECRET in one transaction (same pattern as the GitHub App manifest flow). The config token is used once and never stored.
  • On success the UI advances straight to the Connect to Slack install step — no "now go find your credentials" interlude.
  • Both escape hatches stay: Enter values manually, and the prefilled-manifest link as a secondary path for anyone who'd rather not generate a config token.
  • Error handling maps cleanly to the token field: invalid_auth/expired-token errors get an actionable "generate a fresh token" message, and manifest problems surface Slack's structured errors array with pointers.
  • The mock Slack harness gains a POST apps.manifest.create route with its own acceptedConfigTokens allowlist (config tokens are a different token space than bot tokens), optional manifestCredentials overrides, and created manifests recorded in /mock/state, so the whole flow is testable without a real workspace. The route is reachable via the existing SLACK_API_BASE_URL routing.
  • Docs: the Slack provider page's "Fast path" now documents the token flow with the prefilled manifest as the alternative; the mock-slack-testing skill documents the new harness knobs.

How it was tested

  • New unit tests for the command: success (manifest content, routed URL, Bearer header, single-transaction upsert of the three env vars), token errors, structured manifest errors, incomplete credentials, non-JSON responses, and non-admin rejection.
  • New mock-server tests: create with a config token + manifest recorded in state, invalid_auth for unknown config tokens (HTTP 200 + ok: false, matching real Slack), and invalid_manifest for malformed manifests.
  • Updated/added UI tests for the wizard and Settings surfaces (token field shown by default, create button disabled until a token is entered, prefilled-manifest link flips to manual mode, token success invalidates status and advances, failures toast without advancing).
  • 308 slack-package + 541 web tests in the affected areas pass; pnpm lint, pnpm check-types, and pnpm knip are clean.
  • Not exercised: a live click-through against the full dev stack. The ordering risk around Slack probing the webhook before the signing secret persists is unchanged relative to the current flow (the app exists in Slack long before the secret lands today), and the API flow shrinks that window from minutes to milliseconds.

Checklist

  • The PR title follows the repo convention: [Fix], [Feat], [Improve], [Refactor], [Docs], or [Chore] followed by a user-facing description
  • This PR is small and scoped to one change
  • pnpm lint and pnpm check-types pass locally
  • I added tests or included a clear manual validation note above
  • I removed secrets, tokens, private keys, and customer data from code, logs, and screenshots
  • If this change should appear in the changelog, I ran pnpm changeset

Slack setup previously opened a prefilled manifest in Slack's UI and made
the user copy three secrets back by hand. The setup and settings surfaces
now take a Slack app configuration token instead: an admin-gated tRPC
command (plus a setup-token-gated bootstrap variant) builds the existing
manifest, POSTs it to apps.manifest.create, persists R_SLACK_CLIENT_ID,
R_SLACK_CLIENT_SECRET, and R_SLACK_SIGNING_SECRET in one transaction, and
the UI advances straight to the Connect to Slack install step. The config
token is used once and never stored.

Enter values manually and the prefilled-manifest link remain as fallback
paths. The mock Slack harness gains an apps.manifest.create route with a
separate config-token allowlist so the whole flow is testable without a
real workspace.
@roomote-roomote

roomote-roomote Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

No new code issues found. See task

  • apps/web/src/trpc/commands/slack/create-app-from-manifest.ts:156 — If Slack creates the app but the following database transaction fails, the command returns an error without deleting the new app. Retrying creates another app while the first remains in the workspace with credentials that Roomote discarded; compensate with apps.manifest.delete (using the same config token and appId) or provide an explicit recovery path.
  • apps/web/src/app/(onboarding)/setup/ProviderSetupExperience.tsx:448 — Back and Create app manually remain active while creation is pending. A user can switch paths and save manual credentials while the create request is persisting its credentials, so the writes race; the create success can also replace the manual view with the finish step. Disable these alternate actions for the lifetime of createSlackAppPending.
  • apps/web/src/components/settings/CommsProviderSection.tsx:523 — Automatic Slack app creation still invalidates only comms.status; the new environmentVariables.list invalidation was added to repairTelegram instead. The Environment Variables settings can therefore keep showing its cached pre-creation list.
  • packages/slack/src/mock-slack-server.ts:646 — A string manifest is accepted after any successful JSON.parse, so truthy values such as [], 1, or "text" are recorded and return ok: true even though this route promises an invalid_manifest response unless the manifest is a JSON object. Apply the same non-null object/non-array check after parsing that the direct-object branch already uses.
  • apps/web/src/app/(onboarding)/setup/ProviderSetupExperience.tsx:660 — Slack's prefilled-manifest guidance is rendered unconditionally inside GenericSetupExperience, which is also used for every provider other than Slack and Microsoft. Telegram, Discord, and other setup screens therefore tell users to create an app in Slack; render this fallback only for Slack's manual path.
  • apps/web/src/components/settings/CommsProviderSection.tsx:516 — The creation success stores appSettingsUrl and then refreshes comms.status, but the resulting savedSatisfied change triggers the reset effect at line 568 and clears that URL. In the real Settings flow the new logo instructions disappear as soon as the status refetch completes; preserve the URL across that expected provider-state update.
  • apps/web/src/trpc/commands/slack/create-app-from-manifest.ts:191 — If the compensating apps.manifest.delete request rejects at the transport layer, cleanupCreatedApp throws into the outer catch and returns only the raw network error. The app remains orphaned, but the user loses the app ID and manual-deletion recovery guidance.
  • apps/web/src/components/settings/CommsProviderSection.tsx:586createdSlackAppSettingsUrl is now cleared only when provider.id changes. Removing Slack credentials keeps the same keyed section mounted, so the stale URL continues to short-circuit SlackSetupExperience into “Your Slack app is ready” instead of restoring setup.

Reviewed bed1a9d

@brunobergher brunobergher merged commit d2c2ba2 into develop Jul 16, 2026
17 checks passed
@brunobergher brunobergher deleted the feat/slack-config-token-app-creation branch July 16, 2026 11:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants