1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-07-31 15:24:23 +03:00

Introduce Membership TS type (take 2) (#4107)

* Introduce Membership TS type

* Adapt the Membership TS type to be an enum

* Add docstrings for KnownMembership and Membership

* Move Membership types into a separate file, exported from types.ts

---------

Co-authored-by: Stanislav Demydiuk <s.demydiuk@gmail.com>
This commit is contained in:
Andy Balaam
2024-03-18 12:47:23 +00:00
committed by GitHub
parent 3e989006aa
commit 92342c07ed
44 changed files with 505 additions and 364 deletions

View File

@ -216,7 +216,7 @@ const matrixClient = sdk.createClient({
```javascript ```javascript
matrixClient.on(RoomMemberEvent.Membership, function (event, member) { matrixClient.on(RoomMemberEvent.Membership, function (event, member) {
if (member.membership === "invite" && member.userId === myUserId) { if (member.membership === KnownMembership.Invite && member.userId === myUserId) {
matrixClient.joinRoom(member.roomId).then(function () { matrixClient.joinRoom(member.roomId).then(function () {
console.log("Auto-joined %s", member.roomId); console.log("Auto-joined %s", member.roomId);
}); });

View File

@ -115,7 +115,7 @@ rl.on("line", function (line) {
if (line.indexOf("/join ") === 0) { if (line.indexOf("/join ") === 0) {
var roomIndex = line.split(" ")[1]; var roomIndex = line.split(" ")[1];
viewingRoom = roomList[roomIndex]; viewingRoom = roomList[roomIndex];
if (viewingRoom.getMember(myUserId).membership === "invite") { if (viewingRoom.getMember(myUserId).membership === KnownMembership.Invite) {
// join the room first // join the room first
matrixClient.joinRoom(viewingRoom.roomId).then( matrixClient.joinRoom(viewingRoom.roomId).then(
function (room) { function (room) {

View File

@ -99,6 +99,7 @@ import {
} from "./olm-utils"; } from "./olm-utils";
import { ToDevicePayload } from "../../../src/models/ToDeviceMessage"; import { ToDevicePayload } from "../../../src/models/ToDeviceMessage";
import { AccountDataAccumulator } from "../../test-utils/AccountDataAccumulator"; import { AccountDataAccumulator } from "../../test-utils/AccountDataAccumulator";
import { KnownMembership } from "../../../src/@types/membership";
afterEach(() => { afterEach(() => {
// reset fake-indexeddb after each test, to make sure we don't leak connections // reset fake-indexeddb after each test, to make sure we don't leak connections
@ -1242,7 +1243,7 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("crypto (%s)", (backend: string,
content: { algorithm: "m.megolm.v1.aes-sha2" }, content: { algorithm: "m.megolm.v1.aes-sha2" },
}), }),
testUtils.mkMembership({ testUtils.mkMembership({
mship: "join", mship: KnownMembership.Join,
sender: aliceClient.getUserId()!, sender: aliceClient.getUserId()!,
}), }),
], ],
@ -1661,7 +1662,7 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("crypto (%s)", (backend: string,
type: "m.room.member", type: "m.room.member",
state_key: "@alice:localhost", state_key: "@alice:localhost",
content: { content: {
membership: "invite", membership: KnownMembership.Invite,
}, },
}, },
], ],
@ -1810,7 +1811,7 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("crypto (%s)", (backend: string,
type: "m.room.member", type: "m.room.member",
state_key: "@alice:localhost", state_key: "@alice:localhost",
content: { content: {
membership: "invite", membership: KnownMembership.Invite,
}, },
}, },
], ],
@ -1886,7 +1887,7 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("crypto (%s)", (backend: string,
{ {
type: "m.room.member", type: "m.room.member",
state_key: aliceClient.getUserId(), state_key: aliceClient.getUserId(),
content: { membership: "join" }, content: { membership: KnownMembership.Join },
event_id: "$alijoin", event_id: "$alijoin",
}, },
], ],
@ -1913,7 +1914,7 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("crypto (%s)", (backend: string,
{ {
type: "m.room.member", type: "m.room.member",
state_key: "@other:user", state_key: "@other:user",
content: { membership: "invite" }, content: { membership: KnownMembership.Invite },
event_id: "$otherinvite", event_id: "$otherinvite",
}, },
], ],
@ -2061,7 +2062,7 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("crypto (%s)", (backend: string,
fetchMock.getOnce(new RegExp(membersPath), { fetchMock.getOnce(new RegExp(membersPath), {
chunk: [ chunk: [
testUtils.mkMembershipCustom({ testUtils.mkMembershipCustom({
membership: "join", membership: KnownMembership.Join,
sender: "@bob:xyz", sender: "@bob:xyz",
}), }),
], ],
@ -3090,7 +3091,10 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("crypto (%s)", (backend: string,
const roomResponse = { const roomResponse = {
state: { state: {
events: [ events: [
mkMembershipCustom({ membership: "join", sender: persistentStoreClient.getSafeUserId() }), mkMembershipCustom({
membership: KnownMembership.Join,
sender: persistentStoreClient.getSafeUserId(),
}),
...stateEvents, ...stateEvents,
], ],
}, },

View File

@ -36,6 +36,7 @@ import { TestClient } from "../../TestClient";
import { CRYPTO_ENABLED, IClaimKeysRequest, IQueryKeysRequest, IUploadKeysRequest } from "../../../src/client"; import { CRYPTO_ENABLED, IClaimKeysRequest, IQueryKeysRequest, IUploadKeysRequest } from "../../../src/client";
import { ClientEvent, IContent, ISendEventResponse, MatrixClient, MatrixEvent } from "../../../src/matrix"; import { ClientEvent, IContent, ISendEventResponse, MatrixClient, MatrixEvent } from "../../../src/matrix";
import { DeviceInfo } from "../../../src/crypto/deviceinfo"; import { DeviceInfo } from "../../../src/crypto/deviceinfo";
import { KnownMembership } from "../../../src/@types/membership";
let aliTestClient: TestClient; let aliTestClient: TestClient;
const roomId = "!room:localhost"; const roomId = "!room:localhost";
@ -316,11 +317,11 @@ function firstSync(testClient: TestClient): Promise<void> {
state: { state: {
events: [ events: [
testUtils.mkMembership({ testUtils.mkMembership({
mship: "join", mship: KnownMembership.Join,
user: aliUserId, user: aliUserId,
}), }),
testUtils.mkMembership({ testUtils.mkMembership({
mship: "join", mship: KnownMembership.Join,
user: bobUserId, user: bobUserId,
}), }),
], ],

View File

@ -19,6 +19,7 @@ limitations under the License.
import { TestClient } from "../TestClient"; import { TestClient } from "../TestClient";
import * as testUtils from "../test-utils/test-utils"; import * as testUtils from "../test-utils/test-utils";
import { logger } from "../../src/logger"; import { logger } from "../../src/logger";
import { KnownMembership } from "../../src/@types/membership";
const ROOM_ID = "!room:id"; const ROOM_ID = "!room:id";
@ -43,7 +44,7 @@ function getSyncResponse(roomMembers: string[]) {
stateEvents, stateEvents,
roomMembers.map((m) => roomMembers.map((m) =>
testUtils.mkMembership({ testUtils.mkMembership({
mship: "join", mship: KnownMembership.Join,
sender: m, sender: m,
}), }),
), ),
@ -323,7 +324,7 @@ describe("DeviceList management:", function () {
timeline: { timeline: {
events: [ events: [
testUtils.mkMembership({ testUtils.mkMembership({
mship: "leave", mship: KnownMembership.Leave,
sender: "@bob:xyz", sender: "@bob:xyz",
}), }),
], ],
@ -357,7 +358,7 @@ describe("DeviceList management:", function () {
timeline: { timeline: {
events: [ events: [
testUtils.mkMembership({ testUtils.mkMembership({
mship: "leave", mship: KnownMembership.Leave,
sender: "@bob:xyz", sender: "@bob:xyz",
}), }),
], ],

View File

@ -28,6 +28,7 @@ import {
} from "../../src"; } from "../../src";
import * as utils from "../test-utils/test-utils"; import * as utils from "../test-utils/test-utils";
import { TestClient } from "../TestClient"; import { TestClient } from "../TestClient";
import { KnownMembership } from "../../src/@types/membership";
describe("MatrixClient events", function () { describe("MatrixClient events", function () {
const selfUserId = "@alice:localhost"; const selfUserId = "@alice:localhost";
@ -85,7 +86,7 @@ describe("MatrixClient events", function () {
events: [ events: [
utils.mkMembership({ utils.mkMembership({
room: "!erufh:bar", room: "!erufh:bar",
mship: "join", mship: KnownMembership.Join,
user: "@foo:bar", user: "@foo:bar",
}), }),
utils.mkEvent({ utils.mkEvent({
@ -272,7 +273,7 @@ describe("MatrixClient events", function () {
membersInvokeCount++; membersInvokeCount++;
expect(member.roomId).toEqual("!erufh:bar"); expect(member.roomId).toEqual("!erufh:bar");
expect(member.userId).toEqual("@foo:bar"); expect(member.userId).toEqual("@foo:bar");
expect(member.membership).toEqual("join"); expect(member.membership).toEqual(KnownMembership.Join);
}); });
client!.on(RoomStateEvent.NewMember, function (event, state, member) { client!.on(RoomStateEvent.NewMember, function (event, state, member) {
newMemberInvokeCount++; newMemberInvokeCount++;
@ -310,7 +311,7 @@ describe("MatrixClient events", function () {
}); });
client!.on(RoomMemberEvent.Membership, function (event, member) { client!.on(RoomMemberEvent.Membership, function (event, member) {
membershipInvokeCount++; membershipInvokeCount++;
expect(member.membership).toEqual("join"); expect(member.membership).toEqual(KnownMembership.Join);
}); });
client!.startClient(); client!.startClient();

View File

@ -36,6 +36,7 @@ import { TestClient } from "../TestClient";
import { FeatureSupport, Thread, ThreadEvent } from "../../src/models/thread"; import { FeatureSupport, Thread, ThreadEvent } from "../../src/models/thread";
import { emitPromise } from "../test-utils/test-utils"; import { emitPromise } from "../test-utils/test-utils";
import { Feature, ServerSupport } from "../../src/feature"; import { Feature, ServerSupport } from "../../src/feature";
import { KnownMembership } from "../../src/@types/membership";
const userId = "@alice:localhost"; const userId = "@alice:localhost";
const userName = "Alice"; const userName = "Alice";
@ -63,7 +64,7 @@ const buildRelationPaginationQuery = (params: QueryDict): string => {
const USER_MEMBERSHIP_EVENT = utils.mkMembership({ const USER_MEMBERSHIP_EVENT = utils.mkMembership({
room: roomId, room: roomId,
mship: "join", mship: KnownMembership.Join,
user: userId, user: userId,
name: userName, name: userName,
event: false, event: false,
@ -98,7 +99,7 @@ const INITIAL_SYNC_DATA = {
events: [ events: [
withoutRoomId(ROOM_NAME_EVENT), withoutRoomId(ROOM_NAME_EVENT),
utils.mkMembership({ utils.mkMembership({
mship: "join", mship: KnownMembership.Join,
user: otherUserId, user: otherUserId,
name: "Bob", name: "Bob",
event: false, event: false,
@ -1921,7 +1922,7 @@ describe("MatrixClient event timelines", function () {
// a state event, followed by a redaction thereof // a state event, followed by a redaction thereof
const event = utils.mkMembership({ const event = utils.mkMembership({
mship: "join", mship: KnownMembership.Join,
user: otherUserId, user: otherUserId,
}); });
const redaction = utils.mkEvent({ const redaction = utils.mkEvent({

View File

@ -27,6 +27,7 @@ import { ISearchResults } from "../../src/@types/search";
import { IStore } from "../../src/store"; import { IStore } from "../../src/store";
import { CryptoBackend } from "../../src/common-crypto/CryptoBackend"; import { CryptoBackend } from "../../src/common-crypto/CryptoBackend";
import { SetPresence } from "../../src/sync"; import { SetPresence } from "../../src/sync";
import { KnownMembership } from "../../src/@types/membership";
describe("MatrixClient", function () { describe("MatrixClient", function () {
const userId = "@alice:localhost"; const userId = "@alice:localhost";
@ -162,7 +163,7 @@ describe("MatrixClient", function () {
utils.mkMembership({ utils.mkMembership({
user: userId, user: userId,
room: roomId, room: roomId,
mship: "join", mship: KnownMembership.Join,
event: true, event: true,
}), }),
]); ]);
@ -182,7 +183,7 @@ describe("MatrixClient", function () {
utils.mkMembership({ utils.mkMembership({
user: userId, user: userId,
room: roomId, room: roomId,
mship: "join", mship: KnownMembership.Join,
event: true, event: true,
}), }),
]); ]);
@ -269,7 +270,7 @@ describe("MatrixClient", function () {
utils.mkMembership({ utils.mkMembership({
user: userId, user: userId,
room: roomId, room: roomId,
mship: "knock", mship: KnownMembership.Knock,
event: true, event: true,
}), }),
]); ]);
@ -1912,7 +1913,7 @@ const buildEventJoinRules = () =>
new MatrixEvent({ new MatrixEvent({
age: 80123696, age: 80123696,
content: { content: {
join_rule: "invite", join_rule: KnownMembership.Invite,
}, },
event_id: "$6JDDeDp7fEc0F6YnTWMruNcKWFltR3e9wk7wWDDJrAU", event_id: "$6JDDeDp7fEc0F6YnTWMruNcKWFltR3e9wk7wWDDJrAU",
origin_server_ts: 1643815441191, origin_server_ts: 1643815441191,
@ -1966,7 +1967,7 @@ const buildEventMember = () =>
content: { content: {
avatar_url: "mxc://matrix.org/aNtbVcFfwotudypZcHsIcPOc", avatar_url: "mxc://matrix.org/aNtbVcFfwotudypZcHsIcPOc",
displayname: "andybalaam-test1", displayname: "andybalaam-test1",
membership: "join", membership: KnownMembership.Join,
}, },
event_id: "$Ex5eVmMs_ti784mo8bgddynbwLvy6231lCycJr7Cl9M", event_id: "$Ex5eVmMs_ti784mo8bgddynbwLvy6231lCycJr7Cl9M",
origin_server_ts: 1643815439608, origin_server_ts: 1643815439608,

View File

@ -6,6 +6,7 @@ import { MatrixScheduler } from "../../src/scheduler";
import { MemoryStore } from "../../src/store/memory"; import { MemoryStore } from "../../src/store/memory";
import { MatrixError } from "../../src/http-api"; import { MatrixError } from "../../src/http-api";
import { IStore } from "../../src/store"; import { IStore } from "../../src/store";
import { KnownMembership } from "../../src/@types/membership";
describe("MatrixClient opts", function () { describe("MatrixClient opts", function () {
const baseUrl = "http://localhost.or.something"; const baseUrl = "http://localhost.or.something";
@ -43,13 +44,13 @@ describe("MatrixClient opts", function () {
}), }),
utils.mkMembership({ utils.mkMembership({
room: roomId, room: roomId,
mship: "join", mship: KnownMembership.Join,
user: userB, user: userB,
name: "Bob", name: "Bob",
}), }),
utils.mkMembership({ utils.mkMembership({
room: roomId, room: roomId,
mship: "join", mship: KnownMembership.Join,
user: userId, user: userId,
name: "Alice", name: "Alice",
}), }),

View File

@ -30,6 +30,7 @@ import {
Room, Room,
} from "../../src"; } from "../../src";
import { TestClient } from "../TestClient"; import { TestClient } from "../TestClient";
import { KnownMembership } from "../../src/@types/membership";
describe("MatrixClient room timelines", function () { describe("MatrixClient room timelines", function () {
const userId = "@alice:localhost"; const userId = "@alice:localhost";
@ -42,7 +43,7 @@ describe("MatrixClient room timelines", function () {
const USER_MEMBERSHIP_EVENT = utils.mkMembership({ const USER_MEMBERSHIP_EVENT = utils.mkMembership({
room: roomId, room: roomId,
mship: "join", mship: KnownMembership.Join,
user: userId, user: userId,
name: userName, name: userName,
}); });
@ -76,7 +77,7 @@ describe("MatrixClient room timelines", function () {
ROOM_NAME_EVENT, ROOM_NAME_EVENT,
utils.mkMembership({ utils.mkMembership({
room: roomId, room: roomId,
mship: "join", mship: KnownMembership.Join,
user: otherUserId, user: otherUserId,
name: "Bob", name: "Bob",
}), }),
@ -316,7 +317,7 @@ describe("MatrixClient room timelines", function () {
// make an m.room.member event for alice's join // make an m.room.member event for alice's join
const joinMshipEvent = utils.mkMembership({ const joinMshipEvent = utils.mkMembership({
mship: "join", mship: KnownMembership.Join,
user: userId, user: userId,
room: roomId, room: roomId,
name: "Old Alice", name: "Old Alice",
@ -326,7 +327,7 @@ describe("MatrixClient room timelines", function () {
// make an m.room.member event with prev_content for alice's nick // make an m.room.member event with prev_content for alice's nick
// change // change
const oldMshipEvent = utils.mkMembership({ const oldMshipEvent = utils.mkMembership({
mship: "join", mship: KnownMembership.Join,
user: userId, user: userId,
room: roomId, room: roomId,
name: userName, name: userName,
@ -335,7 +336,7 @@ describe("MatrixClient room timelines", function () {
oldMshipEvent.prev_content = { oldMshipEvent.prev_content = {
displayname: "Old Alice", displayname: "Old Alice",
avatar_url: undefined, avatar_url: undefined,
membership: "join", membership: KnownMembership.Join,
}; };
// set the list of events to return on scrollback (/messages) // set the list of events to return on scrollback (/messages)
@ -487,7 +488,7 @@ describe("MatrixClient room timelines", function () {
utils.mkMembership({ utils.mkMembership({
user: userId, user: userId,
room: roomId, room: roomId,
mship: "join", mship: KnownMembership.Join,
name: "New Name", name: "New Name",
}), }),
utils.mkMessage({ user: userId, room: roomId }), utils.mkMessage({ user: userId, room: roomId }),
@ -554,13 +555,13 @@ describe("MatrixClient room timelines", function () {
utils.mkMembership({ utils.mkMembership({
user: userC, user: userC,
room: roomId, room: roomId,
mship: "join", mship: KnownMembership.Join,
name: "C", name: "C",
}), }),
utils.mkMembership({ utils.mkMembership({
user: userC, user: userC,
room: roomId, room: roomId,
mship: "invite", mship: KnownMembership.Invite,
skey: userD, skey: userD,
}), }),
]; ];
@ -571,9 +572,9 @@ describe("MatrixClient room timelines", function () {
return Promise.all([httpBackend!.flush("/sync", 1), utils.syncPromise(client!)]).then(function () { return Promise.all([httpBackend!.flush("/sync", 1), utils.syncPromise(client!)]).then(function () {
expect(room.currentState.getMembers().length).toEqual(4); expect(room.currentState.getMembers().length).toEqual(4);
expect(room.currentState.getMember(userC)!.name).toEqual("C"); expect(room.currentState.getMember(userC)!.name).toEqual("C");
expect(room.currentState.getMember(userC)!.membership).toEqual("join"); expect(room.currentState.getMember(userC)!.membership).toEqual(KnownMembership.Join);
expect(room.currentState.getMember(userD)!.name).toEqual(userD); expect(room.currentState.getMember(userD)!.name).toEqual(userD);
expect(room.currentState.getMember(userD)!.membership).toEqual("invite"); expect(room.currentState.getMember(userD)!.membership).toEqual(KnownMembership.Invite);
}); });
}); });
}); });
@ -598,9 +599,9 @@ describe("MatrixClient room timelines", function () {
expect(room.timeline[0].event).toEqual(eventData[0]); expect(room.timeline[0].event).toEqual(eventData[0]);
expect(room.currentState.getMembers().length).toEqual(2); expect(room.currentState.getMembers().length).toEqual(2);
expect(room.currentState.getMember(userId)!.name).toEqual(userName); expect(room.currentState.getMember(userId)!.name).toEqual(userName);
expect(room.currentState.getMember(userId)!.membership).toEqual("join"); expect(room.currentState.getMember(userId)!.membership).toEqual(KnownMembership.Join);
expect(room.currentState.getMember(otherUserId)!.name).toEqual("Bob"); expect(room.currentState.getMember(otherUserId)!.name).toEqual("Bob");
expect(room.currentState.getMember(otherUserId)!.membership).toEqual("join"); expect(room.currentState.getMember(otherUserId)!.membership).toEqual(KnownMembership.Join);
}); });
}); });
}); });

View File

@ -46,6 +46,7 @@ import * as utils from "../test-utils/test-utils";
import { TestClient } from "../TestClient"; import { TestClient } from "../TestClient";
import { emitPromise, mkEvent, mkMessage } from "../test-utils/test-utils"; import { emitPromise, mkEvent, mkMessage } from "../test-utils/test-utils";
import { THREAD_RELATION_TYPE } from "../../src/models/thread"; import { THREAD_RELATION_TYPE } from "../../src/models/thread";
import { KnownMembership } from "../../src/@types/membership";
describe("MatrixClient syncing", () => { describe("MatrixClient syncing", () => {
const selfUserId = "@alice:localhost"; const selfUserId = "@alice:localhost";
@ -123,7 +124,7 @@ describe("MatrixClient syncing", () => {
type: "m.room.member", type: "m.room.member",
state_key: selfUserId, state_key: selfUserId,
content: { content: {
membership: "invite", membership: KnownMembership.Invite,
}, },
}, },
], ],
@ -151,10 +152,10 @@ describe("MatrixClient syncing", () => {
type: "m.room.member", type: "m.room.member",
state_key: selfUserId, state_key: selfUserId,
content: { content: {
membership: "leave", membership: KnownMembership.Leave,
}, },
prev_content: { prev_content: {
membership: "invite", membership: KnownMembership.Invite,
}, },
// XXX: And other fields required on an event // XXX: And other fields required on an event
}, },
@ -167,10 +168,10 @@ describe("MatrixClient syncing", () => {
type: "m.room.member", type: "m.room.member",
state_key: selfUserId, state_key: selfUserId,
content: { content: {
membership: "leave", membership: KnownMembership.Leave,
}, },
prev_content: { prev_content: {
membership: "invite", membership: KnownMembership.Invite,
}, },
// XXX: And other fields required on an event // XXX: And other fields required on an event
}, },
@ -193,22 +194,22 @@ describe("MatrixClient syncing", () => {
// Room, string, string // Room, string, string
fires++; fires++;
expect(room.roomId).toBe(roomId); expect(room.roomId).toBe(roomId);
expect(membership).toBe("invite"); expect(membership).toBe(KnownMembership.Invite);
expect(oldMembership).toBeFalsy(); expect(oldMembership).toBeFalsy();
// Second fire: a leave // Second fire: a leave
client!.once(RoomEvent.MyMembership, (room, membership, oldMembership) => { client!.once(RoomEvent.MyMembership, (room, membership, oldMembership) => {
fires++; fires++;
expect(room.roomId).toBe(roomId); expect(room.roomId).toBe(roomId);
expect(membership).toBe("leave"); expect(membership).toBe(KnownMembership.Leave);
expect(oldMembership).toBe("invite"); expect(oldMembership).toBe(KnownMembership.Invite);
// Third/final fire: a second invite // Third/final fire: a second invite
client!.once(RoomEvent.MyMembership, (room, membership, oldMembership) => { client!.once(RoomEvent.MyMembership, (room, membership, oldMembership) => {
fires++; fires++;
expect(room.roomId).toBe(roomId); expect(room.roomId).toBe(roomId);
expect(membership).toBe("invite"); expect(membership).toBe(KnownMembership.Invite);
expect(oldMembership).toBe("leave"); expect(oldMembership).toBe(KnownMembership.Leave);
}); });
}); });
@ -238,7 +239,7 @@ describe("MatrixClient syncing", () => {
type: "m.room.member", type: "m.room.member",
state_key: selfUserId, state_key: selfUserId,
content: { content: {
membership: "knock", membership: KnownMembership.Knock,
}, },
}, },
], ],
@ -266,10 +267,10 @@ describe("MatrixClient syncing", () => {
type: "m.room.member", type: "m.room.member",
state_key: selfUserId, state_key: selfUserId,
content: { content: {
membership: "leave", membership: KnownMembership.Leave,
}, },
prev_content: { prev_content: {
membership: "knock", membership: KnownMembership.Knock,
}, },
// XXX: And other fields required on an event // XXX: And other fields required on an event
}, },
@ -282,10 +283,10 @@ describe("MatrixClient syncing", () => {
type: "m.room.member", type: "m.room.member",
state_key: selfUserId, state_key: selfUserId,
content: { content: {
membership: "leave", membership: KnownMembership.Leave,
}, },
prev_content: { prev_content: {
membership: "knock", membership: KnownMembership.Knock,
}, },
// XXX: And other fields required on an event // XXX: And other fields required on an event
}, },
@ -308,22 +309,22 @@ describe("MatrixClient syncing", () => {
// Room, string, string // Room, string, string
fires++; fires++;
expect(room.roomId).toBe(roomId); expect(room.roomId).toBe(roomId);
expect(membership).toBe("knock"); expect(membership).toBe(KnownMembership.Knock);
expect(oldMembership).toBeFalsy(); expect(oldMembership).toBeFalsy();
// Second fire: a leave // Second fire: a leave
client!.once(RoomEvent.MyMembership, (room, membership, oldMembership) => { client!.once(RoomEvent.MyMembership, (room, membership, oldMembership) => {
fires++; fires++;
expect(room.roomId).toBe(roomId); expect(room.roomId).toBe(roomId);
expect(membership).toBe("leave"); expect(membership).toBe(KnownMembership.Leave);
expect(oldMembership).toBe("knock"); expect(oldMembership).toBe(KnownMembership.Knock);
// Third/final fire: a second knock // Third/final fire: a second knock
client!.once(RoomEvent.MyMembership, (room, membership, oldMembership) => { client!.once(RoomEvent.MyMembership, (room, membership, oldMembership) => {
fires++; fires++;
expect(room.roomId).toBe(roomId); expect(room.roomId).toBe(roomId);
expect(membership).toBe("knock"); expect(membership).toBe(KnownMembership.Knock);
expect(oldMembership).toBe("leave"); expect(oldMembership).toBe(KnownMembership.Leave);
}); });
}); });
@ -381,7 +382,7 @@ describe("MatrixClient syncing", () => {
type: "m.room.member", type: "m.room.member",
state_key: selfUserId, state_key: selfUserId,
content: { content: {
membership: "invite", membership: KnownMembership.Invite,
}, },
}, },
], ],
@ -421,7 +422,7 @@ describe("MatrixClient syncing", () => {
type: "m.room.member", type: "m.room.member",
state_key: selfUserId, state_key: selfUserId,
content: { content: {
membership: "knock", membership: KnownMembership.Knock,
}, },
}, },
], ],
@ -533,12 +534,12 @@ describe("MatrixClient syncing", () => {
events: [ events: [
utils.mkMembership({ utils.mkMembership({
room: roomOne, room: roomOne,
mship: "join", mship: KnownMembership.Join,
user: otherUserId, user: otherUserId,
}), }),
utils.mkMembership({ utils.mkMembership({
room: roomOne, room: roomOne,
mship: "join", mship: KnownMembership.Join,
user: selfUserId, user: selfUserId,
}), }),
utils.mkEvent({ utils.mkEvent({
@ -556,7 +557,7 @@ describe("MatrixClient syncing", () => {
syncData.rooms.join[roomOne].state.events.push( syncData.rooms.join[roomOne].state.events.push(
utils.mkMembership({ utils.mkMembership({
room: roomOne, room: roomOne,
mship: "invite", mship: KnownMembership.Invite,
user: userC, user: userC,
}) as IStateEvent, }) as IStateEvent,
); );
@ -589,7 +590,7 @@ describe("MatrixClient syncing", () => {
syncData.rooms.join[roomOne].state.events.push( syncData.rooms.join[roomOne].state.events.push(
utils.mkMembership({ utils.mkMembership({
room: roomOne, room: roomOne,
mship: "invite", mship: KnownMembership.Invite,
user: userC, user: userC,
}) as IStateEvent, }) as IStateEvent,
); );
@ -617,7 +618,7 @@ describe("MatrixClient syncing", () => {
syncData.rooms.join[roomOne].state.events.push( syncData.rooms.join[roomOne].state.events.push(
utils.mkMembership({ utils.mkMembership({
room: roomOne, room: roomOne,
mship: "invite", mship: KnownMembership.Invite,
user: userC, user: userC,
}) as IStateEvent, }) as IStateEvent,
); );
@ -644,7 +645,7 @@ describe("MatrixClient syncing", () => {
syncData.rooms.join[roomOne].state.events.push( syncData.rooms.join[roomOne].state.events.push(
utils.mkMembership({ utils.mkMembership({
room: roomOne, room: roomOne,
mship: "invite", mship: KnownMembership.Invite,
user: userC, user: userC,
}) as IStateEvent, }) as IStateEvent,
); );
@ -719,12 +720,12 @@ describe("MatrixClient syncing", () => {
}), }),
utils.mkMembership({ utils.mkMembership({
room: roomOne, room: roomOne,
mship: "join", mship: KnownMembership.Join,
user: otherUserId, user: otherUserId,
}), }),
utils.mkMembership({ utils.mkMembership({
room: roomOne, room: roomOne,
mship: "join", mship: KnownMembership.Join,
user: selfUserId, user: selfUserId,
}), }),
utils.mkEvent({ utils.mkEvent({
@ -750,13 +751,13 @@ describe("MatrixClient syncing", () => {
events: [ events: [
utils.mkMembership({ utils.mkMembership({
room: roomTwo, room: roomTwo,
mship: "join", mship: KnownMembership.Join,
user: otherUserId, user: otherUserId,
name: otherDisplayName, name: otherDisplayName,
}), }),
utils.mkMembership({ utils.mkMembership({
room: roomTwo, room: roomTwo,
mship: "join", mship: KnownMembership.Join,
user: selfUserId, user: selfUserId,
}), }),
utils.mkEvent({ utils.mkEvent({
@ -1247,7 +1248,7 @@ describe("MatrixClient syncing", () => {
const USER_MEMBERSHIP_EVENT = utils.mkMembership({ const USER_MEMBERSHIP_EVENT = utils.mkMembership({
room: roomOne, room: roomOne,
mship: "join", mship: KnownMembership.Join,
user: userA, user: userA,
}); });
@ -1508,12 +1509,12 @@ describe("MatrixClient syncing", () => {
}), }),
utils.mkMembership({ utils.mkMembership({
room: roomOne, room: roomOne,
mship: "join", mship: KnownMembership.Join,
user: otherUserId, user: otherUserId,
}), }),
utils.mkMembership({ utils.mkMembership({
room: roomOne, room: roomOne,
mship: "join", mship: KnownMembership.Join,
user: selfUserId, user: selfUserId,
}), }),
utils.mkEvent({ utils.mkEvent({
@ -1605,12 +1606,12 @@ describe("MatrixClient syncing", () => {
}), }),
utils.mkMembership({ utils.mkMembership({
room: roomOne, room: roomOne,
mship: "join", mship: KnownMembership.Join,
user: otherUserId, user: otherUserId,
}), }),
utils.mkMembership({ utils.mkMembership({
room: roomOne, room: roomOne,
mship: "join", mship: KnownMembership.Join,
user: selfUserId, user: selfUserId,
}), }),
utils.mkEvent({ utils.mkEvent({
@ -1761,12 +1762,12 @@ describe("MatrixClient syncing", () => {
events: [ events: [
utils.mkMembership({ utils.mkMembership({
room: roomId, room: roomId,
mship: "join", mship: KnownMembership.Join,
user: otherUserId, user: otherUserId,
}), }),
utils.mkMembership({ utils.mkMembership({
room: roomId, room: roomId,
mship: "join", mship: KnownMembership.Join,
user: selfUserId, user: selfUserId,
}), }),
utils.mkEvent({ utils.mkEvent({
@ -1901,7 +1902,7 @@ describe("MatrixClient syncing", () => {
it("should return a room based on the room initialSync API", async () => { it("should return a room based on the room initialSync API", async () => {
httpBackend!.when("GET", `/rooms/${encodeURIComponent(roomOne)}/initialSync`).respond(200, { httpBackend!.when("GET", `/rooms/${encodeURIComponent(roomOne)}/initialSync`).respond(200, {
room_id: roomOne, room_id: roomOne,
membership: "leave", membership: KnownMembership.Leave,
messages: { messages: {
start: "start", start: "start",
end: "end", end: "end",
@ -1950,7 +1951,7 @@ describe("MatrixClient syncing", () => {
const room = await prom; const room = await prom;
expect(room.roomId).toBe(roomOne); expect(room.roomId).toBe(roomOne);
expect(room.getMyMembership()).toBe("leave"); expect(room.getMyMembership()).toBe(KnownMembership.Leave);
expect(room.name).toBe("Room Name"); expect(room.name).toBe("Room Name");
expect(room.currentState.getStateEvents("m.room.name", "")?.getId()).toBe("$eventId"); expect(room.currentState.getStateEvents("m.room.name", "")?.getId()).toBe("$eventId");
expect(room.timeline[0].getContent().body).toBe("Message 1"); expect(room.timeline[0].getContent().body).toBe("Message 1");
@ -2042,7 +2043,7 @@ describe("MatrixClient syncing (IndexedDB version)", () => {
type: "m.room.member", type: "m.room.member",
state_key: selfUserId, state_key: selfUserId,
content: { content: {
membership: "invite", membership: KnownMembership.Invite,
}, },
}, },
], ],

View File

@ -34,6 +34,7 @@ import { TestClient } from "../TestClient";
import { ReceiptType } from "../../src/@types/read_receipts"; import { ReceiptType } from "../../src/@types/read_receipts";
import { mkThread } from "../test-utils/thread"; import { mkThread } from "../test-utils/thread";
import { SyncState } from "../../src/sync"; import { SyncState } from "../../src/sync";
import { KnownMembership } from "../../src/@types/membership";
const userA = "@alice:localhost"; const userA = "@alice:localhost";
const userB = "@bob:localhost"; const userB = "@bob:localhost";
@ -229,7 +230,7 @@ describe("MatrixClient syncing", () => {
content: { content: {
avatar_url: "", avatar_url: "",
displayname: userB, displayname: userB,
membership: "join", membership: KnownMembership.Join,
}, },
origin_server_ts: 2, origin_server_ts: 2,
sender: userB, sender: userB,
@ -270,7 +271,7 @@ describe("MatrixClient syncing", () => {
}, },
{ {
content: { content: {
join_rule: "invite", join_rule: KnownMembership.Invite,
}, },
origin_server_ts: 4, origin_server_ts: 4,
sender: userB, sender: userB,
@ -316,7 +317,7 @@ describe("MatrixClient syncing", () => {
avatar_url: "", avatar_url: "",
displayname: userA, displayname: userA,
is_direct: true, is_direct: true,
membership: "invite", membership: KnownMembership.Invite,
}, },
origin_server_ts: 8, origin_server_ts: 8,
sender: userB, sender: userB,
@ -338,7 +339,7 @@ describe("MatrixClient syncing", () => {
content: { content: {
avatar_url: "", avatar_url: "",
displayname: userA, displayname: userA,
membership: "join", membership: KnownMembership.Join,
}, },
origin_server_ts: 10, origin_server_ts: 10,
sender: userA, sender: userA,

View File

@ -43,6 +43,7 @@ import { IStoredClientOpts } from "../../src";
import { logger } from "../../src/logger"; import { logger } from "../../src/logger";
import { emitPromise } from "../test-utils/test-utils"; import { emitPromise } from "../test-utils/test-utils";
import { defer } from "../../src/utils"; import { defer } from "../../src/utils";
import { KnownMembership } from "../../src/@types/membership";
describe("SlidingSyncSdk", () => { describe("SlidingSyncSdk", () => {
let client: MatrixClient | undefined; let client: MatrixClient | undefined;
@ -189,7 +190,7 @@ describe("SlidingSyncSdk", () => {
name: "A", name: "A",
required_state: [ required_state: [
mkOwnStateEvent(EventType.RoomCreate, {}, ""), mkOwnStateEvent(EventType.RoomCreate, {}, ""),
mkOwnStateEvent(EventType.RoomMember, { membership: "join" }, selfUserId), mkOwnStateEvent(EventType.RoomMember, { membership: KnownMembership.Join }, selfUserId),
mkOwnStateEvent(EventType.RoomPowerLevels, { users: { [selfUserId]: 100 } }, ""), mkOwnStateEvent(EventType.RoomPowerLevels, { users: { [selfUserId]: 100 } }, ""),
mkOwnStateEvent(EventType.RoomName, { name: "A" }, ""), mkOwnStateEvent(EventType.RoomName, { name: "A" }, ""),
], ],
@ -204,7 +205,7 @@ describe("SlidingSyncSdk", () => {
required_state: [], required_state: [],
timeline: [ timeline: [
mkOwnStateEvent(EventType.RoomCreate, {}, ""), mkOwnStateEvent(EventType.RoomCreate, {}, ""),
mkOwnStateEvent(EventType.RoomMember, { membership: "join" }, selfUserId), mkOwnStateEvent(EventType.RoomMember, { membership: KnownMembership.Join }, selfUserId),
mkOwnStateEvent(EventType.RoomPowerLevels, { users: { [selfUserId]: 100 } }, ""), mkOwnStateEvent(EventType.RoomPowerLevels, { users: { [selfUserId]: 100 } }, ""),
mkOwnEvent(EventType.RoomMessage, { body: "hello B" }), mkOwnEvent(EventType.RoomMessage, { body: "hello B" }),
mkOwnEvent(EventType.RoomMessage, { body: "world B" }), mkOwnEvent(EventType.RoomMessage, { body: "world B" }),
@ -216,7 +217,7 @@ describe("SlidingSyncSdk", () => {
required_state: [], required_state: [],
timeline: [ timeline: [
mkOwnStateEvent(EventType.RoomCreate, {}, ""), mkOwnStateEvent(EventType.RoomCreate, {}, ""),
mkOwnStateEvent(EventType.RoomMember, { membership: "join" }, selfUserId), mkOwnStateEvent(EventType.RoomMember, { membership: KnownMembership.Join }, selfUserId),
mkOwnStateEvent(EventType.RoomPowerLevels, { users: { [selfUserId]: 100 } }, ""), mkOwnStateEvent(EventType.RoomPowerLevels, { users: { [selfUserId]: 100 } }, ""),
mkOwnEvent(EventType.RoomMessage, { body: "hello C" }), mkOwnEvent(EventType.RoomMessage, { body: "hello C" }),
mkOwnEvent(EventType.RoomMessage, { body: "world C" }), mkOwnEvent(EventType.RoomMessage, { body: "world C" }),
@ -229,7 +230,7 @@ describe("SlidingSyncSdk", () => {
required_state: [], required_state: [],
timeline: [ timeline: [
mkOwnStateEvent(EventType.RoomCreate, {}, ""), mkOwnStateEvent(EventType.RoomCreate, {}, ""),
mkOwnStateEvent(EventType.RoomMember, { membership: "join" }, selfUserId), mkOwnStateEvent(EventType.RoomMember, { membership: KnownMembership.Join }, selfUserId),
mkOwnStateEvent(EventType.RoomPowerLevels, { users: { [selfUserId]: 100 } }, ""), mkOwnStateEvent(EventType.RoomPowerLevels, { users: { [selfUserId]: 100 } }, ""),
mkOwnEvent(EventType.RoomMessage, { body: "hello D" }), mkOwnEvent(EventType.RoomMessage, { body: "hello D" }),
mkOwnEvent(EventType.RoomMessage, { body: "world D" }), mkOwnEvent(EventType.RoomMessage, { body: "world D" }),
@ -244,7 +245,7 @@ describe("SlidingSyncSdk", () => {
invite_state: [ invite_state: [
{ {
type: EventType.RoomMember, type: EventType.RoomMember,
content: { membership: "invite" }, content: { membership: KnownMembership.Invite },
state_key: selfUserId, state_key: selfUserId,
sender: "@bob:localhost", sender: "@bob:localhost",
event_id: "$room_e_invite", event_id: "$room_e_invite",
@ -265,7 +266,7 @@ describe("SlidingSyncSdk", () => {
name: "#foo:localhost", name: "#foo:localhost",
required_state: [ required_state: [
mkOwnStateEvent(EventType.RoomCreate, {}, ""), mkOwnStateEvent(EventType.RoomCreate, {}, ""),
mkOwnStateEvent(EventType.RoomMember, { membership: "join" }, selfUserId), mkOwnStateEvent(EventType.RoomMember, { membership: KnownMembership.Join }, selfUserId),
mkOwnStateEvent(EventType.RoomPowerLevels, { users: { [selfUserId]: 100 } }, ""), mkOwnStateEvent(EventType.RoomPowerLevels, { users: { [selfUserId]: 100 } }, ""),
mkOwnStateEvent(EventType.RoomCanonicalAlias, { alias: "#foo:localhost" }, ""), mkOwnStateEvent(EventType.RoomCanonicalAlias, { alias: "#foo:localhost" }, ""),
mkOwnStateEvent(EventType.RoomName, { name: "This should be ignored" }, ""), mkOwnStateEvent(EventType.RoomName, { name: "This should be ignored" }, ""),
@ -281,7 +282,7 @@ describe("SlidingSyncSdk", () => {
required_state: [], required_state: [],
timeline: [ timeline: [
mkOwnStateEvent(EventType.RoomCreate, {}, ""), mkOwnStateEvent(EventType.RoomCreate, {}, ""),
mkOwnStateEvent(EventType.RoomMember, { membership: "join" }, selfUserId), mkOwnStateEvent(EventType.RoomMember, { membership: KnownMembership.Join }, selfUserId),
mkOwnStateEvent(EventType.RoomPowerLevels, { users: { [selfUserId]: 100 } }, ""), mkOwnStateEvent(EventType.RoomPowerLevels, { users: { [selfUserId]: 100 } }, ""),
], ],
joined_count: 5, joined_count: 5,
@ -293,7 +294,7 @@ describe("SlidingSyncSdk", () => {
required_state: [], required_state: [],
timeline: [ timeline: [
mkOwnStateEvent(EventType.RoomCreate, {}, ""), mkOwnStateEvent(EventType.RoomCreate, {}, ""),
mkOwnStateEvent(EventType.RoomMember, { membership: "join" }, selfUserId), mkOwnStateEvent(EventType.RoomMember, { membership: KnownMembership.Join }, selfUserId),
mkOwnStateEvent(EventType.RoomPowerLevels, { users: { [selfUserId]: 100 } }, ""), mkOwnStateEvent(EventType.RoomPowerLevels, { users: { [selfUserId]: 100 } }, ""),
mkOwnEvent(EventType.RoomMessage, { body: "live event" }), mkOwnEvent(EventType.RoomMessage, { body: "live event" }),
], ],
@ -308,7 +309,7 @@ describe("SlidingSyncSdk", () => {
const gotRoom = client!.getRoom(roomA); const gotRoom = client!.getRoom(roomA);
expect(gotRoom).toBeTruthy(); expect(gotRoom).toBeTruthy();
expect(gotRoom!.name).toEqual(data[roomA].name); expect(gotRoom!.name).toEqual(data[roomA].name);
expect(gotRoom!.getMyMembership()).toEqual("join"); expect(gotRoom!.getMyMembership()).toEqual(KnownMembership.Join);
assertTimelineEvents(gotRoom!.getLiveTimeline().getEvents().slice(-2), data[roomA].timeline); assertTimelineEvents(gotRoom!.getLiveTimeline().getEvents().slice(-2), data[roomA].timeline);
}); });
@ -318,7 +319,7 @@ describe("SlidingSyncSdk", () => {
const gotRoom = client!.getRoom(roomB); const gotRoom = client!.getRoom(roomB);
expect(gotRoom).toBeTruthy(); expect(gotRoom).toBeTruthy();
expect(gotRoom!.name).toEqual(data[roomB].name); expect(gotRoom!.name).toEqual(data[roomB].name);
expect(gotRoom!.getMyMembership()).toEqual("join"); expect(gotRoom!.getMyMembership()).toEqual(KnownMembership.Join);
assertTimelineEvents(gotRoom!.getLiveTimeline().getEvents().slice(-5), data[roomB].timeline); assertTimelineEvents(gotRoom!.getLiveTimeline().getEvents().slice(-5), data[roomB].timeline);
}); });
@ -372,7 +373,7 @@ describe("SlidingSyncSdk", () => {
const gotRoom = client!.getRoom(roomH); const gotRoom = client!.getRoom(roomH);
expect(gotRoom).toBeTruthy(); expect(gotRoom).toBeTruthy();
expect(gotRoom!.name).toEqual(data[roomH].name); expect(gotRoom!.name).toEqual(data[roomH].name);
expect(gotRoom!.getMyMembership()).toEqual("join"); expect(gotRoom!.getMyMembership()).toEqual(KnownMembership.Join);
// check the entire timeline is correct // check the entire timeline is correct
assertTimelineEvents(gotRoom!.getLiveTimeline().getEvents(), data[roomH].timeline); assertTimelineEvents(gotRoom!.getLiveTimeline().getEvents(), data[roomH].timeline);
await expect(seenLiveEventDeferred.promise).resolves.toBeTruthy(); await expect(seenLiveEventDeferred.promise).resolves.toBeTruthy();
@ -383,7 +384,7 @@ describe("SlidingSyncSdk", () => {
await emitPromise(client!, ClientEvent.Room); await emitPromise(client!, ClientEvent.Room);
const gotRoom = client!.getRoom(roomE); const gotRoom = client!.getRoom(roomE);
expect(gotRoom).toBeTruthy(); expect(gotRoom).toBeTruthy();
expect(gotRoom!.getMyMembership()).toEqual("invite"); expect(gotRoom!.getMyMembership()).toEqual(KnownMembership.Invite);
expect(gotRoom!.currentState.getJoinRule()).toEqual(JoinRule.Invite); expect(gotRoom!.currentState.getJoinRule()).toEqual(JoinRule.Invite);
}); });
@ -603,9 +604,9 @@ describe("SlidingSyncSdk", () => {
required_state: [], required_state: [],
timeline: [ timeline: [
mkOwnStateEvent(EventType.RoomCreate, {}, ""), mkOwnStateEvent(EventType.RoomCreate, {}, ""),
mkOwnStateEvent(EventType.RoomMember, { membership: "join" }, selfUserId), mkOwnStateEvent(EventType.RoomMember, { membership: KnownMembership.Join }, selfUserId),
mkOwnStateEvent(EventType.RoomPowerLevels, { users: { [selfUserId]: 100 } }, ""), mkOwnStateEvent(EventType.RoomPowerLevels, { users: { [selfUserId]: 100 } }, ""),
mkOwnStateEvent(EventType.RoomMember, { membership: "invite" }, invitee), mkOwnStateEvent(EventType.RoomMember, { membership: KnownMembership.Invite }, invitee),
], ],
}); });
await httpBackend!.flush("/profile", 1, 1000); await httpBackend!.flush("/profile", 1, 1000);
@ -719,7 +720,7 @@ describe("SlidingSyncSdk", () => {
required_state: [], required_state: [],
timeline: [ timeline: [
mkOwnStateEvent(EventType.RoomCreate, {}, ""), mkOwnStateEvent(EventType.RoomCreate, {}, ""),
mkOwnStateEvent(EventType.RoomMember, { membership: "join" }, selfUserId), mkOwnStateEvent(EventType.RoomMember, { membership: KnownMembership.Join }, selfUserId),
mkOwnStateEvent(EventType.RoomPowerLevels, { users: { [selfUserId]: 100 } }, ""), mkOwnStateEvent(EventType.RoomPowerLevels, { users: { [selfUserId]: 100 } }, ""),
mkOwnEvent(EventType.RoomMessage, { body: "hello" }), mkOwnEvent(EventType.RoomMessage, { body: "hello" }),
], ],
@ -923,7 +924,7 @@ describe("SlidingSyncSdk", () => {
required_state: [], required_state: [],
timeline: [ timeline: [
mkOwnStateEvent(EventType.RoomCreate, {}, ""), mkOwnStateEvent(EventType.RoomCreate, {}, ""),
mkOwnStateEvent(EventType.RoomMember, { membership: "join" }, selfUserId), mkOwnStateEvent(EventType.RoomMember, { membership: KnownMembership.Join }, selfUserId),
mkOwnStateEvent(EventType.RoomPowerLevels, { users: { [selfUserId]: 100 } }, ""), mkOwnStateEvent(EventType.RoomPowerLevels, { users: { [selfUserId]: 100 } }, ""),
mkOwnEvent(EventType.RoomMessage, { body: "hello" }), mkOwnEvent(EventType.RoomMessage, { body: "hello" }),
], ],
@ -964,7 +965,7 @@ describe("SlidingSyncSdk", () => {
required_state: [], required_state: [],
timeline: [ timeline: [
mkOwnStateEvent(EventType.RoomCreate, {}, ""), mkOwnStateEvent(EventType.RoomCreate, {}, ""),
mkOwnStateEvent(EventType.RoomMember, { membership: "join" }, selfUserId), mkOwnStateEvent(EventType.RoomMember, { membership: KnownMembership.Join }, selfUserId),
mkOwnStateEvent(EventType.RoomPowerLevels, { users: { [selfUserId]: 100 } }, ""), mkOwnStateEvent(EventType.RoomPowerLevels, { users: { [selfUserId]: 100 } }, ""),
mkOwnEvent(EventType.RoomMessage, { body: "hello" }), mkOwnEvent(EventType.RoomMessage, { body: "hello" }),
], ],
@ -1050,12 +1051,12 @@ describe("SlidingSyncSdk", () => {
required_state: [], required_state: [],
timeline: [ timeline: [
mkOwnStateEvent(EventType.RoomCreate, {}, ""), mkOwnStateEvent(EventType.RoomCreate, {}, ""),
mkOwnStateEvent(EventType.RoomMember, { membership: "join" }, selfUserId), mkOwnStateEvent(EventType.RoomMember, { membership: KnownMembership.Join }, selfUserId),
mkOwnStateEvent(EventType.RoomPowerLevels, { users: { [selfUserId]: 100 } }, ""), mkOwnStateEvent(EventType.RoomPowerLevels, { users: { [selfUserId]: 100 } }, ""),
{ {
type: EventType.RoomMember, type: EventType.RoomMember,
state_key: alice, state_key: alice,
content: { membership: "join" }, content: { membership: KnownMembership.Join },
sender: alice, sender: alice,
origin_server_ts: Date.now(), origin_server_ts: Date.now(),
event_id: "$alice", event_id: "$alice",

View File

@ -19,6 +19,7 @@ import {
import { SyncState } from "../../src/sync"; import { SyncState } from "../../src/sync";
import { eventMapperFor } from "../../src/event-mapper"; import { eventMapperFor } from "../../src/event-mapper";
import { TEST_ROOM_ID } from "./test-data"; import { TEST_ROOM_ID } from "./test-data";
import { KnownMembership, Membership } from "../../src/@types/membership";
/** /**
* Return a promise that is resolved when the client next emits a * Return a promise that is resolved when the client next emits a
@ -87,7 +88,7 @@ export function getSyncResponse(roomMembers: string[], roomId = TEST_ROOM_ID): I
for (let i = 0; i < roomMembers.length; i++) { for (let i = 0; i < roomMembers.length; i++) {
roomResponse.state.events.push( roomResponse.state.events.push(
mkMembershipCustom({ mkMembershipCustom({
membership: "join", membership: KnownMembership.Join,
sender: roomMembers[i], sender: roomMembers[i],
}), }),
); );
@ -251,7 +252,7 @@ export function mkPresence(opts: IPresenceOpts & { event?: boolean }): Partial<I
interface IMembershipOpts { interface IMembershipOpts {
room?: string; room?: string;
mship: string; mship: Membership;
sender?: string; sender?: string;
user?: string; user?: string;
skey?: string; skey?: string;
@ -297,7 +298,7 @@ export function mkMembership(opts: IMembershipOpts & { event?: boolean }): Parti
} }
export function mkMembershipCustom<T>( export function mkMembershipCustom<T>(
base: T & { membership: string; sender: string; content?: IContent }, base: T & { membership: Membership; sender: string; content?: IContent },
): T & { type: EventType; sender: string; state_key: string; content: IContent } & GeneratedMetadata { ): T & { type: EventType; sender: string; state_key: string; content: IContent } & GeneratedMetadata {
const content = base.content || {}; const content = base.content || {};
return mkEventCustom({ return mkEventCustom({

View File

@ -25,6 +25,7 @@ import { UserTrustLevel } from "../../src/crypto/CrossSigning";
import { CryptoBackend } from "../../src/common-crypto/CryptoBackend"; import { CryptoBackend } from "../../src/common-crypto/CryptoBackend";
import { EventDecryptionResult } from "../../src/common-crypto/CryptoBackend"; import { EventDecryptionResult } from "../../src/common-crypto/CryptoBackend";
import * as testData from "../test-utils/test-data"; import * as testData from "../test-utils/test-data";
import { KnownMembership } from "../../src/@types/membership";
const Olm = global.Olm; const Olm = global.Olm;
@ -463,7 +464,7 @@ describe("Crypto", function () {
type: "m.room.member", type: "m.room.member",
sender: "@alice:example.com", sender: "@alice:example.com",
room_id: roomId, room_id: roomId,
content: { membership: "invite" }, content: { membership: KnownMembership.Invite },
state_key: "@bob:example.com", state_key: "@bob:example.com",
}), }),
]); ]);
@ -795,7 +796,7 @@ describe("Crypto", function () {
type: "m.room.member", type: "m.room.member",
sender: "@clara:example.com", sender: "@clara:example.com",
room_id: roomId, room_id: roomId,
content: { membership: "invite" }, content: { membership: KnownMembership.Invite },
state_key: "@bob:example.com", state_key: "@bob:example.com",
}), }),
]); ]);

View File

@ -36,6 +36,7 @@ import { DeviceTrustLevel } from "../../../../src/crypto/CrossSigning";
import { MegolmEncryption as MegolmEncryptionClass } from "../../../../src/crypto/algorithms/megolm"; import { MegolmEncryption as MegolmEncryptionClass } from "../../../../src/crypto/algorithms/megolm";
import { recursiveMapToObject } from "../../../../src/utils"; import { recursiveMapToObject } from "../../../../src/utils";
import { sleep } from "../../../../src/utils"; import { sleep } from "../../../../src/utils";
import { KnownMembership } from "../../../../src/@types/membership";
const MegolmDecryption = algorithms.DECRYPTION_CLASSES.get("m.megolm.v1.aes-sha2")!; const MegolmDecryption = algorithms.DECRYPTION_CLASSES.get("m.megolm.v1.aes-sha2")!;
const MegolmEncryption = algorithms.ENCRYPTION_CLASSES.get("m.megolm.v1.aes-sha2")!; const MegolmEncryption = algorithms.ENCRYPTION_CLASSES.get("m.megolm.v1.aes-sha2")!;
@ -806,11 +807,11 @@ describe("MegolmDecryption", function () {
aliceRoom.getEncryptionTargetMembers = jest.fn().mockResolvedValue([ aliceRoom.getEncryptionTargetMembers = jest.fn().mockResolvedValue([
{ {
userId: "@alice:example.com", userId: "@alice:example.com",
membership: "join", membership: KnownMembership.Join,
}, },
{ {
userId: "@bob:example.com", userId: "@bob:example.com",
membership: "join", membership: KnownMembership.Join,
}, },
]); ]);
const BOB_DEVICES = { const BOB_DEVICES = {

View File

@ -7,6 +7,7 @@ import { MatrixClient } from "../../src/matrix";
import { Room } from "../../src/models/room"; import { Room } from "../../src/models/room";
import { RoomMember } from "../../src/models/room-member"; import { RoomMember } from "../../src/models/room-member";
import { EventTimelineSet } from "../../src/models/event-timeline-set"; import { EventTimelineSet } from "../../src/models/event-timeline-set";
import { KnownMembership } from "../../src/@types/membership";
describe("EventTimeline", function () { describe("EventTimeline", function () {
const roomId = "!foo:bar"; const roomId = "!foo:bar";
@ -50,7 +51,7 @@ describe("EventTimeline", function () {
const events = [ const events = [
utils.mkMembership({ utils.mkMembership({
room: roomId, room: roomId,
mship: "invite", mship: KnownMembership.Invite,
user: userB, user: userB,
skey: userA, skey: userA,
event: true, event: true,
@ -87,7 +88,7 @@ describe("EventTimeline", function () {
const state = [ const state = [
utils.mkMembership({ utils.mkMembership({
room: roomId, room: roomId,
mship: "invite", mship: KnownMembership.Invite,
user: userB, user: userB,
skey: userA, skey: userA,
event: true, event: true,
@ -203,11 +204,11 @@ describe("EventTimeline", function () {
it("should set event.sender for new and old events", function () { it("should set event.sender for new and old events", function () {
const sentinel = new RoomMember(roomId, userA); const sentinel = new RoomMember(roomId, userA);
sentinel.name = "Alice"; sentinel.name = "Alice";
sentinel.membership = "join"; sentinel.membership = KnownMembership.Join;
const oldSentinel = new RoomMember(roomId, userA); const oldSentinel = new RoomMember(roomId, userA);
sentinel.name = "Old Alice"; sentinel.name = "Old Alice";
sentinel.membership = "join"; sentinel.membership = KnownMembership.Join;
mocked(timeline.getState(EventTimeline.FORWARDS)!).getSentinelMember.mockImplementation(function (uid) { mocked(timeline.getState(EventTimeline.FORWARDS)!).getSentinelMember.mockImplementation(function (uid) {
if (uid === userA) { if (uid === userA) {
@ -246,11 +247,11 @@ describe("EventTimeline", function () {
it("should set event.target for new and old m.room.member events", function () { it("should set event.target for new and old m.room.member events", function () {
const sentinel = new RoomMember(roomId, userA); const sentinel = new RoomMember(roomId, userA);
sentinel.name = "Alice"; sentinel.name = "Alice";
sentinel.membership = "join"; sentinel.membership = KnownMembership.Join;
const oldSentinel = new RoomMember(roomId, userA); const oldSentinel = new RoomMember(roomId, userA);
sentinel.name = "Old Alice"; sentinel.name = "Old Alice";
sentinel.membership = "join"; sentinel.membership = KnownMembership.Join;
mocked(timeline.getState(EventTimeline.FORWARDS)!).getSentinelMember.mockImplementation(function (uid) { mocked(timeline.getState(EventTimeline.FORWARDS)!).getSentinelMember.mockImplementation(function (uid) {
if (uid === userA) { if (uid === userA) {
@ -267,14 +268,14 @@ describe("EventTimeline", function () {
const newEv = utils.mkMembership({ const newEv = utils.mkMembership({
room: roomId, room: roomId,
mship: "invite", mship: KnownMembership.Invite,
user: userB, user: userB,
skey: userA, skey: userA,
event: true, event: true,
}); });
const oldEv = utils.mkMembership({ const oldEv = utils.mkMembership({
room: roomId, room: roomId,
mship: "ban", mship: KnownMembership.Ban,
user: userB, user: userB,
skey: userA, skey: userA,
event: true, event: true,
@ -291,7 +292,7 @@ describe("EventTimeline", function () {
const events = [ const events = [
utils.mkMembership({ utils.mkMembership({
room: roomId, room: roomId,
mship: "invite", mship: KnownMembership.Invite,
user: userB, user: userB,
skey: userA, skey: userA,
event: true, event: true,
@ -330,7 +331,7 @@ describe("EventTimeline", function () {
const events = [ const events = [
utils.mkMembership({ utils.mkMembership({
room: roomId, room: roomId,
mship: "invite", mship: KnownMembership.Invite,
user: userB, user: userB,
skey: userA, skey: userA,
event: true, event: true,

View File

@ -71,6 +71,7 @@ import * as featureUtils from "../../src/feature";
import { StubStore } from "../../src/store/stub"; import { StubStore } from "../../src/store/stub";
import { SecretStorageKeyDescriptionAesV1, ServerSideSecretStorageImpl } from "../../src/secret-storage"; import { SecretStorageKeyDescriptionAesV1, ServerSideSecretStorageImpl } from "../../src/secret-storage";
import { CryptoBackend } from "../../src/common-crypto/CryptoBackend"; import { CryptoBackend } from "../../src/common-crypto/CryptoBackend";
import { KnownMembership } from "../../src/@types/membership";
jest.useFakeTimers(); jest.useFakeTimers();
@ -750,7 +751,7 @@ describe("MatrixClient", function () {
it("should get (unstable) file trees with valid state", async () => { it("should get (unstable) file trees with valid state", async () => {
const roomId = "!room:example.org"; const roomId = "!room:example.org";
const mockRoom = { const mockRoom = {
getMyMembership: () => "join", getMyMembership: () => KnownMembership.Join,
currentState: { currentState: {
getStateEvents: (eventType, stateKey) => { getStateEvents: (eventType, stateKey) => {
/* eslint-disable jest/no-conditional-expect */ /* eslint-disable jest/no-conditional-expect */
@ -789,7 +790,7 @@ describe("MatrixClient", function () {
it("should not get (unstable) file trees if not joined", async () => { it("should not get (unstable) file trees if not joined", async () => {
const roomId = "!room:example.org"; const roomId = "!room:example.org";
const mockRoom = { const mockRoom = {
getMyMembership: () => "leave", // "not join" getMyMembership: () => KnownMembership.Leave, // "not join"
} as unknown as Room; } as unknown as Room;
client.getRoom = (getRoomId) => { client.getRoom = (getRoomId) => {
expect(getRoomId).toEqual(roomId); expect(getRoomId).toEqual(roomId);
@ -812,7 +813,7 @@ describe("MatrixClient", function () {
it("should not get (unstable) file trees with invalid create contents", async () => { it("should not get (unstable) file trees with invalid create contents", async () => {
const roomId = "!room:example.org"; const roomId = "!room:example.org";
const mockRoom = { const mockRoom = {
getMyMembership: () => "join", getMyMembership: () => KnownMembership.Join,
currentState: { currentState: {
getStateEvents: (eventType, stateKey) => { getStateEvents: (eventType, stateKey) => {
/* eslint-disable jest/no-conditional-expect */ /* eslint-disable jest/no-conditional-expect */
@ -849,7 +850,7 @@ describe("MatrixClient", function () {
it("should not get (unstable) file trees with invalid purpose/subtype contents", async () => { it("should not get (unstable) file trees with invalid purpose/subtype contents", async () => {
const roomId = "!room:example.org"; const roomId = "!room:example.org";
const mockRoom = { const mockRoom = {
getMyMembership: () => "join", getMyMembership: () => KnownMembership.Join,
currentState: { currentState: {
getStateEvents: (eventType, stateKey) => { getStateEvents: (eventType, stateKey) => {
/* eslint-disable jest/no-conditional-expect */ /* eslint-disable jest/no-conditional-expect */
@ -1309,7 +1310,7 @@ describe("MatrixClient", function () {
describe("redactEvent", () => { describe("redactEvent", () => {
const roomId = "!room:example.org"; const roomId = "!room:example.org";
const mockRoom = { const mockRoom = {
getMyMembership: () => "join", getMyMembership: () => KnownMembership.Join,
currentState: { currentState: {
getStateEvents: (eventType, stateKey) => { getStateEvents: (eventType, stateKey) => {
if (eventType === EventType.RoomEncryption) { if (eventType === EventType.RoomEncryption) {
@ -1448,7 +1449,7 @@ describe("MatrixClient", function () {
const txnId = "m12345"; const txnId = "m12345";
const mockRoom = { const mockRoom = {
getMyMembership: () => "join", getMyMembership: () => KnownMembership.Join,
updatePendingEvent: (event: MatrixEvent, status: EventStatus) => event.setStatus(status), updatePendingEvent: (event: MatrixEvent, status: EventStatus) => event.setStatus(status),
hasEncryptionStateEvent: jest.fn().mockReturnValue(true), hasEncryptionStateEvent: jest.fn().mockReturnValue(true),
} as unknown as Room; } as unknown as Room;

View File

@ -15,6 +15,7 @@ limitations under the License.
*/ */
import { EventTimeline, EventType, MatrixClient, MatrixError, MatrixEvent, Room } from "../../../src"; import { EventTimeline, EventType, MatrixClient, MatrixError, MatrixEvent, Room } from "../../../src";
import { KnownMembership } from "../../../src/@types/membership";
import { CallMembershipData } from "../../../src/matrixrtc/CallMembership"; import { CallMembershipData } from "../../../src/matrixrtc/CallMembership";
import { MatrixRTCSession, MatrixRTCSessionEvent } from "../../../src/matrixrtc/MatrixRTCSession"; import { MatrixRTCSession, MatrixRTCSessionEvent } from "../../../src/matrixrtc/MatrixRTCSession";
import { EncryptionKeysEventContent } from "../../../src/matrixrtc/types"; import { EncryptionKeysEventContent } from "../../../src/matrixrtc/types";
@ -76,7 +77,7 @@ describe("MatrixRTCSession", () => {
it("ignores memberships events of members not in the room", () => { it("ignores memberships events of members not in the room", () => {
const mockRoom = makeMockRoom([membershipTemplate]); const mockRoom = makeMockRoom([membershipTemplate]);
mockRoom.hasMembershipState = (state) => state === "join"; mockRoom.hasMembershipState = (state) => state === KnownMembership.Join;
sess = MatrixRTCSession.roomSessionForRoom(client, mockRoom); sess = MatrixRTCSession.roomSessionForRoom(client, mockRoom);
expect(sess?.memberships.length).toEqual(0); expect(sess?.memberships.length).toEqual(0);
}); });

View File

@ -25,6 +25,7 @@ import {
} from "../../../src/models/MSC3089TreeSpace"; } from "../../../src/models/MSC3089TreeSpace";
import { DEFAULT_ALPHABET } from "../../../src/utils"; import { DEFAULT_ALPHABET } from "../../../src/utils";
import { MatrixError } from "../../../src/http-api"; import { MatrixError } from "../../../src/http-api";
import { KnownMembership } from "../../../src/@types/membership";
describe("MSC3089TreeSpace", () => { describe("MSC3089TreeSpace", () => {
let client: MatrixClient; let client: MatrixClient;
@ -458,14 +459,14 @@ describe("MSC3089TreeSpace", () => {
expect(stateKey).toBeUndefined(); expect(stateKey).toBeUndefined();
return [ return [
// Partial implementations // Partial implementations
{ getContent: () => ({ membership: "join" }), getStateKey: () => joinMemberId }, { getContent: () => ({ membership: KnownMembership.Join }), getStateKey: () => joinMemberId },
{ getContent: () => ({ membership: "knock" }), getStateKey: () => knockMemberId }, { getContent: () => ({ membership: KnownMembership.Knock }), getStateKey: () => knockMemberId },
{ getContent: () => ({ membership: "invite" }), getStateKey: () => inviteMemberId }, { getContent: () => ({ membership: KnownMembership.Invite }), getStateKey: () => inviteMemberId },
{ getContent: () => ({ membership: "leave" }), getStateKey: () => leaveMemberId }, { getContent: () => ({ membership: KnownMembership.Leave }), getStateKey: () => leaveMemberId },
{ getContent: () => ({ membership: "ban" }), getStateKey: () => banMemberId }, { getContent: () => ({ membership: KnownMembership.Ban }), getStateKey: () => banMemberId },
// ensure we don't kick ourselves // ensure we don't kick ourselves
{ getContent: () => ({ membership: "join" }), getStateKey: () => selfUserId }, { getContent: () => ({ membership: KnownMembership.Join }), getStateKey: () => selfUserId },
]; ];
}, },
}; };

View File

@ -27,6 +27,7 @@ import {
UNSTABLE_MSC2666_QUERY_MUTUAL_ROOMS, UNSTABLE_MSC2666_QUERY_MUTUAL_ROOMS,
UNSTABLE_MSC2666_SHARED_ROOMS, UNSTABLE_MSC2666_SHARED_ROOMS,
} from "../../src"; } from "../../src";
import { KnownMembership } from "../../src/@types/membership";
describe("RoomMember", function () { describe("RoomMember", function () {
const roomId = "!foo:bar"; const roomId = "!foo:bar";
@ -50,7 +51,7 @@ describe("RoomMember", function () {
room: roomId, room: roomId,
user: userA, user: userA,
content: { content: {
membership: "join", membership: KnownMembership.Join,
avatar_url: "mxc://flibble/wibble", avatar_url: "mxc://flibble/wibble",
}, },
}); });
@ -282,11 +283,11 @@ describe("RoomMember", function () {
describe("isKicked", () => { describe("isKicked", () => {
it("should return false if membership is not `leave`", () => { it("should return false if membership is not `leave`", () => {
const member1 = new RoomMember(roomId, userA); const member1 = new RoomMember(roomId, userA);
member1.membership = "join"; member1.membership = KnownMembership.Join;
expect(member1.isKicked()).toBeFalsy(); expect(member1.isKicked()).toBeFalsy();
const member2 = new RoomMember(roomId, userA); const member2 = new RoomMember(roomId, userA);
member2.membership = "invite"; member2.membership = KnownMembership.Invite;
expect(member2.isKicked()).toBeFalsy(); expect(member2.isKicked()).toBeFalsy();
const member3 = new RoomMember(roomId, userA); const member3 = new RoomMember(roomId, userA);
@ -295,17 +296,17 @@ describe("RoomMember", function () {
it("should return false if the membership event is unknown", () => { it("should return false if the membership event is unknown", () => {
const member = new RoomMember(roomId, userA); const member = new RoomMember(roomId, userA);
member.membership = "leave"; member.membership = KnownMembership.Leave;
expect(member.isKicked()).toBeFalsy(); expect(member.isKicked()).toBeFalsy();
}); });
it("should return false if the member left of their own accord", () => { it("should return false if the member left of their own accord", () => {
const member = new RoomMember(roomId, userA); const member = new RoomMember(roomId, userA);
member.membership = "leave"; member.membership = KnownMembership.Leave;
member.events.member = utils.mkMembership({ member.events.member = utils.mkMembership({
event: true, event: true,
sender: userA, sender: userA,
mship: "leave", mship: KnownMembership.Leave,
skey: userA, skey: userA,
}); });
expect(member.isKicked()).toBeFalsy(); expect(member.isKicked()).toBeFalsy();
@ -313,11 +314,11 @@ describe("RoomMember", function () {
it("should return true if the member's leave was sent by another user", () => { it("should return true if the member's leave was sent by another user", () => {
const member = new RoomMember(roomId, userA); const member = new RoomMember(roomId, userA);
member.membership = "leave"; member.membership = KnownMembership.Leave;
member.events.member = utils.mkMembership({ member.events.member = utils.mkMembership({
event: true, event: true,
sender: userB, sender: userB,
mship: "leave", mship: KnownMembership.Leave,
skey: userA, skey: userA,
}); });
expect(member.isKicked()).toBeTruthy(); expect(member.isKicked()).toBeTruthy();
@ -327,11 +328,11 @@ describe("RoomMember", function () {
describe("getDMInviter", () => { describe("getDMInviter", () => {
it("should return userId of the sender of the invite if is_direct=true", () => { it("should return userId of the sender of the invite if is_direct=true", () => {
const member = new RoomMember(roomId, userA); const member = new RoomMember(roomId, userA);
member.membership = "invite"; member.membership = KnownMembership.Invite;
member.events.member = utils.mkMembership({ member.events.member = utils.mkMembership({
event: true, event: true,
sender: userB, sender: userB,
mship: "invite", mship: KnownMembership.Invite,
skey: userA, skey: userA,
}); });
member.events.member.event.content!.is_direct = true; member.events.member.event.content!.is_direct = true;
@ -340,11 +341,11 @@ describe("RoomMember", function () {
it("should not return userId of the sender of the invite if is_direct=false", () => { it("should not return userId of the sender of the invite if is_direct=false", () => {
const member = new RoomMember(roomId, userA); const member = new RoomMember(roomId, userA);
member.membership = "invite"; member.membership = KnownMembership.Invite;
member.events.member = utils.mkMembership({ member.events.member = utils.mkMembership({
event: true, event: true,
sender: userB, sender: userB,
mship: "invite", mship: KnownMembership.Invite,
skey: userA, skey: userA,
}); });
member.events.member.event.content!.is_direct = false; member.events.member.event.content!.is_direct = false;
@ -355,7 +356,7 @@ describe("RoomMember", function () {
describe("setMembershipEvent", function () { describe("setMembershipEvent", function () {
const joinEvent = utils.mkMembership({ const joinEvent = utils.mkMembership({
event: true, event: true,
mship: "join", mship: KnownMembership.Join,
user: userA, user: userA,
room: roomId, room: roomId,
name: "Alice", name: "Alice",
@ -363,7 +364,7 @@ describe("RoomMember", function () {
const inviteEvent = utils.mkMembership({ const inviteEvent = utils.mkMembership({
event: true, event: true,
mship: "invite", mship: KnownMembership.Invite,
user: userB, user: userB,
skey: userA, skey: userA,
room: roomId, room: roomId,
@ -371,10 +372,10 @@ describe("RoomMember", function () {
it("should set 'membership' and assign the event to 'events.member'.", function () { it("should set 'membership' and assign the event to 'events.member'.", function () {
member.setMembershipEvent(inviteEvent); member.setMembershipEvent(inviteEvent);
expect(member.membership).toEqual("invite"); expect(member.membership).toEqual(KnownMembership.Invite);
expect(member.events.member).toEqual(inviteEvent); expect(member.events.member).toEqual(inviteEvent);
member.setMembershipEvent(joinEvent); member.setMembershipEvent(joinEvent);
expect(member.membership).toEqual("join"); expect(member.membership).toEqual(KnownMembership.Join);
expect(member.events.member).toEqual(joinEvent); expect(member.events.member).toEqual(joinEvent);
}); });
@ -387,13 +388,13 @@ describe("RoomMember", function () {
return [ return [
utils.mkMembership({ utils.mkMembership({
event: true, event: true,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
user: userB, user: userB,
}), }),
utils.mkMembership({ utils.mkMembership({
event: true, event: true,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
user: userC, user: userC,
name: "Alice", name: "Alice",
@ -443,7 +444,7 @@ describe("RoomMember", function () {
it("should set 'name' to user_id if it is just whitespace", function () { it("should set 'name' to user_id if it is just whitespace", function () {
const joinEvent = utils.mkMembership({ const joinEvent = utils.mkMembership({
event: true, event: true,
mship: "join", mship: KnownMembership.Join,
user: userA, user: userA,
room: roomId, room: roomId,
name: " \u200b ", name: " \u200b ",
@ -457,7 +458,7 @@ describe("RoomMember", function () {
it("should disambiguate users on a fuzzy displayname match", function () { it("should disambiguate users on a fuzzy displayname match", function () {
const joinEvent = utils.mkMembership({ const joinEvent = utils.mkMembership({
event: true, event: true,
mship: "join", mship: KnownMembership.Join,
user: userA, user: userA,
room: roomId, room: roomId,
name: "Alíce\u200b", // note diacritic and zero width char name: "Alíce\u200b", // note diacritic and zero width char
@ -471,7 +472,7 @@ describe("RoomMember", function () {
return [ return [
utils.mkMembership({ utils.mkMembership({
event: true, event: true,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
user: userC, user: userC,
name: "Alice", name: "Alice",

View File

@ -28,6 +28,7 @@ import { MatrixClient } from "../../src/client";
import { DecryptionError } from "../../src/crypto/algorithms"; import { DecryptionError } from "../../src/crypto/algorithms";
import { defer } from "../../src/utils"; import { defer } from "../../src/utils";
import { Room } from "../../src/models/room"; import { Room } from "../../src/models/room";
import { KnownMembership } from "../../src/@types/membership";
describe("RoomState", function () { describe("RoomState", function () {
const roomId = "!foo:bar"; const roomId = "!foo:bar";
@ -44,14 +45,14 @@ describe("RoomState", function () {
utils.mkMembership({ utils.mkMembership({
// userA joined // userA joined
event: true, event: true,
mship: "join", mship: KnownMembership.Join,
user: userA, user: userA,
room: roomId, room: roomId,
}), }),
utils.mkMembership({ utils.mkMembership({
// userB joined // userB joined
event: true, event: true,
mship: "join", mship: KnownMembership.Join,
user: userB, user: userB,
room: roomId, room: roomId,
}), }),
@ -102,20 +103,20 @@ describe("RoomState", function () {
it("should return a member which changes as state changes", function () { it("should return a member which changes as state changes", function () {
const member = state.getMember(userB); const member = state.getMember(userB);
expect(member?.membership).toEqual("join"); expect(member?.membership).toEqual(KnownMembership.Join);
expect(member?.name).toEqual(userB); expect(member?.name).toEqual(userB);
state.setStateEvents([ state.setStateEvents([
utils.mkMembership({ utils.mkMembership({
room: roomId, room: roomId,
user: userB, user: userB,
mship: "leave", mship: KnownMembership.Leave,
event: true, event: true,
name: "BobGone", name: "BobGone",
}), }),
]); ]);
expect(member?.membership).toEqual("leave"); expect(member?.membership).toEqual(KnownMembership.Leave);
expect(member?.name).toEqual("BobGone"); expect(member?.name).toEqual("BobGone");
}); });
}); });
@ -131,17 +132,17 @@ describe("RoomState", function () {
utils.mkMembership({ utils.mkMembership({
room: roomId, room: roomId,
user: userA, user: userA,
mship: "leave", mship: KnownMembership.Leave,
event: true, event: true,
name: "AliceIsGone", name: "AliceIsGone",
}), }),
]); ]);
const postLeaveUser = state.getSentinelMember(userA); const postLeaveUser = state.getSentinelMember(userA);
expect(preLeaveUser?.membership).toEqual("join"); expect(preLeaveUser?.membership).toEqual(KnownMembership.Join);
expect(preLeaveUser?.name).toEqual(userA); expect(preLeaveUser?.name).toEqual(userA);
expect(postLeaveUser?.membership).toEqual("leave"); expect(postLeaveUser?.membership).toEqual(KnownMembership.Leave);
expect(postLeaveUser?.name).toEqual("AliceIsGone"); expect(postLeaveUser?.name).toEqual("AliceIsGone");
}); });
}); });
@ -166,7 +167,7 @@ describe("RoomState", function () {
it("should return a single MatrixEvent if a state_key was specified", function () { it("should return a single MatrixEvent if a state_key was specified", function () {
const event = state.getStateEvents("m.room.member", userA); const event = state.getStateEvents("m.room.member", userA);
expect(event?.getContent()).toMatchObject({ expect(event?.getContent()).toMatchObject({
membership: "join", membership: KnownMembership.Join,
}); });
}); });
}); });
@ -176,13 +177,13 @@ describe("RoomState", function () {
const memberEvents = [ const memberEvents = [
utils.mkMembership({ utils.mkMembership({
user: "@cleo:bar", user: "@cleo:bar",
mship: "invite", mship: KnownMembership.Invite,
room: roomId, room: roomId,
event: true, event: true,
}), }),
utils.mkMembership({ utils.mkMembership({
user: "@daisy:bar", user: "@daisy:bar",
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
}), }),
@ -202,13 +203,13 @@ describe("RoomState", function () {
const memberEvents = [ const memberEvents = [
utils.mkMembership({ utils.mkMembership({
user: "@cleo:bar", user: "@cleo:bar",
mship: "invite", mship: KnownMembership.Invite,
room: roomId, room: roomId,
event: true, event: true,
}), }),
utils.mkMembership({ utils.mkMembership({
user: "@daisy:bar", user: "@daisy:bar",
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
}), }),
@ -228,7 +229,7 @@ describe("RoomState", function () {
const events = [ const events = [
utils.mkMembership({ utils.mkMembership({
user: "@cleo:bar", user: "@cleo:bar",
mship: "invite", mship: KnownMembership.Invite,
room: roomId, room: roomId,
event: true, event: true,
}), }),
@ -282,7 +283,7 @@ describe("RoomState", function () {
it("should call setPowerLevelEvent on a new RoomMember if power levels exist", function () { it("should call setPowerLevelEvent on a new RoomMember if power levels exist", function () {
const memberEvent = utils.mkMembership({ const memberEvent = utils.mkMembership({
mship: "join", mship: KnownMembership.Join,
user: userC, user: userC,
room: roomId, room: roomId,
event: true, event: true,
@ -312,7 +313,7 @@ describe("RoomState", function () {
it("should call setMembershipEvent on the right RoomMember", function () { it("should call setMembershipEvent on the right RoomMember", function () {
const memberEvent = utils.mkMembership({ const memberEvent = utils.mkMembership({
user: userB, user: userB,
mship: "leave", mship: KnownMembership.Leave,
room: roomId, room: roomId,
event: true, event: true,
}); });
@ -447,7 +448,7 @@ describe("RoomState", function () {
it("should add a new member", function () { it("should add a new member", function () {
const oobMemberEvent = utils.mkMembership({ const oobMemberEvent = utils.mkMembership({
user: userLazy, user: userLazy,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
}); });
@ -462,7 +463,7 @@ describe("RoomState", function () {
state.setOutOfBandMembers([ state.setOutOfBandMembers([
utils.mkMembership({ utils.mkMembership({
user: userLazy, user: userLazy,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
}), }),
@ -474,7 +475,7 @@ describe("RoomState", function () {
const userLazy = "@oob:hs"; const userLazy = "@oob:hs";
const oobMemberEvent = utils.mkMembership({ const oobMemberEvent = utils.mkMembership({
user: userLazy, user: userLazy,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
}); });
@ -491,7 +492,7 @@ describe("RoomState", function () {
it("should never overwrite existing members", function () { it("should never overwrite existing members", function () {
const oobMemberEvent = utils.mkMembership({ const oobMemberEvent = utils.mkMembership({
user: userA, user: userA,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
}); });
@ -506,7 +507,7 @@ describe("RoomState", function () {
const doesntExistYetUserId = "@doesntexistyet:hs"; const doesntExistYetUserId = "@doesntexistyet:hs";
const oobMemberEvent = utils.mkMembership({ const oobMemberEvent = utils.mkMembership({
user: doesntExistYetUserId, user: doesntExistYetUserId,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
}); });
@ -529,7 +530,7 @@ describe("RoomState", function () {
state.setOutOfBandMembers([ state.setOutOfBandMembers([
utils.mkMembership({ utils.mkMembership({
user: userLazy, user: userLazy,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
}), }),
@ -554,7 +555,7 @@ describe("RoomState", function () {
copy.setOutOfBandMembers([ copy.setOutOfBandMembers([
utils.mkMembership({ utils.mkMembership({
user: userA, user: userA,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
}), }),
@ -563,7 +564,7 @@ describe("RoomState", function () {
state.setOutOfBandMembers([ state.setOutOfBandMembers([
utils.mkMembership({ utils.mkMembership({
user: userLazy, user: userLazy,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
}), }),
@ -576,7 +577,7 @@ describe("RoomState", function () {
copy.setStateEvents([ copy.setStateEvents([
utils.mkMembership({ utils.mkMembership({
user: userLazy, user: userLazy,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
}), }),
@ -697,9 +698,13 @@ describe("RoomState", function () {
}); });
it("should update after adding joined member", function () { it("should update after adding joined member", function () {
state.setStateEvents([utils.mkMembership({ event: true, mship: "join", user: userA, room: roomId })]); state.setStateEvents([
utils.mkMembership({ event: true, mship: KnownMembership.Join, user: userA, room: roomId }),
]);
expect(state.getJoinedMemberCount()).toEqual(1); expect(state.getJoinedMemberCount()).toEqual(1);
state.setStateEvents([utils.mkMembership({ event: true, mship: "join", user: userC, room: roomId })]); state.setStateEvents([
utils.mkMembership({ event: true, mship: KnownMembership.Join, user: userC, room: roomId }),
]);
expect(state.getJoinedMemberCount()).toEqual(2); expect(state.getJoinedMemberCount()).toEqual(2);
}); });
}); });
@ -710,9 +715,13 @@ describe("RoomState", function () {
}); });
it("should update after adding invited member", function () { it("should update after adding invited member", function () {
state.setStateEvents([utils.mkMembership({ event: true, mship: "invite", user: userA, room: roomId })]); state.setStateEvents([
utils.mkMembership({ event: true, mship: KnownMembership.Invite, user: userA, room: roomId }),
]);
expect(state.getInvitedMemberCount()).toEqual(1); expect(state.getInvitedMemberCount()).toEqual(1);
state.setStateEvents([utils.mkMembership({ event: true, mship: "invite", user: userC, room: roomId })]); state.setStateEvents([
utils.mkMembership({ event: true, mship: KnownMembership.Invite, user: userC, room: roomId }),
]);
expect(state.getInvitedMemberCount()).toEqual(2); expect(state.getInvitedMemberCount()).toEqual(2);
}); });
}); });
@ -723,19 +732,27 @@ describe("RoomState", function () {
}); });
it("should, once used, override counting members from state", function () { it("should, once used, override counting members from state", function () {
state.setStateEvents([utils.mkMembership({ event: true, mship: "join", user: userA, room: roomId })]); state.setStateEvents([
utils.mkMembership({ event: true, mship: KnownMembership.Join, user: userA, room: roomId }),
]);
expect(state.getJoinedMemberCount()).toEqual(1); expect(state.getJoinedMemberCount()).toEqual(1);
state.setJoinedMemberCount(100); state.setJoinedMemberCount(100);
expect(state.getJoinedMemberCount()).toEqual(100); expect(state.getJoinedMemberCount()).toEqual(100);
state.setStateEvents([utils.mkMembership({ event: true, mship: "join", user: userC, room: roomId })]); state.setStateEvents([
utils.mkMembership({ event: true, mship: KnownMembership.Join, user: userC, room: roomId }),
]);
expect(state.getJoinedMemberCount()).toEqual(100); expect(state.getJoinedMemberCount()).toEqual(100);
}); });
it("should, once used, override counting members from state, " + "also after clone", function () { it("should, once used, override counting members from state, " + "also after clone", function () {
state.setStateEvents([utils.mkMembership({ event: true, mship: "join", user: userA, room: roomId })]); state.setStateEvents([
utils.mkMembership({ event: true, mship: KnownMembership.Join, user: userA, room: roomId }),
]);
state.setJoinedMemberCount(100); state.setJoinedMemberCount(100);
const copy = state.clone(); const copy = state.clone();
copy.setStateEvents([utils.mkMembership({ event: true, mship: "join", user: userC, room: roomId })]); copy.setStateEvents([
utils.mkMembership({ event: true, mship: KnownMembership.Join, user: userC, room: roomId }),
]);
expect(state.getJoinedMemberCount()).toEqual(100); expect(state.getJoinedMemberCount()).toEqual(100);
}); });
}); });
@ -746,19 +763,27 @@ describe("RoomState", function () {
}); });
it("should, once used, override counting members from state", function () { it("should, once used, override counting members from state", function () {
state.setStateEvents([utils.mkMembership({ event: true, mship: "invite", user: userB, room: roomId })]); state.setStateEvents([
utils.mkMembership({ event: true, mship: KnownMembership.Invite, user: userB, room: roomId }),
]);
expect(state.getInvitedMemberCount()).toEqual(1); expect(state.getInvitedMemberCount()).toEqual(1);
state.setInvitedMemberCount(100); state.setInvitedMemberCount(100);
expect(state.getInvitedMemberCount()).toEqual(100); expect(state.getInvitedMemberCount()).toEqual(100);
state.setStateEvents([utils.mkMembership({ event: true, mship: "invite", user: userC, room: roomId })]); state.setStateEvents([
utils.mkMembership({ event: true, mship: KnownMembership.Invite, user: userC, room: roomId }),
]);
expect(state.getInvitedMemberCount()).toEqual(100); expect(state.getInvitedMemberCount()).toEqual(100);
}); });
it("should, once used, override counting members from state, " + "also after clone", function () { it("should, once used, override counting members from state, " + "also after clone", function () {
state.setStateEvents([utils.mkMembership({ event: true, mship: "invite", user: userB, room: roomId })]); state.setStateEvents([
utils.mkMembership({ event: true, mship: KnownMembership.Invite, user: userB, room: roomId }),
]);
state.setInvitedMemberCount(100); state.setInvitedMemberCount(100);
const copy = state.clone(); const copy = state.clone();
copy.setStateEvents([utils.mkMembership({ event: true, mship: "invite", user: userC, room: roomId })]); copy.setStateEvents([
utils.mkMembership({ event: true, mship: KnownMembership.Invite, user: userC, room: roomId }),
]);
expect(state.getInvitedMemberCount()).toEqual(100); expect(state.getInvitedMemberCount()).toEqual(100);
}); });
}); });

View File

@ -56,6 +56,7 @@ import { getMockClientWithEventEmitter, mockClientMethodsUser } from "../test-ut
import { logger } from "../../src/logger"; import { logger } from "../../src/logger";
import { IMessageOpts } from "../test-utils/test-utils"; import { IMessageOpts } from "../test-utils/test-utils";
import { flushPromises } from "../test-utils/flushPromises"; import { flushPromises } from "../test-utils/flushPromises";
import { KnownMembership } from "../../src/@types/membership";
describe("Room", function () { describe("Room", function () {
const roomId = "!foo:bar"; const roomId = "!foo:bar";
@ -408,7 +409,7 @@ describe("Room", function () {
const events: MatrixEvent[] = [ const events: MatrixEvent[] = [
utils.mkMembership({ utils.mkMembership({
room: roomId, room: roomId,
mship: "invite", mship: KnownMembership.Invite,
user: userB, user: userB,
skey: userA, skey: userA,
event: true, event: true,
@ -434,7 +435,7 @@ describe("Room", function () {
it("should synthesize read receipts for the senders of events", async function () { it("should synthesize read receipts for the senders of events", async function () {
const sentinel = { const sentinel = {
userId: userA, userId: userA,
membership: "join", membership: KnownMembership.Join,
name: "Alice", name: "Alice",
} as unknown as RoomMember; } as unknown as RoomMember;
mocked(room.currentState.getSentinelMember).mockImplementation(function (uid) { mocked(room.currentState.getSentinelMember).mockImplementation(function (uid) {
@ -636,12 +637,12 @@ describe("Room", function () {
it("should set event.sender for new and old events", async function () { it("should set event.sender for new and old events", async function () {
const sentinel = { const sentinel = {
userId: userA, userId: userA,
membership: "join", membership: KnownMembership.Join,
name: "Alice", name: "Alice",
} as unknown as RoomMember; } as unknown as RoomMember;
const oldSentinel = { const oldSentinel = {
userId: userA, userId: userA,
membership: "join", membership: KnownMembership.Join,
name: "Old Alice", name: "Old Alice",
} as unknown as RoomMember; } as unknown as RoomMember;
mocked(room.currentState.getSentinelMember).mockImplementation(function (uid) { mocked(room.currentState.getSentinelMember).mockImplementation(function (uid) {
@ -680,12 +681,12 @@ describe("Room", function () {
it("should set event.target for new and old m.room.member events", async function () { it("should set event.target for new and old m.room.member events", async function () {
const sentinel = { const sentinel = {
userId: userA, userId: userA,
membership: "join", membership: KnownMembership.Join,
name: "Alice", name: "Alice",
} as unknown as RoomMember; } as unknown as RoomMember;
const oldSentinel = { const oldSentinel = {
userId: userA, userId: userA,
membership: "join", membership: KnownMembership.Join,
name: "Old Alice", name: "Old Alice",
} as unknown as RoomMember; } as unknown as RoomMember;
mocked(room.currentState.getSentinelMember).mockImplementation(function (uid) { mocked(room.currentState.getSentinelMember).mockImplementation(function (uid) {
@ -703,14 +704,14 @@ describe("Room", function () {
const newEv = utils.mkMembership({ const newEv = utils.mkMembership({
room: roomId, room: roomId,
mship: "invite", mship: KnownMembership.Invite,
user: userB, user: userB,
skey: userA, skey: userA,
event: true, event: true,
}); });
const oldEv = utils.mkMembership({ const oldEv = utils.mkMembership({
room: roomId, room: roomId,
mship: "ban", mship: KnownMembership.Ban,
user: userB, user: userB,
skey: userA, skey: userA,
event: true, event: true,
@ -727,7 +728,7 @@ describe("Room", function () {
const events: MatrixEvent[] = [ const events: MatrixEvent[] = [
utils.mkMembership({ utils.mkMembership({
room: roomId, room: roomId,
mship: "invite", mship: KnownMembership.Invite,
user: userB, user: userB,
skey: userA, skey: userA,
event: true, event: true,
@ -948,9 +949,9 @@ describe("Room", function () {
it("should return members whose membership is 'join'", function () { it("should return members whose membership is 'join'", function () {
mocked(room.currentState.getMembers).mockImplementation(function () { mocked(room.currentState.getMembers).mockImplementation(function () {
return [ return [
{ userId: "@alice:bar", membership: "join" } as unknown as RoomMember, { userId: "@alice:bar", membership: KnownMembership.Join } as unknown as RoomMember,
{ userId: "@bob:bar", membership: "invite" } as unknown as RoomMember, { userId: "@bob:bar", membership: KnownMembership.Invite } as unknown as RoomMember,
{ userId: "@cleo:bar", membership: "leave" } as unknown as RoomMember, { userId: "@cleo:bar", membership: KnownMembership.Leave } as unknown as RoomMember,
]; ];
}); });
const res = room.getJoinedMembers(); const res = room.getJoinedMembers();
@ -960,7 +961,7 @@ describe("Room", function () {
it("should return an empty list if no membership is 'join'", function () { it("should return an empty list if no membership is 'join'", function () {
mocked(room.currentState.getMembers).mockImplementation(function () { mocked(room.currentState.getMembers).mockImplementation(function () {
return [{ userId: "@bob:bar", membership: "invite" } as unknown as RoomMember]; return [{ userId: "@bob:bar", membership: KnownMembership.Invite } as unknown as RoomMember];
}); });
const res = room.getJoinedMembers(); const res = room.getJoinedMembers();
expect(res.length).toEqual(0); expect(res.length).toEqual(0);
@ -971,42 +972,42 @@ describe("Room", function () {
it("should return true for a matching userId and membership", function () { it("should return true for a matching userId and membership", function () {
mocked(room.currentState.getMember).mockImplementation(function (userId) { mocked(room.currentState.getMember).mockImplementation(function (userId) {
return { return {
"@alice:bar": { userId: "@alice:bar", membership: "join" }, "@alice:bar": { userId: "@alice:bar", membership: KnownMembership.Join },
"@bob:bar": { userId: "@bob:bar", membership: "invite" }, "@bob:bar": { userId: "@bob:bar", membership: KnownMembership.Invite },
}[userId] as unknown as RoomMember; }[userId] as unknown as RoomMember;
}); });
expect(room.hasMembershipState("@bob:bar", "invite")).toBe(true); expect(room.hasMembershipState("@bob:bar", KnownMembership.Invite)).toBe(true);
}); });
it("should return false if match membership but no match userId", function () { it("should return false if match membership but no match userId", function () {
mocked(room.currentState.getMember).mockImplementation(function (userId) { mocked(room.currentState.getMember).mockImplementation(function (userId) {
return { return {
"@alice:bar": { userId: "@alice:bar", membership: "join" }, "@alice:bar": { userId: "@alice:bar", membership: KnownMembership.Join },
}[userId] as unknown as RoomMember; }[userId] as unknown as RoomMember;
}); });
expect(room.hasMembershipState("@bob:bar", "join")).toBe(false); expect(room.hasMembershipState("@bob:bar", KnownMembership.Join)).toBe(false);
}); });
it("should return false if match userId but no match membership", function () { it("should return false if match userId but no match membership", function () {
mocked(room.currentState.getMember).mockImplementation(function (userId) { mocked(room.currentState.getMember).mockImplementation(function (userId) {
return { return {
"@alice:bar": { userId: "@alice:bar", membership: "join" }, "@alice:bar": { userId: "@alice:bar", membership: KnownMembership.Join },
}[userId] as unknown as RoomMember; }[userId] as unknown as RoomMember;
}); });
expect(room.hasMembershipState("@alice:bar", "ban")).toBe(false); expect(room.hasMembershipState("@alice:bar", KnownMembership.Ban)).toBe(false);
}); });
it("should return false if no match membership or userId", function () { it("should return false if no match membership or userId", function () {
mocked(room.currentState.getMember).mockImplementation(function (userId) { mocked(room.currentState.getMember).mockImplementation(function (userId) {
return { return {
"@alice:bar": { userId: "@alice:bar", membership: "join" }, "@alice:bar": { userId: "@alice:bar", membership: KnownMembership.Join },
}[userId] as unknown as RoomMember; }[userId] as unknown as RoomMember;
}); });
expect(room.hasMembershipState("@bob:bar", "invite")).toBe(false); expect(room.hasMembershipState("@bob:bar", KnownMembership.Invite)).toBe(false);
}); });
it("should return false if no members exist", function () { it("should return false if no members exist", function () {
expect(room.hasMembershipState("@foo:bar", "join")).toBe(false); expect(room.hasMembershipState("@foo:bar", KnownMembership.Join)).toBe(false);
}); });
}); });
@ -1061,7 +1062,7 @@ describe("Room", function () {
}), }),
]); ]);
}; };
const addMember = async function (userId: string, state = "join", opts: any = {}) { const addMember = async function (userId: string, state = KnownMembership.Join, opts: any = {}) {
opts.room = roomId; opts.room = roomId;
opts.mship = state; opts.mship = state;
opts.user = opts.user || userId; opts.user = opts.user || userId;
@ -1083,7 +1084,7 @@ describe("Room", function () {
async function () { async function () {
const roomName = "flibble"; const roomName = "flibble";
const event = await addMember(userA, "invite"); const event = await addMember(userA, KnownMembership.Invite);
event.event.unsigned = {}; event.event.unsigned = {};
event.event.unsigned.invite_room_state = [ event.event.unsigned.invite_room_state = [
{ {
@ -1102,7 +1103,7 @@ describe("Room", function () {
); );
it("should not clobber state events if it isn't an invite room", async function () { it("should not clobber state events if it isn't an invite room", async function () {
const event = await addMember(userA, "join"); const event = await addMember(userA, KnownMembership.Join);
const roomName = "flibble"; const roomName = "flibble";
setRoomName(roomName); setRoomName(roomName);
const roomNameToIgnore = "ignoreme"; const roomNameToIgnore = "ignoreme";
@ -1125,7 +1126,7 @@ describe("Room", function () {
describe("Room.recalculate => Room Name using room summary", function () { describe("Room.recalculate => Room Name using room summary", function () {
it("should use room heroes if available", function () { it("should use room heroes if available", function () {
addMember(userA, "invite"); addMember(userA, KnownMembership.Invite);
addMember(userB); addMember(userB);
addMember(userC); addMember(userC);
addMember(userD); addMember(userD);
@ -1149,8 +1150,8 @@ describe("Room", function () {
it("uses hero name from state", function () { it("uses hero name from state", function () {
const name = "Mr B"; const name = "Mr B";
addMember(userA, "invite"); addMember(userA, KnownMembership.Invite);
addMember(userB, "join", { name }); addMember(userB, KnownMembership.Join, { name });
room.setSummary({ room.setSummary({
"m.heroes": [userB], "m.heroes": [userB],
}); });
@ -1161,7 +1162,7 @@ describe("Room", function () {
it("uses counts from summary", function () { it("uses counts from summary", function () {
const name = "Mr B"; const name = "Mr B";
addMember(userB, "join", { name }); addMember(userB, KnownMembership.Join, { name });
room.setSummary({ room.setSummary({
"m.heroes": [userB], "m.heroes": [userB],
"m.joined_member_count": 50, "m.joined_member_count": 50,
@ -1174,8 +1175,8 @@ describe("Room", function () {
it("relies on heroes in case of absent counts", function () { it("relies on heroes in case of absent counts", function () {
const nameB = "Mr Bean"; const nameB = "Mr Bean";
const nameC = "Mel C"; const nameC = "Mel C";
addMember(userB, "join", { name: nameB }); addMember(userB, KnownMembership.Join, { name: nameB });
addMember(userC, "join", { name: nameC }); addMember(userC, KnownMembership.Join, { name: nameC });
room.setSummary({ room.setSummary({
"m.heroes": [userB, userC], "m.heroes": [userB, userC],
}); });
@ -1185,8 +1186,8 @@ describe("Room", function () {
it("uses only heroes", function () { it("uses only heroes", function () {
const nameB = "Mr Bean"; const nameB = "Mr Bean";
addMember(userB, "join", { name: nameB }); addMember(userB, KnownMembership.Join, { name: nameB });
addMember(userC, "join"); addMember(userC, KnownMembership.Join);
room.setSummary({ room.setSummary({
"m.heroes": [userB], "m.heroes": [userB],
}); });
@ -1306,7 +1307,7 @@ describe("Room", function () {
" (invite join_rules) rooms if you are invited to it.", " (invite join_rules) rooms if you are invited to it.",
function () { function () {
setJoinRule(JoinRule.Invite); setJoinRule(JoinRule.Invite);
addMember(userA, "invite", { user: userB }); addMember(userA, KnownMembership.Invite, { user: userB });
addMember(userB); addMember(userB);
room.recalculate(); room.recalculate();
const name = room.name; const name = room.name;
@ -1396,8 +1397,8 @@ describe("Room", function () {
it("should return '[inviter display name] if state event " + "available", function () { it("should return '[inviter display name] if state event " + "available", function () {
setJoinRule(JoinRule.Invite); setJoinRule(JoinRule.Invite);
addMember(userB, "join", { name: "Alice" }); addMember(userB, KnownMembership.Join, { name: "Alice" });
addMember(userA, "invite", { user: userA }); addMember(userA, KnownMembership.Invite, { user: userA });
room.recalculate(); room.recalculate();
const name = room.name; const name = room.name;
expect(name).toEqual("Alice"); expect(name).toEqual("Alice");
@ -1406,7 +1407,7 @@ describe("Room", function () {
it("should return inviter mxid if display name not available", function () { it("should return inviter mxid if display name not available", function () {
setJoinRule(JoinRule.Invite); setJoinRule(JoinRule.Invite);
addMember(userB); addMember(userB);
addMember(userA, "invite", { user: userA }); addMember(userA, KnownMembership.Invite, { user: userA });
room.recalculate(); room.recalculate();
const name = room.name; const name = room.name;
expect(name).toEqual(userB); expect(name).toEqual(userB);
@ -2063,7 +2064,7 @@ describe("Room", function () {
const memberEvent = utils.mkMembership({ const memberEvent = utils.mkMembership({
user: "@user_a:bar", user: "@user_a:bar",
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
name: "User A", name: "User A",
@ -2083,7 +2084,7 @@ describe("Room", function () {
it("should take members from storage if available", async function () { it("should take members from storage if available", async function () {
const memberEvent2 = utils.mkMembership({ const memberEvent2 = utils.mkMembership({
user: "@user_a:bar", user: "@user_a:bar",
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
name: "Ms A", name: "Ms A",
@ -2112,7 +2113,7 @@ describe("Room", function () {
describe("getMyMembership", function () { describe("getMyMembership", function () {
it("should return synced membership if membership isn't available yet", function () { it("should return synced membership if membership isn't available yet", function () {
const room = new Room(roomId, null!, userA); const room = new Room(roomId, null!, userA);
room.updateMyMembership(JoinRule.Invite); room.updateMyMembership(KnownMembership.Invite);
expect(room.getMyMembership()).toEqual(JoinRule.Invite); expect(room.getMyMembership()).toEqual(JoinRule.Invite);
}); });
it("should emit a Room.myMembership event on a change", function () { it("should emit a Room.myMembership event on a change", function () {
@ -2124,15 +2125,15 @@ describe("Room", function () {
room.on(RoomEvent.MyMembership, (_room, membership, oldMembership) => { room.on(RoomEvent.MyMembership, (_room, membership, oldMembership) => {
events.push({ membership, oldMembership }); events.push({ membership, oldMembership });
}); });
room.updateMyMembership(JoinRule.Invite); room.updateMyMembership(KnownMembership.Invite);
expect(room.getMyMembership()).toEqual(JoinRule.Invite); expect(room.getMyMembership()).toEqual(JoinRule.Invite);
expect(events[0]).toEqual({ membership: "invite", oldMembership: undefined }); expect(events[0]).toEqual({ membership: KnownMembership.Invite, oldMembership: undefined });
events.splice(0); //clear events.splice(0); //clear
room.updateMyMembership(JoinRule.Invite); room.updateMyMembership(KnownMembership.Invite);
expect(events.length).toEqual(0); expect(events.length).toEqual(0);
room.updateMyMembership("join"); room.updateMyMembership(KnownMembership.Join);
expect(room.getMyMembership()).toEqual("join"); expect(room.getMyMembership()).toEqual(KnownMembership.Join);
expect(events[0]).toEqual({ membership: "join", oldMembership: "invite" }); expect(events[0]).toEqual({ membership: KnownMembership.Join, oldMembership: KnownMembership.Invite });
}); });
}); });
@ -2146,7 +2147,7 @@ describe("Room", function () {
state_key: userA, state_key: userA,
sender: userB, sender: userB,
content: { content: {
membership: "invite", membership: KnownMembership.Invite,
is_direct: true, is_direct: true,
}, },
}), }),
@ -2157,7 +2158,7 @@ describe("Room", function () {
it("should fall back to summary heroes and return the first one", () => { it("should fall back to summary heroes and return the first one", () => {
const room = new Room(roomId, null!, userA); const room = new Room(roomId, null!, userA);
room.updateMyMembership("invite"); room.updateMyMembership(KnownMembership.Invite);
room.setSummary({ room.setSummary({
"m.heroes": [userA, userC], "m.heroes": [userA, userC],
"m.joined_member_count": 1, "m.joined_member_count": 1,
@ -2170,7 +2171,7 @@ describe("Room", function () {
it("should return undefined if we're not joined or invited to the room", () => { it("should return undefined if we're not joined or invited to the room", () => {
const room = new Room(roomId, null!, userA); const room = new Room(roomId, null!, userA);
expect(room.getDMInviter()).toBeUndefined(); expect(room.getDMInviter()).toBeUndefined();
room.updateMyMembership("leave"); room.updateMyMembership(KnownMembership.Leave);
expect(room.getDMInviter()).toBeUndefined(); expect(room.getDMInviter()).toBeUndefined();
}); });
}); });
@ -2190,7 +2191,7 @@ describe("Room", function () {
await room.addLiveEvents([ await room.addLiveEvents([
utils.mkMembership({ utils.mkMembership({
user: userB, user: userB,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
}), }),
@ -2220,7 +2221,7 @@ describe("Room", function () {
state_key: userD, state_key: userD,
sender: userD, sender: userD,
content: { content: {
membership: "join", membership: KnownMembership.Join,
}, },
}), }),
]); ]);
@ -2308,11 +2309,11 @@ describe("Room", function () {
describe("maySendMessage", function () { describe("maySendMessage", function () {
it("should return false if synced membership not join", function () { it("should return false if synced membership not join", function () {
const room = new Room(roomId, { isRoomEncrypted: () => false } as any, userA); const room = new Room(roomId, { isRoomEncrypted: () => false } as any, userA);
room.updateMyMembership(JoinRule.Invite); room.updateMyMembership(KnownMembership.Invite);
expect(room.maySendMessage()).toEqual(false); expect(room.maySendMessage()).toEqual(false);
room.updateMyMembership("leave"); room.updateMyMembership(KnownMembership.Leave);
expect(room.maySendMessage()).toEqual(false); expect(room.maySendMessage()).toEqual(false);
room.updateMyMembership("join"); room.updateMyMembership(KnownMembership.Join);
expect(room.maySendMessage()).toEqual(true); expect(room.maySendMessage()).toEqual(true);
}); });
}); });
@ -2328,14 +2329,14 @@ describe("Room", function () {
await room.addLiveEvents([ await room.addLiveEvents([
utils.mkMembership({ utils.mkMembership({
user: userA, user: userA,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
name: "User A", name: "User A",
}), }),
utils.mkMembership({ utils.mkMembership({
user: userB, user: userB,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
name: "User B", name: "User B",
@ -2349,14 +2350,14 @@ describe("Room", function () {
await room.addLiveEvents([ await room.addLiveEvents([
utils.mkMembership({ utils.mkMembership({
user: userA, user: userA,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
name: "User A", name: "User A",
}), }),
utils.mkMembership({ utils.mkMembership({
user: userB, user: userB,
mship: "ban", mship: KnownMembership.Ban,
room: roomId, room: roomId,
event: true, event: true,
name: "User B", name: "User B",
@ -2370,14 +2371,14 @@ describe("Room", function () {
await room.addLiveEvents([ await room.addLiveEvents([
utils.mkMembership({ utils.mkMembership({
user: userA, user: userA,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
name: "User A", name: "User A",
}), }),
utils.mkMembership({ utils.mkMembership({
user: userB, user: userB,
mship: "invite", mship: KnownMembership.Invite,
room: roomId, room: roomId,
event: true, event: true,
name: "User B", name: "User B",
@ -2391,14 +2392,14 @@ describe("Room", function () {
await room.addLiveEvents([ await room.addLiveEvents([
utils.mkMembership({ utils.mkMembership({
user: userA, user: userA,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
name: "User A", name: "User A",
}), }),
utils.mkMembership({ utils.mkMembership({
user: userB, user: userB,
mship: "leave", mship: KnownMembership.Leave,
room: roomId, room: roomId,
event: true, event: true,
name: "User B", name: "User B",
@ -2412,21 +2413,21 @@ describe("Room", function () {
await room.addLiveEvents([ await room.addLiveEvents([
utils.mkMembership({ utils.mkMembership({
user: userA, user: userA,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
name: "User A", name: "User A",
}), }),
utils.mkMembership({ utils.mkMembership({
user: userB, user: userB,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
name: "User B", name: "User B",
}), }),
utils.mkMembership({ utils.mkMembership({
user: userC, user: userC,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
name: "User C", name: "User C",
@ -2440,28 +2441,28 @@ describe("Room", function () {
await room.addLiveEvents([ await room.addLiveEvents([
utils.mkMembership({ utils.mkMembership({
user: userA, user: userA,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
name: "User A", name: "User A",
}), }),
utils.mkMembership({ utils.mkMembership({
user: userB, user: userB,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
name: "User B", name: "User B",
}), }),
utils.mkMembership({ utils.mkMembership({
user: userC, user: userC,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
name: "User C", name: "User C",
}), }),
utils.mkMembership({ utils.mkMembership({
user: userD, user: userD,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
name: "User D", name: "User D",
@ -2477,14 +2478,14 @@ describe("Room", function () {
await room.addLiveEvents([ await room.addLiveEvents([
utils.mkMembership({ utils.mkMembership({
user: userA, user: userA,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
name: "User A", name: "User A",
}), }),
utils.mkMembership({ utils.mkMembership({
user: userB, user: userB,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
name: "User B", name: "User B",
@ -2507,14 +2508,14 @@ describe("Room", function () {
await room.addLiveEvents([ await room.addLiveEvents([
utils.mkMembership({ utils.mkMembership({
user: userA, user: userA,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
name: "User A", name: "User A",
}), }),
utils.mkMembership({ utils.mkMembership({
user: userB, user: userB,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
name: "User B", name: "User B",
@ -2537,14 +2538,14 @@ describe("Room", function () {
await room.addLiveEvents([ await room.addLiveEvents([
utils.mkMembership({ utils.mkMembership({
user: userA, user: userA,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
name: "User A", name: "User A",
}), }),
utils.mkMembership({ utils.mkMembership({
user: userB, user: userB,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
name: "User B", name: "User B",
@ -2567,14 +2568,14 @@ describe("Room", function () {
await room.addLiveEvents([ await room.addLiveEvents([
utils.mkMembership({ utils.mkMembership({
user: userA, user: userA,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
name: "User A", name: "User A",
}), }),
utils.mkMembership({ utils.mkMembership({
user: userB, user: userB,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
name: "User B", name: "User B",
@ -2597,21 +2598,21 @@ describe("Room", function () {
await room.addLiveEvents([ await room.addLiveEvents([
utils.mkMembership({ utils.mkMembership({
user: userA, user: userA,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
name: "User A", name: "User A",
}), }),
utils.mkMembership({ utils.mkMembership({
user: userB, user: userB,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
name: "User B", name: "User B",
}), }),
utils.mkMembership({ utils.mkMembership({
user: userC, user: userC,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
name: "User C", name: "User C",
@ -2635,21 +2636,21 @@ describe("Room", function () {
await room.addLiveEvents([ await room.addLiveEvents([
utils.mkMembership({ utils.mkMembership({
user: userA, user: userA,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
name: "User A", name: "User A",
}), }),
utils.mkMembership({ utils.mkMembership({
user: userB, user: userB,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
name: "User B", name: "User B",
}), }),
utils.mkMembership({ utils.mkMembership({
user: userC, user: userC,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
name: "User C", name: "User C",
@ -2673,14 +2674,14 @@ describe("Room", function () {
await room.addLiveEvents([ await room.addLiveEvents([
utils.mkMembership({ utils.mkMembership({
user: userA, user: userA,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
name: "User A", name: "User A",
}), }),
utils.mkMembership({ utils.mkMembership({
user: userB, user: userB,
mship: "join", mship: KnownMembership.Join,
room: roomId, room: roomId,
event: true, event: true,
name: "User B", name: "User B",

View File

@ -30,6 +30,7 @@ import { RoomEncryptor, toRustHistoryVisibility } from "../../../src/rust-crypto
import { KeyClaimManager } from "../../../src/rust-crypto/KeyClaimManager"; import { KeyClaimManager } from "../../../src/rust-crypto/KeyClaimManager";
import { defer } from "../../../src/utils"; import { defer } from "../../../src/utils";
import { OutgoingRequestsManager } from "../../../src/rust-crypto/OutgoingRequestsManager"; import { OutgoingRequestsManager } from "../../../src/rust-crypto/OutgoingRequestsManager";
import { KnownMembership } from "../../../src/@types/membership";
describe("RoomEncryptor", () => { describe("RoomEncryptor", () => {
describe("History Visibility", () => { describe("History Visibility", () => {
@ -54,7 +55,7 @@ describe("RoomEncryptor", () => {
const mockRoomMember = { const mockRoomMember = {
userId: "@alice:example.org", userId: "@alice:example.org",
membership: "join", membership: KnownMembership.Join,
} as unknown as Mocked<RoomMember>; } as unknown as Mocked<RoomMember>;
function createMockEvent(text: string): Mocked<MatrixEvent> { function createMockEvent(text: string): Mocked<MatrixEvent> {

View File

@ -6,6 +6,7 @@ import { MatrixError } from "../../src/http-api";
import { MatrixScheduler } from "../../src/scheduler"; import { MatrixScheduler } from "../../src/scheduler";
import * as utils from "../test-utils/test-utils"; import * as utils from "../test-utils/test-utils";
import { MatrixEvent } from "../../src"; import { MatrixEvent } from "../../src";
import { KnownMembership } from "../../src/@types/membership";
jest.useFakeTimers(); jest.useFakeTimers();
@ -336,7 +337,7 @@ describe("MatrixScheduler", function () {
utils.mkMembership({ utils.mkMembership({
user: "@alice:bar", user: "@alice:bar",
room: roomId, room: roomId,
mship: "join", mship: KnownMembership.Join,
event: true, event: true,
}), }),
), ),

View File

@ -31,6 +31,7 @@ import {
} from "../../src/sync-accumulator"; } from "../../src/sync-accumulator";
import { IRoomSummary } from "../../src"; import { IRoomSummary } from "../../src";
import * as utils from "../test-utils/test-utils"; import * as utils from "../test-utils/test-utils";
import { KnownMembership, Membership } from "../../src/@types/membership";
// The event body & unsigned object get frozen to assert that they don't get altered // The event body & unsigned object get frozen to assert that they don't get altered
// by the impl // by the impl
@ -95,7 +96,7 @@ describe("SyncAccumulator", function () {
ephemeral: { events: [] }, ephemeral: { events: [] },
unread_notifications: {}, unread_notifications: {},
state: { state: {
events: [member("alice", "join"), member("bob", "join")], events: [member("alice", KnownMembership.Join), member("bob", KnownMembership.Join)],
}, },
summary: { summary: {
"m.heroes": undefined, "m.heroes": undefined,
@ -111,7 +112,7 @@ describe("SyncAccumulator", function () {
knock: { knock: {
"!knock": { "!knock": {
knock_state: { knock_state: {
events: [member("alice", "knock")], events: [member("alice", KnownMembership.Knock)],
}, },
}, },
}, },
@ -128,7 +129,7 @@ describe("SyncAccumulator", function () {
// 10 timeline messages with a prev_batch of "pinned_to_1" // 10 timeline messages with a prev_batch of "pinned_to_1"
sa.accumulate( sa.accumulate(
syncSkeleton({ syncSkeleton({
state: { events: [member("alice", "join")] }, state: { events: [member("alice", KnownMembership.Join)] },
timeline: { timeline: {
events: [ events: [
msg("alice", "1"), msg("alice", "1"),
@ -204,7 +205,7 @@ describe("SyncAccumulator", function () {
it("should remove the stored timeline on limited syncs", () => { it("should remove the stored timeline on limited syncs", () => {
sa.accumulate( sa.accumulate(
syncSkeleton({ syncSkeleton({
state: { events: [member("alice", "join")] }, state: { events: [member("alice", KnownMembership.Join)] },
timeline: { timeline: {
events: [msg("alice", "1"), msg("alice", "2"), msg("alice", "3")], events: [msg("alice", "1"), msg("alice", "2"), msg("alice", "3")],
prev_batch: "pinned_to_1", prev_batch: "pinned_to_1",
@ -312,7 +313,7 @@ describe("SyncAccumulator", function () {
events: [ events: [
{ {
content: { content: {
membership: "invite", membership: KnownMembership.Invite,
}, },
state_key: "bob", state_key: "bob",
sender: "alice", sender: "alice",
@ -336,7 +337,7 @@ describe("SyncAccumulator", function () {
const rejectMemberEvent: IStateEvent = { const rejectMemberEvent: IStateEvent = {
event_id: "$" + Math.random(), event_id: "$" + Math.random(),
content: { content: {
membership: "leave", membership: KnownMembership.Leave,
}, },
origin_server_ts: 123456789, origin_server_ts: 123456789,
state_key: "bob", state_key: "bob",
@ -344,7 +345,7 @@ describe("SyncAccumulator", function () {
type: "m.room.member", type: "m.room.member",
unsigned: { unsigned: {
prev_content: { prev_content: {
membership: "invite", membership: KnownMembership.Invite,
}, },
}, },
}; };
@ -366,7 +367,7 @@ describe("SyncAccumulator", function () {
it("should accumulate knock state", () => { it("should accumulate knock state", () => {
const initKnockState = { const initKnockState = {
events: [member("alice", "knock")], events: [member("alice", KnownMembership.Knock)],
}; };
sa.accumulate( sa.accumulate(
syncSkeleton( syncSkeleton(
@ -453,7 +454,7 @@ describe("SyncAccumulator", function () {
const inviteStateEvents = [ const inviteStateEvents = [
{ {
content: { content: {
membership: "invite", membership: KnownMembership.Invite,
}, },
state_key: "bob", state_key: "bob",
sender: "alice", sender: "alice",
@ -482,7 +483,7 @@ describe("SyncAccumulator", function () {
const memberEvent: IStateEvent = { const memberEvent: IStateEvent = {
event_id: "$" + Math.random(), event_id: "$" + Math.random(),
content: { content: {
membership: "leave", membership: KnownMembership.Leave,
}, },
origin_server_ts: 123456789, origin_server_ts: 123456789,
state_key: "bob", state_key: "bob",
@ -490,7 +491,7 @@ describe("SyncAccumulator", function () {
type: "m.room.member", type: "m.room.member",
unsigned: { unsigned: {
prev_content: { prev_content: {
membership: "knock", membership: KnownMembership.Knock,
}, },
}, },
}; };
@ -528,7 +529,7 @@ describe("SyncAccumulator", function () {
const memberEvent: IStateEvent = { const memberEvent: IStateEvent = {
event_id: "$" + Math.random(), event_id: "$" + Math.random(),
content: { content: {
membership: "leave", membership: KnownMembership.Leave,
}, },
origin_server_ts: 123456789, origin_server_ts: 123456789,
state_key: "bob", state_key: "bob",
@ -536,7 +537,7 @@ describe("SyncAccumulator", function () {
type: "m.room.member", type: "m.room.member",
unsigned: { unsigned: {
prev_content: { prev_content: {
membership: "knock", membership: KnownMembership.Knock,
}, },
}, },
}; };
@ -933,7 +934,7 @@ function makeKnockState(): IKnockState {
name: "Room", name: "Room",
}, },
}) as IStrippedState, }) as IStrippedState,
member("bob", "knock"), member("bob", KnownMembership.Knock),
], ],
}; };
} }
@ -950,7 +951,7 @@ function msg(localpart: string, text: string) {
}; };
} }
function member(localpart: string, membership: string) { function member(localpart: string, membership: Membership) {
return { return {
event_id: "$" + Math.random(), event_id: "$" + Math.random(),
content: { content: {

View File

@ -47,6 +47,7 @@ import { flushPromises } from "../../test-utils/flushPromises";
import { CallFeedReport } from "../../../src/webrtc/stats/statsReport"; import { CallFeedReport } from "../../../src/webrtc/stats/statsReport";
import { CallFeedStatsReporter } from "../../../src/webrtc/stats/callFeedStatsReporter"; import { CallFeedStatsReporter } from "../../../src/webrtc/stats/callFeedStatsReporter";
import { StatsReportEmitter } from "../../../src/webrtc/stats/statsReportEmitter"; import { StatsReportEmitter } from "../../../src/webrtc/stats/statsReportEmitter";
import { KnownMembership } from "../../../src/@types/membership";
const FAKE_STATE_EVENTS = [ const FAKE_STATE_EVENTS = [
{ {
@ -143,7 +144,7 @@ describe("Group Call", function () {
groupCall = new GroupCall(mockClient, room, GroupCallType.Video, false, GroupCallIntent.Prompt); groupCall = new GroupCall(mockClient, room, GroupCallType.Video, false, GroupCallIntent.Prompt);
room.currentState.members[FAKE_USER_ID_1] = { room.currentState.members[FAKE_USER_ID_1] = {
userId: FAKE_USER_ID_1, userId: FAKE_USER_ID_1,
membership: "join", membership: KnownMembership.Join,
} as unknown as RoomMember; } as unknown as RoomMember;
}); });
@ -651,11 +652,11 @@ describe("Group Call", function () {
client1Room.currentState.members[FAKE_USER_ID_1] = client2Room.currentState.members[FAKE_USER_ID_1] = { client1Room.currentState.members[FAKE_USER_ID_1] = client2Room.currentState.members[FAKE_USER_ID_1] = {
userId: FAKE_USER_ID_1, userId: FAKE_USER_ID_1,
membership: "join", membership: KnownMembership.Join,
} as unknown as RoomMember; } as unknown as RoomMember;
client1Room.currentState.members[FAKE_USER_ID_2] = client2Room.currentState.members[FAKE_USER_ID_2] = { client1Room.currentState.members[FAKE_USER_ID_2] = client2Room.currentState.members[FAKE_USER_ID_2] = {
userId: FAKE_USER_ID_2, userId: FAKE_USER_ID_2,
membership: "join", membership: KnownMembership.Join,
} as unknown as RoomMember; } as unknown as RoomMember;
groupCall1 = new GroupCall( groupCall1 = new GroupCall(
@ -831,11 +832,11 @@ describe("Group Call", function () {
room.currentState.getStateEvents = jest.fn().mockImplementation(mockGetStateEvents()); room.currentState.getStateEvents = jest.fn().mockImplementation(mockGetStateEvents());
room.currentState.members[FAKE_USER_ID_1] = { room.currentState.members[FAKE_USER_ID_1] = {
userId: FAKE_USER_ID_1, userId: FAKE_USER_ID_1,
membership: "join", membership: KnownMembership.Join,
} as unknown as RoomMember; } as unknown as RoomMember;
room.currentState.members[FAKE_USER_ID_2] = { room.currentState.members[FAKE_USER_ID_2] = {
userId: FAKE_USER_ID_2, userId: FAKE_USER_ID_2,
membership: "join", membership: KnownMembership.Join,
} as unknown as RoomMember; } as unknown as RoomMember;
}); });
@ -1026,11 +1027,11 @@ describe("Group Call", function () {
room = new Room(FAKE_ROOM_ID, mockClient, FAKE_USER_ID_2); room = new Room(FAKE_ROOM_ID, mockClient, FAKE_USER_ID_2);
room.currentState.members[FAKE_USER_ID_1] = { room.currentState.members[FAKE_USER_ID_1] = {
userId: FAKE_USER_ID_1, userId: FAKE_USER_ID_1,
membership: "join", membership: KnownMembership.Join,
} as unknown as RoomMember; } as unknown as RoomMember;
room.currentState.members[FAKE_USER_ID_2] = { room.currentState.members[FAKE_USER_ID_2] = {
userId: FAKE_USER_ID_2, userId: FAKE_USER_ID_2,
membership: "join", membership: KnownMembership.Join,
} as unknown as RoomMember; } as unknown as RoomMember;
groupCall = await createAndEnterGroupCall(mockClient, room); groupCall = await createAndEnterGroupCall(mockClient, room);
@ -1260,11 +1261,11 @@ describe("Group Call", function () {
room = new Room(FAKE_ROOM_ID, mockClient, FAKE_USER_ID_1); room = new Room(FAKE_ROOM_ID, mockClient, FAKE_USER_ID_1);
room.currentState.members[FAKE_USER_ID_1] = { room.currentState.members[FAKE_USER_ID_1] = {
userId: FAKE_USER_ID_1, userId: FAKE_USER_ID_1,
membership: "join", membership: KnownMembership.Join,
} as unknown as RoomMember; } as unknown as RoomMember;
room.currentState.members[FAKE_USER_ID_2] = { room.currentState.members[FAKE_USER_ID_2] = {
userId: FAKE_USER_ID_2, userId: FAKE_USER_ID_2,
membership: "join", membership: KnownMembership.Join,
} as unknown as RoomMember; } as unknown as RoomMember;
room.currentState.getStateEvents = jest.fn().mockImplementation(mockGetStateEvents()); room.currentState.getStateEvents = jest.fn().mockImplementation(mockGetStateEvents());
@ -1741,11 +1742,11 @@ describe("Group Call", function () {
const room = new Room(FAKE_ROOM_ID, mockClient, FAKE_USER_ID_1); const room = new Room(FAKE_ROOM_ID, mockClient, FAKE_USER_ID_1);
room.currentState.members[FAKE_USER_ID_1] = { room.currentState.members[FAKE_USER_ID_1] = {
userId: FAKE_USER_ID_1, userId: FAKE_USER_ID_1,
membership: "join", membership: KnownMembership.Join,
} as unknown as RoomMember; } as unknown as RoomMember;
room.currentState.members[FAKE_USER_ID_2] = { room.currentState.members[FAKE_USER_ID_2] = {
userId: FAKE_USER_ID_2, userId: FAKE_USER_ID_2,
membership: "join", membership: KnownMembership.Join,
} as unknown as RoomMember; } as unknown as RoomMember;
room.currentState.getStateEvents = jest.fn().mockImplementation(mockGetStateEvents()); room.currentState.getStateEvents = jest.fn().mockImplementation(mockGetStateEvents());
groupCall = await createAndEnterGroupCall(mockClient, room); groupCall = await createAndEnterGroupCall(mockClient, room);

View File

@ -31,6 +31,7 @@ import { RoomState } from "../../../src/models/room-state";
import { GroupCallEventHandler, GroupCallEventHandlerEvent } from "../../../src/webrtc/groupCallEventHandler"; import { GroupCallEventHandler, GroupCallEventHandlerEvent } from "../../../src/webrtc/groupCallEventHandler";
import { flushPromises } from "../../test-utils/flushPromises"; import { flushPromises } from "../../test-utils/flushPromises";
import { makeMockGroupCallStateEvent, MockCallMatrixClient } from "../../test-utils/webrtc"; import { makeMockGroupCallStateEvent, MockCallMatrixClient } from "../../test-utils/webrtc";
import { KnownMembership } from "../../../src/@types/membership";
const FAKE_USER_ID = "@alice:test.dummy"; const FAKE_USER_ID = "@alice:test.dummy";
const FAKE_DEVICE_ID = "AAAAAAA"; const FAKE_DEVICE_ID = "AAAAAAA";
@ -50,7 +51,7 @@ describe("Group Call Event Handler", function () {
mockMember = { mockMember = {
userId: FAKE_USER_ID, userId: FAKE_USER_ID,
membership: "join", membership: KnownMembership.Join,
} as unknown as RoomMember; } as unknown as RoomMember;
const mockEvent = makeMockGroupCallStateEvent(FAKE_ROOM_ID, FAKE_GROUP_CALL_ID); const mockEvent = makeMockGroupCallStateEvent(FAKE_ROOM_ID, FAKE_GROUP_CALL_ID);

57
src/@types/membership.ts Normal file
View File

@ -0,0 +1,57 @@
/*
Copyright 2024 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* Well-known values (from the spec or MSCs) that are allowed in the
* {@link Membership} type.
*/
export enum KnownMembership {
/**
* The user has been banned from the room, and is no longer allowed to join
* it until they are un-banned from the room (by having their membership
* state set to a value other than ban).
*/
Ban = "ban",
/**
* The user has been invited to join a room, but has not yet joined it.
* They may not participate in the room until they join.
* */
Invite = "invite",
/**
* The user has joined the room (possibly after accepting an invite), and
* may participate in it.
*/
Join = "join",
/**
* The user has knocked on the room, requesting permission to participate.
* They may not participate in the room until they join.
*/
Knock = "knock",
/**
* The user was once joined to the room, but has since left (possibly by
* choice, or possibly by being kicked).
*/
Leave = "leave",
}
/**
* The membership state for a user in a room [1]. A value from
* {@link KnownMembership} should be used where available, but all string values
* are allowed to provide flexibility for upcoming spec changes or proposals.
*
* [1] https://spec.matrix.org/latest/client-server-api/#mroommember
*/
export type Membership = KnownMembership | string;

View File

@ -222,6 +222,7 @@ import {
import { RegisterRequest, RegisterResponse } from "./@types/registration"; import { RegisterRequest, RegisterResponse } from "./@types/registration";
import { MatrixRTCSessionManager } from "./matrixrtc/MatrixRTCSessionManager"; import { MatrixRTCSessionManager } from "./matrixrtc/MatrixRTCSessionManager";
import { getRelationsThreadFilter } from "./thread-utils"; import { getRelationsThreadFilter } from "./thread-utils";
import { KnownMembership, Membership } from "./@types/membership";
export type Store = IStore; export type Store = IStore;
@ -721,7 +722,7 @@ export interface IOpenIDToken {
interface IRoomInitialSyncResponse { interface IRoomInitialSyncResponse {
room_id: string; room_id: string;
membership: "invite" | "join" | "leave" | "ban"; membership: Membership;
messages?: { messages?: {
start?: string; start?: string;
end?: string; end?: string;
@ -866,7 +867,7 @@ interface IThirdPartyUser {
interface IRoomSummary extends Omit<IPublicRoomsChunkRoom, "canonical_alias" | "aliases"> { interface IRoomSummary extends Omit<IPublicRoomsChunkRoom, "canonical_alias" | "aliases"> {
room_type?: RoomType; room_type?: RoomType;
membership?: string; membership?: Membership;
is_encrypted: boolean; is_encrypted: boolean;
} }
@ -4357,7 +4358,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
} }
const room = this.getRoom(roomIdOrAlias); const room = this.getRoom(roomIdOrAlias);
if (room?.hasMembershipState(this.credentials.userId!, "join")) return room; if (room?.hasMembershipState(this.credentials.userId!, KnownMembership.Join)) return room;
let signPromise: Promise<IThirdPartySigned | void> = Promise.resolve(); let signPromise: Promise<IThirdPartySigned | void> = Promise.resolve();
@ -4386,7 +4387,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
// with the resolved ID - this method is supposed to no-op if we already // with the resolved ID - this method is supposed to no-op if we already
// were in the room, after all. // were in the room, after all.
const resolvedRoom = this.getRoom(roomId); const resolvedRoom = this.getRoom(roomId);
if (resolvedRoom?.hasMembershipState(this.credentials.userId!, "join")) return resolvedRoom; if (resolvedRoom?.hasMembershipState(this.credentials.userId!, KnownMembership.Join)) return resolvedRoom;
const syncApi = new SyncApi(this, this.clientOpts, this.buildSyncApiOptions()); const syncApi = new SyncApi(this, this.clientOpts, this.buildSyncApiOptions());
const syncRoom = syncApi.createRoom(roomId); const syncRoom = syncApi.createRoom(roomId);
@ -4406,7 +4407,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
*/ */
public knockRoom(roomIdOrAlias: string, opts: KnockRoomOpts = {}): Promise<{ room_id: string }> { public knockRoom(roomIdOrAlias: string, opts: KnockRoomOpts = {}): Promise<{ room_id: string }> {
const room = this.getRoom(roomIdOrAlias); const room = this.getRoom(roomIdOrAlias);
if (room?.hasMembershipState(this.credentials.userId!, "knock")) { if (room?.hasMembershipState(this.credentials.userId!, KnownMembership.Knock)) {
return Promise.resolve({ room_id: room.roomId }); return Promise.resolve({ room_id: room.roomId });
} }
@ -5548,7 +5549,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* @returns Rejects: with an error response. * @returns Rejects: with an error response.
*/ */
public invite(roomId: string, userId: string, reason?: string): Promise<{}> { public invite(roomId: string, userId: string, reason?: string): Promise<{}> {
return this.membershipChange(roomId, userId, "invite", reason); return this.membershipChange(roomId, userId, KnownMembership.Invite, reason);
} }
/** /**
@ -5603,7 +5604,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* @returns Rejects: with an error response. * @returns Rejects: with an error response.
*/ */
public leave(roomId: string): Promise<{}> { public leave(roomId: string): Promise<{}> {
return this.membershipChange(roomId, undefined, "leave"); return this.membershipChange(roomId, undefined, KnownMembership.Leave);
} }
/** /**
@ -5661,7 +5662,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* @returns Rejects: with an error response. * @returns Rejects: with an error response.
*/ */
public ban(roomId: string, userId: string, reason?: string): Promise<{}> { public ban(roomId: string, userId: string, reason?: string): Promise<{}> {
return this.membershipChange(roomId, userId, "ban", reason); return this.membershipChange(roomId, userId, KnownMembership.Ban, reason);
} }
/** /**
@ -5720,7 +5721,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
private membershipChange( private membershipChange(
roomId: string, roomId: string,
userId: string | undefined, userId: string | undefined,
membership: string, membership: Membership | "forget",
reason?: string, reason?: string,
): Promise<{}> { ): Promise<{}> {
// API returns an empty object // API returns an empty object
@ -9780,7 +9781,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
*/ */
public unstableGetFileTreeSpace(roomId: string): MSC3089TreeSpace | null { public unstableGetFileTreeSpace(roomId: string): MSC3089TreeSpace | null {
const room = this.getRoom(roomId); const room = this.getRoom(roomId);
if (room?.getMyMembership() !== "join") return null; if (room?.getMyMembership() !== KnownMembership.Join) return null;
const createEvent = room.currentState.getStateEvents(EventType.RoomCreate, ""); const createEvent = room.currentState.getStateEvents(EventType.RoomCreate, "");
const purposeEvent = room.currentState.getStateEvents( const purposeEvent = room.currentState.getStateEvents(

View File

@ -44,6 +44,7 @@ import { RoomKeyRequestState } from "../OutgoingRoomKeyRequestManager";
import { OlmGroupSessionExtraData } from "../../@types/crypto"; import { OlmGroupSessionExtraData } from "../../@types/crypto";
import { MatrixError } from "../../http-api"; import { MatrixError } from "../../http-api";
import { immediate, MapWithDefault } from "../../utils"; import { immediate, MapWithDefault } from "../../utils";
import { KnownMembership } from "../../@types/membership";
// determine whether the key can be shared with invitees // determine whether the key can be shared with invitees
export function isRoomSharedHistory(room: Room): boolean { export function isRoomSharedHistory(room: Room): boolean {
@ -1680,7 +1681,7 @@ export class MegolmDecryption extends DecryptionAlgorithm {
const fromInviter = const fromInviter =
memberEvent?.getSender() === senderKeyUser || memberEvent?.getSender() === senderKeyUser ||
(memberEvent?.getUnsigned()?.prev_sender === senderKeyUser && (memberEvent?.getUnsigned()?.prev_sender === senderKeyUser &&
memberEvent?.getPrevContent()?.membership === "invite"); memberEvent?.getPrevContent()?.membership === KnownMembership.Invite);
if (room && fromInviter) { if (room && fromInviter) {
return true; return true;

View File

@ -104,6 +104,7 @@ import { Device, DeviceMap } from "../models/device";
import { deviceInfoToDevice } from "./device-converter"; import { deviceInfoToDevice } from "./device-converter";
import { ClientPrefix, MatrixError, Method } from "../http-api"; import { ClientPrefix, MatrixError, Method } from "../http-api";
import { decodeBase64, encodeBase64 } from "../base64"; import { decodeBase64, encodeBase64 } from "../base64";
import { KnownMembership } from "../@types/membership";
/* re-exports for backwards compatibility */ /* re-exports for backwards compatibility */
export type { export type {
@ -3504,7 +3505,7 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
// ignore any rooms which we have left // ignore any rooms which we have left
const myMembership = room.getMyMembership(); const myMembership = room.getMyMembership();
return myMembership === "join" || myMembership === "invite"; return myMembership === KnownMembership.Join || myMembership === KnownMembership.Invite;
}); });
} }
@ -3987,12 +3988,12 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
// the result of anyway, as we'll need to do a query again once all the members are fetched // the result of anyway, as we'll need to do a query again once all the members are fetched
// by calling _trackRoomDevices // by calling _trackRoomDevices
if (roomId in this.roomDeviceTrackingState) { if (roomId in this.roomDeviceTrackingState) {
if (member.membership == "join") { if (member.membership == KnownMembership.Join) {
logger.log("Join event for " + member.userId + " in " + roomId); logger.log("Join event for " + member.userId + " in " + roomId);
// make sure we are tracking the deviceList for this user // make sure we are tracking the deviceList for this user
this.deviceList.startTrackingDeviceList(member.userId); this.deviceList.startTrackingDeviceList(member.userId);
} else if ( } else if (
member.membership == "invite" && member.membership == KnownMembership.Invite &&
this.clientStore.getRoom(roomId)?.shouldEncryptForInvitedMembers() this.clientStore.getRoom(roomId)?.shouldEncryptForInvitedMembers()
) { ) {
logger.log("Invite event for " + member.userId + " in " + roomId); logger.log("Invite event for " + member.userId + " in " + roomId);

View File

@ -23,10 +23,12 @@ import { EventType } from "../@types/event";
import { CallMembership, CallMembershipData } from "./CallMembership"; import { CallMembership, CallMembershipData } from "./CallMembership";
import { RoomStateEvent } from "../models/room-state"; import { RoomStateEvent } from "../models/room-state";
import { Focus } from "./focus"; import { Focus } from "./focus";
import { MatrixError, MatrixEvent } from "../matrix";
import { randomString, secureRandomBase64Url } from "../randomstring"; import { randomString, secureRandomBase64Url } from "../randomstring";
import { EncryptionKeysEventContent } from "./types"; import { EncryptionKeysEventContent } from "./types";
import { decodeBase64, encodeUnpaddedBase64 } from "../base64"; import { decodeBase64, encodeUnpaddedBase64 } from "../base64";
import { KnownMembership } from "../@types/membership";
import { MatrixError } from "../http-api/errors";
import { MatrixEvent } from "../models/event";
const MEMBERSHIP_EXPIRY_TIME = 60 * 60 * 1000; const MEMBERSHIP_EXPIRY_TIME = 60 * 60 * 1000;
const MEMBER_EVENT_CHECK_PERIOD = 2 * 60 * 1000; // How often we check to see if we need to re-send our member event const MEMBER_EVENT_CHECK_PERIOD = 2 * 60 * 1000; // How often we check to see if we need to re-send our member event
@ -156,7 +158,7 @@ export class MatrixRTCSession extends TypedEventEmitter<MatrixRTCSessionEvent, M
logger.info(`Ignoring expired device membership ${membership.sender}/${membership.deviceId}`); logger.info(`Ignoring expired device membership ${membership.sender}/${membership.deviceId}`);
continue; continue;
} }
if (!room.hasMembershipState(membership.sender ?? "", "join")) { if (!room.hasMembershipState(membership.sender ?? "", KnownMembership.Join)) {
logger.info(`Ignoring membership of user ${membership.sender} who is not in the room.`); logger.info(`Ignoring membership of user ${membership.sender} who is not in the room.`);
continue; continue;
} }

View File

@ -33,6 +33,7 @@ import { MSC3089Branch } from "./MSC3089Branch";
import { isRoomSharedHistory } from "../crypto/algorithms/megolm"; import { isRoomSharedHistory } from "../crypto/algorithms/megolm";
import { ISendEventResponse } from "../@types/requests"; import { ISendEventResponse } from "../@types/requests";
import { FileType } from "../http-api"; import { FileType } from "../http-api";
import { KnownMembership } from "../@types/membership";
/** /**
* The recommended defaults for a tree space's power levels. Note that this * The recommended defaults for a tree space's power levels. Note that this
@ -291,11 +292,11 @@ export class MSC3089TreeSpace {
await dir.delete(); await dir.delete();
} }
const kickMemberships = ["invite", "knock", "join"]; const kickMemberships = [KnownMembership.Invite, KnownMembership.Knock, KnownMembership.Join];
const members = this.room.currentState.getStateEvents(EventType.RoomMember); const members = this.room.currentState.getStateEvents(EventType.RoomMember);
for (const member of members) { for (const member of members) {
const isNotUs = member.getStateKey() !== this.client.getUserId(); const isNotUs = member.getStateKey() !== this.client.getUserId();
if (isNotUs && kickMemberships.includes(member.getContent().membership!)) { if (isNotUs && kickMemberships.includes(member.getContent().membership! as KnownMembership)) {
const stateKey = member.getStateKey(); const stateKey = member.getStateKey();
if (!stateKey) { if (!stateKey) {
throw new Error("State key not found for branch"); throw new Error("State key not found for branch");

View File

@ -47,6 +47,7 @@ import { WITHHELD_MESSAGES } from "../crypto/OlmDevice";
import { IAnnotatedPushRule } from "../@types/PushRules"; import { IAnnotatedPushRule } from "../@types/PushRules";
import { Room } from "./room"; import { Room } from "./room";
import { EventTimeline } from "./event-timeline"; import { EventTimeline } from "./event-timeline";
import { Membership } from "../@types/membership";
export { EventStatus } from "./event-status"; export { EventStatus } from "./event-status";
@ -54,7 +55,7 @@ export { EventStatus } from "./event-status";
export interface IContent { export interface IContent {
[key: string]: any; [key: string]: any;
"msgtype"?: MsgType | string; "msgtype"?: MsgType | string;
"membership"?: string; "membership"?: Membership;
"avatar_url"?: string; "avatar_url"?: string;
"displayname"?: string; "displayname"?: string;
"m.relates_to"?: IEventRelation; "m.relates_to"?: IEventRelation;
@ -92,7 +93,7 @@ export interface IEvent {
origin_server_ts: number; origin_server_ts: number;
txn_id?: string; txn_id?: string;
state_key?: string; state_key?: string;
membership?: string; membership?: Membership;
unsigned: IUnsigned; unsigned: IUnsigned;
redacts?: string; redacts?: string;

View File

@ -22,6 +22,7 @@ import { RoomState } from "./room-state";
import { logger } from "../logger"; import { logger } from "../logger";
import { TypedEventEmitter } from "./typed-event-emitter"; import { TypedEventEmitter } from "./typed-event-emitter";
import { EventType } from "../@types/event"; import { EventType } from "../@types/event";
import { KnownMembership, Membership } from "../@types/membership";
export enum RoomMemberEvent { export enum RoomMemberEvent {
Membership = "RoomMember.membership", Membership = "RoomMember.membership",
@ -119,7 +120,7 @@ export class RoomMember extends TypedEventEmitter<RoomMemberEvent, RoomMemberEve
/** /**
* The membership state for this room member e.g. 'join'. * The membership state for this room member e.g. 'join'.
*/ */
public membership?: string; public membership?: Membership;
/** /**
* True if the member's name is disambiguated. * True if the member's name is disambiguated.
*/ */
@ -314,7 +315,7 @@ export class RoomMember extends TypedEventEmitter<RoomMemberEvent, RoomMemberEve
public isKicked(): boolean { public isKicked(): boolean {
return ( return (
this.membership === "leave" && this.membership === KnownMembership.Leave &&
this.events.member !== undefined && this.events.member !== undefined &&
this.events.member.getSender() !== this.events.member.getStateKey() this.events.member.getSender() !== this.events.member.getStateKey()
); );
@ -340,12 +341,12 @@ export class RoomMember extends TypedEventEmitter<RoomMemberEvent, RoomMemberEve
let memberContent = memberEvent.getContent(); let memberContent = memberEvent.getContent();
let inviteSender: string | undefined = memberEvent.getSender(); let inviteSender: string | undefined = memberEvent.getSender();
if (memberContent.membership === "join") { if (memberContent.membership === KnownMembership.Join) {
memberContent = memberEvent.getPrevContent(); memberContent = memberEvent.getPrevContent();
inviteSender = memberEvent.getUnsigned().prev_sender; inviteSender = memberEvent.getUnsigned().prev_sender;
} }
if (memberContent.membership === "invite" && memberContent.is_direct) { if (memberContent.membership === KnownMembership.Invite && memberContent.is_direct) {
return inviteSender; return inviteSender;
} }
} }

View File

@ -25,6 +25,7 @@ import { TypedEventEmitter } from "./typed-event-emitter";
import { Beacon, BeaconEvent, BeaconEventHandlerMap, getBeaconInfoIdentifier, BeaconIdentifier } from "./beacon"; import { Beacon, BeaconEvent, BeaconEventHandlerMap, getBeaconInfoIdentifier, BeaconIdentifier } from "./beacon";
import { TypedReEmitter } from "../ReEmitter"; import { TypedReEmitter } from "../ReEmitter";
import { M_BEACON, M_BEACON_INFO } from "../@types/beacon"; import { M_BEACON, M_BEACON_INFO } from "../@types/beacon";
import { KnownMembership } from "../@types/membership";
export interface IMarkerFoundOptions { export interface IMarkerFoundOptions {
/** Whether the timeline was empty before the marker event arrived in the /** Whether the timeline was empty before the marker event arrived in the
@ -206,7 +207,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
} }
if (this.joinedMemberCount === null) { if (this.joinedMemberCount === null) {
this.joinedMemberCount = this.getMembers().reduce((count, m) => { this.joinedMemberCount = this.getMembers().reduce((count, m) => {
return m.membership === "join" ? count + 1 : count; return m.membership === KnownMembership.Join ? count + 1 : count;
}, 0); }, 0);
} }
return this.joinedMemberCount; return this.joinedMemberCount;
@ -230,7 +231,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
} }
if (this.invitedMemberCount === null) { if (this.invitedMemberCount === null) {
this.invitedMemberCount = this.getMembers().reduce((count, m) => { this.invitedMemberCount = this.getMembers().reduce((count, m) => {
return m.membership === "invite" ? count + 1 : count; return m.membership === KnownMembership.Invite ? count + 1 : count;
}, 0); }, 0);
} }
return this.invitedMemberCount; return this.invitedMemberCount;
@ -434,7 +435,10 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
// leave events apparently elide the displayname or avatar_url, // leave events apparently elide the displayname or avatar_url,
// so let's fake one up so that we don't leak user ids // so let's fake one up so that we don't leak user ids
// into the timeline // into the timeline
if (event.getContent().membership === "leave" || event.getContent().membership === "ban") { if (
event.getContent().membership === KnownMembership.Leave ||
event.getContent().membership === KnownMembership.Ban
) {
event.getContent().avatar_url = event.getContent().avatar_url || event.getPrevContent().avatar_url; event.getContent().avatar_url = event.getContent().avatar_url || event.getPrevContent().avatar_url;
event.getContent().displayname = event.getContent().displayname =
event.getContent().displayname || event.getPrevContent().displayname; event.getContent().displayname || event.getPrevContent().displayname;
@ -776,7 +780,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
*/ */
public maySendRedactionForEvent(mxEvent: MatrixEvent, userId: string): boolean { public maySendRedactionForEvent(mxEvent: MatrixEvent, userId: string): boolean {
const member = this.getMember(userId); const member = this.getMember(userId);
if (!member || member.membership === "leave") return false; if (!member || member.membership === KnownMembership.Leave) return false;
if (mxEvent.status || mxEvent.isRedacted()) return false; if (mxEvent.status || mxEvent.isRedacted()) return false;

View File

@ -68,6 +68,7 @@ import { ReadReceipt, synthesizeReceipt } from "./read-receipt";
import { isPollEvent, Poll, PollEvent } from "./poll"; import { isPollEvent, Poll, PollEvent } from "./poll";
import { RoomReceipts } from "./room-receipts"; import { RoomReceipts } from "./room-receipts";
import { compareEventOrdering } from "./compare-event-ordering"; import { compareEventOrdering } from "./compare-event-ordering";
import { KnownMembership, Membership } from "../@types/membership";
// These constants are used as sane defaults when the homeserver doesn't support // These constants are used as sane defaults when the homeserver doesn't support
// the m.room_versions capability. In practice, KNOWN_SAFE_ROOM_VERSION should be // the m.room_versions capability. In practice, KNOWN_SAFE_ROOM_VERSION should be
@ -177,7 +178,7 @@ export type RoomEventHandlerMap = {
* @param membership - The new membership value * @param membership - The new membership value
* @param prevMembership - The previous membership value * @param prevMembership - The previous membership value
*/ */
[RoomEvent.MyMembership]: (room: Room, membership: string, prevMembership?: string) => void; [RoomEvent.MyMembership]: (room: Room, membership: Membership, prevMembership?: Membership) => void;
/** /**
* Fires whenever a room's tags are updated. * Fires whenever a room's tags are updated.
* @param event - The tags event * @param event - The tags event
@ -351,7 +352,7 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
private readonly pendingEventList?: MatrixEvent[]; private readonly pendingEventList?: MatrixEvent[];
// read by megolm via getter; boolean value - null indicates "use global value" // read by megolm via getter; boolean value - null indicates "use global value"
private blacklistUnverifiedDevices?: boolean; private blacklistUnverifiedDevices?: boolean;
private selfMembership?: string; private selfMembership?: Membership;
private summaryHeroes: string[] | null = null; private summaryHeroes: string[] | null = null;
// flags to stop logspam about missing m.room.create events // flags to stop logspam about missing m.room.create events
private getTypeWarning = false; private getTypeWarning = false;
@ -863,8 +864,8 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
/** /**
* @returns the membership type (join | leave | invite | knock) for the logged in user * @returns the membership type (join | leave | invite | knock) for the logged in user
*/ */
public getMyMembership(): string { public getMyMembership(): Membership {
return this.selfMembership ?? "leave"; return this.selfMembership ?? KnownMembership.Leave;
} }
/** /**
@ -878,7 +879,7 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
return me.getDMInviter(); return me.getDMInviter();
} }
if (this.selfMembership === "invite") { if (this.selfMembership === KnownMembership.Invite) {
// fall back to summary information // fall back to summary information
const memberCount = this.getInvitedAndJoinedMemberCount(); const memberCount = this.getInvitedAndJoinedMemberCount();
if (memberCount === 2) { if (memberCount === 2) {
@ -989,11 +990,11 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
* Sets the membership this room was received as during sync * Sets the membership this room was received as during sync
* @param membership - join | leave | invite * @param membership - join | leave | invite
*/ */
public updateMyMembership(membership: string): void { public updateMyMembership(membership: Membership): void {
const prevMembership = this.selfMembership; const prevMembership = this.selfMembership;
this.selfMembership = membership; this.selfMembership = membership;
if (prevMembership !== membership) { if (prevMembership !== membership) {
if (membership === "leave") { if (membership === KnownMembership.Leave) {
this.cleanupAfterLeaving(); this.cleanupAfterLeaving();
} }
this.emit(RoomEvent.MyMembership, this, membership, prevMembership); this.emit(RoomEvent.MyMembership, this, membership, prevMembership);
@ -1002,7 +1003,12 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
private async loadMembersFromServer(): Promise<IStateEventWithRoomId[]> { private async loadMembersFromServer(): Promise<IStateEventWithRoomId[]> {
const lastSyncToken = this.client.store.getSyncToken(); const lastSyncToken = this.client.store.getSyncToken();
const response = await this.client.members(this.roomId, undefined, "leave", lastSyncToken ?? undefined); const response = await this.client.members(
this.roomId,
undefined,
KnownMembership.Leave,
lastSyncToken ?? undefined,
);
return response.chunk; return response.chunk;
} }
@ -1709,7 +1715,7 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
* @returns A list of currently joined members. * @returns A list of currently joined members.
*/ */
public getJoinedMembers(): RoomMember[] { public getJoinedMembers(): RoomMember[] {
return this.getMembersWithMembership("join"); return this.getMembersWithMembership(KnownMembership.Join);
} }
/** /**
@ -1744,7 +1750,7 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
* @param membership - The membership state. * @param membership - The membership state.
* @returns A list of members with the given membership state. * @returns A list of members with the given membership state.
*/ */
public getMembersWithMembership(membership: string): RoomMember[] { public getMembersWithMembership(membership: Membership): RoomMember[] {
return this.currentState.getMembers().filter(function (m) { return this.currentState.getMembers().filter(function (m) {
return m.membership === membership; return m.membership === membership;
}); });
@ -1757,9 +1763,9 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
*/ */
public async getEncryptionTargetMembers(): Promise<RoomMember[]> { public async getEncryptionTargetMembers(): Promise<RoomMember[]> {
await this.loadMembersIfNeeded(); await this.loadMembersIfNeeded();
let members = this.getMembersWithMembership("join"); let members = this.getMembersWithMembership(KnownMembership.Join);
if (this.shouldEncryptForInvitedMembers()) { if (this.shouldEncryptForInvitedMembers()) {
members = members.concat(this.getMembersWithMembership("invite")); members = members.concat(this.getMembersWithMembership(KnownMembership.Invite));
} }
return members; return members;
} }
@ -1790,7 +1796,7 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
* @param membership - The membership e.g. `'join'` * @param membership - The membership e.g. `'join'`
* @returns True if this user_id has the given membership state. * @returns True if this user_id has the given membership state.
*/ */
public hasMembershipState(userId: string, membership: string): boolean { public hasMembershipState(userId: string, membership: Membership): boolean {
const member = this.getMember(userId); const member = this.getMember(userId);
if (!member) { if (!member) {
return false; return false;
@ -3119,7 +3125,7 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
const membership = membershipEvent.getContent().membership; const membership = membershipEvent.getContent().membership;
this.updateMyMembership(membership!); this.updateMyMembership(membership!);
if (membership === "invite") { if (membership === KnownMembership.Invite) {
const strippedStateEvents = membershipEvent.getUnsigned().invite_room_state || []; const strippedStateEvents = membershipEvent.getUnsigned().invite_room_state || [];
strippedStateEvents.forEach((strippedEvent) => { strippedStateEvents.forEach((strippedEvent) => {
const existingEvent = this.currentState.getStateEvents(strippedEvent.type, strippedEvent.state_key); const existingEvent = this.currentState.getStateEvents(strippedEvent.type, strippedEvent.state_key);
@ -3205,7 +3211,7 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
*/ */
public maySendMessage(): boolean { public maySendMessage(): boolean {
return ( return (
this.getMyMembership() === "join" && this.getMyMembership() === KnownMembership.Join &&
(this.hasEncryptionStateEvent() (this.hasEncryptionStateEvent()
? this.currentState.maySendEvent(EventType.RoomMessageEncrypted, this.myUserId) ? this.currentState.maySendEvent(EventType.RoomMessageEncrypted, this.myUserId)
: this.currentState.maySendEvent(EventType.RoomMessage, this.myUserId)) : this.currentState.maySendEvent(EventType.RoomMessage, this.myUserId))
@ -3218,7 +3224,7 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
* @returns true if the user should be permitted to issue invites for this room. * @returns true if the user should be permitted to issue invites for this room.
*/ */
public canInvite(userId: string): boolean { public canInvite(userId: string): boolean {
let canInvite = this.getMyMembership() === "join"; let canInvite = this.getMyMembership() === KnownMembership.Join;
const powerLevelsEvent = this.currentState.getStateEvents(EventType.RoomPowerLevels, ""); const powerLevelsEvent = this.currentState.getStateEvents(EventType.RoomPowerLevels, "");
const powerLevels = powerLevelsEvent && powerLevelsEvent.getContent(); const powerLevels = powerLevelsEvent && powerLevelsEvent.getContent();
const me = this.getMember(userId); const me = this.getMember(userId);
@ -3400,7 +3406,10 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
}); });
} else { } else {
let otherMembers = this.currentState.getMembers().filter((m) => { let otherMembers = this.currentState.getMembers().filter((m) => {
return m.userId !== userId && (m.membership === "invite" || m.membership === "join"); return (
m.userId !== userId &&
(m.membership === KnownMembership.Invite || m.membership === KnownMembership.Join)
);
}); });
otherMembers = otherMembers.filter(({ userId }) => { otherMembers = otherMembers.filter(({ userId }) => {
// filter service members // filter service members
@ -3428,7 +3437,7 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
const myMembership = this.getMyMembership(); const myMembership = this.getMyMembership();
// if I have created a room and invited people through // if I have created a room and invited people through
// 3rd party invites // 3rd party invites
if (myMembership == "join") { if (myMembership == KnownMembership.Join) {
const thirdPartyInvites = this.currentState.getStateEvents(EventType.RoomThirdPartyInvite); const thirdPartyInvites = this.currentState.getStateEvents(EventType.RoomThirdPartyInvite);
if (thirdPartyInvites?.length) { if (thirdPartyInvites?.length) {
@ -3452,7 +3461,11 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
leftNames = this.currentState leftNames = this.currentState
.getMembers() .getMembers()
.filter((m) => { .filter((m) => {
return m.userId !== userId && m.membership !== "invite" && m.membership !== "join"; return (
m.userId !== userId &&
m.membership !== KnownMembership.Invite &&
m.membership !== KnownMembership.Join
);
}) })
.map((m) => m.name); .map((m) => m.name);
} }

View File

@ -34,6 +34,7 @@ import { RoomMember } from "../models/room-member";
import { HistoryVisibility } from "../@types/partials"; import { HistoryVisibility } from "../@types/partials";
import { OutgoingRequestsManager } from "./OutgoingRequestsManager"; import { OutgoingRequestsManager } from "./OutgoingRequestsManager";
import { logDuration } from "../utils"; import { logDuration } from "../utils";
import { KnownMembership } from "../@types/membership";
/** /**
* RoomEncryptor: responsible for encrypting messages to a given room * RoomEncryptor: responsible for encrypting messages to a given room
@ -100,8 +101,8 @@ export class RoomEncryptor {
*/ */
public onRoomMembership(member: RoomMember): void { public onRoomMembership(member: RoomMember): void {
if ( if (
member.membership == "join" || member.membership == KnownMembership.Join ||
(member.membership == "invite" && this.room.shouldEncryptForInvitedMembers()) (member.membership == KnownMembership.Invite && this.room.shouldEncryptForInvitedMembers())
) { ) {
// make sure we are tracking the deviceList for this user // make sure we are tracking the deviceList for this user
logDuration(this.prefixedLogger, "updateTrackedUsers", async () => { logDuration(this.prefixedLogger, "updateTrackedUsers", async () => {

View File

@ -46,6 +46,7 @@ import { EventType } from "./@types/event";
import { IPushRules } from "./@types/PushRules"; import { IPushRules } from "./@types/PushRules";
import { RoomStateEvent } from "./models/room-state"; import { RoomStateEvent } from "./models/room-state";
import { RoomMemberEvent } from "./models/room-member"; import { RoomMemberEvent } from "./models/room-member";
import { KnownMembership } from "./@types/membership";
// Number of consecutive failed syncs that will lead to a syncState of ERROR as opposed // Number of consecutive failed syncs that will lead to a syncState of ERROR as opposed
// to RECONNECTING. This is needed to inform the client of server issues when the // to RECONNECTING. This is needed to inform the client of server issues when the
@ -649,7 +650,7 @@ export class SlidingSyncSdk {
inviteStateEvents.forEach((e) => { inviteStateEvents.forEach((e) => {
this.client.emit(ClientEvent.Event, e); this.client.emit(ClientEvent.Event, e);
}); });
room.updateMyMembership("invite"); room.updateMyMembership(KnownMembership.Invite);
return; return;
} }
@ -719,7 +720,7 @@ export class SlidingSyncSdk {
// local fields must be set before any async calls because call site assumes // local fields must be set before any async calls because call site assumes
// synchronous execution prior to emitting SlidingSyncState.Complete // synchronous execution prior to emitting SlidingSyncState.Complete
room.updateMyMembership("join"); room.updateMyMembership(KnownMembership.Join);
room.recalculate(); room.recalculate();
if (roomData.initial) { if (roomData.initial) {
@ -845,7 +846,7 @@ export class SlidingSyncSdk {
const client = this.client; const client = this.client;
// For each invited room member we want to give them a displayname/avatar url // For each invited room member we want to give them a displayname/avatar url
// if they have one (the m.room.member invites don't contain this). // if they have one (the m.room.member invites don't contain this).
room.getMembersWithMembership("invite").forEach(function (member) { room.getMembersWithMembership(KnownMembership.Invite).forEach(function (member) {
if (member.requestedProfileInfo) return; if (member.requestedProfileInfo) return;
member.requestedProfileInfo = true; member.requestedProfileInfo = true;
// try to get a cached copy first. // try to get a cached copy first.
@ -865,7 +866,7 @@ export class SlidingSyncSdk {
// the code paths remain the same between invite/join display name stuff // the code paths remain the same between invite/join display name stuff
// which is a worthy trade-off for some minor pollution. // which is a worthy trade-off for some minor pollution.
const inviteEvent = member.events.member!; const inviteEvent = member.events.member!;
if (inviteEvent.getContent().membership !== "invite") { if (inviteEvent.getContent().membership !== KnownMembership.Invite) {
// between resolving and now they have since joined, so don't clobber // between resolving and now they have since joined, so don't clobber
return; return;
} }

View File

@ -32,6 +32,7 @@ import { IStateEventWithRoomId } from "../@types/search";
import { IndexedToDeviceBatch, ToDeviceBatchWithTxnId } from "../models/ToDeviceMessage"; import { IndexedToDeviceBatch, ToDeviceBatchWithTxnId } from "../models/ToDeviceMessage";
import { IStoredClientOpts } from "../client"; import { IStoredClientOpts } from "../client";
import { MapWithDefault } from "../utils"; import { MapWithDefault } from "../utils";
import { KnownMembership } from "../@types/membership";
function isValidFilterId(filterId?: string | number | null): boolean { function isValidFilterId(filterId?: string | number | null): boolean {
const isValidStr = const isValidStr =
@ -118,7 +119,7 @@ export class MemoryStore implements IStore {
* updated. * updated.
*/ */
private onRoomMember = (event: MatrixEvent | null, state: RoomState, member: RoomMember): void => { private onRoomMember = (event: MatrixEvent | null, state: RoomState, member: RoomMember): void => {
if (member.membership === "invite") { if (member.membership === KnownMembership.Invite) {
// We do NOT add invited members because people love to typo user IDs // We do NOT add invited members because people love to typo user IDs
// which would then show up in these lists (!) // which would then show up in these lists (!)
return; return;

View File

@ -61,6 +61,7 @@ import { IEventsResponse } from "./@types/requests";
import { UNREAD_THREAD_NOTIFICATIONS } from "./@types/sync"; import { UNREAD_THREAD_NOTIFICATIONS } from "./@types/sync";
import { Feature, ServerSupport } from "./feature"; import { Feature, ServerSupport } from "./feature";
import { Crypto } from "./crypto"; import { Crypto } from "./crypto";
import { KnownMembership } from "./@types/membership";
const DEBUG = true; const DEBUG = true;
@ -1720,7 +1721,7 @@ export class SyncApi {
const client = this.client; const client = this.client;
// For each invited room member we want to give them a displayname/avatar url // For each invited room member we want to give them a displayname/avatar url
// if they have one (the m.room.member invites don't contain this). // if they have one (the m.room.member invites don't contain this).
room.getMembersWithMembership("invite").forEach(function (member) { room.getMembersWithMembership(KnownMembership.Invite).forEach(function (member) {
if (member.requestedProfileInfo) return; if (member.requestedProfileInfo) return;
member.requestedProfileInfo = true; member.requestedProfileInfo = true;
// try to get a cached copy first. // try to get a cached copy first.
@ -1740,7 +1741,7 @@ export class SyncApi {
// the code paths remain the same between invite/join display name stuff // the code paths remain the same between invite/join display name stuff
// which is a worthy trade-off for some minor pollution. // which is a worthy trade-off for some minor pollution.
const inviteEvent = member.events.member; const inviteEvent = member.events.member;
if (inviteEvent?.getContent().membership !== "invite") { if (inviteEvent?.getContent().membership !== KnownMembership.Invite) {
// between resolving and now they have since joined, so don't clobber // between resolving and now they have since joined, so don't clobber
return; return;
} }

View File

@ -22,3 +22,4 @@ limitations under the License.
*/ */
export type * from "./@types/media"; export type * from "./@types/media";
export * from "./@types/membership";

View File

@ -34,6 +34,7 @@ import {
} from "./stats/statsReport"; } from "./stats/statsReport";
import { SummaryStatsReportGatherer } from "./stats/summaryStatsReportGatherer"; import { SummaryStatsReportGatherer } from "./stats/summaryStatsReportGatherer";
import { CallFeedStatsReporter } from "./stats/callFeedStatsReporter"; import { CallFeedStatsReporter } from "./stats/callFeedStatsReporter";
import { KnownMembership } from "../@types/membership";
export enum GroupCallIntent { export enum GroupCallIntent {
Ring = "m.ring", Ring = "m.ring",
@ -1485,7 +1486,7 @@ export class GroupCall extends TypedEventEmitter<
} }
// Must have a connected device and be joined to the room // Must have a connected device and be joined to the room
if (validDevices.length > 0 && member?.membership === "join") { if (validDevices.length > 0 && member?.membership === KnownMembership.Join) {
const deviceMap = new Map<string, ParticipantState>(); const deviceMap = new Map<string, ParticipantState>();
participants.set(member, deviceMap); participants.set(member, deviceMap);