Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

core: add direct xftp upload/download commands #3781

Merged
merged 37 commits into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
2728509
chat: add direct xftp upload/download commands
dpwiz Feb 2, 2024
fc80915
adapt to FileDescriptionURI record
dpwiz Feb 6, 2024
2dae0af
bump simplexmq
dpwiz Feb 13, 2024
ad79bfe
Merge remote-tracking branch 'origin/master' into ab/direct-xftp
dpwiz Feb 13, 2024
b2fa151
add description uploading
dpwiz Feb 13, 2024
7ccabe9
filter URIs by size
dpwiz Feb 13, 2024
2a66b40
cleanup
dpwiz Feb 13, 2024
8a191d0
add file meta to events
dpwiz Feb 14, 2024
db905c4
remove focus
dpwiz Feb 14, 2024
92569e3
auto-redirect when no URI fits
dpwiz Feb 14, 2024
e522c2e
send "upload complete" event with the original file id
dpwiz Feb 14, 2024
3b87503
remove description upload command
dpwiz Feb 14, 2024
5867dc7
add index
spaced4ndy Feb 14, 2024
b92d4cd
refactor
spaced4ndy Feb 14, 2024
e2a7447
update simplexmq
spaced4ndy Feb 14, 2024
863962d
Apply suggestions from code review
dpwiz Feb 14, 2024
0b06ac8
fix /fc command for non-chat uploads
dpwiz Feb 14, 2024
673856a
fix
dpwiz Feb 14, 2024
1525671
rename (tests fail)
epoberezkin Feb 15, 2024
011148d
num recipients
spaced4ndy Feb 15, 2024
6a6534f
update messages
dpwiz Feb 15, 2024
b33fd23
split "file complete" events for chats and standalone
dpwiz Feb 15, 2024
65ac62c
restore xftpSndFileRedirect
dpwiz Feb 15, 2024
09974b2
remove unused store error
dpwiz Feb 15, 2024
056f685
add send/cancel test
dpwiz Feb 15, 2024
9257a75
untangle standalone views
dpwiz Feb 15, 2024
2ecc0d9
fix confused id
dpwiz Feb 15, 2024
901569a
fix /fc and /fs
dpwiz Feb 16, 2024
6e432a1
resolve comments
dpwiz Feb 16, 2024
360c339
misc fixes
dpwiz Feb 16, 2024
edff527
bump simplexmq
dpwiz Feb 16, 2024
731e17a
Merge remote-tracking branch 'origin/master' into ab/direct-xftp
dpwiz Feb 16, 2024
46bdcd1
fix build
dpwiz Feb 16, 2024
901e72c
handle redirect errors independently
dpwiz Feb 17, 2024
3fa2b19
Merge remote-tracking branch 'origin/master' into ab/direct-xftp
dpwiz Feb 17, 2024
cb0198e
fix missing file status in tests
dpwiz Feb 17, 2024
e88760e
Merge branch 'master' into ab/direct-xftp
epoberezkin Feb 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion cabal.project
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ constraints: zip +disable-bzip2 +disable-zstd
source-repository-package
type: git
location: https://github.com/simplex-chat/simplexmq.git
tag: 8de23c15ad089507cd180746a6ca9fd7a3296dc7
tag: 004597c764a8f8d5dc1e03fbad713b02a878c2ed

source-repository-package
type: git
Expand Down
2 changes: 1 addition & 1 deletion scripts/nix/sha256map.nix
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"https://github.com/simplex-chat/simplexmq.git"."8de23c15ad089507cd180746a6ca9fd7a3296dc7" = "0ck895whp1kzjfv8lx5w6l2xfiggcphvqr4hp2xawy373v3603ls";
"https://github.com/simplex-chat/simplexmq.git"."004597c764a8f8d5dc1e03fbad713b02a878c2ed" = "0c87qjlki5f3p598jazhc9267059fxw5xvqi3zx3g4sqy49aww6a";
"https://github.com/simplex-chat/hs-socks.git"."a30cc7a79a08d8108316094f8f2f82a0c5e1ac51" = "0yasvnr7g91k76mjkamvzab2kvlb1g5pspjyjn2fr6v83swjhj38";
"https://github.com/simplex-chat/direct-sqlcipher.git"."f814ee68b16a9447fbb467ccc8f29bdd3546bfd9" = "1ql13f4kfwkbaq7nygkxgw84213i0zm7c1a8hwvramayxl38dq5d";
"https://github.com/simplex-chat/sqlcipher-simple.git"."a46bd361a19376c5211f1058908fc0ae6bf42446" = "1z0r78d8f0812kxbgsm735qf6xx8lvaz27k1a0b4a2m0sshpd5gl";
Expand Down
1 change: 1 addition & 0 deletions simplex-chat.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ library
Simplex.Chat.Migrations.M20240104_members_profile_update
Simplex.Chat.Migrations.M20240115_block_member_for_all
Simplex.Chat.Migrations.M20240122_indexes
Simplex.Chat.Migrations.M20240214_redirect_file_id
Simplex.Chat.Mobile
Simplex.Chat.Mobile.File
Simplex.Chat.Mobile.Shared
Expand Down
222 changes: 138 additions & 84 deletions src/Simplex/Chat.hs

Large diffs are not rendered by default.

24 changes: 15 additions & 9 deletions src/Simplex/Chat/Controller.hs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ import Simplex.Chat.Remote.Types
import Simplex.Chat.Store (AutoAccept, StoreError (..), UserContactLink, UserMsgReceiptSettings)
import Simplex.Chat.Types
import Simplex.Chat.Types.Preferences
import Simplex.FileTransfer.Description (FileDescriptionURI)
import Simplex.Messaging.Agent (AgentClient, SubscriptionsInfo)
import Simplex.Messaging.Agent.Client (AgentLocks, AgentWorkersDetails (..), AgentWorkersSummary (..), ProtocolTestFailure)
import Simplex.Messaging.Agent.Env.SQLite (AgentConfig, NetworkConfig)
Expand Down Expand Up @@ -452,6 +453,8 @@ data ChatCommand
| ListRemoteCtrls
| StopRemoteCtrl -- Stop listening for announcements or terminate an active session
| DeleteRemoteCtrl RemoteCtrlId -- Remove all local data associated with a remote controller session
| APIXFTPDirectUpload UserId CryptoFile
| APIXFTPDirectDownload UserId FileDescriptionURI CryptoFile
| QuitChat
| ShowVersion
| DebugLocks
Expand Down Expand Up @@ -592,21 +595,24 @@ data ChatResponse
| CRRcvFileAccepted {user :: User, chatItem :: AChatItem}
| CRRcvFileAcceptedSndCancelled {user :: User, rcvFileTransfer :: RcvFileTransfer}
| CRRcvFileDescrNotReady {user :: User, chatItem :: AChatItem}
| CRRcvFileStart {user :: User, chatItem :: AChatItem}
| CRRcvFileProgressXFTP {user :: User, chatItem :: AChatItem, receivedSize :: Int64, totalSize :: Int64}
| CRRcvFileStart {user :: User, chatItem_ :: Maybe AChatItem, rcvFileTransfer :: RcvFileTransfer}
| CRRcvFileProgressXFTP {user :: User, chatItem_ :: Maybe AChatItem, receivedSize :: Int64, totalSize :: Int64, rcvFileTransfer :: RcvFileTransfer}
| CRRcvFileComplete {user :: User, chatItem :: AChatItem}
| CRRcvFileCompleteXFTP {user :: User, targetPath :: FilePath, rcvFileTransfer :: RcvFileTransfer}
| CRRcvFileCancelled {user :: User, chatItem :: AChatItem, rcvFileTransfer :: RcvFileTransfer}
| CRRcvFileSndCancelled {user :: User, chatItem :: AChatItem, rcvFileTransfer :: RcvFileTransfer}
| CRRcvFileError {user :: User, chatItem :: AChatItem, agentError :: AgentErrorType}
| CRRcvFileError {user :: User, chatItem_ :: Maybe AChatItem, agentError :: AgentErrorType, rcvFileTransfer :: RcvFileTransfer}
| CRSndFileStart {user :: User, chatItem :: AChatItem, sndFileTransfer :: SndFileTransfer}
| CRSndFileComplete {user :: User, chatItem :: AChatItem, sndFileTransfer :: SndFileTransfer}
| CRSndFileRcvCancelled {user :: User, chatItem :: AChatItem, sndFileTransfer :: SndFileTransfer}
| CRSndFileRcvCancelled {user :: User, chatItem_ :: Maybe AChatItem, sndFileTransfer :: SndFileTransfer}
| CRSndFileCancelled {user :: User, chatItem :: AChatItem, fileTransferMeta :: FileTransferMeta, sndFileTransfers :: [SndFileTransfer]}
| CRSndFileStartXFTP {user :: User, chatItem :: AChatItem, fileTransferMeta :: FileTransferMeta}
| CRSndFileProgressXFTP {user :: User, chatItem :: AChatItem, fileTransferMeta :: FileTransferMeta, sentSize :: Int64, totalSize :: Int64}
| CRSndFileCompleteXFTP {user :: User, chatItem :: AChatItem, fileTransferMeta :: FileTransferMeta}
| CRSndFileCancelledXFTP {user :: User, chatItem :: AChatItem, fileTransferMeta :: FileTransferMeta}
| CRSndFileError {user :: User, chatItem :: AChatItem}
| CRSndFileStartXFTP {user :: User, chatItem_ :: Maybe AChatItem, fileTransferMeta :: FileTransferMeta}
| CRSndFileStartXFTPDirect {user :: User, fileTransferMeta :: FileTransferMeta} -- sent by _upload instead of ok, signalling fileId to expect
| CRSndFileProgressXFTP {user :: User, chatItem_ :: Maybe AChatItem, fileTransferMeta :: FileTransferMeta, sentSize :: Int64, totalSize :: Int64}
| CRSndFileRedirectXFTP {user :: User, fileTransferMeta :: FileTransferMeta, redirectMeta :: FileTransferMeta}
| CRSndFileCompleteXFTP {user :: User, chatItem_ :: Maybe AChatItem, fileTransferMeta :: FileTransferMeta, rcvURIs :: [Text]}
| CRSndFileCancelledXFTP {user :: User, chatItem_ :: Maybe AChatItem, fileTransferMeta :: FileTransferMeta}
| CRSndFileError {user :: User, chatItem_ :: Maybe AChatItem, fileTransferMeta :: FileTransferMeta}
| CRUserProfileUpdated {user :: User, fromProfile :: Profile, toProfile :: Profile, updateSummary :: UserProfileUpdateSummary}
| CRUserProfileImage {user :: User, profile :: Profile}
| CRContactAliasUpdated {user :: User, toContact :: Contact}
Expand Down
7 changes: 4 additions & 3 deletions src/Simplex/Chat/Markdown.hs
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,11 @@ import qualified Data.Text as T
import Data.Text.Encoding (encodeUtf8)
import Simplex.Chat.Types
import Simplex.Chat.Types.Util
import Simplex.Messaging.Agent.Protocol (AConnectionRequestUri (..), ConnReqScheme (..), ConnReqUriData (..), ConnectionRequestUri (..), SMPQueue (..))
import Simplex.Messaging.Agent.Protocol (AConnectionRequestUri (..), ConnReqUriData (..), ConnectionRequestUri (..), SMPQueue (..))
import Simplex.Messaging.Encoding.String
import Simplex.Messaging.Parsers (defaultJSON, dropPrefix, enumJSON, fstToLower, sumTypeJSON)
import Simplex.Messaging.Protocol (ProtocolServer (..))
import Simplex.Messaging.ServiceScheme (ServiceScheme (..))
import Simplex.Messaging.Util (safeDecodeUtf8)
import System.Console.ANSI.Types
import qualified Text.Email.Validate as Email
Expand Down Expand Up @@ -231,10 +232,10 @@ markdownP = mconcat <$> A.many' fragmentP
simplexUriFormat :: AConnectionRequestUri -> Format
simplexUriFormat = \case
ACR _ (CRContactUri crData) ->
let uri = safeDecodeUtf8 . strEncode $ CRContactUri crData {crScheme = CRSSimplex}
let uri = safeDecodeUtf8 . strEncode $ CRContactUri crData {crScheme = SSSimplex}
in SimplexLink (linkType' crData) uri $ uriHosts crData
ACR _ (CRInvitationUri crData e2e) ->
let uri = safeDecodeUtf8 . strEncode $ CRInvitationUri crData {crScheme = CRSSimplex} e2e
let uri = safeDecodeUtf8 . strEncode $ CRInvitationUri crData {crScheme = SSSimplex} e2e
in SimplexLink XLInvitation uri $ uriHosts crData
where
uriHosts ConnReqUriData {crSmpQueues} = L.map (safeDecodeUtf8 . strEncode) $ sconcat $ L.map (host . qServer) crSmpQueues
Expand Down
22 changes: 22 additions & 0 deletions src/Simplex/Chat/Migrations/M20240214_redirect_file_id.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{-# LANGUAGE QuasiQuotes #-}

module Simplex.Chat.Migrations.M20240214_redirect_file_id where

import Database.SQLite.Simple (Query)
import Database.SQLite.Simple.QQ (sql)

m20240214_redirect_file_id :: Query
m20240214_redirect_file_id =
[sql|
ALTER TABLE files ADD COLUMN redirect_file_id INTEGER REFERENCES files ON DELETE CASCADE;
spaced4ndy marked this conversation as resolved.
Show resolved Hide resolved

CREATE INDEX idx_files_redirect_file_id on files(redirect_file_id);
|]

down_m20240214_redirect_file_id :: Query
down_m20240214_redirect_file_id =
[sql|
DROP INDEX idx_files_redirect_file_id;

ALTER TABLE files DROP COLUMN redirect_file_id;
|]
4 changes: 3 additions & 1 deletion src/Simplex/Chat/Migrations/chat_schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,8 @@ CREATE TABLE files(
protocol TEXT NOT NULL DEFAULT 'smp',
file_crypto_key BLOB,
file_crypto_nonce BLOB,
note_folder_id INTEGER DEFAULT NULL REFERENCES note_folders ON DELETE CASCADE
note_folder_id INTEGER DEFAULT NULL REFERENCES note_folders ON DELETE CASCADE,
redirect_file_id INTEGER REFERENCES files ON DELETE CASCADE
);
CREATE TABLE snd_files(
file_id INTEGER NOT NULL REFERENCES files ON DELETE CASCADE,
Expand Down Expand Up @@ -854,3 +855,4 @@ CREATE INDEX idx_chat_items_notes_item_status on chat_items(
note_folder_id,
item_status
);
CREATE INDEX idx_files_redirect_file_id on files(redirect_file_id);
48 changes: 35 additions & 13 deletions src/Simplex/Chat/Store/Files.hs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ module Simplex.Chat.Store.Files
deleteSndFileChunks,
createRcvFileTransfer,
createRcvGroupFileTransfer,
createRcvDirectFileTransfer,
appendRcvFD,
getRcvFileDescrByRcvFileId,
getRcvFileDescrBySndFileId,
Expand Down Expand Up @@ -88,6 +89,7 @@ import Control.Monad.IO.Class
import Data.Either (rights)
import Data.Int (Int64)
import Data.Maybe (fromMaybe, isJust, listToMaybe)
import Data.Word (Word32)
import Data.Text (Text)
import Data.Time (addUTCTime)
import Data.Time.Clock (UTCTime (..), getCurrentTime, nominalDay)
Expand Down Expand Up @@ -184,7 +186,7 @@ createSndDirectFileTransfer db userId Contact {contactId} filePath FileInvitatio
db
"INSERT INTO snd_files (file_id, file_status, file_inline, connection_id, created_at, updated_at) VALUES (?,?,?,?,?,?)"
(fileId, fileStatus, fileInline, connId, currentTs, currentTs)
pure FileTransferMeta {fileId, xftpSndFile = Nothing, fileName, filePath, fileSize, fileInline, chunkSize, cancelled = False}
pure FileTransferMeta {fileId, xftpSndFile = Nothing, xftpRedirectFor = Nothing, fileName, filePath, fileSize, fileInline, chunkSize, cancelled = False}

createSndDirectFTConnection :: DB.Connection -> User -> Int64 -> (CommandId, ConnId) -> SubscriptionMode -> IO ()
createSndDirectFTConnection db user@User {userId} fileId (cmdId, acId) subMode = do
Expand All @@ -204,7 +206,7 @@ createSndGroupFileTransfer db userId GroupInfo {groupId} filePath FileInvitation
"INSERT INTO files (user_id, group_id, file_name, file_path, file_size, chunk_size, file_inline, ci_file_status, protocol, created_at, updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?)"
((userId, groupId, fileName, filePath, fileSize, chunkSize) :. (fileInline, CIFSSndStored, FPSMP, currentTs, currentTs))
fileId <- insertedRowId db
pure FileTransferMeta {fileId, xftpSndFile = Nothing, fileName, filePath, fileSize, fileInline, chunkSize, cancelled = False}
pure FileTransferMeta {fileId, xftpSndFile = Nothing, xftpRedirectFor = Nothing, fileName, filePath, fileSize, fileInline, chunkSize, cancelled = False}

createSndGroupFileTransferConnection :: DB.Connection -> User -> Int64 -> (CommandId, ConnId) -> GroupMember -> SubscriptionMode -> IO ()
createSndGroupFileTransferConnection db user@User {userId} fileId (cmdId, acId) GroupMember {groupMemberId} subMode = do
Expand Down Expand Up @@ -277,16 +279,16 @@ getSndFTViaMsgDelivery db User {userId} Connection {connId, agentConnId} agentMs
(\n -> SndFileTransfer {fileId, fileStatus, fileName, fileSize, chunkSize, filePath, fileDescrId, fileInline, groupMemberId, recipientDisplayName = n, connId, agentConnId})
<$> (contactName_ <|> memberName_)

createSndFileTransferXFTP :: DB.Connection -> User -> ContactOrGroup -> CryptoFile -> FileInvitation -> AgentSndFileId -> Integer -> IO FileTransferMeta
createSndFileTransferXFTP db User {userId} contactOrGroup (CryptoFile filePath cryptoArgs) FileInvitation {fileName, fileSize} agentSndFileId chunkSize = do
createSndFileTransferXFTP :: DB.Connection -> User -> Maybe ContactOrGroup -> CryptoFile -> FileInvitation -> AgentSndFileId -> Maybe FileTransferId -> Integer -> IO FileTransferMeta
createSndFileTransferXFTP db User {userId} contactOrGroup_ (CryptoFile filePath cryptoArgs) FileInvitation {fileName, fileSize} agentSndFileId xftpRedirectFor chunkSize = do
currentTs <- getCurrentTime
let xftpSndFile = Just XFTPSndFile {agentSndFileId, privateSndFileDescr = Nothing, agentSndFileDeleted = False, cryptoArgs}
DB.execute
db
"INSERT INTO files (contact_id, group_id, user_id, file_name, file_path, file_crypto_key, file_crypto_nonce, file_size, chunk_size, agent_snd_file_id, ci_file_status, protocol, created_at, updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
(contactAndGroupIds contactOrGroup :. (userId, fileName, filePath, CF.fileKey <$> cryptoArgs, CF.fileNonce <$> cryptoArgs, fileSize, chunkSize, agentSndFileId, CIFSSndStored, FPXFTP, currentTs, currentTs))
"INSERT INTO files (contact_id, group_id, user_id, file_name, file_path, file_crypto_key, file_crypto_nonce, file_size, chunk_size, redirect_file_id, agent_snd_file_id, ci_file_status, protocol, created_at, updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
(maybe (Nothing, Nothing) contactAndGroupIds contactOrGroup_ :. (userId, fileName, filePath, CF.fileKey <$> cryptoArgs, CF.fileNonce <$> cryptoArgs, fileSize, chunkSize) :. (xftpRedirectFor, agentSndFileId, CIFSSndStored, FPXFTP, currentTs, currentTs))
fileId <- insertedRowId db
pure FileTransferMeta {fileId, xftpSndFile, fileName, filePath, fileSize, fileInline = Nothing, chunkSize, cancelled = False}
pure FileTransferMeta {fileId, xftpSndFile, xftpRedirectFor, fileName, filePath, fileSize, fileInline = Nothing, chunkSize, cancelled = False}

createSndFTDescrXFTP :: DB.Connection -> User -> Maybe GroupMember -> Connection -> FileTransferMeta -> FileDescr -> IO ()
createSndFTDescrXFTP db User {userId} m Connection {connId} FileTransferMeta {fileId} FileDescr {fileDescrText, fileDescrPartNo, fileDescrComplete} = do
Expand Down Expand Up @@ -536,6 +538,23 @@ createRcvGroupFileTransfer db userId GroupMember {groupId, groupMemberId, localD
(fileId, FSNew, fileConnReq, fileInline, rcvFileInline, groupMemberId, rfdId, currentTs, currentTs)
pure RcvFileTransfer {fileId, xftpRcvFile, fileInvitation = f, fileStatus = RFSNew, rcvFileInline, senderDisplayName = c, chunkSize, cancelled = False, grpMemberId = Just groupMemberId, cryptoArgs = Nothing}

createRcvDirectFileTransfer :: DB.Connection -> UserId -> CryptoFile -> Int64 -> Word32 -> ExceptT StoreError IO Int64
dpwiz marked this conversation as resolved.
Show resolved Hide resolved
createRcvDirectFileTransfer db userId (CryptoFile filePath cfArgs_) fileSize chunkSize = do
currentTs <- liftIO getCurrentTime
fileId <- liftIO $ do
DB.execute
db
"INSERT INTO files (user_id, file_name, file_path, file_size, chunk_size, ci_file_status, protocol, created_at, updated_at) VALUES (?,?,?,?,?,?,?,?,?)"
(userId, takeFileName filePath, filePath, fileSize, chunkSize, CIFSRcvInvitation, FPXFTP, currentTs, currentTs)
insertedRowId db
liftIO . forM_ cfArgs_ $ \cfArgs -> setFileCryptoArgs_ db fileId cfArgs currentTs
liftIO $
DB.execute
db
"INSERT INTO rcv_files (file_id, file_status, created_at, updated_at) VALUES (?,?,?,?)"
(fileId, FSNew, currentTs, currentTs)
pure fileId

createRcvFD_ :: DB.Connection -> UserId -> UTCTime -> FileDescr -> ExceptT StoreError IO RcvFileDescr
createRcvFD_ db userId currentTs FileDescr {fileDescrText, fileDescrPartNo, fileDescrComplete} = do
when (fileDescrPartNo /= 0) $ throwError SERcvFileInvalidDescrPart
Expand Down Expand Up @@ -662,16 +681,19 @@ getRcvFileTransfer_ db userId fileId = do
(FileStatus, Maybe ConnReqInvitation, Maybe Int64, String, Integer, Integer, Maybe Bool) :. (Maybe ContactName, Maybe ContactName, Maybe FilePath, Maybe C.SbKey, Maybe C.CbNonce, Maybe InlineFileMode, Maybe InlineFileMode, Maybe AgentRcvFileId, Bool) :. (Maybe Int64, Maybe AgentConnId) ->
ExceptT StoreError IO RcvFileTransfer
rcvFileTransfer rfd_ ((fileStatus', fileConnReq, grpMemberId, fileName, fileSize, chunkSize, cancelled_) :. (contactName_, memberName_, filePath_, fileKey, fileNonce, fileInline, rcvFileInline, agentRcvFileId, agentRcvFileDeleted) :. (connId_, agentConnId_)) =
case contactName_ <|> memberName_ of
case contactName_ <|> memberName_ <|> directName_ of
dpwiz marked this conversation as resolved.
Show resolved Hide resolved
Nothing -> throwError $ SERcvFileInvalid fileId
Just name -> do
Just name ->
case fileStatus' of
FSNew -> pure $ ft name RFSNew
FSAccepted -> ft name . RFSAccepted <$> rfi
FSConnected -> ft name . RFSConnected <$> rfi
FSComplete -> ft name . RFSComplete <$> rfi
FSCancelled -> ft name . RFSCancelled <$> rfi_
where
directName_ = case (connId_, agentRcvFileId, filePath_) of
(Nothing, Just _, Just _) -> Just "direct" -- filePath marks files that are accepted from contact or, in this case, set by createRcvDirectFileTransfer
_ -> Nothing
ft senderDisplayName fileStatus =
let fileInvitation = FileInvitation {fileName, fileSize, fileDigest = Nothing, fileConnReq, fileInline, fileDescr = Nothing}
cryptoArgs = CFArgs <$> fileKey <*> fileNonce
Expand Down Expand Up @@ -906,17 +928,17 @@ getFileTransferMeta_ db userId fileId =
DB.query
db
[sql|
SELECT file_name, file_size, chunk_size, file_path, file_crypto_key, file_crypto_nonce, file_inline, agent_snd_file_id, agent_snd_file_deleted, private_snd_file_descr, cancelled
SELECT file_name, file_size, chunk_size, file_path, file_crypto_key, file_crypto_nonce, file_inline, agent_snd_file_id, agent_snd_file_deleted, private_snd_file_descr, cancelled, redirect_file_id
FROM files
WHERE user_id = ? AND file_id = ?
|]
(userId, fileId)
where
fileTransferMeta :: (String, Integer, Integer, FilePath, Maybe C.SbKey, Maybe C.CbNonce, Maybe InlineFileMode, Maybe AgentSndFileId, Bool, Maybe Text, Maybe Bool) -> FileTransferMeta
fileTransferMeta (fileName, fileSize, chunkSize, filePath, fileKey, fileNonce, fileInline, aSndFileId_, agentSndFileDeleted, privateSndFileDescr, cancelled_) =
fileTransferMeta :: (String, Integer, Integer, FilePath, Maybe C.SbKey, Maybe C.CbNonce, Maybe InlineFileMode, Maybe AgentSndFileId, Bool, Maybe Text, Maybe Bool, Maybe FileTransferId) -> FileTransferMeta
fileTransferMeta (fileName, fileSize, chunkSize, filePath, fileKey, fileNonce, fileInline, aSndFileId_, agentSndFileDeleted, privateSndFileDescr, cancelled_, xftpRedirectFor) =
let cryptoArgs = CFArgs <$> fileKey <*> fileNonce
xftpSndFile = (\fId -> XFTPSndFile {agentSndFileId = fId, privateSndFileDescr, agentSndFileDeleted, cryptoArgs}) <$> aSndFileId_
in FileTransferMeta {fileId, xftpSndFile, fileName, fileSize, chunkSize, filePath, fileInline, cancelled = fromMaybe False cancelled_}
in FileTransferMeta {fileId, xftpSndFile, xftpRedirectFor, fileName, fileSize, chunkSize, filePath, fileInline, cancelled = fromMaybe False cancelled_}

createLocalFile :: ToField (CIFileStatus d) => CIFileStatus d -> DB.Connection -> User -> NoteFolder -> ChatItemId -> UTCTime -> CryptoFile -> Integer -> Integer -> IO Int64
createLocalFile fileStatus db User {userId} NoteFolder {noteFolderId} chatItemId itemTs CryptoFile {filePath, cryptoArgs} fileSize fileChunkSize = do
Expand Down
7 changes: 7 additions & 0 deletions src/Simplex/Chat/Store/Messages.hs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}
{-# OPTIONS_GHC -fno-warn-ambiguous-fields #-}

Check warning on line 14 in src/Simplex/Chat/Store/Messages.hs

View workflow job for this annotation

GitHub Actions / build-ubuntu-20.04-8.10.7

unrecognised warning flag: -fno-warn-ambiguous-fields

Check warning on line 14 in src/Simplex/Chat/Store/Messages.hs

View workflow job for this annotation

GitHub Actions / build-ubuntu-20.04-8.10.7

unrecognised warning flag: -fno-warn-ambiguous-fields

module Simplex.Chat.Store.Messages
( getContactConnIds_,
Expand Down Expand Up @@ -92,6 +92,7 @@
getLocalChatItemIdByText,
getLocalChatItemIdByText',
getChatItemByFileId,
lookupChatItemByFileId,
getChatItemByGroupId,
updateDirectChatItemStatus,
getTimedItems,
Expand Down Expand Up @@ -417,7 +418,7 @@
insertChatItemMessage_ :: DB.Connection -> ChatItemId -> MessageId -> UTCTime -> IO ()
insertChatItemMessage_ db ciId msgId ts = DB.execute db "INSERT INTO chat_item_messages (chat_item_id, message_id, created_at, updated_at) VALUES (?,?,?,?)" (ciId, msgId, ts, ts)

getChatItemQuote_ :: ChatTypeQuotable c => DB.Connection -> User -> ChatDirection c 'MDRcv -> QuotedMsg -> IO (CIQuote c)

Check warning on line 421 in src/Simplex/Chat/Store/Messages.hs

View workflow job for this annotation

GitHub Actions / build-ubuntu-20.04-9.6.3

Redundant constraint: ChatTypeQuotable c

Check warning on line 421 in src/Simplex/Chat/Store/Messages.hs

View workflow job for this annotation

GitHub Actions / build-ubuntu-22.04-9.6.3

Redundant constraint: ChatTypeQuotable c

Check warning on line 421 in src/Simplex/Chat/Store/Messages.hs

View workflow job for this annotation

GitHub Actions / build-macos-latest-9.6.3

Redundant constraint: ChatTypeQuotable c

Check warning on line 421 in src/Simplex/Chat/Store/Messages.hs

View workflow job for this annotation

GitHub Actions / build-windows-latest-9.6.3

Redundant constraint: ChatTypeQuotable c
getChatItemQuote_ db User {userId, userContactId} chatDirection QuotedMsg {msgRef = MsgRef {msgId, sentAt, sent, memberId}, content} =
case chatDirection of
CDDirectRcv Contact {contactId} -> getDirectChatItemQuote_ contactId (not sent)
Expand Down Expand Up @@ -2085,6 +2086,12 @@
(userId, fileId)
getAChatItem db vr user chatRef itemId

lookupChatItemByFileId :: DB.Connection -> VersionRange -> User -> Int64 -> ExceptT StoreError IO (Maybe AChatItem)
lookupChatItemByFileId db vr user fileId = do
fmap Just (getChatItemByFileId db vr user fileId) `catchError` \case
SEChatItemNotFoundByFileId {} -> pure Nothing
e -> throwError e

getChatItemByGroupId :: DB.Connection -> VersionRange -> User -> GroupId -> ExceptT StoreError IO AChatItem
getChatItemByGroupId db vr user@User {userId} groupId = do
(chatRef, itemId) <-
Expand Down