From b69e88d4e3247e340ddd2540df5e9ac5a4baf908 Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Fri, 4 Nov 2016 14:00:26 +0000 Subject: [PATCH] Decrypt m.file attachments --- src/components/views/messages/MFileBody.js | 64 ++++++++++++++++++++-- 1 file changed, 58 insertions(+), 6 deletions(-) diff --git a/src/components/views/messages/MFileBody.js b/src/components/views/messages/MFileBody.js index c37cd32c4e..855cdac59c 100644 --- a/src/components/views/messages/MFileBody.js +++ b/src/components/views/messages/MFileBody.js @@ -20,11 +20,17 @@ var React = require('react'); var filesize = require('filesize'); var MatrixClientPeg = require('../../../MatrixClientPeg'); var sdk = require('../../../index'); -var dis = require("../../../dispatcher"); +var DecryptFile = require('../../../utils/DecryptFile'); module.exports = React.createClass({ displayName: 'MFileBody', + getInitialState: function() { + return { + decryptedUrl: null, + }; + }, + presentableTextForFile: function(content) { var linkText = 'Attachment'; if (content.body && content.body.length > 0) { @@ -47,21 +53,67 @@ module.exports = React.createClass({ return linkText; }, + _getContentUrl: function() { + var content = this.props.mxEvent.getContent(); + if (content.file !== undefined) { + return this.state.decryptedUrl; + } else { + return MatrixClientPeg.get().mxcUrlToHttp(content.url); + } + }, + + componentDidMount: function() { + var content = this.props.mxEvent.getContent(); + var self = this; + if (content.file !== undefined && this.state.decryptedUrl === null) { + DecryptFile.decryptFile(content.file).then(function(blob) { + if (!self._unmounted) { + self.setState({ + decryptedUrl: window.URL.createObjectURL(blob), + }); + } + }).catch(function (err) { + console.warn("Unable to decrypt attachment: ", err) + // Set a placeholder image when we can't decrypt the image. + self.refs.image.src = "img/warning.svg"; + }); + } + }, + + componentWillUnmount: function() { + this._unmounted = true; + if (this.state.decryptedUrl) { + window.URL.revokeObjectURL(this.state.decryptedUrl); + } + }, + render: function() { var content = this.props.mxEvent.getContent(); - var cli = MatrixClientPeg.get(); - var httpUrl = cli.mxcUrlToHttp(content.url); var text = this.presentableTextForFile(content); var TintableSvg = sdk.getComponent("elements.TintableSvg"); + if (content.file !== undefined && this.state.decryptedUrl === null) { - if (httpUrl) { + // Need to decrypt the attachment + // The attachment is decrypted in componentDidMount. + // For now add an img tag with a spinner. + return ( + + {content.body} + + ); + } + + var contentUrl = this._getContentUrl(); + + if (contentUrl) { if (this.props.tileShape === "file_grid") { return (
- + { content.body && content.body.length > 0 ? content.body : "Attachment" }
@@ -75,7 +127,7 @@ module.exports = React.createClass({ return (