Merge pull request #16 from matrix-org/markjh/end-to-end

Add basic support for end-to-end crypto using olm.
This commit is contained in:
David Baker 2015-07-21 13:21:43 -07:00
commit e03809b224
6 changed files with 101 additions and 4 deletions

View file

@ -25,9 +25,10 @@ module.exports = React.createClass({
mixins: [UnknownMessageTileController], mixins: [UnknownMessageTileController],
render: function() { render: function() {
var content = this.props.mxEvent.getContent();
return ( return (
<span className="mx_UnknownMessageTile"> <span className="mx_UnknownMessageTile">
? {content.body}
</span> </span>
); );
}, },

View file

@ -118,6 +118,12 @@ module.exports = React.createClass({
}) })
}, },
onEncryptChanged: function(ev) {
this.setState({
encrypt: ev.target.checked,
});
},
render: function() { render: function() {
var curr_phase = this.state.phase; var curr_phase = this.state.phase;
if (curr_phase == this.phases.CREATING) { if (curr_phase == this.phases.CREATING) {
@ -142,7 +148,7 @@ module.exports = React.createClass({
<Presets ref="presets" onChange={this.onPresetChanged} preset={this.state.preset}/> <br /> <Presets ref="presets" onChange={this.onPresetChanged} preset={this.state.preset}/> <br />
<label><input type="checkbox" ref="is_private" checked={this.state.is_private} onChange={this.onPrivateChanged}/> Make this room private</label> <label><input type="checkbox" ref="is_private" checked={this.state.is_private} onChange={this.onPrivateChanged}/> Make this room private</label>
<label><input type="checkbox" ref="share_history" checked={this.state.share_history} onChange={this.onShareHistoryChanged}/> Share message history with new users</label> <label><input type="checkbox" ref="share_history" checked={this.state.share_history} onChange={this.onShareHistoryChanged}/> Share message history with new users</label>
<label><input type="checkbox"/> Encrypt room</label> <label><input type="checkbox" ref="encrypt" checked={this.state.encrypt} onChange={this.onEncryptChanged}/> Encrypt room</label>
<CreateRoomButton onCreateRoom={this.onCreateRoom} /> <br /> <CreateRoomButton onCreateRoom={this.onCreateRoom} /> <br />
{error_box} {error_box}
</div> </div>

View file

@ -23,6 +23,16 @@ var matrixClient = null;
var localStorage = window.localStorage; var localStorage = window.localStorage;
function deviceId() {
var id = Math.floor(Math.random()*16777215).toString(16);
id = "W" + "000000".substring(id.length) + id;
if (localStorage) {
id = localStorage.getItem("mx_device_id") || id;
localStorage.setItem("mx_device_id", id);
}
return id;
}
function createClient(hs_url, is_url, user_id, access_token) { function createClient(hs_url, is_url, user_id, access_token) {
var opts = { var opts = {
baseUrl: hs_url, baseUrl: hs_url,
@ -31,6 +41,11 @@ function createClient(hs_url, is_url, user_id, access_token) {
userId: user_id userId: user_id
}; };
if (localStorage) {
opts.sessionStore = new Matrix.WebStorageSessionStore(localStorage);
opts.deviceId = deviceId();
}
matrixClient = Matrix.createClient(opts); matrixClient = Matrix.createClient(opts);
} }

View file

@ -18,6 +18,7 @@ limitations under the License.
var MatrixClientPeg = require("./MatrixClientPeg"); var MatrixClientPeg = require("./MatrixClientPeg");
var dis = require("./dispatcher"); var dis = require("./dispatcher");
var encryption = require("./encryption");
var reject = function(msg) { var reject = function(msg) {
return { return {
@ -42,6 +43,25 @@ var commands = {
return reject("Usage: /nick <display_name>"); return reject("Usage: /nick <display_name>");
}, },
encrypt: function(room_id, args) {
if (args == "on") {
var client = MatrixClientPeg.get();
var members = client.getRoom(room_id).currentState.members;
var user_ids = Object.keys(members);
return success(
encryption.enableEncryption(client, room_id, user_ids)
);
}
if (args == "off") {
var client = MatrixClientPeg.get();
return success(
encryption.disableEncryption(client, room_id)
);
}
return reject("Usage: encrypt <on/off>");
},
// Change the room topic // Change the room topic
topic: function(room_id, args) { topic: function(room_id, args) {
if (args) { if (args) {

View file

@ -19,6 +19,8 @@ limitations under the License.
var React = require("react"); var React = require("react");
var MatrixClientPeg = require("../../MatrixClientPeg"); var MatrixClientPeg = require("../../MatrixClientPeg");
var PresetValues = require('../atoms/create_room/Presets').Presets; var PresetValues = require('../atoms/create_room/Presets').Presets;
var q = require('q');
var encryption = require("../../encryption");
module.exports = { module.exports = {
propTypes: { propTypes: {
@ -97,7 +99,20 @@ module.exports = {
return; return;
} }
var deferred = MatrixClientPeg.get().createRoom(options); var deferred = cli.createRoom(options);
var response;
if (this.state.encrypt) {
deferred = deferred.then(function(res) {
response = res;
return encryption.enableEncryption(
cli, response.roomId, options.invite
);
}).then(function() {
return q(response) }
);
}
this.setState({ this.setState({
phase: this.phases.CREATING, phase: this.phases.CREATING,

40
src/encryption.js Normal file
View file

@ -0,0 +1,40 @@
/*
Copyright 2015 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.
*/
'use strict';
function enableEncyption(client, roomId, members) {
members = members.slice(0);
members.push(client.credentials.userId);
// TODO: Check the keys actually match what keys the user has.
// TODO: Don't redownload keys each time.
return client.downloadKeys(members, "forceDownload").then(function(res) {
return client.setRoomEncryption(roomId, {
algorithm: "m.olm.v1.curve25519-aes-sha2",
members: members,
});
})
}
function disableEncryption(client, roomId) {
return client.disableRoomEncryption(roomId);
}
module.exports = {
enableEncryption: enableEncyption,
disableEncryption: disableEncryption,
}