diff --git a/app/services/dispatcher/run.js b/app/services/dispatcher/run.js index c64144cae3462621fc5615ec2d8f6026513e4ad0..88c377f7aa0c233f4a964ab56c1b04cf2d5be550 100644 --- a/app/services/dispatcher/run.js +++ b/app/services/dispatcher/run.js @@ -1,3 +1,4 @@ +/* eslint no-case-declarations: 0 */ const { get } = require('lodash') const signal = require('../signal') const channelRepository = require('./../../db/repositories/channel') @@ -27,6 +28,11 @@ const logger = require('./logger') * } */ +const dispatchActions = { + RELAY: 'RELAY', + REPAIR_TRUST: 'REPAIR_TRUST', +} + // INITIALIZATION const run = async (db, sock) => { @@ -45,31 +51,46 @@ const run = async (db, sock) => { const listenForInboundMessages = async (db, sock, channels) => Promise.all(channels.map(ch => signal.subscribe(sock, ch.phoneNumber))).then(listening => { - sock.on('data', inboundMsg => dispatch(db, sock, parseMessage(inboundMsg))) + sock.on('data', inboundMsg => dispatch(db, sock, parseSdMessage(inboundMsg))) return listening }) // MESSAGE DISPATCH -const dispatch = async (db, sock, inboundMsg) => { - if (shouldRelay(inboundMsg)) { - const channelPhoneNumber = inboundMsg.data.username - const sdMessage = signal.parseOutboundSdMessage(inboundMsg) - try { - const [channel, sender] = await Promise.all([ - channelRepository.findDeep(db, channelPhoneNumber), - classifySender(db, channelPhoneNumber, inboundMsg.data.source), - ]) - return messenger.dispatch( - await executor.processCommand({ db, sock, channel, sender, sdMessage }), - ) - } catch (e) { - logger.error(e) +const dispatch = async (db, sock, inboundSdMsg) => { + const dispatchAction = parseDistpatchAction(inboundSdMsg) + if (!dispatchAction) return + try { + switch (dispatchAction) { + case dispatchAction.RELAY: + return dispatchRelay(db, sock, inboundSdMsg) + case dispatchAction.REPAIR_TRUST: + return dispatchRepairTrust(sock, inboundSdMsg) } + } catch (e) { + logger.error(e) } } -const parseMessage = inboundMsg => { +const dispatchRelay = async (db, sock, sdMessage) => { + const [channel, sender] = await parseChannelAndSender(sdMessage) + return messenger.dispatch( + await executor.processCommand({ + db, + sock, + channel, + sender, + sdMessage: signal.parseOutboundSdMessage(sdMessage), + }), + ) +} + +const dispatchRepairTrust = (sock, sdMessage) => + signal.trust(sock, parseChannelPhoneNumber(sdMessage), parseFailedRecipient(sdMessage)) + +// PARSERS + +const parseSdMessage = inboundMsg => { try { return JSON.parse(inboundMsg) } catch (e) { @@ -77,9 +98,31 @@ const parseMessage = inboundMsg => { } } +const parseChannelPhoneNumber = sdMessage => sdMessage.data.username +const parseFailedRecipient = sdMessage => get(sdMessage, 'data.request.recipientNumber') + +const parseDistpatchAction = sdMessage => { + if (shouldRelay(sdMessage)) return dispatchActions.RELAY + if (shouldRepairTrust(sdMessage)) return dispatchActions.REPAIR_TRUST + return null +} + const shouldRelay = sdMessage => sdMessage.type === signal.messageTypes.MESSAGE && get(sdMessage, 'data.dataMessage') +const shouldRepairTrust = sdMessage => + sdMessage.type === signal.messageTypes.ERROR && + get(sdMessage, 'data.request.type') === signal.messageTypes.SEND + +// (Database, SignaldMessage) -> [Channel, Sender] +const parseChannelAndSender = async (db, sdMessage) => { + const channelPhoneNumber = parseChannelPhoneNumber(sdMessage) + return Promise.all([ + channelRepository.findDeep(db, channelPhoneNumber), + classifySender(db, channelPhoneNumber, sdMessage.data.source), + ]) +} + const classifySender = async (db, channelPhoneNumber, sender) => ({ phoneNumber: sender, isPublisher: await channelRepository.isPublisher(db, channelPhoneNumber, sender),