Skip to content

Normalize Slack-shaped OAuth token exchange payloads - #1346

Merged
kody-bot merged 1 commit into
mainfrom
cursor/slack-token-exchange-shape-c0a2
Aug 9, 2026
Merged

kody-bot merged 1 commit into
mainfrom
cursor/slack-token-exchange-shape-c0a2

Conversation

@kentcdodds

@kentcdodds kentcdodds commented Aug 9, 2026 •

Copy link
Copy Markdown
Owner

What

Two small normalizations in the host-side /connect/oauth token exchange, in oauth-token-exchange.ts + handleOAuthExchangeAction:

  1. authed_user hoisting. Slack's oauth.v2.access nests user tokens under authed_user β€” top-level access_token is the bot token, and is absent entirely for user-scope-only apps. The exchange response now hoists access_token / refresh_token / expires_in / token_type / scope from authed_user to the standard top-level names when the top level lacks a token, never overwriting present fields. Standard OAuth payloads pass through untouched (same object identity).
  2. ok: false soft failures. Slack reports token-endpoint failures as { ok: false, error } with HTTP 200; these now map to the standard exchange-failure response (502 + provider error string) instead of surfacing downstream as a confusing "payload did not include an access_token".

Why

Community data shows @kody/slack is the most-adopted integration package (4 forks, 2 stars) β€” each fork today means a user registering their own Slack app. This unblocks a platform (built-in) Slack app configured with user_scope via extraAuthorizeParams, keeping token persistence provider-agnostic downstream.

Testing

Unit tests for both helpers (user-scope-only hoisting, bot-token non-overwrite, standard payload passthrough, soft-failure detection). npm run validate green.

Open in WebΒ Open in CursorΒ 

Summary by CodeRabbit

  • Bug Fixes
    • Improved OAuth token exchange handling for Slack-style responses.
    • Preserved valid top-level tokens while recovering tokens nested in user details.
    • Correctly identifies soft failures returned with successful HTTP responses.
    • Supports standard, tokenless, and failure payloads without altering their expected structure.

Slack's oauth.v2.access nests user tokens under authed_user (top-level
access_token is the bot token, absent entirely for user-scope-only
apps) and reports failures as { ok: false, error } with HTTP 200. The
exchange handler now hoists the nested token fields to the standard
top-level names (never overwriting present ones) and maps ok:false
payloads to the standard exchange-failure response, so a platform
Slack app configured with user_scope via extraAuthorizeParams works
end to end without provider-specific code downstream.

Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
@coderabbitai

coderabbitai Bot commented Aug 9, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. πŸŽ‰

ℹ️ Recent review info
βš™οΈ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: c71d591d-80ed-47c3-afac-2587e51e0d46

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between f3895ae and 95507e7.

πŸ“’ Files selected for processing (3)
  • packages/worker/src/app/handlers/account-secrets.ts
  • packages/worker/src/integrations/oauth-token-exchange.node.test.ts
  • packages/worker/src/integrations/oauth-token-exchange.ts

πŸ“ Walkthrough

Walkthrough

The OAuth token exchange flow now detects { ok: false } soft failures, normalizes Slack nested token payloads, and returns standardized errors or normalized provider responses.

Changes

OAuth response handling

Layer / File(s) Summary
OAuth payload helpers and validation
packages/worker/src/integrations/oauth-token-exchange.ts, packages/worker/src/integrations/oauth-token-exchange.node.test.ts
The helper hoists Slack OAuth fields from authed_user when no valid top-level token exists. It preserves existing values and detects ok: false responses. Tests cover both behaviors.
Account secrets integration
packages/worker/src/app/handlers/account-secrets.ts
The handler maps OAuth soft failures to standardized errors and normalizes successful payloads before returning provider status.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant OAuthProvider
  participant AccountSecretsHandler
  participant OAuthPayloadHelpers
  OAuthProvider->>AccountSecretsHandler: return token exchange payload
  AccountSecretsHandler->>OAuthPayloadHelpers: detect soft failure
  OAuthPayloadHelpers-->>AccountSecretsHandler: return classification
  AccountSecretsHandler->>OAuthPayloadHelpers: normalize successful payload
  OAuthPayloadHelpers-->>AccountSecretsHandler: return normalized payload
Loading

Possibly related PRs

  • kentcdodds/kody#979: Refactors the OAuth integration used by this token exchange flow.
  • kentcdodds/kody#1303: Modifies the OAuth exchange helper and account secrets handler for exchange request styles and platform integrations.
πŸš₯ Pre-merge checks | βœ… 5
βœ… Passed checks (5 passed)
Check name Status Explanation
Title check βœ… Passed The title clearly and concisely describes the main change: normalization of Slack-shaped OAuth token exchange payloads.
Description check βœ… Passed The description explains the intent, summarizes the changes, and documents testing; the optional System changes section is not required.
Docstring Coverage βœ… Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check βœ… Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check βœ… Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
πŸ“ Generate docstrings
  • Create stacked PR
  • Commit on current branch
πŸ§ͺ Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cursor/slack-token-exchange-shape-c0a2

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.

@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

πŸ”Ž Preview deployed: https://kody-pr-1346.kody-a99.workers.dev

Worker: kody-pr-1346
D1: kody-pr-1346-db
KV: kody-pr-1346-oauth-kv

Mocks:

@kody-bot
kody-bot merged commit 07279cc into main Aug 9, 2026
10 checks passed
@kody-bot
kody-bot deleted the cursor/slack-token-exchange-shape-c0a2 branch August 9, 2026 17:43
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.

3 participants