cryptobox-hd
Version:
High-level API with persistent storage for Proteus-HD.
232 lines (212 loc) • 8.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var Proteus = require("proteus-hd");
var dexie_1 = require("dexie");
var error_1 = require("./error");
var SerialisedRecord_1 = require("./SerialisedRecord");
var IndexedDB = (function () {
function IndexedDB(identifier) {
var _this = this;
this.prekeys = {};
this.TABLE = {
LOCAL_IDENTITY: "keys",
PRE_KEYS: "prekeys",
SESSIONS: "sessions"
};
this.localIdentityKey = 'local_identity';
if (typeof indexedDB === "undefined") {
var warning = "IndexedDB isn't supported by your platform.";
throw new Error(warning);
}
if (typeof identifier === 'string') {
var schema = {};
schema[this.TABLE.LOCAL_IDENTITY] = '';
schema[this.TABLE.PRE_KEYS] = '';
schema[this.TABLE.SESSIONS] = '';
this.db = new dexie_1.default("cryptobox@" + identifier);
this.db.version(1).stores(schema);
}
else {
this.db = identifier;
}
this.db.on('blocked', function (event) {
_this.db.close();
});
}
IndexedDB.prototype.create = function (store_name, primary_key, entity) {
var _this = this;
return Promise.resolve()
.then(function () {
if (entity) {
return _this.db[store_name].add(entity, primary_key);
}
throw new error_1.RecordTypeError("Entity is \"undefined\" or \"null\". Store name \"" + store_name + "\", Primary Key \"" + primary_key + "\".");
});
};
IndexedDB.prototype.read = function (store_name, primary_key) {
var _this = this;
return Promise.resolve()
.then(function () {
return _this.db[store_name].get(primary_key);
})
.then(function (record) {
if (record) {
return record;
}
var message = "Record \"" + primary_key + "\" from object store \"" + store_name + "\" could not be found.";
throw new error_1.RecordNotFoundError(message);
});
};
IndexedDB.prototype.update = function (store_name, primary_key, changes) {
return this.db[store_name].update(primary_key, changes);
};
IndexedDB.prototype.delete = function (store_name, primary_key) {
var _this = this;
return Promise.resolve()
.then(function () {
return _this.db[store_name].delete(primary_key);
})
.then(function () {
return primary_key;
});
};
IndexedDB.prototype.delete_all = function () {
var _this = this;
return Promise.resolve()
.then(function () {
return _this.db[_this.TABLE.LOCAL_IDENTITY].clear();
})
.then(function () {
return _this.db[_this.TABLE.PRE_KEYS].clear();
})
.then(function () {
return _this.db[_this.TABLE.SESSIONS].clear();
})
.then(function () {
return true;
});
};
IndexedDB.prototype.delete_prekey = function (prekey_id) {
return this.delete(this.TABLE.PRE_KEYS, prekey_id.toString())
.then(function () {
return prekey_id;
});
};
IndexedDB.prototype.delete_session = function (session_id) {
return this.delete(this.TABLE.SESSIONS, session_id)
.then(function (primary_key) {
return primary_key;
});
};
IndexedDB.prototype.load_identity = function () {
return this.read(this.TABLE.LOCAL_IDENTITY, this.localIdentityKey)
.then(function (record) {
return Proteus.keys.IdentityKeyPair.deserialise(record.serialised);
})
.catch(function (error) {
if (error instanceof error_1.RecordNotFoundError) {
return undefined;
}
throw error;
});
};
IndexedDB.prototype.load_prekey = function (prekey_id) {
return this.read(this.TABLE.PRE_KEYS, prekey_id.toString())
.then(function (record) {
return Proteus.keys.PreKey.deserialise(record.serialised);
})
.catch(function (error) {
if (error instanceof error_1.RecordNotFoundError) {
return undefined;
}
throw error;
});
};
IndexedDB.prototype.load_prekeys = function () {
var _this = this;
return Promise.resolve()
.then(function () {
return _this.db[_this.TABLE.PRE_KEYS].toArray();
})
.then(function (records) {
return records.map(function (record) {
return Proteus.keys.PreKey.deserialise(record.serialised);
});
});
};
IndexedDB.prototype.read_session = function (identity, session_id) {
return this.read(this.TABLE.SESSIONS, session_id)
.then(function (payload) {
return Proteus.session.Session.deserialise(identity, payload.serialised);
});
};
IndexedDB.prototype.save_identity = function (identity) {
var _this = this;
var payload = new SerialisedRecord_1.SerialisedRecord(identity.serialise(), this.localIdentityKey);
this.identity = identity;
return this.create(this.TABLE.LOCAL_IDENTITY, payload.id, payload)
.then(function (primaryKey) {
var fingerprint = identity.public_key.fingerprint();
var message = "Saved local identity \"" + fingerprint + "\""
+ (" with key \"" + primaryKey + "\" in object store \"" + _this.TABLE.LOCAL_IDENTITY + "\".");
return identity;
});
};
IndexedDB.prototype.save_prekey = function (prekey) {
var _this = this;
var payload = new SerialisedRecord_1.SerialisedRecord(prekey.serialise(), prekey.key_id.toString());
this.prekeys[prekey.key_id] = prekey;
return this.create(this.TABLE.PRE_KEYS, payload.id, payload)
.then(function (primaryKey) {
var message = "Saved PreKey (ID \"" + prekey.key_id + "\") with key \"" + primaryKey + "\" in object store \"" + _this.TABLE.PRE_KEYS + "\".";
return prekey;
});
};
IndexedDB.prototype.save_prekeys = function (prekeys) {
var _this = this;
if (prekeys.length === 0) {
return Promise.resolve(prekeys);
}
var items = [];
var keys = prekeys.map(function (preKey) {
var key = preKey.key_id.toString();
var payload = new SerialisedRecord_1.SerialisedRecord(preKey.serialise(), key);
items.push(payload);
return key;
});
return Promise.resolve()
.then(function () {
return _this.db[_this.TABLE.PRE_KEYS].bulkPut(items, keys);
})
.then(function () {
return prekeys;
});
};
IndexedDB.prototype.create_session = function (session_id, session) {
var _this = this;
var payload = new SerialisedRecord_1.SerialisedRecord(session.serialise(), session_id);
return this.create(this.TABLE.SESSIONS, payload.id, payload)
.then(function (primaryKey) {
var message = "Added session ID \"" + session_id + "\" in object store \"" + _this.TABLE.SESSIONS + "\" with key \"" + primaryKey + "\".";
return session;
})
.catch(function (error) {
if (error instanceof dexie_1.default.ConstraintError) {
var message = "Session with ID '" + session_id + "' already exists and cannot get overwritten. You need to delete the session first if you want to do it.";
throw new error_1.RecordAlreadyExistsError(message);
}
throw error;
});
};
IndexedDB.prototype.update_session = function (session_id, session) {
var _this = this;
var payload = new SerialisedRecord_1.SerialisedRecord(session.serialise(), session_id);
return this.update(this.TABLE.SESSIONS, payload.id, { serialised: payload.serialised })
.then(function (primaryKey) {
var message = "Updated session ID \"" + session_id + "\" in object store \"" + _this.TABLE.SESSIONS + "\" with key \"" + primaryKey + "\".";
return session;
});
};
return IndexedDB;
}());
exports.default = IndexedDB;