mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-10-23 17:13:10 +00:00
core: preserve profile peer type when connecting incognito (#7751)
* core: preserve profile peer type when connecting incognito * Apply batched suggestions from code review Co-authored-by: Evgeny <evgeny@poberezkin.com> * fix --------- Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
This commit is contained in:
1 parent
139ce5f8cc
commit
1d0247b7dd
7 files changed
+58
-23
No files matched your search
@@ -462,7 +462,7 @@ processChatCommand cxt nm = \case
|
||||
checkValidName displayName
|
||||
checkProfileImageSize image
|
||||
checkProfileSize p
|
||||
p@Profile {displayName} <- liftIO $ maybe generateRandomProfile pure profile
|
||||
p@Profile {displayName} <- liftIO $ maybe (generateRandomProfile Nothing) pure profile
|
||||
u <- asks currentUser
|
||||
users <- withFastStore' getUsers
|
||||
forM_ users $ \User {profile = LocalProfile {displayName = n}, activeUser, viewPwdHash, userChatRelay = userChatRelay'} -> do
|
||||
@@ -2132,7 +2132,7 @@ processChatCommand cxt nm = \case
|
||||
Welcome -> withUser $ pure . CRWelcome
|
||||
APIAddContact userId incognito -> withUserId userId $ \user -> do
|
||||
-- [incognito] generate profile for connection
|
||||
incognitoProfile <- if incognito then Just <$> liftIO generateRandomProfile else pure Nothing
|
||||
incognitoProfile <- if incognito then Just <$> liftIO (generateIncognitoProfile user) else pure Nothing
|
||||
subMode <- chatReadVar subscriptionMode
|
||||
(preparedReq, preparedParams@PreparedLinkParams {plpLinkKey = LinkKey linkKey}) <- withAgent $ \a -> prepareInvitationLink a (aUserId user) IKUsePQ Nothing
|
||||
linkProfile <- presentUserBadge user incognitoProfile (Just $ PHLink linkKey) $ userProfileDirect user incognitoProfile Nothing True
|
||||
@@ -2150,7 +2150,7 @@ processChatCommand cxt nm = \case
|
||||
let PendingContactConnection {pccConnStatus, customUserProfileId, connLinkInv} = conn
|
||||
case (pccConnStatus, customUserProfileId, incognito) of
|
||||
(ConnNew, Nothing, True) -> do
|
||||
incognitoProfile <- liftIO generateRandomProfile
|
||||
incognitoProfile <- liftIO $ generateIncognitoProfile user
|
||||
sLnk <- updatePCCShortLinkData conn $ userProfileDirect user (Just incognitoProfile) Nothing True
|
||||
conn' <- withFastStore' $ \db -> do
|
||||
pId <- createIncognitoProfile db user incognitoProfile
|
||||
@@ -2329,7 +2329,7 @@ processChatCommand cxt nm = \case
|
||||
publicMemberCount_ = (\PublicGroupData {publicMemberCount} -> publicMemberCount) <$> publicGroupData_
|
||||
-- Prepare group record once before connecting to relays (updatePreparedRelayedGroup):
|
||||
-- set group link info and incognito profile, generate and store membership keys
|
||||
incognitoProfile <- if incognito then Just <$> liftIO generateRandomProfile else pure Nothing
|
||||
incognitoProfile <- if incognito then Just <$> liftIO (generateIncognitoProfile user) else pure Nothing
|
||||
let cReqHash = contactCReqHash $ CRContactUri crData {crScheme = SSSimplex} e2e
|
||||
g'@(GIK gInfo' _) <- withFastStore $ \db -> do
|
||||
g'@(GIK gInfo' _) <- updatePreparedRelayedGroup db cxt user gInfo mainCReq cReqHash incognitoProfile rootKey publicMemberCount_
|
||||
@@ -3886,7 +3886,7 @@ processChatCommand cxt nm = \case
|
||||
pqSup' = PQSupportOn
|
||||
joinNewConn chatV = do
|
||||
-- [incognito] generate profile to send
|
||||
incognitoProfile <- if incognito then Just <$> liftIO generateRandomProfile else pure Nothing
|
||||
incognitoProfile <- if incognito then Just <$> liftIO (generateIncognitoProfile user) else pure Nothing
|
||||
(connId, binding) <- withAgent $ \a -> prepareConnectionToJoin a (aUserId user) True cReq pqSup'
|
||||
let ccLink = CCLink cReq $ serverShortLink <$> sLnk_
|
||||
conn <- withFastStore' $ \db -> createDirectConnection' db userId connId ccLink contactId_ ConnPrepared incognitoProfile subMode chatV pqSup'
|
||||
@@ -3958,7 +3958,7 @@ processChatCommand cxt nm = \case
|
||||
-- [incognito] generate profile to send, or use membership profile for relay groups
|
||||
incognitoProfile_ <- case gInfo_ of
|
||||
Just (Just (GIK gInfo _)) | useRelays' gInfo -> pure $ ExistingIncognito <$> incognitoMembershipProfile gInfo
|
||||
_ -> if incognito then Just . NewIncognito <$> liftIO generateRandomProfile else pure Nothing
|
||||
_ -> if incognito then Just . NewIncognito <$> liftIO (generateIncognitoProfile user) else pure Nothing
|
||||
let incognitoProfile = fromIncognitoProfile <$> incognitoProfile_
|
||||
subMode <- chatReadVar subscriptionMode
|
||||
let sLnk' = serverShortLink <$> sLnk
|
||||
@@ -3974,7 +3974,7 @@ processChatCommand cxt nm = \case
|
||||
(connId, chatV, reqHeader) <- prepareContact user cReq pqSup
|
||||
newXContactId <- XContactId <$> drgRandomBytes 16
|
||||
-- [incognito] generate profile to send
|
||||
incognitoProfile <- if incognito then Just <$> liftIO generateRandomProfile else pure Nothing
|
||||
incognitoProfile <- if incognito then Just <$> liftIO (generateIncognitoProfile user) else pure Nothing
|
||||
subMode <- chatReadVar subscriptionMode
|
||||
let cReqHash = contactCReqHash cReq
|
||||
conn <- withFastStore' $ \db -> createConnReqConnection db userId connId (Just $ PCEContact ct) cReq reqHeader cReqHash shortLink newXContactId (NewIncognito <$> incognitoProfile) Nothing subMode chatV pqSup
|
||||
@@ -4345,7 +4345,7 @@ processChatCommand cxt nm = \case
|
||||
when (isPublicGroup groupKeys && isJust (memberAdmission >>= review)) $ throwCmdError "Admission review is not supported in channels"
|
||||
when (not (isPublicGroup groupKeys) && isJust publicGroup) $ throwCmdError "publicGroup is not allowed in groups"
|
||||
-- [incognito] generate incognito profile for group membership
|
||||
incognitoProfile <- if incognito then Just <$> liftIO generateRandomProfile else pure Nothing
|
||||
incognitoProfile <- if incognito then Just <$> liftIO (generateIncognitoProfile user) else pure Nothing
|
||||
withFastStore $ \db -> createNewGroup db cxt user gProfile incognitoProfile memberId groupKeys publicMemberCount_
|
||||
createNewGroupItems :: User -> GroupInfo -> CM ()
|
||||
createNewGroupItems user gInfo = do
|
||||
|
||||
@@ -994,7 +994,7 @@ acceptContactRequest nm user@User {userId} UserContactRequest {agentInvitationId
|
||||
let chatV = vr cxt `peerConnChatVersion` cReqChatVRange
|
||||
(ct, conn, incognitoProfile, getPresHeader) <- case contactId_ of
|
||||
Nothing -> do
|
||||
incognitoProfile <- if incognito then Just . NewIncognito <$> liftIO generateRandomProfile else pure Nothing
|
||||
incognitoProfile <- if incognito then Just . NewIncognito <$> liftIO (generateIncognitoProfile user) else pure Nothing
|
||||
(connId, binding) <- withAgent $ \a -> prepareConnectionToAccept a (aUserId user) True invId pqSup'
|
||||
(ct, conn) <- withStore' $ \db ->
|
||||
createContactFromRequest db user userContactLinkId_ connId chatV cReqChatVRange cName profileId cp xContactId incognitoProfile subMode pqSup' False
|
||||
@@ -1003,7 +1003,7 @@ acceptContactRequest nm user@User {userId} UserContactRequest {agentInvitationId
|
||||
ct <- withFastStore $ \db -> getContact db cxt user contactId
|
||||
case contactConn ct of
|
||||
Nothing -> do
|
||||
incognitoProfile <- if incognito then Just . NewIncognito <$> liftIO generateRandomProfile else pure Nothing
|
||||
incognitoProfile <- if incognito then Just . NewIncognito <$> liftIO (generateIncognitoProfile user) else pure Nothing
|
||||
(connId, binding) <- withAgent $ \a -> prepareConnectionToAccept a (aUserId user) True invId pqSup'
|
||||
currentTs <- liftIO getCurrentTime
|
||||
conn <- withStore' $ \db -> do
|
||||
@@ -1336,6 +1336,9 @@ introduceInChannel cxt user g@(GIK gInfo _) subscriber@GroupMember {activeConn =
|
||||
sendIntros ms = forM_ (L.nonEmpty $ map (memberIntroEvt gInfo) ms) $ \evts ->
|
||||
sendGroupMemberMessages user g conn evts
|
||||
|
||||
generateIncognitoProfile :: User -> IO Profile
|
||||
generateIncognitoProfile User {profile = LocalProfile {peerType}} = generateRandomProfile peerType
|
||||
|
||||
userProfileInGroup :: User -> GroupInfo -> Maybe Profile -> Profile
|
||||
userProfileInGroup user g = userProfileInGroup' user (Just g)
|
||||
{-# INLINE userProfileInGroup #-}
|
||||
|
||||
@@ -57,7 +57,6 @@ import Simplex.Chat.Messages
|
||||
import Simplex.Chat.Messages.Batch (batchDeliveryTasks1, batchProfiles, batchProfilesWithBody, encodeBinaryBatch, encodeFwdElement, maxBatchElementSize)
|
||||
import Simplex.Chat.Messages.CIContent
|
||||
import Simplex.Chat.Messages.CIContent.Events
|
||||
import Simplex.Chat.ProfileGenerator (generateRandomProfile)
|
||||
import Simplex.Chat.Protocol
|
||||
import Simplex.Chat.Store
|
||||
import Simplex.Chat.Store.Connections
|
||||
@@ -1535,7 +1534,7 @@ processAgentMessageConn cxt user@User {userId} entity gks_ corrId agentConnId ag
|
||||
Just AutoAccept {acceptIncognito} -> do
|
||||
incognitoProfile <-
|
||||
if not shortLinkDataSet && acceptIncognito
|
||||
then Just . NewIncognito <$> liftIO generateRandomProfile
|
||||
then Just . NewIncognito <$> liftIO (generateIncognitoProfile user)
|
||||
else pure Nothing
|
||||
ct' <- acceptContactRequestAsync user uclId ct ucr incognitoProfile
|
||||
toView $ CEvtAcceptingContactRequest user ct'
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
{-# LANGUAGE NamedFieldPuns #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
|
||||
module Simplex.Chat.ProfileGenerator where
|
||||
|
||||
import Data.Text (Text)
|
||||
import Simplex.Chat.Types (Profile (..))
|
||||
import Simplex.Chat.Types (ChatPeerType, Profile (..))
|
||||
import System.Random (randomRIO)
|
||||
|
||||
generateRandomProfile :: IO Profile
|
||||
generateRandomProfile = do
|
||||
generateRandomProfile :: Maybe ChatPeerType -> IO Profile
|
||||
generateRandomProfile peerType = do
|
||||
adjective <- pick adjectives
|
||||
noun <- pickNoun adjective 2
|
||||
pure $ Profile {displayName = adjective <> noun, fullName = "", shortDescr = Nothing, description = Nothing, image = Nothing, contactLink = Nothing, peerType = Nothing, preferences = Nothing, badge = Nothing, contactDomain = Nothing}
|
||||
pure $ Profile {displayName = adjective <> noun, fullName = "", shortDescr = Nothing, description = Nothing, image = Nothing, contactLink = Nothing, peerType, preferences = Nothing, badge = Nothing, contactDomain = Nothing}
|
||||
where
|
||||
pick :: [a] -> IO a
|
||||
pick xs = (xs !!) <$> randomRIO (0, length xs - 1)
|
||||
|
||||
@@ -5108,8 +5108,8 @@ Query:
|
||||
Plan:
|
||||
|
||||
Query:
|
||||
INSERT INTO contact_profiles (display_name, full_name, short_descr, description, image, user_id, incognito, created_at, updated_at)
|
||||
VALUES (?,?,?,?,?,?,?,?,?)
|
||||
INSERT INTO contact_profiles (display_name, full_name, short_descr, description, image, chat_peer_type, user_id, incognito, created_at, updated_at)
|
||||
VALUES (?,?,?,?,?,?,?,?,?,?)
|
||||
|
||||
Plan:
|
||||
SEARCH contact_requests USING COVERING INDEX idx_contact_requests_contact_profile_id (contact_profile_id=?)
|
||||
|
||||
@@ -323,14 +323,14 @@ createConnection_ db userId connType entityId acId connStatus connChatVersion pe
|
||||
ent ct = if connType == ct then entityId else Nothing
|
||||
|
||||
createIncognitoProfile_ :: DB.Connection -> UserId -> UTCTime -> Profile -> IO Int64
|
||||
createIncognitoProfile_ db userId createdAt Profile {displayName, fullName, shortDescr, description, image} = do
|
||||
createIncognitoProfile_ db userId createdAt Profile {displayName, fullName, shortDescr, description, image, peerType} = do
|
||||
DB.execute
|
||||
db
|
||||
[sql|
|
||||
INSERT INTO contact_profiles (display_name, full_name, short_descr, description, image, user_id, incognito, created_at, updated_at)
|
||||
VALUES (?,?,?,?,?,?,?,?,?)
|
||||
INSERT INTO contact_profiles (display_name, full_name, short_descr, description, image, chat_peer_type, user_id, incognito, created_at, updated_at)
|
||||
VALUES (?,?,?,?,?,?,?,?,?,?)
|
||||
|]
|
||||
(displayName, fullName, shortDescr, description, image, userId, Just (BI True), createdAt, createdAt)
|
||||
(displayName, fullName, shortDescr, description, image, peerType, userId, Just (BI True), createdAt, createdAt)
|
||||
insertedRowId db
|
||||
|
||||
updateConnSupportPQ :: DB.Connection -> Int64 -> PQSupport -> PQEncryption -> IO ()
|
||||
|
||||
@@ -32,7 +32,7 @@ import Simplex.Chat.Options (ChatOpts (..), CoreChatOpts (..))
|
||||
import Simplex.Chat.Protocol (ChatBinding (..), ChatMsgEvent (XInfo), ContactShortLinkData (ContactShortLinkData), LinkOwnerSig, MsgChatLink (..), MsgContent (..), encodeChatBinding)
|
||||
import Simplex.Chat.Store.Groups (getGroupMembers)
|
||||
import Simplex.Chat.Store.Shared (createContact, getGroupInfoKeys)
|
||||
import Simplex.Chat.Types (AgentConnId (..), ConnStatus (..), GroupId, GroupInfo (..), GroupInfoKeys (..), GroupMember (..), Profile (..), GroupRejectionReason (..), fromLocalProfile, profileFromName, userProfileDirect, pattern VersionChat)
|
||||
import Simplex.Chat.Types (AgentConnId (..), ChatPeerType (..), ConnStatus (..), GroupId, GroupInfo (..), GroupInfoKeys (..), GroupMember (..), Profile (..), GroupRejectionReason (..), fromLocalProfile, profileFromName, userProfileDirect, pattern VersionChat)
|
||||
import qualified Simplex.Messaging.Crypto as C
|
||||
import Simplex.Messaging.Crypto.BBS (BBSPublicKey, BBSSecretKey, bbsKeyGen)
|
||||
import Simplex.Chat.Types.Shared (GroupMemberRole (..))
|
||||
@@ -133,6 +133,8 @@ chatProfileTests = do
|
||||
it "connection incognito unchanged errors" testConnectionIncognitoUnchangedErrors
|
||||
it "set, reset, set connection incognito" testSetResetSetConnectionIncognito
|
||||
it "join group incognito" testJoinGroupIncognito
|
||||
it "join group incognito as bot" $ testJoinGroupIncognitoPeerType (Just CPTBot)
|
||||
it "join group incognito as human" $ testJoinGroupIncognitoPeerType Nothing
|
||||
it "can't invite contact to whom user connected incognito to a group" testCantInviteContactIncognito
|
||||
it "can't see global preferences update" testCantSeeGlobalPrefsUpdateIncognito
|
||||
it "deleting contact first, group second deletes incognito profile" testDeleteContactThenGroupDeletesIncognitoProfile
|
||||
@@ -4905,6 +4907,36 @@ testShortLinkConnectPreparedGroupIncognito = testChat3 aliceProfile bobProfile c
|
||||
alice <# "#team cath> 3"
|
||||
bob ?<# "#team cath> 3"
|
||||
|
||||
testJoinGroupIncognitoPeerType :: HasCallStack => Maybe ChatPeerType -> TestParams -> IO ()
|
||||
testJoinGroupIncognitoPeerType peerType_ = testChat3 aliceProfile bobProfile {peerType = peerType_} cathProfile test
|
||||
where
|
||||
test alice bob cath = do
|
||||
createGroup2 "team" alice cath
|
||||
alice ##> "/create link #team"
|
||||
(shortLink, fullLink) <- getGroupLinks alice "team" GRMember True
|
||||
bob ##> ("/_connect plan 1 " <> shortLink)
|
||||
bob <## "group link: ok to connect directly"
|
||||
groupSLinkData <- getTermLine bob
|
||||
bob ##> ("/_prepare group 1 " <> fullLink <> " " <> shortLink <> " " <> groupSLinkData)
|
||||
bob <## "#team: group is prepared"
|
||||
bob ##> "/_connect group #1 incognito=on"
|
||||
bobIncognito <- getTermLine bob
|
||||
bob <## "#team: connection started incognito"
|
||||
alice <## (bobIncognito <> ": accepting request to join group #team...")
|
||||
concurrentlyN_
|
||||
[ alice <## ("#team: " <> bobIncognito <> " joined the group"),
|
||||
do
|
||||
bob <## "#team: joining the group..."
|
||||
bob <## ("#team: you joined the group incognito as " <> bobIncognito)
|
||||
bob <## "#team: member cath (Catherine) is connected",
|
||||
do
|
||||
cath <## ("#team: alice added " <> bobIncognito <> " to the group (connecting...)")
|
||||
cath <## ("#team: new member " <> bobIncognito <> " is connected")
|
||||
]
|
||||
forM_ [alice, cath] $ \cc -> do
|
||||
GroupMember {memberProfile} <- getTestMember cc "team" (T.pack bobIncognito)
|
||||
peerType (fromLocalProfile memberProfile) `shouldBe` peerType_
|
||||
|
||||
testShortLinkChangePreparedGroupUser :: HasCallStack => TestParams -> IO ()
|
||||
testShortLinkChangePreparedGroupUser = testChat3 aliceProfile bobProfile cathProfile test
|
||||
where
|
||||
|
||||
Reference in new issue
Block a user