You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-11-23 17:02:25 +03:00
More lint
This commit is contained in:
@@ -14,11 +14,11 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { SessionMembershipData } from "../../../src/matrixrtc/membership/legacy";
|
import { type SessionMembershipData } from "../../../src/matrixrtc/membership/legacy";
|
||||||
import { EventType, type MatrixEvent } from "../../../src";
|
import { EventType, type MatrixEvent } from "../../../src";
|
||||||
import { CallMembership, DEFAULT_EXPIRE_DURATION } from "../../../src/matrixrtc/CallMembership";
|
import { CallMembership, DEFAULT_EXPIRE_DURATION } from "../../../src/matrixrtc/CallMembership";
|
||||||
import { sessionMembershipTemplate } from "./mocks";
|
import { sessionMembershipTemplate } from "./mocks";
|
||||||
import { RtcMembershipData } from "../../../src/matrixrtc/membership/rtc";
|
import { type RtcMembershipData } from "../../../src/matrixrtc/membership/rtc";
|
||||||
|
|
||||||
function makeMockEvent(
|
function makeMockEvent(
|
||||||
eventType: EventType.RTCMembership | EventType.GroupCallMemberPrefix,
|
eventType: EventType.RTCMembership | EventType.GroupCallMemberPrefix,
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import {
|
|||||||
} from "../../../src";
|
} from "../../../src";
|
||||||
import { KnownMembership } from "../../../src/@types/membership";
|
import { KnownMembership } from "../../../src/@types/membership";
|
||||||
import { MatrixRTCSession, MatrixRTCSessionEvent } from "../../../src/matrixrtc/MatrixRTCSession";
|
import { MatrixRTCSession, MatrixRTCSessionEvent } from "../../../src/matrixrtc/MatrixRTCSession";
|
||||||
import { SlotDescription, Status, type EncryptionKeysEventContent } from "../../../src/matrixrtc/types";
|
import { type SlotDescription, Status, type EncryptionKeysEventContent } from "../../../src/matrixrtc/types";
|
||||||
import {
|
import {
|
||||||
makeMockEvent,
|
makeMockEvent,
|
||||||
makeMockRoom,
|
makeMockRoom,
|
||||||
|
|||||||
@@ -160,7 +160,6 @@ describe.each([{ eventKind: "sticky" }, { eventKind: "memberState" }])(
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
const room2 = makeMockRoom(room2MembershipData, eventKind === "sticky", slotDescription);
|
const room2 = makeMockRoom(room2MembershipData, eventKind === "sticky", slotDescription);
|
||||||
console.log({ room2: room2.roomId });
|
|
||||||
jest.spyOn(client, "getRooms").mockReturnValue([room1, room2]);
|
jest.spyOn(client, "getRooms").mockReturnValue([room1, room2]);
|
||||||
client.emit(ClientEvent.Room, room2);
|
client.emit(ClientEvent.Room, room2);
|
||||||
expect(onStarted).toHaveBeenCalled();
|
expect(onStarted).toHaveBeenCalled();
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ import {
|
|||||||
import { MembershipManagerEvent, Status, type Transport } from "../../../src/matrixrtc";
|
import { MembershipManagerEvent, Status, type Transport } from "../../../src/matrixrtc";
|
||||||
import { makeMockClient, makeMockRoom, sessionMembershipTemplate, mockCallMembership, type MockClient } from "./mocks";
|
import { makeMockClient, makeMockRoom, sessionMembershipTemplate, mockCallMembership, type MockClient } from "./mocks";
|
||||||
import { LegacyMembershipManager, StickyEventMembershipManager } from "../../../src/matrixrtc/MembershipManager.ts";
|
import { LegacyMembershipManager, StickyEventMembershipManager } from "../../../src/matrixrtc/MembershipManager.ts";
|
||||||
import { SessionMembershipData } from "../../../src/matrixrtc/membership/legacy.ts";
|
import { type SessionMembershipData } from "../../../src/matrixrtc/membership/legacy.ts";
|
||||||
import { RtcMembershipData } from "../../../src/matrixrtc/membership/rtc.ts";
|
import { type RtcMembershipData } from "../../../src/matrixrtc/membership/rtc.ts";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a promise that will resolve once a mocked method is called.
|
* Create a promise that will resolve once a mocked method is called.
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ import { CallMembership } from "../../../src/matrixrtc/CallMembership";
|
|||||||
import { secureRandomString } from "../../../src/randomstring";
|
import { secureRandomString } from "../../../src/randomstring";
|
||||||
import {
|
import {
|
||||||
DefaultCallApplicationDescription,
|
DefaultCallApplicationDescription,
|
||||||
RtcSlotEventContent,
|
type RtcSlotEventContent,
|
||||||
SlotDescription,
|
type SlotDescription,
|
||||||
slotDescriptionToId,
|
slotDescriptionToId,
|
||||||
} from "../../../src/matrixrtc";
|
} from "../../../src/matrixrtc";
|
||||||
import { mkMatrixEvent } from "../../../src/testing";
|
import { mkMatrixEvent } from "../../../src/testing";
|
||||||
|
|||||||
@@ -63,8 +63,8 @@ import { type LocalNotificationSettings } from "./local_notifications.ts";
|
|||||||
import { type IPushRules } from "./PushRules.ts";
|
import { type IPushRules } from "./PushRules.ts";
|
||||||
import { type SecretInfo, type SecretStorageKeyDescription } from "../secret-storage.ts";
|
import { type SecretInfo, type SecretStorageKeyDescription } from "../secret-storage.ts";
|
||||||
import { type POLICIES_ACCOUNT_EVENT_TYPE } from "../models/invites-ignorer-types.ts";
|
import { type POLICIES_ACCOUNT_EVENT_TYPE } from "../models/invites-ignorer-types.ts";
|
||||||
import { RtcMembershipData } from "../matrixrtc/membership/rtc.ts";
|
import { type RtcMembershipData } from "../matrixrtc/membership/rtc.ts";
|
||||||
import { SessionMembershipData } from "../matrixrtc/membership/legacy.ts";
|
import { type SessionMembershipData } from "../matrixrtc/membership/legacy.ts";
|
||||||
|
|
||||||
export enum EventType {
|
export enum EventType {
|
||||||
// Room state events
|
// Room state events
|
||||||
@@ -161,7 +161,7 @@ export enum EventType {
|
|||||||
CallNotify = "org.matrix.msc4075.call.notify",
|
CallNotify = "org.matrix.msc4075.call.notify",
|
||||||
RTCNotification = "org.matrix.msc4075.rtc.notification",
|
RTCNotification = "org.matrix.msc4075.rtc.notification",
|
||||||
RTCDecline = "org.matrix.msc4310.rtc.decline",
|
RTCDecline = "org.matrix.msc4310.rtc.decline",
|
||||||
RTCSlot = "org.matrix.msc4143.rtc.slot"
|
RTCSlot = "org.matrix.msc4143.rtc.slot",
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum RelationType {
|
export enum RelationType {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { RtcSlotEventContent, SlotDescription } from "./types";
|
import { type RtcSlotEventContent, type SlotDescription } from "./types.ts";
|
||||||
|
|
||||||
export const DefaultCallApplicationDescription: SlotDescription = {
|
export const DefaultCallApplicationDescription: SlotDescription = {
|
||||||
id: "",
|
id: "",
|
||||||
application: "m.call"
|
application: "m.call",
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -13,14 +13,14 @@ export interface CallSlotEventContent extends RtcSlotEventContent<"m.call"> {
|
|||||||
"type": "m.call";
|
"type": "m.call";
|
||||||
"m.call.id"?: string;
|
"m.call.id"?: string;
|
||||||
};
|
};
|
||||||
slot_id: `${string}#${string}`,
|
slot_id: `${string}#${string}`;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Default slot for a room using "m.call".
|
* Default slot for a room using "m.call".
|
||||||
*/
|
*/
|
||||||
export const DefaultCallApplicationSlot: CallSlotEventContent = {
|
export const DefaultCallApplicationSlot: CallSlotEventContent = {
|
||||||
application: {
|
application: {
|
||||||
"type": "m.call",
|
type: "m.call",
|
||||||
},
|
},
|
||||||
slot_id: "m.call#",
|
slot_id: "m.call#",
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ import { type RTCCallIntent, type Transport, type SlotDescription } from "./type
|
|||||||
import { type IContent, type MatrixEvent } from "../models/event.ts";
|
import { type IContent, type MatrixEvent } from "../models/event.ts";
|
||||||
import { logger } from "../logger.ts";
|
import { logger } from "../logger.ts";
|
||||||
import { slotDescriptionToId, slotIdToDescription } from "./utils.ts";
|
import { slotDescriptionToId, slotIdToDescription } from "./utils.ts";
|
||||||
import { checkSessionsMembershipData, SessionMembershipData } from "./membership/legacy.ts";
|
import { checkSessionsMembershipData, type SessionMembershipData } from "./membership/legacy.ts";
|
||||||
import { checkRtcMembershipData, RtcMembershipData } from "./membership/rtc.ts";
|
import { checkRtcMembershipData, type RtcMembershipData } from "./membership/rtc.ts";
|
||||||
import { EventType } from "../matrix.ts";
|
import { EventType } from "../matrix.ts";
|
||||||
import { MatrixRTCMembershipParseError } from "./membership/common.ts";
|
import { MatrixRTCMembershipParseError } from "./membership/common.ts";
|
||||||
|
|
||||||
@@ -45,8 +45,9 @@ enum MembershipKind {
|
|||||||
Session = "session",
|
Session = "session",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MembershipData =
|
||||||
type MembershipData = { kind: MembershipKind.RTC; data: RtcMembershipData } | { kind: MembershipKind.Session; data: SessionMembershipData };
|
| { kind: MembershipKind.RTC; data: RtcMembershipData }
|
||||||
|
| { kind: MembershipKind.Session; data: SessionMembershipData };
|
||||||
// TODO: Rename to RtcMembership once we removed the legacy SessionMembership from this file.
|
// TODO: Rename to RtcMembership once we removed the legacy SessionMembership from this file.
|
||||||
export class CallMembership {
|
export class CallMembership {
|
||||||
public static equal(a?: CallMembership, b?: CallMembership): boolean {
|
public static equal(a?: CallMembership, b?: CallMembership): boolean {
|
||||||
@@ -72,6 +73,7 @@ export class CallMembership {
|
|||||||
if (sender === undefined) throw new Error("parentEvent is missing sender field");
|
if (sender === undefined) throw new Error("parentEvent is missing sender field");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// Event types are strictly checked here.
|
||||||
if (evType === EventType.RTCMembership && checkRtcMembershipData(data, sender)) {
|
if (evType === EventType.RTCMembership && checkRtcMembershipData(data, sender)) {
|
||||||
this.membershipData = { kind: MembershipKind.RTC, data };
|
this.membershipData = { kind: MembershipKind.RTC, data };
|
||||||
} else if (evType === EventType.GroupCallMemberPrefix && checkSessionsMembershipData(data)) {
|
} else if (evType === EventType.GroupCallMemberPrefix && checkSessionsMembershipData(data)) {
|
||||||
@@ -171,7 +173,7 @@ export class CallMembership {
|
|||||||
return data.application;
|
return data.application;
|
||||||
case MembershipKind.Session:
|
case MembershipKind.Session:
|
||||||
default:
|
default:
|
||||||
// XXX: This is a hack around
|
// XXX: This is a hack around
|
||||||
return { "type": data.application, "m.call.intent": data["m.call.intent"] };
|
return { "type": data.application, "m.call.intent": data["m.call.intent"] };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -249,8 +251,9 @@ export class CallMembership {
|
|||||||
const { kind } = this.membershipData;
|
const { kind } = this.membershipData;
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
case MembershipKind.RTC:
|
case MembershipKind.RTC:
|
||||||
console.log("isExpired", this.matrixEvent.unstableStickyExpiresAt, Date.now());
|
return this.matrixEvent.unstableStickyExpiresAt
|
||||||
return this.matrixEvent.unstableStickyExpiresAt ? Date.now() > this.matrixEvent.unstableStickyExpiresAt: false;
|
? Date.now() > this.matrixEvent.unstableStickyExpiresAt
|
||||||
|
: false;
|
||||||
case MembershipKind.Session:
|
case MembershipKind.Session:
|
||||||
default:
|
default:
|
||||||
return this.getMsUntilExpiry()! <= 0;
|
return this.getMsUntilExpiry()! <= 0;
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ import { type MatrixEvent } from "../models/event.ts";
|
|||||||
import { RoomStickyEventsEvent, type RoomStickyEventsMap } from "../models/room-sticky-events.ts";
|
import { RoomStickyEventsEvent, type RoomStickyEventsMap } from "../models/room-sticky-events.ts";
|
||||||
import { DefaultCallApplicationSlot } from "./CallApplication.ts";
|
import { DefaultCallApplicationSlot } from "./CallApplication.ts";
|
||||||
import { slotDescriptionToId } from "./utils.ts";
|
import { slotDescriptionToId } from "./utils.ts";
|
||||||
import { RtcMembershipData } from "./membership/rtc.ts";
|
import { type RtcMembershipData } from "./membership/rtc.ts";
|
||||||
import { RoomKeyTransport } from "./RoomKeyTransport.ts";
|
import { RoomKeyTransport } from "./RoomKeyTransport.ts";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -300,7 +300,7 @@ export class MatrixRTCSession extends TypedEventEmitter<
|
|||||||
* @returns The contents of the slot event, or null if no matching slot found.
|
* @returns The contents of the slot event, or null if no matching slot found.
|
||||||
*/
|
*/
|
||||||
public static getRtcSlot(
|
public static getRtcSlot(
|
||||||
room: Pick<Room, "getLiveTimeline"|"roomId">,
|
room: Pick<Room, "getLiveTimeline" | "roomId">,
|
||||||
slotDescription: SlotDescription,
|
slotDescription: SlotDescription,
|
||||||
): RtcSlotEventContent | null {
|
): RtcSlotEventContent | null {
|
||||||
const slotId = slotDescriptionToId(slotDescription);
|
const slotId = slotDescriptionToId(slotDescription);
|
||||||
@@ -325,8 +325,8 @@ export class MatrixRTCSession extends TypedEventEmitter<
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
"slot_id" in slotContent === false ||
|
"slot_id" in slotContent === false ||
|
||||||
typeof slotContent.slot_id !== "string" ||
|
typeof slotContent.slot_id !== "string" ||
|
||||||
!slotContent.slot_id.startsWith(slotContent.application.type + "#")
|
!slotContent.slot_id.startsWith(slotContent.application.type + "#")
|
||||||
) {
|
) {
|
||||||
logger.debug(`Mismatched app for ${room.roomId}`, slotContent);
|
logger.debug(`Mismatched app for ${room.roomId}`, slotContent);
|
||||||
@@ -361,17 +361,14 @@ export class MatrixRTCSession extends TypedEventEmitter<
|
|||||||
// Has a slot and the application parameters match, fetch sticky members.
|
// Has a slot and the application parameters match, fetch sticky members.
|
||||||
callMemberEvents = [...room._unstable_getStickyEvents()].filter((e) => {
|
callMemberEvents = [...room._unstable_getStickyEvents()].filter((e) => {
|
||||||
if (e.getType() !== EventType.RTCMembership) {
|
if (e.getType() !== EventType.RTCMembership) {
|
||||||
console.log("Invalid type");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const content = e.getContent<RtcMembershipData>();
|
const content = e.getContent<RtcMembershipData>();
|
||||||
// Ensure the slot ID of the membership matches the state
|
// Ensure the slot ID of the membership matches the state
|
||||||
if (content.slot_id !== slotId) {
|
if (content.slot_id !== slotId) {
|
||||||
console.log("Invalid slot ID", content.slot_id, slotId);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (content.application.type !== slotDescription.application) {
|
if (content.application.type !== slotDescription.application) {
|
||||||
console.log("Invalid application.type", content.application.type, slotDescription.application);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -453,7 +450,6 @@ export class MatrixRTCSession extends TypedEventEmitter<
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return callMemberships;
|
return callMemberships;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -612,7 +608,13 @@ export class MatrixRTCSession extends TypedEventEmitter<
|
|||||||
this.slotDescription,
|
this.slotDescription,
|
||||||
this.logger,
|
this.logger,
|
||||||
)
|
)
|
||||||
: new LegacyMembershipManager(joinConfig, this.roomSubset, this.client, this.slotDescription, this.logger);
|
: new LegacyMembershipManager(
|
||||||
|
joinConfig,
|
||||||
|
this.roomSubset,
|
||||||
|
this.client,
|
||||||
|
this.slotDescription,
|
||||||
|
this.logger,
|
||||||
|
);
|
||||||
|
|
||||||
this.reEmitter.reEmit(this.membershipManager!, [
|
this.reEmitter.reEmit(this.membershipManager!, [
|
||||||
MembershipManagerEvent.ProbablyLeft,
|
MembershipManagerEvent.ProbablyLeft,
|
||||||
|
|||||||
@@ -26,17 +26,10 @@ import type { MatrixClient } from "../client.ts";
|
|||||||
import { ConnectionError, HTTPError, MatrixError } from "../http-api/errors.ts";
|
import { ConnectionError, HTTPError, MatrixError } from "../http-api/errors.ts";
|
||||||
import { type Logger, logger as rootLogger } from "../logger.ts";
|
import { type Logger, logger as rootLogger } from "../logger.ts";
|
||||||
import { type Room } from "../models/room.ts";
|
import { type Room } from "../models/room.ts";
|
||||||
import {
|
import { type CallMembership, DEFAULT_EXPIRE_DURATION } from "./CallMembership.ts";
|
||||||
type CallMembership,
|
import type { RtcMembershipData } from "./membership/rtc.ts";
|
||||||
DEFAULT_EXPIRE_DURATION,
|
import type { SessionMembershipData } from "./membership/legacy.ts";
|
||||||
} from "./CallMembership.ts";
|
import { type Transport, isMyMembership, type RTCCallIntent, Status, type SlotDescription } from "./types.ts";
|
||||||
import type {
|
|
||||||
RtcMembershipData,
|
|
||||||
} from "./membership/rtc.ts"
|
|
||||||
import type {
|
|
||||||
SessionMembershipData,
|
|
||||||
} from "./membership/legacy.ts"
|
|
||||||
import { type Transport, isMyMembership, type RTCCallIntent, Status, SlotDescription } from "./types.ts";
|
|
||||||
import { type MembershipConfig, type SessionConfig } from "./MatrixRTCSession.ts";
|
import { type MembershipConfig, type SessionConfig } from "./MatrixRTCSession.ts";
|
||||||
import { ActionScheduler, type ActionUpdate } from "./MembershipManagerActionScheduler.ts";
|
import { ActionScheduler, type ActionUpdate } from "./MembershipManagerActionScheduler.ts";
|
||||||
import { TypedEventEmitter } from "../models/typed-event-emitter.ts";
|
import { TypedEventEmitter } from "../models/typed-event-emitter.ts";
|
||||||
@@ -185,7 +178,7 @@ type MembershipManagerClient = Pick<
|
|||||||
* - Stop the timer for the delay refresh
|
* - Stop the timer for the delay refresh
|
||||||
* - Stop the timer for updating the state event
|
* - Stop the timer for updating the state event
|
||||||
*/
|
*/
|
||||||
export abstract class MembershipManager<MembershipData extends SessionMembershipData|RtcMembershipData>
|
export abstract class MembershipManager<MembershipData extends SessionMembershipData | RtcMembershipData>
|
||||||
extends TypedEventEmitter<MembershipManagerEvent, MembershipManagerEventHandlerMap>
|
extends TypedEventEmitter<MembershipManagerEvent, MembershipManagerEventHandlerMap>
|
||||||
implements IMembershipManager
|
implements IMembershipManager
|
||||||
{
|
{
|
||||||
@@ -1024,25 +1017,22 @@ export class LegacyMembershipManager extends MembershipManager<SessionMembership
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected clientSendMembership: (myMembership: SessionMembershipData | EmptyObject) => Promise<ISendEventResponse> =
|
||||||
protected clientSendMembership: (
|
(myMembership) => {
|
||||||
myMembership: SessionMembershipData | EmptyObject,
|
return this.client.sendStateEvent(
|
||||||
) => Promise<ISendEventResponse> = (myMembership) => {
|
this.room.roomId,
|
||||||
return this.client.sendStateEvent(
|
EventType.GroupCallMemberPrefix,
|
||||||
this.room.roomId,
|
myMembership,
|
||||||
EventType.GroupCallMemberPrefix,
|
this.memberId,
|
||||||
myMembership,
|
);
|
||||||
this.memberId,
|
};
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of the Membership manager that uses sticky events
|
* Implementation of the Membership manager that uses sticky events
|
||||||
* rather than state events.
|
* rather than state events.
|
||||||
*
|
*
|
||||||
* This exclusively sends RTCMembershipData
|
* This exclusively sends RTCMembershipData
|
||||||
*/
|
*/
|
||||||
export class StickyEventMembershipManager extends MembershipManager<RtcMembershipData> {
|
export class StickyEventMembershipManager extends MembershipManager<RtcMembershipData> {
|
||||||
public constructor(
|
public constructor(
|
||||||
@@ -1068,9 +1058,9 @@ export class StickyEventMembershipManager extends MembershipManager<RtcMembershi
|
|||||||
{ msc4354_sticky_key: this.memberId },
|
{ msc4354_sticky_key: this.memberId },
|
||||||
);
|
);
|
||||||
|
|
||||||
protected clientSendMembership: (
|
protected clientSendMembership: (myMembership: RtcMembershipData | EmptyObject) => Promise<ISendEventResponse> = (
|
||||||
myMembership: RtcMembershipData | EmptyObject,
|
myMembership,
|
||||||
) => Promise<ISendEventResponse> = (myMembership) => {
|
) => {
|
||||||
return this.clientWithSticky._unstable_sendStickyEvent(
|
return this.clientWithSticky._unstable_sendStickyEvent(
|
||||||
this.room.roomId,
|
this.room.roomId,
|
||||||
MEMBERSHIP_STICKY_DURATION_MS,
|
MEMBERSHIP_STICKY_DURATION_MS,
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
|
/**
|
||||||
|
* Thrown when an event does not look valid for use with MatrixRTC.
|
||||||
|
*/
|
||||||
export class MatrixRTCMembershipParseError extends Error {
|
export class MatrixRTCMembershipParseError extends Error {
|
||||||
constructor(public readonly type: string, public readonly errors: string[]) {
|
public constructor(
|
||||||
|
public readonly type: string,
|
||||||
|
public readonly errors: string[],
|
||||||
|
) {
|
||||||
super(`Does not match ${type}:\n${errors.join("\n")}`);
|
super(`Does not match ${type}:\n${errors.join("\n")}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { EventType, IContent } from "../../matrix";
|
import { EventType, type IContent } from "../../matrix.ts";
|
||||||
import { RTCCallIntent, Transport } from "../types";
|
import { type RTCCallIntent, type Transport } from "../types.ts";
|
||||||
import { MatrixRTCMembershipParseError } from "./common";
|
import { MatrixRTCMembershipParseError } from "./common.ts";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* **Legacy** (MatrixRTC) session membership data.
|
* **Legacy** (MatrixRTC) session membership data.
|
||||||
@@ -31,8 +31,8 @@ export type SessionMembershipData = {
|
|||||||
* NOTE: This is still included for legacy reasons, but not consumed by the SDK.
|
* NOTE: This is still included for legacy reasons, but not consumed by the SDK.
|
||||||
*/
|
*/
|
||||||
"focus_active": {
|
"focus_active": {
|
||||||
type: string,
|
type: string;
|
||||||
focus_selection: "oldest_membership"|string,
|
focus_selection: "oldest_membership" | string;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -72,6 +72,12 @@ export type SessionMembershipData = {
|
|||||||
"m.call.intent"?: RTCCallIntent;
|
"m.call.intent"?: RTCCallIntent;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates that `data` matches the format expected by the legacy form of MSC4143.
|
||||||
|
* @param data The event content.
|
||||||
|
* @returns true if `data` is valid SessionMembershipData
|
||||||
|
* @throws {MatrixRTCMembershipParseError} if the content is not valid
|
||||||
|
*/
|
||||||
export const checkSessionsMembershipData = (data: IContent): data is SessionMembershipData => {
|
export const checkSessionsMembershipData = (data: IContent): data is SessionMembershipData => {
|
||||||
const prefix = " - ";
|
const prefix = " - ";
|
||||||
const errors: string[] = [];
|
const errors: string[] = [];
|
||||||
@@ -108,8 +114,8 @@ export const checkSessionsMembershipData = (data: IContent): data is SessionMemb
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (errors.length) {
|
if (errors.length) {
|
||||||
throw new MatrixRTCMembershipParseError(EventType.GroupCallMemberPrefix, errors)
|
throw new MatrixRTCMembershipParseError(EventType.GroupCallMemberPrefix, errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { EventType, IContent, MXID_PATTERN, RelationType } from "../../matrix";
|
import { EventType, type IContent, MXID_PATTERN, type RelationType } from "../../matrix.ts";
|
||||||
import { RtcSlotEventContent, Transport } from "../types";
|
import { type RtcSlotEventContent, type Transport } from "../types.ts";
|
||||||
import { MatrixRTCMembershipParseError } from "./common";
|
import { MatrixRTCMembershipParseError } from "./common.ts";
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the current form of MSC4143.
|
* Represents the current form of MSC4143.
|
||||||
@@ -11,7 +10,7 @@ export interface RtcMembershipData {
|
|||||||
"member": {
|
"member": {
|
||||||
claimed_user_id: string;
|
claimed_user_id: string;
|
||||||
claimed_device_id: string;
|
claimed_device_id: string;
|
||||||
id: string
|
id: string;
|
||||||
};
|
};
|
||||||
"m.relates_to"?: {
|
"m.relates_to"?: {
|
||||||
event_id: string;
|
event_id: string;
|
||||||
@@ -24,10 +23,14 @@ export interface RtcMembershipData {
|
|||||||
"sticky_key"?: string;
|
"sticky_key"?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const checkRtcMembershipData = (
|
/**
|
||||||
data: IContent,
|
* Validates that `data` matches the format expected by MSC4143.
|
||||||
referenceUserId: string,
|
* @param data The event content.
|
||||||
): data is RtcMembershipData => {
|
* @param sender The sender of the event.
|
||||||
|
* @returns true if `data` is valid RtcMembershipData
|
||||||
|
* @throws {MatrixRTCMembershipParseError} if the content is not valid
|
||||||
|
*/
|
||||||
|
export const checkRtcMembershipData = (data: IContent, sender: string): data is RtcMembershipData => {
|
||||||
const errors: string[] = [];
|
const errors: string[] = [];
|
||||||
const prefix = " - ";
|
const prefix = " - ";
|
||||||
|
|
||||||
@@ -40,13 +43,20 @@ export const checkRtcMembershipData = (
|
|||||||
if (typeof data.member !== "object" || data.member === null) {
|
if (typeof data.member !== "object" || data.member === null) {
|
||||||
errors.push(prefix + "member must be an object");
|
errors.push(prefix + "member must be an object");
|
||||||
} else {
|
} else {
|
||||||
if (typeof data.member.claimed_user_id !== "string") errors.push(prefix + "member.claimed_user_id must be string");
|
if (typeof data.member.claimed_user_id !== "string") {
|
||||||
else if (!MXID_PATTERN.test(data.member.claimed_user_id)) errors.push(prefix + "member.claimed_user_id must be a valid mxid");
|
errors.push(prefix + "member.claimed_user_id must be string");
|
||||||
|
} else if (!MXID_PATTERN.test(data.member.claimed_user_id)) {
|
||||||
|
errors.push(prefix + "member.claimed_user_id must be a valid mxid");
|
||||||
|
}
|
||||||
// This is not what the spec enforces but there currently are no rules what power levels are required to
|
// This is not what the spec enforces but there currently are no rules what power levels are required to
|
||||||
// send a m.rtc.member event for a other user. So we add this check for simplicity and to avoid possible attacks until there
|
// send a m.rtc.member event for a other user. So we add this check for simplicity and to avoid possible attacks until there
|
||||||
// is a proper definition when this is allowed.
|
// is a proper definition when this is allowed.
|
||||||
else if (data.member.claimed_user_id !== referenceUserId) errors.push(prefix + "member.claimed_user_id must match the sender");
|
else if (data.member.claimed_user_id !== sender) {
|
||||||
if (typeof data.member.claimed_device_id !== "string") errors.push(prefix + "member.claimed_device_id must be string");
|
errors.push(prefix + "member.claimed_user_id must match the sender");
|
||||||
|
}
|
||||||
|
if (typeof data.member.claimed_device_id !== "string") {
|
||||||
|
errors.push(prefix + "member.claimed_device_id must be string");
|
||||||
|
}
|
||||||
if (typeof data.member.id !== "string") errors.push(prefix + "member.id must be string");
|
if (typeof data.member.id !== "string") errors.push(prefix + "member.id must be string");
|
||||||
}
|
}
|
||||||
if (typeof data.application !== "object" || data.application === null) {
|
if (typeof data.application !== "object" || data.application === null) {
|
||||||
@@ -103,8 +113,8 @@ export const checkRtcMembershipData = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (errors.length) {
|
if (errors.length) {
|
||||||
throw new MatrixRTCMembershipParseError(EventType.RTCMembership, errors)
|
throw new MatrixRTCMembershipParseError(EventType.RTCMembership, errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -207,7 +207,7 @@ export interface RtcSlotEventContent<T extends string = string> {
|
|||||||
// other application specific keys
|
// other application specific keys
|
||||||
[key: string]: unknown;
|
[key: string]: unknown;
|
||||||
};
|
};
|
||||||
slot_id: string,
|
slot_id: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user