Page MenuHomePhorge

D12132.1765129284.diff
No OneTemporary

Size
8 KB
Referenced Files
None
Subscribers
None

D12132.1765129284.diff

diff --git a/lib/handlers/db-ops-handler.react.js b/lib/handlers/db-ops-handler.react.js
--- a/lib/handlers/db-ops-handler.react.js
+++ b/lib/handlers/db-ops-handler.react.js
@@ -5,6 +5,7 @@
import { opsProcessingFinishedActionType } from '../actions/db-ops-actions.js';
import { IdentityClientContext } from '../shared/identity-client-context.js';
+import { usePeerToPeer } from '../tunnelbroker/peer-to-peer-context.js';
import { useTunnelbroker } from '../tunnelbroker/tunnelbroker-context.js';
import type { DBOpsEntry } from '../types/db-ops-types.js';
import type { StoreOperations } from '../types/store-ops-types.js';
@@ -28,6 +29,7 @@
const { sendMessage } = useTunnelbroker();
const identityContext = React.useContext(IdentityClientContext);
invariant(identityContext, 'Identity context should be set');
+ const { processOutboundMessages } = usePeerToPeer();
const dispatch = useDispatch();
@@ -41,6 +43,9 @@
void (async () => {
if (ops) {
await processDBStoreOperations(ops);
+ if (ops.outboundP2PMessages && ops.outboundP2PMessages.length > 0) {
+ processOutboundMessages();
+ }
}
dispatch({
type: opsProcessingFinishedActionType,
diff --git a/lib/tunnelbroker/peer-to-peer-context.js b/lib/tunnelbroker/peer-to-peer-context.js
new file mode 100644
--- /dev/null
+++ b/lib/tunnelbroker/peer-to-peer-context.js
@@ -0,0 +1,193 @@
+// @flow
+
+import invariant from 'invariant';
+import * as React from 'react';
+
+import {
+ type TunnelbrokerClientMessageToDevice,
+ useTunnelbroker,
+} from './tunnelbroker-context.js';
+import {
+ IdentityClientContext,
+ type IdentityClientContextType,
+} from '../shared/identity-client-context.js';
+import {
+ type OutboundP2PMessage,
+ outboundP2PMessageStatuses,
+} from '../types/sqlite-types.js';
+import {
+ type EncryptedMessage,
+ peerToPeerMessageTypes,
+} from '../types/tunnelbroker/peer-to-peer-message-types.js';
+import { getConfig } from '../utils/config.js';
+import { createOlmSessionWithPeer } from '../utils/crypto-utils.js';
+
+type PeerToPeerContextType = {
+ +processOutboundMessages: () => void,
+};
+
+const PeerToPeerContext: React.Context<?PeerToPeerContextType> =
+ React.createContext<?PeerToPeerContextType>();
+
+type Props = {
+ +children: React.Node,
+};
+
+async function processOutboundP2PMessages(
+ sendMessageWithID: (
+ message: TunnelbrokerClientMessageToDevice,
+ messageID: string,
+ ) => Promise<void>,
+ sendMessage: (message: TunnelbrokerClientMessageToDevice) => Promise<void>,
+ identityContext: IdentityClientContextType,
+): Promise<void> {
+ const { olmAPI, sqliteAPI } = getConfig();
+ await olmAPI.initializeCryptoAccount();
+ const messages = await sqliteAPI.getAllOutboundP2PMessage();
+
+ const devicesMap: { [deviceID: string]: OutboundP2PMessage[] } = {};
+ for (const message: OutboundP2PMessage of messages) {
+ if (!devicesMap[message.deviceID]) {
+ devicesMap[message.deviceID] = [message];
+ } else {
+ devicesMap[message.deviceID].push(message);
+ }
+ }
+
+ const authMetadata = await identityContext.getAuthMetadata();
+ if (!authMetadata.deviceID || !authMetadata.userID || !authMetadata.userID) {
+ return;
+ }
+
+ const sendMessageToPeer = async (message: OutboundP2PMessage) => {
+ if (!authMetadata.deviceID || !authMetadata.userID) {
+ return;
+ }
+ const encryptedMessage: EncryptedMessage = {
+ type: peerToPeerMessageTypes.ENCRYPTED_MESSAGE,
+ senderInfo: {
+ deviceID: authMetadata.deviceID,
+ userID: authMetadata.userID,
+ },
+ encryptedData: JSON.parse(message.ciphertext),
+ };
+ await sendMessageWithID(
+ {
+ deviceID: message.deviceID,
+ payload: JSON.stringify(encryptedMessage),
+ },
+ message.messageID,
+ );
+ await sqliteAPI.markOutboundP2PMessageAsSent(
+ message.messageID,
+ message.deviceID,
+ );
+ };
+
+ for (const peerDeviceID in devicesMap) {
+ for (const message of devicesMap[peerDeviceID]) {
+ if (message.status === outboundP2PMessageStatuses.addressed) {
+ try {
+ const result = await olmAPI.encryptAndPersist(
+ message.plaintext,
+ message.deviceID,
+ message.messageID,
+ );
+
+ const encryptedMessage: OutboundP2PMessage = {
+ ...message,
+ ciphertext: JSON.stringify(result),
+ };
+ await sendMessageToPeer(encryptedMessage);
+ } catch (e) {
+ try {
+ await createOlmSessionWithPeer(
+ authMetadata,
+ identityContext.identityClient,
+ sendMessage,
+ message.userID,
+ peerDeviceID,
+ );
+ const result = await olmAPI.encryptAndPersist(
+ message.plaintext,
+ message.deviceID,
+ message.messageID,
+ );
+ const encryptedMessage: OutboundP2PMessage = {
+ ...message,
+ ciphertext: JSON.stringify(result),
+ };
+
+ await sendMessageToPeer(encryptedMessage);
+ } catch (err) {
+ console.log(
+ `Error creating session with peer ${peerDeviceID}`,
+ err,
+ );
+ break;
+ }
+ }
+ } else if (message.status === outboundP2PMessageStatuses.encrypted) {
+ await sendMessageToPeer(message);
+ }
+ }
+ }
+}
+
+function PeerToPeerProvider(props: Props): React.Node {
+ const { children } = props;
+
+ const restartPromise = React.useRef<boolean>(false);
+ const promiseRunning = React.useRef<boolean>(false);
+ const promise = React.useRef<?Promise<void>>(null);
+
+ const identityContext = React.useContext(IdentityClientContext);
+ invariant(identityContext, 'Identity context should be set');
+
+ const { sendMessageWithID, sendMessage } = useTunnelbroker();
+
+ const processOutboundMessages = React.useCallback(() => {
+ if (!promiseRunning.current) {
+ promise.current = (async () => {
+ promiseRunning.current = true;
+ await processOutboundP2PMessages(
+ sendMessageWithID,
+ sendMessage,
+ identityContext,
+ );
+ do {
+ await processOutboundP2PMessages(
+ sendMessageWithID,
+ sendMessage,
+ identityContext,
+ );
+ } while (restartPromise.current);
+ promiseRunning.current = false;
+ })();
+ } else {
+ restartPromise.current = true;
+ }
+ }, [identityContext, sendMessage, sendMessageWithID]);
+
+ const value: PeerToPeerContextType = React.useMemo(
+ () => ({
+ processOutboundMessages,
+ }),
+ [processOutboundMessages],
+ );
+
+ return (
+ <PeerToPeerContext.Provider value={value}>
+ {children}
+ </PeerToPeerContext.Provider>
+ );
+}
+
+function usePeerToPeer(): PeerToPeerContextType {
+ const context = React.useContext(PeerToPeerContext);
+ invariant(context, 'PeerToPeerContext not found');
+
+ return context;
+}
+
+export { PeerToPeerProvider, usePeerToPeer };
diff --git a/lib/tunnelbroker/tunnelbroker-context.js b/lib/tunnelbroker/tunnelbroker-context.js
--- a/lib/tunnelbroker/tunnelbroker-context.js
+++ b/lib/tunnelbroker/tunnelbroker-context.js
@@ -5,6 +5,7 @@
import * as React from 'react';
import uuid from 'uuid';
+import { PeerToPeerProvider } from './peer-to-peer-context.js';
import type { SecondaryTunnelbrokerConnection } from './secondary-tunnelbroker-connection.js';
import { tunnnelbrokerURL } from '../facts/tunnelbroker.js';
import { peerToPeerMessageHandler } from '../handlers/peer-to-peer-message-handler.js';
@@ -497,7 +498,7 @@
return (
<TunnelbrokerContext.Provider value={value}>
- {children}
+ <PeerToPeerProvider>{children}</PeerToPeerProvider>
</TunnelbrokerContext.Provider>
);
}
diff --git a/lib/types/sqlite-types.js b/lib/types/sqlite-types.js
--- a/lib/types/sqlite-types.js
+++ b/lib/types/sqlite-types.js
@@ -2,6 +2,12 @@
import type { StoreOperations } from './store-ops-types.js';
+export const outboundP2PMessageStatuses = Object.freeze({
+ addressed: 'addressed',
+ encrypted: 'encrypted',
+ sent: 'sent',
+});
+
export type InboundP2PMessage = {
+messageID: string,
+senderDeviceID: string,

File Metadata

Mime Type
text/plain
Expires
Sun, Dec 7, 5:41 PM (19 h, 43 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5845258
Default Alt Text
D12132.1765129284.diff (8 KB)

Event Timeline