fix(comms): closing the inbox stops new DMs from earlier blast recipients - #1036
Merged
Conversation
…ents An artist who sent a blast and later turned off "Allow Messages from Everyone" kept getting new DMs. Two paths let any blast recipient through regardless of the artist's current inbox settings: - chat.create skipped the receiver's inbox settings whenever the receiver had ever blasted the sender, with no regard for settings changed after the blast. - chat_allowed treated a thread holding nothing but the blast seed as an "existing chat", so a recipient who had opened the blast could message the artist at any later time. A blast now grants reply rights only while it is newer than the blaster's most recent inbox settings change. Real conversations are untouched, blasting while closed still lets recipients reply (existing test), and a fresh blast after closing re-opens replies to that blast. Also: an upserted chat_permissions row now refreshes updated_at, and a chat whose latest message is a blast reports recheck_permissions so clients consult the other member's current settings before showing the composer. Co-Authored-By: Claude Fable 5.1 <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.
Problem
Reported in Slack: a user turned off "Allow Messages from Everyone" (nothing checked, i.e.
none) and kept receiving new DMs.Inbox settings were honored for cold outreach, but two paths ignored them for anyone the artist had ever blasted:
chat.createbypasses the receiver's inbox settings when the receiver has a blast reaching the sender (hasNewBlastFromUser). That check looked at the sender's last permission change only, so a blast from any time in the past kept the door open forever.chat_allowed()treats any thread with a message as an "existing chat". A recipient who opened a blast into a thread but never replied has a thread holding only the blast seed, which counted, so they could message the artist later regardless of settings.For an artist with a large follower base who has blasted at least once, that is effectively every follower.
Fix
A blast only grants reply rights while it is newer than the blaster's most recent inbox settings change ("last change wins", mirroring the rule already applied on the recipient side):
hasNewBlastFromUser: also requireblast.created_at> blaster's latestchat_permissions.updated_at.chat_allowed(): in the existing-chat clause, blast messages only count if newer thanto_user's latest settings change. Non-blast messages count as before, so real conversations keep working.updatePermissions: the upsert now refreshesupdated_aton conflict so "latest change" is accurate for checkbox-style updates too.recheck_permissionsis also set when a chat's latest message is a blast, so the web/mobile composer consultscurrent_user_has_permissioninstead of assuming the thread grants access.Unchanged behavior: blasting while the inbox is closed still lets recipients reply to that blast (existing
TestChatBlastFollowersexpectation), and a new blast sent after closing re-opens replies to it.sql/01_schema.sqlcarries the same function body because CI builds the test template from the dump rather than running migrations.Test
New
TestChatBlastThenCloseInboxcovers: recipient can't start a thread off an old blast, seed-only thread grants no reply rights, real conversation keeps working, new blast while closed re-opens, closing again shuts it. Verified the test fails against the previouschat_allowedat the two leak points and passes with the fix. Full./api/commsand./apichat/blast suites pass.Not verified against prod data (no DB access from this session), so this is the code-level cause consistent with the report; existing real conversations continuing after closing the inbox is still by design.
🤖 Generated with Claude Code