Skip to content

Commit ce67d9c

Browse files
Room Version 12 fixes (#979)
* Relax our room_id validation as room version 12 drops the server part of the room_id Signed-off-by: MTRNord <[email protected]> * Ensure we log validation errors as this caused quite a headache while debugging room version 12 changes Signed-off-by: MTRNord <[email protected]> * Add changeset --------- Signed-off-by: MTRNord <[email protected]>
1 parent 2307e72 commit ce67d9c

File tree

5 files changed

+100
-7
lines changed

5 files changed

+100
-7
lines changed

.changeset/rare-beans-send.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
'@matrix-widget-toolkit/testing': minor
3+
'@matrix-widget-toolkit/react': minor
4+
'@matrix-widget-toolkit/api': minor
5+
'@matrix-widget-toolkit/mui': minor
6+
---
7+
8+
Reduce strictness on room_ids to comply with changes in room version 12

example-widget-mui/src/events/validation.test.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,19 @@
1616

1717
import { RoomEvent } from '@matrix-widget-toolkit/api';
1818
import Joi from 'joi';
19-
import { beforeEach, describe, expect, it } from 'vitest';
19+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
2020
import { isValidEvent } from './validation';
2121

22+
// Mock console.warn for tests
23+
const originalConsoleWarn = console.warn;
24+
beforeEach(() => {
25+
console.warn = vi.fn();
26+
});
27+
28+
afterEach(() => {
29+
console.warn = originalConsoleWarn;
30+
});
31+
2232
const exampleSchema = Joi.object({
2333
key: Joi.string(),
2434
});
@@ -63,6 +73,19 @@ describe('isValidEvent', () => {
6373
);
6474
});
6575

76+
it('should log warning when content validation fails', () => {
77+
event.content = { other: 'my-value' };
78+
79+
expect(isValidEvent(event, 'com.example.event', exampleSchema)).toEqual(
80+
false,
81+
);
82+
expect(console.warn).toHaveBeenCalledWith(
83+
'Error while validating com.example.event event:',
84+
expect.any(Array),
85+
{ event },
86+
);
87+
});
88+
6689
it('should validate successful', () => {
6790
expect(isValidEvent(event, 'com.example.event', exampleSchema)).toEqual(
6891
true,

example-widget-mui/src/events/validation.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,11 @@ export function isValidEvent(
3333
const result = schema.validate(event.content);
3434

3535
if (result.error) {
36-
// TODO: Log here if desired: console.warn('Error while validating event', result.error);
36+
console.warn(
37+
`Error while validating ${eventType} event:`,
38+
result.error.details,
39+
{ event },
40+
);
3741
return false;
3842
}
3943

packages/api/src/api/extras/events.test.ts

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
import { describe, expect, it } from 'vitest';
17+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
1818
import { RoomEvent, StateEvent, ToDeviceMessageEvent } from '../types';
1919
import {
2020
isRoomEvent,
@@ -24,6 +24,16 @@ import {
2424
isValidToDeviceMessageEvent,
2525
} from './events';
2626

27+
// Mock console.warn for tests
28+
const originalConsoleWarn = console.warn;
29+
beforeEach(() => {
30+
console.warn = vi.fn();
31+
});
32+
33+
afterEach(() => {
34+
console.warn = originalConsoleWarn;
35+
});
36+
2737
const roomEvent: RoomEvent = {
2838
type: 'com.example.type',
2939
sender: '@user-id',
@@ -93,6 +103,16 @@ describe('isValidRoomEvent', () => {
93103
}),
94104
).toBe(false);
95105
});
106+
107+
it('should log warning when validation fails', () => {
108+
const invalidEvent = { ...roomEventData, type: undefined };
109+
expect(isValidRoomEvent(invalidEvent)).toBe(false);
110+
expect(console.warn).toHaveBeenCalledWith(
111+
'Invalid room event:',
112+
expect.any(Array),
113+
{ event: invalidEvent },
114+
);
115+
});
96116
});
97117

98118
const stateEventData: StateEvent = {
@@ -138,6 +158,16 @@ describe('isValidStateEvent', () => {
138158
}),
139159
).toBe(false);
140160
});
161+
162+
it('should log warning when validation fails', () => {
163+
const invalidEvent = { ...stateEventData, type: undefined };
164+
expect(isValidStateEvent(invalidEvent)).toBe(false);
165+
expect(console.warn).toHaveBeenCalledWith(
166+
'Invalid state event:',
167+
expect.any(Array),
168+
{ event: invalidEvent },
169+
);
170+
});
141171
});
142172

143173
const toDeviceMessageData: ToDeviceMessageEvent = {
@@ -172,4 +202,14 @@ describe('isValidToDeviceMessageEvent', () => {
172202
}),
173203
).toBe(false);
174204
});
205+
206+
it('should log warning when validation fails', () => {
207+
const invalidEvent = { ...toDeviceMessageData, type: undefined };
208+
expect(isValidToDeviceMessageEvent(invalidEvent)).toBe(false);
209+
expect(console.warn).toHaveBeenCalledWith(
210+
'Invalid to device message event:',
211+
expect.any(Array),
212+
{ event: invalidEvent },
213+
);
214+
});
175215
});

packages/api/src/api/extras/events.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,12 @@ export function isRoomEvent(event: RoomEvent | StateEvent): event is RoomEvent {
4848
// Allow any here, so that the validation works for every event
4949
// eslint-disable-next-line @typescript-eslint/no-explicit-any
5050
export function isValidRoomEvent(event: unknown): event is RoomEvent<any> {
51-
return roomEventSchema.validate(event).error === undefined;
51+
const result = roomEventSchema.validate(event);
52+
if (result.error) {
53+
console.warn('Invalid room event:', result.error.details, { event });
54+
return false;
55+
}
56+
return true;
5257
}
5358

5459
/**
@@ -60,7 +65,12 @@ export function isValidRoomEvent(event: unknown): event is RoomEvent<any> {
6065
// Allow any here, so that the validation works for every event
6166
// eslint-disable-next-line @typescript-eslint/no-explicit-any
6267
export function isValidStateEvent(event: unknown): event is StateEvent<any> {
63-
return stateEventSchema.validate(event).error === undefined;
68+
const result = stateEventSchema.validate(event);
69+
if (result.error) {
70+
console.warn('Invalid state event:', result.error.details, { event });
71+
return false;
72+
}
73+
return true;
6474
}
6575

6676
/**
@@ -74,7 +84,14 @@ export function isValidToDeviceMessageEvent(
7484
// Allow any here, so that the validation works for every event
7585
// eslint-disable-next-line @typescript-eslint/no-explicit-any
7686
): event is ToDeviceMessageEvent<any> {
77-
return toDeviceMessageSchema.validate(event).error === undefined;
87+
const result = toDeviceMessageSchema.validate(event);
88+
if (result.error) {
89+
console.warn('Invalid to device message event:', result.error.details, {
90+
event,
91+
});
92+
return false;
93+
}
94+
return true;
7895
}
7996

8097
/**
@@ -85,7 +102,8 @@ const eventSchemaProps = {
85102
// Do roughly check against the format
86103
// https://spec.matrix.org/v1.13/appendices/#common-identifier-format
87104
sender: Joi.string().pattern(new RegExp('^@[^\\s:]*:\\S*$')).required(),
88-
room_id: Joi.string().pattern(new RegExp('^![^:]*:\\S*')).required(),
105+
// Prior versions of the code had checked for a server_name. However in room version 12+ this got dropped. There is no way for us to check this here.
106+
room_id: Joi.string().pattern(new RegExp('^!')).required(),
89107
content: Joi.object().required(),
90108
};
91109

0 commit comments

Comments
 (0)