diff --git a/src/base-apis.js b/src/base-apis.js index 086477365..bf2381790 100644 --- a/src/base-apis.js +++ b/src/base-apis.js @@ -1071,6 +1071,10 @@ MatrixBaseApis.prototype.searchUserDirectory = function(opts) { * @param {string=} opts.name Name to give the file on the server. Defaults * to file.name. * + * @param {boolean=} opts.includeFilename if false will not send the filename, + * e.g for encrypted file uploads where filename leaks are undesirable. + * Defaults to true. + * * @param {string=} opts.type Content-type for the upload. Defaults to * file.type, or applicaton/octet-stream. * diff --git a/src/http-api.js b/src/http-api.js index 82548855e..b753d6bf8 100644 --- a/src/http-api.js +++ b/src/http-api.js @@ -118,6 +118,10 @@ module.exports.MatrixHttpApi.prototype = { * @param {string=} opts.name Name to give the file on the server. Defaults * to file.name. * + * @param {boolean=} opts.includeFilename if false will not send the filename, + * e.g for encrypted file uploads where filename leaks are undesirable. + * Defaults to true. + * * @param {string=} opts.type Content-type for the upload. Defaults to * file.type, or applicaton/octet-stream. * @@ -152,6 +156,9 @@ module.exports.MatrixHttpApi.prototype = { opts = {}; } + // default opts.includeFilename to true (ignoring falsey values) + const includeFilename = opts.includeFilename !== false; + // if the file doesn't have a mime type, use a default since // the HS errors if we don't supply one. const contentType = opts.type || file.type || 'application/octet-stream'; @@ -272,10 +279,26 @@ module.exports.MatrixHttpApi.prototype = { } }); let url = this.opts.baseUrl + "/_matrix/media/v1/upload"; - url += "?access_token=" + encodeURIComponent(this.opts.accessToken); - url += "&filename=" + encodeURIComponent(fileName); + + const queryArgs = []; + + if (includeFilename && fileName) { + queryArgs.push("filename=" + encodeURIComponent(fileName)); + } + + if (!this.useAuthorizationHeader) { + queryArgs.push("access_token=" + + encodeURIComponent(this.opts.accessToken)); + } + + if (queryArgs.length > 0) { + url += "?" + queryArgs.join("&"); + } xhr.open("POST", url); + if (this.useAuthorizationHeader) { + xhr.setRequestHeader("Authorization", "Bearer " + this.opts.accessToken); + } xhr.setRequestHeader("Content-Type", contentType); xhr.send(body); promise = defer.promise; @@ -283,9 +306,11 @@ module.exports.MatrixHttpApi.prototype = { // dirty hack (as per _request) to allow the upload to be cancelled. promise.abort = xhr.abort.bind(xhr); } else { - const queryParams = { - filename: fileName, - }; + const queryParams = {}; + + if (includeFilename && fileName) { + queryParams.filename = fileName; + } promise = this.authedRequest( opts.callback, "POST", "/upload", queryParams, body, {