diff --git a/package.json b/package.json
index 7879363451..a7f65919a5 100644
--- a/package.json
+++ b/package.json
@@ -42,7 +42,6 @@
   },
   "dependencies": {
     "babel-runtime": "^6.11.6",
-    "browser-encrypt-attachment": "0.0.0",
     "browser-request": "^0.3.3",
     "classnames": "^2.1.2",
     "draft-js": "^0.8.1",
@@ -55,7 +54,6 @@
     "fuse.js": "^2.2.0",
     "glob": "^5.0.14",
     "highlight.js": "^8.9.1",
-    "isomorphic-fetch": "^2.2.1",
     "linkifyjs": "^2.1.3",
     "lodash": "^4.13.1",
     "marked": "^0.3.5",
diff --git a/src/ContentMessages.js b/src/ContentMessages.js
index 28c28e875e..fd18b22d30 100644
--- a/src/ContentMessages.js
+++ b/src/ContentMessages.js
@@ -23,8 +23,6 @@ var MatrixClientPeg = require('./MatrixClientPeg');
 var sdk = require('./index');
 var Modal = require('./Modal');
 
-var encrypt = require("browser-encrypt-attachment");
-
 function infoForImageFile(imageFile) {
     var deferred = q.defer();
 
@@ -83,24 +81,6 @@ function infoForVideoFile(videoFile) {
     return deferred.promise;
 }
 
-/**
- * Read the file as an ArrayBuffer.
- * @return {Promise} A promise that resolves with an ArrayBuffer when the file
- *   is read.
- */
-function readFileAsArrayBuffer(file) {
-    const deferred = q.defer();
-    const reader = new FileReader();
-    reader.onload = function(e) {
-        deferred.resolve(e.target.result);
-    };
-    reader.onerror = function(e) {
-        deferred.reject(e);
-    };
-    reader.readAsArrayBuffer(file);
-    return deferred.promise;
-}
-
 
 class ContentMessages {
     constructor() {
@@ -157,26 +137,10 @@ class ContentMessages {
         this.inprogress.push(upload);
         dis.dispatch({action: 'upload_started'});
 
-        var encryptInfo = null;
         var error;
         var self = this;
         return def.promise.then(function() {
-            if (matrixClient.isRoomEncrypted(roomId)) {
-                // If the room is encrypted then encrypt the file before uploading it.
-                // First read the file into memory.
-                upload.promise = readFileAsArrayBuffer(file).then(function(data) {
-                    // Then encrypt the file.
-                    return encrypt.encryptAttachment(data);
-                }).then(function(encryptResult) {
-                    // Record the information needed to decrypt the attachment.
-                    encryptInfo = encryptResult.info;
-                    // Pass the encrypted data as a Blob to the uploader.
-                    var blob = new Blob([encryptResult.data]);
-                    return matrixClient.uploadContent(blob);
-                });
-            } else {
-                upload.promise = matrixClient.uploadContent(file);
-            }
+            upload.promise = matrixClient.uploadContent(file);
             return upload.promise;
         }).progress(function(ev) {
             if (ev) {
@@ -185,19 +149,7 @@ class ContentMessages {
                 dis.dispatch({action: 'upload_progress', upload: upload});
             }
         }).then(function(url) {
-            if (encryptInfo === null) {
-                // If the attachment isn't encrypted then include the URL directly.
-                content.url = url;
-            } else {
-                // If the attachment is encrypted then bundle the URL along
-                // with the information needed to decrypt the attachment and
-                // add it under a file key.
-                encryptInfo.url = url;
-                if (file.type) {
-                    encryptInfo.mimetype = file.type;
-                }
-                content.file = encryptInfo;
-            }
+            content.url = url;
             return matrixClient.sendMessage(roomId, content);
         }, function(err) {
             error = err;
diff --git a/src/components/views/messages/MAudioBody.js b/src/components/views/messages/MAudioBody.js
index ff753621c7..6113fa7c6c 100644
--- a/src/components/views/messages/MAudioBody.js
+++ b/src/components/views/messages/MAudioBody.js
@@ -21,67 +21,29 @@ import MFileBody from './MFileBody';
 
 import MatrixClientPeg from '../../../MatrixClientPeg';
 import sdk from '../../../index';
-import { decryptFile } from '../../../utils/DecryptFile';
 
 export default class MAudioBody extends React.Component {
     constructor(props) {
         super(props);
         this.state = {
-            playing: false,
-            decryptedUrl: null,
+            playing: false
         }
     }
+
     onPlayToggle() {
         this.setState({
             playing: !this.state.playing
         });
     }
 
-    _getContentUrl() {
-        const content = this.props.mxEvent.getContent();
-        if (content.file !== undefined) {
-            return this.state.decryptedUrl;
-        } else {
-            return MatrixClientPeg.get().mxcUrlToHttp(content.url);
-        }
-    }
-
-    componentDidMount() {
-        var content = this.props.mxEvent.getContent();
-        if (content.file !== undefined && this.state.decryptedUrl === null) {
-            decryptFile(content.file).done((url) => {
-                this.setState({
-                    decryptedUrl: url
-                });
-            }, (err) => {
-                console.warn("Unable to decrypt attachment: ", err)
-                // Set a placeholder image when we can't decrypt the image.
-                this.refs.image.src = "img/warning.svg";
-            });
-        }
-    }
-
     render() {
-        const content = this.props.mxEvent.getContent();
-
-        if (content.file !== undefined && this.state.decryptedUrl === null) {
-            // Need to decrypt the attachment
-            // The attachment is decrypted in componentDidMount.
-            // For now add an img tag with a spinner.
-            return (
-                <span className="mx_MAudioBody">
-                <img src="img/spinner.gif" ref="image"
-                    alt={content.body} />
-                </span>
-            );
-        }
-
-        const contentUrl = this._getContentUrl();
+        var content = this.props.mxEvent.getContent();
+        var cli = MatrixClientPeg.get();
 
         return (
             <span className="mx_MAudioBody">
-                <audio src={contentUrl} controls />
-                <MFileBody {...this.props} decryptedUrl={this.state.decryptedUrl} />
+                <audio src={cli.mxcUrlToHttp(content.url)} controls />
+                <MFileBody {...this.props} />
             </span>
         );
     }
diff --git a/src/components/views/messages/MFileBody.js b/src/components/views/messages/MFileBody.js
index e8c97e5f44..c37cd32c4e 100644
--- a/src/components/views/messages/MFileBody.js
+++ b/src/components/views/messages/MFileBody.js
@@ -16,22 +16,15 @@ limitations under the License.
 
 'use strict';
 
-import React from 'react';
-import filesize from 'filesize';
-import MatrixClientPeg from '../../../MatrixClientPeg';
-import sdk from '../../../index';
-import {decryptFile} from '../../../utils/DecryptFile';
-
+var React = require('react');
+var filesize = require('filesize');
+var MatrixClientPeg = require('../../../MatrixClientPeg');
+var sdk = require('../../../index');
+var dis = require("../../../dispatcher");
 
 module.exports = React.createClass({
     displayName: 'MFileBody',
 
-    getInitialState: function() {
-        return {
-            decryptedUrl: (this.props.decryptedUrl ? this.props.decryptedUrl : null),
-        };
-    },
-
     presentableTextForFile: function(content) {
         var linkText = 'Attachment';
         if (content.body && content.body.length > 0) {
@@ -54,88 +47,22 @@ module.exports = React.createClass({
         return linkText;
     },
 
-    _getContentUrl: function() {
-        const content = this.props.mxEvent.getContent();
-        if (content.file !== undefined) {
-            return this.state.decryptedUrl;
-        } else {
-            return MatrixClientPeg.get().mxcUrlToHttp(content.url);
-        }
-    },
-
-    componentDidMount: function() {
-        const content = this.props.mxEvent.getContent();
-        if (content.file !== undefined && this.state.decryptedUrl === null) {
-            decryptFile(content.file).done((url) => {
-                this.setState({
-                    decryptedUrl: url,
-                });
-            }, (err) => {
-                console.warn("Unable to decrypt attachment: ", err)
-                // Set a placeholder image when we can't decrypt the image.
-                this.refs.image.src = "img/warning.svg";
-            });
-        }
-    },
-
     render: function() {
-        const content = this.props.mxEvent.getContent();
+        var content = this.props.mxEvent.getContent();
+        var cli = MatrixClientPeg.get();
 
-        const text = this.presentableTextForFile(content);
+        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) {
 
-            // Need to decrypt the attachment
-            // The attachment is decrypted in componentDidMount.
-            // For now add an img tag with a spinner.
-            return (
-                <span className="mx_MFileBody" ref="body">
-                <img src="img/spinner.gif" ref="image"
-                    alt={content.body} />
-                </span>
-            );
-        }
-
-        const contentUrl = this._getContentUrl();
-
-        const 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 (httpUrl) {
             if (this.props.tileShape === "file_grid") {
                 return (
                     <span className="mx_MFileBody">
                         <div className="mx_MImageBody_download">
-                            <a className="mx_ImageBody_downloadLink" href={contentUrl} target="_blank" rel="noopener" download={downloadAttr}>
-                                { fileName }
+                            <a className="mx_ImageBody_downloadLink" href={cli.mxcUrlToHttp(content.url)} target="_blank" rel="noopener">
+                                { content.body && content.body.length > 0 ? content.body : "Attachment" }
                             </a>
                             <div className="mx_MImageBody_size">
                                 { content.info && content.info.size ? filesize(content.info.size) : "" }
@@ -148,7 +75,7 @@ module.exports = React.createClass({
                 return (
                     <span className="mx_MFileBody">
                         <div className="mx_MImageBody_download">
-                            <a href={contentUrl} target="_blank" rel="noopener" download={downloadAttr}>
+                            <a href={cli.mxcUrlToHttp(content.url)} target="_blank" rel="noopener">
                                 <TintableSvg src="img/download.svg" width="12" height="14"/>
                                 Download {text}
                             </a>
diff --git a/src/components/views/messages/MImageBody.js b/src/components/views/messages/MImageBody.js
index 4a3cfce591..526fc6a3a5 100644
--- a/src/components/views/messages/MImageBody.js
+++ b/src/components/views/messages/MImageBody.js
@@ -16,15 +16,14 @@ limitations under the License.
 
 'use strict';
 
-import React from 'react';
-import MFileBody from './MFileBody';
-import MatrixClientPeg from '../../../MatrixClientPeg';
-import ImageUtils from '../../../ImageUtils';
-import Modal from '../../../Modal';
-import sdk from '../../../index';
-import dis from '../../../dispatcher';
-import {decryptFile} from '../../../utils/DecryptFile';
+var React = require('react');
+var filesize = require('filesize');
 
+var MatrixClientPeg = require('../../../MatrixClientPeg');
+var ImageUtils = require('../../../ImageUtils');
+var Modal = require('../../../Modal');
+var sdk = require('../../../index');
+var dis = require("../../../dispatcher");
 
 module.exports = React.createClass({
     displayName: 'MImageBody',
@@ -34,20 +33,13 @@ module.exports = React.createClass({
         mxEvent: React.PropTypes.object.isRequired,
     },
 
-    getInitialState: function() {
-        return {
-            decryptedUrl: null,
-        };
-    },
-
-
     onClick: function onClick(ev) {
         if (ev.button == 0 && !ev.metaKey) {
             ev.preventDefault();
-            const content = this.props.mxEvent.getContent();
-            const httpUrl = this._getContentUrl();
-            const ImageView = sdk.getComponent("elements.ImageView");
-            const params = {
+            var content = this.props.mxEvent.getContent();
+            var httpUrl = MatrixClientPeg.get().mxcUrlToHttp(content.url);
+            var ImageView = sdk.getComponent("elements.ImageView");
+            var params = {
                 src: httpUrl,
                 mxEvent: this.props.mxEvent
             };
@@ -63,7 +55,7 @@ module.exports = React.createClass({
     },
 
     _isGif: function() {
-        const content = this.props.mxEvent.getContent();
+        var content = this.props.mxEvent.getContent();
         return (content && content.info && content.info.mimetype === "image/gif");
     },
 
@@ -72,7 +64,9 @@ module.exports = React.createClass({
             return;
         }
         var imgElement = e.target;
-        imgElement.src = this._getContentUrl();
+        imgElement.src = MatrixClientPeg.get().mxcUrlToHttp(
+            this.props.mxEvent.getContent().url
+        );
     },
 
     onImageLeave: function(e) {
@@ -83,40 +77,14 @@ module.exports = React.createClass({
         imgElement.src = this._getThumbUrl();
     },
 
-    _getContentUrl: function() {
-        const content = this.props.mxEvent.getContent();
-        if (content.file !== undefined) {
-            return this.state.decryptedUrl;
-        } else {
-            return MatrixClientPeg.get().mxcUrlToHttp(content.url);
-        }
-    },
-
     _getThumbUrl: function() {
-        const content = this.props.mxEvent.getContent();
-        if (content.file !== undefined) {
-            // TODO: Decrypt and use the thumbnail file if one is present.
-            return this.state.decryptedUrl;
-        } else {
-            return MatrixClientPeg.get().mxcUrlToHttp(content.url, 800, 600);
-        }
+        var content = this.props.mxEvent.getContent();
+        return MatrixClientPeg.get().mxcUrlToHttp(content.url, 800, 600);
     },
 
     componentDidMount: function() {
         this.dispatcherRef = dis.register(this.onAction);
         this.fixupHeight();
-        const content = this.props.mxEvent.getContent();
-        if (content.file !== undefined && this.state.decryptedUrl === null) {
-            decryptFile(content.file).done((url) => {
-                this.setState({
-                    decryptedUrl: url,
-                });
-            }, (err) => {
-                console.warn("Unable to decrypt attachment: ", err)
-                // Set a placeholder image when we can't decrypt the image.
-                this.refs.image.src = "img/warning.svg";
-            });
-        }
     },
 
     componentWillUnmount: function() {
@@ -135,13 +103,14 @@ module.exports = React.createClass({
             return;
         }
 
-        const content = this.props.mxEvent.getContent();
-        const timelineWidth = this.refs.body.offsetWidth;
-        const maxHeight = 600; // let images take up as much width as they can so long as the height doesn't exceed 600px.
+        var content = this.props.mxEvent.getContent();
+
+        var thumbHeight = null;
+        var timelineWidth = this.refs.body.offsetWidth;
+        var maxHeight = 600; // let images take up as much width as they can so long as the height doesn't exceed 600px.
         // the alternative here would be 600*timelineWidth/800; to scale them down to fit inside a 4:3 bounding box
 
         //console.log("trying to fit image into timelineWidth of " + this.refs.body.offsetWidth + " or " + this.refs.body.clientWidth);
-        var thumbHeight = null;
         if (content.info) {
             thumbHeight = ImageUtils.thumbHeight(content.info.w, content.info.h, timelineWidth, maxHeight);
         }
@@ -150,35 +119,45 @@ module.exports = React.createClass({
     },
 
     render: function() {
-        const TintableSvg = sdk.getComponent("elements.TintableSvg");
-        const content = this.props.mxEvent.getContent();
+        var TintableSvg = sdk.getComponent("elements.TintableSvg");
+        var content = this.props.mxEvent.getContent();
+        var cli = MatrixClientPeg.get();
 
-        if (content.file !== undefined && this.state.decryptedUrl === null) {
-
-            // Need to decrypt the attachment
-            // The attachment is decrypted in componentDidMount.
-            // For now add an img tag with a spinner.
-            return (
-                <span className="mx_MImageBody" ref="body">
-                <img className="mx_MImageBody_thumbnail" src="img/spinner.gif" ref="image"
-                    alt={content.body} />
-                </span>
+        var download;
+        if (this.props.tileShape === "file_grid") {
+            download = (
+                <div className="mx_MImageBody_download">
+                    <a className="mx_MImageBody_downloadLink" href={cli.mxcUrlToHttp(content.url)} 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={cli.mxcUrlToHttp(content.url)} 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>
             );
         }
 
-        const contentUrl = this._getContentUrl();
-        const thumbUrl = this._getThumbUrl();
-
+        var thumbUrl = this._getThumbUrl();
         if (thumbUrl) {
             return (
                 <span className="mx_MImageBody" ref="body">
-                    <a href={contentUrl} onClick={ this.onClick }>
+                    <a href={cli.mxcUrlToHttp(content.url)} onClick={ this.onClick }>
                         <img className="mx_MImageBody_thumbnail" src={thumbUrl} ref="image"
                             alt={content.body}
                             onMouseEnter={this.onImageEnter}
                             onMouseLeave={this.onImageLeave} />
                     </a>
-                    <MFileBody {...this.props} decryptedUrl={this.state.decryptedUrl} />
+                    { download }
                 </span>
             );
         } else if (content.body) {
diff --git a/src/components/views/messages/MVideoBody.js b/src/components/views/messages/MVideoBody.js
index a32348ea1a..d29a3ea53e 100644
--- a/src/components/views/messages/MVideoBody.js
+++ b/src/components/views/messages/MVideoBody.js
@@ -16,24 +16,16 @@ limitations under the License.
 
 'use strict';
 
-import React from 'react';
-import MFileBody from './MFileBody';
-import MatrixClientPeg from '../../../MatrixClientPeg';
-import Model from '../../../Modal';
-import sdk from '../../../index';
-import { decryptFile } from '../../../utils/DecryptFile';
-import q from 'q';
+var React = require('react');
+var filesize = require('filesize');
+
+var MatrixClientPeg = require('../../../MatrixClientPeg');
+var Modal = require('../../../Modal');
+var sdk = require('../../../index');
 
 module.exports = React.createClass({
     displayName: 'MVideoBody',
 
-    getInitialState: function() {
-        return {
-            decryptedUrl: null,
-            decryptedThumbnailUrl: null,
-        };
-    },
-
     thumbScale: function(fullWidth, fullHeight, thumbWidth, thumbHeight) {
         if (!fullWidth || !fullHeight) {
             // Cannot calculate thumbnail height for image: missing w/h in metadata. We can't even
@@ -56,92 +48,59 @@ module.exports = React.createClass({
         }
     },
 
-    _getContentUrl: function() {
-        const content = this.props.mxEvent.getContent();
-        if (content.file !== undefined) {
-            return this.state.decryptedUrl;
-        } else {
-            return MatrixClientPeg.get().mxcUrlToHttp(content.url);
-        }
-    },
-
-    _getThumbUrl: function() {
-        const content = this.props.mxEvent.getContent();
-        if (content.file !== undefined) {
-            return this.state.decryptedThumbnailUrl;
-        } else if (content.info.thumbnail_url) {
-            return MatrixClientPeg.get().mxcUrlToHttp(content.info.thumbnail_url);
-        } else {
-            return null;
-        }
-    },
-
-    componentDidMount: function() {
-        const content = this.props.mxEvent.getContent();
-        if (content.file !== undefined && this.state.decryptedUrl === null) {
-            var thumbnailPromise = q(null);
-            if (content.info.thumbnail_file) {
-                thumbnailPromise = decryptFile(
-                    content.info.thumbnail_file
-                );
-            }
-            thumbnailPromise.then((thumbnailUrl) => {
-                decryptFile(content.file).then((contentUrl) => {
-                    this.setState({
-                        decryptedUrl: contentUrl,
-                        decryptedThumbnailUrl: thumbnailUrl,
-                    });
-                });
-            }).catch((err) => {
-                console.warn("Unable to decrypt attachment: ", err)
-                // Set a placeholder image when we can't decrypt the image.
-                this.refs.image.src = "img/warning.svg";
-            }).done();
-        }
-    },
-
     render: function() {
-        const content = this.props.mxEvent.getContent();
-
-        if (content.file !== undefined && this.state.decryptedUrl === null) {
-            // Need to decrypt the attachment
-            // The attachment is decrypted in componentDidMount.
-            // For now add an img tag with a spinner.
-            return (
-                <span className="mx_MImageBody" ref="body">
-                <img className="mx_MImageBody_thumbnail" src="img/spinner.gif" ref="image"
-                    alt={content.body} />
-                </span>
-            );
-        }
-
-        const contentUrl = this._getContentUrl();
-        const thumbUrl = this._getThumbUrl();
+        var content = this.props.mxEvent.getContent();
+        var cli = MatrixClientPeg.get();
 
         var height = null;
         var width = null;
         var poster = null;
         var preload = "metadata";
         if (content.info) {
-            const scale = this.thumbScale(content.info.w, content.info.h, 480, 360);
+            var scale = this.thumbScale(content.info.w, content.info.h, 480, 360);
             if (scale) {
                 width = Math.floor(content.info.w * scale);
                 height = Math.floor(content.info.h * scale);
             }
 
-            if (thumbUrl) {
-                poster = thumbUrl;
+            if (content.info.thumbnail_url) {
+                poster = cli.mxcUrlToHttp(content.info.thumbnail_url);
                 preload = "none";
             }
         }
 
+        var download;
+        if (this.props.tileShape === "file_grid") {
+            download = (
+                <div className="mx_MImageBody_download">
+                    <a className="mx_MImageBody_downloadLink" href={cli.mxcUrlToHttp(content.url)} 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={cli.mxcUrlToHttp(content.url)} 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 (
             <span className="mx_MVideoBody">
-                <video className="mx_MVideoBody" src={contentUrl} alt={content.body}
+                <video className="mx_MVideoBody" src={cli.mxcUrlToHttp(content.url)} alt={content.body}
                     controls preload={preload} autoPlay={false}
                     height={height} width={width} poster={poster}>
                 </video>
-                <MFileBody {...this.props} decryptedUrl={this.state.decryptedUrl} />
+                { download }
             </span>
         );
     },
diff --git a/src/utils/DecryptFile.js b/src/utils/DecryptFile.js
deleted file mode 100644
index 38eab1d073..0000000000
--- a/src/utils/DecryptFile.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
-Copyright 2016 OpenMarket Ltd
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-// Pull in the encryption lib so that we can decrypt attachments.
-import encrypt from 'browser-encrypt-attachment';
-// Pull in a fetch polyfill so we can download encrypted attachments.
-import 'isomorphic-fetch';
-// Grab the client so that we can turn mxc:// URLs into https:// URLS.
-import MatrixClientPeg from '../MatrixClientPeg';
-import q from 'q';
-
-
-/**
- * Read blob as a data:// URI.
- * @return {Promise} A promise that resolves with the data:// URI.
- */
-function readBlobAsDataUri(file) {
-    var deferred = q.defer();
-    var reader = new FileReader();
-    reader.onload = function(e) {
-        deferred.resolve(e.target.result);
-    };
-    reader.onerror = function(e) {
-        deferred.reject(e);
-    };
-    reader.readAsDataURL(file);
-    return deferred.promise;
-}
-
-
-/**
- * Decrypt a file attached to a matrix event.
- * @param file {Object} The json taken from the matrix event.
- *   This passed to [link]{@link https://github.com/matrix-org/browser-encrypt-attachments}
- *   as the encryption info object, so will also have the those keys in addition to
- *   the keys below.
- * @param file.url {string} An mxc:// URL for the encrypted file.
- * @param file.mimetype {string} The MIME-type of the plaintext file.
- */
-export function decryptFile(file) {
-    const url = MatrixClientPeg.get().mxcUrlToHttp(file.url);
-    // Download the encrypted file as an array buffer.
-    return q(fetch(url)).then(function(response) {
-        return response.arrayBuffer();
-    }).then(function(responseData) {
-        // Decrypt the array buffer using the information taken from
-        // the event content.
-        return encrypt.decryptAttachment(responseData, file);
-    }).then(function(dataArray) {
-        // Turn the array into a Blob and give it the correct MIME-type.
-        var blob = new Blob([dataArray], {type: file.mimetype});
-        return readBlobAsDataUri(blob);
-    });
-}