core: refactor connectViaContact (#6034)

* core: refactor connectViaContact

* true, comment

* optimize connectViaContact for prepared entities

* refactor Connection

* refactor pcc

---------

Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
This commit is contained in:
spaced4ndy
2025-07-04 09:47:40 +00:00
committed by GitHub
parent ad5ccaaa9d
commit fc98558a37
11 changed files with 274 additions and 259 deletions
+74 -99
View File
@@ -1176,7 +1176,7 @@ processChatCommand' vr = \case
updateContactAccepted db user ct contactUsed
conn' <-
if sqSecured
then conn {connStatus = ConnSndReady} <$ updateConnectionStatusFromTo db connId ConnNew ConnSndReady
then updateConnectionStatusFromTo db conn ConnNew ConnSndReady
else pure conn
pure ct {contactUsed, activeConn = Just conn'}
pure (ct', sqSecured)
@@ -1816,7 +1816,7 @@ processChatCommand' vr = \case
gInfo' <- withFastStore $ \db -> updatePreparedGroupUser db vr user gInfo hostMember newUser
pure $ CRGroupUserChanged user gInfo newUser gInfo'
APIConnectPreparedContact contactId incognito msgContent_ -> withUser $ \user -> do
Contact {preparedContact} <- withFastStore $ \db -> getContact db vr user contactId
ct@Contact {preparedContact} <- withFastStore $ \db -> getContact db vr user contactId
case preparedContact of
Nothing -> throwCmdError "contact doesn't have link to connect"
Just PreparedContact {connLinkToConnect = ACCL SCMInvitation ccLink} -> do
@@ -1836,15 +1836,15 @@ processChatCommand' vr = \case
smId <- getSharedMsgId
withFastStore' $ \db -> setRequestSharedMsgIdForContact db contactId smId
pure (smId, mc)
connectViaContact user incognito ccLink welcomeSharedMsgId msg_ (Just $ ACCGContact contactId) >>= \case
CRSentInvitation {customUserProfile} -> do
connectViaContact user (Just $ PCEContact ct) incognito ccLink welcomeSharedMsgId msg_ >>= \case
CVRSentInvitation _conn customUserProfile -> do
-- get updated contact with connection
ct' <- withFastStore $ \db -> getContact db vr user contactId
forM_ msg_ $ \(sharedMsgId, mc) -> do
ci <- createChatItem user (CDDirectSnd ct') False (CISndMsgContent mc) (Just sharedMsgId) Nothing
toView $ CEvtNewChatItems user [ci]
pure $ CRStartedConnectionToContact user ct' customUserProfile
cr -> pure cr
CVRConnectedContact ct' -> pure $ CRContactAlreadyExists user ct'
APIConnectPreparedGroup groupId incognito msgContent_ -> withUser $ \user -> do
(gInfo, hostMember) <- withFastStore $ \db -> (,) <$> getGroupInfo db vr user groupId <*> getHostMember db vr user groupId
case preparedGroup gInfo of
@@ -1856,8 +1856,8 @@ processChatCommand' vr = \case
smId <- getSharedMsgId
withFastStore' $ \db -> setRequestSharedMsgIdForGroup db groupId smId
pure (smId, mc)
connectViaContact user incognito connLinkToConnect welcomeSharedMsgId msg_ (Just $ ACCGGroup gInfo $ groupMemberId' hostMember) >>= \case
CRSentInvitation {customUserProfile} -> do
connectViaContact user (Just $ PCEGroup gInfo hostMember) incognito connLinkToConnect welcomeSharedMsgId msg_ >>= \case
CVRSentInvitation _conn customUserProfile -> do
-- get updated group info (connLinkStartedConnection and incognito membership)
gInfo' <- withFastStore $ \db -> do
liftIO $ setPreparedGroupStartedConnection db groupId
@@ -1866,13 +1866,16 @@ processChatCommand' vr = \case
ci <- createChatItem user (CDGroupSnd gInfo' Nothing) False (CISndMsgContent mc) (Just sharedMsgId) Nothing
toView $ CEvtNewChatItems user [ci]
pure $ CRStartedConnectionToGroup user gInfo' customUserProfile
cr -> pure cr
CVRConnectedContact _ct -> throwChatError $ CEException "contact already exists when connecting to group"
APIConnect userId incognito acl -> withUserId userId $ \user -> case acl of
ACCL SCMInvitation ccLink -> do
(dbConnId, incognitoProfile) <- connectViaInvitation user incognito ccLink Nothing
pcc <- withFastStore $ \db -> getPendingContactConnection db userId dbConnId
(conn, incognitoProfile) <- connectViaInvitation user incognito ccLink Nothing
let pcc = mkPendingContactConnection conn $ Just ccLink
pure $ CRSentConfirmation user pcc incognitoProfile
ACCL SCMContact ccLink -> connectViaContact user incognito ccLink Nothing Nothing Nothing
ACCL SCMContact ccLink ->
connectViaContact user Nothing incognito ccLink Nothing Nothing >>= \case
CVRConnectedContact ct -> pure $ CRContactAlreadyExists user ct
CVRSentInvitation conn incognitoProfile -> pure $ CRSentInvitation user (mkPendingContactConnection conn Nothing) incognitoProfile
Connect incognito (Just cLink@(ACL m cLink')) -> withUser $ \user -> do
(ccLink, plan) <- connectPlan user cLink `catchChatError` \e -> case cLink' of CLFull cReq -> pure (ACCL m (CCLink cReq Nothing), CPInvitationLink (ILPOk Nothing)); _ -> throwError e
connectWithPlan user incognito ccLink plan
@@ -2907,7 +2910,7 @@ processChatCommand' vr = \case
CTGroup -> withFastStore $ \db -> getGroupChatItemIdByText' db user cId msg
CTLocal -> withFastStore $ \db -> getLocalChatItemIdByText' db user cId msg
_ -> throwCmdError "not supported"
connectViaInvitation :: User -> IncognitoEnabled -> CreatedLinkInvitation -> Maybe ContactId -> CM (Int64, Maybe Profile)
connectViaInvitation :: User -> IncognitoEnabled -> CreatedLinkInvitation -> Maybe ContactId -> CM (Connection, Maybe Profile)
connectViaInvitation user@User {userId} incognito (CCLink cReq@(CRInvitationUri crData e2e) sLnk_) contactId_ =
withInvitationLock "connect" (strEncode cReq) $ do
subMode <- chatReadVar subscriptionMode
@@ -2926,73 +2929,66 @@ processChatCommand' vr = \case
dm <- encodeConnInfoPQ pqSup' chatV $ XInfo profileToSend
withFastStore' (\db -> getConnectionEntityByConnReq db vr user cReqs) >>= \case
Nothing -> joinNewConn chatV dm
Just (RcvDirectMsgConnection conn@Connection {connId = dbConnId, connStatus, contactConnInitiated} _ct_)
Just (RcvDirectMsgConnection conn@Connection {connStatus, contactConnInitiated} _ct_)
| connStatus == ConnNew && contactConnInitiated -> joinNewConn chatV dm -- own connection link
| connStatus == ConnPrepared -> joinPreparedConn dbConnId (aConnId conn) dm -- retrying join after error
| connStatus == ConnPrepared -> joinPreparedConn conn dm -- retrying join after error
Just ent -> throwCmdError $ "connection is not RcvDirectMsgConnection: " <> show (connEntityInfo ent)
where
joinNewConn chatV dm = do
connId <- withAgent $ \a -> prepareConnectionToJoin a (aUserId user) True cReq pqSup'
let ccLink = CCLink cReq $ serverShortLink <$> sLnk_
createdAt <- liftIO getCurrentTime
(dbConnId, _) <- withFastStore' $ \db -> createDirectConnection_ db userId connId ccLink contactId_ ConnPrepared (incognitoProfile $> profileToSend) subMode chatV pqSup' createdAt
joinPreparedConn dbConnId connId dm
joinPreparedConn dbConnId connId dm = do
(sqSecured, _serviceId) <- withAgent $ \a -> joinConnection a (aUserId user) connId True cReq dm pqSup' subMode
conn <- withFastStore' $ \db -> createDirectConnection' db userId connId ccLink contactId_ ConnPrepared (incognitoProfile $> profileToSend) subMode chatV pqSup'
joinPreparedConn conn dm
joinPreparedConn conn@Connection {connId = dbConnId} dm = do
(sqSecured, _serviceId) <- withAgent $ \a -> joinConnection a (aUserId user) (aConnId conn) True cReq dm pqSup' subMode
let newStatus = if sqSecured then ConnSndReady else ConnJoined
withFastStore' $ \db -> updateConnectionStatusFromTo db dbConnId ConnPrepared newStatus
pure (dbConnId, incognitoProfile)
conn' <- withFastStore' $ \db -> updateConnectionStatusFromTo db conn ConnPrepared newStatus
pure (conn', incognitoProfile)
cReqs =
( CRInvitationUri crData {crScheme = SSSimplex} e2e,
CRInvitationUri crData {crScheme = simplexChat} e2e
)
connectViaContact :: User -> IncognitoEnabled -> CreatedLinkContact -> Maybe SharedMsgId -> Maybe (SharedMsgId, MsgContent) -> Maybe AttachConnToContactOrGroup -> CM ChatResponse
connectViaContact user@User {userId} incognito (CCLink cReq@(CRContactUri crData@ConnReqUriData {crClientData}) sLnk) welcomeSharedMsgId msg_ attachConnTo_ = withInvitationLock "connectViaContact" (strEncode cReq) $ do
connectViaContact :: User -> Maybe PreparedChatEntity -> IncognitoEnabled -> CreatedLinkContact -> Maybe SharedMsgId -> Maybe (SharedMsgId, MsgContent) -> CM ConnectViaContactResult
connectViaContact user@User {userId} preparedEntity_ incognito (CCLink cReq@(CRContactUri crData@ConnReqUriData {crClientData}) sLnk) welcomeSharedMsgId msg_ = withInvitationLock "connectViaContact" (strEncode cReq) $ do
let groupLinkId = crClientData >>= decodeJSON >>= \(CRDataGroup gli) -> Just gli
cReqHash = ConnReqUriHash . C.sha256Hash . strEncode
cReqHash1 = cReqHash $ CRContactUri crData {crScheme = SSSimplex}
cReqHash2 = cReqHash $ CRContactUri crData {crScheme = simplexChat}
case groupLinkId of
-- contact address
-- groupLinkId is Nothing for business chats
when (isJust msg_ && isJust groupLinkId) $ throwChatError CEConnReqMessageProhibited
case preparedEntity_ of
Just (PCEContact ct@Contact {activeConn}) -> case activeConn of
Nothing -> connect' Nothing cReqHash1 Nothing
Just conn@Connection {connStatus, xContactId} -> case connStatus of
ConnPrepared -> joinPreparedConn' xContactId conn False
_ -> pure $ CVRConnectedContact ct
Just (PCEGroup _gInfo GroupMember {activeConn}) -> case activeConn of
Nothing -> connect' groupLinkId cReqHash1 Nothing
Just conn@Connection {connStatus, xContactId} -> case connStatus of
ConnPrepared -> joinPreparedConn' xContactId conn $ isJust groupLinkId
_ -> connect' groupLinkId cReqHash1 xContactId -- why not "already connected" for host member?
Nothing ->
withFastStore' (\db -> getConnReqContactXContactId db vr user cReqHash1 cReqHash2) >>= \case
(Just Contact {activeConn = Just conn@Connection {connStatus = ConnPrepared}}, Just (xContactId, _)) -> do
incognitoProfile <- joinPreparedConn' xContactId conn
pure $ CRSentInvitation user (toPCC conn) incognitoProfile
(Just contact, _) -> pure $ CRContactAlreadyExists user contact
(Nothing, Just (xContactId, Just conn@Connection {connId, connStatus = ConnPrepared})) -> do
incognitoProfile <- joinPreparedConn' xContactId conn
-- TODO [short links] align Connection and PendingContactConnection so it doesn't need to be read again
pcc <- withStore $ \db -> getPendingContactConnection db userId connId
pure $ CRSentInvitation user pcc incognitoProfile
(Nothing, xContactId_) -> procCmd $ do
Right ct@Contact {activeConn} -> case groupLinkId of
Nothing -> case activeConn of
Just conn@Connection {connStatus = ConnPrepared, xContactId} -> joinPreparedConn' xContactId conn False
_ -> pure $ CVRConnectedContact ct
Just gLinkId ->
-- allow repeat contact request
-- TODO [short links] is this branch needed? it probably remained from the time we created host contact
connect' (Just gLinkId) cReqHash1 Nothing
Left conn_ -> case conn_ of
Just conn@Connection {connStatus = ConnPrepared, xContactId} -> joinPreparedConn' xContactId conn $ isJust groupLinkId
-- TODO [short links] this is executed on repeat request after success
-- it probably should send the second message without creating the second connection?
xContactId <- mkXContactId $ fst <$> xContactId_
connect' Nothing cReqHash1 xContactId False
-- group link
Just gLinkId -> do
-- TODO [short links] reset "connection started" column
when (isJust msg_) $ throwChatError CEConnReqMessageProhibited
withFastStore' (\db -> getConnReqContactXContactId db vr user cReqHash1 cReqHash2) >>= \case
(Just _contact, _) -> procCmd $ do
-- allow repeat contact request
-- TODO [short links] is this branch needed? it probably remained from the time we created host contact
newXContactId <- XContactId <$> drgRandomBytes 16
connect' (Just gLinkId) cReqHash1 newXContactId True
(Nothing, Just (xContactId, Just conn@Connection {connStatus = ConnPrepared})) -> do
incognitoProfile <- joinPreparedConn' xContactId conn
pure $ CRSentInvitation user (toPCC conn) incognitoProfile
(_, xContactId_) -> procCmd $ do
-- TODO [short links] this is executed on repeat request after success
-- it probably should send the second message without creating the second connection?
xContactId <- mkXContactId $ fst <$> xContactId_
connect' (Just gLinkId) cReqHash1 xContactId True
Just Connection {xContactId} -> connect' groupLinkId cReqHash1 xContactId
Nothing -> connect' groupLinkId cReqHash1 Nothing
where
joinPreparedConn' xContactId conn@Connection {connId = dbConnId, agentConnId = AgentConnId connId, connChatVersion = chatV, customUserProfileId = pId_} = do
joinPreparedConn' xContactId_ conn@Connection {customUserProfileId = pId_} inGroup = do
xContactId <- mkXContactId xContactId_
incognitoProfile <- getOrCreateIncognitoProfile
joinContact user dbConnId connId cReq incognitoProfile xContactId welcomeSharedMsgId msg_ False PQSupportOn chatV
pure incognitoProfile
conn' <- joinContact user conn cReq incognitoProfile xContactId welcomeSharedMsgId msg_ inGroup PQSupportOn
pure $ CVRSentInvitation conn' incognitoProfile
where
getOrCreateIncognitoProfile
| incognito =
@@ -3010,33 +3006,21 @@ processChatCommand' vr = \case
createdAt <- liftIO getCurrentTime
void $ createIncognitoProfile_ db userId createdAt p
pure $ Just p
toPCC Connection {connId, agentConnId, connStatus, viaUserContactLink, groupLinkId, customUserProfileId, createdAt} =
PendingContactConnection
{ pccConnId = connId,
pccAgentConnId = agentConnId,
pccConnStatus = connStatus,
viaContactUri = True,
viaUserContactLink,
groupLinkId,
customUserProfileId,
connLinkInv = Nothing,
localAlias = "",
createdAt,
updatedAt = createdAt
}
mkXContactId = maybe (XContactId <$> drgRandomBytes 16) pure
connect' groupLinkId cReqHash xContactId inGroup = do
let pqSup = if inGroup then PQSupportOff else PQSupportOn
connect' groupLinkId cReqHash xContactId_ = do
let inGroup = isJust groupLinkId
pqSup = if inGroup then PQSupportOff else PQSupportOn
(connId, chatV) <- prepareContact user cReq pqSup
xContactId <- mkXContactId xContactId_
-- [incognito] generate profile to send
incognitoProfile <- if incognito then Just <$> liftIO generateRandomProfile else pure Nothing
subMode <- chatReadVar subscriptionMode
let sLnk' = serverShortLink <$> sLnk
conn@PendingContactConnection {pccConnId} <- withFastStore' $ \db -> createConnReqConnection db userId connId cReqHash sLnk' attachConnTo_ xContactId incognitoProfile groupLinkId subMode chatV pqSup
joinContact user pccConnId connId cReq incognitoProfile xContactId welcomeSharedMsgId msg_ inGroup pqSup chatV
pure $ CRSentInvitation user conn incognitoProfile
conn <- withFastStore' $ \db -> createConnReqConnection db userId connId preparedEntity_ cReqHash sLnk' xContactId incognitoProfile groupLinkId subMode chatV pqSup
conn' <- joinContact user conn cReq incognitoProfile xContactId welcomeSharedMsgId msg_ inGroup pqSup
pure $ CVRSentInvitation conn' incognitoProfile
connectContactViaAddress :: User -> IncognitoEnabled -> Contact -> CreatedLinkContact -> CM ChatResponse
connectContactViaAddress user incognito ct (CCLink cReq shortLink) =
connectContactViaAddress user@User {userId} incognito ct@Contact {contactId} (CCLink cReq shortLink) =
withInvitationLock "connectContactViaAddress" (strEncode cReq) $ do
newXContactId <- XContactId <$> drgRandomBytes 16
let pqSup = PQSupportOn
@@ -3045,8 +3029,9 @@ processChatCommand' vr = \case
-- [incognito] generate profile to send
incognitoProfile <- if incognito then Just <$> liftIO generateRandomProfile else pure Nothing
subMode <- chatReadVar subscriptionMode
(pccConnId, ct') <- withFastStore $ \db -> createAddressContactConnection db vr user ct connId cReqHash shortLink newXContactId incognitoProfile subMode chatV pqSup
joinContact user pccConnId connId cReq incognitoProfile newXContactId Nothing Nothing False pqSup chatV
conn <- withFastStore' $ \db -> createConnReqConnection db userId connId (Just $ PCEContact ct) cReqHash shortLink newXContactId incognitoProfile Nothing subMode chatV pqSup
void $ joinContact user conn cReq incognitoProfile newXContactId Nothing Nothing False pqSup
ct' <- withStore $ \db -> getContact db vr user contactId
pure $ CRSentInvitationToContact user ct' incognitoProfile
prepareContact :: User -> ConnReqContact -> PQSupport -> CM (ConnId, VersionChat)
prepareContact user cReq pqSup = do
@@ -3059,13 +3044,13 @@ processChatCommand' vr = \case
let chatV = agentToChatVersion agentV
connId <- withAgent $ \a -> prepareConnectionToJoin a (aUserId user) True cReq pqSup
pure (connId, chatV)
joinContact :: User -> Int64 -> ConnId -> ConnReqContact -> Maybe Profile -> XContactId -> Maybe SharedMsgId -> Maybe (SharedMsgId, MsgContent) -> Bool -> PQSupport -> VersionChat -> CM ()
joinContact user pccConnId connId cReq incognitoProfile xContactId welcomeSharedMsgId msg_ inGroup pqSup chatV = do
joinContact :: User -> Connection -> ConnReqContact -> Maybe Profile -> XContactId -> Maybe SharedMsgId -> Maybe (SharedMsgId, MsgContent) -> Bool -> PQSupport -> CM Connection
joinContact user conn@Connection {connId = dbConnId, connChatVersion = chatV} cReq incognitoProfile xContactId welcomeSharedMsgId msg_ inGroup pqSup = do
let profileToSend = userProfileToSend user incognitoProfile Nothing inGroup
dm <- encodeConnInfoPQ pqSup chatV (XContact profileToSend (Just xContactId) welcomeSharedMsgId msg_)
subMode <- chatReadVar subscriptionMode
void $ withAgent $ \a -> joinConnection a (aUserId user) connId True cReq dm pqSup subMode
withFastStore' $ \db -> updateConnectionStatusFromTo db pccConnId ConnPrepared ConnJoined
void $ withAgent $ \a -> joinConnection a (aUserId user) (aConnId conn) True cReq dm pqSup subMode
withFastStore' $ \db -> updateConnectionStatusFromTo db conn ConnPrepared ConnJoined
contactMember :: Contact -> [GroupMember] -> Maybe GroupMember
contactMember Contact {contactId} =
find $ \GroupMember {memberContactId = cId, memberStatus = s} ->
@@ -3916,6 +3901,10 @@ processChatCommand' vr = \case
gVar <- asks random
liftIO $ SharedMsgId <$> encodedRandomBytes gVar 12
data ConnectViaContactResult
= CVRConnectedContact Contact
| CVRSentInvitation Connection (Maybe Profile)
protocolServers :: UserProtocol p => SProtocolType p -> ([Maybe ServerOperator], [UserServer 'PSMP], [UserServer 'PXFTP]) -> ([Maybe ServerOperator], [UserServer 'PSMP], [UserServer 'PXFTP])
protocolServers p (operators, smpServers, xftpServers) = case p of
SPSMP -> (operators, smpServers, [])
@@ -4071,27 +4060,13 @@ subscribeUserConnections vr onlyNeeded agentBatchSubscribe user = do
where
addEntity (cts, ucs, ms, sfts, rfts, pcs) = \case
RcvDirectMsgConnection c (Just ct) -> let cts' = addConn c ct cts in (cts', ucs, ms, sfts, rfts, pcs)
RcvDirectMsgConnection c Nothing -> let pcs' = addConn c (toPCC c) pcs in (cts, ucs, ms, sfts, rfts, pcs')
RcvDirectMsgConnection c Nothing -> let pcs' = addConn c (mkPendingContactConnection c Nothing) pcs in (cts, ucs, ms, sfts, rfts, pcs')
RcvGroupMsgConnection c _g m -> let ms' = addConn c (toShortMember m c) ms in (cts, ucs, ms', sfts, rfts, pcs)
SndFileConnection c sft -> let sfts' = addConn c sft sfts in (cts, ucs, ms, sfts', rfts, pcs)
RcvFileConnection c rft -> let rfts' = addConn c rft rfts in (cts, ucs, ms, sfts, rfts', pcs)
UserContactConnection c uc -> let ucs' = addConn c uc ucs in (cts, ucs', ms, sfts, rfts, pcs)
addConn :: Connection -> a -> Map ConnId a -> Map ConnId a
addConn = M.insert . aConnId
toPCC Connection {connId, agentConnId, connStatus, viaUserContactLink, groupLinkId, customUserProfileId, localAlias, createdAt} =
PendingContactConnection
{ pccConnId = connId,
pccAgentConnId = agentConnId,
pccConnStatus = connStatus,
viaContactUri = False,
viaUserContactLink,
groupLinkId,
customUserProfileId,
connLinkInv = Nothing,
localAlias,
createdAt,
updatedAt = createdAt
}
toShortMember GroupMember {groupMemberId, groupId, localDisplayName} Connection {agentConnId} =
ShortGroupMember
{ groupMemberId,
+1 -1
View File
@@ -95,7 +95,7 @@ getConnectionEntity db vr user@User {userId, userContactId} agentConnId = do
DB.query
db
[sql|
SELECT connection_id, agent_conn_id, conn_level, via_contact, via_user_contact_link, via_group_link, group_link_id, custom_user_profile_id,
SELECT connection_id, agent_conn_id, conn_level, via_contact, via_user_contact_link, via_group_link, group_link_id, xcontact_id, custom_user_profile_id,
conn_status, conn_type, contact_conn_initiated, local_alias, contact_id, group_member_id, snd_file_id, rcv_file_id, user_contact_link_id,
created_at, security_code, security_code_verified_at, pq_support, pq_encryption, pq_snd_enabled, pq_rcv_enabled, auth_err_counter, quota_err_counter,
conn_chat_version, peer_chat_min_version, peer_chat_max_version
+1 -1
View File
@@ -113,7 +113,7 @@ createOrUpdateContactRequest
cp.preferences, ct.user_preferences, ct.created_at, ct.updated_at, ct.chat_ts, ct.conn_full_link_to_connect, ct.conn_short_link_to_connect, ct.welcome_shared_msg_id, ct.request_shared_msg_id, ct.contact_request_id,
ct.contact_group_member_id, ct.contact_grp_inv_sent, ct.ui_themes, ct.chat_deleted, ct.custom_data, ct.chat_item_ttl,
-- Connection
c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.custom_user_profile_id, c.conn_status, c.conn_type, c.contact_conn_initiated, c.local_alias,
c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.xcontact_id, c.custom_user_profile_id, c.conn_status, c.conn_type, c.contact_conn_initiated, c.local_alias,
c.contact_id, c.group_member_id, c.snd_file_id, c.rcv_file_id, c.user_contact_link_id, c.created_at, c.security_code, c.security_code_verified_at, c.pq_support, c.pq_encryption, c.pq_snd_enabled, c.pq_rcv_enabled, c.auth_err_counter, c.quota_err_counter,
c.conn_chat_version, c.peer_chat_min_version, c.peer_chat_max_version
FROM contacts ct
+98 -50
View File
@@ -26,12 +26,11 @@ module Simplex.Chat.Store.Direct
-- * Contacts and connections functions
getPendingContactConnection,
deletePendingContactConnection,
createDirectConnection_,
createDirectConnection',
createDirectConnection,
createIncognitoProfile,
createConnReqConnection,
setPreparedGroupStartedConnection,
createAddressContactConnection,
getProfileById,
getConnReqContactXContactId,
createPreparedContact,
@@ -113,6 +112,7 @@ import Simplex.Messaging.Agent.Store.AgentStore (firstRow, maybeFirstRow)
import Simplex.Messaging.Agent.Store.DB (BoolInt (..))
import qualified Simplex.Messaging.Agent.Store.DB as DB
import Simplex.Messaging.Crypto.Ratchet (PQSupport)
import qualified Simplex.Messaging.Crypto.Ratchet as CR
import Simplex.Messaging.Protocol (SubscriptionMode (..))
#if defined(dbPostgres)
import Database.PostgreSQL.Simple (Only (..), Query, (:.) (..))
@@ -154,16 +154,11 @@ deletePendingContactConnection db userId connId =
|]
(userId, connId, ConnContact)
createAddressContactConnection :: DB.Connection -> VersionRangeChat -> User -> Contact -> ConnId -> ConnReqUriHash -> Maybe ShortLinkContact -> XContactId -> Maybe Profile -> SubscriptionMode -> VersionChat -> PQSupport -> ExceptT StoreError IO (Int64, Contact)
createAddressContactConnection db vr user@User {userId} Contact {contactId} acId cReqHash sLnk xContactId incognitoProfile subMode chatV pqSup = do
PendingContactConnection {pccConnId} <- liftIO $ createConnReqConnection db userId acId cReqHash sLnk (Just $ ACCGContact contactId) xContactId incognitoProfile Nothing subMode chatV pqSup
(pccConnId,) <$> getContact db vr user contactId
createConnReqConnection :: DB.Connection -> UserId -> ConnId -> ConnReqUriHash -> Maybe ShortLinkContact -> Maybe AttachConnToContactOrGroup -> XContactId -> Maybe Profile -> Maybe GroupLinkId -> SubscriptionMode -> VersionChat -> PQSupport -> IO PendingContactConnection
createConnReqConnection db userId acId cReqHash sLnk attachConnTo_ xContactId incognitoProfile groupLinkId subMode chatV pqSup = do
createConnReqConnection :: DB.Connection -> UserId -> ConnId -> Maybe PreparedChatEntity -> ConnReqUriHash -> Maybe ShortLinkContact -> XContactId -> Maybe Profile -> Maybe GroupLinkId -> SubscriptionMode -> VersionChat -> PQSupport -> IO Connection
createConnReqConnection db userId acId preparedEntity_ cReqHash sLnk xContactId incognitoProfile groupLinkId subMode chatV pqSup = do
currentTs <- getCurrentTime
customUserProfileId <- mapM (createIncognitoProfile_ db userId currentTs) incognitoProfile
let pccConnStatus = ConnPrepared
let connStatus = ConnPrepared
DB.execute
db
[sql|
@@ -174,21 +169,51 @@ createConnReqConnection db userId acId cReqHash sLnk attachConnTo_ xContactId in
created_at, updated_at, to_subscribe, conn_chat_version, pq_support, pq_encryption
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
|]
( (userId, acId, pccConnStatus, connType, BI True)
( (userId, acId, connStatus, connType, BI True)
:. (cReqHash, sLnk, contactId_, groupMemberId_)
:. (xContactId, customUserProfileId, BI (isJust groupLinkId), groupLinkId)
:. (currentTs, currentTs, BI (subMode == SMOnlyCreate), chatV, pqSup, pqSup)
)
pccConnId <- insertedRowId db
case attachConnTo_ of
Just (ACCGGroup gInfo _gmId) -> updatePreparedGroup gInfo pccConnId customUserProfileId currentTs
connId <- insertedRowId db
case preparedEntity_ of
Just (PCEGroup gInfo _) -> updatePreparedGroup gInfo connId customUserProfileId currentTs
_ -> pure ()
pure PendingContactConnection {pccConnId, pccAgentConnId = AgentConnId acId, pccConnStatus, viaContactUri = True, viaUserContactLink = Nothing, groupLinkId, customUserProfileId, connLinkInv = Nothing, localAlias = "", createdAt = currentTs, updatedAt = currentTs}
pure
Connection
{ connId,
agentConnId = AgentConnId acId,
connChatVersion = chatV,
-- TODO (proposed):
-- - add agent version 8 for short links
-- - update agentToChatVersion to convert 8 to 16
-- - return and correctly set peer's range from link (via connRequestPQSupport)
peerChatVRange = chatInitialVRange, -- this is 1-1
connLevel = 0,
viaContact = Nothing,
viaUserContactLink = Nothing,
viaGroupLink = isJust groupLinkId,
groupLinkId,
xContactId = Just xContactId,
customUserProfileId,
connType,
connStatus,
contactConnInitiated = True,
localAlias = "",
entityId,
connectionCode = Nothing,
pqSupport = pqSup,
pqEncryption = CR.pqSupportToEnc pqSup,
pqSndEnabled = Nothing,
pqRcvEnabled = Nothing,
authErrCounter = 0,
quotaErrCounter = 0,
createdAt = currentTs
}
where
(connType, contactId_, groupMemberId_) = case attachConnTo_ of
Just (ACCGContact ctId) -> (ConnContact, Just ctId, Nothing)
Just (ACCGGroup _gInfo gmId) -> (ConnMember, Nothing, Just gmId)
Nothing -> (ConnContact, Nothing, Nothing)
(connType, contactId_, groupMemberId_, entityId) = case preparedEntity_ of
Just (PCEContact Contact {contactId}) -> (ConnContact, Just contactId, Nothing, Just contactId)
Just (PCEGroup _ GroupMember {groupMemberId}) -> (ConnMember, Nothing, Just groupMemberId, Just groupMemberId)
Nothing -> (ConnContact, Nothing, Nothing, Nothing)
updatePreparedGroup GroupInfo {groupId, membership} pccConnId customUserProfileId currentTs = do
setViaGroupLinkHash db groupId pccConnId
when (isJust customUserProfileId) $
@@ -205,20 +230,17 @@ setPreparedGroupStartedConnection db groupId = do
"UPDATE groups SET conn_link_started_connection = ?, updated_at = ? WHERE group_id = ?"
(BI True, currentTs, groupId)
getConnReqContactXContactId :: DB.Connection -> VersionRangeChat -> User -> ConnReqUriHash -> ConnReqUriHash -> IO (Maybe Contact, Maybe (XContactId, Maybe Connection))
getConnReqContactXContactId db vr user@User {userId} cReqHash1 cReqHash2 = do
getContactByConnReqHash db vr user cReqHash1 cReqHash2 >>= \case
Just (xContactId_, ct@Contact {activeConn}) -> pure (Just ct, (,activeConn) <$> xContactId_)
Nothing -> (Nothing,) <$> getConnectionXContactId
getConnReqContactXContactId :: DB.Connection -> VersionRangeChat -> User -> ConnReqUriHash -> ConnReqUriHash -> IO (Either (Maybe Connection) Contact)
getConnReqContactXContactId db vr user@User {userId} cReqHash1 cReqHash2 =
getContactByConnReqHash db vr user cReqHash1 cReqHash2 >>= maybe (Left <$> getConnection) (pure . Right)
where
getConnectionXContactId :: IO (Maybe (XContactId, Maybe Connection))
getConnectionXContactId =
maybeFirstRow toConnectionAndXContactId $
getConnection :: IO (Maybe Connection)
getConnection =
maybeFirstRow (toConnection vr) $
DB.query
db
[sql|
SELECT xcontact_id,
connection_id, agent_conn_id, conn_level, via_contact, via_user_contact_link, via_group_link, group_link_id, custom_user_profile_id, conn_status, conn_type, contact_conn_initiated, local_alias,
SELECT connection_id, agent_conn_id, conn_level, via_contact, via_user_contact_link, via_group_link, group_link_id, xcontact_id, custom_user_profile_id, conn_status, conn_type, contact_conn_initiated, local_alias,
contact_id, group_member_id, snd_file_id, rcv_file_id, user_contact_link_id, created_at, security_code, security_code_verified_at, pq_support, pq_encryption, pq_snd_enabled, pq_rcv_enabled, auth_err_counter, quota_err_counter,
conn_chat_version, peer_chat_min_version, peer_chat_max_version
FROM connections
@@ -227,24 +249,21 @@ getConnReqContactXContactId db vr user@User {userId} cReqHash1 cReqHash2 = do
LIMIT 1
|]
(userId, cReqHash1, userId, cReqHash2)
toConnectionAndXContactId :: Only XContactId :. ConnectionRow -> (XContactId, Maybe Connection)
toConnectionAndXContactId (Only xContactId_ :. connRow) = (xContactId_, Just $ toConnection vr connRow)
getContactByConnReqHash :: DB.Connection -> VersionRangeChat -> User -> ConnReqUriHash -> ConnReqUriHash -> IO (Maybe (Maybe XContactId, Contact))
getContactByConnReqHash :: DB.Connection -> VersionRangeChat -> User -> ConnReqUriHash -> ConnReqUriHash -> IO (Maybe Contact)
getContactByConnReqHash db vr user@User {userId} cReqHash1 cReqHash2 = do
r <-
maybeFirstRow toContactAndXContactId $
ct <-
maybeFirstRow (toContact vr user []) $
DB.query
db
[sql|
SELECT
c.xcontact_id,
-- Contact
ct.contact_id, ct.contact_profile_id, ct.local_display_name, ct.via_group, cp.display_name, cp.full_name, cp.image, cp.contact_link, cp.local_alias, ct.contact_used, ct.contact_status, ct.enable_ntfs, ct.send_rcpts, ct.favorite,
cp.preferences, ct.user_preferences, ct.created_at, ct.updated_at, ct.chat_ts, ct.conn_full_link_to_connect, ct.conn_short_link_to_connect, ct.welcome_shared_msg_id, ct.request_shared_msg_id, ct.contact_request_id,
ct.contact_group_member_id, ct.contact_grp_inv_sent, ct.ui_themes, ct.chat_deleted, ct.custom_data, ct.chat_item_ttl,
-- Connection
c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.custom_user_profile_id, c.conn_status, c.conn_type, c.contact_conn_initiated, c.local_alias,
c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.xcontact_id, c.custom_user_profile_id, c.conn_status, c.conn_type, c.contact_conn_initiated, c.local_alias,
c.contact_id, c.group_member_id, c.snd_file_id, c.rcv_file_id, c.user_contact_link_id, c.created_at, c.security_code, c.security_code_verified_at, c.pq_support, c.pq_encryption, c.pq_snd_enabled, c.pq_rcv_enabled, c.auth_err_counter, c.quota_err_counter,
c.conn_chat_version, c.peer_chat_min_version, c.peer_chat_max_version
FROM contacts ct
@@ -258,18 +277,47 @@ getContactByConnReqHash db vr user@User {userId} cReqHash1 cReqHash2 = do
LIMIT 1
|]
(userId, cReqHash1, userId, cReqHash2, CSActive)
mapM (traverse $ addDirectChatTags db) r
where
toContactAndXContactId :: Only (Maybe XContactId) :. (ContactRow :. MaybeConnectionRow) -> (Maybe XContactId, Contact)
toContactAndXContactId (Only xContactId_ :. ctRow) = (xContactId_, toContact vr user [] ctRow)
mapM (addDirectChatTags db) ct
createDirectConnection' :: DB.Connection -> UserId -> ConnId -> CreatedLinkInvitation -> Maybe ContactId -> ConnStatus -> Maybe Profile -> SubscriptionMode -> VersionChat -> PQSupport -> IO Connection
createDirectConnection' db userId acId ccLink contactId_ connStatus incognitoProfile subMode chatV pqSup = do
createdAt <- getCurrentTime
(connId, customUserProfileId, contactConnInitiated) <- createDirectConnection_ db userId acId ccLink contactId_ connStatus incognitoProfile subMode chatV pqSup createdAt
pure
Connection
{ connId,
agentConnId = AgentConnId acId,
connChatVersion = chatV,
peerChatVRange = chatInitialVRange, -- see comment in createConnReqConnection
connLevel = 0,
viaContact = Nothing,
viaUserContactLink = Nothing,
viaGroupLink = False,
groupLinkId = Nothing,
xContactId = Nothing,
customUserProfileId,
connType = ConnContact,
connStatus,
contactConnInitiated,
localAlias = "",
entityId = contactId_,
connectionCode = Nothing,
pqSupport = pqSup,
pqEncryption = CR.pqSupportToEnc pqSup,
pqSndEnabled = Nothing,
pqRcvEnabled = Nothing,
authErrCounter = 0,
quotaErrCounter = 0,
createdAt
}
createDirectConnection :: DB.Connection -> User -> ConnId -> CreatedLinkInvitation -> Maybe ContactId -> ConnStatus -> Maybe Profile -> SubscriptionMode -> VersionChat -> PQSupport -> IO PendingContactConnection
createDirectConnection db User {userId} acId ccLink contactId_ pccConnStatus incognitoProfile subMode chatV pqSup = do
createdAt <- getCurrentTime
(pccConnId, customUserProfileId) <- createDirectConnection_ db userId acId ccLink contactId_ pccConnStatus incognitoProfile subMode chatV pqSup createdAt
(pccConnId, customUserProfileId, _) <- createDirectConnection_ db userId acId ccLink contactId_ pccConnStatus incognitoProfile subMode chatV pqSup createdAt
pure PendingContactConnection {pccConnId, pccAgentConnId = AgentConnId acId, pccConnStatus, viaContactUri = False, viaUserContactLink = Nothing, groupLinkId = Nothing, customUserProfileId, connLinkInv = Just ccLink, localAlias = "", createdAt, updatedAt = createdAt}
createDirectConnection_ :: DB.Connection -> UserId -> ConnId -> CreatedLinkInvitation -> Maybe ContactId -> ConnStatus -> Maybe Profile -> SubscriptionMode -> VersionChat -> PQSupport -> UTCTime -> IO (Int64, Maybe Int64)
createDirectConnection_ :: DB.Connection -> UserId -> ConnId -> CreatedLinkInvitation -> Maybe ContactId -> ConnStatus -> Maybe Profile -> SubscriptionMode -> VersionChat -> PQSupport -> UTCTime -> IO (Int64, Maybe Int64, Bool)
createDirectConnection_ db userId acId (CCLink cReq shortLinkInv) contactId_ pccConnStatus incognitoProfile subMode chatV pqSup createdAt = do
customUserProfileId <- mapM (createIncognitoProfile_ db userId createdAt) incognitoProfile
let contactConnInitiated = pccConnStatus == ConnNew
@@ -285,7 +333,7 @@ createDirectConnection_ db userId acId (CCLink cReq shortLinkInv) contactId_ pcc
:. (createdAt, createdAt, BI (subMode == SMOnlyCreate), chatV, pqSup, pqSup)
)
dbConnId <- insertedRowId db
pure (dbConnId, customUserProfileId)
pure (dbConnId, customUserProfileId, contactConnInitiated)
createIncognitoProfile :: DB.Connection -> User -> Profile -> IO Int64
createIncognitoProfile db User {userId} p = do
@@ -856,7 +904,7 @@ getContact_ db vr user@User {userId} contactId deleted = do
cp.preferences, ct.user_preferences, ct.created_at, ct.updated_at, ct.chat_ts, ct.conn_full_link_to_connect, ct.conn_short_link_to_connect, ct.welcome_shared_msg_id, ct.request_shared_msg_id, ct.contact_request_id,
ct.contact_group_member_id, ct.contact_grp_inv_sent, ct.ui_themes, ct.chat_deleted, ct.custom_data, ct.chat_item_ttl,
-- Connection
c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.custom_user_profile_id, c.conn_status, c.conn_type, c.contact_conn_initiated, c.local_alias,
c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.xcontact_id, c.custom_user_profile_id, c.conn_status, c.conn_type, c.contact_conn_initiated, c.local_alias,
c.contact_id, c.group_member_id, c.snd_file_id, c.rcv_file_id, c.user_contact_link_id, c.created_at, c.security_code, c.security_code_verified_at, c.pq_support, c.pq_encryption, c.pq_snd_enabled, c.pq_rcv_enabled, c.auth_err_counter, c.quota_err_counter,
c.conn_chat_version, c.peer_chat_min_version, c.peer_chat_max_version
FROM contacts ct
@@ -909,7 +957,7 @@ getContactConnections db vr userId Contact {contactId} =
DB.query
db
[sql|
SELECT c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.custom_user_profile_id,
SELECT c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.xcontact_id, c.custom_user_profile_id,
c.conn_status, c.conn_type, c.contact_conn_initiated, c.local_alias, c.contact_id, c.group_member_id, c.snd_file_id, c.rcv_file_id, c.user_contact_link_id,
c.created_at, c.security_code, c.security_code_verified_at, c.pq_support, c.pq_encryption, c.pq_snd_enabled, c.pq_rcv_enabled, c.auth_err_counter, c.quota_err_counter,
c.conn_chat_version, c.peer_chat_min_version, c.peer_chat_max_version
@@ -927,7 +975,7 @@ getConnectionById db vr User {userId} connId = ExceptT $ do
DB.query
db
[sql|
SELECT connection_id, agent_conn_id, conn_level, via_contact, via_user_contact_link, via_group_link, group_link_id, custom_user_profile_id,
SELECT connection_id, agent_conn_id, conn_level, via_contact, via_user_contact_link, via_group_link, group_link_id, xcontact_id, custom_user_profile_id,
conn_status, conn_type, contact_conn_initiated, local_alias, contact_id, group_member_id, snd_file_id, rcv_file_id, user_contact_link_id,
created_at, security_code, security_code_verified_at, pq_support, pq_encryption, pq_snd_enabled, pq_rcv_enabled, auth_err_counter, quota_err_counter,
conn_chat_version, peer_chat_min_version, peer_chat_max_version
@@ -968,11 +1016,11 @@ updateConnectionStatus :: DB.Connection -> Connection -> ConnStatus -> IO ()
updateConnectionStatus db Connection {connId} = updateConnectionStatus_ db connId
{-# INLINE updateConnectionStatus #-}
updateConnectionStatusFromTo :: DB.Connection -> Int64 -> ConnStatus -> ConnStatus -> IO ()
updateConnectionStatusFromTo db connId fromStatus toStatus = do
updateConnectionStatusFromTo :: DB.Connection -> Connection -> ConnStatus -> ConnStatus -> IO Connection
updateConnectionStatusFromTo db conn@Connection {connId} fromStatus toStatus = do
maybeFirstRow fromOnly (DB.query db "SELECT conn_status FROM connections WHERE connection_id = ?" (Only connId)) >>= \case
Just status | status == fromStatus -> updateConnectionStatus_ db connId toStatus
_ -> pure ()
Just status | status == fromStatus -> updateConnectionStatus_ db connId toStatus $> conn {connStatus = toStatus}
_ -> pure conn
updateConnectionStatus_ :: DB.Connection -> Int64 -> ConnStatus -> IO ()
updateConnectionStatus_ db connId connStatus = do
+6 -4
View File
@@ -217,7 +217,7 @@ getGroupLinkConnection db vr User {userId} groupInfo@GroupInfo {groupId} =
DB.query
db
[sql|
SELECT c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.custom_user_profile_id,
SELECT c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.xcontact_id, c.custom_user_profile_id,
c.conn_status, c.conn_type, c.contact_conn_initiated, c.local_alias, c.contact_id, c.group_member_id, c.snd_file_id, c.rcv_file_id, c.user_contact_link_id,
c.created_at, c.security_code, c.security_code_verified_at, c.pq_support, c.pq_encryption, c.pq_snd_enabled, c.pq_rcv_enabled, c.auth_err_counter, c.quota_err_counter,
c.conn_chat_version, c.peer_chat_min_version, c.peer_chat_max_version
@@ -1011,7 +1011,7 @@ groupMemberQuery =
m.invited_by, m.invited_by_group_member_id, m.local_display_name, m.contact_id, m.contact_profile_id, p.contact_profile_id, p.display_name, p.full_name, p.image, p.contact_link, p.local_alias, p.preferences,
m.created_at, m.updated_at,
m.support_chat_ts, m.support_chat_items_unread, m.support_chat_items_member_attention, m.support_chat_items_mentions, m.support_chat_last_msg_from_member_ts,
c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.custom_user_profile_id,
c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.xcontact_id, c.custom_user_profile_id,
c.conn_status, c.conn_type, c.contact_conn_initiated, c.local_alias, c.contact_id, c.group_member_id, c.snd_file_id, c.rcv_file_id, c.user_contact_link_id,
c.created_at, c.security_code, c.security_code_verified_at, c.pq_support, c.pq_encryption, c.pq_snd_enabled, c.pq_rcv_enabled, c.auth_err_counter, c.quota_err_counter,
c.conn_chat_version, c.peer_chat_min_version, c.peer_chat_max_version
@@ -1836,7 +1836,7 @@ getViaGroupMember db vr User {userId, userContactId} Contact {contactId} = do
m.invited_by, m.invited_by_group_member_id, m.local_display_name, m.contact_id, m.contact_profile_id, p.contact_profile_id, p.display_name, p.full_name, p.image, p.contact_link, p.local_alias, p.preferences,
m.created_at, m.updated_at,
m.support_chat_ts, m.support_chat_items_unread, m.support_chat_items_member_attention, m.support_chat_items_mentions, m.support_chat_last_msg_from_member_ts,
c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.custom_user_profile_id,
c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.xcontact_id, c.custom_user_profile_id,
c.conn_status, c.conn_type, c.contact_conn_initiated, c.local_alias, c.contact_id, c.group_member_id, c.snd_file_id, c.rcv_file_id, c.user_contact_link_id,
c.created_at, c.security_code, c.security_code_verified_at, c.pq_support, c.pq_encryption, c.pq_snd_enabled, c.pq_rcv_enabled, c.auth_err_counter, c.quota_err_counter,
c.conn_chat_version, c.peer_chat_min_version, c.peer_chat_max_version
@@ -2464,7 +2464,7 @@ createMemberContact
db
"UPDATE group_members SET contact_id = ?, updated_at = ? WHERE contact_profile_id = ?"
(contactId, currentTs, memberContactProfileId)
DB.execute
DB.execute -- why do we insert conn_req_inv here? how is it used?
db
[sql|
INSERT INTO connections (
@@ -2489,6 +2489,7 @@ createMemberContact
viaUserContactLink = Nothing,
viaGroupLink = False,
groupLinkId = Nothing,
xContactId = Nothing,
customUserProfileId,
connLevel,
connStatus = ConnNew,
@@ -2623,6 +2624,7 @@ createMemberContactConn_
viaUserContactLink = Nothing,
viaGroupLink = False,
groupLinkId = Nothing,
xContactId = Nothing,
customUserProfileId,
connLevel,
connStatus = ConnJoined,
+2 -2
View File
@@ -370,7 +370,7 @@ getUserAddressConnection db vr User {userId} = do
DB.query
db
[sql|
SELECT c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.custom_user_profile_id,
SELECT c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.xcontact_id, c.custom_user_profile_id,
c.conn_status, c.conn_type, c.contact_conn_initiated, c.local_alias, c.contact_id, c.group_member_id, c.snd_file_id, c.rcv_file_id, c.user_contact_link_id,
c.created_at, c.security_code, c.security_code_verified_at, c.pq_support, c.pq_encryption, c.pq_snd_enabled, c.pq_rcv_enabled, c.auth_err_counter, c.quota_err_counter,
c.conn_chat_version, c.peer_chat_min_version, c.peer_chat_max_version
@@ -386,7 +386,7 @@ getUserContactLinks db vr User {userId} =
<$> DB.query
db
[sql|
SELECT c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.custom_user_profile_id,
SELECT c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.xcontact_id, c.custom_user_profile_id,
c.conn_status, c.conn_type, c.contact_conn_initiated, c.local_alias, c.contact_id, c.group_member_id, c.snd_file_id, c.rcv_file_id, c.user_contact_link_id,
c.created_at, c.security_code, c.security_code_verified_at, c.pq_support, c.pq_encryption, c.pq_snd_enabled, c.pq_rcv_enabled, c.auth_err_counter, c.quota_err_counter,
c.conn_chat_version, c.peer_chat_min_version, c.peer_chat_max_version,
@@ -200,7 +200,7 @@ Query:
cp.preferences, ct.user_preferences, ct.created_at, ct.updated_at, ct.chat_ts, ct.conn_full_link_to_connect, ct.conn_short_link_to_connect, ct.welcome_shared_msg_id, ct.request_shared_msg_id, ct.contact_request_id,
ct.contact_group_member_id, ct.contact_grp_inv_sent, ct.ui_themes, ct.chat_deleted, ct.custom_data, ct.chat_item_ttl,
-- Connection
c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.custom_user_profile_id, c.conn_status, c.conn_type, c.contact_conn_initiated, c.local_alias,
c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.xcontact_id, c.custom_user_profile_id, c.conn_status, c.conn_type, c.contact_conn_initiated, c.local_alias,
c.contact_id, c.group_member_id, c.snd_file_id, c.rcv_file_id, c.user_contact_link_id, c.created_at, c.security_code, c.security_code_verified_at, c.pq_support, c.pq_encryption, c.pq_snd_enabled, c.pq_rcv_enabled, c.auth_err_counter, c.quota_err_counter,
c.conn_chat_version, c.peer_chat_min_version, c.peer_chat_max_version
FROM contacts ct
@@ -606,7 +606,7 @@ Plan:
SEARCH connections USING INDEX idx_connections_updated_at (user_id=?)
Query:
SELECT connection_id, agent_conn_id, conn_level, via_contact, via_user_contact_link, via_group_link, group_link_id, custom_user_profile_id,
SELECT connection_id, agent_conn_id, conn_level, via_contact, via_user_contact_link, via_group_link, group_link_id, xcontact_id, custom_user_profile_id,
conn_status, conn_type, contact_conn_initiated, local_alias, contact_id, group_member_id, snd_file_id, rcv_file_id, user_contact_link_id,
created_at, security_code, security_code_verified_at, pq_support, pq_encryption, pq_snd_enabled, pq_rcv_enabled, auth_err_counter, quota_err_counter,
conn_chat_version, peer_chat_min_version, peer_chat_max_version
@@ -616,6 +616,22 @@ Query:
Plan:
SEARCH connections USING INDEX sqlite_autoindex_connections_1 (agent_conn_id=?)
Query:
SELECT connection_id, agent_conn_id, conn_level, via_contact, via_user_contact_link, via_group_link, group_link_id, xcontact_id, custom_user_profile_id, conn_status, conn_type, contact_conn_initiated, local_alias,
contact_id, group_member_id, snd_file_id, rcv_file_id, user_contact_link_id, created_at, security_code, security_code_verified_at, pq_support, pq_encryption, pq_snd_enabled, pq_rcv_enabled, auth_err_counter, quota_err_counter,
conn_chat_version, peer_chat_min_version, peer_chat_max_version
FROM connections
WHERE (user_id = ? AND via_contact_uri_hash = ?)
OR (user_id = ? AND via_contact_uri_hash = ?)
LIMIT 1
Plan:
MULTI-INDEX OR
INDEX 1
SEARCH connections USING INDEX idx_connections_via_contact_uri_hash (user_id=? AND via_contact_uri_hash=?)
INDEX 2
SEARCH connections USING INDEX idx_connections_via_contact_uri_hash (user_id=? AND via_contact_uri_hash=?)
Query:
SELECT ct.contact_id
FROM group_members m
@@ -710,23 +726,6 @@ SEARCH m USING INTEGER PRIMARY KEY (rowid=?) LEFT-JOIN
SEARCH g USING INTEGER PRIMARY KEY (rowid=?) LEFT-JOIN
SEARCH h USING INDEX idx_sent_probe_hashes_sent_probe_id (sent_probe_id=?)
Query:
SELECT xcontact_id,
connection_id, agent_conn_id, conn_level, via_contact, via_user_contact_link, via_group_link, group_link_id, custom_user_profile_id, conn_status, conn_type, contact_conn_initiated, local_alias,
contact_id, group_member_id, snd_file_id, rcv_file_id, user_contact_link_id, created_at, security_code, security_code_verified_at, pq_support, pq_encryption, pq_snd_enabled, pq_rcv_enabled, auth_err_counter, quota_err_counter,
conn_chat_version, peer_chat_min_version, peer_chat_max_version
FROM connections
WHERE (user_id = ? AND via_contact_uri_hash = ?)
OR (user_id = ? AND via_contact_uri_hash = ?)
LIMIT 1
Plan:
MULTI-INDEX OR
INDEX 1
SEARCH connections USING INDEX idx_connections_via_contact_uri_hash (user_id=? AND via_contact_uri_hash=?)
INDEX 2
SEARCH connections USING INDEX idx_connections_via_contact_uri_hash (user_id=? AND via_contact_uri_hash=?)
Query:
UPDATE chat_items SET item_status = ?, updated_at = ?
WHERE user_id = ? AND group_id = ? AND item_status = ? AND chat_item_id = ?
@@ -931,6 +930,36 @@ SEARCH i USING INTEGER PRIMARY KEY (rowid=?)
SEARCH f USING INDEX idx_files_chat_item_id (chat_item_id=?) LEFT-JOIN
SEARCH ri USING COVERING INDEX idx_chat_items_direct_shared_msg_id (user_id=? AND contact_id=? AND shared_msg_id=?) LEFT-JOIN
Query:
SELECT
-- Contact
ct.contact_id, ct.contact_profile_id, ct.local_display_name, ct.via_group, cp.display_name, cp.full_name, cp.image, cp.contact_link, cp.local_alias, ct.contact_used, ct.contact_status, ct.enable_ntfs, ct.send_rcpts, ct.favorite,
cp.preferences, ct.user_preferences, ct.created_at, ct.updated_at, ct.chat_ts, ct.conn_full_link_to_connect, ct.conn_short_link_to_connect, ct.welcome_shared_msg_id, ct.request_shared_msg_id, ct.contact_request_id,
ct.contact_group_member_id, ct.contact_grp_inv_sent, ct.ui_themes, ct.chat_deleted, ct.custom_data, ct.chat_item_ttl,
-- Connection
c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.xcontact_id, c.custom_user_profile_id, c.conn_status, c.conn_type, c.contact_conn_initiated, c.local_alias,
c.contact_id, c.group_member_id, c.snd_file_id, c.rcv_file_id, c.user_contact_link_id, c.created_at, c.security_code, c.security_code_verified_at, c.pq_support, c.pq_encryption, c.pq_snd_enabled, c.pq_rcv_enabled, c.auth_err_counter, c.quota_err_counter,
c.conn_chat_version, c.peer_chat_min_version, c.peer_chat_max_version
FROM contacts ct
JOIN contact_profiles cp ON ct.contact_profile_id = cp.contact_profile_id
JOIN connections c ON c.contact_id = ct.contact_id
WHERE
( (c.user_id = ? AND c.via_contact_uri_hash = ?) OR
(c.user_id = ? AND c.via_contact_uri_hash = ?)
) AND ct.contact_status = ? AND ct.deleted = 0
ORDER BY c.created_at DESC
LIMIT 1
Plan:
MULTI-INDEX OR
INDEX 1
SEARCH c USING INDEX idx_connections_via_contact_uri_hash (user_id=? AND via_contact_uri_hash=?)
INDEX 2
SEARCH c USING INDEX idx_connections_via_contact_uri_hash (user_id=? AND via_contact_uri_hash=?)
SEARCH ct USING INTEGER PRIMARY KEY (rowid=?)
SEARCH cp USING INTEGER PRIMARY KEY (rowid=?)
USE TEMP B-TREE FOR ORDER BY
Query:
SELECT
-- GroupInfo
@@ -952,7 +981,7 @@ Query:
m.invited_by, m.invited_by_group_member_id, m.local_display_name, m.contact_id, m.contact_profile_id, p.contact_profile_id, p.display_name, p.full_name, p.image, p.contact_link, p.local_alias, p.preferences,
m.created_at, m.updated_at,
m.support_chat_ts, m.support_chat_items_unread, m.support_chat_items_member_attention, m.support_chat_items_mentions, m.support_chat_last_msg_from_member_ts,
c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.custom_user_profile_id,
c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.xcontact_id, c.custom_user_profile_id,
c.conn_status, c.conn_type, c.contact_conn_initiated, c.local_alias, c.contact_id, c.group_member_id, c.snd_file_id, c.rcv_file_id, c.user_contact_link_id,
c.created_at, c.security_code, c.security_code_verified_at, c.pq_support, c.pq_encryption, c.pq_snd_enabled, c.pq_rcv_enabled, c.auth_err_counter, c.quota_err_counter,
c.conn_chat_version, c.peer_chat_min_version, c.peer_chat_max_version
@@ -982,37 +1011,6 @@ SEARCH c USING INTEGER PRIMARY KEY (rowid=?) LEFT-JOIN
CORRELATED SCALAR SUBQUERY 1
SEARCH cc USING COVERING INDEX idx_connections_group_member (user_id=? AND group_member_id=?)
Query:
SELECT
c.xcontact_id,
-- Contact
ct.contact_id, ct.contact_profile_id, ct.local_display_name, ct.via_group, cp.display_name, cp.full_name, cp.image, cp.contact_link, cp.local_alias, ct.contact_used, ct.contact_status, ct.enable_ntfs, ct.send_rcpts, ct.favorite,
cp.preferences, ct.user_preferences, ct.created_at, ct.updated_at, ct.chat_ts, ct.conn_full_link_to_connect, ct.conn_short_link_to_connect, ct.welcome_shared_msg_id, ct.request_shared_msg_id, ct.contact_request_id,
ct.contact_group_member_id, ct.contact_grp_inv_sent, ct.ui_themes, ct.chat_deleted, ct.custom_data, ct.chat_item_ttl,
-- Connection
c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.custom_user_profile_id, c.conn_status, c.conn_type, c.contact_conn_initiated, c.local_alias,
c.contact_id, c.group_member_id, c.snd_file_id, c.rcv_file_id, c.user_contact_link_id, c.created_at, c.security_code, c.security_code_verified_at, c.pq_support, c.pq_encryption, c.pq_snd_enabled, c.pq_rcv_enabled, c.auth_err_counter, c.quota_err_counter,
c.conn_chat_version, c.peer_chat_min_version, c.peer_chat_max_version
FROM contacts ct
JOIN contact_profiles cp ON ct.contact_profile_id = cp.contact_profile_id
JOIN connections c ON c.contact_id = ct.contact_id
WHERE
( (c.user_id = ? AND c.via_contact_uri_hash = ?) OR
(c.user_id = ? AND c.via_contact_uri_hash = ?)
) AND ct.contact_status = ? AND ct.deleted = 0
ORDER BY c.created_at DESC
LIMIT 1
Plan:
MULTI-INDEX OR
INDEX 1
SEARCH c USING INDEX idx_connections_via_contact_uri_hash (user_id=? AND via_contact_uri_hash=?)
INDEX 2
SEARCH c USING INDEX idx_connections_via_contact_uri_hash (user_id=? AND via_contact_uri_hash=?)
SEARCH ct USING INTEGER PRIMARY KEY (rowid=?)
SEARCH cp USING INTEGER PRIMARY KEY (rowid=?)
USE TEMP B-TREE FOR ORDER BY
Query:
SELECT
g.group_id, g.local_display_name, gp.display_name, gp.full_name, g.local_alias, gp.description, gp.image,
@@ -1084,7 +1082,7 @@ SEARCH connections USING INDEX idx_connections_via_contact_uri_hash (user_id=? A
USE TEMP B-TREE FOR ORDER BY
Query:
SELECT c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.custom_user_profile_id,
SELECT c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.xcontact_id, c.custom_user_profile_id,
c.conn_status, c.conn_type, c.contact_conn_initiated, c.local_alias, c.contact_id, c.group_member_id, c.snd_file_id, c.rcv_file_id, c.user_contact_link_id,
c.created_at, c.security_code, c.security_code_verified_at, c.pq_support, c.pq_encryption, c.pq_snd_enabled, c.pq_rcv_enabled, c.auth_err_counter, c.quota_err_counter,
c.conn_chat_version, c.peer_chat_min_version, c.peer_chat_max_version
@@ -1530,7 +1528,7 @@ Query:
cp.preferences, ct.user_preferences, ct.created_at, ct.updated_at, ct.chat_ts, ct.conn_full_link_to_connect, ct.conn_short_link_to_connect, ct.welcome_shared_msg_id, ct.request_shared_msg_id, ct.contact_request_id,
ct.contact_group_member_id, ct.contact_grp_inv_sent, ct.ui_themes, ct.chat_deleted, ct.custom_data, ct.chat_item_ttl,
-- Connection
c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.custom_user_profile_id, c.conn_status, c.conn_type, c.contact_conn_initiated, c.local_alias,
c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.xcontact_id, c.custom_user_profile_id, c.conn_status, c.conn_type, c.contact_conn_initiated, c.local_alias,
c.contact_id, c.group_member_id, c.snd_file_id, c.rcv_file_id, c.user_contact_link_id, c.created_at, c.security_code, c.security_code_verified_at, c.pq_support, c.pq_encryption, c.pq_snd_enabled, c.pq_rcv_enabled, c.auth_err_counter, c.quota_err_counter,
c.conn_chat_version, c.peer_chat_min_version, c.peer_chat_max_version
FROM contacts ct
@@ -2924,7 +2922,7 @@ Plan:
SEARCH chat_items USING COVERING INDEX idx_chat_items_notes (user_id=? AND note_folder_id=? AND item_status=?)
Query:
SELECT c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.custom_user_profile_id,
SELECT c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.xcontact_id, c.custom_user_profile_id,
c.conn_status, c.conn_type, c.contact_conn_initiated, c.local_alias, c.contact_id, c.group_member_id, c.snd_file_id, c.rcv_file_id, c.user_contact_link_id,
c.created_at, c.security_code, c.security_code_verified_at, c.pq_support, c.pq_encryption, c.pq_snd_enabled, c.pq_rcv_enabled, c.auth_err_counter, c.quota_err_counter,
c.conn_chat_version, c.peer_chat_min_version, c.peer_chat_max_version
@@ -2937,7 +2935,7 @@ SEARCH uc USING INDEX idx_user_contact_links_group_id (group_id=?)
SEARCH c USING INDEX idx_connections_user_contact_link_id (user_contact_link_id=?)
Query:
SELECT c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.custom_user_profile_id,
SELECT c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.xcontact_id, c.custom_user_profile_id,
c.conn_status, c.conn_type, c.contact_conn_initiated, c.local_alias, c.contact_id, c.group_member_id, c.snd_file_id, c.rcv_file_id, c.user_contact_link_id,
c.created_at, c.security_code, c.security_code_verified_at, c.pq_support, c.pq_encryption, c.pq_snd_enabled, c.pq_rcv_enabled, c.auth_err_counter, c.quota_err_counter,
c.conn_chat_version, c.peer_chat_min_version, c.peer_chat_max_version
@@ -2950,7 +2948,7 @@ SEARCH uc USING INDEX sqlite_autoindex_user_contact_links_1 (user_id=? AND local
SEARCH c USING INDEX idx_connections_user_contact_link_id (user_contact_link_id=?)
Query:
SELECT c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.custom_user_profile_id,
SELECT c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.xcontact_id, c.custom_user_profile_id,
c.conn_status, c.conn_type, c.contact_conn_initiated, c.local_alias, c.contact_id, c.group_member_id, c.snd_file_id, c.rcv_file_id, c.user_contact_link_id,
c.created_at, c.security_code, c.security_code_verified_at, c.pq_support, c.pq_encryption, c.pq_snd_enabled, c.pq_rcv_enabled, c.auth_err_counter, c.quota_err_counter,
c.conn_chat_version, c.peer_chat_min_version, c.peer_chat_max_version,
@@ -3137,7 +3135,7 @@ Plan:
SEARCH commands USING INTEGER PRIMARY KEY (rowid=?)
Query:
SELECT connection_id, agent_conn_id, conn_level, via_contact, via_user_contact_link, via_group_link, group_link_id, custom_user_profile_id,
SELECT connection_id, agent_conn_id, conn_level, via_contact, via_user_contact_link, via_group_link, group_link_id, xcontact_id, custom_user_profile_id,
conn_status, conn_type, contact_conn_initiated, local_alias, contact_id, group_member_id, snd_file_id, rcv_file_id, user_contact_link_id,
created_at, security_code, security_code_verified_at, pq_support, pq_encryption, pq_snd_enabled, pq_rcv_enabled, auth_err_counter, quota_err_counter,
conn_chat_version, peer_chat_min_version, peer_chat_max_version
@@ -4766,7 +4764,7 @@ Query:
m.invited_by, m.invited_by_group_member_id, m.local_display_name, m.contact_id, m.contact_profile_id, p.contact_profile_id, p.display_name, p.full_name, p.image, p.contact_link, p.local_alias, p.preferences,
m.created_at, m.updated_at,
m.support_chat_ts, m.support_chat_items_unread, m.support_chat_items_member_attention, m.support_chat_items_mentions, m.support_chat_last_msg_from_member_ts,
c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.custom_user_profile_id,
c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.xcontact_id, c.custom_user_profile_id,
c.conn_status, c.conn_type, c.contact_conn_initiated, c.local_alias, c.contact_id, c.group_member_id, c.snd_file_id, c.rcv_file_id, c.user_contact_link_id,
c.created_at, c.security_code, c.security_code_verified_at, c.pq_support, c.pq_encryption, c.pq_snd_enabled, c.pq_rcv_enabled, c.auth_err_counter, c.quota_err_counter,
c.conn_chat_version, c.peer_chat_min_version, c.peer_chat_max_version
@@ -4799,7 +4797,7 @@ Query:
m.invited_by, m.invited_by_group_member_id, m.local_display_name, m.contact_id, m.contact_profile_id, p.contact_profile_id, p.display_name, p.full_name, p.image, p.contact_link, p.local_alias, p.preferences,
m.created_at, m.updated_at,
m.support_chat_ts, m.support_chat_items_unread, m.support_chat_items_member_attention, m.support_chat_items_mentions, m.support_chat_last_msg_from_member_ts,
c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.custom_user_profile_id,
c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.xcontact_id, c.custom_user_profile_id,
c.conn_status, c.conn_type, c.contact_conn_initiated, c.local_alias, c.contact_id, c.group_member_id, c.snd_file_id, c.rcv_file_id, c.user_contact_link_id,
c.created_at, c.security_code, c.security_code_verified_at, c.pq_support, c.pq_encryption, c.pq_snd_enabled, c.pq_rcv_enabled, c.auth_err_counter, c.quota_err_counter,
c.conn_chat_version, c.peer_chat_min_version, c.peer_chat_max_version
@@ -4824,7 +4822,7 @@ Query:
m.invited_by, m.invited_by_group_member_id, m.local_display_name, m.contact_id, m.contact_profile_id, p.contact_profile_id, p.display_name, p.full_name, p.image, p.contact_link, p.local_alias, p.preferences,
m.created_at, m.updated_at,
m.support_chat_ts, m.support_chat_items_unread, m.support_chat_items_member_attention, m.support_chat_items_mentions, m.support_chat_last_msg_from_member_ts,
c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.custom_user_profile_id,
c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.xcontact_id, c.custom_user_profile_id,
c.conn_status, c.conn_type, c.contact_conn_initiated, c.local_alias, c.contact_id, c.group_member_id, c.snd_file_id, c.rcv_file_id, c.user_contact_link_id,
c.created_at, c.security_code, c.security_code_verified_at, c.pq_support, c.pq_encryption, c.pq_snd_enabled, c.pq_rcv_enabled, c.auth_err_counter, c.quota_err_counter,
c.conn_chat_version, c.peer_chat_min_version, c.peer_chat_max_version
@@ -4849,7 +4847,7 @@ Query:
m.invited_by, m.invited_by_group_member_id, m.local_display_name, m.contact_id, m.contact_profile_id, p.contact_profile_id, p.display_name, p.full_name, p.image, p.contact_link, p.local_alias, p.preferences,
m.created_at, m.updated_at,
m.support_chat_ts, m.support_chat_items_unread, m.support_chat_items_member_attention, m.support_chat_items_mentions, m.support_chat_last_msg_from_member_ts,
c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.custom_user_profile_id,
c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.xcontact_id, c.custom_user_profile_id,
c.conn_status, c.conn_type, c.contact_conn_initiated, c.local_alias, c.contact_id, c.group_member_id, c.snd_file_id, c.rcv_file_id, c.user_contact_link_id,
c.created_at, c.security_code, c.security_code_verified_at, c.pq_support, c.pq_encryption, c.pq_snd_enabled, c.pq_rcv_enabled, c.auth_err_counter, c.quota_err_counter,
c.conn_chat_version, c.peer_chat_min_version, c.peer_chat_max_version
@@ -4874,7 +4872,7 @@ Query:
m.invited_by, m.invited_by_group_member_id, m.local_display_name, m.contact_id, m.contact_profile_id, p.contact_profile_id, p.display_name, p.full_name, p.image, p.contact_link, p.local_alias, p.preferences,
m.created_at, m.updated_at,
m.support_chat_ts, m.support_chat_items_unread, m.support_chat_items_member_attention, m.support_chat_items_mentions, m.support_chat_last_msg_from_member_ts,
c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.custom_user_profile_id,
c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.xcontact_id, c.custom_user_profile_id,
c.conn_status, c.conn_type, c.contact_conn_initiated, c.local_alias, c.contact_id, c.group_member_id, c.snd_file_id, c.rcv_file_id, c.user_contact_link_id,
c.created_at, c.security_code, c.security_code_verified_at, c.pq_support, c.pq_encryption, c.pq_snd_enabled, c.pq_rcv_enabled, c.auth_err_counter, c.quota_err_counter,
c.conn_chat_version, c.peer_chat_min_version, c.peer_chat_max_version
@@ -4899,7 +4897,7 @@ Query:
m.invited_by, m.invited_by_group_member_id, m.local_display_name, m.contact_id, m.contact_profile_id, p.contact_profile_id, p.display_name, p.full_name, p.image, p.contact_link, p.local_alias, p.preferences,
m.created_at, m.updated_at,
m.support_chat_ts, m.support_chat_items_unread, m.support_chat_items_member_attention, m.support_chat_items_mentions, m.support_chat_last_msg_from_member_ts,
c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.custom_user_profile_id,
c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.xcontact_id, c.custom_user_profile_id,
c.conn_status, c.conn_type, c.contact_conn_initiated, c.local_alias, c.contact_id, c.group_member_id, c.snd_file_id, c.rcv_file_id, c.user_contact_link_id,
c.created_at, c.security_code, c.security_code_verified_at, c.pq_support, c.pq_encryption, c.pq_snd_enabled, c.pq_rcv_enabled, c.auth_err_counter, c.quota_err_counter,
c.conn_chat_version, c.peer_chat_min_version, c.peer_chat_max_version
@@ -4924,7 +4922,7 @@ Query:
m.invited_by, m.invited_by_group_member_id, m.local_display_name, m.contact_id, m.contact_profile_id, p.contact_profile_id, p.display_name, p.full_name, p.image, p.contact_link, p.local_alias, p.preferences,
m.created_at, m.updated_at,
m.support_chat_ts, m.support_chat_items_unread, m.support_chat_items_member_attention, m.support_chat_items_mentions, m.support_chat_last_msg_from_member_ts,
c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.custom_user_profile_id,
c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.xcontact_id, c.custom_user_profile_id,
c.conn_status, c.conn_type, c.contact_conn_initiated, c.local_alias, c.contact_id, c.group_member_id, c.snd_file_id, c.rcv_file_id, c.user_contact_link_id,
c.created_at, c.security_code, c.security_code_verified_at, c.pq_support, c.pq_encryption, c.pq_snd_enabled, c.pq_rcv_enabled, c.auth_err_counter, c.quota_err_counter,
c.conn_chat_version, c.peer_chat_min_version, c.peer_chat_max_version
+8 -6
View File
@@ -197,12 +197,12 @@ toFileInfo (fileId, fileStatus, filePath) = CIFileInfo {fileId, fileStatus, file
type EntityIdsRow = (Maybe Int64, Maybe Int64, Maybe Int64, Maybe Int64, Maybe Int64)
type ConnectionRow = (Int64, ConnId, Int, Maybe Int64, Maybe Int64, BoolInt, Maybe GroupLinkId, Maybe Int64, ConnStatus, ConnType, BoolInt, LocalAlias) :. EntityIdsRow :. (UTCTime, Maybe Text, Maybe UTCTime, PQSupport, PQEncryption, Maybe PQEncryption, Maybe PQEncryption, Int, Int, Maybe VersionChat, VersionChat, VersionChat)
type ConnectionRow = (Int64, ConnId, Int, Maybe Int64, Maybe Int64, BoolInt, Maybe GroupLinkId, Maybe XContactId) :. (Maybe Int64, ConnStatus, ConnType, BoolInt, LocalAlias) :. EntityIdsRow :. (UTCTime, Maybe Text, Maybe UTCTime, PQSupport, PQEncryption, Maybe PQEncryption, Maybe PQEncryption, Int, Int, Maybe VersionChat, VersionChat, VersionChat)
type MaybeConnectionRow = (Maybe Int64, Maybe ConnId, Maybe Int, Maybe Int64, Maybe Int64, Maybe BoolInt, Maybe GroupLinkId, Maybe Int64, Maybe ConnStatus, Maybe ConnType, Maybe BoolInt, Maybe LocalAlias) :. EntityIdsRow :. (Maybe UTCTime, Maybe Text, Maybe UTCTime, Maybe PQSupport, Maybe PQEncryption, Maybe PQEncryption, Maybe PQEncryption, Maybe Int, Maybe Int, Maybe VersionChat, Maybe VersionChat, Maybe VersionChat)
type MaybeConnectionRow = (Maybe Int64, Maybe ConnId, Maybe Int, Maybe Int64, Maybe Int64, Maybe BoolInt, Maybe GroupLinkId, Maybe XContactId) :. (Maybe Int64, Maybe ConnStatus, Maybe ConnType, Maybe BoolInt, Maybe LocalAlias) :. EntityIdsRow :. (Maybe UTCTime, Maybe Text, Maybe UTCTime, Maybe PQSupport, Maybe PQEncryption, Maybe PQEncryption, Maybe PQEncryption, Maybe Int, Maybe Int, Maybe VersionChat, Maybe VersionChat, Maybe VersionChat)
toConnection :: VersionRangeChat -> ConnectionRow -> Connection
toConnection vr ((connId, acId, connLevel, viaContact, viaUserContactLink, BI viaGroupLink, groupLinkId, customUserProfileId, connStatus, connType, BI contactConnInitiated, localAlias) :. (contactId, groupMemberId, sndFileId, rcvFileId, userContactLinkId) :. (createdAt, code_, verifiedAt_, pqSupport, pqEncryption, pqSndEnabled, pqRcvEnabled, authErrCounter, quotaErrCounter, chatV, minVer, maxVer)) =
toConnection vr ((connId, acId, connLevel, viaContact, viaUserContactLink, BI viaGroupLink, groupLinkId, xContactId) :. (customUserProfileId, connStatus, connType, BI contactConnInitiated, localAlias) :. (contactId, groupMemberId, sndFileId, rcvFileId, userContactLinkId) :. (createdAt, code_, verifiedAt_, pqSupport, pqEncryption, pqSndEnabled, pqRcvEnabled, authErrCounter, quotaErrCounter, chatV, minVer, maxVer)) =
Connection
{ connId,
agentConnId = AgentConnId acId,
@@ -213,6 +213,7 @@ toConnection vr ((connId, acId, connLevel, viaContact, viaUserContactLink, BI vi
viaUserContactLink,
viaGroupLink,
groupLinkId,
xContactId,
customUserProfileId,
connStatus,
connType,
@@ -238,8 +239,8 @@ toConnection vr ((connId, acId, connLevel, viaContact, viaUserContactLink, BI vi
entityId_ ConnUserContact = userContactLinkId
toMaybeConnection :: VersionRangeChat -> MaybeConnectionRow -> Maybe Connection
toMaybeConnection vr ((Just connId, Just agentConnId, Just connLevel, viaContact, viaUserContactLink, Just viaGroupLink, groupLinkId, customUserProfileId, Just connStatus, Just connType, Just contactConnInitiated, Just localAlias) :. (contactId, groupMemberId, sndFileId, rcvFileId, userContactLinkId) :. (Just createdAt, code_, verifiedAt_, Just pqSupport, Just pqEncryption, pqSndEnabled_, pqRcvEnabled_, Just authErrCounter, Just quotaErrCounter, connChatVersion, Just minVer, Just maxVer)) =
Just $ toConnection vr ((connId, agentConnId, connLevel, viaContact, viaUserContactLink, viaGroupLink, groupLinkId, customUserProfileId, connStatus, connType, contactConnInitiated, localAlias) :. (contactId, groupMemberId, sndFileId, rcvFileId, userContactLinkId) :. (createdAt, code_, verifiedAt_, pqSupport, pqEncryption, pqSndEnabled_, pqRcvEnabled_, authErrCounter, quotaErrCounter, connChatVersion, minVer, maxVer))
toMaybeConnection vr ((Just connId, Just agentConnId, Just connLevel, viaContact, viaUserContactLink, Just viaGroupLink, groupLinkId, xContactId) :. (customUserProfileId, Just connStatus, Just connType, Just contactConnInitiated, Just localAlias) :. (contactId, groupMemberId, sndFileId, rcvFileId, userContactLinkId) :. (Just createdAt, code_, verifiedAt_, Just pqSupport, Just pqEncryption, pqSndEnabled_, pqRcvEnabled_, Just authErrCounter, Just quotaErrCounter, connChatVersion, Just minVer, Just maxVer)) =
Just $ toConnection vr ((connId, agentConnId, connLevel, viaContact, viaUserContactLink, viaGroupLink, groupLinkId, xContactId) :. (customUserProfileId, connStatus, connType, contactConnInitiated, localAlias) :. (contactId, groupMemberId, sndFileId, rcvFileId, userContactLinkId) :. (createdAt, code_, verifiedAt_, pqSupport, pqEncryption, pqSndEnabled_, pqRcvEnabled_, authErrCounter, quotaErrCounter, connChatVersion, minVer, maxVer))
toMaybeConnection _ _ = Nothing
createConnection_ :: DB.Connection -> UserId -> ConnType -> Maybe Int64 -> ConnId -> ConnStatus -> VersionChat -> VersionRangeChat -> Maybe ContactId -> Maybe Int64 -> Maybe ProfileId -> Int -> UTCTime -> SubscriptionMode -> PQSupport -> IO Connection
@@ -273,7 +274,8 @@ createConnection_ db userId connType entityId acId connStatus connChatVersion pe
viaContact,
viaUserContactLink,
viaGroupLink,
groupLinkId = Nothing,
groupLinkId = Nothing, -- should it be set to viaLinkGroupId
xContactId = Nothing,
customUserProfileId,
connLevel,
connStatus,
+19 -8
View File
@@ -510,7 +510,7 @@ data GroupSummary = GroupSummary
data ContactOrGroup = CGContact Contact | CGGroup GroupInfo [GroupMember]
data AttachConnToContactOrGroup = ACCGContact ContactId | ACCGGroup GroupInfo GroupMemberId
data PreparedChatEntity = PCEContact Contact | PCEGroup {groupInfo :: GroupInfo, hostMember :: GroupMember}
contactAndGroupIds :: ContactOrGroup -> (Maybe ContactId, Maybe GroupId)
contactAndGroupIds = \case
@@ -1555,6 +1555,7 @@ data Connection = Connection
viaUserContactLink :: Maybe Int64, -- user contact link ID, if connected via "user address"
viaGroupLink :: Bool, -- whether contact connected via group link
groupLinkId :: Maybe GroupLinkId,
xContactId :: Maybe XContactId,
customUserProfileId :: Maybe Int64,
connType :: ConnType,
connStatus :: ConnStatus,
@@ -1618,7 +1619,7 @@ data PendingContactConnection = PendingContactConnection
{ pccConnId :: Int64,
pccAgentConnId :: AgentConnId,
pccConnStatus :: ConnStatus,
viaContactUri :: Bool,
viaContactUri :: Bool, -- whether connection was created via contact request to a contact link
viaUserContactLink :: Maybe Int64,
groupLinkId :: Maybe GroupLinkId,
customUserProfileId :: Maybe Int64,
@@ -1629,6 +1630,22 @@ data PendingContactConnection = PendingContactConnection
}
deriving (Eq, Show)
mkPendingContactConnection :: Connection -> Maybe CreatedLinkInvitation -> PendingContactConnection
mkPendingContactConnection Connection {connId, agentConnId, connStatus, xContactId, viaUserContactLink, groupLinkId, customUserProfileId, localAlias, createdAt} connLinkInv =
PendingContactConnection
{ pccConnId = connId,
pccAgentConnId = agentConnId,
pccConnStatus = connStatus,
viaContactUri = isJust xContactId,
viaUserContactLink,
groupLinkId,
customUserProfileId,
connLinkInv,
localAlias,
createdAt,
updatedAt = createdAt
}
aConnId' :: PendingContactConnection -> ConnId
aConnId' PendingContactConnection {pccAgentConnId = AgentConnId cId} = cId
@@ -1712,12 +1729,6 @@ instance TextEncoding ConnType where
ConnRcvFile -> "rcv_file"
ConnUserContact -> "user_contact"
data NewConnection = NewConnection
{ agentConnId :: ByteString,
connLevel :: Int,
viaConn :: Maybe Int64
}
data GroupMemberIntro = GroupMemberIntro
{ introId :: Int64,
reMember :: GroupMember,