Skip to content

Commit 823316b

Browse files
committed
Remove use of insecure sendSharedHistoryKeys in MSC3089 impl
1 parent 82e9eef commit 823316b

File tree

2 files changed

+7
-73
lines changed

2 files changed

+7
-73
lines changed

spec/unit/models/MSC3089TreeSpace.spec.ts

Lines changed: 4 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ describe("MSC3089TreeSpace", () => {
107107
return Promise.resolve();
108108
});
109109
client.invite = fn;
110-
await tree.invite(target, false, false);
110+
await tree.invite(target, false);
111111
expect(fn).toHaveBeenCalledTimes(1);
112112
});
113113

@@ -120,7 +120,7 @@ describe("MSC3089TreeSpace", () => {
120120
return Promise.resolve();
121121
});
122122
client.invite = fn;
123-
await tree.invite(target, false, false);
123+
await tree.invite(target, false);
124124
expect(fn).toHaveBeenCalledTimes(2);
125125
});
126126

@@ -133,7 +133,7 @@ describe("MSC3089TreeSpace", () => {
133133
});
134134
client.invite = fn;
135135

136-
await expect(tree.invite(target, false, false)).rejects.toThrow("MatrixError: Sample Failure");
136+
await expect(tree.invite(target, false)).rejects.toThrow("MatrixError: Sample Failure");
137137

138138
expect(fn).toHaveBeenCalledTimes(1);
139139
});
@@ -155,61 +155,10 @@ describe("MSC3089TreeSpace", () => {
155155
{ invite: (userId) => fn(tree.roomId, userId) } as MSC3089TreeSpace,
156156
];
157157

158-
await tree.invite(target, true, false);
158+
await tree.invite(target, true);
159159
expect(fn).toHaveBeenCalledTimes(4);
160160
});
161161

162-
it("should share keys with invitees", async () => {
163-
const target = targetUser;
164-
const sendKeysFn = jest.fn().mockImplementation((inviteRoomId: string, userIds: string[]) => {
165-
expect(inviteRoomId).toEqual(roomId);
166-
expect(userIds).toMatchObject([target]);
167-
return Promise.resolve();
168-
});
169-
client.invite = () => Promise.resolve({}); // we're not testing this here - see other tests
170-
client.sendSharedHistoryKeys = sendKeysFn;
171-
172-
// Mock the history check as best as possible
173-
const historyVis = "shared";
174-
const historyFn = jest.fn().mockImplementation((eventType: string, stateKey?: string) => {
175-
// We're not expecting a super rigid test: the function that calls this internally isn't
176-
// really being tested here.
177-
expect(eventType).toEqual(EventType.RoomHistoryVisibility);
178-
expect(stateKey).toEqual("");
179-
return { getContent: () => ({ history_visibility: historyVis }) }; // eslint-disable-line camelcase
180-
});
181-
room.currentState.getStateEvents = historyFn;
182-
183-
// Note: inverse test is implicit from other tests, which disable the call stack of this
184-
// test in order to pass.
185-
await tree.invite(target, false, true);
186-
expect(sendKeysFn).toHaveBeenCalledTimes(1);
187-
expect(historyFn).toHaveBeenCalledTimes(1);
188-
});
189-
190-
it("should not share keys with invitees if inappropriate history visibility", async () => {
191-
const target = targetUser;
192-
const sendKeysFn = jest.fn().mockImplementation((inviteRoomId: string, userIds: string[]) => {
193-
expect(inviteRoomId).toEqual(roomId);
194-
expect(userIds).toMatchObject([target]);
195-
return Promise.resolve();
196-
});
197-
client.invite = () => Promise.resolve({}); // we're not testing this here - see other tests
198-
client.sendSharedHistoryKeys = sendKeysFn;
199-
200-
const historyVis = "joined"; // NOTE: Changed.
201-
const historyFn = jest.fn().mockImplementation((eventType: string, stateKey?: string) => {
202-
expect(eventType).toEqual(EventType.RoomHistoryVisibility);
203-
expect(stateKey).toEqual("");
204-
return { getContent: () => ({ history_visibility: historyVis }) }; // eslint-disable-line camelcase
205-
});
206-
room.currentState.getStateEvents = historyFn;
207-
208-
await tree.invite(target, false, true);
209-
expect(sendKeysFn).toHaveBeenCalledTimes(0);
210-
expect(historyFn).toHaveBeenCalledTimes(1);
211-
});
212-
213162
async function evaluatePowerLevels(pls: any, role: TreePermissions, expectedPl: number) {
214163
makePowerLevels(pls);
215164
const fn = jest

src/models/MSC3089TreeSpace.ts

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ import {
3030
simpleRetryOperation,
3131
} from "../utils.ts";
3232
import { MSC3089Branch } from "./MSC3089Branch.ts";
33-
import { isRoomSharedHistory } from "../crypto/algorithms/megolm.ts";
3433
import { ISendEventResponse } from "../@types/requests.ts";
3534
import { FileType } from "../http-api/index.ts";
3635
import { KnownMembership } from "../@types/membership.ts";
@@ -136,28 +135,14 @@ export class MSC3089TreeSpace {
136135
* @param userId - The user ID to invite.
137136
* @param andSubspaces - True (default) to invite the user to all
138137
* directories/subspaces too, recursively.
139-
* @param shareHistoryKeys - True (default) to share encryption keys
140-
* with the invited user. This will allow them to decrypt the events (files)
141-
* in the tree. Keys will not be shared if the room is lacking appropriate
142-
* history visibility (by default, history visibility is "shared" in trees,
143-
* which is an appropriate visibility for these purposes).
144138
* @returns Promise which resolves when complete.
145139
*/
146-
public async invite(userId: string, andSubspaces = true, shareHistoryKeys = true): Promise<void> {
140+
public async invite(userId: string, andSubspaces = true): Promise<void> {
147141
const promises: Promise<void>[] = [this.retryInvite(userId)];
148142
if (andSubspaces) {
149-
promises.push(...this.getDirectories().map((d) => d.invite(userId, andSubspaces, shareHistoryKeys)));
143+
promises.push(...this.getDirectories().map((d) => d.invite(userId, andSubspaces)));
150144
}
151-
return Promise.all(promises).then(() => {
152-
// Note: key sharing is default on because for file trees it is relatively important that the invite
153-
// target can actually decrypt the files. The implied use case is that by inviting a user to the tree
154-
// it means the sender would like the receiver to view/download the files contained within, much like
155-
// sharing a folder in other circles.
156-
if (shareHistoryKeys && isRoomSharedHistory(this.room)) {
157-
// noinspection JSIgnoredPromiseFromCall - we aren't concerned as much if this fails.
158-
this.client.sendSharedHistoryKeys(this.roomId, [userId]);
159-
}
160-
});
145+
await Promise.all(promises);
161146
}
162147

163148
private retryInvite(userId: string): Promise<void> {

0 commit comments

Comments
 (0)