Page MenuHomePhabricator

D13374.id44292.diff
No OneTemporary

D13374.id44292.diff

diff --git a/lib/utils/peer-to-peer-communication-utils.js b/lib/utils/peer-to-peer-communication-utils.js
--- a/lib/utils/peer-to-peer-communication-utils.js
+++ b/lib/utils/peer-to-peer-communication-utils.js
@@ -1,5 +1,14 @@
// @flow
+import { getConfig } from './config.js';
+import { olmSessionErrors } from './olm-utils.js';
+import { type AuthMetadata } from '../shared/identity-client-context.js';
+import type { TunnelbrokerClientMessageToDevice } from '../tunnelbroker/tunnelbroker-context.js';
+import type { OutboundP2PMessage } from '../types/sqlite-types.js';
+import { outboundP2PMessageStatuses } from '../types/sqlite-types.js';
+import type { EncryptedMessage } from '../types/tunnelbroker/peer-to-peer-message-types.js';
+import { peerToPeerMessageTypes } from '../types/tunnelbroker/peer-to-peer-message-types.js';
+
function getClientMessageIDFromTunnelbrokerMessageID(
tunnelbrokerMessageID: string,
): string {
@@ -10,4 +19,172 @@
return ids[1];
}
-export { getClientMessageIDFromTunnelbrokerMessageID };
+async function sendMessageToPeer(
+ message: OutboundP2PMessage,
+ authMetadata: ?AuthMetadata,
+ sendMessage: (
+ message: TunnelbrokerClientMessageToDevice,
+ messageID: ?string,
+ ) => Promise<void>,
+): Promise<'success' | 'failure'> {
+ const { sqliteAPI } = getConfig();
+
+ if (!authMetadata || !authMetadata.deviceID || !authMetadata.userID) {
+ return 'failure';
+ }
+
+ try {
+ const encryptedMessage: EncryptedMessage = {
+ type: peerToPeerMessageTypes.ENCRYPTED_MESSAGE,
+ senderInfo: {
+ deviceID: authMetadata.deviceID,
+ userID: authMetadata.userID,
+ },
+ encryptedData: JSON.parse(message.ciphertext),
+ };
+ await sendMessage(
+ {
+ deviceID: message.deviceID,
+ payload: JSON.stringify(encryptedMessage),
+ },
+ message.messageID,
+ );
+ await sqliteAPI.markOutboundP2PMessageAsSent(
+ message.messageID,
+ message.deviceID,
+ );
+ return 'success';
+ } catch (e) {
+ console.error(e);
+ return 'failure';
+ }
+}
+
+async function encryptAndSendMessageToPeer(
+ message: OutboundP2PMessage,
+ authMetadata: ?AuthMetadata,
+ sendMessage: (
+ message: TunnelbrokerClientMessageToDevice,
+ messageID: ?string,
+ ) => Promise<void>,
+): Promise<'success' | 'failure' | 'missing_session'> {
+ const { olmAPI } = getConfig();
+
+ try {
+ const result = await olmAPI.encryptAndPersist(
+ message.plaintext,
+ message.deviceID,
+ message.messageID,
+ );
+
+ const encryptedMessage: OutboundP2PMessage = {
+ ...message,
+ ciphertext: JSON.stringify(result),
+ };
+ return await sendMessageToPeer(encryptedMessage, authMetadata, sendMessage);
+ } catch (e) {
+ if (e.message?.includes(olmSessionErrors.sessionDoesNotExist)) {
+ return 'missing_session';
+ }
+ console.log(`Error sending messages to peer ${message.deviceID}`, e);
+ return 'failure';
+ }
+}
+
+export type HandleOutboundP2PMessageResult = {
+ +status: 'success' | 'failure' | 'missing_session',
+ +messageID: string,
+};
+async function handleOutboundP2PMessage(
+ message: OutboundP2PMessage,
+ authMetadata: ?AuthMetadata,
+ sendMessage: (
+ message: TunnelbrokerClientMessageToDevice,
+ messageID: ?string,
+ ) => Promise<void>,
+): Promise<HandleOutboundP2PMessageResult> {
+ if (message.status === outboundP2PMessageStatuses.persisted) {
+ const status = await encryptAndSendMessageToPeer(
+ message,
+ authMetadata,
+ sendMessage,
+ );
+ return {
+ status,
+ messageID: message.messageID,
+ };
+ } else if (message.status === outboundP2PMessageStatuses.encrypted) {
+ const status = await sendMessageToPeer(message, authMetadata, sendMessage);
+ return {
+ status,
+ messageID: message.messageID,
+ };
+ } else if (message.status === outboundP2PMessageStatuses.sent) {
+ // Handle edge-case when message was sent, but it wasn't updated
+ // in the message store.
+ return {
+ status: 'success',
+ messageID: message.messageID,
+ };
+ }
+ return {
+ status: 'failure',
+ messageID: message.messageID,
+ };
+}
+
+export type EphemeralEncryptAndSendMessageToPeerResult = {
+ +status: 'success' | 'failure' | 'missing_session',
+ +recipient: { +userID: string, +deviceID: string },
+};
+async function ephemeralEncryptAndSendMessageToPeer(
+ contentPayload: string,
+ recipient: { +userID: string, +deviceID: string },
+ authMetadata: ?AuthMetadata,
+ sendMessage: (
+ message: TunnelbrokerClientMessageToDevice,
+ messageID: ?string,
+ ) => Promise<void>,
+): Promise<EphemeralEncryptAndSendMessageToPeerResult> {
+ const { olmAPI } = getConfig();
+
+ if (!authMetadata || !authMetadata.deviceID || !authMetadata.userID) {
+ return { status: 'failure', recipient };
+ }
+ const senderInfo = {
+ deviceID: authMetadata.deviceID,
+ userID: authMetadata.userID,
+ };
+
+ try {
+ const encryptedData = await olmAPI.encrypt(
+ contentPayload,
+ recipient.deviceID,
+ );
+ const encryptedMessage: EncryptedMessage = {
+ type: peerToPeerMessageTypes.ENCRYPTED_MESSAGE,
+ senderInfo,
+ encryptedData,
+ };
+ await sendMessage({
+ deviceID: recipient.deviceID,
+ payload: JSON.stringify(encryptedMessage),
+ });
+
+ return { status: 'success', recipient };
+ } catch (e) {
+ if (e.message?.includes(olmSessionErrors.sessionDoesNotExist)) {
+ return { status: 'missing_session', recipient };
+ }
+ console.log(`Error sending messages to peer ${recipient.deviceID}`, e);
+ return { status: 'failure', recipient };
+ }
+}
+
+export {
+ getClientMessageIDFromTunnelbrokerMessageID,
+ sendMessageToPeer,
+ encryptAndSendMessageToPeer,
+ ephemeralEncryptAndSendMessageToPeer,
+ handleOutboundP2PMessage,
+};

File Metadata

Mime Type
text/plain
Expires
Thu, Sep 19, 6:11 PM (1 h, 16 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2141386
Default Alt Text
D13374.id44292.diff (5 KB)

Event Timeline