You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-11-28 05:03:59 +03:00
Initial framework for indexeddb-backed crypto store
Doesn't do anything useful yet - just demonstrates a framework for how I hope it will fit into the sdk.
This commit is contained in:
@@ -1,4 +1,13 @@
|
||||
var matrixcs = require("./lib/matrix");
|
||||
matrixcs.request(require("browser-request"));
|
||||
|
||||
matrixcs.setCryptoStoreFactory(
|
||||
function() {
|
||||
return new matrixcs.IndexedDBCryptoStore(
|
||||
global.indexedDB, "matrix-js-sdk:crypto"
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
module.exports = matrixcs; // keep export for browserify package deps
|
||||
global.matrixcs = matrixcs;
|
||||
|
||||
@@ -160,6 +160,7 @@ function MatrixClient(opts) {
|
||||
opts.sessionStore,
|
||||
userId, this.deviceId,
|
||||
this.store,
|
||||
opts.cryptoStore,
|
||||
);
|
||||
|
||||
this.olmVersion = Crypto.getOlmVersion();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
Copyright 2016 OpenMarket Ltd
|
||||
Copyright 2017 Vector Creations Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -15,7 +16,6 @@ limitations under the License.
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
|
||||
/**
|
||||
* @module crypto
|
||||
*/
|
||||
@@ -50,14 +50,18 @@ const DeviceList = require('./DeviceList').default;
|
||||
* @param {string} deviceId The identifier for this device.
|
||||
*
|
||||
* @param {Object} clientStore the MatrixClient data store.
|
||||
*
|
||||
* @param {module:crypto/store/base~CryptoStore} cryptoStore
|
||||
* storage for the crypto layer.
|
||||
*/
|
||||
function Crypto(baseApis, eventEmitter, sessionStore, userId, deviceId,
|
||||
clientStore) {
|
||||
clientStore, cryptoStore) {
|
||||
this._baseApis = baseApis;
|
||||
this._sessionStore = sessionStore;
|
||||
this._userId = userId;
|
||||
this._deviceId = deviceId;
|
||||
this._clientStore = clientStore;
|
||||
this._cryptoStore = cryptoStore;
|
||||
|
||||
this._olmDevice = new OlmDevice(sessionStore);
|
||||
this._deviceList = new DeviceList(baseApis, sessionStore, this._olmDevice);
|
||||
|
||||
11
src/crypto/store/base.js
Normal file
11
src/crypto/store/base.js
Normal file
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Internal module. Defintions for storage for the crypto module
|
||||
*
|
||||
* @module
|
||||
*/
|
||||
|
||||
/**
|
||||
* Abstraction of things that can store data required for end-to-end encryption
|
||||
*
|
||||
* @interface CryptoStore
|
||||
*/
|
||||
98
src/crypto/store/indexeddb-crypto-store.js
Normal file
98
src/crypto/store/indexeddb-crypto-store.js
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
Copyright 2017 Vector Creations 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.
|
||||
*/
|
||||
|
||||
import q from 'q';
|
||||
|
||||
/**
|
||||
* Internal module. indexeddb storage for e2e.
|
||||
*
|
||||
* @module
|
||||
*/
|
||||
|
||||
const VERSION = 1;
|
||||
|
||||
/**
|
||||
* @implements {module:crypto/store/base~CryptoStore}
|
||||
*/
|
||||
export default class IndexedDBCryptoStore {
|
||||
constructor(indexedDB, dbName) {
|
||||
if (!indexedDB) {
|
||||
throw new Error("must pass indexedDB into IndexedDBCryptoStore");
|
||||
}
|
||||
this._indexedDB = indexedDB;
|
||||
this._dbName = dbName;
|
||||
this._dbPromise = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the database exists and is up-to-date
|
||||
*
|
||||
* @return {Promise} resolves to an instance of IDBDatabase when
|
||||
* the database is ready
|
||||
*/
|
||||
connect() {
|
||||
if (this._dbPromise) {
|
||||
return this._dbPromise;
|
||||
}
|
||||
|
||||
this._dbPromise = new q.Promise((resolve, reject) => {
|
||||
const req = this._indexedDB.open(this._dbName, VERSION);
|
||||
|
||||
req.onupgradeneeded = (ev) => {
|
||||
const db = ev.target.result;
|
||||
const oldVersion = ev.oldVersion;
|
||||
console.log(
|
||||
`Upgrading IndexedDBCryptoStore from version ${oldVersion}`
|
||||
+ ` to ${VERSION}`,
|
||||
);
|
||||
if (oldVersion < 1) { // The database did not previously exist.
|
||||
createDatabase(db);
|
||||
}
|
||||
// Expand as needed.
|
||||
};
|
||||
|
||||
req.onblocked = () => {
|
||||
reject(new Error(
|
||||
"unable to upgrade indexeddb because it is open elsewhere",
|
||||
));
|
||||
};
|
||||
|
||||
req.onerror = (ev) => {
|
||||
reject(new Error(
|
||||
"unable to connect to indexeddb: " + ev.target.error,
|
||||
));
|
||||
};
|
||||
|
||||
req.onsuccess = (r) => {
|
||||
resolve(r.target.result);
|
||||
};
|
||||
});
|
||||
return this._dbPromise;
|
||||
}
|
||||
}
|
||||
|
||||
function createDatabase(db) {
|
||||
const outgoingRoomKeyRequestsStore =
|
||||
db.createObjectStore("outgoingRoomKeyRequests", { keyPath: "requestId" });
|
||||
|
||||
// we assume that the RoomKeyRequestBody will have room_id and session_id
|
||||
// properties, to make the index efficient.
|
||||
outgoingRoomKeyRequestsStore.createIndex("session",
|
||||
["requestBody.room_id", "requestBody.session_id"],
|
||||
);
|
||||
|
||||
outgoingRoomKeyRequestsStore.createIndex("state", "state");
|
||||
}
|
||||
29
src/crypto/store/memory-crypto-store.js
Normal file
29
src/crypto/store/memory-crypto-store.js
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
Copyright 2017 Vector Creations 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Internal module. in-memory storage for e2e.
|
||||
*
|
||||
* @module
|
||||
*/
|
||||
|
||||
/**
|
||||
* @implements {module:crypto/store/base~CryptoStore}
|
||||
*/
|
||||
export default class MemoryCryptoStore {
|
||||
constructor() {
|
||||
}
|
||||
}
|
||||
@@ -63,6 +63,11 @@ module.exports.TimelineWindow = require("./timeline-window").TimelineWindow;
|
||||
module.exports.InteractiveAuth = require("./interactive-auth");
|
||||
|
||||
|
||||
module.exports.MemoryCryptoStore =
|
||||
require("./crypto/store/memory-crypto-store").default;
|
||||
module.exports.IndexedDBCryptoStore =
|
||||
require("./crypto/store/indexeddb-crypto-store").default;
|
||||
|
||||
/**
|
||||
* Create a new Matrix Call.
|
||||
* @function
|
||||
@@ -124,6 +129,19 @@ module.exports.wrapRequest = function(wrapper) {
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
let cryptoStoreFactory = () => new module.exports.MemoryCryptoStore;
|
||||
|
||||
/**
|
||||
* Configure a different factory to be used for creating crypto stores
|
||||
*
|
||||
* @param {Function} fac a funciton which will return a new
|
||||
* {@link module:crypto.store.base~CryptoStore}.
|
||||
*/
|
||||
module.exports.setCryptoStoreFactory = function(fac) {
|
||||
cryptoStoreFactory = fac;
|
||||
};
|
||||
|
||||
/**
|
||||
* Construct a Matrix Client. Similar to {@link module:client~MatrixClient}
|
||||
* except that the 'request', 'store' and 'scheduler' dependencies are satisfied.
|
||||
@@ -136,6 +154,11 @@ module.exports.wrapRequest = function(wrapper) {
|
||||
* {@link module:scheduler~MatrixScheduler}.
|
||||
* @param {requestFunction} opts.request If not set, defaults to the function
|
||||
* supplied to {@link request} which defaults to the request module from NPM.
|
||||
*
|
||||
* @param {module:crypto.store.base~CryptoStore=} opts.cryptoStore
|
||||
* crypto store implementation. Calls the factory supplied to
|
||||
* {@link setCryptoStoreFactory if unspecified}
|
||||
*
|
||||
* @return {MatrixClient} A new matrix client.
|
||||
* @see {@link module:client~MatrixClient} for the full list of options for
|
||||
* <code>opts</code>.
|
||||
@@ -151,6 +174,7 @@ module.exports.createClient = function(opts) {
|
||||
localStorage: global.localStorage,
|
||||
});
|
||||
opts.scheduler = opts.scheduler || new module.exports.MatrixScheduler();
|
||||
opts.cryptoStore = opts.cryptoStore || cryptoStoreFactory();
|
||||
return new module.exports.MatrixClient(opts);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user