Skip to content

Commit

Permalink
add missing body type check to makerequest
Browse files Browse the repository at this point in the history
  • Loading branch information
ggazzo committed Dec 9, 2024
1 parent 08ab439 commit 88de43d
Show file tree
Hide file tree
Showing 12 changed files with 73 additions and 58 deletions.
11 changes: 4 additions & 7 deletions packages/fake/src/room.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,9 +207,8 @@ export const fakeEndpoints = new Elysia({ prefix: "/fake" })
method: "PUT",
domain: username.split(":").pop() as string,
uri: `/_matrix/federation/v2/invite/${roomId}/${inviteEventId}`,
options: {
body: payload,
},
body: payload,
options: {},
signingKey: config.signingKey[0],
signingName: config.name,
});
Expand Down Expand Up @@ -341,12 +340,10 @@ export const fakeEndpoints = new Elysia({ prefix: "/fake" })
method: "PUT",
domain: target,
uri: `/_matrix/federation/v1/send/${Date.now()}`,
options: {
body: payload,
},
body: payload,
signingKey: config.signingKey[0],
signingName: config.name,
});
} as any);

console.log("response ->", responseMake);

Expand Down
5 changes: 1 addition & 4 deletions packages/homeserver/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@ import { Elysia } from "elysia";
import { BadJSONError, MatrixError } from "./errors";
import federationEndpoints from "./routes/federation";
import { keyV2Endpoints } from "./routes/key/server";
import type {
ElysiaRoutes,
ElysiaRoutesResponsesByEndpoint,
} from "./extractRouteTypings";
import type { ElysiaRoutes } from "./extractRouteTypings";

export const app = new Elysia({
handler: {
Expand Down
6 changes: 4 additions & 2 deletions packages/homeserver/src/authentication.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,15 @@ export async function signRequest<T extends object>(
return signedJson;
}

export type HashedEvent<T extends EventBase> = T & {
export type HashedEvent<T extends Record<string, unknown>> = T & {
hashes: {
sha256: string;
};
};

export function computeHash<T extends EventBase>(content: T): HashedEvent<T> {
export function computeHash<T extends Record<string, unknown>>(
content: T,
): HashedEvent<T> {
// remove the fields that are not part of the hash
const {
age_ts,
Expand Down
2 changes: 1 addition & 1 deletion packages/homeserver/src/events/eventBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export type EventBase = {
origin: string;
origin_server_ts: number;

content?: Record<string, unknown>;
content?: object;
unsigned?: Record<string, any> | undefined;
};

Expand Down
3 changes: 3 additions & 0 deletions packages/homeserver/src/events/m.room.member-invite.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const finalEvent = {
},
},
unsigned: {
age: 4,
age_ts: 1733107418773,
invite_room_state: [
{
Expand Down Expand Up @@ -85,6 +86,8 @@ test("roomMemberInviteEvent", async () => {
membership: "invite",
},
unsigned: {
// TODO: Check what this is
age: 4,
age_ts: 1733107418773,
invite_room_state: [
{
Expand Down
4 changes: 4 additions & 0 deletions packages/homeserver/src/events/m.room.member.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,14 @@ export const isRoomMemberEvent = (
return event.type === "m.room.member";
};
export interface RoomMemberEvent extends EventBase {
type: "m.room.member";
content: {
membership: Membership;
};
state_key: string;
unsigned: {
// TODO: Check what this is
age: number;
age_ts: number;
invite_room_state: (
| {
Expand Down
16 changes: 2 additions & 14 deletions packages/homeserver/src/extractRouteTypings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,12 @@ type ConcatRoutes<
P extends string = "",
K extends keyof R = keyof R,
> = K extends string
? R[K] extends { response: infer G }
? { method: Uppercase<K>; path: `${P}`; response: G }
? R[K] extends { response: infer G; body: infer B }
? { method: Uppercase<K>; path: `${P}`; response: G; body: B }
: K extends `:${string}`
? ConcatRoutes<R[K], `${P}/${string}`, keyof R[K]>
: ConcatRoutes<R[K], `${P}/${K}`, keyof R[K]>
: K;

export type ElysiaRoutes<T extends Elysia<any, any, any, any, any, any>> =
ConcatRoutes<ExtractElysiaRoutes<T>>;

// organize by method
export type ElysiaRoutesResponsesByEndpoint<T extends ElysiaRoutes<any>> =
T extends {
response: infer R;
method: infer M;
path: infer P;
}
? {
[K in T["method"]]: T["response"];
}
: never;
24 changes: 12 additions & 12 deletions packages/homeserver/src/makeRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,17 @@ type getAllResponsesByPath<
export const makeRequest = async <
M extends HomeServerRoutes["method"],
U extends getAllResponsesByMethod<HomeServerRoutes, M>["path"],
R extends getAllResponsesByPath<HomeServerRoutes, M, U>["response"][200],
B extends getAllResponsesByPath<HomeServerRoutes, M, U>["body"],
>({
method,
domain,
uri,
body,
options = {},
signingKey,
signingName,
queryString,
}: {
}: (B extends Record<string, unknown> ? { body: B } : { body?: never }) & {
method: M;
domain: string;
uri: U;
Expand All @@ -40,23 +41,18 @@ export const makeRequest = async <
if (queryString) {
url.search = queryString;
}
const body =
options.body &&
(await signJson(
computeHash({ ...options.body, signatures: {} }),
signingKey,
signingName,
));
const signedBody =
body && (await signJson(computeHash(body), signingKey, signingName));

console.log("body ->", method, domain, url.toString(), body);
console.log("body ->", method, domain, url.toString(), signedBody);

const auth = await authorizationHeaders(
signingName,
signingKey,
domain,
method,
uri,
body,
signedBody,
);

console.log("auth ->", method, domain, uri, auth);
Expand All @@ -71,13 +67,16 @@ export const makeRequest = async <
},
});

return response.json() as Promise<R>;
return response.json() as Promise<
getAllResponsesByPath<HomeServerRoutes, M, U>["response"][200]
>;
};

export const makeUnsignedRequest = async <
M extends HomeServerRoutes["method"],
U extends getAllResponsesByMethod<HomeServerRoutes, M>["path"],
R extends getAllResponsesByPath<HomeServerRoutes, M, U>["response"][200],
B extends getAllResponsesByPath<HomeServerRoutes, M, U>["body"],
>({
method,
domain,
Expand All @@ -90,6 +89,7 @@ export const makeUnsignedRequest = async <
method: M;
domain: string;
uri: U;
body: B;
options?: Record<string, any>;
signingKey: SigningKey;
signingName: string;
Expand Down
2 changes: 1 addition & 1 deletion packages/homeserver/src/procedures/makeJoin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,5 @@ export const makeJoinEventBuilder =
return {
event,
room_version: "10",
};
} as const;
};
13 changes: 7 additions & 6 deletions packages/homeserver/src/pruneEventDict.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { EventBase } from "./events/eventBase";
import { isRoomMemberEvent } from "./events/m.room.member";

interface RoomVersion {
updated_redaction_rules: boolean;
Expand Down Expand Up @@ -95,23 +96,23 @@ export function pruneEventDict<T extends EventBase>(

for (const field of fields) {
if (field in eventDict.content) {
// @ts-ignore
content[field] = eventDict.content[field];
}
}
}

if (eventType === "m.room.member") {
if (isRoomMemberEvent(eventDict)) {
const contentKeys = [
...(eventType === "m.room.member" ? ["membership"] : []),
...(eventType === "m.room.member" && roomVersion.restricted_join_rule_fix
? ["authorising_user"]
: []),
"membership",
...(roomVersion.restricted_join_rule_fix ? ["authorising_user"] : []),
];

addFields(...contentKeys);

if (roomVersion.updated_redaction_rules) {
const thirdPartyInvite = eventDict.content?.third_party_invite;
// @ts-ignore
const thirdPartyInvite = eventDict.content.third_party_invite;
if (thirdPartyInvite && typeof thirdPartyInvite === "object") {
content.third_party_invite = {};
if ("signed" in thirdPartyInvite) {
Expand Down
16 changes: 5 additions & 11 deletions packages/homeserver/src/routes/federation/invite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,21 +57,15 @@ export const inviteEndpoint = new Elysia().put(
// }
// };

const joinBody = {
...responseMake.event,
origin: config.name,
origin_server_ts: Date.now(),
depth: responseMake.event.depth + 1,
};

console.log("send_join payload ->", joinBody);

const responseBody = await makeRequest({
method: "PUT",
domain: event.origin,
uri: `/_matrix/federation/v2/send_join/${params.roomId}/${event.state_key}`,
options: {
body: joinBody,
body: {
...responseMake.event,
origin: config.name,
origin_server_ts: Date.now(),
depth: responseMake.event.depth + 1,
},
signingKey: config.signingKey[0],
signingName: config.name,
Expand Down
29 changes: 29 additions & 0 deletions packages/homeserver/src/routes/federation/sendJoin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,35 @@ export const sendJoinEndpoint = new Elysia().put(
return result;
},
{
body: t.Object({
type: t.Literal("m.room.member"),
state_key: t.String({
description:
"The user ID for the invite event, generated by the inviting server.",
}),
sender: t.String({
description:
"The user ID for the invite event, generated by the inviting server.",
}),
origin_server_ts: t.Number({
description:
"The user ID for the invite event, generated by the inviting server.",
}),
origin: t.String({
description:
"The user ID for the invite event, generated by the inviting server.",
}),
content: t.Object({
membership: t.String({
description:
"The user ID for the invite event, generated by the inviting server.",
}),
}),
depth: t.Number({
description:
"The user ID for the invite event, generated by the inviting server.",
}),
}),
params: t.Object(
{
roomId: t.String({
Expand Down

0 comments on commit 88de43d

Please sign in to comment.