Skip to content

Conversation

@ricardogarim
Copy link
Contributor

@ricardogarim ricardogarim commented Oct 14, 2025

Changes:

  • Makes the federation invite route return 403 when shouldProcessInvite fails validation.
    • Introduces a NotAllowedError custom error.
    • Updates Elysia error responses for federated endpoints to use FederationErrorResponseDto.
  • Adds support for the m.room.encryption Matrix event and enables propagation of the homeserver.matrix.encryption event.
  • Adds settings for allowedEncryptedRooms and allowedNonPrivateRooms to control invite behavior.

Related to RocketChat/Rocket.Chat#37227.

Summary by CodeRabbit

  • New Features

    • Configurable invite policy: enable/disable invites to encrypted and non‑private rooms via environment variables; runtime access to invite config exposed.
    • Federation event support: homeserver now emits encryption events for downstream notification/processing.
    • SDK error type: NotAllowedError exposed for blocked invite scenarios.
    • Room/encryption event schema: encryption event content added to public types.
  • Bug Fixes / API

    • Invite route returns standardized federation-style 403/500 payloads for rejections and errors.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 14, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

Adds invite configuration and enforcement for encrypted/public rooms, exports NotAllowedError, maps that error to 403 in the homeserver invite controller, introduces a federation error DTO, wires invite config into the homeserver module, emits m.room.encryption events from staging-area, and extends room event schemas/types to include encryption.

Changes

Cohort / File(s) Summary
Federation SDK index
packages/federation-sdk/src/index.ts
Export NotAllowedError; extend HomeserverEventSignatures with 'homeserver.matrix.encryption' carrying { event_id, event: PduForType<'m.room.encryption'> }.
Invite config (SDK)
packages/federation-sdk/src/services/config.service.ts
Add AppConfig.invite with allowedEncryptedRooms and allowedNonPrivateRooms; extend AppConfigSchema; add ConfigService.getInviteConfig().
Invite service
packages/federation-sdk/src/services/invite.service.ts
Add exported NotAllowedError; add private shouldProcessInvite(event) to check room encryption/public flags against config and throw when disallowed; call it at start of processInvite.
Staging-area handling
packages/federation-sdk/src/services/staging-area.service.ts
Emit homeserver.matrix.encryption with { event_id, event } when receiving m.room.encryption PDUs (in addition to existing emissions).
Room service typing
packages/federation-sdk/src/services/room.service.ts
Use inferred residentServer type when calling federationService.makeJoin (removed as string cast).
Homeserver invite controller
packages/homeserver/src/controllers/federation/invite.controller.ts
Import NotAllowedError; wrap processInvite in try/catch; map NotAllowedError → 403 (M_FORBIDDEN) and other errors → 500 (M_UNKNOWN); update route response schemas and handler signature to include set.
Federation error DTOs
packages/homeserver/src/dtos/federation/error.dto.ts, packages/homeserver/src/dtos/index.ts
Add runtime FederationErrorResponseDto (errcode enum + error string) and re-export it from central DTO index.
Homeserver config wiring
packages/homeserver/src/homeserver.module.ts
Add invite config block populated from env vars INVITE_ALLOWED_ENCRYPTED_ROOMS and INVITE_ALLOWED_NON_PRIVATE_ROOMS.
Room types: encryption
packages/room/src/types/v3-11.ts
Add PduEncryptionEventContentSchema, internal EventPduTypeRoomEncryption, include m.room.encryption in PduStateEventSchema union and related type checks.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Controller as HomeserverController
  participant InviteService
  participant Config as ConfigService

  Client->>Controller: POST /federation/invite (member PDU)
  Controller->>InviteService: processInvite(event, ...)
  InviteService->>Config: getInviteConfig()
  Config-->>InviteService: {allowedEncryptedRooms, allowedNonPrivateRooms}
  alt Disallowed by config
    InviteService-->>Controller: throw NotAllowedError
    Controller-->>Client: 403 { errcode: M_FORBIDDEN, error }
  else Allowed
    InviteService-->>Controller: ProcessInviteResponseDto
    Controller-->>Client: 200 ProcessInviteResponseDto
  end
Loading
sequenceDiagram
  participant StagingArea
  participant EventBus
  participant Consumers

  StagingArea->>StagingArea: receive PDU
  alt PDU.type == "m.room.encryption"
    StagingArea->>EventBus: emit homeserver.matrix.encryption { event_id, event }
  else PDU.type == "m.room.message" or "m.room.encrypted"
    StagingArea->>EventBus: emit existing events (message/encrypted)
  end
  EventBus-->>Consumers: dispatch event
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • ggazzo
  • sampaiodiego

Poem

"A rabbit hops through code so spry,
Sniffs encrypted rooms up high.
Guards the invite with careful paw,
Says 403 when rules it saw.
Hops off with logs and one big carrot 🥕"

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title concisely describes the primary fix for federation invites, namely enabling invites to non-private or encrypted rooms through configurable settings, which aligns with the main changeset.

📜 Recent 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 cecfffb and 6c1db76.

📒 Files selected for processing (10)
  • packages/federation-sdk/src/index.ts (2 hunks)
  • packages/federation-sdk/src/services/config.service.ts (3 hunks)
  • packages/federation-sdk/src/services/invite.service.ts (3 hunks)
  • packages/federation-sdk/src/services/room.service.ts (1 hunks)
  • packages/federation-sdk/src/services/staging-area.service.ts (1 hunks)
  • packages/homeserver/src/controllers/federation/invite.controller.ts (2 hunks)
  • packages/homeserver/src/dtos/federation/error.dto.ts (1 hunks)
  • packages/homeserver/src/dtos/index.ts (1 hunks)
  • packages/homeserver/src/homeserver.module.ts (1 hunks)
  • packages/room/src/types/v3-11.ts (3 hunks)

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@codecov-commenter
Copy link

codecov-commenter commented Oct 14, 2025

Codecov Report

❌ Patch coverage is 80.00000% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 60.55%. Comparing base (2a0357e) to head (6c1db76).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
...ages/federation-sdk/src/services/config.service.ts 50.00% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #280      +/-   ##
==========================================
+ Coverage   60.46%   60.55%   +0.09%     
==========================================
  Files          67       67              
  Lines        6673     6691      +18     
==========================================
+ Hits         4035     4052      +17     
- Misses       2638     2639       +1     

☔ 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.

@ricardogarim ricardogarim force-pushed the fix/block-encrypted-and-non-private-rooms-join branch 2 times, most recently from 53687fc to 7faaf02 Compare October 15, 2025 14:22
@ricardogarim ricardogarim marked this pull request as ready for review October 15, 2025 14:40
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: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/room/src/types/v3-11.ts (1)

788-796: Remove m.room.encryption from timeline event types.

m.room.encryption is a state event, not a timeline event. Including it in isTimelineEventType is incorrect and will cause improper event handling.

Apply this diff:

 export function isTimelineEventType(type: PduType) {
 	return (
 		type === 'm.room.message' ||
 		type === 'm.room.encrypted' ||
-		type === 'm.room.encryption' ||
 		type === 'm.reaction' ||
 		type === 'm.room.redaction'
 	);
 }
📜 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 2a0357e and 7faaf02.

📒 Files selected for processing (10)
  • packages/federation-sdk/src/index.ts (2 hunks)
  • packages/federation-sdk/src/services/config.service.ts (3 hunks)
  • packages/federation-sdk/src/services/invite.service.ts (3 hunks)
  • packages/federation-sdk/src/services/room.service.ts (2 hunks)
  • packages/federation-sdk/src/services/staging-area.service.ts (1 hunks)
  • packages/homeserver/src/controllers/federation/invite.controller.ts (2 hunks)
  • packages/homeserver/src/dtos/federation/error.dto.ts (1 hunks)
  • packages/homeserver/src/dtos/index.ts (1 hunks)
  • packages/homeserver/src/homeserver.module.ts (1 hunks)
  • packages/room/src/types/v3-11.ts (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (5)
packages/federation-sdk/src/services/staging-area.service.ts (2)
packages/room/src/manager/event-wrapper.ts (2)
  • event (129-138)
  • roomId (101-103)
packages/room/src/manager/v3.ts (1)
  • eventId (17-29)
packages/federation-sdk/src/services/invite.service.ts (2)
packages/room/src/manager/event-wrapper.ts (1)
  • event (129-138)
packages/room/src/types/_common.ts (1)
  • PduForType (26-26)
packages/federation-sdk/src/index.ts (1)
packages/room/src/types/_common.ts (2)
  • EventID (8-8)
  • PduForType (26-26)
packages/room/src/types/v3-11.ts (1)
packages/room/src/manager/event-wrapper.ts (1)
  • type (97-99)
packages/homeserver/src/controllers/federation/invite.controller.ts (4)
packages/homeserver/src/middlewares/isAuthenticated.ts (1)
  • isAuthenticatedMiddleware (4-71)
packages/federation-sdk/src/services/invite.service.ts (1)
  • NotAllowedError (28-33)
packages/homeserver/src/dtos/federation/invite.dto.ts (1)
  • ProcessInviteResponseDto (12-14)
packages/homeserver/src/dtos/federation/error.dto.ts (2)
  • FederationErrorResponseDto (3-11)
  • FederationErrorResponseDto (13-15)
🔇 Additional comments (11)
packages/federation-sdk/src/services/room.service.ts (1)

849-849: LGTM! Removing unnecessary type cast.

The removal of the as string type cast is a good change. It allows TypeScript to properly infer the type from extractDomainFromId, improving type safety.

packages/homeserver/src/dtos/federation/error.dto.ts (1)

1-15: LGTM! Clean federation error DTO implementation.

The schema properly defines the federation error response structure with appropriate error codes for Matrix protocol compliance.

packages/homeserver/src/dtos/index.ts (1)

15-15: LGTM! Proper DTO re-export.

The federation error DTO is correctly exported from the centralized DTO index.

packages/federation-sdk/src/services/staging-area.service.ts (1)

311-319: LGTM! Proper encryption event emission.

The m.room.encryption event handling follows the established pattern for other event types, with appropriate payload structure.

packages/federation-sdk/src/index.ts (2)

93-93: LGTM! NotAllowedError properly exported.

Exposing NotAllowedError enables consumers (like the homeserver invite controller) to handle invite rejection scenarios.


167-173: LGTM! Encryption event signature properly defined.

The homeserver.matrix.encryption event signature follows the established pattern with correct typing.

packages/federation-sdk/src/services/invite.service.ts (2)

28-33: LGTM! Clean error class definition.

The NotAllowedError properly extends Error with a descriptive name for invite rejection scenarios.


152-186: LGTM! Solid invite validation logic.

The shouldProcessInvite method correctly validates room properties against configuration:

  • Detects public rooms via join_rule check
  • Detects encrypted rooms via m.room.encryption state event
  • Applies config-driven policy to reject invites when appropriate

The rejection logic properly uses AND/OR operators to enforce both constraints.

packages/federation-sdk/src/services/config.service.ts (3)

34-37: LGTM! Invite config properly typed.

The invite configuration block is correctly defined in the AppConfig interface with clear boolean fields for encryption and privacy controls.


76-79: LGTM! Invite schema validation added.

The Zod schema properly validates the invite configuration structure, ensuring type safety at runtime.


124-126: LGTM! Clean accessor for invite config.

The getInviteConfig method provides type-safe access to the invite configuration.

@ricardogarim ricardogarim force-pushed the fix/block-encrypted-and-non-private-rooms-join branch 5 times, most recently from 6f04192 to 0af839b Compare October 15, 2025 15: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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/room/src/types/v3-11.ts (1)

788-796: Remove m.room.encryption from timeline event check.

m.room.encryption is a state event (with an empty state key), not a timeline event. Including it in isTimelineEventType is incorrect and inconsistent with the schema definition at lines 716-720 which correctly uses PduNoContentEmptyStateKeyStateEventSchema.

Apply this diff:

 export function isTimelineEventType(type: PduType) {
 	return (
 		type === 'm.room.message' ||
 		type === 'm.room.encrypted' ||
-		type === 'm.room.encryption' ||
 		type === 'm.reaction' ||
 		type === 'm.room.redaction'
 	);
 }
♻️ Duplicate comments (2)
packages/room/src/types/v3-11.ts (1)

540-545: Fix the schema - m.room.encryption is a state event, not an encrypted message.

The past review comment correctly identified that PduEncryptionEventContentSchema should NOT include a ciphertext field. According to the Matrix spec, m.room.encryption is a state event that configures encryption settings for a room, not an encrypted message event. The ciphertext field belongs to m.room.encrypted events (which already exists as EncryptedContentSchema at lines 520-538).

The content should include:

  • algorithm: The encryption algorithm (required)
  • rotation_period_ms: Optional rotation period in milliseconds
  • rotation_period_msgs: Optional rotation period in message count

Apply this diff:

 export const PduEncryptionEventContentSchema = z.object({
 	algorithm: z
 		.enum(['m.megolm.v1.aes-sha2'])
 		.describe('The algorithm used to encrypt the content.'),
-	ciphertext: z.string().describe('The encrypted content.'),
+	rotation_period_ms: z
+		.number()
+		.int()
+		.positive()
+		.optional()
+		.describe('How long the session should be used before changing it (in milliseconds).'),
+	rotation_period_msgs: z
+		.number()
+		.int()
+		.positive()
+		.optional()
+		.describe('How many messages should be sent before changing the session.'),
 });
packages/homeserver/src/controllers/federation/invite.controller.ts (1)

28-54: Use error.message instead of hard-coded text (per previous agreement).

Lines 38-43 hard-code the error message as 'This server does not allow joining this type of room based on federation settings.' despite previous review feedback where you explicitly agreed to use error.message to preserve the descriptive policy reason (e.g., "encrypted" vs "public"). The NotAllowedError carries specific context that federation clients need to understand why the invite was rejected.

Apply this diff:

 			} catch (error) {
 				if (error instanceof NotAllowedError) {
 					set.status = 403;
 					return {
 						errcode: 'M_FORBIDDEN',
-						error:
-							'This server does not allow joining this type of room based on federation settings.',
+						error: error.message,
 					};
 				}
 
 				set.status = 500;
 				return {
 					errcode: 'M_UNKNOWN',
 					error:
 						error instanceof Error
 							? error.message
 							: 'Internal server error while processing request',
 				};
 			}
📜 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 192685c and 0af839b.

📒 Files selected for processing (9)
  • packages/federation-sdk/src/index.ts (2 hunks)
  • packages/federation-sdk/src/services/config.service.ts (3 hunks)
  • packages/federation-sdk/src/services/invite.service.ts (3 hunks)
  • packages/federation-sdk/src/services/room.service.ts (1 hunks)
  • packages/homeserver/src/controllers/federation/invite.controller.ts (2 hunks)
  • packages/homeserver/src/dtos/federation/error.dto.ts (1 hunks)
  • packages/homeserver/src/dtos/index.ts (1 hunks)
  • packages/homeserver/src/homeserver.module.ts (1 hunks)
  • packages/room/src/types/v3-11.ts (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • packages/federation-sdk/src/services/config.service.ts
  • packages/federation-sdk/src/index.ts
  • packages/homeserver/src/homeserver.module.ts
  • packages/federation-sdk/src/services/room.service.ts
🧰 Additional context used
🧬 Code graph analysis (3)
packages/federation-sdk/src/services/invite.service.ts (1)
packages/federation-sdk/src/index.ts (4)
  • NotAllowedError (93-93)
  • PduForType (22-22)
  • PersistentEventBase (25-25)
  • RoomVersion (26-26)
packages/homeserver/src/controllers/federation/invite.controller.ts (4)
packages/homeserver/src/middlewares/isAuthenticated.ts (1)
  • isAuthenticatedMiddleware (4-71)
packages/federation-sdk/src/services/invite.service.ts (1)
  • NotAllowedError (28-33)
packages/homeserver/src/dtos/federation/invite.dto.ts (1)
  • ProcessInviteResponseDto (12-14)
packages/homeserver/src/dtos/federation/error.dto.ts (2)
  • FederationErrorResponseDto (3-11)
  • FederationErrorResponseDto (13-15)
packages/room/src/types/v3-11.ts (1)
packages/room/src/manager/event-wrapper.ts (1)
  • type (97-99)
🔇 Additional comments (7)
packages/homeserver/src/dtos/federation/error.dto.ts (1)

1-15: LGTM!

The FederationErrorResponseDto schema is correctly defined with appropriate Matrix error codes (M_UNRECOGNIZED, M_UNAUTHORIZED, M_FORBIDDEN, M_UNKNOWN) and follows Elysia conventions. The type alias is properly exported using Static<typeof>.

packages/federation-sdk/src/services/invite.service.ts (2)

28-33: LGTM!

The NotAllowedError class follows standard error class patterns and correctly extends Error with a descriptive name property.


196-196: LGTM!

The call to shouldProcessInvite is correctly placed at the start of processInvite to validate the invite before processing, and it's properly awaited.

packages/room/src/types/v3-11.ts (1)

716-720: LGTM!

The EventPduTypeRoomEncryption correctly uses PduNoContentEmptyStateKeyStateEventSchema since m.room.encryption is a state event with an empty state key. This addresses the previous review feedback.

packages/homeserver/src/dtos/index.ts (1)

15-15: LGTM!

The export for federation/error.dto is correctly placed alongside other federation DTO exports, making FederationErrorResponseDto publicly accessible.

packages/homeserver/src/controllers/federation/invite.controller.ts (2)

5-5: LGTM!

The imports are correctly organized, bringing in NotAllowedError from the federation-sdk and the necessary DTOs for error responses and request/response schemas.

Also applies to: 10-15


63-67: LGTM!

The response schema correctly maps status codes to their respective DTOs (200 → ProcessInviteResponseDto, 403/500 → FederationErrorResponseDto), providing proper OpenAPI documentation for the route.

@ricardogarim ricardogarim force-pushed the fix/block-encrypted-and-non-private-rooms-join branch from 0af839b to cecfffb Compare October 15, 2025 15:40
ggazzo
ggazzo previously approved these changes Oct 15, 2025
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: 2

♻️ Duplicate comments (2)
packages/room/src/types/v3-11.ts (1)

540-545: Fix the schema to match Matrix spec for m.room.encryption.

The PduEncryptionEventContentSchema still incorrectly includes a ciphertext field. According to the Matrix spec, m.room.encryption is a state event that configures encryption settings for a room, not an encrypted message event (which is m.room.encrypted at lines 710-714).

The content should only include:

  • algorithm: The encryption algorithm (required)
  • rotation_period_ms: Optional rotation period in milliseconds
  • rotation_period_msgs: Optional rotation period in message count

Apply this diff:

 export const PduEncryptionEventContentSchema = z.object({
 	algorithm: z
 		.enum(['m.megolm.v1.aes-sha2'])
 		.describe('The algorithm used to encrypt the content.'),
-	ciphertext: z.string().describe('The encrypted content.'),
+	rotation_period_ms: z
+		.number()
+		.int()
+		.positive()
+		.optional()
+		.describe('How long the session should be used before changing it (in milliseconds).'),
+	rotation_period_msgs: z
+		.number()
+		.int()
+		.positive()
+		.optional()
+		.describe('How many messages should be sent before changing the session.'),
 });
packages/federation-sdk/src/services/invite.service.ts (1)

152-186: Clarify the error message when multiple conditions are violated.

When both isRoomEncrypted and isRoomNonPrivate are true, the error message at Line 183 only mentions one reason. This could confuse federation clients about which policy was violated.

Consider building a list of violated reasons and including all applicable policy violations in the error message. For example:

 		const shouldRejectInvite =
 			(!allowedEncryptedRooms && isRoomEncrypted) ||
 			(!allowedNonPrivateRooms && isRoomNonPrivate);
 		if (shouldRejectInvite) {
+			const reasons = [];
+			if (!allowedEncryptedRooms && isRoomEncrypted) {
+				reasons.push('encrypted');
+			}
+			if (!allowedNonPrivateRooms && isRoomNonPrivate) {
+				reasons.push('public');
+			}
 			throw new NotAllowedError(
-				`Could not process invite due to room being ${isRoomEncrypted ? 'encrypted' : 'public'}`,
+				`Could not process invite due to room being ${reasons.join(' and ')}`,
 			);
 		}
📜 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 0af839b and cecfffb.

📒 Files selected for processing (10)
  • packages/federation-sdk/src/index.ts (2 hunks)
  • packages/federation-sdk/src/services/config.service.ts (3 hunks)
  • packages/federation-sdk/src/services/invite.service.ts (3 hunks)
  • packages/federation-sdk/src/services/room.service.ts (1 hunks)
  • packages/federation-sdk/src/services/staging-area.service.ts (1 hunks)
  • packages/homeserver/src/controllers/federation/invite.controller.ts (2 hunks)
  • packages/homeserver/src/dtos/federation/error.dto.ts (1 hunks)
  • packages/homeserver/src/dtos/index.ts (1 hunks)
  • packages/homeserver/src/homeserver.module.ts (1 hunks)
  • packages/room/src/types/v3-11.ts (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • packages/homeserver/src/homeserver.module.ts
  • packages/federation-sdk/src/index.ts
  • packages/homeserver/src/dtos/federation/error.dto.ts
  • packages/homeserver/src/dtos/index.ts
🧰 Additional context used
🧬 Code graph analysis (4)
packages/homeserver/src/controllers/federation/invite.controller.ts (4)
packages/homeserver/src/middlewares/isAuthenticated.ts (1)
  • isAuthenticatedMiddleware (4-71)
packages/federation-sdk/src/services/invite.service.ts (1)
  • NotAllowedError (28-33)
packages/homeserver/src/dtos/federation/invite.dto.ts (1)
  • ProcessInviteResponseDto (12-14)
packages/homeserver/src/dtos/federation/error.dto.ts (2)
  • FederationErrorResponseDto (3-11)
  • FederationErrorResponseDto (13-15)
packages/federation-sdk/src/services/invite.service.ts (3)
packages/federation-sdk/src/index.ts (4)
  • NotAllowedError (93-93)
  • PduForType (22-22)
  • PersistentEventBase (25-25)
  • RoomVersion (26-26)
packages/room/src/manager/event-wrapper.ts (1)
  • event (129-138)
packages/room/src/types/_common.ts (1)
  • PduForType (26-26)
packages/room/src/types/v3-11.ts (1)
packages/room/src/manager/event-wrapper.ts (1)
  • type (97-99)
packages/federation-sdk/src/services/staging-area.service.ts (2)
packages/room/src/manager/event-wrapper.ts (1)
  • event (129-138)
packages/room/src/manager/v3.ts (1)
  • eventId (17-29)
🔇 Additional comments (8)
packages/federation-sdk/src/services/staging-area.service.ts (1)

311-316: LGTM! Clean implementation of encryption event handling.

The new case for m.room.encryption follows the established pattern and appropriately emits a minimal event payload. This is correct for encryption setup events where consumers need the full event object to extract encryption parameters.

packages/federation-sdk/src/services/room.service.ts (1)

848-848: LGTM! Trailing comma follows best practices.

The trailing comma addition aligns with modern JavaScript/TypeScript conventions and makes future parameter additions cleaner in version control diffs.

packages/room/src/types/v3-11.ts (2)

716-720: LGTM!

The schema correctly uses PduNoContentEmptyStateKeyStateEventSchema, which is appropriate for m.room.encryption as it's a state event with an empty state key per the Matrix specification.


766-766: LGTM!

Correctly adds EventPduTypeRoomEncryption to PduStateEventSchema since m.room.encryption is a state event.

packages/federation-sdk/src/services/invite.service.ts (2)

28-33: LGTM!

The NotAllowedError class is correctly implemented as a custom error type for authorization failures during invite processing.


196-196: LGTM!

The call to shouldProcessInvite at the start of processInvite correctly enforces invite validation before proceeding with invite processing.

packages/homeserver/src/controllers/federation/invite.controller.ts (2)

28-54: LGTM!

The error handling implementation is correct:

  • NotAllowedError returns 403 with M_FORBIDDEN errcode and a generic policy message (as confirmed by the maintainer).
  • Other errors return 500 with M_UNKNOWN errcode and the actual error message for debugging.

63-67: LGTM!

The response schema definitions correctly document the possible response types (200, 403, 500) using the appropriate DTOs.

Comment on lines +34 to +37
invite: {
allowedEncryptedRooms: boolean;
allowedNonPrivateRooms: boolean;
};
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

🧩 Analysis chain

Verify test coverage for the new invite configuration.

The implementation follows existing patterns and is correct. However, the codecov report indicates that this file has 50% patch coverage with 4 missing lines.

Please ensure that the new invite configuration block and the getInviteConfig() method have adequate test coverage. You can run the following script to check which lines are missing coverage:

Also applies to: 76-79, 124-126


🏁 Script executed:

#!/bin/bash
# Description: Check test coverage for config.service.ts

# Find and display test files for config.service
fd -e spec.ts -e test.ts config.service

# Check if the invite config is tested
rg -nP "getInviteConfig|invite.*config" --type=ts -g '*test*' -g '*spec*'

Length of output: 0


🏁 Script executed:

#!/bin/bash
# Search for config.service usages and config getters in test files
rg -n "config.service" -g "*spec.ts" -g "*test.ts"
rg -n "getDatabaseConfig" -g "*spec.ts" -g "*test.ts"
rg -n "getMediaConfig" -g "*spec.ts" -g "*test.ts"
rg -n "getInviteConfig" -g "*spec.ts" -g "*test.ts"

Length of output: 347


Add unit tests for the new invite configuration

No tests currently cover getInviteConfig() or the invite block in config.service.ts; please add spec tests to exercise those code paths and restore full coverage.

🤖 Prompt for AI Agents
In packages/federation-sdk/src/services/config.service.ts around lines 34 to 37,
there are no unit tests covering getInviteConfig() or the invite configuration
block; add Jest spec tests that import ConfigService (or the module exposing
getInviteConfig), mock the underlying configuration/source to supply variations,
and assert the returned invite object shape and values. Create tests for:
default behavior when invite is missing, explicit true/false values for
allowedEncryptedRooms and allowedNonPrivateRooms, and any edge/invalid inputs
the service tolerates; use beforeEach to set/restore config mocks and expect
exact booleans to restore coverage for these code paths.

@ricardogarim ricardogarim force-pushed the fix/block-encrypted-and-non-private-rooms-join branch from cecfffb to 6c1db76 Compare October 15, 2025 15:46
@ggazzo ggazzo merged commit 72ec1a0 into main Oct 15, 2025
2 of 3 checks passed
@ggazzo ggazzo deleted the fix/block-encrypted-and-non-private-rooms-join branch October 15, 2025 15:47
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