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 => { Whisper.events.on('devicePairingRequestRejected', async pubKey => {
await libloki.storage.removeContactPreKeyBundle(pubKey); await libloki.storage.removeContactPreKeyBundle(pubKey);
const pubKeyObject = new libsession.Types.PubKey(pubKey);
await libsession.Protocols.MultiDeviceProtocol.removePairingAuthorisations( await libsession.Protocols.MultiDeviceProtocol.removePairingAuthorisations(
pubKeyObject pubKey
); );
}); });
@ -1438,9 +1436,8 @@
if (isSecondaryDevice) { if (isSecondaryDevice) {
return; return;
} }
const pubKeyObject = new libsession.Types.PubKey(pubKey);
await libsession.Protocols.MultiDeviceProtocol.removePairingAuthorisations( await libsession.Protocols.MultiDeviceProtocol.removePairingAuthorisations(
pubKeyObject pubKey
); );
await window.lokiFileServerAPI.updateOurDeviceMapping(); await window.lokiFileServerAPI.updateOurDeviceMapping();
// TODO: we should ensure the message was sent and retry automatically if not // TODO: we should ensure the message was sent and retry automatically if not
@ -1755,6 +1752,8 @@
return; 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 user = libsession.Types.PubKey.from(sender);
const primaryDevice = user const primaryDevice = user
? await libsession.Protocols.MultiDeviceProtocol.getPrimaryDevice(user) ? await libsession.Protocols.MultiDeviceProtocol.getPrimaryDevice(user)
@ -1818,18 +1817,16 @@
} }
const ourPrimaryKey = window.storage.get('primaryDevicePubKey'); const ourPrimaryKey = window.storage.get('primaryDevicePubKey');
if (ourPrimaryKey) { if (ourPrimaryKey) {
const user = new libsession.Types.PubKey(ourPrimaryKey);
const secondaryDevices = await libsession.Protocols.MultiDeviceProtocol.getSecondaryDevices( const secondaryDevices = await libsession.Protocols.MultiDeviceProtocol.getSecondaryDevices(
user ourPrimaryKey
); );
if (secondaryDevices.some(device => device.key === id)) { if (secondaryDevices.some(device => device.key === id)) {
await conversation.setSecondaryStatus(true, ourPrimaryKey); await conversation.setSecondaryStatus(true, ourPrimaryKey);
} }
} }
const user = new libsession.Types.PubKey(id);
const devices = await libsession.Protocols.MultiDeviceProtocol.getAllDevices( const devices = await libsession.Protocols.MultiDeviceProtocol.getAllDevices(
user id
); );
const deviceConversations = await Promise.all( const deviceConversations = await Promise.all(
devices.map(d => devices.map(d =>

@ -879,7 +879,14 @@
const device = window.libsession.Types.PubKey.from(this.id); const device = window.libsession.Types.PubKey.from(this.id);
if (device) { 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 // Something funky has happened

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

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

@ -1720,9 +1720,8 @@ MessageReceiver.prototype.extend({
async handleSyncMessage(envelope, syncMessage) { async handleSyncMessage(envelope, syncMessage) {
// We should only accept sync messages from our devices // We should only accept sync messages from our devices
const ourNumber = textsecure.storage.user.getNumber(); const ourNumber = textsecure.storage.user.getNumber();
const user = new libsession.Types.PubKey(ourNumber);
const ourDevices = await libsession.Protocols.MultiDeviceProtocol.getAllDevices( const ourDevices = await libsession.Protocols.MultiDeviceProtocol.getAllDevices(
user ourNumber
); );
const validSyncSender = ourDevices.some( const validSyncSender = ourDevices.some(
device => device.key === envelope.source 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 // TODO: We should fetch mappings when we can and only fetch them once every 5 minutes or something
/** /*
* Save pairing authorisation to the database. The reason we're exporing a class here instead of just exporting the functions directly is for the sake of testing.
* @param authorisation The pairing authorisation. 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.
*/ */
export async function savePairingAuthorisation( // tslint:disable-next-line: no-unnecessary-class
authorisation: PairingAuthorisation export class MultiDeviceProtocol {
): Promise<void> { /**
return createOrUpdatePairingAuthorisation(authorisation); * 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. * Get pairing authorisations for a given device.
* @param device The device to get pairing authorisations for. * @param device The device to get pairing authorisations for.
*/ */
export async function getPairingAuthorisations( public static async getPairingAuthorisations(
device: PubKey device: PubKey | string
): Promise<Array<PairingAuthorisation>> { ): Promise<Array<PairingAuthorisation>> {
return getPairingAuthorisationsFor(device.key); const pubKey = typeof device === 'string' ? new PubKey(device) : device;
}
/** return getPairingAuthorisationsFor(pubKey.key);
* 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 [...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;
/** return removePairingAuthorisationsFor(pubKey.key);
* 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;
} }
const pubKey = PrimaryPubKey.from(authorisations[0].primaryDevicePubKey); /**
if (!pubKey) { * Get all devices linked to a user.
throw new Error(`Primary user public key is invalid for ${user.key}.`); *
* @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}.`);
}
/** return primary;
* Get all the secondary devices linked to a user. }
*
* @param user The user to get the devices from. /**
*/ * Get all the secondary devices linked to a user.
export async function getSecondaryDevices( *
user: PubKey * @param user The user to get the devices from.
): Promise<Array<SecondaryPubKey>> { */
const primary = await getPrimaryDevice(user); public static async getSecondaryDevices(
const authorisations = await getPairingAuthorisations(primary); user: PubKey | string
): Promise<Array<SecondaryPubKey>> {
const primary = await this.getPrimaryDevice(user);
const authorisations = await this.getPairingAuthorisations(primary);
return authorisations return authorisations
.map(a => a.secondaryDevicePubKey) .map(a => a.secondaryDevicePubKey)
.map(pubKey => new SecondaryPubKey(pubKey)); .map(pubKey => new SecondaryPubKey(pubKey));
}
} }

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

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

Loading…
Cancel
Save