diff --git a/src/Simplex/Chat.hs b/src/Simplex/Chat.hs index a3970eb4b0..7c960a0995 100644 --- a/src/Simplex/Chat.hs +++ b/src/Simplex/Chat.hs @@ -3380,6 +3380,8 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do xFileAcptInv ct sharedMsgId fileConnReq_ fName msgMeta = do checkIntegrityCreateItem (CDDirectRcv ct) msgMeta fileId <- withStore $ \db -> getDirectFileIdBySharedMsgId db user ct sharedMsgId + (AChatItem _ _ _ ci) <- withStore $ \db -> getChatItemByFileId db user fileId + assertSMPAcceptNotProhibited ci ft@FileTransferMeta {fileName, fileSize, fileInline, cancelled} <- withStore (\db -> getFileTransferMeta db user fileId) -- [async agent commands] no continuation needed, but command should be asynchronous for stability if fName == fileName @@ -3391,9 +3393,9 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do -- receiving inline _ -> do event <- withStore $ \db -> do - ci <- updateDirectCIFileStatus db user fileId $ CIFSSndTransfer 0 1 + ci' <- updateDirectCIFileStatus db user fileId $ CIFSSndTransfer 0 1 sft <- liftIO $ createSndDirectInlineFT db ct ft - pure $ CRSndFileStart user ci sft + pure $ CRSndFileStart user ci' sft toView event ifM (allowSendInline fileSize fileInline) @@ -3401,6 +3403,17 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do (messageError "x.file.acpt.inv: fileSize is bigger than allowed to send inline") else messageError "x.file.acpt.inv: fileName is different from expected" + assertSMPAcceptNotProhibited :: ChatItem c d -> m () + assertSMPAcceptNotProhibited ChatItem {file = Just CIFile {fileId, fileProtocol}, content} + | fileProtocol == FPXFTP && not (imageOrVoice content) = throwChatError $ CEFallbackToSMPProhibited fileId + | otherwise = pure () + where + imageOrVoice :: CIContent d -> Bool + imageOrVoice (CISndMsgContent (MCImage _ _)) = True + imageOrVoice (CISndMsgContent (MCVoice _ _)) = True + imageOrVoice _ = False + assertSMPAcceptNotProhibited _ = pure () + checkSndInlineFTComplete :: Connection -> AgentMsgId -> m () checkSndInlineFTComplete conn agentMsgId = do sft_ <- withStore' $ \db -> getSndFTViaMsgDelivery db user conn agentMsgId @@ -3463,6 +3476,8 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do xFileAcptInvGroup g@GroupInfo {groupId} m@GroupMember {activeConn} sharedMsgId fileConnReq_ fName msgMeta = do checkIntegrityCreateItem (CDGroupRcv g m) msgMeta fileId <- withStore $ \db -> getGroupFileIdBySharedMsgId db userId groupId sharedMsgId + (AChatItem _ _ _ ci) <- withStore $ \db -> getChatItemByFileId db user fileId + assertSMPAcceptNotProhibited ci -- TODO check that it's not already accepted ft@FileTransferMeta {fileName, fileSize, fileInline, cancelled} <- withStore (\db -> getFileTransferMeta db user fileId) if fName == fileName @@ -3475,9 +3490,9 @@ processAgentMessageConn user@User {userId} corrId agentConnId agentMessage = do (_, Just conn) -> do -- receiving inline event <- withStore $ \db -> do - ci <- updateDirectCIFileStatus db user fileId $ CIFSSndTransfer 0 1 + ci' <- updateDirectCIFileStatus db user fileId $ CIFSSndTransfer 0 1 sft <- liftIO $ createSndGroupInlineFT db m conn ft - pure $ CRSndFileStart user ci sft + pure $ CRSndFileStart user ci' sft toView event ifM (allowSendInline fileSize fileInline) diff --git a/src/Simplex/Chat/Controller.hs b/src/Simplex/Chat/Controller.hs index c71a99ab9f..e90d6fcaca 100644 --- a/src/Simplex/Chat/Controller.hs +++ b/src/Simplex/Chat/Controller.hs @@ -795,6 +795,7 @@ data ChatErrorType | CEFileNotReceived {fileId :: FileTransferId} | CEXFTPRcvFile {fileId :: FileTransferId, agentRcvFileId :: AgentRcvFileId, agentError :: AgentErrorType} | CEXFTPSndFile {fileId :: FileTransferId, agentSndFileId :: AgentSndFileId, agentError :: AgentErrorType} + | CEFallbackToSMPProhibited {fileId :: FileTransferId} | CEInlineFileProhibited {fileId :: FileTransferId} | CEInvalidQuote | CEInvalidChatItemUpdate diff --git a/src/Simplex/Chat/View.hs b/src/Simplex/Chat/View.hs index 06a775f9e9..93b946bf9b 100644 --- a/src/Simplex/Chat/View.hs +++ b/src/Simplex/Chat/View.hs @@ -1305,6 +1305,7 @@ viewChatError logLevel = \case CEFileNotReceived fileId -> ["file " <> sShow fileId <> " not received"] CEXFTPRcvFile fileId aFileId e -> ["error receiving XFTP file " <> sShow fileId <> ", agent file id " <> sShow aFileId <> ": " <> sShow e | logLevel == CLLError] CEXFTPSndFile fileId aFileId e -> ["error sending XFTP file " <> sShow fileId <> ", agent file id " <> sShow aFileId <> ": " <> sShow e | logLevel == CLLError] + CEFallbackToSMPProhibited fileId -> ["recipient tried to accept file " <> sShow fileId <> " via old protocol, prohibited"] CEInlineFileProhibited _ -> ["A small file sent without acceptance - you can enable receiving such files with -f option."] CEInvalidQuote -> ["cannot reply to this message"] CEInvalidChatItemUpdate -> ["cannot update this item"]