Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add authenticated media to getAvatarUrl in room and room-member models #4616

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions spec/unit/room-member.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,40 @@ describe("RoomMember", function () {
const url = member.getAvatarUrl(hsUrl, 64, 64, "crop", false, false);
expect(url).toEqual(null);
});

it("should return unauthenticated media URL if useAuthentication is not set", function () {
member.events.member = utils.mkEvent({
event: true,
type: "m.room.member",
skey: userA,
room: roomId,
user: userA,
content: {
membership: KnownMembership.Join,
avatar_url: "mxc://flibble/wibble",
},
});
const url = member.getAvatarUrl(hsUrl, 1, 1, "", false, false);
// Check for unauthenticated media prefix
expect(url?.indexOf("/_matrix/media/v3/")).not.toEqual(-1);
});

it("should return authenticated media URL if useAuthentication=true", function () {
member.events.member = utils.mkEvent({
event: true,
type: "m.room.member",
skey: userA,
room: roomId,
user: userA,
content: {
membership: KnownMembership.Join,
avatar_url: "mxc://flibble/wibble",
},
});
const url = member.getAvatarUrl(hsUrl, 1, 1, "", false, false, true);
// Check for authenticated media prefix
expect(url?.indexOf("/_matrix/client/v1/media/")).not.toEqual(-1);
});
});

describe("setPowerLevelEvent", function () {
Expand Down
42 changes: 42 additions & 0 deletions spec/unit/room.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,48 @@ describe("Room", function () {
const url = room.getAvatarUrl(hsUrl, 64, 64, "crop", false);
expect(url).toEqual(null);
});

it("should return unauthenticated media URL if useAuthentication is not set", function () {
// @ts-ignore - mocked doesn't handle overloads sanely
mocked(room.currentState.getStateEvents).mockImplementation(function (type, key) {
if (type === EventType.RoomAvatar && key === "") {
return utils.mkEvent({
event: true,
type: EventType.RoomAvatar,
skey: "",
room: roomId,
user: userA,
content: {
url: "mxc://flibble/wibble",
},
});
}
});
const url = room.getAvatarUrl(hsUrl, 100, 100, "scale");
// Check for unauthenticated media prefix
expect(url?.indexOf("/_matrix/media/v3/")).not.toEqual(-1);
});

it("should return authenticated media URL if useAuthentication=true", function () {
// @ts-ignore - mocked doesn't handle overloads sanely
mocked(room.currentState.getStateEvents).mockImplementation(function (type, key) {
if (type === EventType.RoomAvatar && key === "") {
return utils.mkEvent({
event: true,
type: EventType.RoomAvatar,
skey: "",
room: roomId,
user: userA,
content: {
url: "mxc://flibble/wibble",
},
});
}
});
const url = room.getAvatarUrl(hsUrl, 100, 100, "scale", undefined, true);
// Check for authenticated media prefix
expect(url?.indexOf("/_matrix/client/v1/media/")).not.toEqual(-1);
});
});

describe("getMember", function () {
Expand Down
17 changes: 16 additions & 1 deletion src/models/room-member.ts
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,11 @@ export class RoomMember extends TypedEventEmitter<RoomMemberEvent, RoomMemberEve
* If false, any non-matrix content URLs will be ignored. Setting this option to
* true will expose URLs that, if fetched, will leak information about the user
* to anyone who they share a room with.
* @param useAuthentication - (optional) If true, the caller supports authenticated
* media and wants an authentication-required URL. Note that server support for
* authenticated media will not be checked - it is the caller's responsibility
* to do so before calling this function. Note also that useAuthentication
* implies allowRedirects. Defaults to false (unauthenticated endpoints).
* @returns the avatar URL or null.
*/
public getAvatarUrl(
Expand All @@ -377,13 +382,23 @@ export class RoomMember extends TypedEventEmitter<RoomMemberEvent, RoomMemberEve
resizeMethod: string,
allowDefault = true,
allowDirectLinks: boolean,
useAuthentication: boolean = false,
): string | null {
const rawUrl = this.getMxcAvatarUrl();

if (!rawUrl && !allowDefault) {
return null;
}
const httpUrl = getHttpUriForMxc(baseUrl, rawUrl, width, height, resizeMethod, allowDirectLinks);
const httpUrl = getHttpUriForMxc(
baseUrl,
rawUrl,
width,
height,
resizeMethod,
allowDirectLinks,
undefined,
useAuthentication,
);
if (httpUrl) {
return httpUrl;
}
Expand Down
17 changes: 16 additions & 1 deletion src/models/room.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1661,6 +1661,11 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
* "crop" or "scale".
* @param allowDefault - True to allow an identicon for this room if an
* avatar URL wasn't explicitly set. Default: true. (Deprecated)
* @param useAuthentication - (optional) If true, the caller supports authenticated
* media and wants an authentication-required URL. Note that server support for
* authenticated media will not be checked - it is the caller's responsibility
* to do so before calling this function. Note also that useAuthentication
* implies allowRedirects. Defaults to false (unauthenticated endpoints).
* @returns the avatar URL or null.
*/
public getAvatarUrl(
Expand All @@ -1669,6 +1674,7 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
height: number,
resizeMethod: ResizeMethod,
allowDefault = true,
useAuthentication: boolean = false,
): string | null {
const roomAvatarEvent = this.currentState.getStateEvents(EventType.RoomAvatar, "");
if (!roomAvatarEvent && !allowDefault) {
Expand All @@ -1677,7 +1683,16 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {

const mainUrl = roomAvatarEvent ? roomAvatarEvent.getContent().url : null;
if (mainUrl) {
return getHttpUriForMxc(baseUrl, mainUrl, width, height, resizeMethod);
return getHttpUriForMxc(
baseUrl,
mainUrl,
width,
height,
resizeMethod,
undefined,
undefined,
useAuthentication,
);
}

return null;
Expand Down
Loading