Skip to content

Conversation

@yuriassuncx
Copy link
Contributor

@yuriassuncx yuriassuncx commented Oct 8, 2025

Summary by CodeRabbit

  • New Features

    • Guided Slack connect flow with a selection page showing workspace, user, and channels (shows up to 50) before continuing.
    • Configure access permissions: pick specific channels or grant all current and future channels.
    • Dark/light theme toggle with saved preference.
    • Option to specify a custom bot name during setup.
  • Improvements

    • Clearer messages when permissions already exist to avoid overwrites.
    • More robust error handling and structured feedback tied to your installation.

yuriassuncx and others added 16 commits September 25, 2025 12:19
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
…tart loader for custom bot handling, and improve UI for bot selection page
@github-actions
Copy link
Contributor

github-actions bot commented Oct 8, 2025

Tagging Options

Should a new tag be published when this PR is merged?

  • 👍 for Patch 0.128.2 update
  • 🎉 for Minor 0.129.0 update
  • 🚀 for Major 1.0.0 update

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 8, 2025

Walkthrough

Reworks Slack OAuth flows: callback becomes stateful and permission-aware (handles savePermission/continue paths, validates and stores permissions, or proceeds to token exchange and workspace/user/channel fetch), adds permission types and a selection UI generator/template, and simplifies the OAuth start loader to always return a redirect to Slack authorization URL.

Changes

Cohort / File(s) Summary
Slack OAuth callback
slack/actions/oauth/callback.ts
Converts callback to a stateful, multi-path handler: adds State decoding and StateProvider, OAuthTokenResponse, permission helpers (hasExistingPermissions, createPermissionExistsError), branches for savePermission/continue vs token exchange, validates permission payloads, performs token exchange and Slack API fetches (team/users/conversations), returns HTML via generateSelectionPage or structured JSON/errors.
OAuth start loader
slack/loaders/oauth/start.ts
Simplifies start to a single synchronous function that builds OAuth auth params and returns a redirect to Slack; removes request/CORS/session handling and drops botName from Props.
Public API types
slack/mod.ts
Adds SlackPermission type and extends Props with permission?, account?, and customBotName? (doc annotations updated).
Selection page generator
slack/utils/ui-templates/page-generator.ts
New generateSelectionPage and supporting types (SlackWorkspace, SlackChannel, SlackUser, SelectionPageOptions); dynamic HTML generator with channel listing, theming, client-side handlers for skip/confirm selection and payload encoding, plus a fallback page generator.
Selection HTML template
slack/utils/ui-templates/selection-page.template.html
Adds a full HTML template used by the generator: placeholders for workspace/user/channels, theme toggle, inline JS to parse data, construct base64 permission payload, and navigate with savePermission/continue flags.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant B as Browser
  participant S as App Server (callback)
  participant SL as Slack API

  Note over S: Request includes code + state (+ optional savePermission/continue/permissions)

  B->>S: GET /oauth/callback?code&state(&savePermission|continue|permissions)
  S->>S: decodeState(state)
  alt savePermission path
    S->>S: decode & validate permissions payload
    S->>S: hasExistingPermissions? -> maybe createPermissionExistsError
    S-->>B: JSON { installId, account?, permission? } or error
  else continue or initial presentation
    S->>SL: oauth.v2.access(code)
    SL-->>S: OAuthTokenResponse (access_token, authed_user, team, bot, ...)
    S->>SL: team.info / users.info / conversations.list (using tokens)
    SL-->>S: workspace, user, channels
    S->>S: generateSelectionPage(workspace, channels, user, callbackUrl)
    S-->>B: 200 HTML (selection UI)
  end
Loading
sequenceDiagram
  autonumber
  participant Client as Caller
  participant S as App Server (start)

  Note over S: New simplified start(props) -> redirect

  Client->>S: start(props: { clientId, redirectUri, state })
  S->>S: build authParams (scopes, client_id, redirect_uri, state)
  S-->>Client: 302 -> https://slack.com/oauth/v2/authorize?...state=...
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • viktormarinho
  • mcandeia

Poem

I nibbled the state, a crunchy string,
Hopped through tokens, fetched everything.
Channels like carrots, stacked in a row,
Light and dark meadows where selections grow.
Click “Configure” or “Continue” — hop! onward we go.

Pre-merge checks and finishing touches

❌ Failed checks (3 warnings)
Check name Status Explanation Resolution
Title Check ⚠️ Warning The pull request title “Hotfix(Slack): Improve Slack Custom Bot Flow” focuses narrowly on a custom bot bug fix, but the changeset introduces a comprehensive stateful OAuth flow, permission management, UI selection pages, and major public API expansions, so it does not accurately or concisely summarize the main change. Rename the pull request to reflect the primary change, for example “Implement stateful Slack OAuth callback flow with permission selection UI” to clearly summarize the new multi‐path OAuth and UI enhancements.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Description Check ⚠️ Warning The pull request description is currently just the deno-fmt-ignore-file placeholder and does not include any of the required template sections such as a brief summary of changes, an issue link, a Loom video link, or a demonstration link. Please complete the pull request description by providing a concise explanation of the proposed changes, linking to the related issue, including a Loom screencast URL, and supplying a demonstration environment or branch link.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

🧹 Nitpick comments (2)
slack/actions/oauth/callback.ts (2)

100-105: Improve type safety in permission check.

The hasExistingPermissions function uses a loose type check and Object.keys() that could yield false positives. An empty object would pass the check even though it has no meaningful permissions.

Consider a more specific check:

 function hasExistingPermissions(permission: unknown): boolean {
   if (!permission || typeof permission !== "object" || permission === null) {
     return false;
   }
-  return Object.keys(permission as Record<string, unknown>).length > 0;
+  const p = permission as { workspace?: unknown; channels?: unknown; allCurrentAndFutureChannels?: boolean };
+  return !!(p.workspace || p.channels || p.allCurrentAndFutureChannels);
 }

266-268: Document the 50-channel limit.

The hardcoded limit of 50 channels (line 266) is mentioned in comments and the UI ("Showing first 50 channels"), but the business logic rationale isn't documented. Consider whether pagination or a configurable limit would better serve workspaces with many channels.

Add a constant with documentation:

const MAX_CHANNELS_FOR_DISPLAY = 50;

// Fetch channels (limit to first 50 for display)
const channelsResponse = await fetch(
  "https://slack.com/api/conversations.list",
  {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${tokenData.access_token}`,
      "Content-Type": "application/x-www-form-urlencoded",
    },
    body: new URLSearchParams({
      limit: MAX_CHANNELS_FOR_DISPLAY.toString(),
      types: "public_channel,private_channel",
    }),
  },
);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5d1e5fd and c5ba6e2.

📒 Files selected for processing (4)
  • slack/actions/oauth/callback.ts (1 hunks)
  • slack/mod.ts (2 hunks)
  • slack/utils/ui-templates/page-generator.ts (7 hunks)
  • slack/utils/ui-templates/selection-page.template.html (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
slack/actions/oauth/callback.ts (4)
slack/mod.ts (3)
  • Props (57-123)
  • State (125-131)
  • AppContext (133-133)
slack/loaders/oauth/start.ts (1)
  • Props (10-19)
slack/utils/state-helpers.ts (1)
  • decodeState (6-13)
slack/utils/ui-templates/page-generator.ts (1)
  • generateSelectionPage (31-703)
slack/mod.ts (1)
mcp/bindings.ts (1)
  • Callbacks (9-13)
🪛 GitHub Actions: ci
slack/utils/ui-templates/selection-page.template.html

[error] 471-632: Deno fmt --check failed. Found 1 not formatted file in 2077 files. Run 'deno fmt' to fix formatting issues in this file.

🔇 Additional comments (3)
slack/mod.ts (1)

44-55: LGTM!

The SlackPermission interface is well-structured and clearly defines the permission model for workspace and channel access.

slack/actions/oauth/callback.ts (2)

4-24: LGTM!

The OAuthTokenResponse interface accurately models the Slack OAuth v2 token response structure.


288-296: No changes needed for callback URL
URLSearchParams.set("savePermission", "true") retains all existing query parameters and only overrides the specified key.

Likely an incorrect or invalid review comment.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c5ba6e2 and 7820221.

📒 Files selected for processing (1)
  • slack/loaders/oauth/start.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
slack/loaders/oauth/start.ts (3)
slack/mod.ts (1)
  • Props (57-110)
slack/actions/oauth/callback.ts (1)
  • Props (26-69)
slack/utils/constants.ts (2)
  • SCOPES (1-17)
  • OAUTH_URL_AUTH (21-21)

- Add comprehensive validation for base64 permissions data in callback.ts
- Implement proper error handling for parallel Slack API fetches
- Fix Unicode-safe base64 encoding in page-generator.ts
- Correct workspace domain display in selection-page.template.html
- Clean up fallback page HTML structure
- Run deno fmt on selection-page.template.html for proper formatting
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7820221 and f63f544.

📒 Files selected for processing (3)
  • slack/actions/oauth/callback.ts (1 hunks)
  • slack/utils/ui-templates/page-generator.ts (1 hunks)
  • slack/utils/ui-templates/selection-page.template.html (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • slack/utils/ui-templates/selection-page.template.html
🧰 Additional context used
🧬 Code graph analysis (1)
slack/actions/oauth/callback.ts (4)
slack/loaders/oauth/start.ts (1)
  • Props (3-7)
slack/mod.ts (3)
  • Props (57-110)
  • State (112-118)
  • AppContext (120-120)
slack/utils/state-helpers.ts (1)
  • decodeState (6-13)
slack/utils/ui-templates/page-generator.ts (1)
  • generateSelectionPage (31-715)

@mcandeia mcandeia merged commit 71aa6eb into deco-cx:main Oct 9, 2025
3 checks passed
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