1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-08-09 10:22:46 +03:00

Add authenticated media to getAvatarURL in room and room-member models (#4616)

This commit is contained in:
m004
2025-01-15 10:49:18 +01:00
committed by GitHub
parent 07f97d724f
commit ffbb4716c4
4 changed files with 108 additions and 2 deletions

View File

@@ -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 () {

View File

@@ -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 () {

View File

@@ -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(
@@ -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;
}

View File

@@ -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(
@@ -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) {
@@ -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;