Skip to content

fix: Slack integration reliability, security hardening, and UX improvements#88

Merged
bd73-com merged 4 commits intomainfrom
claude/fix-recurring-issue-DWVEU
Mar 7, 2026
Merged

fix: Slack integration reliability, security hardening, and UX improvements#88
bd73-com merged 4 commits intomainfrom
claude/fix-recurring-issue-DWVEU

Conversation

@bd73-com
Copy link
Owner

@bd73-com bd73-com commented Mar 6, 2026

Summary

Fixes the recurring "Slack integration is not available" error that users see when Slack credentials aren't configured server-side. The root cause was the UI showing an alarming error alert instead of simply hiding the Slack section. This PR also hardens the Slack OAuth flow against host-header injection, prevents schema drift between DDL migrations and Drizzle definitions, and improves the Developer page tier-gating UX.

This addresses issues from PRs #82, #83, #85 which each attempted to fix the Slack availability message but only improved error wording rather than fixing the fundamental UX problem.

Changes

Slack UI (core fix)

  • Hide the entire Slack notification section when the server reports available: false instead of showing a scary error alert to end users who can't fix server configuration
  • Remove unused Alert/AlertCircle imports from NotificationChannelsPanel.tsx

Security hardening

  • Add validateHost() utility with fail-closed allowlist against REPLIT_DOMAINS to prevent host-header injection in Slack OAuth install and callback flows
  • Replace process.env.REPLIT_DOMAINS direct usage with validated host in OAuth redirect URI construction
  • Add isValidEncryptedToken() validation before storing encrypted Slack bot tokens
  • Collapse unavailableReason from two specific values ("setup_incomplete", "not_configured") to a single generic "unavailable" to avoid leaking infrastructure state
  • Wrap getSlackConnection() in try-catch in the status endpoint so DB failures return 500 instead of hanging the request

Architecture

  • Extract inline DDL migrations from registerRoutes() into server/services/ensureTables.ts (single source of truth for startup table creation)
  • Add channelTablesExist() runtime guard to notificationReady.ts with permanent positive caching
  • Guard all notification channel and Slack integration routes with channelTablesExist() checks
  • Lazy-load the Developer page (React.lazy) — only downloaded for Power-plan users
  • ProtectedRoute redirects to /dashboard on tier mismatch instead of showing LandingPage (previously indistinguishable from being logged out)

Scraper improvements

  • Add stealth evasion (navigator.webdriver, plugins, permissions patches) for Browserless sessions
  • Use /stealth endpoint and encodeURIComponent for Browserless API token
  • Add Client Hints headers (Sec-CH-UA, Sec-CH-UA-Mobile, Sec-CH-UA-Platform)

Other

  • Standardize date/time formatting across the app via client/src/lib/date-format.ts (formatDate, formatTime, formatDateTime)
  • Remove "API Docs" link from public navigation
  • Defensive deletion in storage.ts for partially-migrated databases (swallows only "relation" errors)

Tests (19 new tests)

  • server/services/ensureTables.test.ts: 11 tests — startup migration functions + schema sync assertions comparing DDL columns against Drizzle schema definitions
  • client/src/lib/date-format.test.ts: 7 tests — date/time formatting with edge cases
  • server/routes.notificationChannels.test.ts: +1 test — getSlackConnection error propagation
  • Existing test suites expanded: notificationReady.test.ts, hostValidation.test.ts, encryption.test.ts, scraper.test.ts, migration.test.ts

How to test

  1. Slack section hidden when not configured: Remove SLACK_CLIENT_ID from env vars, visit a monitor's notification channels panel as a Pro/Power user — the Slack section should not appear at all (no error, no alert, just absent)
  2. Slack section visible when configured: Set SLACK_CLIENT_ID and SLACK_CLIENT_SECRET, restart — the Slack section should appear with "Connect to Slack" button
  3. Tier mismatch redirect: Log in as a non-Power user and navigate to /developer — should redirect to /dashboard instead of showing the landing page
  4. Host validation: Attempt Slack install with a spoofed Host header not in REPLIT_DOMAINS — should return 400
  5. Schema sync test: Add a column to notificationChannels in shared/schema.ts without updating ensureTables.ts — the schema sync test should fail
  6. Full test suite: npm run test — all 1062 tests pass

https://claude.ai/code/session_017WdTqmNUwoVYvsgEDoLrHK

claude added 4 commits March 6, 2026 17:49
Instead of showing a scary "Slack integration is not available" error
to end users (who cannot fix server configuration), hide the entire
Slack section when the backend reports available=false. This stops the
recurring cycle of "improving" the error message (#82, #83, #85).

https://claude.ai/code/session_017WdTqmNUwoVYvsgEDoLrHK
- ensureTables.test.ts: 8 tests covering all 3 startup migration
  functions (happy path, error handling, console logging)
- date-format.test.ts: 7 tests covering formatDate, formatTime,
  formatDateTime with edge cases (midnight, single-digit padding)
- notificationChannels: add test verifying unhandled getSlackConnection
  error propagates (no try-catch in status endpoint)

https://claude.ai/code/session_017WdTqmNUwoVYvsgEDoLrHK
- Collapse unavailableReason from "setup_incomplete"/"not_configured"
  to a single generic "unavailable" to avoid leaking infrastructure
  state to authenticated users
- Wrap getSlackConnection() in try-catch so a DB failure returns 500
  instead of hanging the request as an unhandled async rejection

https://claude.ai/code/session_017WdTqmNUwoVYvsgEDoLrHK
- ProtectedRoute now redirects to /dashboard instead of showing the
  landing page when an authenticated user doesn't have the required
  tier. Previously indistinguishable from being logged out.

- Add schema sync assertions in ensureTables.test.ts that compare the
  DDL column names in ensureChannelTables() against the Drizzle schema
  definitions. If either side drifts, the test fails — preventing the
  root cause of the recurring Slack integration bug.

https://claude.ai/code/session_017WdTqmNUwoVYvsgEDoLrHK
@github-actions github-actions bot added fix security Security fix labels Mar 6, 2026
@coderabbitai
Copy link

coderabbitai bot commented Mar 6, 2026

Warning

Rate limit exceeded

@bd73-com has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 14 minutes and 2 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: ba061ea8-d1fc-4ad3-bc77-a624af726f7c

📥 Commits

Reviewing files that changed from the base of the PR and between ff1b7f0 and 052cd83.

📒 Files selected for processing (8)
  • client/src/App.tsx
  • client/src/components/NotificationChannelsPanel.tsx
  • client/src/hooks/use-slack.ts
  • client/src/lib/date-format.test.ts
  • server/routes.notificationChannels.test.ts
  • server/routes.ts
  • server/services/ensureTables.test.ts
  • shared/routes.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch claude/fix-recurring-issue-DWVEU

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.

@bd73-com bd73-com merged commit e9d7850 into main Mar 7, 2026
2 checks passed
@bd73-com bd73-com deleted the claude/fix-recurring-issue-DWVEU branch March 7, 2026 09:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fix security Security fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants