Skip to content

fix(comms): closing the inbox stops new DMs from earlier blast recipients - #1036

Merged
dylanjeffers merged 1 commit into
mainfrom
fix/inbox-closed-blast-replies
Sep 10, 2026
Merged

fix(comms): closing the inbox stops new DMs from earlier blast recipients#1036
dylanjeffers merged 1 commit into
mainfrom
fix/inbox-closed-blast-replies

Conversation

@dylanjeffers

Copy link
Copy Markdown
Contributor

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:

  1. chat.create bypasses 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.
  2. 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 require blast.created_at > blaster's latest chat_permissions.updated_at.
  • chat_allowed(): in the existing-chat clause, blast messages only count if newer than to_user's latest settings change. Non-blast messages count as before, so real conversations keep working.
  • updatePermissions: the upsert now refreshes updated_at on conflict so "latest change" is accurate for checkbox-style updates too.
  • recheck_permissions is also set when a chat's latest message is a blast, so the web/mobile composer consults current_user_has_permission instead of assuming the thread grants access.

Unchanged behavior: blasting while the inbox is closed still lets recipients reply to that blast (existing TestChatBlastFollowers expectation), and a new blast sent after closing re-opens replies to it.

sql/01_schema.sql carries the same function body because CI builds the test template from the dump rather than running migrations.

Test

New TestChatBlastThenCloseInbox covers: 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 previous chat_allowed at the two leak points and passes with the fix. Full ./api/comms and ./api chat/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

…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>
@dylanjeffers
dylanjeffers merged commit 86c0628 into main Sep 10, 2026
2 checks passed
@dylanjeffers
dylanjeffers deleted the fix/inbox-closed-blast-replies branch September 10, 2026 20:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant