Skip to content

Commit

Permalink
chore: refactor make join
Browse files Browse the repository at this point in the history
  • Loading branch information
ggazzo authored Dec 7, 2024
2 parents 1c33425 + 44d4d27 commit 300fcce
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 76 deletions.
2 changes: 1 addition & 1 deletion packages/main/src/events/m.room.member.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ declare module "./eventBase" {
}
}

interface RoomMemberEvent extends EventBase {
export interface RoomMemberEvent extends EventBase {
content: {
membership: Membership;
};
Expand Down
46 changes: 45 additions & 1 deletion packages/main/src/mongodb.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { MongoClient } from "mongodb";
import type { EventBase } from "./events/eventBase";
import { NotFoundError } from "elysia";

const MONGODB_URI = process.env.MONGODB_URI;
if (!MONGODB_URI) {
Expand All @@ -16,4 +17,47 @@ export type EventStore = {
event: EventBase;
};

export const eventsCollection = db.collection<EventStore>("events");
const eventsCollection = db.collection<EventStore>("events");

export const getLastEvent = async (roomId: string) => {
const events = await eventsCollection
.find({ "event.room_id": roomId }, { sort: { "event.depth": -1 } })
.toArray();

if (events.length === 0) {
throw new NotFoundError(`No events found for room ${roomId}`);
}

return events[0];
};

export const getAuthEvents = async (roomId: string) => {
return eventsCollection
.find(
{
"event.room_id": roomId,
$or: [
{
"event.type": {
$in: [
"m.room.create",
"m.room.power_levels",
"m.room.join_rules",
],
},
},
{
// Lots of room members, when including the join ones it fails the auth check
"event.type": "m.room.member",
"event.content.membership": "invite",
},
],
},
{
projection: {
_id: 1,
},
},
)
.toArray();
};
47 changes: 47 additions & 0 deletions packages/main/src/procedures/makeJoin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { Elysia, t } from "elysia";

import "@hs/endpoints/src/query";
import "@hs/endpoints/src/server";
import type { EventStore } from "../mongodb";
import { IncompatibleRoomVersionError } from "../errors";
import { roomMemberEvent } from "../events/m.room.member";

// "method":"GET",
// "url":"http://rc1:443/_matrix/federation/v1/make_join/%21kwkcWPpOXEJvlcollu%3Arc1/%40admin%3Ahs1?ver=1&ver=2&ver=3&ver=4&ver=5&ver=6&ver=7&ver=8&ver=9&ver=10&ver=11&ver=org.matrix.msc3757.10&ver=org.matrix.msc3757.11",

export const makeJoinEventBuilder =
(
getLastEvent: (roomId: string) => Promise<EventStore>,
getAuthEvents: (roomId: string) => Promise<EventStore[]>,
) =>
async (
roomId: string,
userId: string,
roomVersion: string,
origin: string,
) => {
if (roomVersion !== "10") {
throw new IncompatibleRoomVersionError(
"Your homeserver does not support the features required to join this room",
{ roomVersion: "10" },
);
}
const lastEvent = await getLastEvent(roomId);
const authEvents = await getAuthEvents(roomId);
const event = roomMemberEvent({
membership: "join",
roomId,
sender: userId,
state_key: userId,
auth_events: authEvents.map((event) => event._id),
prev_events: [lastEvent._id],
depth: lastEvent.event.depth + 1,
origin,
ts: Date.now(),
});

return {
event,
room_version: "10",
};
};
78 changes: 4 additions & 74 deletions packages/main/src/routes/federation/makeJoin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ import "@hs/endpoints/src/query";
import "@hs/endpoints/src/server";
import { isMongodbContext } from "../../plugins/isMongodbContext";
import { isConfigContext } from "../../plugins/isConfigContext";
import { roomMemberEvent } from "../../events/m.room.member";
import { signEvent } from "../../signEvent";
import { generateId } from "../../authentication";
import { makeJoinEventBuilder } from "../../procedures/makeJoin";

// "method":"GET",
// "url":"http://rc1:443/_matrix/federation/v1/make_join/%21kwkcWPpOXEJvlcollu%3Arc1/%40admin%3Ahs1?ver=1&ver=2&ver=3&ver=4&ver=5&ver=6&ver=7&ver=8&ver=9&ver=10&ver=11&ver=org.matrix.msc3757.10&ver=org.matrix.msc3757.11",
Expand All @@ -22,7 +20,7 @@ export const makeJoinEndpoint = new Elysia().get(
}
const {
config,
mongo: { eventsCollection },
mongo: { getAuthEvents, getLastEvent },
} = context;

const roomId = decodeURIComponent(params.roomId);
Expand All @@ -35,76 +33,8 @@ export const makeJoinEndpoint = new Elysia().get(
throw new Error("Invalid room Id");
}

const [lastEvent] = await eventsCollection
.find(
{ "event.room_id": roomId },
{ sort: { "event.depth": -1 }, limit: 1 },
)
.toArray();

const authEvents = await eventsCollection
.find(
{
"event.room_id": roomId,
$or: [
{
"event.type": {
$in: [
"m.room.create",
"m.room.power_levels",
"m.room.join_rules",
],
},
},
{
// Lots of room members, when including the join ones it fails the auth check
"event.type": "m.room.member",
"event.content.membership": "invite",
},
],
},
{
projection: {
_id: 1,
},
},
)
.toArray();

console.log("lastEvent ->", lastEvent);

const event = roomMemberEvent({
membership: "join",
roomId,
sender: userId,
state_key: userId,
auth_events: [...authEvents].map((event) => event._id),
prev_events: [lastEvent._id],
depth: lastEvent.event.depth + 1,
origin: config.name,
ts: Date.now(),
});

const signedEvent = await signEvent(event, config.signingKey[0]);

const eventId = await generateId(signedEvent);

console.log("eventId ->", eventId);

const result = {
event: event,
room_version: "10",
};

console.log("make_join result ->", result);

// // TODO: how to prevent duplicates?
// await eventsCollection.insertOne({
// _id: eventId,
// event: signedEvent,
// });

return result;
const makeJoinEvent = makeJoinEventBuilder(getLastEvent, getAuthEvents);
return await makeJoinEvent(roomId, userId, query.ver, config.name);
},
{
response: {
Expand Down

0 comments on commit 300fcce

Please sign in to comment.