Skip to content

Commit b52b385

Browse files
authored
refactor: propagate room version through PersistentEventBase (#230)
1 parent 15e2656 commit b52b385

File tree

13 files changed

+118
-132
lines changed

13 files changed

+118
-132
lines changed

packages/federation-sdk/src/services/state.service.ts

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ export class StateService {
9191
throw new Error('Create event not found for room version');
9292
}
9393

94-
return createEvent.event.content?.room_version;
94+
return createEvent.event.content.room_version;
9595
}
9696

9797
private logState(label: string, state: State) {
@@ -438,7 +438,7 @@ export class StateService {
438438
}
439439

440440
private async addPrevEvents(event: PersistentEventBase) {
441-
const roomVersion = await this.getRoomVersion(event.roomId);
441+
const roomVersion = event.version;
442442
if (!roomVersion) {
443443
throw new Error('Room version not found while filling prev events');
444444
}
@@ -478,13 +478,7 @@ export class StateService {
478478
event: PersistentEventBase,
479479
state: State,
480480
): Promise<void> {
481-
const roomVersion = event.isCreateEvent()
482-
? event.getContent().room_version
483-
: await this.getRoomVersion(event.roomId);
484-
485-
if (!roomVersion) {
486-
throw new Error('Room version not found');
487-
}
481+
const roomVersion = event.version;
488482

489483
// always check for conflicts at the prev_event state
490484

@@ -594,9 +588,7 @@ export class StateService {
594588
return;
595589
}
596590

597-
const roomVersion = event.isCreateEvent()
598-
? event.getContent().room_version
599-
: await this.getRoomVersion(event.roomId);
591+
const roomVersion = event.version;
600592

601593
if (!roomVersion) {
602594
throw new Error('Room version not found');
@@ -748,12 +740,7 @@ export class StateService {
748740
throw new Error('State events are not persisted with this method');
749741
}
750742

751-
const roomVersion = await this.getRoomVersion(event.roomId);
752-
if (!roomVersion) {
753-
throw new Error(
754-
'Room version not found when trying to persist a timeline event',
755-
);
756-
}
743+
const roomVersion = event.version;
757744

758745
const { state: room, stateId } = await this.getFullRoomStateAndStateId(
759746
event.roomId,

packages/room/src/authorizartion-rules/rules.ts

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
11
import assert from 'node:assert';
2-
import {
3-
type PduCreateEventContent,
4-
type PduMembershipEventContent,
5-
type PduPowerLevelsEventContent,
6-
type PduType,
7-
} from '../types/v3-11';
2+
import { type PduType } from '../types/v3-11';
83

94
import type { PersistentEventBase } from '../manager/event-wrapper';
105
import { PowerLevelEvent } from '../manager/power-level-event-wrapper';
6+
import { RoomVersion } from '../manager/type';
117
import {
128
type EventStore,
139
getStateByMapKey,
@@ -173,7 +169,9 @@ async function isMembershipChangeAllowed(
173169

174170
const content = membershipEventToCheck.getContent();
175171

176-
const previousEvents = await membershipEventToCheck.getPreviousEvents(store);
172+
const previousEvents = await store.getEvents(
173+
membershipEventToCheck.getPreviousEventIds(),
174+
);
177175

178176
switch (content.membership) {
179177
case 'join': {
@@ -353,7 +351,7 @@ async function isMembershipChangeAllowed(
353351

354352
export function validatePowerLevelEvent(
355353
powerLevelEvent: PowerLevelEvent,
356-
roomCreateEvent: PersistentEventBase,
354+
roomCreateEvent: PersistentEventBase<RoomVersion, 'm.room.create'>,
357355
authEventMap: Map<StateMapKey, PersistentEventBase>,
358356
) {
359357
// If the users property in content is not an object with keys that are valid user IDs with values that are integers (or a string that is an integer), reject.

packages/room/src/manager/event-wrapper.ts

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export const REDACT_ALLOW_ALL_KEYS: unique symbol = Symbol.for('all');
4141

4242
// convinient wrapper to manage schema differences when working with same algorithms across different versions
4343
export abstract class PersistentEventBase<
44-
T extends RoomVersion = '11',
44+
Version extends RoomVersion = RoomVersion,
4545
Type extends PduType = PduType,
4646
> {
4747
private _rejectedReason?: string;
@@ -50,7 +50,10 @@ export abstract class PersistentEventBase<
5050

5151
protected rawEvent: PduWithHashesAndSignaturesOptional;
5252

53-
constructor(event: PduWithHashesAndSignaturesOptional) {
53+
constructor(
54+
event: PduWithHashesAndSignaturesOptional,
55+
public readonly version: Version,
56+
) {
5457
this.rawEvent = JSON.parse(JSON.stringify(event));
5558
if (this.rawEvent.signatures) {
5659
this.signatures = this.rawEvent.signatures;
@@ -141,14 +144,13 @@ export abstract class PersistentEventBase<
141144
throw new Error('Event is not a power level event');
142145
}
143146

144-
// room version dependent
145-
abstract getAuthorizationEvents(
146-
store: EventStore,
147-
): Promise<PersistentEventBase<T>[]>;
147+
getAuthEventIds() {
148+
return this.rawEvent.auth_events;
149+
}
148150

149-
abstract getPreviousEvents(
150-
store: EventStore,
151-
): Promise<PersistentEventBase<T>[]>;
151+
getPreviousEventIds() {
152+
return this.rawEvent.prev_events;
153+
}
152154

153155
isState() {
154156
// spec wise this is the right way to check if an event is a state event
@@ -162,49 +164,55 @@ export abstract class PersistentEventBase<
162164
return !this.isState();
163165
}
164166

165-
isTopicEvent(): this is PersistentEventBase<T, 'm.room.topic'> {
167+
isTopicEvent(): this is PersistentEventBase<Version, 'm.room.topic'> {
166168
return this.isState() && this.type === 'm.room.topic';
167169
}
168170

169-
isPowerLevelEvent(): this is PersistentEventBase<T, 'm.room.power_levels'> {
171+
isPowerLevelEvent(): this is PersistentEventBase<
172+
Version,
173+
'm.room.power_levels'
174+
> {
170175
return this.isState() && this.type === 'm.room.power_levels';
171176
}
172177

173-
isNameEvent(): this is PersistentEventBase<T, 'm.room.name'> {
178+
isNameEvent(): this is PersistentEventBase<Version, 'm.room.name'> {
174179
return this.isState() && this.type === 'm.room.name';
175180
}
176181

177-
isJoinRuleEvent(): this is PersistentEventBase<T, 'm.room.join_rules'> {
182+
isJoinRuleEvent(): this is PersistentEventBase<Version, 'm.room.join_rules'> {
178183
return this.isState() && this.type === 'm.room.join_rules';
179184
}
180185

181-
isMembershipEvent(): this is PersistentEventBase<T, 'm.room.member'> {
186+
isMembershipEvent(): this is PersistentEventBase<Version, 'm.room.member'> {
182187
return this.isState() && this.type === 'm.room.member';
183188
}
184189

185-
isCreateEvent(): this is PersistentEventBase<T, 'm.room.create'> {
190+
isCreateEvent(): this is PersistentEventBase<Version, 'm.room.create'> {
186191
return this.isState() && this.type === 'm.room.create';
187192
}
188193

189-
isServerAclEvent(): this is PersistentEventBase<T, 'm.room.server_acl'> {
194+
isServerAclEvent(): this is PersistentEventBase<
195+
Version,
196+
'm.room.server_acl'
197+
> {
190198
return this.isState() && this.type === 'm.room.server_acl';
191199
}
192200

193201
isHistoryVisibilityEvent(): this is PersistentEventBase<
194-
T,
202+
Version,
195203
'm.room.history_visibility'
196204
> {
197205
return this.isState() && this.type === 'm.room.history_visibility';
198206
}
199207

200208
isCanonicalAliasEvent(): this is PersistentEventBase<
201-
T,
209+
Version,
202210
'm.room.canonical_alias'
203211
> {
204212
return this.isState() && this.type === 'm.room.canonical_alias';
205213
}
206214

207-
isAliasEvent(): this is PersistentEventBase<T, 'm.room.aliases'> {
215+
isAliasEvent(): this is PersistentEventBase<Version, 'm.room.aliases'> {
208216
return this.isState() && this.type === 'm.room.aliases';
209217
}
210218

@@ -412,15 +420,15 @@ export abstract class PersistentEventBase<
412420
return this._rejectedReason;
413421
}
414422

415-
addPrevEvents(events: PersistentEventBase<T>[]) {
423+
addPrevEvents(events: PersistentEventBase<Version>[]) {
416424
this.rawEvent.prev_events.push(...events.map((e) => e.eventId));
417425
if (this.rawEvent.depth <= events[events.length - 1].depth) {
418426
this.rawEvent.depth = events[events.length - 1].depth + 1;
419427
}
420428
return this;
421429
}
422430

423-
authedBy(event: PersistentEventBase<T>) {
431+
authedBy(event: PersistentEventBase<Version>) {
424432
this.rawEvent.auth_events.push(event.eventId);
425433
return this;
426434
}

packages/room/src/manager/factory.ts

Lines changed: 7 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,4 @@
1-
import {
2-
Pdu,
3-
type PduCreateEventContent,
4-
type PduJoinRuleEventContent,
5-
type PduMembershipEventContent,
6-
PduPowerLevelsEventContent,
7-
PduType,
8-
} from '../types/v3-11';
1+
import { Pdu, type PduCreateEventContent, PduType } from '../types/v3-11';
92

103
import { PersistentEventV3 } from './v3';
114

@@ -59,7 +52,7 @@ export class PersistentEventFactory {
5952

6053
static createFromRawEvent<Type extends PduType>(
6154
event: PduWithHashesAndSignaturesOptional,
62-
roomVersion: RoomVersion,
55+
roomVersion: string,
6356
): PersistentEventBase<RoomVersion, Type> {
6457
if (!PersistentEventFactory.isSupportedRoomVersion(roomVersion)) {
6558
throw new Error(`Room version ${roomVersion} is not supported`);
@@ -69,32 +62,17 @@ export class PersistentEventFactory {
6962
case '3':
7063
case '4':
7164
case '5':
72-
return new PersistentEventV3(event) as PersistentEventBase<
73-
RoomVersion,
74-
Type
75-
>;
65+
return new PersistentEventV3(event, roomVersion);
7666
case '6':
7767
case '7':
78-
return new PersistentEventV6(event) as PersistentEventBase<
79-
RoomVersion,
80-
Type
81-
>;
68+
return new PersistentEventV6(event, roomVersion);
8269
case '8':
83-
return new PersistentEventV8(event) as PersistentEventBase<
84-
RoomVersion,
85-
Type
86-
>;
70+
return new PersistentEventV8(event, roomVersion);
8771
case '9':
8872
case '10':
89-
return new PersistentEventV9(event) as PersistentEventBase<
90-
RoomVersion,
91-
Type
92-
>;
73+
return new PersistentEventV9(event, roomVersion);
9374
case '11':
94-
return new PersistentEventV11(event) as PersistentEventBase<
95-
RoomVersion,
96-
Type
97-
>;
75+
return new PersistentEventV11(event, roomVersion);
9876
default:
9977
throw new Error(`Unknown room version: ${roomVersion}`);
10078
}

packages/room/src/manager/power-level-event-wrapper.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,10 @@ class PowerLevelEvent<
6868
return this._content.redact ?? 50;
6969
}
7070

71-
getPowerLevelForUser(userId: string, createEvent?: PersistentEventBase) {
71+
getPowerLevelForUser(
72+
userId: string,
73+
createEvent?: PersistentEventBase<RoomVersion, 'm.room.create'>,
74+
) {
7275
if (!this._content) {
7376
if (createEvent?.sender === userId) {
7477
return 100;

packages/room/src/manager/room-state.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,6 @@ export class RoomState {
151151
throw new Error('Room create event not found');
152152
}
153153

154-
return createEvent.getContent().room_version;
154+
return createEvent.getContent().room_version as RoomVersion;
155155
}
156156
}

packages/room/src/manager/v11.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
import {} from '../types/v3-11';
1+
import { type PduType } from '../types/v3-11';
22
import { REDACT_ALLOW_ALL_KEYS } from './event-wrapper';
33
import { PersistentEventV9 } from './v9';
44

5-
export class PersistentEventV11 extends PersistentEventV9 {
5+
export class PersistentEventV11<
6+
Type extends PduType = PduType,
7+
> extends PersistentEventV9<Type> {
68
getAllowedKeys(): string[] {
79
return [
810
'event_id',

packages/room/src/manager/v3.ts

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { toUnpaddedBase64 } from '@rocket.chat/federation-crypto';
22
import type { EventID } from '../types/_common';
3-
import {} from '../types/v3-11';
3+
import { PduType } from '../types/v3-11';
44
import {
55
type EventStore,
66
PersistentEventBase,
@@ -9,16 +9,11 @@ import {
99
import type { RoomVersion3To11 } from './type';
1010

1111
// v3 is where it changes first
12-
export class PersistentEventV3 extends PersistentEventBase<RoomVersion3To11> {
12+
export class PersistentEventV3<
13+
Type extends PduType = PduType,
14+
> extends PersistentEventBase<RoomVersion3To11, Type> {
1315
private _eventId?: EventID;
1416

15-
async getAuthorizationEvents(store: EventStore) {
16-
return store.getEvents(this.rawEvent.auth_events);
17-
}
18-
19-
async getPreviousEvents(store: EventStore) {
20-
return store.getEvents(this.rawEvent.prev_events);
21-
}
2217
get eventId(): EventID {
2318
if (this._eventId) {
2419
return this._eventId;

packages/room/src/manager/v6.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
import {} from '../types/v3-11';
1+
import { PduType } from '../types/v3-11';
22
import { PersistentEventV3 } from './v3';
33

4-
export class PersistentEventV6 extends PersistentEventV3 {
4+
export class PersistentEventV6<
5+
Type extends PduType = PduType,
6+
> extends PersistentEventV3<Type> {
57
getAllowedContentKeys() {
68
const resp = super.getAllowedContentKeys();
79

packages/room/src/manager/v8.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
import {} from '../types/v3-11';
1+
import { PduType } from '../types/v3-11';
22
import { PersistentEventV6 } from './v6';
33

4-
export class PersistentEventV8 extends PersistentEventV6 {
4+
export class PersistentEventV8<
5+
Type extends PduType = PduType,
6+
> extends PersistentEventV6<Type> {
57
getAllowedContentKeys() {
68
const resp = super.getAllowedContentKeys();
79

0 commit comments

Comments
 (0)