Make everything use MFileBody for downloads, ensure that encrypted attachments are actually downloaded
Conflicts: src/components/views/messages/MImageBody.js
This commit is contained in:
parent
ee1768f644
commit
736ab743ee
3 changed files with 37 additions and 54 deletions
|
@ -100,13 +100,43 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
var contentUrl = this._getContentUrl();
|
var contentUrl = this._getContentUrl();
|
||||||
|
|
||||||
|
var fileName = content.body && content.body.length > 0 ? content.body : "Attachment";
|
||||||
|
|
||||||
|
var downloadAttr = undefined;
|
||||||
|
if (this.state.decryptedUrl) {
|
||||||
|
// If the file is encrypted then we MUST download it rather than displaying it
|
||||||
|
// because Firefox is vunerable to XSS attacks in data:// URLs
|
||||||
|
// and all browsers are vunerable to XSS attacks in blob: URLs
|
||||||
|
// created with window.URL.createObjectURL
|
||||||
|
// See https://bugzilla.mozilla.org/show_bug.cgi?id=255107
|
||||||
|
// See https://w3c.github.io/FileAPI/#originOfBlobURL
|
||||||
|
//
|
||||||
|
// This is not a problem for unencrypted links because they are
|
||||||
|
// either fetched from a different domain so are safe because of
|
||||||
|
// the same-origin policy or they are fetch from the same domain,
|
||||||
|
// in which case we trust that the homeserver will set a
|
||||||
|
// Content-Security-Policy that disables script execution.
|
||||||
|
// It is reasonable to trust the homeserver in that case since
|
||||||
|
// it is the same domain that controls this javascript.
|
||||||
|
//
|
||||||
|
// We can't apply the same workaround for encrypted files because
|
||||||
|
// we can't supply HTTP headers when the user clicks on a blob:
|
||||||
|
// or data:// uri.
|
||||||
|
//
|
||||||
|
// We should probably provide a download attribute anyway so that
|
||||||
|
// the file will have the correct name when the user tries to
|
||||||
|
// download it. We can't provide a Content-Disposition header
|
||||||
|
// like we would for HTTP.
|
||||||
|
downloadAttr = fileName;
|
||||||
|
}
|
||||||
|
|
||||||
if (contentUrl) {
|
if (contentUrl) {
|
||||||
if (this.props.tileShape === "file_grid") {
|
if (this.props.tileShape === "file_grid") {
|
||||||
return (
|
return (
|
||||||
<span className="mx_MFileBody">
|
<span className="mx_MFileBody">
|
||||||
<div className="mx_MImageBody_download">
|
<div className="mx_MImageBody_download">
|
||||||
<a className="mx_ImageBody_downloadLink" href={contentUrl} target="_blank" rel="noopener">
|
<a className="mx_ImageBody_downloadLink" href={contentUrl} target="_blank" rel="noopener" download={downloadAttr}>
|
||||||
{ content.body && content.body.length > 0 ? content.body : "Attachment" }
|
{ fileName }
|
||||||
</a>
|
</a>
|
||||||
<div className="mx_MImageBody_size">
|
<div className="mx_MImageBody_size">
|
||||||
{ content.info && content.info.size ? filesize(content.info.size) : "" }
|
{ content.info && content.info.size ? filesize(content.info.size) : "" }
|
||||||
|
@ -119,7 +149,7 @@ module.exports = React.createClass({
|
||||||
return (
|
return (
|
||||||
<span className="mx_MFileBody">
|
<span className="mx_MFileBody">
|
||||||
<div className="mx_MImageBody_download">
|
<div className="mx_MImageBody_download">
|
||||||
<a href={contentUrl} target="_blank" rel="noopener">
|
<a href={contentUrl} target="_blank" rel="noopener" download={downloadAttr}>
|
||||||
<TintableSvg src="img/download.svg" width="12" height="14"/>
|
<TintableSvg src="img/download.svg" width="12" height="14"/>
|
||||||
Download {text}
|
Download {text}
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -18,6 +18,7 @@ limitations under the License.
|
||||||
|
|
||||||
var React = require('react');
|
var React = require('react');
|
||||||
var filesize = require('filesize');
|
var filesize = require('filesize');
|
||||||
|
var MFileBody = require('./MFileBody');
|
||||||
var MatrixClientPeg = require('../../../MatrixClientPeg');
|
var MatrixClientPeg = require('../../../MatrixClientPeg');
|
||||||
var ImageUtils = require('../../../ImageUtils');
|
var ImageUtils = require('../../../ImageUtils');
|
||||||
var Modal = require('../../../Modal');
|
var Modal = require('../../../Modal');
|
||||||
|
@ -172,30 +173,6 @@ module.exports = React.createClass({
|
||||||
var contentUrl = this._getContentUrl();
|
var contentUrl = this._getContentUrl();
|
||||||
var thumbUrl = this._getThumbUrl();
|
var thumbUrl = this._getThumbUrl();
|
||||||
|
|
||||||
var download;
|
|
||||||
if (this.props.tileShape === "file_grid") {
|
|
||||||
download = (
|
|
||||||
<div className="mx_MImageBody_download">
|
|
||||||
<a className="mx_MImageBody_downloadLink" href={contentUrl} target="_blank" rel="noopener">
|
|
||||||
{content.body}
|
|
||||||
</a>
|
|
||||||
<div className="mx_MImageBody_size">
|
|
||||||
{ content.info && content.info.size ? filesize(content.info.size) : "" }
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
download = (
|
|
||||||
<div className="mx_MImageBody_download">
|
|
||||||
<a href={contentUrl} target="_blank" rel="noopener">
|
|
||||||
<TintableSvg src="img/download.svg" width="12" height="14"/>
|
|
||||||
Download {content.body} ({ content.info && content.info.size ? filesize(content.info.size) : "Unknown size" })
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (thumbUrl) {
|
if (thumbUrl) {
|
||||||
return (
|
return (
|
||||||
<span className="mx_MImageBody" ref="body">
|
<span className="mx_MImageBody" ref="body">
|
||||||
|
@ -205,7 +182,7 @@ module.exports = React.createClass({
|
||||||
onMouseEnter={this.onImageEnter}
|
onMouseEnter={this.onImageEnter}
|
||||||
onMouseLeave={this.onImageLeave} />
|
onMouseLeave={this.onImageLeave} />
|
||||||
</a>
|
</a>
|
||||||
{ download }
|
<MFileBody {...this.props} />
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
} else if (content.body) {
|
} else if (content.body) {
|
||||||
|
|
|
@ -19,6 +19,7 @@ limitations under the License.
|
||||||
var React = require('react');
|
var React = require('react');
|
||||||
var filesize = require('filesize');
|
var filesize = require('filesize');
|
||||||
|
|
||||||
|
import MFileBody from './MFileBody';
|
||||||
|
|
||||||
var MatrixClientPeg = require('../../../MatrixClientPeg');
|
var MatrixClientPeg = require('../../../MatrixClientPeg');
|
||||||
var Modal = require('../../../Modal');
|
var Modal = require('../../../Modal');
|
||||||
|
@ -140,38 +141,13 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var download;
|
|
||||||
if (this.props.tileShape === "file_grid") {
|
|
||||||
download = (
|
|
||||||
<div className="mx_MImageBody_download">
|
|
||||||
<a className="mx_MImageBody_downloadLink" href={contentUrl} target="_blank" rel="noopener">
|
|
||||||
{content.body}
|
|
||||||
</a>
|
|
||||||
<div className="mx_MImageBody_size">
|
|
||||||
{ content.info && content.info.size ? filesize(content.info.size) : "" }
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var TintableSvg = sdk.getComponent("elements.TintableSvg");
|
|
||||||
download = (
|
|
||||||
<div className="mx_MImageBody_download">
|
|
||||||
<a href={contentUrl} target="_blank" rel="noopener">
|
|
||||||
<TintableSvg src="img/download.svg" width="12" height="14"/>
|
|
||||||
Download {content.body} ({ content.info && content.info.size ? filesize(content.info.size) : "Unknown size" })
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span className="mx_MVideoBody">
|
<span className="mx_MVideoBody">
|
||||||
<video className="mx_MVideoBody" src={contentUrl} alt={content.body}
|
<video className="mx_MVideoBody" src={contentUrl} alt={content.body}
|
||||||
controls preload={preload} autoPlay={false}
|
controls preload={preload} autoPlay={false}
|
||||||
height={height} width={width} poster={poster}>
|
height={height} width={width} poster={poster}>
|
||||||
</video>
|
</video>
|
||||||
{ download }
|
<MFileBody {...this.props} />
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue