fix: Slack integration reliability, security hardening, and UX improvements#88
fix: Slack integration reliability, security hardening, and UX improvements#88
Conversation
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
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the 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 configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (8)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
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)
available: falseinstead of showing a scary error alert to end users who can't fix server configurationAlert/AlertCircleimports fromNotificationChannelsPanel.tsxSecurity hardening
validateHost()utility with fail-closed allowlist againstREPLIT_DOMAINSto prevent host-header injection in Slack OAuth install and callback flowsprocess.env.REPLIT_DOMAINSdirect usage with validated host in OAuth redirect URI constructionisValidEncryptedToken()validation before storing encrypted Slack bot tokensunavailableReasonfrom two specific values ("setup_incomplete","not_configured") to a single generic"unavailable"to avoid leaking infrastructure stategetSlackConnection()in try-catch in the status endpoint so DB failures return 500 instead of hanging the requestArchitecture
registerRoutes()intoserver/services/ensureTables.ts(single source of truth for startup table creation)channelTablesExist()runtime guard tonotificationReady.tswith permanent positive cachingchannelTablesExist()checksReact.lazy) — only downloaded for Power-plan usersProtectedRouteredirects to/dashboardon tier mismatch instead of showingLandingPage(previously indistinguishable from being logged out)Scraper improvements
/stealthendpoint andencodeURIComponentfor Browserless API tokenSec-CH-UA,Sec-CH-UA-Mobile,Sec-CH-UA-Platform)Other
client/src/lib/date-format.ts(formatDate,formatTime,formatDateTime)storage.tsfor 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 definitionsclient/src/lib/date-format.test.ts: 7 tests — date/time formatting with edge casesserver/routes.notificationChannels.test.ts: +1 test —getSlackConnectionerror propagationnotificationReady.test.ts,hostValidation.test.ts,encryption.test.ts,scraper.test.ts,migration.test.tsHow to test
SLACK_CLIENT_IDfrom 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)SLACK_CLIENT_IDandSLACK_CLIENT_SECRET, restart — the Slack section should appear with "Connect to Slack" button/developer— should redirect to/dashboardinstead of showing the landing pageHostheader not inREPLIT_DOMAINS— should return 400notificationChannelsinshared/schema.tswithout updatingensureTables.ts— the schema sync test should failnpm run test— all 1062 tests passhttps://claude.ai/code/session_017WdTqmNUwoVYvsgEDoLrHK