Skip to content

Comments

Use a single room per server-user pair for events#3910

Open
IanCal wants to merge 53 commits intomainfrom
cs-9552-refactor-realm-event-sending-to-use-realm-server-session
Open

Use a single room per server-user pair for events#3910
IanCal wants to merge 53 commits intomainfrom
cs-9552-refactor-realm-event-sending-to-use-realm-server-session

Conversation

@IanCal
Copy link
Contributor

@IanCal IanCal commented Jan 27, 2026

Currently we require that every realm-user pair has a unique room.

Instead, we can have a single server user, and a single dm room for events between the server and user. Indexing events have realm URLs added so that the host can correctly identify which realm to update.

Since users have just one session room, this has been added as a column on the users table and the session_rooms table has been removed.

We also now only notify users that have read or write access to a realm if they are explicitly identified in the permissions.

Most of the changes are in tests to make sure that users are created and have the right access, partly to handle the hard coded details in the realm server about owners.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7cd147b2c3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 76 to 80
'JOIN realm_user_permissions rup',
'ON rup.username = sr.matrix_user_id',
'WHERE rup.realm_url =',
param(realmURL),
'AND (rup.read = true OR rup.write = true)',

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Include public permissions when selecting session rooms

This query now only returns session rooms for users that have explicit realm_user_permissions rows (it joins on rup.username = sr.matrix_user_id). For realms that are world‑readable via the '*' permission row, users who only have public access will not match this join, so fetchAllSessionRooms returns no rooms for them. Because NodeAdapter.broadcastRealmEvent relies on this mapping, those public users will stop receiving realm events (e.g. incremental index invalidations) even though they can read the realm. This regression happens specifically for realms that are readable via '*' but have no per‑user permission rows.

Useful? React with 👍 / 👎.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Only specifically mentioned users with read or write access are now going to be notified of updates. This is an expected and OK change. Pinging all users if we change catalog could be a huge issue, and should be solved in a different way so this drop of functionality is expected.

@github-actions
Copy link

Preview deployments

@IanCal IanCal marked this pull request as draft January 27, 2026 15:08
@github-actions
Copy link

github-actions bot commented Jan 27, 2026

Host Test Results

    1 files  ±    0      1 suites  ±0   5h 56m 13s ⏱️ + 4h 17m 38s
1 849 tests +   12  1 794 ✅  -    30  13 💤 ± 0   1 ❌ + 1  41 🔥 +41 
3 671 runs  +1 819  3 562 ✅ +1 723  26 💤 +13  42 ❌ +42  41 🔥 +41 

For more details on these failures and errors, see this check.

Results for commit 9086d4f. ± Comparison against base commit c9b3642.

This pull request removes 9 and adds 21 tests. Note that renamed tests count towards both.
Chrome ‑ Acceptance | interact submode tests > 1 stack: clicking a linked file opens it as a new isolated stack item
Chrome ‑ Integration | card-basics > cards allowed to be edited: linksTo FileDef renders without editor controls in edit format
Chrome ‑ Integration | card-basics > cards allowed to be edited: linksToMany FileDef renders without editor controls in edit format
Chrome ‑ Unit | index-writer: can get compiled module and source from WIP index
Chrome ‑ Unit | index-writer: can get compiled module and source when requested with file extension
Chrome ‑ Unit | index-writer: can get compiled module and source when requested without file extension
Chrome ‑ Unit | index-writer: can get error doc for module
Chrome ‑ Unit | index-writer: can perform invalidations for a module entry
Chrome ‑ Unit | index-writer: returns undefined when getting a deleted module
Chrome ‑ Acceptance | code submode | head format preview: does not show warning when head template only has allowed tags
Chrome ‑ Acceptance | code submode | head format preview: shows warning when head template contains disallowed tags
Chrome ‑ Acceptance | code submode | inspector tests: "in-this-file" panel displays FileDef declarations with correct labeling
Chrome ‑ Acceptance | code submode | inspector tests: Schema/Playground/Spec panes render for a focused FileDef declaration
Chrome ‑ Acceptance | file chooser tests: can link a file via the chooser
Chrome ‑ Acceptance | file chooser tests: clicking a linked file opens it as a new isolated stack item
Chrome ‑ Acceptance | file chooser tests: file chooser filters by type when field is ImageDef
Chrome ‑ Acceptance | file chooser tests: file chooser shows all files when field is FileDef
Chrome ‑ Global error: Uncaught Error: intentional error thrown at http://localhost:7357/assets/chunk.b1e276f78ce231c0029c.js, line 93736  While executing test: Integration | Store: can capture error when auto saving 
Chrome ‑ Integration | card-basics > cards allowed to be edited: linksTo FileDef renders editor controls in edit format
…

♻️ This comment has been updated with latest results.

@IanCal IanCal marked this pull request as ready for review February 17, 2026 16:57
@IanCal IanCal requested review from a team and lukemelia February 17, 2026 17:04
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 289cf14ced

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +1898 to +1908
const content = event.content as RealmEventContent;
if (!content.realmURL) {
realmEventsLogger.debug(
'Ignoring realm event because no realm found',
'Ignoring realm event because no realm URL was provided',
event,
);
} else {
if (realmResourceForEvent.info?.realmUserId !== event.sender) {
realmEventsLogger.warn(
`Realm event sender ${event.sender} is not the realm user ${realmResourceForEvent.info?.realmUserId}`,
event,
);
}

(event.content as any).origin_server_ts = event.origin_server_ts;
this.messageService.relayRealmEvent(
realmResourceForEvent.url,
event.content as RealmEventContent,
);
return;
}

(content as any).origin_server_ts = event.origin_server_ts;
this.messageService.relayRealmEvent(content);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Reject realm events from non-session rooms

processDecryptedEventFromAuthRoom now relays any APP_BOXEL_REALM_EVENT_TYPE event as long as content.realmURL exists, but this path is reached for every non-AI room event. That means a participant in any unrelated DM/group room can send a crafted realm event and trigger invalidations for whatever realm URL the client is subscribed to. Previously this code first resolved event.room_id to a known session room before relaying, so removing that check introduces spoofable cross-room realm updates.

Useful? React with 👍 / 👎.

Comment on lines +41 to +44
if (rows.length === 0) {
throw new Error(
`Cannot set session room for user ${matrixUserId}: user does not exist in the users table`,
);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Handle missing users when persisting session rooms

upsertSessionRoom now throws when the matrix user has no users row, and Realm's /_session login flow calls this path during session creation. For first-time/non-provisioned matrix users, this turns session creation into a 500 instead of issuing a JWT (or a controlled 4xx), which is a regression from the previous upsert behavior that created session-room mappings independently of users rows.

Useful? React with 👍 / 👎.

Copy link
Contributor

@habdelra habdelra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good. I assume this change is not backwards compatible, meaning that we'll need to abandon AI conversations that were created from before this is merged?

@IanCal
Copy link
Contributor Author

IanCal commented Feb 18, 2026

looks good. I assume this change is not backwards compatible, meaning that we'll need to abandon AI conversations that were created from before this is merged?

I think it's mostly backwards compatible, this doesn't touch how the ai conversations work, and the session rooms are (relatively) ephemeral anyway. If the session room we create for login is in existing users dms then they should already be in the room we'll use for indexing events, if not they won't get them until they get a new jwt.

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.

2 participants