Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import type { StateMapKey } from '@hs/room';
import type { PersistentEventBase } from '@hs/room';

export type StateStore = {
_id: ObjectId;
delta: {
identifier: StateMapKey;
eventId: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ import {
GetMissingEventsBodyDto,
GetMissingEventsParamsDto,
GetMissingEventsResponseDto,
GetStateIdsParamsDto,
GetStateIdsQueryDto,
GetStateIdsResponseDto,
GetStateParamsDto,
GetStateQueryDto,
GetStateResponseDto,
MakeJoinParamsDto,
MakeJoinQueryDto,
MakeJoinResponseDto,
Expand Down Expand Up @@ -76,7 +82,7 @@ export const profilesPlugin = (app: Elysia) => {

const { ver } = query;

return profilesService.makeJoin(roomId, userId, ver ?? ['1']) as any;
return profilesService.makeJoin(roomId, userId, ver ?? ['1']);
},
{
params: MakeJoinParamsDto,
Expand Down
11 changes: 9 additions & 2 deletions packages/homeserver/src/dtos/federation/profiles.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,19 +76,26 @@ export const MakeJoinQueryDto = t.Object({
),
});

const MembershipDto = t.Union([
t.Literal('join'),
t.Literal('leave'),
t.Literal('invite'),
t.Literal('ban'),
t.Literal('knock'),
]);

Comment on lines +79 to +86
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Don’t widen membership for make_join; it should be 'join' only

The event template returned by make_join must carry membership 'join'. Allowing other values here weakens validation.

Apply this diff (keep MembershipDto for other contexts, but restrict this field):

-			membership: MembershipDto,
+			membership: t.Literal('join'),

Also applies to: 91-91


🌐 Web query:

Matrix Federation make_join response: confirm that the event content.membership in the template must be 'join' per the current spec.

💡 Result:

Yes. The make_join response's event.template content.membership is required to be "join". See the Server‑Server API /make_join response which specifies the event.content.membership must be the value "join". [1][2]

Sources:
[1] Matrix spec — Server‑Server API, GET /_matrix/federation/v1/make_join (response “event” / Membership Event Content). [2] Matrix legacy federation doc — /make_join (shows example and membership = "join").


Don’t widen membership for make_join; restrict to 'join'

Matrix /make_join requires event.template.content.membership === "join" — restrict the DTO accordingly.

File: packages/homeserver/src/dtos/federation/profiles.dto.ts (lines 79-86; also applies to line 91)

Apply this diff (keep MembershipDto for other contexts, but restrict this field):

-			membership: MembershipDto,
+			membership: t.Literal('join'),

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

🤖 Prompt for AI Agents
In packages/homeserver/src/dtos/federation/profiles.dto.ts around lines 79-86
(and also adjust usage at line 91), the membership type used for make_join is
too broad; create or use a narrowed type that only allows the literal 'join' for
the make_join path instead of the existing MembershipDto union. Keep the
existing MembershipDto for other contexts, then replace the membership field
used for make_join with a t.Literal('join') (or a new MakeJoinMembershipDto
alias) and update the type at line 91 accordingly so
event.template.content.membership is restricted to "join".

export const MakeJoinResponseDto = t.Object({
room_version: t.String({ description: 'Room version' }),
event: t.Object({
content: t.Object({
membership: t.Literal('join'),
membership: MembershipDto,
join_authorised_via_users_server: t.Optional(t.String()),
}),
room_id: RoomIdDto,
sender: UsernameDto,
state_key: UsernameDto,
type: t.Literal('m.room.member'),
origin_server_ts: TimestampDto,
origin: ServerNameDto,
depth: t.Optional(
t.Number({ description: 'Depth of the event in the DAG' }),
),
Expand Down
21 changes: 21 additions & 0 deletions packages/homeserver/src/dtos/federation/state-ids.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { type Static, t } from 'elysia';
import { RoomIdDto } from '../common/validation.dto';

export const GetStateIdsParamsDto = t.Object({
roomId: RoomIdDto,
});

export const GetStateIdsQueryDto = t.Object({
event_id: t.String({ description: 'Event ID to get state at' }),
});

export const GetStateIdsResponseDto = t.Object({
pdu_ids: t.Array(t.String(), { description: 'List of state event IDs' }),
auth_chain_ids: t.Array(t.String(), {
description: 'List of auth chain event IDs',
}),
});

export type GetStateIdsParams = Static<typeof GetStateIdsParamsDto>;
export type GetStateIdsQuery = Static<typeof GetStateIdsQueryDto>;
export type GetStateIdsResponse = Static<typeof GetStateIdsResponseDto>;
23 changes: 23 additions & 0 deletions packages/homeserver/src/dtos/federation/state.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { type Static, t } from 'elysia';
import { RoomIdDto } from '../common/validation.dto';

export const GetStateParamsDto = t.Object({
roomId: RoomIdDto,
});

export const GetStateQueryDto = t.Object({
event_id: t.String({ description: 'Event ID to get state at' }),
});

export const GetStateResponseDto = t.Object({
pdus: t.Array(t.Record(t.String(), t.Any()), {
description: 'List of state event objects',
}),
auth_chain: t.Array(t.Record(t.String(), t.Any()), {
description: 'List of auth chain event objects',
}),
});

export type GetStateParams = Static<typeof GetStateParamsDto>;
export type GetStateQuery = Static<typeof GetStateQueryDto>;
export type GetStateResponse = Static<typeof GetStateResponseDto>;
2 changes: 2 additions & 0 deletions packages/homeserver/src/dtos/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ export * from './common/validation.dto';
export * from './federation/invite.dto';
export * from './federation/profiles.dto';
export * from './federation/send-join.dto';
export * from './federation/state-ids.dto';
export * from './federation/state.dto';
export * from './federation/transactions.dto';
export * from './federation/versions.dto';

Expand Down