From a378626a5a740741a898f3749ef098ba25fc8c1d Mon Sep 17 00:00:00 2001 From: Narasimha-sc <166327228+Narasimha-sc@users.noreply.github.com> Date: Mon, 27 Jul 2026 19:02:56 +0000 Subject: [PATCH] core: do not accept contact request that was already accepted --- src/Simplex/Chat/Library/Internal.hs | 4 ++++ tests/ChatTests/Profiles.hs | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/Simplex/Chat/Library/Internal.hs b/src/Simplex/Chat/Library/Internal.hs index 6fb002eaee..d900a92c5f 100644 --- a/src/Simplex/Chat/Library/Internal.hs +++ b/src/Simplex/Chat/Library/Internal.hs @@ -914,6 +914,10 @@ acceptContactRequest nm user@User {userId} UserContactRequest {agentInvitationId forM_ xContactId $ \xcId -> setContactAcceptedXContactId db ct xcId createAcceptedContactConn db user userContactLinkId_ contactId connId chatV cReqChatVRange pqSup' incognitoProfile subMode currentTs pure (ct {activeConn = Just conn} :: Contact, conn, incognitoProfile) + -- contact connection in any status other than prepared is created when the request is accepted + -- (see createAcceptedContactConn), so the request was already accepted - + -- accepting it again would fail in the agent, as the invitation is already used. + Just Connection {connStatus} | connStatus /= ConnPrepared -> throwCmdError "contact request already accepted" Just conn@Connection {customUserProfileId} -> do incognitoProfile <- forM customUserProfileId $ \pId -> withFastStore $ \db -> getProfileById db userId pId pure (ct, conn, ExistingIncognito <$> incognitoProfile) diff --git a/tests/ChatTests/Profiles.hs b/tests/ChatTests/Profiles.hs index 4b82779b0e..a012a1224c 100644 --- a/tests/ChatTests/Profiles.hs +++ b/tests/ChatTests/Profiles.hs @@ -61,6 +61,7 @@ chatProfileTests = do it "supporter badge sent to contact connecting via address" testUserBadgeContactAddress describe "user contact link" $ do it "create and connect via contact link" testUserContactLink + it "accepting contact request twice fails" testAcceptContactRequestTwice it "create address on specified server" testCreateAddressOnServer it "retry connecting via contact link" testRetryConnectingViaContactLink it "add contact link to profile" testProfileLink @@ -644,6 +645,24 @@ testUserContactLink = alice @@@ [("@cath", lastChatFeature), ("@bob", "hey")] alice <##> cath +testAcceptContactRequestTwice :: HasCallStack => TestParams -> IO () +testAcceptContactRequestTwice = + testChat2 aliceProfile bobProfile $ + \alice bob -> do + alice ##> "/ad" + cLink <- getContactLink alice True + bob ##> ("/c " <> cLink) + alice <#? bob + alice ##> "/ac bob" + alice <## "bob (Bob): accepting contact request, you can send messages to contact" + concurrently_ + (bob <## "alice (Alice): contact is connected") + (alice <## "bob (Bob): contact is connected") + -- the request is not deleted when accepted, accepting it again fails without using the invitation + alice ##> "/_accept 1" + alice <## "bad chat command: contact request already accepted" + alice <##> bob + testCreateAddressOnServer :: HasCallStack => TestParams -> IO () testCreateAddressOnServer ps = testChat aliceProfile test ps where