Encrypt attachments in encrypted rooms, decrypt image attachments when displaying them

This commit is contained in:
Mark Haines 2016-11-02 16:26:10 +00:00
parent a6417c287f
commit e0cea74c7e
3 changed files with 91 additions and 3 deletions

View file

@ -23,6 +23,8 @@ 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();
@ -81,6 +83,24 @@ 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) {
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.readAsArrayBuffer(file);
return deferred.promise;
}
class ContentMessages {
constructor() {
@ -137,10 +157,26 @@ class ContentMessages {
this.inprogress.push(upload);
dis.dispatch({action: 'upload_started'});
var encryptInfo = null;
var error;
var self = this;
return def.promise.then(function() {
upload.promise = matrixClient.uploadContent(file);
if (matrixClient.isRoomEncrypted(room_id)) {
// 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);
}
return upload.promise;
}).progress(function(ev) {
if (ev) {
@ -149,7 +185,16 @@ class ContentMessages {
dis.dispatch({action: 'upload_progress', upload: upload});
}
}).then(function(url) {
content.url = 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;
content.file = encryptInfo;
}
return matrixClient.sendMessage(roomId, content);
}, function(err) {
error = err;