mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-10-22 21:52:28 +00:00
core: fix profile creation and update in channels (#7740)
Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
This commit is contained in:
1 parent
77f9f4a464
commit
139ce5f8cc
5 files changed
+74
-19
No files matched your search
@@ -76,7 +76,7 @@ createOrUpdateContactRequest
|
||||
invId
|
||||
cReqChatVRange@(VersionRange minV maxV)
|
||||
presHeader_
|
||||
profile@Profile {displayName, fullName, shortDescr, description, image, contactLink, preferences}
|
||||
profile@Profile {displayName, fullName, shortDescr, description, image, contactLink, peerType, preferences}
|
||||
xContactId_
|
||||
welcomeMsgId_
|
||||
requestMsg_
|
||||
@@ -174,8 +174,8 @@ createOrUpdateContactRequest
|
||||
liftIO $
|
||||
DB.execute
|
||||
db
|
||||
"INSERT INTO contact_profiles (display_name, full_name, short_descr, description, image, contact_link, user_id, local_alias, created_at, updated_at, badge_proof, badge_pres_header, badge_expiry, badge_type, badge_verified, badge_extra, badge_master_key, badge_signature, badge_key_idx, preferences, preferences_json) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
|
||||
((displayName, fullName, shortDescr, description, image, contactLink, userId) :. ("" :: LocalAlias, currentTs, currentTs) :. badgeToRow badge badgeVerified :. prefsToRow preferences)
|
||||
"INSERT INTO contact_profiles (display_name, full_name, short_descr, description, image, contact_link, chat_peer_type, user_id, local_alias, created_at, updated_at, badge_proof, badge_pres_header, badge_expiry, badge_type, badge_verified, badge_extra, badge_master_key, badge_signature, badge_key_idx, preferences, preferences_json) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
|
||||
((displayName, fullName, shortDescr, description, image, contactLink, peerType, userId) :. ("" :: LocalAlias, currentTs, currentTs) :. badgeToRow badge badgeVerified :. prefsToRow preferences)
|
||||
profileId <- liftIO $ insertedRowId db
|
||||
liftIO $
|
||||
DB.execute
|
||||
@@ -247,6 +247,7 @@ createOrUpdateContactRequest
|
||||
description = ?,
|
||||
image = ?,
|
||||
contact_link = ?,
|
||||
chat_peer_type = ?,
|
||||
updated_at = ?,
|
||||
badge_proof = ?,
|
||||
badge_pres_header = ?,
|
||||
@@ -264,7 +265,7 @@ createOrUpdateContactRequest
|
||||
AND contact_request_id = ?
|
||||
)
|
||||
|]
|
||||
((displayName, fullName, shortDescr, description, image, contactLink, currentTs) :. badgeToRow badge badgeVerified :. (userId, contactRequestId))
|
||||
((displayName, fullName, shortDescr, description, image, contactLink, peerType, currentTs) :. badgeToRow badge badgeVerified :. (userId, contactRequestId))
|
||||
updateRequest currentTs =
|
||||
if displayName == oldDisplayName
|
||||
then
|
||||
|
||||
@@ -752,17 +752,17 @@ updateMemberContactProfileReset_ db userId profileId profile badgeVerified = do
|
||||
updateMemberContactProfileReset_' db userId profileId profile badgeVerified currentTs
|
||||
|
||||
updateMemberContactProfileReset_' :: DB.Connection -> UserId -> ProfileId -> Profile -> Maybe Bool -> UTCTime -> IO ()
|
||||
updateMemberContactProfileReset_' db userId profileId Profile {displayName, fullName, shortDescr, description, image, contactDomain, badge} badgeVerified updatedAt =
|
||||
updateMemberContactProfileReset_' db userId profileId Profile {displayName, fullName, shortDescr, description, image, contactLink, peerType, contactDomain, badge} badgeVerified updatedAt =
|
||||
DB.execute
|
||||
db
|
||||
[sql|
|
||||
UPDATE contact_profiles
|
||||
SET display_name = ?, full_name = ?, short_descr = ?, description = ?, image = ?, contact_link = NULL, preferences = NULL, preferences_json = NULL, updated_at = ?,
|
||||
SET display_name = ?, full_name = ?, short_descr = ?, description = ?, image = ?, contact_link = ?, chat_peer_type = ?, preferences = NULL, preferences_json = NULL, updated_at = ?,
|
||||
badge_proof = ?, badge_pres_header = ?, badge_expiry = ?, badge_type = ?, badge_verified = ?, badge_extra = ?, badge_master_key = ?, badge_signature = ?, badge_key_idx = ?,
|
||||
contact_domain = ?, contact_domain_proof = ?
|
||||
WHERE user_id = ? AND contact_profile_id = ?
|
||||
|]
|
||||
((displayName, fullName, shortDescr, description, image, updatedAt) :. badgeToRow badge badgeVerified :. contactDomainToRow contactDomain :. (userId, profileId))
|
||||
((displayName, fullName, shortDescr, description, image, contactLink, peerType, updatedAt) :. badgeToRow badge badgeVerified :. contactDomainToRow contactDomain :. (userId, profileId))
|
||||
|
||||
-- update only member profile fields (when member has associated contact - we keep contactLink and prefs)
|
||||
updateMemberContactProfile_ :: DB.Connection -> UserId -> ProfileId -> Profile -> Maybe Bool -> IO ()
|
||||
|
||||
@@ -2127,7 +2127,7 @@ createJoiningMember
|
||||
User {userId, userContactId}
|
||||
GroupInfo {groupId, membership}
|
||||
cReqChatVRange
|
||||
p@Profile {displayName, fullName, shortDescr, description, image, contactLink, preferences}
|
||||
p@Profile {displayName, fullName, shortDescr, description, image, contactLink, peerType, preferences}
|
||||
presHeader_
|
||||
cReqXContactId_
|
||||
cReqMemberId_
|
||||
@@ -2141,8 +2141,8 @@ createJoiningMember
|
||||
liftIO $
|
||||
DB.execute
|
||||
db
|
||||
"INSERT INTO contact_profiles (display_name, full_name, short_descr, description, image, contact_link, user_id, created_at, updated_at, badge_proof, badge_pres_header, badge_expiry, badge_type, badge_verified, badge_extra, badge_master_key, badge_signature, badge_key_idx, preferences, preferences_json) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
|
||||
((displayName, fullName, shortDescr, description, image, contactLink, userId, currentTs, currentTs) :. badgeToRow badge badgeVerified :. prefsToRow preferences)
|
||||
"INSERT INTO contact_profiles (display_name, full_name, short_descr, description, image, contact_link, chat_peer_type, user_id, created_at, updated_at, badge_proof, badge_pres_header, badge_expiry, badge_type, badge_verified, badge_extra, badge_master_key, badge_signature, badge_key_idx, preferences, preferences_json) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
|
||||
((displayName, fullName, shortDescr, description, image, contactLink, peerType, userId, currentTs, currentTs) :. badgeToRow badge badgeVerified :. prefsToRow preferences)
|
||||
profileId <- liftIO $ insertedRowId db
|
||||
r@(groupMemberId, _) <- case cReqMemberId_ of
|
||||
Just memberId -> do
|
||||
@@ -2500,13 +2500,13 @@ createNewGroupMember db cxt user gInfo invitingMember memInfo@MemberInfo {profil
|
||||
createNewMember_ db user (groupId' gInfo) newMember badgeVerified currentTs
|
||||
|
||||
createNewMemberProfile_ :: DB.Connection -> StoreCxt -> User -> Profile -> Maybe ProofPresHeader -> UTCTime -> ExceptT StoreError IO (Text, ProfileId, Profile, Maybe Bool)
|
||||
createNewMemberProfile_ db cxt User {userId} p@Profile {displayName, fullName, shortDescr, description, image, contactLink, preferences} presHeader_ createdAt =
|
||||
createNewMemberProfile_ db cxt User {userId} p@Profile {displayName, fullName, shortDescr, description, image, contactLink, peerType, preferences} presHeader_ createdAt =
|
||||
ExceptT . withLocalDisplayName db userId displayName $ \ldn -> do
|
||||
(p'@Profile {badge}, badgeVerified) <- profileBadgeVerified presHeader_ (badgeKeys cxt) Nothing p
|
||||
DB.execute
|
||||
db
|
||||
"INSERT INTO contact_profiles (display_name, full_name, short_descr, description, image, contact_link, user_id, created_at, updated_at, badge_proof, badge_pres_header, badge_expiry, badge_type, badge_verified, badge_extra, badge_master_key, badge_signature, badge_key_idx, preferences, preferences_json) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
|
||||
((displayName, fullName, shortDescr, description, image, contactLink, userId, createdAt, createdAt) :. badgeToRow badge badgeVerified :. prefsToRow preferences)
|
||||
"INSERT INTO contact_profiles (display_name, full_name, short_descr, description, image, contact_link, chat_peer_type, user_id, created_at, updated_at, badge_proof, badge_pres_header, badge_expiry, badge_type, badge_verified, badge_extra, badge_master_key, badge_signature, badge_key_idx, preferences, preferences_json) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
|
||||
((displayName, fullName, shortDescr, description, image, contactLink, peerType, userId, createdAt, createdAt) :. badgeToRow badge badgeVerified :. prefsToRow preferences)
|
||||
profileId <- insertedRowId db
|
||||
pure $ Right (ldn, profileId, p', badgeVerified)
|
||||
|
||||
|
||||
@@ -507,6 +507,7 @@ Query:
|
||||
description = ?,
|
||||
image = ?,
|
||||
contact_link = ?,
|
||||
chat_peer_type = ?,
|
||||
updated_at = ?,
|
||||
badge_proof = ?,
|
||||
badge_pres_header = ?,
|
||||
@@ -5463,7 +5464,7 @@ SEARCH contact_profiles USING INTEGER PRIMARY KEY (rowid=?)
|
||||
|
||||
Query:
|
||||
UPDATE contact_profiles
|
||||
SET display_name = ?, full_name = ?, short_descr = ?, description = ?, image = ?, contact_link = NULL, preferences = NULL, preferences_json = NULL, updated_at = ?,
|
||||
SET display_name = ?, full_name = ?, short_descr = ?, description = ?, image = ?, contact_link = ?, chat_peer_type = ?, preferences = NULL, preferences_json = NULL, updated_at = ?,
|
||||
badge_proof = ?, badge_pres_header = ?, badge_expiry = ?, badge_type = ?, badge_verified = ?, badge_extra = ?, badge_master_key = ?, badge_signature = ?, badge_key_idx = ?,
|
||||
contact_domain = ?, contact_domain_proof = ?
|
||||
WHERE user_id = ? AND contact_profile_id = ?
|
||||
@@ -7358,15 +7359,15 @@ Query: INSERT INTO contact_profiles (display_name, full_name, short_descr, descr
|
||||
Plan:
|
||||
SEARCH contact_requests USING COVERING INDEX idx_contact_requests_contact_profile_id (contact_profile_id=?)
|
||||
|
||||
Query: INSERT INTO contact_profiles (display_name, full_name, short_descr, description, image, contact_link, chat_peer_type, user_id, created_at, updated_at, badge_proof, badge_pres_header, badge_expiry, badge_type, badge_verified, badge_extra, badge_master_key, badge_signature, badge_key_idx, preferences, preferences_json) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
|
||||
Plan:
|
||||
SEARCH contact_requests USING COVERING INDEX idx_contact_requests_contact_profile_id (contact_profile_id=?)
|
||||
|
||||
Query: INSERT INTO contact_profiles (display_name, full_name, short_descr, description, image, contact_link, chat_peer_type, user_id, local_alias, created_at, updated_at, badge_proof, badge_pres_header, badge_expiry, badge_type, badge_verified, badge_extra, badge_master_key, badge_signature, badge_key_idx, contact_domain, contact_domain_proof, preferences, preferences_json) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
|
||||
Plan:
|
||||
SEARCH contact_requests USING COVERING INDEX idx_contact_requests_contact_profile_id (contact_profile_id=?)
|
||||
|
||||
Query: INSERT INTO contact_profiles (display_name, full_name, short_descr, description, image, contact_link, user_id, created_at, updated_at, badge_proof, badge_pres_header, badge_expiry, badge_type, badge_verified, badge_extra, badge_master_key, badge_signature, badge_key_idx, preferences, preferences_json) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
|
||||
Plan:
|
||||
SEARCH contact_requests USING COVERING INDEX idx_contact_requests_contact_profile_id (contact_profile_id=?)
|
||||
|
||||
Query: INSERT INTO contact_profiles (display_name, full_name, short_descr, description, image, contact_link, user_id, local_alias, created_at, updated_at, badge_proof, badge_pres_header, badge_expiry, badge_type, badge_verified, badge_extra, badge_master_key, badge_signature, badge_key_idx, preferences, preferences_json) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
|
||||
Query: INSERT INTO contact_profiles (display_name, full_name, short_descr, description, image, contact_link, chat_peer_type, user_id, local_alias, created_at, updated_at, badge_proof, badge_pres_header, badge_expiry, badge_type, badge_verified, badge_extra, badge_master_key, badge_signature, badge_key_idx, preferences, preferences_json) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
|
||||
Plan:
|
||||
SEARCH contact_requests USING COVERING INDEX idx_contact_requests_contact_profile_id (contact_profile_id=?)
|
||||
|
||||
@@ -7930,6 +7931,11 @@ Query: SELECT notification FROM delivery_jobs ORDER BY delivery_job_id DESC LIMI
|
||||
Plan:
|
||||
SCAN delivery_jobs
|
||||
|
||||
Query: SELECT p.contact_link, p.chat_peer_type FROM group_members m JOIN contact_profiles p ON p.contact_profile_id = m.contact_profile_id WHERE m.local_display_name = ?
|
||||
Plan:
|
||||
SCAN m
|
||||
SEARCH p USING INTEGER PRIMARY KEY (rowid=?)
|
||||
|
||||
Query: SELECT purchase_key FROM badge_code_redemptions
|
||||
Plan:
|
||||
SCAN badge_code_redemptions
|
||||
|
||||
@@ -305,6 +305,7 @@ chatGroupTests = do
|
||||
it "multiple large profiles pack across batches in one multi-sender job" testChannelMultipleLargeProfiles
|
||||
it "overflow profile batch is sent without notification flag" testChannelOverflowProfileNotification
|
||||
it "profile update reuses existing announcement (no re-prepend)" testChannelProfileUpdateNoRePrepend
|
||||
it "owner, relay and subscriber store address and peer type of promoted member" testChannelMemberAddressPeerType
|
||||
describe "channel operations" $ do
|
||||
it "should update channel profile (signed)" testChannelUpdateProfileSigned
|
||||
it "should preserve working link after profile update" testChannelLinkAfterProfileUpdate
|
||||
@@ -10234,6 +10235,53 @@ testChannelProfileUpdateNoRePrepend ps =
|
||||
threadDelay 500000
|
||||
memberIntroducedTo bob "kate" "dan"
|
||||
|
||||
testChannelMemberAddressPeerType :: HasCallStack => TestParams -> IO ()
|
||||
testChannelMemberAddressPeerType ps =
|
||||
withNewTestChat ps "alice" aliceProfile $ \alice ->
|
||||
withNewTestChatOpts ps relayTestOpts "bob" bobProfile $ \bob ->
|
||||
withNewTestChat ps "cath" cathBotProfile $ \cath ->
|
||||
withNewTestChat ps "dan" danProfile $ \dan -> do
|
||||
_ <- setupRelay alice bob
|
||||
alice ##> "/_public group 1 1 {\"displayName\": \"team\", \"fullName\": \"\", \"groupPreferences\": {\"directMessages\": {\"enable\": \"on\"}, \"support\": {\"enable\": \"off\"}}}"
|
||||
alice <## "group #team is created"
|
||||
alice <## "wait for selected relay(s) to join, then you can invite members via group link"
|
||||
concurrentlyN_
|
||||
[ do
|
||||
alice <## "#team: group link relays updated, current relays:"
|
||||
alice <## " - relay id 1: active"
|
||||
alice <## "group link:"
|
||||
void $ getTermLine alice,
|
||||
bob <## "#team: you joined the group as relay"
|
||||
]
|
||||
alice ##> "/show link #team"
|
||||
(shortLink, fullLink) <- getGroupLinks alice "team" GRObserver False
|
||||
|
||||
cath ##> "/ad"
|
||||
_ <- getContactLinks cath True
|
||||
cath ##> "/pa on"
|
||||
cath <## "new contact address set"
|
||||
|
||||
memberJoinChannel "team" [bob] [alice] shortLink fullLink cath
|
||||
memberJoinChannel "team" [bob] [alice] shortLink fullLink dan
|
||||
promoteChannelMember "team" alice bob cath [dan]
|
||||
|
||||
cath #> "#team hi from cath"
|
||||
bob <# "#team cath> hi from cath"
|
||||
alice <# "#team cath> hi from cath [>>]"
|
||||
dan <### [EndsWith "updated to cath"]
|
||||
dan <## "#team: bob introduced cath (Catherine) in the channel"
|
||||
dan <# "#team cath> hi from cath [>>]"
|
||||
|
||||
Just cathAddress <- withCCUser cath $ \User {profile = LocalProfile {contactLink}} -> pure contactLink
|
||||
mapM (`memberAddressPeerType` "cath") [alice, bob, dan] `shouldReturn` replicate 3 [(Just cathAddress, Just CPTBot)]
|
||||
where
|
||||
cathBotProfile = (cathProfile :: Profile) {peerType = Just CPTBot}
|
||||
|
||||
memberAddressPeerType :: TestCC -> T.Text -> IO [(Maybe ConnLinkContact, Maybe ChatPeerType)]
|
||||
memberAddressPeerType cc name =
|
||||
withCCTransaction cc $ \db ->
|
||||
DB.query db "SELECT p.contact_link, p.chat_peer_type FROM group_members m JOIN contact_profiles p ON p.contact_profile_id = m.contact_profile_id WHERE m.local_display_name = ?" (Only name)
|
||||
|
||||
testChannelMultiSendersIndependent :: HasCallStack => TestParams -> IO ()
|
||||
testChannelMultiSendersIndependent ps =
|
||||
withNewTestChat ps "alice" aliceProfile $ \alice -> do
|
||||
|
||||
Reference in new issue
Block a user