Repository navigation
fix(slack): judge a Slack bind by its secret reference, not an object that is always there - #1875
Merged
Merged
Conversation
… that is always there Every new Slack install on commonly.me has been refused at "Authorize in Slack" since #1537: POST /api/installables/slack/authorize-url answers 409 slack_already_authorized on a row that holds no bind. `config.pendingBind` is a nested schema path, so the hydrated document carries it as `{}` even when the stored row has none, and the route read it by truthiness. The confirm and reject routes had the same read inverted, so `slack_bind_missing` could never fire and they went on to a CAS keyed on an undefined botTokenRef. All three now ask whether the callback stored a bind, by the botTokenRef it always writes. The $exists filters in the CAS updates read the stored row and were already right. The existing suite could not see this: it mocks Integration with plain objects, where an absent key is absent. The new tests hand the routes a real `Integration.hydrate(...)` document, the shape findOne returns, and three of them fail on main. The two screenshots are the stranger walk on 9a32fca at 1200 and 390 after the 409: the page names nothing. That is a separate frontend row. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RUTWqLu6zhFPraoPHZcjQP
This was referenced Sep 25, 2026
lilyshen0722
added a commit
to thantiklermcirony/commonly
that referenced
this pull request
Oct 9, 2026
…rule the Slack defect earned (Team-Commonly#1877) * docs: the 09-25 stranger walk of GitHub, Slack and Telegram, and the rule the Slack defect earned The readiness matrix gains the walk's per-cell results and corrects two rows it had wrong: Slack was recorded as stable while every new install was refused at Authorize in Slack (fixed in Team-Commonly#1875), and GitHub was recorded as disabled while it has been live on our own repository since 09-18. Review-checklist rule 34 is rule 24's inverse: a hand-built fixture also lies about absence, because a nested schema path hydrates as {} on every document. Checked on mongoose 7.8.6: schema.path() is undefined for the nested path, schema.nested[] is true, the hydrated value is {} and truthy, and toJSON drops it, which is why no API response ever showed it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RUTWqLu6zhFPraoPHZcjQP * docs(plans): GitHub C9 expiry is green and C4 lapsed unverified Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RUTWqLu6zhFPraoPHZcjQP --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No one can connect Slack on commonly.me, and no one has been able to since #1537 (09-04). Found in the stranger walk for the readiness matrix on build
9a32fca5: Add → Connect (install 200) → Authorize in Slack →POST /api/installables/slack/authorize-url→409 slack_already_authorized, "Slack is already awaiting confirmation or connected." It happens on a fresh install whose stored row has nochatIdand nopendingBind.Cause
config.pendingBindis a nested schema path (models/Integration.ts), so a hydrated document carries it as{}even when the stored row has none. The route read it by truthiness (installables.ts:169), so every row looked already bound. I proved it in the running backend pod with the compiled model on the stranger's row, which givesdoc.config.pendingBind → {}, truthy.The confirm and reject routes had the same read inverted:
if (!pending)could never fire, soslack_bind_missingwas unreachable and they went on to a CAS keyed on an undefinedbotTokenRef.Fix
All three sites now ask
hasPendingBind(config), meaning whether the callback stored a bind, judged by thebotTokenRefit always writes. The$existsfilters in the CAS updates read the stored row and were already right, so they are unchanged.Why the suite missed it, and the test
slackOAuth.installables.test.jsmocksIntegrationwith plain objects, where an absent key really is absent. The new block hands the routes a realIntegration.hydrate(...)document, the shapefindOnereturns in production:pendingBind(if a schema change ends that, the tests below stop proving anything)slack_bind_missingand write nothing: red on mainMutation-checked: with
routes/installables.tsrestored fromorigin/main, 3 of the 5 new tests fail and the other 11 pass. With the fix, 14/14 pass.eslint routes/installables.tsis clean.Not in this PR
After the 409 the page names nothing: the Slack row stays on "Authorize in Slack" at 1200 and 390, with no error rendered. The two screenshots under
docs/design/evidence/slack-authorize-409/are that "before" pair. The page fix is a separate frontend row in the Connectors lane (Kai, after Row A).Gate: Vera.
🤖 Generated with Claude Code
https://claude.ai/code/session_01RUTWqLu6zhFPraoPHZcjQP