Skip to content

Conversation

@ricardogarim
Copy link
Contributor

@ricardogarim ricardogarim commented Sep 19, 2025

Summary by CodeRabbit

  • Refactor
    • Streamlined the internal creation of room initialization events using a dedicated factory, reducing duplication and potential inconsistencies.
    • Improves maintainability and reliability without altering user-facing behavior.
    • No changes to room creation flows or existing functionality; everything continues to work as before.
    • This refactor prepares the codebase for easier future enhancements while keeping current features stable.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 19, 2025

Walkthrough

Refactors two call sites in room.service to create m.room.create events via PersistentEventFactory.newCreateEvent(creatorUserId, version) instead of manually constructing the event with newEvent<'m.room.create'>(...). The returned roomCreateEvent (with roomId and eventId) is then used as before; surrounding logic remains unchanged.

Changes

Cohort / File(s) Summary
Room create factory refactor
packages/federation-sdk/src/services/room.service.ts
Replace manual newEvent<'m.room.create'>({...}) payload construction with PersistentEventFactory.newCreateEvent(creatorUserId, PersistentEventFactory.defaultRoomVersion) at two call sites; subsequent usage of roomCreateEvent unchanged.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Caller
  participant RoomService
  participant PersistentEventFactory
  participant EventStore

  Caller->>RoomService: createRoom(...)
  RoomService->>PersistentEventFactory: newCreateEvent(creatorUserId, version)
  PersistentEventFactory-->>RoomService: roomCreateEvent (roomId, eventId, content)
  RoomService->>EventStore: persist(roomCreateEvent)
  EventStore-->>RoomService: ack
  RoomService-->>Caller: result (includes roomId/eventId)
  Note over RoomService,PersistentEventFactory: Changed: uses newCreateEvent instead of manual newEvent payload
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Poem

A rabbit taps keys with delight,
Swapping builders for factories right.
No payloads to craft,
Just newCreateEvent draft—
Hop! Room IDs shine in the light. 🐇✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title clearly and concisely describes the primary change: replacing the generic create-room call with the newCreateEvent factory for DM room creation, which matches the refactor in the diff where m.room.create constructions were replaced by PersistentEventFactory.newCreateEvent; it is specific, actionable, and free of noise.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/create-dm-room

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov-commenter
Copy link

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 81.01%. Comparing base (99347aa) to head (4d109a2).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #205   +/-   ##
=======================================
  Coverage   81.01%   81.01%           
=======================================
  Files          63       63           
  Lines        4692     4692           
=======================================
  Hits         3801     3801           
  Misses        891      891           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@ggazzo ggazzo merged commit 19bcb9b into main Sep 19, 2025
2 of 3 checks passed
@ggazzo ggazzo deleted the fix/create-dm-room branch September 19, 2025 02:04
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 99347aa and 4d109a2.

📒 Files selected for processing (1)
  • packages/federation-sdk/src/services/room.service.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
packages/federation-sdk/src/services/room.service.ts (2)
packages/core/src/events/m.room.create.ts (1)
  • roomCreateEvent (26-43)
packages/room/src/manager/factory.ts (1)
  • PersistentEventFactory (37-144)

Comment on lines +1197 to 1200
const roomCreateEvent = PersistentEventFactory.newCreateEvent(
creatorUserId,
PersistentEventFactory.defaultRoomVersion,
);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

🧩 Analysis chain

Swap to PersistentEventFactory.newCreateEvent looks correct; add a guard to ensure local creator and avoid bad roomId domains

newCreateEvent derives the roomId domain from creatorUserId. If creatorUserId is not local or contains a port/IPv6 (e.g., @U:example.org:8448), we may create a room hosted on the wrong “resident” server, which breaks subsequent logic that assumes a locally hosted room. Add a defensive check before creating the room.

Apply near this call:

@@
-    const stateService = this.stateService;
+    const stateService = this.stateService;
+    // Ensure the DM is created on this server; prevents room_id domain mismatch
+    const creatorServerName = creatorUserId.split(':').slice(1).join(':');
+    if (creatorServerName !== localServerName) {
+      throw new HttpException('Creator must be a local user to create a DM room on this server', HttpStatus.BAD_REQUEST);
+    }
 
-    const roomCreateEvent = PersistentEventFactory.newCreateEvent(
+    const roomCreateEvent = PersistentEventFactory.newCreateEvent(
       creatorUserId,
       PersistentEventFactory.defaultRoomVersion,
     );

Optional follow‑up: consider extending newCreateEvent to accept an explicit domain/serverName to avoid inferring it from a userId string.

Run to verify no remaining call sites use newEvent<'m.room.create'> and to inspect DM room creation call sites:


🏁 Script executed:

#!/bin/bash
rg -nP --type=ts "PersistentEventFactory\.newEvent<\s*'m\.room\.create'"
rg -n --type=ts -C3 "createDirectMessageRoom\("

Length of output: 1350


🏁 Script executed:

#!/bin/bash
# Show the implementation of createDirectMessageRoom to confirm where newCreateEvent is called and context variables
awk 'NR>=1170 && NR<=1250' packages/federation-sdk/src/services/room.service.ts || echo "File not found"

Length of output: 2083


🏁 Script executed:

#!/bin/bash
set -euo pipefail
echo "Searching for PersistentEventFactory..."
rg -n --hidden "PersistentEventFactory" || true

echo
echo "Locating file that defines the factory..."
file=$(rg -n --hidden "export class PersistentEventFactory|class PersistentEventFactory" --hidden --files-with-matches | head -n1 || true)
echo "Found: $file"
if [ -n "$file" ]; then
  echo
  echo "Showing file contents around newCreateEvent..."
  rg -n "newCreateEvent" "$file" -n -N -S || true
  sed -n '1,240p' "$file"
fi

Length of output: 11441


Require creator to be local before calling PersistentEventFactory.newCreateEvent

newCreateEvent derives the room_id domain from the creator string (packages/room/src/manager/factory.ts uses creator.split(':').pop()). createDirectMessageRoom calls it without verifying the creator is local (packages/federation-sdk/src/services/room.service.ts ≈ line 1197) — this can produce a room hosted on the wrong server. Add a defensive guard.

@@
-    const stateService = this.stateService;
+    const stateService = this.stateService;
+    // Ensure the DM is created on this server; prevents room_id domain mismatch
+    const creatorServerName = creatorUserId.split(':').slice(1).join(':');
+    if (creatorServerName !== localServerName) {
+      throw new HttpException('Creator must be a local user to create a DM room on this server', HttpStatus.BAD_REQUEST);
+    }
 
-    const roomCreateEvent = PersistentEventFactory.newCreateEvent(
+    const roomCreateEvent = PersistentEventFactory.newCreateEvent(
       creatorUserId,
       PersistentEventFactory.defaultRoomVersion,
     );

Optional: extend newCreateEvent to accept an explicit serverName to avoid inferring the domain.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In packages/federation-sdk/src/services/room.service.ts around lines 1197-1200,
the code calls PersistentEventFactory.newCreateEvent(creatorUserId, ...) without
ensuring the creator is a local user, which lets newCreateEvent infer the
room_id domain from a non-local creator and can produce a room hosted on the
wrong server; add a defensive guard that verifies the creatorUserId is local
(use the existing isLocalUser/isLocalMxid utility or compare the MXID domain to
the local server name) and throw or return an error if not local before calling
newCreateEvent, or alternatively refactor to call newCreateEvent with an
explicit serverName parameter (update factory signature and call sites) so the
room domain is not inferred from the creator.

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.

4 participants