Handle strings in MultiDeviceProtocol

pull/1176/head
Mikunj 5 years ago
parent b36b3e7725
commit 7a6ea97efb

@ -1426,10 +1426,8 @@
Whisper.events.on('devicePairingRequestRejected', async pubKey => {
await libloki.storage.removeContactPreKeyBundle(pubKey);
const pubKeyObject = new libsession.Types.PubKey(pubKey);
await libsession.Protocols.MultiDeviceProtocol.removePairingAuthorisations(
pubKeyObject
pubKey
);
});
@ -1438,9 +1436,8 @@
if (isSecondaryDevice) {
return;
}
const pubKeyObject = new libsession.Types.PubKey(pubKey);
await libsession.Protocols.MultiDeviceProtocol.removePairingAuthorisations(
pubKeyObject
pubKey
);
await window.lokiFileServerAPI.updateOurDeviceMapping();
// TODO: we should ensure the message was sent and retry automatically if not
@ -1755,6 +1752,8 @@
return;
}
// A sender here could be referring to a group.
// Groups don't have primary devices so we need to take that into consideration.
const user = libsession.Types.PubKey.from(sender);
const primaryDevice = user
? await libsession.Protocols.MultiDeviceProtocol.getPrimaryDevice(user)
@ -1818,18 +1817,16 @@
}
const ourPrimaryKey = window.storage.get('primaryDevicePubKey');
if (ourPrimaryKey) {
const user = new libsession.Types.PubKey(ourPrimaryKey);
const secondaryDevices = await libsession.Protocols.MultiDeviceProtocol.getSecondaryDevices(
user
ourPrimaryKey
);
if (secondaryDevices.some(device => device.key === id)) {
await conversation.setSecondaryStatus(true, ourPrimaryKey);
}
}
const user = new libsession.Types.PubKey(id);
const devices = await libsession.Protocols.MultiDeviceProtocol.getAllDevices(
user
id
);
const deviceConversations = await Promise.all(
devices.map(d =>

@ -879,7 +879,14 @@
const device = window.libsession.Types.PubKey.from(this.id);
if (device) {
return ConversationController.getOrCreateAndWait(device.key, 'private');
const primary = await window.libsession.Protocols.MultiDeviceProtocol.getPrimaryDevice(
device
);
return ConversationController.getOrCreateAndWait(
primary.key,
'private'
);
}
// Something funky has happened

@ -219,9 +219,8 @@ class LokiHomeServerInstance extends LokiFileServerInstance {
async updateOurDeviceMapping() {
const isPrimary = !storage.get('isSecondaryDevice');
const ourKey = new window.libsession.Types.PubKey(this.ourKey);
const authorisations = await window.libsession.Protocols.MultiDeviceProtocol.getPairingAuthorisations(
ourKey
this.ourKey
);
return this._setOurDeviceMapping(authorisations, isPrimary);

@ -605,9 +605,8 @@
e && e.stack ? e.stack : e
);
// File server upload failed or message sending failed, we should rollback changes
const pubKey = new libsession.Types.PubKey(secondaryDevicePubKey);
await libsession.Protocols.MultiDeviceProtocol.removePairingAuthorisations(
pubKey
secondaryDevicePubKey
);
await lokiFileServerAPI.updateOurDeviceMapping();
throw e;

@ -1720,9 +1720,8 @@ MessageReceiver.prototype.extend({
async handleSyncMessage(envelope, syncMessage) {
// We should only accept sync messages from our devices
const ourNumber = textsecure.storage.user.getNumber();
const user = new libsession.Types.PubKey(ourNumber);
const ourDevices = await libsession.Protocols.MultiDeviceProtocol.getAllDevices(
user
ourNumber
);
const validSyncSender = ourDevices.some(
device => device.key === envelope.source

@ -9,85 +9,102 @@ import { PrimaryPubKey, PubKey, SecondaryPubKey } from '../types';
// TODO: We should fetch mappings when we can and only fetch them once every 5 minutes or something
/**
* Save pairing authorisation to the database.
* @param authorisation The pairing authorisation.
*/
export async function savePairingAuthorisation(
authorisation: PairingAuthorisation
): Promise<void> {
return createOrUpdatePairingAuthorisation(authorisation);
}
/*
The reason we're exporing a class here instead of just exporting the functions directly is for the sake of testing.
We might want to stub out specific functions inside the multi device protocol itself but when export functions directly then it's not possible without weird hacks.
*/
// tslint:disable-next-line: no-unnecessary-class
export class MultiDeviceProtocol {
/**
* Save pairing authorisation to the database.
* @param authorisation The pairing authorisation.
*/
public static async savePairingAuthorisation(
authorisation: PairingAuthorisation
): Promise<void> {
return createOrUpdatePairingAuthorisation(authorisation);
}
/**
* Get pairing authorisations for a given device.
* @param device The device to get pairing authorisations for.
*/
export async function getPairingAuthorisations(
device: PubKey
): Promise<Array<PairingAuthorisation>> {
return getPairingAuthorisationsFor(device.key);
}
/**
* Get pairing authorisations for a given device.
* @param device The device to get pairing authorisations for.
*/
public static async getPairingAuthorisations(
device: PubKey | string
): Promise<Array<PairingAuthorisation>> {
const pubKey = typeof device === 'string' ? new PubKey(device) : device;
/**
* Remove all pairing authorisations for a given device.
* @param device The device to remove authorisation for.
*/
export async function removePairingAuthorisations(
device: PubKey
): Promise<void> {
return removePairingAuthorisationsFor(device.key);
}
/**
* Get all devices linked to a user.
*
* @param user The user to get all the devices from.
*/
export async function getAllDevices(user: PubKey): Promise<Array<PubKey>> {
const authorisations = await getPairingAuthorisations(user);
const devices = _.flatMap(
authorisations,
({ primaryDevicePubKey, secondaryDevicePubKey }) => [
primaryDevicePubKey,
secondaryDevicePubKey,
]
);
return getPairingAuthorisationsFor(pubKey.key);
}
return [...new Set(devices)].map(p => new PubKey(p));
}
/**
* Remove all pairing authorisations for a given device.
* @param device The device to remove authorisation for.
*/
public static async removePairingAuthorisations(
device: PubKey | string
): Promise<void> {
const pubKey = typeof device === 'string' ? new PubKey(device) : device;
/**
* Get the primary device linked to a user.
*
* @param user The user to get primary device for.
*/
export async function getPrimaryDevice(user: PubKey): Promise<PrimaryPubKey> {
const authorisations = await getPairingAuthorisations(user);
if (authorisations.length === 0) {
return user;
return removePairingAuthorisationsFor(pubKey.key);
}
const pubKey = PrimaryPubKey.from(authorisations[0].primaryDevicePubKey);
if (!pubKey) {
throw new Error(`Primary user public key is invalid for ${user.key}.`);
/**
* Get all devices linked to a user.
*
* @param user The user to get all the devices from.
*/
public static async getAllDevices(
user: PubKey | string
): Promise<Array<PubKey>> {
const pubKey = typeof user === 'string' ? new PubKey(user) : user;
const authorisations = await this.getPairingAuthorisations(pubKey);
const devices = _.flatMap(
authorisations,
({ primaryDevicePubKey, secondaryDevicePubKey }) => [
primaryDevicePubKey,
secondaryDevicePubKey,
]
);
return [...new Set(devices)].map(p => new PubKey(p));
}
return pubKey;
}
/**
* Get the primary device linked to a user.
*
* @param user The user to get primary device for.
*/
public static async getPrimaryDevice(
user: PubKey | string
): Promise<PrimaryPubKey> {
const pubKey = typeof user === 'string' ? new PubKey(user) : user;
const authorisations = await this.getPairingAuthorisations(pubKey);
if (authorisations.length === 0) {
return pubKey;
}
const primary = PrimaryPubKey.from(authorisations[0].primaryDevicePubKey);
if (!primary) {
throw new Error(`Primary user public key is invalid for ${pubKey.key}.`);
}
/**
* Get all the secondary devices linked to a user.
*
* @param user The user to get the devices from.
*/
export async function getSecondaryDevices(
user: PubKey
): Promise<Array<SecondaryPubKey>> {
const primary = await getPrimaryDevice(user);
const authorisations = await getPairingAuthorisations(primary);
return primary;
}
/**
* Get all the secondary devices linked to a user.
*
* @param user The user to get the devices from.
*/
public static async getSecondaryDevices(
user: PubKey | string
): Promise<Array<SecondaryPubKey>> {
const primary = await this.getPrimaryDevice(user);
const authorisations = await this.getPairingAuthorisations(primary);
return authorisations
.map(a => a.secondaryDevicePubKey)
.map(pubKey => new SecondaryPubKey(pubKey));
return authorisations
.map(a => a.secondaryDevicePubKey)
.map(pubKey => new SecondaryPubKey(pubKey));
}
}

@ -1,4 +1,4 @@
import { SessionProtocol } from './SessionProtocol';
import * as MultiDeviceProtocol from './MultiDeviceProtocol';
export * from './MultiDeviceProtocol';
export { SessionProtocol, MultiDeviceProtocol };
export { SessionProtocol };

@ -92,7 +92,7 @@
"function-name": [
true,
{
"function-regex": "^[a-z][\\w\\d]+$",
"function-regex": "^_?[a-z][\\w\\d]+$",
"method-regex": "^[a-z][\\w\\d]+$",
"private-method-regex": "^[a-z][\\w\\d]+$",
"protected-method-regex": "^[a-z][\\w\\d]+$",

Loading…
Cancel
Save