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
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 () {
console.log("Auto-joined %s", member.roomId);
});

View File

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

View File

@ -99,6 +99,7 @@ import {
} from "./olm-utils";
import { ToDevicePayload } from "../../../src/models/ToDeviceMessage";
import { AccountDataAccumulator } from "../../test-utils/AccountDataAccumulator";
import { KnownMembership } from "../../../src/@types/membership";
afterEach(() => {
// 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" },
}),
testUtils.mkMembership({
mship: "join",
mship: KnownMembership.Join,
sender: aliceClient.getUserId()!,
}),
],
@ -1661,7 +1662,7 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("crypto (%s)", (backend: string,
type: "m.room.member",
state_key: "@alice:localhost",
content: {
membership: "invite",
membership: KnownMembership.Invite,
},
},
],
@ -1810,7 +1811,7 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("crypto (%s)", (backend: string,
type: "m.room.member",
state_key: "@alice:localhost",
content: {
membership: "invite",
membership: KnownMembership.Invite,
},
},
],
@ -1886,7 +1887,7 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("crypto (%s)", (backend: string,
{
type: "m.room.member",
state_key: aliceClient.getUserId(),
content: { membership: "join" },
content: { membership: KnownMembership.Join },
event_id: "$alijoin",
},
],
@ -1913,7 +1914,7 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("crypto (%s)", (backend: string,
{
type: "m.room.member",
state_key: "@other:user",
content: { membership: "invite" },
content: { membership: KnownMembership.Invite },
event_id: "$otherinvite",
},
],
@ -2061,7 +2062,7 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("crypto (%s)", (backend: string,
fetchMock.getOnce(new RegExp(membersPath), {
chunk: [
testUtils.mkMembershipCustom({
membership: "join",
membership: KnownMembership.Join,
sender: "@bob:xyz",
}),
],
@ -3090,7 +3091,10 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("crypto (%s)", (backend: string,
const roomResponse = {
state: {
events: [
mkMembershipCustom({ membership: "join", sender: persistentStoreClient.getSafeUserId() }),
mkMembershipCustom({
membership: KnownMembership.Join,
sender: persistentStoreClient.getSafeUserId(),
}),
...stateEvents,
],
},

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -30,6 +30,7 @@ import {
Room,
} from "../../src";
import { TestClient } from "../TestClient";
import { KnownMembership } from "../../src/@types/membership";
describe("MatrixClient room timelines", function () {
const userId = "@alice:localhost";
@ -42,7 +43,7 @@ describe("MatrixClient room timelines", function () {
const USER_MEMBERSHIP_EVENT = utils.mkMembership({
room: roomId,
mship: "join",
mship: KnownMembership.Join,
user: userId,
name: userName,
});
@ -76,7 +77,7 @@ describe("MatrixClient room timelines", function () {
ROOM_NAME_EVENT,
utils.mkMembership({
room: roomId,
mship: "join",
mship: KnownMembership.Join,
user: otherUserId,
name: "Bob",
}),
@ -316,7 +317,7 @@ describe("MatrixClient room timelines", function () {
// make an m.room.member event for alice's join
const joinMshipEvent = utils.mkMembership({
mship: "join",
mship: KnownMembership.Join,
user: userId,
room: roomId,
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
// change
const oldMshipEvent = utils.mkMembership({
mship: "join",
mship: KnownMembership.Join,
user: userId,
room: roomId,
name: userName,
@ -335,7 +336,7 @@ describe("MatrixClient room timelines", function () {
oldMshipEvent.prev_content = {
displayname: "Old Alice",
avatar_url: undefined,
membership: "join",
membership: KnownMembership.Join,
};
// set the list of events to return on scrollback (/messages)
@ -487,7 +488,7 @@ describe("MatrixClient room timelines", function () {
utils.mkMembership({
user: userId,
room: roomId,
mship: "join",
mship: KnownMembership.Join,
name: "New Name",
}),
utils.mkMessage({ user: userId, room: roomId }),
@ -554,13 +555,13 @@ describe("MatrixClient room timelines", function () {
utils.mkMembership({
user: userC,
room: roomId,
mship: "join",
mship: KnownMembership.Join,
name: "C",
}),
utils.mkMembership({
user: userC,
room: roomId,
mship: "invite",
mship: KnownMembership.Invite,
skey: userD,
}),
];
@ -571,9 +572,9 @@ describe("MatrixClient room timelines", function () {
return Promise.all([httpBackend!.flush("/sync", 1), utils.syncPromise(client!)]).then(function () {
expect(room.currentState.getMembers().length).toEqual(4);
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)!.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.currentState.getMembers().length).toEqual(2);
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)!.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 { emitPromise, mkEvent, mkMessage } from "../test-utils/test-utils";
import { THREAD_RELATION_TYPE } from "../../src/models/thread";
import { KnownMembership } from "../../src/@types/membership";
describe("MatrixClient syncing", () => {
const selfUserId = "@alice:localhost";
@ -123,7 +124,7 @@ describe("MatrixClient syncing", () => {
type: "m.room.member",
state_key: selfUserId,
content: {
membership: "invite",
membership: KnownMembership.Invite,
},
},
],
@ -151,10 +152,10 @@ describe("MatrixClient syncing", () => {
type: "m.room.member",
state_key: selfUserId,
content: {
membership: "leave",
membership: KnownMembership.Leave,
},
prev_content: {
membership: "invite",
membership: KnownMembership.Invite,
},
// XXX: And other fields required on an event
},
@ -167,10 +168,10 @@ describe("MatrixClient syncing", () => {
type: "m.room.member",
state_key: selfUserId,
content: {
membership: "leave",
membership: KnownMembership.Leave,
},
prev_content: {
membership: "invite",
membership: KnownMembership.Invite,
},
// XXX: And other fields required on an event
},
@ -193,22 +194,22 @@ describe("MatrixClient syncing", () => {
// Room, string, string
fires++;
expect(room.roomId).toBe(roomId);
expect(membership).toBe("invite");
expect(membership).toBe(KnownMembership.Invite);
expect(oldMembership).toBeFalsy();
// Second fire: a leave
client!.once(RoomEvent.MyMembership, (room, membership, oldMembership) => {
fires++;
expect(room.roomId).toBe(roomId);
expect(membership).toBe("leave");
expect(oldMembership).toBe("invite");
expect(membership).toBe(KnownMembership.Leave);
expect(oldMembership).toBe(KnownMembership.Invite);
// Third/final fire: a second invite
client!.once(RoomEvent.MyMembership, (room, membership, oldMembership) => {
fires++;
expect(room.roomId).toBe(roomId);
expect(membership).toBe("invite");
expect(oldMembership).toBe("leave");
expect(membership).toBe(KnownMembership.Invite);
expect(oldMembership).toBe(KnownMembership.Leave);
});
});
@ -238,7 +239,7 @@ describe("MatrixClient syncing", () => {
type: "m.room.member",
state_key: selfUserId,
content: {
membership: "knock",
membership: KnownMembership.Knock,
},
},
],
@ -266,10 +267,10 @@ describe("MatrixClient syncing", () => {
type: "m.room.member",
state_key: selfUserId,
content: {
membership: "leave",
membership: KnownMembership.Leave,
},
prev_content: {
membership: "knock",
membership: KnownMembership.Knock,
},
// XXX: And other fields required on an event
},
@ -282,10 +283,10 @@ describe("MatrixClient syncing", () => {
type: "m.room.member",
state_key: selfUserId,
content: {
membership: "leave",
membership: KnownMembership.Leave,
},
prev_content: {
membership: "knock",
membership: KnownMembership.Knock,
},
// XXX: And other fields required on an event
},
@ -308,22 +309,22 @@ describe("MatrixClient syncing", () => {
// Room, string, string
fires++;
expect(room.roomId).toBe(roomId);
expect(membership).toBe("knock");
expect(membership).toBe(KnownMembership.Knock);
expect(oldMembership).toBeFalsy();
// Second fire: a leave
client!.once(RoomEvent.MyMembership, (room, membership, oldMembership) => {
fires++;
expect(room.roomId).toBe(roomId);
expect(membership).toBe("leave");
expect(oldMembership).toBe("knock");
expect(membership).toBe(KnownMembership.Leave);
expect(oldMembership).toBe(KnownMembership.Knock);
// Third/final fire: a second knock
client!.once(RoomEvent.MyMembership, (room, membership, oldMembership) => {
fires++;
expect(room.roomId).toBe(roomId);
expect(membership).toBe("knock");
expect(oldMembership).toBe("leave");
expect(membership).toBe(KnownMembership.Knock);
expect(oldMembership).toBe(KnownMembership.Leave);
});
});
@ -381,7 +382,7 @@ describe("MatrixClient syncing", () => {
type: "m.room.member",
state_key: selfUserId,
content: {
membership: "invite",
membership: KnownMembership.Invite,
},
},
],
@ -421,7 +422,7 @@ describe("MatrixClient syncing", () => {
type: "m.room.member",
state_key: selfUserId,
content: {
membership: "knock",
membership: KnownMembership.Knock,
},
},
],
@ -533,12 +534,12 @@ describe("MatrixClient syncing", () => {
events: [
utils.mkMembership({
room: roomOne,
mship: "join",
mship: KnownMembership.Join,
user: otherUserId,
}),
utils.mkMembership({
room: roomOne,
mship: "join",
mship: KnownMembership.Join,
user: selfUserId,
}),
utils.mkEvent({
@ -556,7 +557,7 @@ describe("MatrixClient syncing", () => {
syncData.rooms.join[roomOne].state.events.push(
utils.mkMembership({
room: roomOne,
mship: "invite",
mship: KnownMembership.Invite,
user: userC,
}) as IStateEvent,
);
@ -589,7 +590,7 @@ describe("MatrixClient syncing", () => {
syncData.rooms.join[roomOne].state.events.push(
utils.mkMembership({
room: roomOne,
mship: "invite",
mship: KnownMembership.Invite,
user: userC,
}) as IStateEvent,
);
@ -617,7 +618,7 @@ describe("MatrixClient syncing", () => {
syncData.rooms.join[roomOne].state.events.push(
utils.mkMembership({
room: roomOne,
mship: "invite",
mship: KnownMembership.Invite,
user: userC,
}) as IStateEvent,
);
@ -644,7 +645,7 @@ describe("MatrixClient syncing", () => {
syncData.rooms.join[roomOne].state.events.push(
utils.mkMembership({
room: roomOne,
mship: "invite",
mship: KnownMembership.Invite,
user: userC,
}) as IStateEvent,
);
@ -719,12 +720,12 @@ describe("MatrixClient syncing", () => {
}),
utils.mkMembership({
room: roomOne,
mship: "join",
mship: KnownMembership.Join,
user: otherUserId,
}),
utils.mkMembership({
room: roomOne,
mship: "join",
mship: KnownMembership.Join,
user: selfUserId,
}),
utils.mkEvent({
@ -750,13 +751,13 @@ describe("MatrixClient syncing", () => {
events: [
utils.mkMembership({
room: roomTwo,
mship: "join",
mship: KnownMembership.Join,
user: otherUserId,
name: otherDisplayName,
}),
utils.mkMembership({
room: roomTwo,
mship: "join",
mship: KnownMembership.Join,
user: selfUserId,
}),
utils.mkEvent({
@ -1247,7 +1248,7 @@ describe("MatrixClient syncing", () => {
const USER_MEMBERSHIP_EVENT = utils.mkMembership({
room: roomOne,
mship: "join",
mship: KnownMembership.Join,
user: userA,
});
@ -1508,12 +1509,12 @@ describe("MatrixClient syncing", () => {
}),
utils.mkMembership({
room: roomOne,
mship: "join",
mship: KnownMembership.Join,
user: otherUserId,
}),
utils.mkMembership({
room: roomOne,
mship: "join",
mship: KnownMembership.Join,
user: selfUserId,
}),
utils.mkEvent({
@ -1605,12 +1606,12 @@ describe("MatrixClient syncing", () => {
}),
utils.mkMembership({
room: roomOne,
mship: "join",
mship: KnownMembership.Join,
user: otherUserId,
}),
utils.mkMembership({
room: roomOne,
mship: "join",
mship: KnownMembership.Join,
user: selfUserId,
}),
utils.mkEvent({
@ -1761,12 +1762,12 @@ describe("MatrixClient syncing", () => {
events: [
utils.mkMembership({
room: roomId,
mship: "join",
mship: KnownMembership.Join,
user: otherUserId,
}),
utils.mkMembership({
room: roomId,
mship: "join",
mship: KnownMembership.Join,
user: selfUserId,
}),
utils.mkEvent({
@ -1901,7 +1902,7 @@ describe("MatrixClient syncing", () => {
it("should return a room based on the room initialSync API", async () => {
httpBackend!.when("GET", `/rooms/${encodeURIComponent(roomOne)}/initialSync`).respond(200, {
room_id: roomOne,
membership: "leave",
membership: KnownMembership.Leave,
messages: {
start: "start",
end: "end",
@ -1950,7 +1951,7 @@ describe("MatrixClient syncing", () => {
const room = await prom;
expect(room.roomId).toBe(roomOne);
expect(room.getMyMembership()).toBe("leave");
expect(room.getMyMembership()).toBe(KnownMembership.Leave);
expect(room.name).toBe("Room Name");
expect(room.currentState.getStateEvents("m.room.name", "")?.getId()).toBe("$eventId");
expect(room.timeline[0].getContent().body).toBe("Message 1");
@ -2042,7 +2043,7 @@ describe("MatrixClient syncing (IndexedDB version)", () => {
type: "m.room.member",
state_key: selfUserId,
content: {
membership: "invite",
membership: KnownMembership.Invite,
},
},
],

View File

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

View File

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

View File

@ -19,6 +19,7 @@ import {
import { SyncState } from "../../src/sync";
import { eventMapperFor } from "../../src/event-mapper";
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
@ -87,7 +88,7 @@ export function getSyncResponse(roomMembers: string[], roomId = TEST_ROOM_ID): I
for (let i = 0; i < roomMembers.length; i++) {
roomResponse.state.events.push(
mkMembershipCustom({
membership: "join",
membership: KnownMembership.Join,
sender: roomMembers[i],
}),
);
@ -251,7 +252,7 @@ export function mkPresence(opts: IPresenceOpts & { event?: boolean }): Partial<I
interface IMembershipOpts {
room?: string;
mship: string;
mship: Membership;
sender?: string;
user?: string;
skey?: string;
@ -297,7 +298,7 @@ export function mkMembership(opts: IMembershipOpts & { event?: boolean }): Parti
}
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 {
const content = base.content || {};
return mkEventCustom({

View File

@ -25,6 +25,7 @@ import { UserTrustLevel } from "../../src/crypto/CrossSigning";
import { CryptoBackend } from "../../src/common-crypto/CryptoBackend";
import { EventDecryptionResult } from "../../src/common-crypto/CryptoBackend";
import * as testData from "../test-utils/test-data";
import { KnownMembership } from "../../src/@types/membership";
const Olm = global.Olm;
@ -463,7 +464,7 @@ describe("Crypto", function () {
type: "m.room.member",
sender: "@alice:example.com",
room_id: roomId,
content: { membership: "invite" },
content: { membership: KnownMembership.Invite },
state_key: "@bob:example.com",
}),
]);
@ -795,7 +796,7 @@ describe("Crypto", function () {
type: "m.room.member",
sender: "@clara:example.com",
room_id: roomId,
content: { membership: "invite" },
content: { membership: KnownMembership.Invite },
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 { recursiveMapToObject } 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 MegolmEncryption = algorithms.ENCRYPTION_CLASSES.get("m.megolm.v1.aes-sha2")!;
@ -806,11 +807,11 @@ describe("MegolmDecryption", function () {
aliceRoom.getEncryptionTargetMembers = jest.fn().mockResolvedValue([
{
userId: "@alice:example.com",
membership: "join",
membership: KnownMembership.Join,
},
{
userId: "@bob:example.com",
membership: "join",
membership: KnownMembership.Join,
},
]);
const BOB_DEVICES = {

View File

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

View File

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

View File

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

View File

@ -25,6 +25,7 @@ import {
} from "../../../src/models/MSC3089TreeSpace";
import { DEFAULT_ALPHABET } from "../../../src/utils";
import { MatrixError } from "../../../src/http-api";
import { KnownMembership } from "../../../src/@types/membership";
describe("MSC3089TreeSpace", () => {
let client: MatrixClient;
@ -458,14 +459,14 @@ describe("MSC3089TreeSpace", () => {
expect(stateKey).toBeUndefined();
return [
// Partial implementations
{ getContent: () => ({ membership: "join" }), getStateKey: () => joinMemberId },
{ getContent: () => ({ membership: "knock" }), getStateKey: () => knockMemberId },
{ getContent: () => ({ membership: "invite" }), getStateKey: () => inviteMemberId },
{ getContent: () => ({ membership: "leave" }), getStateKey: () => leaveMemberId },
{ getContent: () => ({ membership: "ban" }), getStateKey: () => banMemberId },
{ getContent: () => ({ membership: KnownMembership.Join }), getStateKey: () => joinMemberId },
{ getContent: () => ({ membership: KnownMembership.Knock }), getStateKey: () => knockMemberId },
{ getContent: () => ({ membership: KnownMembership.Invite }), getStateKey: () => inviteMemberId },
{ getContent: () => ({ membership: KnownMembership.Leave }), getStateKey: () => leaveMemberId },
{ getContent: () => ({ membership: KnownMembership.Ban }), getStateKey: () => banMemberId },
// 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_SHARED_ROOMS,
} from "../../src";
import { KnownMembership } from "../../src/@types/membership";
describe("RoomMember", function () {
const roomId = "!foo:bar";
@ -50,7 +51,7 @@ describe("RoomMember", function () {
room: roomId,
user: userA,
content: {
membership: "join",
membership: KnownMembership.Join,
avatar_url: "mxc://flibble/wibble",
},
});
@ -282,11 +283,11 @@ describe("RoomMember", function () {
describe("isKicked", () => {
it("should return false if membership is not `leave`", () => {
const member1 = new RoomMember(roomId, userA);
member1.membership = "join";
member1.membership = KnownMembership.Join;
expect(member1.isKicked()).toBeFalsy();
const member2 = new RoomMember(roomId, userA);
member2.membership = "invite";
member2.membership = KnownMembership.Invite;
expect(member2.isKicked()).toBeFalsy();
const member3 = new RoomMember(roomId, userA);
@ -295,17 +296,17 @@ describe("RoomMember", function () {
it("should return false if the membership event is unknown", () => {
const member = new RoomMember(roomId, userA);
member.membership = "leave";
member.membership = KnownMembership.Leave;
expect(member.isKicked()).toBeFalsy();
});
it("should return false if the member left of their own accord", () => {
const member = new RoomMember(roomId, userA);
member.membership = "leave";
member.membership = KnownMembership.Leave;
member.events.member = utils.mkMembership({
event: true,
sender: userA,
mship: "leave",
mship: KnownMembership.Leave,
skey: userA,
});
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", () => {
const member = new RoomMember(roomId, userA);
member.membership = "leave";
member.membership = KnownMembership.Leave;
member.events.member = utils.mkMembership({
event: true,
sender: userB,
mship: "leave",
mship: KnownMembership.Leave,
skey: userA,
});
expect(member.isKicked()).toBeTruthy();
@ -327,11 +328,11 @@ describe("RoomMember", function () {
describe("getDMInviter", () => {
it("should return userId of the sender of the invite if is_direct=true", () => {
const member = new RoomMember(roomId, userA);
member.membership = "invite";
member.membership = KnownMembership.Invite;
member.events.member = utils.mkMembership({
event: true,
sender: userB,
mship: "invite",
mship: KnownMembership.Invite,
skey: userA,
});
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", () => {
const member = new RoomMember(roomId, userA);
member.membership = "invite";
member.membership = KnownMembership.Invite;
member.events.member = utils.mkMembership({
event: true,
sender: userB,
mship: "invite",
mship: KnownMembership.Invite,
skey: userA,
});
member.events.member.event.content!.is_direct = false;
@ -355,7 +356,7 @@ describe("RoomMember", function () {
describe("setMembershipEvent", function () {
const joinEvent = utils.mkMembership({
event: true,
mship: "join",
mship: KnownMembership.Join,
user: userA,
room: roomId,
name: "Alice",
@ -363,7 +364,7 @@ describe("RoomMember", function () {
const inviteEvent = utils.mkMembership({
event: true,
mship: "invite",
mship: KnownMembership.Invite,
user: userB,
skey: userA,
room: roomId,
@ -371,10 +372,10 @@ describe("RoomMember", function () {
it("should set 'membership' and assign the event to 'events.member'.", function () {
member.setMembershipEvent(inviteEvent);
expect(member.membership).toEqual("invite");
expect(member.membership).toEqual(KnownMembership.Invite);
expect(member.events.member).toEqual(inviteEvent);
member.setMembershipEvent(joinEvent);
expect(member.membership).toEqual("join");
expect(member.membership).toEqual(KnownMembership.Join);
expect(member.events.member).toEqual(joinEvent);
});
@ -387,13 +388,13 @@ describe("RoomMember", function () {
return [
utils.mkMembership({
event: true,
mship: "join",
mship: KnownMembership.Join,
room: roomId,
user: userB,
}),
utils.mkMembership({
event: true,
mship: "join",
mship: KnownMembership.Join,
room: roomId,
user: userC,
name: "Alice",
@ -443,7 +444,7 @@ describe("RoomMember", function () {
it("should set 'name' to user_id if it is just whitespace", function () {
const joinEvent = utils.mkMembership({
event: true,
mship: "join",
mship: KnownMembership.Join,
user: userA,
room: roomId,
name: " \u200b ",
@ -457,7 +458,7 @@ describe("RoomMember", function () {
it("should disambiguate users on a fuzzy displayname match", function () {
const joinEvent = utils.mkMembership({
event: true,
mship: "join",
mship: KnownMembership.Join,
user: userA,
room: roomId,
name: "Alíce\u200b", // note diacritic and zero width char
@ -471,7 +472,7 @@ describe("RoomMember", function () {
return [
utils.mkMembership({
event: true,
mship: "join",
mship: KnownMembership.Join,
room: roomId,
user: userC,
name: "Alice",

View File

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

View File

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

View File

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

View File

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

View File

@ -31,6 +31,7 @@ import {
} from "../../src/sync-accumulator";
import { IRoomSummary } from "../../src";
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
// by the impl
@ -95,7 +96,7 @@ describe("SyncAccumulator", function () {
ephemeral: { events: [] },
unread_notifications: {},
state: {
events: [member("alice", "join"), member("bob", "join")],
events: [member("alice", KnownMembership.Join), member("bob", KnownMembership.Join)],
},
summary: {
"m.heroes": undefined,
@ -111,7 +112,7 @@ describe("SyncAccumulator", function () {
knock: {
"!knock": {
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"
sa.accumulate(
syncSkeleton({
state: { events: [member("alice", "join")] },
state: { events: [member("alice", KnownMembership.Join)] },
timeline: {
events: [
msg("alice", "1"),
@ -204,7 +205,7 @@ describe("SyncAccumulator", function () {
it("should remove the stored timeline on limited syncs", () => {
sa.accumulate(
syncSkeleton({
state: { events: [member("alice", "join")] },
state: { events: [member("alice", KnownMembership.Join)] },
timeline: {
events: [msg("alice", "1"), msg("alice", "2"), msg("alice", "3")],
prev_batch: "pinned_to_1",
@ -312,7 +313,7 @@ describe("SyncAccumulator", function () {
events: [
{
content: {
membership: "invite",
membership: KnownMembership.Invite,
},
state_key: "bob",
sender: "alice",
@ -336,7 +337,7 @@ describe("SyncAccumulator", function () {
const rejectMemberEvent: IStateEvent = {
event_id: "$" + Math.random(),
content: {
membership: "leave",
membership: KnownMembership.Leave,
},
origin_server_ts: 123456789,
state_key: "bob",
@ -344,7 +345,7 @@ describe("SyncAccumulator", function () {
type: "m.room.member",
unsigned: {
prev_content: {
membership: "invite",
membership: KnownMembership.Invite,
},
},
};
@ -366,7 +367,7 @@ describe("SyncAccumulator", function () {
it("should accumulate knock state", () => {
const initKnockState = {
events: [member("alice", "knock")],
events: [member("alice", KnownMembership.Knock)],
};
sa.accumulate(
syncSkeleton(
@ -453,7 +454,7 @@ describe("SyncAccumulator", function () {
const inviteStateEvents = [
{
content: {
membership: "invite",
membership: KnownMembership.Invite,
},
state_key: "bob",
sender: "alice",
@ -482,7 +483,7 @@ describe("SyncAccumulator", function () {
const memberEvent: IStateEvent = {
event_id: "$" + Math.random(),
content: {
membership: "leave",
membership: KnownMembership.Leave,
},
origin_server_ts: 123456789,
state_key: "bob",
@ -490,7 +491,7 @@ describe("SyncAccumulator", function () {
type: "m.room.member",
unsigned: {
prev_content: {
membership: "knock",
membership: KnownMembership.Knock,
},
},
};
@ -528,7 +529,7 @@ describe("SyncAccumulator", function () {
const memberEvent: IStateEvent = {
event_id: "$" + Math.random(),
content: {
membership: "leave",
membership: KnownMembership.Leave,
},
origin_server_ts: 123456789,
state_key: "bob",
@ -536,7 +537,7 @@ describe("SyncAccumulator", function () {
type: "m.room.member",
unsigned: {
prev_content: {
membership: "knock",
membership: KnownMembership.Knock,
},
},
};
@ -933,7 +934,7 @@ function makeKnockState(): IKnockState {
name: "Room",
},
}) 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 {
event_id: "$" + Math.random(),
content: {

View File

@ -47,6 +47,7 @@ import { flushPromises } from "../../test-utils/flushPromises";
import { CallFeedReport } from "../../../src/webrtc/stats/statsReport";
import { CallFeedStatsReporter } from "../../../src/webrtc/stats/callFeedStatsReporter";
import { StatsReportEmitter } from "../../../src/webrtc/stats/statsReportEmitter";
import { KnownMembership } from "../../../src/@types/membership";
const FAKE_STATE_EVENTS = [
{
@ -143,7 +144,7 @@ describe("Group Call", function () {
groupCall = new GroupCall(mockClient, room, GroupCallType.Video, false, GroupCallIntent.Prompt);
room.currentState.members[FAKE_USER_ID_1] = {
userId: FAKE_USER_ID_1,
membership: "join",
membership: KnownMembership.Join,
} 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] = {
userId: FAKE_USER_ID_1,
membership: "join",
membership: KnownMembership.Join,
} as unknown as RoomMember;
client1Room.currentState.members[FAKE_USER_ID_2] = client2Room.currentState.members[FAKE_USER_ID_2] = {
userId: FAKE_USER_ID_2,
membership: "join",
membership: KnownMembership.Join,
} as unknown as RoomMember;
groupCall1 = new GroupCall(
@ -831,11 +832,11 @@ describe("Group Call", function () {
room.currentState.getStateEvents = jest.fn().mockImplementation(mockGetStateEvents());
room.currentState.members[FAKE_USER_ID_1] = {
userId: FAKE_USER_ID_1,
membership: "join",
membership: KnownMembership.Join,
} as unknown as RoomMember;
room.currentState.members[FAKE_USER_ID_2] = {
userId: FAKE_USER_ID_2,
membership: "join",
membership: KnownMembership.Join,
} as unknown as RoomMember;
});
@ -1026,11 +1027,11 @@ describe("Group Call", function () {
room = new Room(FAKE_ROOM_ID, mockClient, FAKE_USER_ID_2);
room.currentState.members[FAKE_USER_ID_1] = {
userId: FAKE_USER_ID_1,
membership: "join",
membership: KnownMembership.Join,
} as unknown as RoomMember;
room.currentState.members[FAKE_USER_ID_2] = {
userId: FAKE_USER_ID_2,
membership: "join",
membership: KnownMembership.Join,
} as unknown as RoomMember;
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.currentState.members[FAKE_USER_ID_1] = {
userId: FAKE_USER_ID_1,
membership: "join",
membership: KnownMembership.Join,
} as unknown as RoomMember;
room.currentState.members[FAKE_USER_ID_2] = {
userId: FAKE_USER_ID_2,
membership: "join",
membership: KnownMembership.Join,
} as unknown as RoomMember;
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);
room.currentState.members[FAKE_USER_ID_1] = {
userId: FAKE_USER_ID_1,
membership: "join",
membership: KnownMembership.Join,
} as unknown as RoomMember;
room.currentState.members[FAKE_USER_ID_2] = {
userId: FAKE_USER_ID_2,
membership: "join",
membership: KnownMembership.Join,
} as unknown as RoomMember;
room.currentState.getStateEvents = jest.fn().mockImplementation(mockGetStateEvents());
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 { flushPromises } from "../../test-utils/flushPromises";
import { makeMockGroupCallStateEvent, MockCallMatrixClient } from "../../test-utils/webrtc";
import { KnownMembership } from "../../../src/@types/membership";
const FAKE_USER_ID = "@alice:test.dummy";
const FAKE_DEVICE_ID = "AAAAAAA";
@ -50,7 +51,7 @@ describe("Group Call Event Handler", function () {
mockMember = {
userId: FAKE_USER_ID,
membership: "join",
membership: KnownMembership.Join,
} as unknown as RoomMember;
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 { MatrixRTCSessionManager } from "./matrixrtc/MatrixRTCSessionManager";
import { getRelationsThreadFilter } from "./thread-utils";
import { KnownMembership, Membership } from "./@types/membership";
export type Store = IStore;
@ -721,7 +722,7 @@ export interface IOpenIDToken {
interface IRoomInitialSyncResponse {
room_id: string;
membership: "invite" | "join" | "leave" | "ban";
membership: Membership;
messages?: {
start?: string;
end?: string;
@ -866,7 +867,7 @@ interface IThirdPartyUser {
interface IRoomSummary extends Omit<IPublicRoomsChunkRoom, "canonical_alias" | "aliases"> {
room_type?: RoomType;
membership?: string;
membership?: Membership;
is_encrypted: boolean;
}
@ -4357,7 +4358,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
}
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();
@ -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
// were in the room, after all.
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 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 }> {
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 });
}
@ -5548,7 +5549,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* @returns Rejects: with an error response.
*/
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.
*/
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.
*/
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(
roomId: string,
userId: string | undefined,
membership: string,
membership: Membership | "forget",
reason?: string,
): Promise<{}> {
// API returns an empty object
@ -9780,7 +9781,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
*/
public unstableGetFileTreeSpace(roomId: string): MSC3089TreeSpace | null {
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 purposeEvent = room.currentState.getStateEvents(

View File

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

View File

@ -104,6 +104,7 @@ import { Device, DeviceMap } from "../models/device";
import { deviceInfoToDevice } from "./device-converter";
import { ClientPrefix, MatrixError, Method } from "../http-api";
import { decodeBase64, encodeBase64 } from "../base64";
import { KnownMembership } from "../@types/membership";
/* re-exports for backwards compatibility */
export type {
@ -3504,7 +3505,7 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
// ignore any rooms which we have left
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
// by calling _trackRoomDevices
if (roomId in this.roomDeviceTrackingState) {
if (member.membership == "join") {
if (member.membership == KnownMembership.Join) {
logger.log("Join event for " + member.userId + " in " + roomId);
// make sure we are tracking the deviceList for this user
this.deviceList.startTrackingDeviceList(member.userId);
} else if (
member.membership == "invite" &&
member.membership == KnownMembership.Invite &&
this.clientStore.getRoom(roomId)?.shouldEncryptForInvitedMembers()
) {
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 { RoomStateEvent } from "../models/room-state";
import { Focus } from "./focus";
import { MatrixError, MatrixEvent } from "../matrix";
import { randomString, secureRandomBase64Url } from "../randomstring";
import { EncryptionKeysEventContent } from "./types";
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 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}`);
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.`);
continue;
}

View File

@ -33,6 +33,7 @@ import { MSC3089Branch } from "./MSC3089Branch";
import { isRoomSharedHistory } from "../crypto/algorithms/megolm";
import { ISendEventResponse } from "../@types/requests";
import { FileType } from "../http-api";
import { KnownMembership } from "../@types/membership";
/**
* The recommended defaults for a tree space's power levels. Note that this
@ -291,11 +292,11 @@ export class MSC3089TreeSpace {
await dir.delete();
}
const kickMemberships = ["invite", "knock", "join"];
const kickMemberships = [KnownMembership.Invite, KnownMembership.Knock, KnownMembership.Join];
const members = this.room.currentState.getStateEvents(EventType.RoomMember);
for (const member of members) {
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();
if (!stateKey) {
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 { Room } from "./room";
import { EventTimeline } from "./event-timeline";
import { Membership } from "../@types/membership";
export { EventStatus } from "./event-status";
@ -54,7 +55,7 @@ export { EventStatus } from "./event-status";
export interface IContent {
[key: string]: any;
"msgtype"?: MsgType | string;
"membership"?: string;
"membership"?: Membership;
"avatar_url"?: string;
"displayname"?: string;
"m.relates_to"?: IEventRelation;
@ -92,7 +93,7 @@ export interface IEvent {
origin_server_ts: number;
txn_id?: string;
state_key?: string;
membership?: string;
membership?: Membership;
unsigned: IUnsigned;
redacts?: string;

View File

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

View File

@ -25,6 +25,7 @@ import { TypedEventEmitter } from "./typed-event-emitter";
import { Beacon, BeaconEvent, BeaconEventHandlerMap, getBeaconInfoIdentifier, BeaconIdentifier } from "./beacon";
import { TypedReEmitter } from "../ReEmitter";
import { M_BEACON, M_BEACON_INFO } from "../@types/beacon";
import { KnownMembership } from "../@types/membership";
export interface IMarkerFoundOptions {
/** 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) {
this.joinedMemberCount = this.getMembers().reduce((count, m) => {
return m.membership === "join" ? count + 1 : count;
return m.membership === KnownMembership.Join ? count + 1 : count;
}, 0);
}
return this.joinedMemberCount;
@ -230,7 +231,7 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
}
if (this.invitedMemberCount === null) {
this.invitedMemberCount = this.getMembers().reduce((count, m) => {
return m.membership === "invite" ? count + 1 : count;
return m.membership === KnownMembership.Invite ? count + 1 : count;
}, 0);
}
return this.invitedMemberCount;
@ -434,7 +435,10 @@ export class RoomState extends TypedEventEmitter<EmittedEvents, EventHandlerMap>
// leave events apparently elide the displayname or avatar_url,
// so let's fake one up so that we don't leak user ids
// 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().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 {
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;

View File

@ -68,6 +68,7 @@ import { ReadReceipt, synthesizeReceipt } from "./read-receipt";
import { isPollEvent, Poll, PollEvent } from "./poll";
import { RoomReceipts } from "./room-receipts";
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
// 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 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.
* @param event - The tags event
@ -351,7 +352,7 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
private readonly pendingEventList?: MatrixEvent[];
// read by megolm via getter; boolean value - null indicates "use global value"
private blacklistUnverifiedDevices?: boolean;
private selfMembership?: string;
private selfMembership?: Membership;
private summaryHeroes: string[] | null = null;
// flags to stop logspam about missing m.room.create events
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
*/
public getMyMembership(): string {
return this.selfMembership ?? "leave";
public getMyMembership(): Membership {
return this.selfMembership ?? KnownMembership.Leave;
}
/**
@ -878,7 +879,7 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
return me.getDMInviter();
}
if (this.selfMembership === "invite") {
if (this.selfMembership === KnownMembership.Invite) {
// fall back to summary information
const memberCount = this.getInvitedAndJoinedMemberCount();
if (memberCount === 2) {
@ -989,11 +990,11 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
* Sets the membership this room was received as during sync
* @param membership - join | leave | invite
*/
public updateMyMembership(membership: string): void {
public updateMyMembership(membership: Membership): void {
const prevMembership = this.selfMembership;
this.selfMembership = membership;
if (prevMembership !== membership) {
if (membership === "leave") {
if (membership === KnownMembership.Leave) {
this.cleanupAfterLeaving();
}
this.emit(RoomEvent.MyMembership, this, membership, prevMembership);
@ -1002,7 +1003,12 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
private async loadMembersFromServer(): Promise<IStateEventWithRoomId[]> {
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;
}
@ -1709,7 +1715,7 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
* @returns A list of currently joined members.
*/
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.
* @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 m.membership === membership;
});
@ -1757,9 +1763,9 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
*/
public async getEncryptionTargetMembers(): Promise<RoomMember[]> {
await this.loadMembersIfNeeded();
let members = this.getMembersWithMembership("join");
let members = this.getMembersWithMembership(KnownMembership.Join);
if (this.shouldEncryptForInvitedMembers()) {
members = members.concat(this.getMembersWithMembership("invite"));
members = members.concat(this.getMembersWithMembership(KnownMembership.Invite));
}
return members;
}
@ -1790,7 +1796,7 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
* @param membership - The membership e.g. `'join'`
* @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);
if (!member) {
return false;
@ -3119,7 +3125,7 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
const membership = membershipEvent.getContent().membership;
this.updateMyMembership(membership!);
if (membership === "invite") {
if (membership === KnownMembership.Invite) {
const strippedStateEvents = membershipEvent.getUnsigned().invite_room_state || [];
strippedStateEvents.forEach((strippedEvent) => {
const existingEvent = this.currentState.getStateEvents(strippedEvent.type, strippedEvent.state_key);
@ -3205,7 +3211,7 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
*/
public maySendMessage(): boolean {
return (
this.getMyMembership() === "join" &&
this.getMyMembership() === KnownMembership.Join &&
(this.hasEncryptionStateEvent()
? this.currentState.maySendEvent(EventType.RoomMessageEncrypted, 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.
*/
public canInvite(userId: string): boolean {
let canInvite = this.getMyMembership() === "join";
let canInvite = this.getMyMembership() === KnownMembership.Join;
const powerLevelsEvent = this.currentState.getStateEvents(EventType.RoomPowerLevels, "");
const powerLevels = powerLevelsEvent && powerLevelsEvent.getContent();
const me = this.getMember(userId);
@ -3400,7 +3406,10 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
});
} else {
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 }) => {
// filter service members
@ -3428,7 +3437,7 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
const myMembership = this.getMyMembership();
// if I have created a room and invited people through
// 3rd party invites
if (myMembership == "join") {
if (myMembership == KnownMembership.Join) {
const thirdPartyInvites = this.currentState.getStateEvents(EventType.RoomThirdPartyInvite);
if (thirdPartyInvites?.length) {
@ -3452,7 +3461,11 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
leftNames = 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
);
})
.map((m) => m.name);
}

View File

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

View File

@ -46,6 +46,7 @@ import { EventType } from "./@types/event";
import { IPushRules } from "./@types/PushRules";
import { RoomStateEvent } from "./models/room-state";
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
// to RECONNECTING. This is needed to inform the client of server issues when the
@ -649,7 +650,7 @@ export class SlidingSyncSdk {
inviteStateEvents.forEach((e) => {
this.client.emit(ClientEvent.Event, e);
});
room.updateMyMembership("invite");
room.updateMyMembership(KnownMembership.Invite);
return;
}
@ -719,7 +720,7 @@ export class SlidingSyncSdk {
// local fields must be set before any async calls because call site assumes
// synchronous execution prior to emitting SlidingSyncState.Complete
room.updateMyMembership("join");
room.updateMyMembership(KnownMembership.Join);
room.recalculate();
if (roomData.initial) {
@ -845,7 +846,7 @@ export class SlidingSyncSdk {
const client = this.client;
// 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).
room.getMembersWithMembership("invite").forEach(function (member) {
room.getMembersWithMembership(KnownMembership.Invite).forEach(function (member) {
if (member.requestedProfileInfo) return;
member.requestedProfileInfo = true;
// 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
// which is a worthy trade-off for some minor pollution.
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
return;
}

View File

@ -32,6 +32,7 @@ import { IStateEventWithRoomId } from "../@types/search";
import { IndexedToDeviceBatch, ToDeviceBatchWithTxnId } from "../models/ToDeviceMessage";
import { IStoredClientOpts } from "../client";
import { MapWithDefault } from "../utils";
import { KnownMembership } from "../@types/membership";
function isValidFilterId(filterId?: string | number | null): boolean {
const isValidStr =
@ -118,7 +119,7 @@ export class MemoryStore implements IStore {
* updated.
*/
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
// which would then show up in these lists (!)
return;

View File

@ -61,6 +61,7 @@ import { IEventsResponse } from "./@types/requests";
import { UNREAD_THREAD_NOTIFICATIONS } from "./@types/sync";
import { Feature, ServerSupport } from "./feature";
import { Crypto } from "./crypto";
import { KnownMembership } from "./@types/membership";
const DEBUG = true;
@ -1720,7 +1721,7 @@ export class SyncApi {
const client = this.client;
// 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).
room.getMembersWithMembership("invite").forEach(function (member) {
room.getMembersWithMembership(KnownMembership.Invite).forEach(function (member) {
if (member.requestedProfileInfo) return;
member.requestedProfileInfo = true;
// 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
// which is a worthy trade-off for some minor pollution.
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
return;
}

View File

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

View File

@ -34,6 +34,7 @@ import {
} from "./stats/statsReport";
import { SummaryStatsReportGatherer } from "./stats/summaryStatsReportGatherer";
import { CallFeedStatsReporter } from "./stats/callFeedStatsReporter";
import { KnownMembership } from "../@types/membership";
export enum GroupCallIntent {
Ring = "m.ring",
@ -1485,7 +1486,7 @@ export class GroupCall extends TypedEventEmitter<
}
// 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>();
participants.set(member, deviceMap);