nativescript-libsignal-protocol
Version:
A Libsignal-Protocol wrapper for NativeScript.
958 lines • 46.2 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var LibsignalProtocol;
(function (LibsignalProtocol) {
var MemorySignalProtocolStore = (function () {
function MemorySignalProtocolStore(identityKeyPair, registrationId) {
this.Direction = {
SENDING: 1,
RECEIVING: 2,
};
this.MemoryStore = new org.whispersystems.libsignal.state.impl.InMemorySignalProtocolStore(identityKeyPair, registrationId);
}
MemorySignalProtocolStore.prototype.getIdentityKeyPair = function () {
return this.MemoryStore.getIdentityKeyPair();
};
MemorySignalProtocolStore.prototype.getLocalRegistrationId = function () {
return this.MemoryStore.getLocalRegistrationId();
};
MemorySignalProtocolStore.prototype.saveIdentity = function (address, identityKey) {
return this.MemoryStore.saveIdentity(address, identityKey);
};
MemorySignalProtocolStore.prototype.isTrustedIdentity = function (address, identityKey, direction) {
return this.MemoryStore(address, identityKey, direction);
};
MemorySignalProtocolStore.prototype.getIdentity = function (address) {
return this.MemoryStore.getIdentity(address);
};
MemorySignalProtocolStore.prototype.loadPreKey = function (preKeyId) {
return this.MemoryStore.loadPreKey(preKeyId);
};
MemorySignalProtocolStore.prototype.storePreKey = function (preKeyId, record) {
return this.MemoryStore.storePreKey(preKeyId, record);
};
MemorySignalProtocolStore.prototype.containsPreKey = function (preKeyId) {
return this.MemoryStore.containsPreKey(preKeyId);
};
MemorySignalProtocolStore.prototype.removePreKey = function (preKeyId) {
return this.MemoryStore.removePreKey(preKeyId);
};
MemorySignalProtocolStore.prototype.loadSession = function (address) {
return this.MemoryStore.loadSession(address);
};
MemorySignalProtocolStore.prototype.getSubDeviceSessions = function (name) {
return this.MemoryStore.getSubDeviceSessions(name);
};
MemorySignalProtocolStore.prototype.storeSession = function (address, record) {
return this.MemoryStore.storeSession(address, record);
};
MemorySignalProtocolStore.prototype.containsSession = function (address) {
return this.MemoryStore.containsSession(address);
};
MemorySignalProtocolStore.prototype.deleteSession = function (address) {
return this.MemoryStore.deleteSession(address);
};
MemorySignalProtocolStore.prototype.deleteAllSessions = function (name) {
return this.MemoryStore.deleteAllSessions(name);
};
MemorySignalProtocolStore.prototype.loadSignedPreKey = function (signedPreKeyId) {
return this.MemoryStore.loadSignedPreKey(signedPreKeyId);
};
MemorySignalProtocolStore.prototype.loadSignedPreKeys = function () {
return this.MemoryStore.loadSignedPreKeys();
};
MemorySignalProtocolStore.prototype.storeSignedPreKey = function (signedPreKeyId, record) {
return this.MemoryStore.storeSignedPreKey(signedPreKeyId, record);
};
MemorySignalProtocolStore.prototype.containsSignedPreKey = function (signedPreKeyId) {
return this.MemoryStore.containsSignedPreKey(signedPreKeyId);
};
MemorySignalProtocolStore.prototype.removeSignedPreKey = function (signedPreKeyId) {
return this.MemoryStore.removeSignedPreKey(signedPreKeyId);
};
return MemorySignalProtocolStore;
}());
LibsignalProtocol.MemorySignalProtocolStore = MemorySignalProtocolStore;
var SessionCipher = (function () {
function SessionCipher(store, remoteAddress) {
this.CipherStore = new org.whispersystems.libsignal.SessionCipher(store, remoteAddress);
}
SessionCipher.prototype.encrypt = function (paddedMessage) {
return this.CipherStore.encrypt(paddedMessage);
};
SessionCipher.prototype.decrypt = function (ciphertext, callback) {
if (typeof callback === 'undefined')
return this.CipherStore.decrypt(ciphertext, callback);
return this.CipherStore.decrypt(ciphertext);
};
return SessionCipher;
}());
LibsignalProtocol.SessionCipher = SessionCipher;
var InMemorySignalProtocolStore = (function () {
function InMemorySignalProtocolStore() {
this.store = {};
this.Direction = {
SENDING: 1,
RECEIVING: 2,
};
}
InMemorySignalProtocolStore.prototype.getIdentityKeyPair = function () {
return Promise.resolve(this.get('identityKey'));
};
InMemorySignalProtocolStore.prototype.getLocalRegistrationId = function () {
return Promise.resolve(this.get('registrationId'));
};
InMemorySignalProtocolStore.prototype.put = function (key, value) {
if (key === undefined || value === undefined || key === null || value === null)
throw new Error('Tried to store undefined/null');
this.store[key] = value;
};
InMemorySignalProtocolStore.prototype.get = function (key, defaultValue) {
if (key === null || key === undefined)
throw new Error('Tried to get value for undefined/null key');
if (key in this.store) {
return this.store[key];
}
else {
return defaultValue;
}
};
InMemorySignalProtocolStore.prototype.remove = function (key) {
if (key === null || key === undefined)
throw new Error('Tried to remove value for undefined/null key');
delete this.store[key];
};
InMemorySignalProtocolStore.prototype.isTrustedIdentity = function (identifier, identityKey, direction) {
if (identifier === null || identifier === undefined) {
throw new Error('tried to check identity key for undefined/null key');
}
if (!(identityKey instanceof ArrayBuffer)) {
throw new Error('Expected identityKey to be an ArrayBuffer');
}
var trusted = this.get('identityKey' + identifier);
if (trusted === undefined) {
return Promise.resolve(true);
}
return Promise.resolve(LibsignalProtocol.Util.isEqualString(identityKey, trusted));
};
InMemorySignalProtocolStore.prototype.loadIdentityKey = function (identifier) {
if (identifier === null || identifier === undefined)
throw new Error('Tried to get identity key for undefined/null key');
return Promise.resolve(this.get('identityKey' + identifier));
};
InMemorySignalProtocolStore.prototype.saveIdentity = function (identifier, identityKey) {
if (identifier === null || identifier === undefined)
throw new Error('Tried to put identity key for undefined/null key');
if (typeof identifier !== 'string' || !identifier.match(/.*\.\d+/)) {
throw new Error('Invalid SignalProtocolAddress string');
}
var parts = identifier.split('.');
var address = new org.whispersystems.libsignal.SignalProtocolAddress(parts[0], parseInt(parts[1]));
var existing = this.get('identityKey' + address.getName());
this.put('identityKey' + address.getName(), identityKey);
if (existing && !LibsignalProtocol.Util.isEqualString(identityKey, existing)) {
return Promise.resolve(true);
}
else {
return Promise.resolve(false);
}
};
InMemorySignalProtocolStore.prototype.loadPreKey = function (keyId) {
var res = this.get('25519KeypreKey' + keyId);
if (res !== undefined) {
res = { pubKey: res.pubKey, privKey: res.privKey };
}
return Promise.resolve(res);
};
InMemorySignalProtocolStore.prototype.storePreKey = function (keyId, keyPair) {
return Promise.resolve(this.put('25519KeypreKey' + keyId, keyPair));
};
InMemorySignalProtocolStore.prototype.removePreKey = function (keyId) {
return Promise.resolve(this.remove('25519KeypreKey' + keyId));
};
InMemorySignalProtocolStore.prototype.loadSignedPreKey = function (keyId) {
var res = this.get('25519KeysignedKey' + keyId);
if (res !== undefined) {
res = { pubKey: res.pubKey, privKey: res.privKey };
}
return Promise.resolve(res);
};
InMemorySignalProtocolStore.prototype.storeSignedPreKey = function (keyId, keyPair) {
return Promise.resolve(this.put('25519KeysignedKey' + keyId, keyPair));
};
InMemorySignalProtocolStore.prototype.removeSignedPreKey = function (keyId) {
return Promise.resolve(this.remove('25519KeysignedKey' + keyId));
};
InMemorySignalProtocolStore.prototype.loadSession = function (identifier) {
return Promise.resolve(this.get('session' + identifier));
};
InMemorySignalProtocolStore.prototype.storeSession = function (identifier, record) {
return Promise.resolve(this.put('session' + identifier, record));
};
InMemorySignalProtocolStore.prototype.removeSession = function (identifier) {
return Promise.resolve(this.remove('session' + identifier));
};
InMemorySignalProtocolStore.prototype.removeAllSessions = function (identifier) {
for (var id in this.store) {
if (id.startsWith('session' + identifier)) {
delete this.store[id];
}
}
return Promise.resolve();
};
return InMemorySignalProtocolStore;
}());
LibsignalProtocol.InMemorySignalProtocolStore = InMemorySignalProtocolStore;
var Util = (function () {
function Util() {
}
Util.base64Encode = function (mixed) {
return android.util.Base64.encodeToString(mixed, android.util.Base64.NO_WRAP);
};
Util.base64Decode = function (base64Str) {
return android.util.Base64.decode(base64Str, android.util.Base64.NO_WRAP);
};
Util.base64ToArrayBuffer = function (base64) {
var binary_string = Util.atob(base64);
var len = binary_string.length;
var bytes = new Uint8Array(len);
for (var i = 0; i < len; i++) {
bytes[i] = binary_string.charCodeAt(i);
}
return bytes.buffer;
};
Util.arrayBufferToBase64 = function (buffer) {
var binary = '';
var bytes = new Uint8Array(buffer);
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
binary += String.fromCharCode(bytes[i]);
}
return Util.btoa(binary);
};
Util.atob = function (str) {
var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", b64re = /^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/;
str = String(str).replace(/[\t\n\f\r ]+/g, "");
if (!b64re.test(str))
throw new TypeError("Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.");
str += "==".slice(2 - (str.length & 3));
var bitmap, result = "", r1, r2, i = 0;
for (; i < str.length;) {
bitmap = b64.indexOf(str.charAt(i++)) << 18 | b64.indexOf(str.charAt(i++)) << 12
| (r1 = b64.indexOf(str.charAt(i++))) << 6 | (r2 = b64.indexOf(str.charAt(i++)));
result += r1 === 64 ? String.fromCharCode(bitmap >> 16 & 255)
: r2 === 64 ? String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255)
: String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255, bitmap & 255);
}
return result;
};
;
Util.btoa = function (str) {
var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", b64re = /^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/;
str = String(str);
var bitmap, a, b, c, result = "", i = 0, rest = str.length % 3;
for (; i < str.length;) {
if ((a = str.charCodeAt(i++)) > 255
|| (b = str.charCodeAt(i++)) > 255
|| (c = str.charCodeAt(i++)) > 255)
throw new TypeError("Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.");
bitmap = (a << 16) | (b << 8) | c;
result += b64.charAt(bitmap >> 18 & 63) + b64.charAt(bitmap >> 12 & 63)
+ b64.charAt(bitmap >> 6 & 63) + b64.charAt(bitmap & 63);
}
return rest ? result.slice(0, rest - 3) + "===".substring(rest) : result;
};
;
Util.toString = function (value) {
try {
if (value === null)
return '';
else if (typeof value === 'string')
return value;
else if (typeof value === 'number')
return Number(value).toString();
else if (typeof value === 'function')
return value.toString();
else if (typeof value === 'object') {
if (value.hasOwnProperty('length'))
return value.toString();
else
return JSON.stringify(value);
}
else
return java.lang.String.valueOf(value);
}
catch (err) {
console.log("Unable to convert value.toString");
return '';
}
};
Util.isEqualString = function (value, compared) {
return !!(LibsignalProtocol.Util.toString(value) === LibsignalProtocol.Util.toString(compared));
};
return Util;
}());
LibsignalProtocol.Util = Util;
var Core = (function () {
function Core() {
}
Core.importPreKeyRecord = function (serialized) {
try {
return new org.whispersystems.libsignal.state.PreKeyRecord(serialized);
}
catch (err) {
console.log('ERROR -- Unable to import PreKeyRecord');
console.log(err.message ? err.message : '...');
}
return null;
};
Core.importSignedPreKeyRecord = function (serialized) {
try {
return new org.whispersystems.libsignal.state.SignedPreKeyRecord(serialized);
}
catch (err) {
console.log('ERROR -- Unable to import SignedPreKeyRecord');
console.log(err.message ? err.message : '...');
}
return null;
};
Core.importSignedPreKey = function (serialized) {
return new org.whispersystems.libsignal.state.SignedPreKeyRecord(serialized);
};
Core.importIdentityKey = function (serialized) {
try {
return new org.whispersystems.libsignal.IdentityKey(serialized, 0);
}
catch (err) {
console.log('ERROR -- Unable to import IdentityKey');
console.log(err.message ? err.message : '...');
}
return null;
};
Core.importIdentityKeyPair = function (serialized) {
try {
return new org.whispersystems.libsignal.IdentityKeyPair(serialized);
}
catch (err) {
console.log('ERROR -- Unable to import IdentityKeyPair');
console.log(err.message ? err.message : '...');
}
return null;
};
Core.importPublicKey = function (serialized) {
try {
return org.whispersystems.libsignal.ecc.Curve.decodePoint(serialized, 0);
}
catch (err) {
console.log('ERROR -- Unable to import ECPublicKey');
console.log(err.message ? err.message : '...');
}
return null;
};
Core.createPreKeySignalMessage = function (serialized) {
try {
return new org.whispersystems.libsignal.protocol.PreKeySignalMessage(serialized);
}
catch (err) {
console.log('ERROR -- Unable to create PreKeySignalMessage');
}
return null;
};
Core.createSignalMessage = function (serialized) {
try {
return new org.whispersystems.libsignal.protocol.SignalMessage(serialized);
}
catch (err) {
console.log('ERROR -- Unable to create SignalMessage');
console.log(err.message ? err.message : '...');
}
return null;
};
Core.createPreKeyRecord = function (id, keyPair) {
return new org.whispersystems.libsignal.state.PreKeyRecord(id, keyPair);
};
Core.createSignedPreKeyRecord = function (id, timestamp, keyPair, signature) {
return new org.whispersystems.libsignal.state.SignedPreKeyRecord(id, timestamp, keyPair, signature);
};
Core.createSignalProtocolStore = function (identityKeyPair, registrationId) {
return new org.whispersystems.libsignal.state.impl.InMemorySignalProtocolStore(identityKeyPair, registrationId);
};
Core.createTestSignalProtocolStore = function () {
function generateRegistrationId() {
return org.whispersystems.libsignal.util.KeyHelper.generateRegistrationId(false);
}
function generateIdentityKeyPair() {
var keyPair = Curve.generateKeyPair();
var publicKey = new org.whispersystems.libsignal.IdentityKey(keyPair.getPublicKey());
return new org.whispersystems.libsignal.IdentityKeyPair(publicKey, keyPair.getPrivateKey());
}
return new org.whispersystems.libsignal.state.impl.InMemorySignalProtocolStore(generateIdentityKeyPair(), generateRegistrationId());
};
Core.createIdentityKeyPair = function (publicKey, privateKey) {
return new org.whispersystems.libsignal.IdentityKeyPair(publicKey, privateKey);
};
Core.createIdentityKey = function (publicKey) {
return new org.whispersystems.libsignal.IdentityKey(publicKey);
};
Core.createSessionBuilder = function (store, address) {
try {
return new org.whispersystems.libsignal.SessionBuilder(store, address);
}
catch (err) {
console.log('ERROR -- Unable to create SessionBuilder');
console.log(err.message ? err.message : '...');
}
return null;
};
Core.createSessionCipher = function (store, address) {
return new org.whispersystems.libsignal.SessionCipher(store, address);
};
Core.createMemorySignalProtocolStore = function (identityKeyPair, registrationId) {
return new org.whispersystems.libsignal.state.impl.InMemorySignalProtocolStore(identityKeyPair, registrationId);
};
Core.createSessionRecord = function () {
return new org.whispersystems.libsignal.state.SessionRecord();
};
Core.createSignalProtocolAddress = function (registrationId, deviceId) {
try {
return new org.whispersystems.libsignal.SignalProtocolAddress(registrationId + '', deviceId);
}
catch (err) {
console.log('ERROR -- Unable to create SignalProtocolAddress');
console.log(err.message ? err.message : '...');
}
return null;
};
Core.createPreKeyBundle = function (registrationId, deviceId, preKeyId, preKeyPublic, signedPreKeyId, signedPreKeyPublic, signedPreKeySignature, identityKey) {
try {
return new org.whispersystems.libsignal.state.PreKeyBundle(registrationId, deviceId, preKeyId, preKeyPublic, signedPreKeyId, signedPreKeyPublic, signedPreKeySignature, identityKey);
}
catch (err) {
console.log('ERROR -- Unable to create PreKeyBundle');
console.log(err.message ? err.message : '...');
}
return null;
};
return Core;
}());
LibsignalProtocol.Core = Core;
var Curve = (function () {
function Curve() {
}
Curve.generateKeyPair = function () {
try {
return new org.whispersystems.libsignal.ecc.Curve.generateKeyPair();
}
catch (err) {
console.log('ERROR -- Unable to generate KeyPair');
console.log(err.message ? err.message : '...');
}
return null;
};
Curve.calculateSignature = function (signingKey, message) {
try {
return new org.whispersystems.libsignal.ecc.Curve.calculateSignature(signingKey, message);
}
catch (err) {
console.log('ERROR -- Unable to calculate signature');
console.log(err.message ? err.message : '...');
}
return null;
};
return Curve;
}());
LibsignalProtocol.Curve = Curve;
var KeyHelper = (function () {
function KeyHelper() {
}
KeyHelper.generateRegistrationId = function (extendedRange) {
if (typeof extendedRange === 'undefined')
extendedRange = false;
return org.whispersystems.libsignal.util.KeyHelper.generateRegistrationId(extendedRange);
};
KeyHelper.generateIdentityKeyPair = function () {
try {
return org.whispersystems.libsignal.util.KeyHelper.generateIdentityKeyPair();
}
catch (err) {
console.log('ERROR -- Unable to generate IdentityKeyPair');
console.log(err.message ? err.message : '...');
}
return null;
};
KeyHelper.generateIdentityKeyPairFormatted = function () {
try {
var IDKeyPair = org.whispersystems.libsignal.util.KeyHelper.generateIdentityKeyPair();
return {
pubKey: Util.base64Encode(IDKeyPair.getPublicKey().serialize()),
privKey: Util.base64Encode(IDKeyPair.getPrivateKey().serialize()),
};
}
catch (err) {
console.log('ERROR -- Unable to generate IdentityKeyPairFormatted');
console.log(err.message ? err.message : '...');
}
return null;
};
KeyHelper.generateKeyPair = function (pubKey, privKey) {
return new org.whispersystems.libsignal.ecc.ECKeyPair(pubKey, privKey);
};
KeyHelper.importIdentityKeyPair = function (serialized) {
return new org.whispersystems.libsignal.IdentityKeyPair(serialized);
};
KeyHelper.importSignedPreKeyRecord = function (serialized) {
return new org.whispersystems.libsignal.state.SignedPreKeyRecord(serialized);
};
KeyHelper.importSignalProtocolAddress = function (name, deviceId) {
return new org.whispersystems.libsignal.SignalProtocolAddress(name, deviceId);
};
KeyHelper.generatePreKeys = function (start, count) {
try {
return org.whispersystems.libsignal.util.KeyHelper.generatePreKeys(start, count);
}
catch (err) {
console.log('ERROR -- Unable to generate PreKeyBundle');
console.log(err.message ? err.message : '...');
}
return null;
};
KeyHelper.generatePreKeysFormatted = function (start, count) {
try {
var result = [];
var preKeys = org.whispersystems.libsignal.util.KeyHelper.generatePreKeys(start, count);
for (var i = 0; i < preKeys.size(); i++) {
var key = preKeys.get(i);
var keyPair = key.getKeyPair();
result.push({
keyId: key.getId(),
keyPair: {
pubKey: Util.base64Encode(keyPair.getPublicKey().serialize()),
privKey: Util.base64Encode(keyPair.getPrivateKey().serialize())
},
serialized: Util.base64Encode(key.serialize())
});
}
return result;
}
catch (err) {
console.log('ERROR -- Unable to generate PreKeyBundleFormatted');
console.log(err.message ? err.message : '...');
}
return null;
};
KeyHelper.generateLastResortPreKeyRecord = function () {
var keyPair = Curve.generateKeyPair();
return new org.whispersystems.libsignal.state.PreKeyRecord(0xFFFFFF, keyPair);
};
KeyHelper.generateSignedPreKey = function (identityKeyPair, signedPreKeyId) {
try {
return org.whispersystems.libsignal.util.KeyHelper.generateSignedPreKey(identityKeyPair, signedPreKeyId);
}
catch (err) {
console.log('ERROR -- Unable to generate SignedPreKey');
console.log(err.message ? err.message : '...');
}
return null;
};
KeyHelper.generateSignedPreKeyFormatted = function (identityKeyPair, signedPreKeyId) {
try {
var signedPreKey = org.whispersystems.libsignal.util.KeyHelper.generateSignedPreKey(identityKeyPair, signedPreKeyId);
return {
keyId: signedPreKey.getId(),
keyPair: {
pubKey: Util.base64Encode(signedPreKey.getKeyPair().getPublicKey().serialize()),
privKey: Util.base64Encode(signedPreKey.getKeyPair().getPrivateKey().serialize()),
},
signature: Util.base64Encode(signedPreKey.getSignature())
};
}
catch (err) {
console.log('ERROR -- Unable to generate SignedPreKey');
console.log(err.message ? err.message : '...');
}
return null;
};
KeyHelper.verifySignedPreKey = function (signingKey, message, signature) {
return org.whispersystems.libsignal.ecc.Curve.verifySignature(signingKey, message, signature);
};
return KeyHelper;
}());
LibsignalProtocol.KeyHelper = KeyHelper;
var ClientInfo = (function () {
function ClientInfo(identityKey, registrationId, deviceId, preKeys, signedPreKeyId, signedPreKey, signedPreKeySignature) {
this.identityKey = identityKey;
this.registrationId = registrationId;
this.deviceId = deviceId;
this.preKeys = preKeys;
this.signedPreKeyId = signedPreKeyId;
this.signedPreKey = signedPreKey;
this.signedPreKeySignature = signedPreKeySignature;
}
ClientInfo.prototype.fetchPreKey = function (preKeyIndex) {
var preKey = this.preKeys.splice(preKeyIndex, 1);
return preKey[0];
};
ClientInfo.prototype.getPreKeyBundle = function () {
var random = new java.util.Random();
var preKeyIds = Object.keys(this.preKeys);
var preKeyIndex = preKeyIds[random.nextInt(preKeyIds.length)];
var preKey = this.fetchPreKey(preKeyIndex);
return {
registrationId: this.registrationId,
deviceId: this.deviceId,
preKeyPublic: preKey.pubKey,
preKeyRecordId: preKey.id,
signedPreKeyPublic: this.signedPreKey,
signedPreKeyRecordId: this.signedPreKeyId,
signature: this.signedPreKeySignature,
identityPubKey: this.identityKey
};
};
return ClientInfo;
}());
LibsignalProtocol.ClientInfo = ClientInfo;
var Client = (function () {
function Client(clientName, registrationId, deviceId, identityKeyPairStr, signedPreKeyStr, importedPreKeys, contacts) {
this.username = clientName;
this.deviceId = deviceId;
this.registrationId = registrationId;
this.random = new java.util.Random();
this.contacts = [];
this.preKeys = [];
this.identityKeyPair;
this.signedPreKey;
this.createAddress();
this.createIdentityKeyPair(identityKeyPairStr);
this.createSignedPreKey(signedPreKeyStr);
this.store = Core.createMemorySignalProtocolStore(this.identityKeyPair, this.registrationId);
this.store.storeSignedPreKey(this.signedPreKey.getId(), this.signedPreKey);
var lastResortPreKeyRecord = KeyHelper.generateLastResortPreKeyRecord();
this.store.storePreKey(lastResortPreKeyRecord.getId(), lastResortPreKeyRecord);
this.createPreKeys(importedPreKeys);
this.createContacts(contacts);
}
Client.prototype.hasContact = function (contactName) {
var contactIndex = this.contacts.findIndex(function (contact) {
return !!(contact.name === contactName);
});
return !!(contactIndex >= 0);
};
Client.prototype.getContact = function (contactName) {
return this.contacts.find(function (contact) {
return !!(contact.name === contactName);
});
};
Client.prototype.getContactIndex = function (contactName) {
return this.contacts.findIndex(function (contact) {
return !!(contact.name === contactName);
});
};
Client.prototype.getSessionRecord = function (contactName) {
if (!this.hasContact(contactName))
return false;
var contact = this.getContact(contactName);
return this.store.loadSession(contact.signalAddress);
};
Client.prototype.hasSession = function (contactName) {
if (!this.hasContact(contactName))
return false;
var contact = this.getContact(contactName);
return !!(this.store.containsSession(contact.signalAddress));
};
Client.prototype.hasPreKey = function (preKeyId) {
return !!(this.store.containsPreKey(preKeyId));
};
Client.prototype.hasSignedPreKey = function (signedPreKeyId) {
return !!(this.store.containsSignedPreKey(signedPreKeyId));
};
Client.prototype.generatePreKeyBatch = function (startFrom) {
var _this = this;
if (typeof startFrom === 'undefined')
startFrom = this.random.nextInt(0xFFFFFF - 101);
var preKeys = KeyHelper.generatePreKeysFormatted(startFrom, 100);
preKeys.forEach(function (preKey) {
try {
_this.preKeys.push({
id: preKey.keyId,
pubKey: preKey.keyPair.pubKey,
serialized: preKey.serialized
});
var preKeyRecord = Core.importPreKeyRecord(Util.base64Decode(preKey.serialized));
_this.store.storePreKey(preKeyRecord.getId(), preKeyRecord);
}
catch (err) {
console.log('Unable to import prekey batch');
console.log(err);
}
});
return preKeys.map(function (preKey) {
return {
id: preKey.keyId,
pubKey: preKey.keyPair.pubKey,
serialized: preKey.serialized
};
});
};
Client.prototype.importPreKeys = function (preKeys) {
return __awaiter(this, void 0, void 0, function () {
var _this = this;
return __generator(this, function (_a) {
if (typeof preKeys === 'undefined') {
console.log('No prekeys provided to import!');
return [2, false];
}
preKeys.forEach(function (_key) {
var preKeyRecord = Core.importPreKeyRecord(Util.base64Decode(_key.serialized));
var keyPair = preKeyRecord.getKeyPair();
_this.preKeys.push({
id: preKeyRecord.getId(),
pubKey: Util.base64Encode(keyPair.getPublicKey().serialize()),
serialized: Util.base64Encode(preKeyRecord.serialize())
});
_this.store.storePreKey(preKeyRecord.getId(), preKeyRecord);
});
return [2, true];
});
});
};
Client.prototype.exportRegistrationObj = function () {
return {
address: {
name: this.address.getName(),
deviceId: this.address.getDeviceId(),
registrationId: this.store.getLocalRegistrationId()
},
identityPubKey: Util.base64Encode(this.store.getIdentityKeyPair().getPublicKey().serialize()),
signedPreKey: {
id: this.signedPreKey.getId(),
pubKey: Util.base64Encode(this.signedPreKey.getKeyPair().getPublicKey().serialize()),
signature: Util.base64Encode(this.signedPreKey.getSignature())
},
preKeys: this.preKeys.map(function (key) {
return {
id: key.id,
pubKey: key.pubKey
};
})
};
};
Client.prototype.addSession = function (contact, contactBundle) {
try {
var signalAddress = Core.createSignalProtocolAddress(contact.registrationId, contact.deviceId);
var preKeyBundle = this.importPreKeyBundle(signalAddress, contactBundle);
var sessionBuilder = Core.createSessionBuilder(this.store, signalAddress);
sessionBuilder.process(preKeyBundle);
var sessionCipher = Core.createSessionCipher(this.store, signalAddress);
if (this.hasContact(contact.name)) {
console.log('updating contact');
var nContact = this.getContactIndex(contact.name);
this.contacts[nContact].sessionCipher = sessionCipher;
}
else {
console.log('creating contact');
this.contacts.push({
name: contact.name,
registrationId: contact.registrationId,
deviceId: contact.deviceId,
preKeyBundle: contactBundle,
sessionCipher: sessionCipher,
signalAddress: signalAddress
});
}
return Promise.resolve(true);
}
catch (err) {
console.log("Unable to add session for [" + contact.name + "]");
console.log(err.message ? err.message : err);
throw new Error('bad_session');
}
};
Client.prototype.prepareMessage = function (contactName, message) {
if (!this.hasContact(contactName)) {
throw new Error('missing_contact');
}
var cipher = this.getContact(contactName).sessionCipher;
return Promise.resolve(this.encryptMessage(message, cipher));
};
Client.prototype.encodeMessage = function (message) {
return Promise.resolve(Util.base64Encode(message));
};
Client.prototype.decodeMessage = function (message) {
return Promise.resolve(Util.base64Decode(message));
};
Client.prototype.decryptEncodedMessage = function (contactName, message) {
return __awaiter(this, void 0, void 0, function () {
var decodedMessage, cipher;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!this.hasContact(contactName)) {
throw new Error('missing_contact');
}
return [4, this.decodeMessage(message)];
case 1:
decodedMessage = _a.sent();
cipher = this.getContact(contactName).sessionCipher;
return [2, Promise.resolve(this.decryptMessage(decodedMessage, cipher))];
}
});
});
};
Client.prototype.toJSON = function () {
return {
username: this.username,
deviceId: this.deviceId,
registrationId: this.registrationId,
address: {
name: this.registrationId,
deviceId: this.deviceId
},
identityKeyPair: Util.base64Encode(this.store.getIdentityKeyPair().serialize()),
signedPreKey: Util.base64Encode(this.signedPreKey.serialize()),
contacts: this.contacts.map(function (c) {
return {
"address": {
"name": c.name,
"registrationId": c.registrationId,
"deviceId": c.deviceId,
},
"preKeyBundle": {
"registrationId": c.preKeyBundle.registrationId,
"deviceId": c.preKeyBundle.deviceId,
"preKeyPublic": c.preKeyBundle.preKeyPublic,
"preKeyRecordId": c.preKeyBundle.preKeyRecordId,
"signedPreKeyPublic": c.preKeyBundle.signedPreKeyPublic,
"signedPreKeyRecordId": c.preKeyBundle.signedPreKeyRecordId,
"signature": c.preKeyBundle.signature,
"identityPubKey": c.preKeyBundle.identityPubKey
}
};
}),
preKeys: this.preKeys
};
};
Client.prototype.serialize = function () {
var serialize = {
client: {
registrationId: this.registrationId,
username: this.username,
deviceId: this.deviceId
},
contacts: this.contacts,
signedPreKey: Util.base64Encode(this.signedPreKey.serialize()),
identityKeyPair: Util.base64Encode(this.store.getIdentityKeyPair().serialize()),
preKeys: this.preKeys
};
return JSON.stringify(serialize);
};
Client.prototype.importPreKeyBundle = function (signalAddress, importedData) {
var identityPubKey = Core.importIdentityKey(Util.base64Decode(importedData.identityPubKey));
return Core.createPreKeyBundle(Number(signalAddress.getName()), Number(signalAddress.getDeviceId()), importedData.preKeyRecordId, Core.importPublicKey(Util.base64Decode(importedData.preKeyPublic)), importedData.signedPreKeyRecordId, Core.importPublicKey(Util.base64Decode(importedData.signedPreKeyPublic)), Util.base64Decode(importedData.signature), identityPubKey);
};
Client.prototype.encryptMessage = function (message, sessionCipher) {
var javaStr = new java.lang.String(message);
return sessionCipher.encrypt(javaStr.getBytes("UTF-8")).serialize();
};
Client.prototype.decryptMessage = function (message, cipher) {
var signalMessage;
try {
signalMessage = Core.createPreKeySignalMessage(message);
if (signalMessage) {
console.log('isPreKeySignalMessage');
var text = cipher.decrypt(signalMessage);
return new java.lang.String(text).toString();
}
else {
console.log('Failed PreKeySignalMessage will try SignalMessage');
signalMessage = Core.createSignalMessage(message);
var text = cipher.decrypt(signalMessage);
return new java.lang.String(text).toString();
}
}
catch (err) {
console.log('Unable to decrypt[1]');
console.log(err);
}
return new Error('Unable to decrypt[2]');
};
Client.prototype.createAddress = function () {
this.address = Core.createSignalProtocolAddress(this.username, this.deviceId);
return this.address;
};
Client.prototype.createIdentityKeyPair = function (importedIdentityKeyPair) {
if (typeof importedIdentityKeyPair === 'undefined') {
this.identityKeyPair = KeyHelper.generateIdentityKeyPair();
}
else {
this.identityKeyPair = Core.importIdentityKeyPair(Util.base64Decode(importedIdentityKeyPair));
}
return this.identityKeyPair;
};
Client.prototype.createSignedPreKey = function (importedSignedPreKey) {
if (typeof importedSignedPreKey === 'undefined') {
this.signedPreKey = KeyHelper.generateSignedPreKey(this.identityKeyPair, this.random.nextInt(0xFFFFFF - 1));
}
else {
this.signedPreKey = Core.importSignedPreKeyRecord(Util.base64Decode(importedSignedPreKey));
}
return this.signedPreKey;
};
Client.prototype.createPreKeys = function (importedPreKeys) {
var _this = this;
if (typeof importedPreKeys === 'undefined') {
var preKeys = KeyHelper.generatePreKeysFormatted(this.random.nextInt(0xFFFFFF - 101), 100);
preKeys.forEach(function (preKeyFormatted) {
try {
_this.preKeys.push({
id: preKeyFormatted.keyId,
pubKey: preKeyFormatted.keyPair.pubKey,
serialized: preKeyFormatted.serialized
});
var preKeyRecord = Core.importPreKeyRecord(Util.base64Decode(preKeyFormatted.serialized));
_this.store.storePreKey(preKeyRecord.getId(), preKeyRecord);
}
catch (err) {
console.log('nope2');
console.log(err);
}
});
}
else {
importedPreKeys.forEach(function (preKey) {
var preKeyRecord = Core.importPreKeyRecord(Util.base64Decode(preKey.serialized));
var keyPair = preKeyRecord.getKeyPair();
_this.preKeys.push({
id: preKeyRecord.getId(),
pubKey: Util.base64Encode(keyPair.getPublicKey().serialize()),
serialized: Util.base64Encode(preKeyRecord.serialize())
});
_this.store.storePreKey(preKeyRecord.getId(), preKeyRecord);
});
}
return this.preKeys;
};
Client.prototype.createContacts = function (importedContacts) {
var _this = this;
if (typeof importedContacts !== 'undefined' && importedContacts.length > 0) {
importedContacts.forEach(function (contact) { return __awaiter(_this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4, this.addSession(contact.address, contact.preKeyBundle)];
case 1:
_a.sent();
console.log("...added " + contact.address.name + " for " + this.username, {
hasContact: this.hasContact(contact.address.name),
hasSession: this.hasSession(contact.address.name)
});
return [2];
}
});
}); });
}
return this.contacts;
};
return Client;
}());
LibsignalProtocol.Client = Client;
})(LibsignalProtocol = exports.LibsignalProtocol || (exports.LibsignalProtocol = {}));
//# sourceMappingURL=libsignal-protocol.android.js.map