mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2025-06-28 12:19:54 +00:00
Merge branch 'short-links' into f/short-links-kotlin-user-picker
This commit is contained in:
commit
86953de2f4
10 changed files with 94 additions and 76 deletions
|
@ -1533,9 +1533,10 @@ func acceptContactRequest(incognito: Bool, contactRequestId: Int64) async {
|
|||
NetworkModel.shared.setContactNetworkStatus(contact, .connected)
|
||||
}
|
||||
if contact.sndReady {
|
||||
let chatId = chat.id
|
||||
DispatchQueue.main.async {
|
||||
dismissAllSheets(animated: true) {
|
||||
ItemsModel.shared.loadOpenChat(chat.id)
|
||||
ItemsModel.shared.loadOpenChat(chatId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -707,6 +707,7 @@ struct ComposeView: View {
|
|||
await MainActor.run {
|
||||
self.chatModel.updateContact(contact)
|
||||
clearState()
|
||||
NetworkModel.shared.setContactNetworkStatus(contact, .connected)
|
||||
}
|
||||
} else {
|
||||
AlertManager.shared.showAlertMsg(title: "Empty message!")
|
||||
|
@ -744,6 +745,7 @@ struct ComposeView: View {
|
|||
if let contact = await apiConnectPreparedContact(contactId: chat.chatInfo.apiId, incognito: incognitoGroupDefault.get(), msg: mc) {
|
||||
await MainActor.run {
|
||||
self.chatModel.updateContact(contact)
|
||||
NetworkModel.shared.setContactNetworkStatus(contact, .connected)
|
||||
clearState()
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -455,7 +455,7 @@ struct ChatPreviewView: View {
|
|||
let size = dynamicSize(userFont).incognitoSize
|
||||
switch chat.chatInfo {
|
||||
case let .direct(contact):
|
||||
if contact.active && contact.activeConn != nil {
|
||||
if contact.active, let status = contact.activeConn?.connStatus, status == .ready || status == .sndReady {
|
||||
NetworkStatusView(contact: contact, size: size)
|
||||
} else {
|
||||
incognitoIcon(chat.chatInfo.incognito, theme.colors.secondary, size: size)
|
||||
|
|
|
@ -1735,8 +1735,8 @@ public struct Contact: Identifiable, Decodable, NamedChat, Hashable {
|
|||
public var sndReady: Bool { get { ready || activeConn?.connStatus == .sndReady } }
|
||||
public var active: Bool { get { contactStatus == .active } }
|
||||
public var nextSendGrpInv: Bool { get { contactGroupMemberId != nil && !contactGrpInvSent } }
|
||||
public var nextConnectPrepared: Bool { preparedContact != nil && activeConn == nil }
|
||||
public var nextAcceptContactRequest: Bool { contactRequestId != nil && activeConn == nil }
|
||||
public var nextConnectPrepared: Bool { preparedContact != nil && (activeConn == nil || activeConn?.connStatus == .prepared) }
|
||||
public var nextAcceptContactRequest: Bool { contactRequestId != nil && (activeConn == nil || activeConn?.connStatus == .new) }
|
||||
public var sendMsgToConnect: Bool { nextSendGrpInv || nextConnectPrepared }
|
||||
public var displayName: String { localAlias == "" ? profile.displayName : localAlias }
|
||||
public var fullName: String { get { profile.fullName } }
|
||||
|
@ -1833,7 +1833,7 @@ public struct Connection: Decodable, Hashable {
|
|||
public var connId: Int64
|
||||
public var agentConnId: String
|
||||
public var peerChatVRange: VersionRange
|
||||
var connStatus: ConnStatus
|
||||
public var connStatus: ConnStatus
|
||||
public var connLevel: Int
|
||||
public var viaGroupLink: Bool
|
||||
public var customUserProfileId: Int64?
|
||||
|
|
|
@ -456,7 +456,7 @@ data ChatCommand
|
|||
| APIChangePreparedGroupUser GroupId UserId
|
||||
| APIConnectPreparedContact {contactId :: ContactId, incognito :: IncognitoEnabled, msgContent_ :: Maybe MsgContent}
|
||||
| APIConnectPreparedGroup GroupId IncognitoEnabled (Maybe MsgContent)
|
||||
| APIConnect UserId IncognitoEnabled (Maybe ACreatedConnLink)
|
||||
| APIConnect UserId IncognitoEnabled ACreatedConnLink
|
||||
| Connect IncognitoEnabled (Maybe AConnectionLink)
|
||||
| APIConnectContactViaAddress UserId IncognitoEnabled ContactId
|
||||
| ConnectSimplex IncognitoEnabled -- UserId (not used in UI)
|
||||
|
|
|
@ -1157,7 +1157,6 @@ processChatCommand' vr = \case
|
|||
when (shortLinkDataSet && incognito) $ throwCmdError "incognito not allowed for address with short link data"
|
||||
withUserContactLock "acceptContact" uclId $ do
|
||||
cReq <- withFastStore $ \db -> getContactRequest db user connReqId
|
||||
-- TODO [short links] accept async, move to continuation on JOIN?
|
||||
(ct, conn@Connection {connId}, sqSecured) <- acceptContactRequest user cReq incognito
|
||||
let contactUsed = isNothing gLinkInfo_
|
||||
ct' <- withStore' $ \db -> do
|
||||
|
@ -1795,18 +1794,16 @@ processChatCommand' vr = \case
|
|||
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} ->
|
||||
connectViaInvitation user incognito ccLink (Just contactId) >>= \case
|
||||
CRSentConfirmation {customUserProfile} -> do
|
||||
-- get updated contact with connection
|
||||
ct' <- withFastStore $ \db -> getContact db vr user contactId
|
||||
forM_ msgContent_ $ \mc -> do
|
||||
let evt = XMsgNew $ MCSimple (extMsgContent mc Nothing)
|
||||
(msg, _) <- sendDirectContactMessage user ct' evt
|
||||
ci <- saveSndChatItem user (CDDirectSnd ct') msg (CISndMsgContent mc)
|
||||
toView $ CEvtNewChatItems user [AChatItem SCTDirect SMDSnd (DirectChat ct') ci]
|
||||
pure $ CRStartedConnectionToContact user ct' customUserProfile
|
||||
cr -> pure cr
|
||||
Just PreparedContact {connLinkToConnect = ACCL SCMInvitation ccLink} -> do
|
||||
(_, customUserProfile) <- connectViaInvitation user incognito ccLink (Just contactId)
|
||||
-- get updated contact with connection
|
||||
ct' <- withFastStore $ \db -> getContact db vr user contactId
|
||||
forM_ msgContent_ $ \mc -> do
|
||||
let evt = XMsgNew $ MCSimple (extMsgContent mc Nothing)
|
||||
(msg, _) <- sendDirectContactMessage user ct' evt
|
||||
ci <- saveSndChatItem user (CDDirectSnd ct') msg (CISndMsgContent mc)
|
||||
toView $ CEvtNewChatItems user [AChatItem SCTDirect SMDSnd (DirectChat ct') ci]
|
||||
pure $ CRStartedConnectionToContact user ct' customUserProfile
|
||||
Just PreparedContact {connLinkToConnect = ACCL SCMContact ccLink, welcomeSharedMsgId} -> do
|
||||
-- TODO [short links] reuse welcomeSharedMsgId
|
||||
msg_ <- forM msgContent_ $ \mc -> (,mc) <$> getSharedMsgId
|
||||
|
@ -1831,11 +1828,12 @@ processChatCommand' vr = \case
|
|||
gInfo' <- withFastStore $ \db -> getGroupInfo db vr user groupId
|
||||
pure $ CRStartedConnectionToGroup user gInfo' customUserProfile
|
||||
cr -> pure cr
|
||||
APIConnect userId incognito (Just (ACCL SCMInvitation ccLink)) -> withUserId userId $ \user ->
|
||||
connectViaInvitation user incognito ccLink Nothing
|
||||
APIConnect userId incognito (Just (ACCL SCMContact ccLink)) -> withUserId userId $ \user ->
|
||||
connectViaContact user incognito ccLink Nothing Nothing Nothing
|
||||
APIConnect _ _ Nothing -> throwChatError CEInvalidConnReq
|
||||
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
|
||||
pure $ CRSentConfirmation user pcc incognitoProfile
|
||||
ACCL SCMContact ccLink -> connectViaContact user incognito ccLink Nothing Nothing Nothing
|
||||
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
|
||||
|
@ -2869,9 +2867,9 @@ 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 ChatResponse
|
||||
connectViaInvitation :: User -> IncognitoEnabled -> CreatedLinkInvitation -> Maybe ContactId -> CM (Int64, Maybe Profile)
|
||||
connectViaInvitation user@User {userId} incognito (CCLink cReq@(CRInvitationUri crData e2e) sLnk_) contactId_ =
|
||||
withInvitationLock "connect" (strEncode cReq) . procCmd $ do
|
||||
withInvitationLock "connect" (strEncode cReq) $ do
|
||||
subMode <- chatReadVar subscriptionMode
|
||||
-- [incognito] generate profile to send
|
||||
incognitoProfile <- if incognito then Just <$> liftIO generateRandomProfile else pure Nothing
|
||||
|
@ -2884,24 +2882,22 @@ 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, connStatus, contactConnInitiated} _ct_)
|
||||
Just (RcvDirectMsgConnection conn@Connection {connId = dbConnId, connStatus, contactConnInitiated} _ct_)
|
||||
| connStatus == ConnNew && contactConnInitiated -> joinNewConn chatV dm -- own connection link
|
||||
| connStatus == ConnPrepared -> do
|
||||
-- retrying join after error
|
||||
pcc <- withFastStore $ \db -> getPendingContactConnection db userId connId
|
||||
joinPreparedConn (aConnId conn) pcc dm
|
||||
| connStatus == ConnPrepared -> joinPreparedConn dbConnId (aConnId 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_
|
||||
pcc <- withFastStore' $ \db -> createDirectConnection db user connId ccLink contactId_ ConnPrepared (incognitoProfile $> profileToSend) subMode chatV pqSup'
|
||||
joinPreparedConn connId pcc dm
|
||||
joinPreparedConn connId pcc@PendingContactConnection {pccConnId} dm = do
|
||||
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
|
||||
let newStatus = if sqSecured then ConnSndReady else ConnJoined
|
||||
withFastStore' $ \db -> updateConnectionStatusFromTo db pccConnId ConnPrepared newStatus
|
||||
pure $ CRSentConfirmation user pcc {pccConnStatus = newStatus} incognitoProfile
|
||||
withFastStore' $ \db -> updateConnectionStatusFromTo db dbConnId ConnPrepared newStatus
|
||||
pure (dbConnId, incognitoProfile)
|
||||
cReqs =
|
||||
( CRInvitationUri crData {crScheme = SSSimplex} e2e,
|
||||
CRInvitationUri crData {crScheme = simplexChat} e2e
|
||||
|
@ -3363,7 +3359,7 @@ processChatCommand' vr = \case
|
|||
case plan of
|
||||
CPContactAddress (CAPContactViaAddress Contact {contactId}) ->
|
||||
processChatCommand $ APIConnectContactViaAddress userId incognito contactId
|
||||
_ -> processChatCommand $ APIConnect userId incognito (Just ccLink)
|
||||
_ -> processChatCommand $ APIConnect userId incognito ccLink
|
||||
| otherwise = pure $ CRConnectionPlan user ccLink plan
|
||||
invitationRequestPlan :: User -> ConnReqInvitation -> Maybe ContactShortLinkData -> CM ConnectionPlan
|
||||
invitationRequestPlan user cReq contactSLinkData_ = do
|
||||
|
@ -4480,7 +4476,7 @@ chatCommandP =
|
|||
"/_connect contact @" *> (APIConnectPreparedContact <$> A.decimal <*> incognitoOnOffP <*> optional (A.space *> msgContentP)),
|
||||
"/_connect group #" *> (APIConnectPreparedGroup <$> A.decimal <*> incognitoOnOffP <*> optional (A.space *> msgContentP)),
|
||||
"/_connect " *> (APIAddContact <$> A.decimal <*> incognitoOnOffP),
|
||||
"/_connect " *> (APIConnect <$> A.decimal <*> incognitoOnOffP <* A.space <*> connLinkP_),
|
||||
"/_connect " *> (APIConnect <$> A.decimal <*> incognitoOnOffP <* A.space <*> connLinkP),
|
||||
"/_set incognito :" *> (APISetConnectionIncognito <$> A.decimal <* A.space <*> onOffP),
|
||||
"/_set conn user :" *> (APIChangeConnectionUser <$> A.decimal <* A.space <*> A.decimal),
|
||||
("/connect" <|> "/c") *> (AddContact <$> incognitoP),
|
||||
|
@ -4598,8 +4594,6 @@ chatCommandP =
|
|||
cReq <- strP
|
||||
sLink_ <- optional (A.space *> strP)
|
||||
pure $ CCLink cReq sLink_
|
||||
connLinkP_ =
|
||||
((Just <$> connLinkP) <|> A.takeTill (== ' ') $> Nothing)
|
||||
incognitoP = (A.space *> ("incognito" <|> "i")) $> True <|> pure False
|
||||
incognitoOnOffP = (A.space *> "incognito=" *> onOffP) <|> pure False
|
||||
imagePrefix = (<>) <$> "data:" <*> ("image/png;base64," <|> "image/jpg;base64,")
|
||||
|
|
|
@ -869,6 +869,14 @@ getRcvFilePath fileId fPath_ fn keepHandle = case fPath_ of
|
|||
liftIO $ B.hPut h "" >> hFlush h
|
||||
| otherwise = liftIO $ B.writeFile fPath ""
|
||||
|
||||
-- TODO [short links]
|
||||
-- Please note:
|
||||
-- - the connection here is created as ConnNew, even though when joining it is created as ConnPrepared.
|
||||
-- (changing it is risky, as there may be existing "prepared" connections that were not accepted in ConnNew status).
|
||||
-- - after accepted, the status is changed by this func caller to ConnSndReady if it is sndSecure, and not changed otherwise - joined changed to ConnJoined in this case.
|
||||
-- - xContactId is set on the contact at the first acceptance attempt, not after accept success, which prevents profile updates after such attempt.
|
||||
-- It may be reasonable to set it when contact is first prepared, but then we can't use it to ignore requests after acceptance,
|
||||
-- and it may lead to race conditions with XInfo events.
|
||||
acceptContactRequest :: User -> UserContactRequest -> IncognitoEnabled -> CM (Contact, Connection, SndQueueSecured)
|
||||
acceptContactRequest user@User {userId} UserContactRequest {agentInvitationId = AgentInvId invId, contactId_, cReqChatVRange, localDisplayName = cName, profileId, profile = cp, userContactLinkId, xContactId, pqSupport} incognito = do
|
||||
subMode <- chatReadVar subscriptionMode
|
||||
|
|
|
@ -23,6 +23,7 @@ module Simplex.Chat.Store.Direct
|
|||
-- * Contacts and connections functions
|
||||
getPendingContactConnection,
|
||||
deletePendingContactConnection,
|
||||
createDirectConnection_,
|
||||
createDirectConnection,
|
||||
createIncognitoProfile,
|
||||
createConnReqConnection,
|
||||
|
@ -63,7 +64,6 @@ module Simplex.Chat.Store.Direct
|
|||
deleteContactRequest,
|
||||
createContactFromRequest,
|
||||
createAcceptedContactConn,
|
||||
createAcceptedContact,
|
||||
updateContactAccepted,
|
||||
getUserByContactRequestId,
|
||||
getPendingContactConnections,
|
||||
|
@ -235,8 +235,13 @@ getContactByConnReqHash db vr user@User {userId} cReqHash = do
|
|||
mapM (addDirectChatTags db) ct_
|
||||
|
||||
createDirectConnection :: DB.Connection -> User -> ConnId -> CreatedLinkInvitation -> Maybe ContactId -> ConnStatus -> Maybe Profile -> SubscriptionMode -> VersionChat -> PQSupport -> IO PendingContactConnection
|
||||
createDirectConnection db User {userId} acId ccLink@(CCLink cReq shortLinkInv) contactId_ pccConnStatus incognitoProfile subMode chatV pqSup = do
|
||||
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
|
||||
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 userId acId (CCLink cReq shortLinkInv) contactId_ pccConnStatus incognitoProfile subMode chatV pqSup createdAt = do
|
||||
customUserProfileId <- mapM (createIncognitoProfile_ db userId createdAt) incognitoProfile
|
||||
let contactConnInitiated = pccConnStatus == ConnNew
|
||||
DB.execute
|
||||
|
@ -250,8 +255,8 @@ createDirectConnection db User {userId} acId ccLink@(CCLink cReq shortLinkInv) c
|
|||
( (userId, acId, cReq, shortLinkInv, pccConnStatus, ConnContact, contactId_, BI contactConnInitiated, customUserProfileId)
|
||||
:. (createdAt, createdAt, BI (subMode == SMOnlyCreate), chatV, pqSup, pqSup)
|
||||
)
|
||||
pccConnId <- insertedRowId db
|
||||
pure PendingContactConnection {pccConnId, pccAgentConnId = AgentConnId acId, pccConnStatus, viaContactUri = False, viaUserContactLink = Nothing, groupLinkId = Nothing, customUserProfileId, connLinkInv = Just ccLink, localAlias = "", createdAt, updatedAt = createdAt}
|
||||
dbConnId <- insertedRowId db
|
||||
pure (dbConnId, customUserProfileId)
|
||||
|
||||
createIncognitoProfile :: DB.Connection -> User -> Profile -> IO Int64
|
||||
createIncognitoProfile db User {userId} p = do
|
||||
|
@ -777,37 +782,6 @@ createAcceptedContactConn db User {userId} uclId contactId agentConnId connChatV
|
|||
ExistingIncognito LocalProfile {profileId = pId} -> pure pId
|
||||
createConnection_ db userId ConnContact (Just contactId) agentConnId ConnNew connChatVersion cReqChatVRange Nothing (Just uclId) customUserProfileId 0 currentTs subMode pqSup
|
||||
|
||||
createAcceptedContact :: DB.Connection -> VersionRangeChat -> User -> Int64 -> ConnId -> VersionChat -> VersionRangeChat -> Profile -> Maybe XContactId -> PQSupport -> Maybe IncognitoProfile -> SubscriptionMode -> ExceptT StoreError IO (Contact, Connection)
|
||||
createAcceptedContact
|
||||
db
|
||||
vr
|
||||
user@User {userId}
|
||||
uclId
|
||||
agentConnId
|
||||
connChatVersion
|
||||
cReqChatVRange
|
||||
Profile {displayName, fullName, image, contactLink, preferences}
|
||||
xContactId
|
||||
pqSup
|
||||
incognitoProfile
|
||||
subMode = do
|
||||
currentTs <- liftIO getCurrentTime
|
||||
let userPreferences = fromMaybe emptyChatPrefs $ incognitoProfile >> preferences
|
||||
contactId <- ExceptT . withLocalDisplayName db userId displayName $ \ldn -> do
|
||||
DB.execute
|
||||
db
|
||||
"INSERT INTO contact_profiles (display_name, full_name, image, contact_link, user_id, preferences, created_at, updated_at) VALUES (?,?,?,?,?,?,?,?)"
|
||||
(displayName, fullName, image, contactLink, userId, preferences, currentTs, currentTs)
|
||||
profileId <- insertedRowId db
|
||||
DB.execute
|
||||
db
|
||||
"INSERT INTO contacts (user_id, local_display_name, contact_profile_id, enable_ntfs, user_preferences, created_at, updated_at, chat_ts, xcontact_id, contact_used) VALUES (?,?,?,?,?,?,?,?,?,?)"
|
||||
(userId, ldn, profileId, BI True, userPreferences, currentTs, currentTs, currentTs, xContactId, BI True)
|
||||
Right <$> insertedRowId db
|
||||
conn <- liftIO $ createAcceptedContactConn db user uclId contactId agentConnId connChatVersion cReqChatVRange pqSup incognitoProfile subMode currentTs
|
||||
ct <- getContact db vr user contactId
|
||||
pure (ct, conn)
|
||||
|
||||
updateContactAccepted :: DB.Connection -> User -> Contact -> Bool -> IO ()
|
||||
updateContactAccepted db User {userId} Contact {contactId} contactUsed =
|
||||
DB.execute
|
||||
|
|
|
@ -99,7 +99,6 @@ import Data.Type.Equality
|
|||
import Data.Word (Word32)
|
||||
import Simplex.Chat.Messages
|
||||
import Simplex.Chat.Messages.CIContent
|
||||
import Simplex.Chat.Protocol
|
||||
import Simplex.Chat.Store.Direct
|
||||
import Simplex.Chat.Store.Messages
|
||||
import Simplex.Chat.Store.Profiles
|
||||
|
|
|
@ -118,6 +118,8 @@ chatProfileTests = do
|
|||
it "prepare contact with image in profile" testShortLinkInvitationImage
|
||||
it "prepare contact with a long name in profile" testShortLinkInvitationLongName
|
||||
it "prepare contact using address short link data and connect" testShortLinkAddressPrepareContact
|
||||
it "prepare contact via invitation and connect after it is deleted" testShortLinkDeletedInvitation
|
||||
it "prepare contact via address and connect after it is deleted" testShortLinkDeletedAddress
|
||||
it "prepare business chat using address short link data and connect" testShortLinkAddressPrepareBusiness
|
||||
it "prepare group using group short link data and connect" testShortLinkPrepareGroup
|
||||
it "prepare group using group short link data and connect, host rejects" testShortLinkPrepareGroupReject
|
||||
|
@ -3008,6 +3010,44 @@ testShortLinkAddressPrepareContact =
|
|||
(alice <## "bob (Bob): contact is connected")
|
||||
alice <##> bob
|
||||
|
||||
testShortLinkDeletedInvitation :: HasCallStack => TestParams -> IO ()
|
||||
testShortLinkDeletedInvitation =
|
||||
testChat2 aliceProfile bobProfile $
|
||||
\alice bob -> do
|
||||
alice ##> "/_connect 1"
|
||||
(shortLink, fullLink) <- getInvitations alice
|
||||
bob ##> ("/_connect plan 1 " <> shortLink)
|
||||
bob <## "invitation link: ok to connect"
|
||||
contactSLinkData <- getTermLine bob
|
||||
bob ##> ("/_prepare contact 1 " <> fullLink <> " " <> shortLink <> " " <> contactSLinkData)
|
||||
bob <## "alice: contact is prepared"
|
||||
alice @@@ [(":1","")]
|
||||
alice ##> "/_delete :1"
|
||||
alice <## "connection :1 deleted"
|
||||
bob ##> "/_connect contact @2"
|
||||
bob <##. "error: connection authorization failed"
|
||||
bob ##> "/_connect contact @2"
|
||||
bob <##. "error: connection authorization failed"
|
||||
|
||||
testShortLinkDeletedAddress :: HasCallStack => TestParams -> IO ()
|
||||
testShortLinkDeletedAddress =
|
||||
testChat2 aliceProfile bobProfile $
|
||||
\alice bob -> do
|
||||
alice ##> "/ad"
|
||||
(shortLink, fullLink) <- getContactLinks alice True
|
||||
bob ##> ("/_connect plan 1 " <> shortLink)
|
||||
bob <## "contact address: ok to connect"
|
||||
contactSLinkData <- getTermLine bob
|
||||
bob ##> ("/_prepare contact 1 " <> fullLink <> " " <> shortLink <> " " <> contactSLinkData)
|
||||
bob <## "alice: contact is prepared"
|
||||
alice ##> "/da"
|
||||
alice <## "Your chat address is deleted - accepted contacts will remain connected."
|
||||
alice <## "To create a new chat address use /ad"
|
||||
bob ##> "/_connect contact @2"
|
||||
bob <##. "error: connection authorization failed"
|
||||
bob ##> "/_connect contact @2"
|
||||
bob <##. "error: connection authorization failed"
|
||||
|
||||
testShortLinkAddressPrepareBusiness :: HasCallStack => TestParams -> IO ()
|
||||
testShortLinkAddressPrepareBusiness =
|
||||
testChat3 businessProfile aliceProfile {fullName = "Alice @ Biz"} bobProfile $
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue