From 50791e3aa759c2fab8f0312c82b6eb2b5c609717 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 20 Dec 2019 14:06:36 -0700 Subject: [PATCH 1/2] Make ContentRepo a class for easier importing Exporting it the way we were was causing problems for webpack way down the line, so we export it differently here to get around that. We also have to fix all the import references so we import the right thing. --- spec/unit/content-repo.spec.js | 2 +- src/client.js | 4 +- src/content-repo.js | 162 +++++++++++++++++---------------- src/matrix.js | 2 +- src/models/room-member.js | 2 +- src/models/room.js | 2 +- 6 files changed, 88 insertions(+), 86 deletions(-) diff --git a/spec/unit/content-repo.spec.js b/spec/unit/content-repo.spec.js index db96728e6..fbb6f6784 100644 --- a/spec/unit/content-repo.spec.js +++ b/spec/unit/content-repo.spec.js @@ -1,4 +1,4 @@ -import * as ContentRepo from "../../src/content-repo"; +import {ContentRepo} from "../../src/content-repo"; describe("ContentRepo", function() { const baseUrl = "https://my.home.server"; diff --git a/src/client.js b/src/client.js index 04158dd64..b8f5bf3e1 100644 --- a/src/client.js +++ b/src/client.js @@ -36,7 +36,7 @@ import {createNewMatrixCall} from "./webrtc/call"; import * as utils from './utils'; import {sleep} from './utils'; import {MatrixError, PREFIX_MEDIA_R0, PREFIX_UNSTABLE} from "./http-api"; -import * as contentRepo from "./content-repo"; +import {ContentRepo} from "./content-repo"; import * as ContentHelpers from "./content-helpers"; import * as olmlib from "./crypto/olmlib"; import {ReEmitter} from './ReEmitter'; @@ -3132,7 +3132,7 @@ MatrixClient.prototype.setAvatarUrl = function(url, callback) { */ MatrixClient.prototype.mxcUrlToHttp = function(mxcUrl, width, height, resizeMethod, allowDirectLinks) { - return contentRepo.getHttpUriForMxc( + return ContentRepo.getHttpUriForMxc( this.baseUrl, mxcUrl, width, height, resizeMethod, allowDirectLinks, ); }; diff --git a/src/content-repo.js b/src/content-repo.js index 4bc4ca688..7ac25d461 100644 --- a/src/content-repo.js +++ b/src/content-repo.js @@ -20,90 +20,92 @@ limitations under the License. import * as utils from "./utils"; -/** - * Get the HTTP URL for an MXC URI. - * @param {string} baseUrl The base homeserver url which has a content repo. - * @param {string} mxc The mxc:// URI. - * @param {Number} width The desired width of the thumbnail. - * @param {Number} height The desired height of the thumbnail. - * @param {string} resizeMethod The thumbnail resize method to use, either - * "crop" or "scale". - * @param {Boolean} allowDirectLinks If true, return any non-mxc URLs - * directly. Fetching such URLs will leak information about the user to - * anyone they share a room with. If false, will return the emptry string - * for such URLs. - * @return {string} The complete URL to the content. - */ -export function getHttpUriForMxc(baseUrl, mxc, width, height, - resizeMethod, allowDirectLinks) { - if (typeof mxc !== "string" || !mxc) { - return ''; - } - if (mxc.indexOf("mxc://") !== 0) { - if (allowDirectLinks) { - return mxc; - } else { +export class ContentRepo { + /** + * Get the HTTP URL for an MXC URI. + * @param {string} baseUrl The base homeserver url which has a content repo. + * @param {string} mxc The mxc:// URI. + * @param {Number} width The desired width of the thumbnail. + * @param {Number} height The desired height of the thumbnail. + * @param {string} resizeMethod The thumbnail resize method to use, either + * "crop" or "scale". + * @param {Boolean} allowDirectLinks If true, return any non-mxc URLs + * directly. Fetching such URLs will leak information about the user to + * anyone they share a room with. If false, will return the emptry string + * for such URLs. + * @return {string} The complete URL to the content. + */ + static getHttpUriForMxc(baseUrl, mxc, width, height, + resizeMethod, allowDirectLinks) { + if (typeof mxc !== "string" || !mxc) { return ''; } - } - let serverAndMediaId = mxc.slice(6); // strips mxc:// - let prefix = "/_matrix/media/r0/download/"; - const params = {}; + if (mxc.indexOf("mxc://") !== 0) { + if (allowDirectLinks) { + return mxc; + } else { + return ''; + } + } + let serverAndMediaId = mxc.slice(6); // strips mxc:// + let prefix = "/_matrix/media/r0/download/"; + const params = {}; - if (width) { - params.width = Math.round(width); - } - if (height) { - params.height = Math.round(height); - } - if (resizeMethod) { - params.method = resizeMethod; - } - if (utils.keys(params).length > 0) { - // these are thumbnailing params so they probably want the - // thumbnailing API... - prefix = "/_matrix/media/r0/thumbnail/"; + if (width) { + params.width = Math.round(width); + } + if (height) { + params.height = Math.round(height); + } + if (resizeMethod) { + params.method = resizeMethod; + } + if (utils.keys(params).length > 0) { + // these are thumbnailing params so they probably want the + // thumbnailing API... + prefix = "/_matrix/media/r0/thumbnail/"; + } + + const fragmentOffset = serverAndMediaId.indexOf("#"); + let fragment = ""; + if (fragmentOffset >= 0) { + fragment = serverAndMediaId.substr(fragmentOffset); + serverAndMediaId = serverAndMediaId.substr(0, fragmentOffset); + } + return baseUrl + prefix + serverAndMediaId + + (utils.keys(params).length === 0 ? "" : + ("?" + utils.encodeParams(params))) + fragment; } - const fragmentOffset = serverAndMediaId.indexOf("#"); - let fragment = ""; - if (fragmentOffset >= 0) { - fragment = serverAndMediaId.substr(fragmentOffset); - serverAndMediaId = serverAndMediaId.substr(0, fragmentOffset); + /** + * Get an identicon URL from an arbitrary string. + * @param {string} baseUrl The base homeserver url which has a content repo. + * @param {string} identiconString The string to create an identicon for. + * @param {Number} width The desired width of the image in pixels. Default: 96. + * @param {Number} height The desired height of the image in pixels. Default: 96. + * @return {string} The complete URL to the identicon. + * @deprecated This is no longer in the specification. + */ + static getIdenticonUri(baseUrl, identiconString, width, height) { + if (!identiconString) { + return null; + } + if (!width) { + width = 96; + } + if (!height) { + height = 96; + } + const params = { + width: width, + height: height, + }; + + const path = utils.encodeUri("/_matrix/media/unstable/identicon/$ident", { + $ident: identiconString, + }); + return baseUrl + path + + (utils.keys(params).length === 0 ? "" : + ("?" + utils.encodeParams(params))); } - return baseUrl + prefix + serverAndMediaId + - (utils.keys(params).length === 0 ? "" : - ("?" + utils.encodeParams(params))) + fragment; -} - -/** - * Get an identicon URL from an arbitrary string. - * @param {string} baseUrl The base homeserver url which has a content repo. - * @param {string} identiconString The string to create an identicon for. - * @param {Number} width The desired width of the image in pixels. Default: 96. - * @param {Number} height The desired height of the image in pixels. Default: 96. - * @return {string} The complete URL to the identicon. - * @deprecated This is no longer in the specification. - */ -export function getIdenticonUri(baseUrl, identiconString, width, height) { - if (!identiconString) { - return null; - } - if (!width) { - width = 96; - } - if (!height) { - height = 96; - } - const params = { - width: width, - height: height, - }; - - const path = utils.encodeUri("/_matrix/media/unstable/identicon/$ident", { - $ident: identiconString, - }); - return baseUrl + path + - (utils.keys(params).length === 0 ? "" : - ("?" + utils.encodeParams(params))); } diff --git a/src/matrix.js b/src/matrix.js index f611d1d7c..32892d650 100644 --- a/src/matrix.js +++ b/src/matrix.js @@ -44,8 +44,8 @@ export * from "./store/indexeddb"; export * from "./store/session/webstorage"; export * from "./crypto/store/memory-crypto-store"; export * from "./crypto/store/indexeddb-crypto-store"; +export * from "./content-repo"; export const ContentHelpers = import("./content-helpers"); -export const ContentRepo = import("./content-repo"); export { createNewMatrixCall, setAudioOutput as setMatrixCallAudioOutput, diff --git a/src/models/room-member.js b/src/models/room-member.js index fb53f5614..db3b85946 100644 --- a/src/models/room-member.js +++ b/src/models/room-member.js @@ -20,7 +20,7 @@ limitations under the License. */ import {EventEmitter} from "events"; -import * as ContentRepo from "../content-repo"; +import {ContentRepo} from "../content-repo"; import * as utils from "../utils"; /** diff --git a/src/models/room.js b/src/models/room.js index fae36d2ca..77a6f370e 100644 --- a/src/models/room.js +++ b/src/models/room.js @@ -23,7 +23,7 @@ limitations under the License. import {EventEmitter} from "events"; import {EventTimelineSet} from "./event-timeline-set"; import {EventTimeline} from "./event-timeline"; -import * as ContentRepo from "../content-repo"; +import {ContentRepo} from "../content-repo"; import * as utils from "../utils"; import {EventStatus, MatrixEvent} from "./event"; import {RoomMember} from "./room-member"; From f4d1c5c006027962cd18dffb3f7c521d9e24e831 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 3 Jan 2020 12:15:57 -0700 Subject: [PATCH 2/2] Switch back to plain export functions instead of class --- spec/unit/content-repo.spec.js | 24 ++--- src/client.js | 4 +- src/content-repo.js | 162 ++++++++++++++++----------------- src/models/room-member.js | 6 +- src/models/room.js | 6 +- 5 files changed, 100 insertions(+), 102 deletions(-) diff --git a/spec/unit/content-repo.spec.js b/spec/unit/content-repo.spec.js index fbb6f6784..b55055684 100644 --- a/spec/unit/content-repo.spec.js +++ b/spec/unit/content-repo.spec.js @@ -1,4 +1,4 @@ -import {ContentRepo} from "../../src/content-repo"; +import {getHttpUriForMxc, getIdenticonUri} from "../../src/content-repo"; describe("ContentRepo", function() { const baseUrl = "https://my.home.server"; @@ -7,7 +7,7 @@ describe("ContentRepo", function() { it("should do nothing to HTTP URLs when allowing direct links", function() { const httpUrl = "http://example.com/image.jpeg"; expect( - ContentRepo.getHttpUriForMxc( + getHttpUriForMxc( baseUrl, httpUrl, undefined, undefined, undefined, true, ), ).toEqual(httpUrl); @@ -15,25 +15,25 @@ describe("ContentRepo", function() { it("should return the empty string HTTP URLs by default", function() { const httpUrl = "http://example.com/image.jpeg"; - expect(ContentRepo.getHttpUriForMxc(baseUrl, httpUrl)).toEqual(""); + expect(getHttpUriForMxc(baseUrl, httpUrl)).toEqual(""); }); it("should return a download URL if no width/height/resize are specified", function() { const mxcUri = "mxc://server.name/resourceid"; - expect(ContentRepo.getHttpUriForMxc(baseUrl, mxcUri)).toEqual( + expect(getHttpUriForMxc(baseUrl, mxcUri)).toEqual( baseUrl + "/_matrix/media/r0/download/server.name/resourceid", ); }); it("should return the empty string for null input", function() { - expect(ContentRepo.getHttpUriForMxc(null)).toEqual(""); + expect(getHttpUriForMxc(null)).toEqual(""); }); it("should return a thumbnail URL if a width/height/resize is specified", function() { const mxcUri = "mxc://server.name/resourceid"; - expect(ContentRepo.getHttpUriForMxc(baseUrl, mxcUri, 32, 64, "crop")).toEqual( + expect(getHttpUriForMxc(baseUrl, mxcUri, 32, 64, "crop")).toEqual( baseUrl + "/_matrix/media/r0/thumbnail/server.name/resourceid" + "?width=32&height=64&method=crop", ); @@ -42,7 +42,7 @@ describe("ContentRepo", function() { it("should put fragments from mxc:// URIs after any query parameters", function() { const mxcUri = "mxc://server.name/resourceid#automade"; - expect(ContentRepo.getHttpUriForMxc(baseUrl, mxcUri, 32)).toEqual( + expect(getHttpUriForMxc(baseUrl, mxcUri, 32)).toEqual( baseUrl + "/_matrix/media/r0/thumbnail/server.name/resourceid" + "?width=32#automade", ); @@ -51,7 +51,7 @@ describe("ContentRepo", function() { it("should put fragments from mxc:// URIs at the end of the HTTP URI", function() { const mxcUri = "mxc://server.name/resourceid#automade"; - expect(ContentRepo.getHttpUriForMxc(baseUrl, mxcUri)).toEqual( + expect(getHttpUriForMxc(baseUrl, mxcUri)).toEqual( baseUrl + "/_matrix/media/r0/download/server.name/resourceid#automade", ); }); @@ -59,25 +59,25 @@ describe("ContentRepo", function() { describe("getIdenticonUri", function() { it("should do nothing for null input", function() { - expect(ContentRepo.getIdenticonUri(null)).toEqual(null); + expect(getIdenticonUri(null)).toEqual(null); }); it("should set w/h by default to 96", function() { - expect(ContentRepo.getIdenticonUri(baseUrl, "foobar")).toEqual( + expect(getIdenticonUri(baseUrl, "foobar")).toEqual( baseUrl + "/_matrix/media/unstable/identicon/foobar" + "?width=96&height=96", ); }); it("should be able to set custom w/h", function() { - expect(ContentRepo.getIdenticonUri(baseUrl, "foobar", 32, 64)).toEqual( + expect(getIdenticonUri(baseUrl, "foobar", 32, 64)).toEqual( baseUrl + "/_matrix/media/unstable/identicon/foobar" + "?width=32&height=64", ); }); it("should URL encode the identicon string", function() { - expect(ContentRepo.getIdenticonUri(baseUrl, "foo#bar", 32, 64)).toEqual( + expect(getIdenticonUri(baseUrl, "foo#bar", 32, 64)).toEqual( baseUrl + "/_matrix/media/unstable/identicon/foo%23bar" + "?width=32&height=64", ); diff --git a/src/client.js b/src/client.js index b8f5bf3e1..b5a1bf881 100644 --- a/src/client.js +++ b/src/client.js @@ -36,7 +36,7 @@ import {createNewMatrixCall} from "./webrtc/call"; import * as utils from './utils'; import {sleep} from './utils'; import {MatrixError, PREFIX_MEDIA_R0, PREFIX_UNSTABLE} from "./http-api"; -import {ContentRepo} from "./content-repo"; +import {getHttpUriForMxc} from "./content-repo"; import * as ContentHelpers from "./content-helpers"; import * as olmlib from "./crypto/olmlib"; import {ReEmitter} from './ReEmitter'; @@ -3132,7 +3132,7 @@ MatrixClient.prototype.setAvatarUrl = function(url, callback) { */ MatrixClient.prototype.mxcUrlToHttp = function(mxcUrl, width, height, resizeMethod, allowDirectLinks) { - return ContentRepo.getHttpUriForMxc( + return getHttpUriForMxc( this.baseUrl, mxcUrl, width, height, resizeMethod, allowDirectLinks, ); }; diff --git a/src/content-repo.js b/src/content-repo.js index 7ac25d461..4bc4ca688 100644 --- a/src/content-repo.js +++ b/src/content-repo.js @@ -20,92 +20,90 @@ limitations under the License. import * as utils from "./utils"; -export class ContentRepo { - /** - * Get the HTTP URL for an MXC URI. - * @param {string} baseUrl The base homeserver url which has a content repo. - * @param {string} mxc The mxc:// URI. - * @param {Number} width The desired width of the thumbnail. - * @param {Number} height The desired height of the thumbnail. - * @param {string} resizeMethod The thumbnail resize method to use, either - * "crop" or "scale". - * @param {Boolean} allowDirectLinks If true, return any non-mxc URLs - * directly. Fetching such URLs will leak information about the user to - * anyone they share a room with. If false, will return the emptry string - * for such URLs. - * @return {string} The complete URL to the content. - */ - static getHttpUriForMxc(baseUrl, mxc, width, height, - resizeMethod, allowDirectLinks) { - if (typeof mxc !== "string" || !mxc) { +/** + * Get the HTTP URL for an MXC URI. + * @param {string} baseUrl The base homeserver url which has a content repo. + * @param {string} mxc The mxc:// URI. + * @param {Number} width The desired width of the thumbnail. + * @param {Number} height The desired height of the thumbnail. + * @param {string} resizeMethod The thumbnail resize method to use, either + * "crop" or "scale". + * @param {Boolean} allowDirectLinks If true, return any non-mxc URLs + * directly. Fetching such URLs will leak information about the user to + * anyone they share a room with. If false, will return the emptry string + * for such URLs. + * @return {string} The complete URL to the content. + */ +export function getHttpUriForMxc(baseUrl, mxc, width, height, + resizeMethod, allowDirectLinks) { + if (typeof mxc !== "string" || !mxc) { + return ''; + } + if (mxc.indexOf("mxc://") !== 0) { + if (allowDirectLinks) { + return mxc; + } else { return ''; } - if (mxc.indexOf("mxc://") !== 0) { - if (allowDirectLinks) { - return mxc; - } else { - return ''; - } - } - let serverAndMediaId = mxc.slice(6); // strips mxc:// - let prefix = "/_matrix/media/r0/download/"; - const params = {}; + } + let serverAndMediaId = mxc.slice(6); // strips mxc:// + let prefix = "/_matrix/media/r0/download/"; + const params = {}; - if (width) { - params.width = Math.round(width); - } - if (height) { - params.height = Math.round(height); - } - if (resizeMethod) { - params.method = resizeMethod; - } - if (utils.keys(params).length > 0) { - // these are thumbnailing params so they probably want the - // thumbnailing API... - prefix = "/_matrix/media/r0/thumbnail/"; - } - - const fragmentOffset = serverAndMediaId.indexOf("#"); - let fragment = ""; - if (fragmentOffset >= 0) { - fragment = serverAndMediaId.substr(fragmentOffset); - serverAndMediaId = serverAndMediaId.substr(0, fragmentOffset); - } - return baseUrl + prefix + serverAndMediaId + - (utils.keys(params).length === 0 ? "" : - ("?" + utils.encodeParams(params))) + fragment; + if (width) { + params.width = Math.round(width); + } + if (height) { + params.height = Math.round(height); + } + if (resizeMethod) { + params.method = resizeMethod; + } + if (utils.keys(params).length > 0) { + // these are thumbnailing params so they probably want the + // thumbnailing API... + prefix = "/_matrix/media/r0/thumbnail/"; } - /** - * Get an identicon URL from an arbitrary string. - * @param {string} baseUrl The base homeserver url which has a content repo. - * @param {string} identiconString The string to create an identicon for. - * @param {Number} width The desired width of the image in pixels. Default: 96. - * @param {Number} height The desired height of the image in pixels. Default: 96. - * @return {string} The complete URL to the identicon. - * @deprecated This is no longer in the specification. - */ - static getIdenticonUri(baseUrl, identiconString, width, height) { - if (!identiconString) { - return null; - } - if (!width) { - width = 96; - } - if (!height) { - height = 96; - } - const params = { - width: width, - height: height, - }; - - const path = utils.encodeUri("/_matrix/media/unstable/identicon/$ident", { - $ident: identiconString, - }); - return baseUrl + path + - (utils.keys(params).length === 0 ? "" : - ("?" + utils.encodeParams(params))); + const fragmentOffset = serverAndMediaId.indexOf("#"); + let fragment = ""; + if (fragmentOffset >= 0) { + fragment = serverAndMediaId.substr(fragmentOffset); + serverAndMediaId = serverAndMediaId.substr(0, fragmentOffset); } + return baseUrl + prefix + serverAndMediaId + + (utils.keys(params).length === 0 ? "" : + ("?" + utils.encodeParams(params))) + fragment; +} + +/** + * Get an identicon URL from an arbitrary string. + * @param {string} baseUrl The base homeserver url which has a content repo. + * @param {string} identiconString The string to create an identicon for. + * @param {Number} width The desired width of the image in pixels. Default: 96. + * @param {Number} height The desired height of the image in pixels. Default: 96. + * @return {string} The complete URL to the identicon. + * @deprecated This is no longer in the specification. + */ +export function getIdenticonUri(baseUrl, identiconString, width, height) { + if (!identiconString) { + return null; + } + if (!width) { + width = 96; + } + if (!height) { + height = 96; + } + const params = { + width: width, + height: height, + }; + + const path = utils.encodeUri("/_matrix/media/unstable/identicon/$ident", { + $ident: identiconString, + }); + return baseUrl + path + + (utils.keys(params).length === 0 ? "" : + ("?" + utils.encodeParams(params))); } diff --git a/src/models/room-member.js b/src/models/room-member.js index db3b85946..8fd07ebae 100644 --- a/src/models/room-member.js +++ b/src/models/room-member.js @@ -20,7 +20,7 @@ limitations under the License. */ import {EventEmitter} from "events"; -import {ContentRepo} from "../content-repo"; +import {getHttpUriForMxc, getIdenticonUri} from "../content-repo"; import * as utils from "../utils"; /** @@ -269,13 +269,13 @@ RoomMember.prototype.getAvatarUrl = if (!rawUrl && !allowDefault) { return null; } - const httpUrl = ContentRepo.getHttpUriForMxc( + const httpUrl = getHttpUriForMxc( baseUrl, rawUrl, width, height, resizeMethod, allowDirectLinks, ); if (httpUrl) { return httpUrl; } else if (allowDefault) { - return ContentRepo.getIdenticonUri( + return getIdenticonUri( baseUrl, this.userId, width, height, ); } diff --git a/src/models/room.js b/src/models/room.js index 77a6f370e..62fdbb86a 100644 --- a/src/models/room.js +++ b/src/models/room.js @@ -23,7 +23,7 @@ limitations under the License. import {EventEmitter} from "events"; import {EventTimelineSet} from "./event-timeline-set"; import {EventTimeline} from "./event-timeline"; -import {ContentRepo} from "../content-repo"; +import {getHttpUriForMxc, getIdenticonUri} from "../content-repo"; import * as utils from "../utils"; import {EventStatus, MatrixEvent} from "./event"; import {RoomMember} from "./room-member"; @@ -811,11 +811,11 @@ Room.prototype.getAvatarUrl = function(baseUrl, width, height, resizeMethod, const mainUrl = roomAvatarEvent ? roomAvatarEvent.getContent().url : null; if (mainUrl) { - return ContentRepo.getHttpUriForMxc( + return getHttpUriForMxc( baseUrl, mainUrl, width, height, resizeMethod, ); } else if (allowDefault) { - return ContentRepo.getIdenticonUri( + return getIdenticonUri( baseUrl, this.roomId, width, height, ); }