chore(sync): merge upstream main back into dev - #26
Conversation
A Slack channel currently has to carry its own bot token and signing secret, so a deployment serving several Slack workspaces must create one app per channel, and a channel whose secret is absent silently accepts unsigned deliveries. - config gains deployment-wide slack.clientId/clientSecret/botToken/ signingSecret (SLACK_* environment aliases follow the existing Discord pattern); config.ResolveSlack resolves per channel with the deployment-wide values as the fallback - the inbound webhook verifies deliveries against whatever secret resolves - channel first, deployment-wide second - and warn-logs every rejected delivery with the channel id and where the verifying secret came from, so a channel bound to a second Slack app is diagnosable the moment the fallback secret appears - outbound replies fall back to the deployment-wide bot token the same way, so a shared app can post on behalf of every channel - tests: SlackApp precedence, ResolveSlack before Load, and an inbound delivery signed with the deployment secret being accepted on a channel that carries none
feat(slack): deployment-wide Slack app credentials and webhook hardening
Add English UI screenshots under screenshots/en/ and point the English README.md at them, so README.md shows English UI while README_ZH.md keeps the original Chinese screenshots. Co-authored-by: Confetti Labs <confetti-labs@users.noreply.github.com>
docs: use English screenshots in README
…2026-09-25 # Conflicts: # .env.example # internal/pkg/config/config.go # internal/pkg/config/runtime.go # internal/services/slack_inbound_service_test.go # internal/services/slack_outbound_service.go
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
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 |
There was a problem hiding this comment.
Code Review
This pull request updates screenshot asset paths in the README, cleans up imports and whitespace in the Slack services, and adds a new test to verify that Slack inbound channels fall back to the deployment-wide signing secret. The feedback recommends capturing and restoring the existing global configuration in the test's defer block rather than setting it to nil, preventing potential side effects on other tests.
| config.SetCurrent(&config.Config{Slack: config.SlackConfig{SigningSecret: slackTestSigningSecret}}) | ||
| defer config.SetCurrent(nil) |
There was a problem hiding this comment.
Unconditionally setting the global configuration to nil in defer can break other tests in the same package if they run sequentially and rely on a previously initialized configuration. It is safer to capture the existing configuration and restore it when the test finishes.
| config.SetCurrent(&config.Config{Slack: config.SlackConfig{SigningSecret: slackTestSigningSecret}}) | |
| defer config.SetCurrent(nil) | |
| oldConfig := config.GetCurrent() | |
| config.SetCurrent(&config.Config{Slack: config.SlackConfig{SigningSecret: slackTestSigningSecret}}) | |
| defer config.SetCurrent(oldConfig) |
Summary
Periodic sync after upstream merged huabeitech#51 (the Slack deployment-wide credentials + webhook hardening port, originally authored here) and huabeitech#52 (community docs PR - English screenshots).
Conflict resolution notes:
TestSlackInboundFallsBackToDeploymentSigningSecretand the fork'sTestVerifySlackSignatureEnforcesReplayWindowdrift table)firstNonBlankand the config resolver suite deduped; env example kept the fork's fuller Meta/Slack documentation blocksNo upstream file or test dropped (verified post-commit).
DB_TYPEstays out of prod .env per the 2026-09-25 sqlite incident.Validation
Full Go suite green with
go test -tags devacross the CI package list; vet clean; frontend typecheck clean.📌 TL;DR
This PR implements a fallback mechanism for Slack webhook signature verification, allowing channels without a specific signing secret to use the deployment-wide configuration. It also includes minor import and whitespace cleanups in related Slack service files.
🎯 Type of Change
🔍 Changes Walkthrough
internal/services/slack_inbound_service.gointernal/services/slack_inbound_service_test.goTestSlackInboundFallsBackToDeploymentSigningSecretto verify that webhooks signed with the global deployment secret are accepted when a channel lacks a specific secret.internal/services/slack_outbound_service.goprocessOutboxfunction for code cleanliness.📊 Architectural Flow
sequenceDiagram participant Slack as Slack Platform participant Service as SlackInboundService participant Channel as Channel Model participant Config as Global Config Slack->>Service: Webhook Request (Timestamp, Signature, Payload) Service->>Channel: Get Channel by ID alt Channel has specific SigningSecret Service->>Service: Verify Signature using Channel Secret else Channel SigningSecret is empty Service->>Config: Get Deployment-wide SigningSecret Service->>Service: Verify Signature using Deployment Secret end Service->>Service: Process Event if Valid