diff --git a/lib/handlers/db-ops-handler.react.js b/lib/handlers/db-ops-handler.react.js index a2db344c6..59b0238c9 100644 --- a/lib/handlers/db-ops-handler.react.js +++ b/lib/handlers/db-ops-handler.react.js @@ -1,61 +1,73 @@ // @flow import * as React from 'react'; import { opsProcessingFinishedActionType } from '../actions/db-ops-actions.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'; import { type MessageProcessed, peerToPeerMessageTypes, } from '../types/tunnelbroker/peer-to-peer-message-types.js'; import { getConfig } from '../utils/config.js'; +import { getContentSigningKey } from '../utils/crypto-utils.js'; +import { getMessageForException } from '../utils/errors.js'; import { useDispatch, useSelector } from '../utils/redux-utils.js'; type Props = { +processDBStoreOperations: StoreOperations => Promise, }; function DBOpsHandler(props: Props): React.Node { const { sqliteAPI } = getConfig(); const { processDBStoreOperations } = props; const queueFront = useSelector(state => state.dbOpsStore.queuedOps[0]); const prevQueueFront = React.useRef(null); const { sendMessage } = useTunnelbroker(); const dispatch = useDispatch(); React.useEffect(() => { if (!queueFront || prevQueueFront.current === queueFront) { return; } prevQueueFront.current = queueFront; const { ops, messageSourceMetadata } = queueFront; void (async () => { if (ops) { await processDBStoreOperations(ops); } dispatch({ type: opsProcessingFinishedActionType, }); if (messageSourceMetadata) { - const { messageID, senderDeviceID } = messageSourceMetadata; - const message: MessageProcessed = { - type: peerToPeerMessageTypes.MESSAGE_PROCESSED, - messageID, - }; - await sendMessage({ - deviceID: senderDeviceID, - payload: JSON.stringify(message), - }); - await sqliteAPI.removeInboundP2PMessages([messageID]); + try { + const { messageID, senderDeviceID } = messageSourceMetadata; + const deviceID = await getContentSigningKey(); + const message: MessageProcessed = { + type: peerToPeerMessageTypes.MESSAGE_PROCESSED, + messageID, + deviceID, + }; + await sendMessage({ + deviceID: senderDeviceID, + payload: JSON.stringify(message), + }); + await sqliteAPI.removeInboundP2PMessages([messageID]); + } catch (e) { + console.log( + `Error while sending confirmation: ${ + getMessageForException(e) ?? 'unknown error' + }`, + ); + } } })(); }, [queueFront, dispatch, processDBStoreOperations, sendMessage, sqliteAPI]); return null; } export { DBOpsHandler }; diff --git a/lib/types/tunnelbroker/peer-to-peer-message-types.js b/lib/types/tunnelbroker/peer-to-peer-message-types.js index f834ac6a1..bcd06de9a 100644 --- a/lib/types/tunnelbroker/peer-to-peer-message-types.js +++ b/lib/types/tunnelbroker/peer-to-peer-message-types.js @@ -1,116 +1,118 @@ // @flow import type { TInterface, TUnion } from 'tcomb'; import t from 'tcomb'; import { tShape, tString, tUserID } from '../../utils/validation-utils.js'; import { type EncryptedData, encryptedDataValidator } from '../crypto-types.js'; import { signedDeviceListValidator, type SignedDeviceList, } from '../identity-service-types.js'; export type SenderInfo = { +userID: string, +deviceID: string, }; const senderInfoValidator: TInterface = tShape({ userID: tUserID, deviceID: t.String, }); export const peerToPeerMessageTypes = Object.freeze({ OUTBOUND_SESSION_CREATION: 'OutboundSessionCreation', ENCRYPTED_MESSAGE: 'EncryptedMessage', REFRESH_KEY_REQUEST: 'RefreshKeyRequest', QR_CODE_AUTH_MESSAGE: 'QRCodeAuthMessage', DEVICE_LIST_UPDATED: 'DeviceListUpdated', MESSAGE_PROCESSED: 'MessageProcessed', }); export type OutboundSessionCreation = { +type: 'OutboundSessionCreation', +senderInfo: SenderInfo, +encryptedData: EncryptedData, +sessionVersion: number, }; export const outboundSessionCreationValidator: TInterface = tShape({ type: tString(peerToPeerMessageTypes.OUTBOUND_SESSION_CREATION), senderInfo: senderInfoValidator, encryptedData: encryptedDataValidator, sessionVersion: t.Number, }); export type EncryptedMessage = { +type: 'EncryptedMessage', +senderInfo: SenderInfo, +encryptedData: EncryptedData, }; export const encryptedMessageValidator: TInterface = tShape({ type: tString(peerToPeerMessageTypes.ENCRYPTED_MESSAGE), senderInfo: senderInfoValidator, encryptedData: encryptedDataValidator, }); export type RefreshKeyRequest = { +type: 'RefreshKeyRequest', +deviceID: string, +numberOfKeys: number, }; export const refreshKeysRequestValidator: TInterface = tShape({ type: tString(peerToPeerMessageTypes.REFRESH_KEY_REQUEST), deviceID: t.String, numberOfKeys: t.Number, }); export type QRCodeAuthMessage = { +type: 'QRCodeAuthMessage', +encryptedContent: string, }; export const qrCodeAuthMessageValidator: TInterface = tShape({ type: tString(peerToPeerMessageTypes.QR_CODE_AUTH_MESSAGE), encryptedContent: t.String, }); export type DeviceListUpdated = { +type: 'DeviceListUpdated', +userID: string, +signedDeviceList: SignedDeviceList, }; export const deviceListUpdatedValidator: TInterface = tShape({ type: tString(peerToPeerMessageTypes.DEVICE_LIST_UPDATED), userID: tUserID, signedDeviceList: signedDeviceListValidator, }); export type MessageProcessed = { +type: 'MessageProcessed', +messageID: string, + +deviceID: string, }; export const messageProcessedValidator: TInterface = tShape({ type: tString(peerToPeerMessageTypes.MESSAGE_PROCESSED), messageID: t.String, + deviceID: t.String, }); export type PeerToPeerMessage = | OutboundSessionCreation | EncryptedMessage | RefreshKeyRequest | QRCodeAuthMessage | DeviceListUpdated | MessageProcessed; export const peerToPeerMessageValidator: TUnion = t.union([ outboundSessionCreationValidator, encryptedMessageValidator, refreshKeysRequestValidator, qrCodeAuthMessageValidator, deviceListUpdatedValidator, messageProcessedValidator, ]);