mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-10-23 00:02:28 +00:00
core: supporter badges using anonymous BBS credentials (#7040)
* core: supporter badges using anonymous BBS credentials * badges in profiles * badge in profiles * process badges * update simplexmq * update simplexmq * change types * fix migration * migration * update simplexmq * fix bot API, schema * fix postgresql build * refactor * postgresql schema * correctly set badges in all cases * badges ffi * plan, bot types * FFI * FFI: export badge symbols * add extra field * refactor badge types to GADT * configurable badge key * add badge to profile, test * ui: badge images * generate badge key and sign badge * badge sign in CLI * fix commands, ui * rename badges * Binary * image size, migration * update badge images, add public key * send badges in more cases * update UI, tests * bot types, schema * postgres schema * tone down badges * revert formula * refactor badges * smaller badges * badge position * better badge position * simpler * position * move position * update simplexmq * show badge after name * badge layout * fix badge * debug badge height * shift badge * fix badge in member name * bigger badge * badge layout * differentiate badge colors * more avatars for the user's profiles * refactor * remove color filter * alerts * multiple keys, old expired * use new BBS api * update badge keys, bot api * presentation header * simplify * parser * update iOS images * update public keys * query plans * update simplexmq * refactor badge types * simplexmq * bot api types * update simplexmq - commoncrypto flag * update simplexmq * pass commoncrypto flag to simplexmq in nix iOS build * ios ui * update core library, fixes * badge layout * badge size * badge gap * remove extensions * simplify * share badge in more events, reverify badge if verification failed * larger files with badges * allow sending larger files * simpler * update simplexmq * better decoder for badge keys * update simplexmq --------- Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com> Co-authored-by: shum <github.shum@liber.li>
This commit is contained in:
116 files changed
+3121
-654
No files matched your search
@@ -196,6 +196,7 @@ import Data.Text (Text)
|
||||
import qualified Data.Text as T
|
||||
import Data.Time.Clock (NominalDiffTime, UTCTime (..), addUTCTime, getCurrentTime)
|
||||
import Data.Text.Encoding (encodeUtf8)
|
||||
import Simplex.Chat.Badges (BadgeRow, badgeToRow, verifyBadge_)
|
||||
import Simplex.Chat.Messages
|
||||
import Simplex.Chat.Operators
|
||||
import Simplex.Chat.Protocol hiding (Binary)
|
||||
@@ -225,12 +226,12 @@ import Database.SQLite.Simple (Only (..), Query, (:.) (..))
|
||||
import Database.SQLite.Simple.QQ (sql)
|
||||
#endif
|
||||
|
||||
type MaybeGroupMemberRow = (Maybe GroupMemberId, Maybe GroupId, Maybe Int64, Maybe MemberId, Maybe VersionChat, Maybe VersionChat, Maybe GroupMemberRole, Maybe GroupMemberCategory, Maybe GroupMemberStatus, Maybe BoolInt, Maybe MemberRestrictionStatus) :. (Maybe Int64, Maybe GroupMemberId, Maybe ContactName, Maybe ContactId, Maybe ProfileId) :. (Maybe ProfileId, Maybe ContactName, Maybe Text, Maybe Text, Maybe ImageData, Maybe ConnLinkContact, Maybe ChatPeerType, Maybe LocalAlias, Maybe Preferences) :. (Maybe UTCTime, Maybe UTCTime) :. (Maybe UTCTime, Maybe Int64, Maybe Int64, Maybe Int64, Maybe UTCTime, Maybe C.PublicKeyEd25519, Maybe ShortLinkContact)
|
||||
type MaybeGroupMemberRow = (Maybe GroupMemberId, Maybe GroupId, Maybe Int64, Maybe MemberId, Maybe VersionChat, Maybe VersionChat, Maybe GroupMemberRole, Maybe GroupMemberCategory, Maybe GroupMemberStatus, Maybe BoolInt, Maybe MemberRestrictionStatus) :. (Maybe Int64, Maybe GroupMemberId, Maybe ContactName, Maybe ContactId, Maybe ProfileId) :. ((Maybe ProfileId, Maybe ContactName, Maybe Text, Maybe Text, Maybe ImageData, Maybe ConnLinkContact, Maybe ChatPeerType, Maybe LocalAlias, Maybe Preferences) :. BadgeRow) :. (Maybe UTCTime, Maybe UTCTime) :. (Maybe UTCTime, Maybe Int64, Maybe Int64, Maybe Int64, Maybe UTCTime, Maybe C.PublicKeyEd25519, Maybe ShortLinkContact)
|
||||
|
||||
toMaybeGroupMember :: Int64 -> MaybeGroupMemberRow -> Maybe GroupMember
|
||||
toMaybeGroupMember userContactId ((Just groupMemberId, Just groupId, Just indexInGroup, Just memberId, Just minVer, Just maxVer, Just memberRole, Just memberCategory, Just memberStatus, Just showMessages, memberBlocked') :. (invitedById, invitedByGroupMemberId, Just localDisplayName, memberContactId, Just memberContactProfileId) :. (Just profileId, Just displayName, Just fullName, shortDescr, image, contactLink, peerType, Just localAlias, contactPreferences) :. (Just createdAt, Just updatedAt) :. (supportChatTs, Just supportChatUnread, Just supportChatUnanswered, Just supportChatMentions, supportChatLastMsgFromMemberTs, memberPubKey, relayLink)) =
|
||||
Just $ toGroupMember userContactId ((groupMemberId, groupId, indexInGroup, memberId, minVer, maxVer, memberRole, memberCategory, memberStatus, showMessages, memberBlocked') :. (invitedById, invitedByGroupMemberId, localDisplayName, memberContactId, memberContactProfileId) :. (profileId, displayName, fullName, shortDescr, image, contactLink, peerType, localAlias, contactPreferences) :. (createdAt, updatedAt) :. (supportChatTs, supportChatUnread, supportChatUnanswered, supportChatMentions, supportChatLastMsgFromMemberTs, memberPubKey, relayLink))
|
||||
toMaybeGroupMember _ _ = Nothing
|
||||
toMaybeGroupMember :: UTCTime -> Int64 -> MaybeGroupMemberRow -> Maybe GroupMember
|
||||
toMaybeGroupMember now userContactId ((Just groupMemberId, Just groupId, Just indexInGroup, Just memberId, Just minVer, Just maxVer, Just memberRole, Just memberCategory, Just memberStatus, Just showMessages, memberBlocked') :. (invitedById, invitedByGroupMemberId, Just localDisplayName, memberContactId, Just memberContactProfileId) :. ((Just profileId, Just displayName, Just fullName, shortDescr, image, contactLink, peerType, Just localAlias, contactPreferences) :. badgeRow) :. (Just createdAt, Just updatedAt) :. (supportChatTs, Just supportChatUnread, Just supportChatUnanswered, Just supportChatMentions, supportChatLastMsgFromMemberTs, memberPubKey, relayLink)) =
|
||||
Just $ toGroupMember now userContactId ((groupMemberId, groupId, indexInGroup, memberId, minVer, maxVer, memberRole, memberCategory, memberStatus, showMessages, memberBlocked') :. (invitedById, invitedByGroupMemberId, localDisplayName, memberContactId, memberContactProfileId) :. ((profileId, displayName, fullName, shortDescr, image, contactLink, peerType, localAlias, contactPreferences) :. badgeRow) :. (createdAt, updatedAt) :. (supportChatTs, supportChatUnread, supportChatUnanswered, supportChatMentions, supportChatLastMsgFromMemberTs, memberPubKey, relayLink))
|
||||
toMaybeGroupMember _ _ _ = Nothing
|
||||
|
||||
createGroupLink :: DB.Connection -> TVar ChaChaDRG -> User -> GroupInfo -> ConnId -> CreatedLinkContact -> GroupLinkId -> GroupMemberRole -> SubscriptionMode -> ExceptT StoreError IO GroupLink
|
||||
createGroupLink db gVar user@User {userId} groupInfo@GroupInfo {groupId, localDisplayName} agentConnId (CCLink cReq shortLink) groupLinkId memberRole subMode = do
|
||||
@@ -634,7 +635,7 @@ createPreparedGroup db gVar cxt user@User {userId, userContactId} groupProfile b
|
||||
randHostId <- liftIO $ encodedRandomBytes gVar 12
|
||||
let memberId = MemberId $ encodeUtf8 groupLDN <> "_unknown_host_" <> randHostId
|
||||
hostProfile = profileFromName $ nameFromBS randHostId
|
||||
(localDisplayName, profileId) <- createNewMemberProfile_ db user hostProfile currentTs
|
||||
(localDisplayName, profileId, _) <- createNewMemberProfile_ db cxt user hostProfile currentTs
|
||||
indexInGroup <- getUpdateNextIndexInGroup_ db groupId
|
||||
liftIO $ do
|
||||
DB.execute
|
||||
@@ -789,7 +790,7 @@ updatePreparedUserAndHostMembers'
|
||||
|]
|
||||
(memberId, memberRole, membershipStatus, currentTs, groupMemberId' membership)
|
||||
updateHostMember currentTs = do
|
||||
_ <- updateMemberProfile db user hostMember fromMemberProfile
|
||||
_ <- updateMemberProfile db cxt user hostMember fromMemberProfile
|
||||
let MemberIdRole memberId memberRole = fromMember
|
||||
gmId = groupMemberId' hostMember
|
||||
liftIO $
|
||||
@@ -839,7 +840,7 @@ createGroupViaLink'
|
||||
(,) <$> getGroupInfo db cxt user groupId <*> getGroupMemberById db cxt user hostMemberId
|
||||
where
|
||||
insertHost_ currentTs groupId = do
|
||||
(localDisplayName, profileId) <- createNewMemberProfile_ db user fromMemberProfile currentTs
|
||||
(localDisplayName, profileId, _) <- createNewMemberProfile_ db cxt user fromMemberProfile currentTs
|
||||
let MemberIdRole {memberId, memberRole} = fromMember
|
||||
indexInGroup <- getUpdateNextIndexInGroup_ db groupId
|
||||
liftIO $ do
|
||||
@@ -1005,7 +1006,8 @@ getInProgressGroups db cxt user@User {userId} createdAtCutoff = do
|
||||
|
||||
getBaseGroupDetails :: DB.Connection -> StoreCxt -> User -> Maybe ContactId -> Maybe Text -> IO [GroupInfo]
|
||||
getBaseGroupDetails db cxt User {userId, userContactId} _contactId_ search_ = do
|
||||
map (toGroupInfo cxt userContactId [])
|
||||
currentTs <- getCurrentTime
|
||||
map (toGroupInfo currentTs cxt userContactId [])
|
||||
<$> DB.query db (groupInfoQuery <> " " <> condition) (userId, userContactId, search, search, search, search)
|
||||
where
|
||||
condition =
|
||||
@@ -1039,16 +1041,18 @@ getGroupInfoByName db cxt user gName = do
|
||||
getGroupInfo db cxt user gId
|
||||
|
||||
getGroupMember :: DB.Connection -> StoreCxt -> User -> GroupId -> GroupMemberId -> ExceptT StoreError IO GroupMember
|
||||
getGroupMember db cxt user@User {userId} groupId groupMemberId =
|
||||
ExceptT . firstRow (toContactMember cxt user) (SEGroupMemberNotFound groupMemberId) $
|
||||
getGroupMember db cxt user@User {userId} groupId groupMemberId = do
|
||||
currentTs <- liftIO getCurrentTime
|
||||
ExceptT . firstRow (toContactMember currentTs cxt user) (SEGroupMemberNotFound groupMemberId) $
|
||||
DB.query
|
||||
db
|
||||
(groupMemberQuery <> " WHERE m.group_id = ? AND m.group_member_id = ? AND m.user_id = ?")
|
||||
(groupId, groupMemberId, userId)
|
||||
|
||||
getHostMember :: DB.Connection -> StoreCxt -> User -> GroupId -> ExceptT StoreError IO GroupMember
|
||||
getHostMember db cxt user groupId =
|
||||
ExceptT . firstRow (toContactMember cxt user) (SEGroupHostMemberNotFound groupId) $
|
||||
getHostMember db cxt user groupId = do
|
||||
currentTs <- liftIO getCurrentTime
|
||||
ExceptT . firstRow (toContactMember currentTs cxt user) (SEGroupHostMemberNotFound groupId) $
|
||||
DB.query
|
||||
db
|
||||
(groupMemberQuery <> " WHERE m.group_id = ? AND m.member_category = ?")
|
||||
@@ -1088,32 +1092,36 @@ toMentionedMember (groupMemberId, memberId, memberRole, displayName, localAlias)
|
||||
in CIMention {memberId, memberRef}
|
||||
|
||||
getGroupMemberById :: DB.Connection -> StoreCxt -> User -> GroupMemberId -> ExceptT StoreError IO GroupMember
|
||||
getGroupMemberById db cxt user@User {userId} groupMemberId =
|
||||
ExceptT . firstRow (toContactMember cxt user) (SEGroupMemberNotFound groupMemberId) $
|
||||
getGroupMemberById db cxt user@User {userId} groupMemberId = do
|
||||
currentTs <- liftIO getCurrentTime
|
||||
ExceptT . firstRow (toContactMember currentTs cxt user) (SEGroupMemberNotFound groupMemberId) $
|
||||
DB.query
|
||||
db
|
||||
(groupMemberQuery <> " WHERE m.group_member_id = ? AND m.user_id = ?")
|
||||
(groupMemberId, userId)
|
||||
|
||||
getGroupMemberByIndex :: DB.Connection -> StoreCxt -> User -> GroupInfo -> Int64 -> ExceptT StoreError IO GroupMember
|
||||
getGroupMemberByIndex db cxt user GroupInfo {groupId} indexInGroup =
|
||||
ExceptT . firstRow (toContactMember cxt user) (SEGroupMemberNotFoundByIndex indexInGroup) $
|
||||
getGroupMemberByIndex db cxt user GroupInfo {groupId} indexInGroup = do
|
||||
currentTs <- liftIO getCurrentTime
|
||||
ExceptT . firstRow (toContactMember currentTs cxt user) (SEGroupMemberNotFoundByIndex indexInGroup) $
|
||||
DB.query
|
||||
db
|
||||
(groupMemberQuery <> " WHERE m.group_id = ? AND m.index_in_group = ?")
|
||||
(groupId, indexInGroup)
|
||||
|
||||
getSupportScopeMemberByIndex :: DB.Connection -> StoreCxt -> User -> GroupInfo -> GroupMemberId -> Int64 -> ExceptT StoreError IO GroupMember
|
||||
getSupportScopeMemberByIndex db cxt user GroupInfo {groupId} scopeGMId indexInGroup =
|
||||
ExceptT . firstRow (toContactMember cxt user) (SEGroupMemberNotFoundByIndex indexInGroup) $
|
||||
getSupportScopeMemberByIndex db cxt user GroupInfo {groupId} scopeGMId indexInGroup = do
|
||||
currentTs <- liftIO getCurrentTime
|
||||
ExceptT . firstRow (toContactMember currentTs cxt user) (SEGroupMemberNotFoundByIndex indexInGroup) $
|
||||
DB.query
|
||||
db
|
||||
(groupMemberQuery <> " WHERE m.group_id = ? AND m.index_in_group = ? AND (m.member_role IN (?,?,?) OR m.group_member_id = ?)")
|
||||
(groupId, indexInGroup, GRModerator, GRAdmin, GROwner, scopeGMId)
|
||||
|
||||
getGroupMemberByMemberId :: DB.Connection -> StoreCxt -> User -> GroupInfo -> MemberId -> ExceptT StoreError IO GroupMember
|
||||
getGroupMemberByMemberId db cxt user GroupInfo {groupId} memberId =
|
||||
ExceptT . firstRow (toContactMember cxt user) (SEGroupMemberNotFoundByMemberId memberId) $
|
||||
getGroupMemberByMemberId db cxt user GroupInfo {groupId} memberId = do
|
||||
currentTs <- liftIO getCurrentTime
|
||||
ExceptT . firstRow (toContactMember currentTs cxt user) (SEGroupMemberNotFoundByMemberId memberId) $
|
||||
DB.query
|
||||
db
|
||||
(groupMemberQuery <> " WHERE m.group_id = ? AND m.member_id = ?")
|
||||
@@ -1146,8 +1154,9 @@ getGroupMemberIdViaMemberId db User {userId} GroupInfo {groupId} memberId =
|
||||
(userId, groupId, memberId)
|
||||
|
||||
getGroupMembers :: DB.Connection -> StoreCxt -> User -> GroupInfo -> IO [GroupMember]
|
||||
getGroupMembers db cxt user@User {userId, userContactId} GroupInfo {groupId} =
|
||||
map (toContactMember cxt user)
|
||||
getGroupMembers db cxt user@User {userId, userContactId} GroupInfo {groupId} = do
|
||||
currentTs <- getCurrentTime
|
||||
map (toContactMember currentTs cxt user)
|
||||
<$> DB.query
|
||||
db
|
||||
(groupMemberQuery <> " WHERE m.user_id = ? AND m.group_id = ? AND (m.contact_id IS NULL OR m.contact_id != ?)")
|
||||
@@ -1156,8 +1165,9 @@ getGroupMembers db cxt user@User {userId, userContactId} GroupInfo {groupId} =
|
||||
getGroupMembersByIndexes :: DB.Connection -> StoreCxt -> User -> GroupInfo -> [Int64] -> IO [GroupMember]
|
||||
getGroupMembersByIndexes db cxt user gInfo indexesInGroup = do
|
||||
#if defined(dbPostgres)
|
||||
currentTs <- getCurrentTime
|
||||
let GroupInfo {groupId} = gInfo
|
||||
map (toContactMember cxt user) <$>
|
||||
map (toContactMember currentTs cxt user) <$>
|
||||
DB.query
|
||||
db
|
||||
(groupMemberQuery <> " WHERE m.group_id = ? AND m.index_in_group IN ?")
|
||||
@@ -1169,8 +1179,9 @@ getGroupMembersByIndexes db cxt user gInfo indexesInGroup = do
|
||||
getSupportScopeMembersByIndexes :: DB.Connection -> StoreCxt -> User -> GroupInfo -> GroupMemberId -> [Int64] -> IO [GroupMember]
|
||||
getSupportScopeMembersByIndexes db cxt user gInfo scopeGMId indexesInGroup = do
|
||||
#if defined(dbPostgres)
|
||||
currentTs <- getCurrentTime
|
||||
let GroupInfo {groupId} = gInfo
|
||||
map (toContactMember cxt user) <$>
|
||||
map (toContactMember currentTs cxt user) <$>
|
||||
DB.query
|
||||
db
|
||||
(groupMemberQuery <> " WHERE m.group_id = ? AND m.index_in_group IN ? AND (m.member_role IN (?,?,?) OR m.group_member_id = ?)")
|
||||
@@ -1181,7 +1192,8 @@ getSupportScopeMembersByIndexes db cxt user gInfo scopeGMId indexesInGroup = do
|
||||
|
||||
getGroupModerators :: DB.Connection -> StoreCxt -> User -> GroupInfo -> IO [GroupMember]
|
||||
getGroupModerators db cxt user@User {userId, userContactId} GroupInfo {groupId} = do
|
||||
map (toContactMember cxt user)
|
||||
currentTs <- getCurrentTime
|
||||
map (toContactMember currentTs cxt user)
|
||||
<$> DB.query
|
||||
db
|
||||
(groupMemberQuery <> " WHERE m.user_id = ? AND m.group_id = ? AND (m.contact_id IS NULL OR m.contact_id != ?) AND m.member_role IN (?,?,?)")
|
||||
@@ -1189,7 +1201,8 @@ getGroupModerators db cxt user@User {userId, userContactId} GroupInfo {groupId}
|
||||
|
||||
getGroupRelayMembers :: DB.Connection -> StoreCxt -> User -> GroupInfo -> IO [GroupMember]
|
||||
getGroupRelayMembers db cxt user@User {userId, userContactId} GroupInfo {groupId} = do
|
||||
map (toContactMember cxt user)
|
||||
currentTs <- getCurrentTime
|
||||
map (toContactMember currentTs cxt user)
|
||||
<$> DB.query
|
||||
db
|
||||
(groupMemberQuery <> " WHERE m.user_id = ? AND m.group_id = ? AND m.contact_id IS DISTINCT FROM ? AND m.member_role = ?")
|
||||
@@ -1197,7 +1210,8 @@ getGroupRelayMembers db cxt user@User {userId, userContactId} GroupInfo {groupId
|
||||
|
||||
getGroupMembersForExpiration :: DB.Connection -> StoreCxt -> User -> GroupInfo -> IO [GroupMember]
|
||||
getGroupMembersForExpiration db cxt user@User {userId, userContactId} GroupInfo {groupId} = do
|
||||
map (toContactMember cxt user)
|
||||
currentTs <- getCurrentTime
|
||||
map (toContactMember currentTs cxt user)
|
||||
<$> DB.query
|
||||
db
|
||||
( groupMemberQuery
|
||||
@@ -1361,7 +1375,7 @@ createRelayForOwner :: DB.Connection -> StoreCxt -> TVar ChaChaDRG -> User -> Gr
|
||||
createRelayForOwner db cxt gVar user@User {userId, userContactId} GroupInfo {groupId, membership} UserChatRelay {relayProfile = RelayProfile {displayName}} = do
|
||||
currentTs <- liftIO getCurrentTime
|
||||
let relayProfile = profileFromName displayName
|
||||
(localDisplayName, memProfileId) <- createNewMemberProfile_ db user relayProfile currentTs
|
||||
(localDisplayName, memProfileId, _) <- createNewMemberProfile_ db cxt user relayProfile currentTs
|
||||
groupMemberId <- createWithRandomId' db gVar $ \memId -> runExceptT $ do
|
||||
indexInGroup <- getUpdateNextIndexInGroup_ db groupId
|
||||
liftIO $
|
||||
@@ -1380,11 +1394,12 @@ createRelayForOwner db cxt gVar user@User {userId, userContactId} GroupInfo {gro
|
||||
getGroupMemberById db cxt user groupMemberId
|
||||
|
||||
getCreateRelayForMember :: DB.Connection -> StoreCxt -> TVar ChaChaDRG -> User -> GroupInfo -> ShortLinkContact -> ExceptT StoreError IO GroupMember
|
||||
getCreateRelayForMember db cxt gVar user@User {userId, userContactId} GroupInfo {groupId, localDisplayName = groupLDN} relayLink =
|
||||
liftIO getGroupMemberByRelayLink >>= maybe createRelayMember pure
|
||||
getCreateRelayForMember db cxt gVar user@User {userId, userContactId} GroupInfo {groupId, localDisplayName = groupLDN} relayLink = do
|
||||
currentTs <- liftIO getCurrentTime
|
||||
liftIO (getGroupMemberByRelayLink currentTs) >>= maybe createRelayMember pure
|
||||
where
|
||||
getGroupMemberByRelayLink =
|
||||
maybeFirstRow (toContactMember cxt user) $
|
||||
getGroupMemberByRelayLink currentTs =
|
||||
maybeFirstRow (toContactMember currentTs cxt user) $
|
||||
DB.query
|
||||
db
|
||||
#if defined(dbPostgres)
|
||||
@@ -1399,7 +1414,7 @@ getCreateRelayForMember db cxt gVar user@User {userId, userContactId} GroupInfo
|
||||
randRelayId <- liftIO $ encodedRandomBytes gVar 12
|
||||
let memberId = MemberId $ encodeUtf8 groupLDN <> "_unknown_relay_" <> randRelayId
|
||||
relayProfile = profileFromName $ nameFromBS randRelayId
|
||||
(localDisplayName, profileId) <- createNewMemberProfile_ db user relayProfile currentTs
|
||||
(localDisplayName, profileId, _) <- createNewMemberProfile_ db cxt user relayProfile currentTs
|
||||
indexInGroup <- getUpdateNextIndexInGroup_ db groupId
|
||||
groupMemberId <- liftIO $ do
|
||||
DB.execute
|
||||
@@ -1472,7 +1487,7 @@ setRelayLinkAccepted db cxt user m (MemberKey relayKey) profile = do
|
||||
WHERE group_member_id = ?
|
||||
|]
|
||||
(relayKey, currentTs, gmId)
|
||||
void $ updateMemberProfile db user m profile
|
||||
void $ updateMemberProfile db cxt user m profile
|
||||
(,) <$> getGroupMemberById db cxt user gmId <*> getGroupRelayByGMId db gmId
|
||||
|
||||
setRelayLinkConfId :: DB.Connection -> GroupMember -> ConfirmationId -> ShortLinkContact -> IO ()
|
||||
@@ -1519,8 +1534,8 @@ getRelayConfId db m =
|
||||
|]
|
||||
(Only (groupMemberId' m))
|
||||
|
||||
updateRelayMemberData :: DB.Connection -> User -> GroupMember -> MemberId -> MemberKey -> Profile -> ExceptT StoreError IO ()
|
||||
updateRelayMemberData db user m memberId (MemberKey relayKey) profile = do
|
||||
updateRelayMemberData :: DB.Connection -> StoreCxt -> User -> GroupMember -> MemberId -> MemberKey -> Profile -> ExceptT StoreError IO ()
|
||||
updateRelayMemberData db cxt user m memberId (MemberKey relayKey) profile = do
|
||||
currentTs <- liftIO getCurrentTime
|
||||
liftIO $
|
||||
DB.execute
|
||||
@@ -1531,7 +1546,7 @@ updateRelayMemberData db user m memberId (MemberKey relayKey) profile = do
|
||||
WHERE group_member_id = ?
|
||||
|]
|
||||
(memberId, relayKey, currentTs, groupMemberId' m)
|
||||
void $ updateMemberProfile db user m profile
|
||||
void $ updateMemberProfile db cxt user m profile
|
||||
|
||||
setGroupInProgressDone :: DB.Connection -> GroupInfo -> IO ()
|
||||
setGroupInProgressDone db GroupInfo {groupId} = do
|
||||
@@ -1584,7 +1599,7 @@ createRelayRequestGroup db cxt user@User {userId} GroupRelayInvitation {fromMemb
|
||||
insertOwner_ currentTs groupId = do
|
||||
let MemberIdRole {memberId, memberRole} = fromMember
|
||||
VersionRange minV maxV = reqChatVRange
|
||||
(localDisplayName, profileId) <- createNewMemberProfile_ db user fromMemberProfile currentTs
|
||||
(localDisplayName, profileId, _) <- createNewMemberProfile_ db cxt user fromMemberProfile currentTs
|
||||
indexInGroup <- getUpdateNextIndexInGroup_ db groupId
|
||||
liftIO $ do
|
||||
DB.execute
|
||||
@@ -1651,7 +1666,8 @@ isRelayGroupRejected db User {userId} groupLink =
|
||||
|
||||
getRelayServedGroups :: DB.Connection -> StoreCxt -> User -> IO [GroupInfo]
|
||||
getRelayServedGroups db cxt User {userId, userContactId} = do
|
||||
map (toGroupInfo cxt userContactId [])
|
||||
currentTs <- getCurrentTime
|
||||
map (toGroupInfo currentTs cxt userContactId [])
|
||||
<$> DB.query
|
||||
db
|
||||
( groupInfoQuery
|
||||
@@ -1661,8 +1677,9 @@ getRelayServedGroups db cxt User {userId, userContactId} = do
|
||||
|
||||
getRelayInactiveGroups :: DB.Connection -> StoreCxt -> User -> NominalDiffTime -> IO [GroupInfo]
|
||||
getRelayInactiveGroups db cxt User {userId, userContactId} ttl = do
|
||||
cutoffTs <- addUTCTime (- ttl) <$> getCurrentTime
|
||||
map (toGroupInfo cxt userContactId [])
|
||||
currentTs <- getCurrentTime
|
||||
let cutoffTs = addUTCTime (- ttl) currentTs
|
||||
map (toGroupInfo currentTs cxt userContactId [])
|
||||
<$> DB.query
|
||||
db
|
||||
( groupInfoQuery
|
||||
@@ -1697,14 +1714,15 @@ createNewContactMemberAsync db gVar user@User {userId, userContactId} GroupInfo
|
||||
:. (minV, maxV)
|
||||
)
|
||||
|
||||
createJoiningMember :: DB.Connection -> TVar ChaChaDRG -> User -> GroupInfo -> VersionRangeChat -> Profile -> Maybe XContactId -> Maybe MemberId -> Maybe SharedMsgId -> GroupMemberRole -> GroupMemberStatus -> Maybe MemberKey -> ExceptT StoreError IO (GroupMemberId, MemberId)
|
||||
createJoiningMember :: DB.Connection -> StoreCxt -> TVar ChaChaDRG -> User -> GroupInfo -> VersionRangeChat -> Profile -> Maybe XContactId -> Maybe MemberId -> Maybe SharedMsgId -> GroupMemberRole -> GroupMemberStatus -> Maybe MemberKey -> ExceptT StoreError IO (GroupMemberId, MemberId)
|
||||
createJoiningMember
|
||||
db
|
||||
cxt
|
||||
gVar
|
||||
User {userId, userContactId}
|
||||
GroupInfo {groupId, membership}
|
||||
cReqChatVRange
|
||||
Profile {displayName, fullName, shortDescr, image, contactLink, preferences}
|
||||
Profile {displayName, fullName, shortDescr, image, contactLink, badge, preferences}
|
||||
cReqXContactId_
|
||||
cReqMemberId_
|
||||
welcomeMsgId_
|
||||
@@ -1712,12 +1730,13 @@ createJoiningMember
|
||||
memberStatus
|
||||
memberKey_ = do
|
||||
currentTs <- liftIO getCurrentTime
|
||||
badgeVerified <- liftIO $ verifyBadge_ (badgeKeys cxt) badge
|
||||
ExceptT . withLocalDisplayName db userId displayName $ \ldn -> runExceptT $ do
|
||||
liftIO $
|
||||
DB.execute
|
||||
db
|
||||
"INSERT INTO contact_profiles (display_name, full_name, short_descr, image, contact_link, user_id, preferences, created_at, updated_at) VALUES (?,?,?,?,?,?,?,?,?)"
|
||||
(displayName, fullName, shortDescr, image, contactLink, userId, preferences, currentTs, currentTs)
|
||||
"INSERT INTO contact_profiles (display_name, full_name, short_descr, image, contact_link, user_id, preferences, 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) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
|
||||
((displayName, fullName, shortDescr, image, contactLink, userId, preferences, currentTs, currentTs) :. badgeToRow badge badgeVerified)
|
||||
profileId <- liftIO $ insertedRowId db
|
||||
case cReqMemberId_ of
|
||||
Just memberId -> do
|
||||
@@ -2053,10 +2072,10 @@ increaseGroupMembersRequireAttention db User {userId} g@GroupInfo {groupId, memb
|
||||
pure g {membersRequireAttention = membersRequireAttention + 1}
|
||||
|
||||
-- | add new member with profile
|
||||
createNewGroupMember :: DB.Connection -> User -> GroupInfo -> GroupMember -> MemberInfo -> GroupMemberCategory -> GroupMemberStatus -> ExceptT StoreError IO GroupMember
|
||||
createNewGroupMember db user gInfo invitingMember memInfo@MemberInfo {profile} memCategory memStatus = do
|
||||
createNewGroupMember :: DB.Connection -> StoreCxt -> User -> GroupInfo -> GroupMember -> MemberInfo -> GroupMemberCategory -> GroupMemberStatus -> ExceptT StoreError IO GroupMember
|
||||
createNewGroupMember db cxt user gInfo invitingMember memInfo@MemberInfo {profile} memCategory memStatus = do
|
||||
currentTs <- liftIO getCurrentTime
|
||||
(localDisplayName, memProfileId) <- createNewMemberProfile_ db user profile currentTs
|
||||
(localDisplayName, memProfileId, badgeVerified) <- createNewMemberProfile_ db cxt user profile currentTs
|
||||
let newMember =
|
||||
NewGroupMember
|
||||
{ memInfo,
|
||||
@@ -2069,19 +2088,20 @@ createNewGroupMember db user gInfo invitingMember memInfo@MemberInfo {profile} m
|
||||
memContactId = Nothing,
|
||||
memProfileId
|
||||
}
|
||||
createNewMember_ db user gInfo newMember currentTs
|
||||
createNewMember_ db user gInfo newMember badgeVerified currentTs
|
||||
|
||||
createNewMemberProfile_ :: DB.Connection -> User -> Profile -> UTCTime -> ExceptT StoreError IO (Text, ProfileId)
|
||||
createNewMemberProfile_ db User {userId} Profile {displayName, fullName, shortDescr, image, contactLink, preferences} createdAt =
|
||||
createNewMemberProfile_ :: DB.Connection -> StoreCxt -> User -> Profile -> UTCTime -> ExceptT StoreError IO (Text, ProfileId, Maybe Bool)
|
||||
createNewMemberProfile_ db cxt User {userId} Profile {displayName, fullName, shortDescr, image, contactLink, badge, preferences} createdAt =
|
||||
ExceptT . withLocalDisplayName db userId displayName $ \ldn -> do
|
||||
badgeVerified <- verifyBadge_ (badgeKeys cxt) badge
|
||||
DB.execute
|
||||
db
|
||||
"INSERT INTO contact_profiles (display_name, full_name, short_descr, image, contact_link, user_id, preferences, created_at, updated_at) VALUES (?,?,?,?,?,?,?,?,?)"
|
||||
(displayName, fullName, shortDescr, image, contactLink, userId, preferences, createdAt, createdAt)
|
||||
"INSERT INTO contact_profiles (display_name, full_name, short_descr, image, contact_link, user_id, preferences, 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) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
|
||||
((displayName, fullName, shortDescr, image, contactLink, userId, preferences, createdAt, createdAt) :. badgeToRow badge badgeVerified)
|
||||
profileId <- insertedRowId db
|
||||
pure $ Right (ldn, profileId)
|
||||
pure $ Right (ldn, profileId, badgeVerified)
|
||||
|
||||
createNewMember_ :: DB.Connection -> User -> GroupInfo -> NewGroupMember -> UTCTime -> ExceptT StoreError IO GroupMember
|
||||
createNewMember_ :: DB.Connection -> User -> GroupInfo -> NewGroupMember -> Maybe Bool -> UTCTime -> ExceptT StoreError IO GroupMember
|
||||
createNewMember_
|
||||
db
|
||||
User {userId, userContactId}
|
||||
@@ -2097,6 +2117,7 @@ createNewMember_
|
||||
memContactId = memberContactId,
|
||||
memProfileId = memberContactProfileId
|
||||
}
|
||||
badgeVerified
|
||||
createdAt = do
|
||||
let invitedById = fromInvitedBy userContactId invitedBy
|
||||
activeConn = Nothing
|
||||
@@ -2134,7 +2155,7 @@ createNewMember_
|
||||
invitedBy,
|
||||
invitedByGroupMemberId = memInvitedByGroupMemberId,
|
||||
localDisplayName,
|
||||
memberProfile = toLocalProfile memberContactProfileId memberProfile "",
|
||||
memberProfile = toLocalProfile memberContactProfileId memberProfile "" createdAt badgeVerified,
|
||||
memberContactId,
|
||||
memberContactProfileId,
|
||||
activeConn,
|
||||
@@ -2248,18 +2269,19 @@ getMemberRelationsVector db GroupMember {groupMemberId} =
|
||||
"SELECT member_relations_vector FROM group_members WHERE group_member_id = ?"
|
||||
(Only groupMemberId)
|
||||
|
||||
createIntroReMember :: DB.Connection -> User -> GroupInfo -> MemberInfo -> Maybe MemberRestrictions -> ExceptT StoreError IO GroupMember
|
||||
createIntroReMember :: DB.Connection -> StoreCxt -> User -> GroupInfo -> MemberInfo -> Maybe MemberRestrictions -> ExceptT StoreError IO GroupMember
|
||||
createIntroReMember
|
||||
db
|
||||
cxt
|
||||
user
|
||||
gInfo
|
||||
memInfo@(MemberInfo _ _ _ memberProfile _)
|
||||
memRestrictions_ = do
|
||||
currentTs <- liftIO getCurrentTime
|
||||
(localDisplayName, memProfileId) <- createNewMemberProfile_ db user memberProfile currentTs
|
||||
(localDisplayName, memProfileId, badgeVerified) <- createNewMemberProfile_ db cxt user memberProfile currentTs
|
||||
let memRestriction = restriction <$> memRestrictions_
|
||||
newMember = NewGroupMember {memInfo, memCategory = GCPreMember, memStatus = GSMemIntroduced, memRestriction, memInvitedBy = IBUnknown, memInvitedByGroupMemberId = Nothing, localDisplayName, memContactId = Nothing, memProfileId}
|
||||
createNewMember_ db user gInfo newMember currentTs
|
||||
createNewMember_ db user gInfo newMember badgeVerified currentTs
|
||||
|
||||
createIntroReMemberConn :: DB.Connection -> User -> GroupMember -> GroupMember -> VersionChat -> MemberInfo -> (CommandId, ConnId) -> SubscriptionMode -> ExceptT StoreError IO GroupMember
|
||||
createIntroReMemberConn
|
||||
@@ -2983,41 +3005,47 @@ setMemberContactStartedConnection db Contact {contactId} = do
|
||||
"UPDATE contacts SET grp_direct_inv_started_connection = ?, updated_at = ? WHERE contact_id = ?"
|
||||
(BI True, currentTs, contactId)
|
||||
|
||||
updateMemberProfile :: DB.Connection -> User -> GroupMember -> Profile -> ExceptT StoreError IO GroupMember
|
||||
updateMemberProfile db user@User {userId} m p'
|
||||
| displayName == newName = do
|
||||
liftIO $ updateMemberContactProfileReset_ db userId profileId p'
|
||||
pure m {memberProfile = profile}
|
||||
| otherwise =
|
||||
ExceptT . withLocalDisplayName db userId newName $ \ldn -> do
|
||||
currentTs <- getCurrentTime
|
||||
updateMemberContactProfileReset_' db userId profileId p' currentTs
|
||||
DB.execute
|
||||
db
|
||||
"UPDATE group_members SET local_display_name = ?, updated_at = ? WHERE user_id = ? AND group_member_id = ?"
|
||||
(ldn, currentTs, userId, groupMemberId)
|
||||
safeDeleteLDN db user localDisplayName
|
||||
pure $ Right m {localDisplayName = ldn, memberProfile = profile}
|
||||
updateMemberProfile :: DB.Connection -> StoreCxt -> User -> GroupMember -> Profile -> ExceptT StoreError IO GroupMember
|
||||
updateMemberProfile db cxt user@User {userId} m p' = do
|
||||
currentTs <- liftIO getCurrentTime
|
||||
badgeVerified <- liftIO $ profileBadgeVerified (badgeKeys cxt) (memberProfile m) p'
|
||||
let memberProfile = toLocalProfile profileId p' localAlias currentTs badgeVerified
|
||||
updateMemberProfile' currentTs badgeVerified memberProfile
|
||||
where
|
||||
GroupMember {groupMemberId, localDisplayName, memberProfile = LocalProfile {profileId, displayName, localAlias}} = m
|
||||
Profile {displayName = newName} = p'
|
||||
profile = toLocalProfile profileId p' localAlias
|
||||
updateMemberProfile' currentTs badgeVerified memberProfile
|
||||
| displayName == newName = do
|
||||
liftIO $ updateMemberContactProfileReset_' db userId profileId p' badgeVerified currentTs
|
||||
pure m {memberProfile}
|
||||
| otherwise =
|
||||
ExceptT . withLocalDisplayName db userId newName $ \ldn -> do
|
||||
updateMemberContactProfileReset_' db userId profileId p' badgeVerified currentTs
|
||||
DB.execute
|
||||
db
|
||||
"UPDATE group_members SET local_display_name = ?, updated_at = ? WHERE user_id = ? AND group_member_id = ?"
|
||||
(ldn, currentTs, userId, groupMemberId)
|
||||
safeDeleteLDN db user localDisplayName
|
||||
pure $ Right m {localDisplayName = ldn, memberProfile}
|
||||
|
||||
updateContactMemberProfile :: DB.Connection -> User -> GroupMember -> Contact -> Profile -> ExceptT StoreError IO (GroupMember, Contact)
|
||||
updateContactMemberProfile db user@User {userId} m ct@Contact {contactId} p'
|
||||
| displayName == newName = do
|
||||
liftIO $ updateMemberContactProfile_ db userId profileId p'
|
||||
pure (m {memberProfile = profile}, ct {profile} :: Contact)
|
||||
| otherwise =
|
||||
ExceptT . withLocalDisplayName db userId newName $ \ldn -> do
|
||||
currentTs <- getCurrentTime
|
||||
updateMemberContactProfile_' db userId profileId p' currentTs
|
||||
updateContactLDN_ db user contactId localDisplayName ldn currentTs
|
||||
pure $ Right (m {localDisplayName = ldn, memberProfile = profile}, ct {localDisplayName = ldn, profile} :: Contact)
|
||||
updateContactMemberProfile :: DB.Connection -> StoreCxt -> User -> GroupMember -> Contact -> Profile -> ExceptT StoreError IO (GroupMember, Contact)
|
||||
updateContactMemberProfile db cxt user@User {userId} m ct@Contact {contactId} p' = do
|
||||
currentTs <- liftIO getCurrentTime
|
||||
badgeVerified <- liftIO $ profileBadgeVerified (badgeKeys cxt) (memberProfile m) p'
|
||||
let profile = toLocalProfile profileId p' localAlias currentTs badgeVerified
|
||||
updateContactMemberProfile' currentTs badgeVerified profile
|
||||
where
|
||||
GroupMember {localDisplayName, memberProfile = LocalProfile {profileId, displayName, localAlias}} = m
|
||||
Profile {displayName = newName} = p'
|
||||
profile = toLocalProfile profileId p' localAlias
|
||||
updateContactMemberProfile' currentTs badgeVerified profile
|
||||
| displayName == newName = do
|
||||
liftIO $ updateMemberContactProfile_' db userId profileId p' badgeVerified currentTs
|
||||
pure (m {memberProfile = profile}, ct {profile} :: Contact)
|
||||
| otherwise =
|
||||
ExceptT . withLocalDisplayName db userId newName $ \ldn -> do
|
||||
updateMemberContactProfile_' db userId profileId p' badgeVerified currentTs
|
||||
updateContactLDN_ db user contactId localDisplayName ldn currentTs
|
||||
pure $ Right (m {localDisplayName = ldn, memberProfile = profile}, ct {localDisplayName = ldn, profile} :: Contact)
|
||||
|
||||
getXGrpLinkMemReceived :: DB.Connection -> GroupMemberId -> ExceptT StoreError IO Bool
|
||||
getXGrpLinkMemReceived db mId =
|
||||
@@ -3036,7 +3064,7 @@ createNewUnknownGroupMember :: DB.Connection -> StoreCxt -> User -> GroupInfo ->
|
||||
createNewUnknownGroupMember db cxt user@User {userId, userContactId} GroupInfo {groupId} memberId memberName unknownMemberRole = do
|
||||
currentTs <- liftIO getCurrentTime
|
||||
let memberProfile = profileFromName memberName
|
||||
(localDisplayName, profileId) <- createNewMemberProfile_ db user memberProfile currentTs
|
||||
(localDisplayName, profileId, _) <- createNewMemberProfile_ db cxt user memberProfile currentTs
|
||||
indexInGroup <- getUpdateNextIndexInGroup_ db groupId
|
||||
liftIO $
|
||||
DB.execute
|
||||
@@ -3061,7 +3089,7 @@ createLinkOwnerMember :: DB.Connection -> StoreCxt -> User -> GroupInfo -> Maybe
|
||||
createLinkOwnerMember db cxt user@User {userId, userContactId} GroupInfo {groupId} contactId_ memberId ownerKey = do
|
||||
currentTs <- liftIO getCurrentTime
|
||||
let memberProfile = profileFromName $ nameFromMemberId memberId
|
||||
(localDisplayName, profileId) <- createNewMemberProfile_ db user memberProfile currentTs
|
||||
(localDisplayName, profileId, _) <- createNewMemberProfile_ db cxt user memberProfile currentTs
|
||||
indexInGroup <- getUpdateNextIndexInGroup_ db groupId
|
||||
liftIO $
|
||||
DB.execute
|
||||
@@ -3087,7 +3115,7 @@ createLinkOwnerMember db cxt user@User {userId, userContactId} GroupInfo {groupI
|
||||
-- Updating from an in-band message would allow a compromised relay to substitute keys.
|
||||
updatePreparedChannelMember :: DB.Connection -> StoreCxt -> User -> GroupMember -> MemberInfo -> ExceptT StoreError IO GroupMember
|
||||
updatePreparedChannelMember db cxt user@User {userId} member@GroupMember {groupMemberId, memberChatVRange} MemberInfo {memberRole, v, profile} = do
|
||||
_ <- updateMemberProfile db user member profile
|
||||
_ <- updateMemberProfile db cxt user member profile
|
||||
currentTs <- liftIO getCurrentTime
|
||||
liftIO $
|
||||
DB.execute
|
||||
@@ -3108,7 +3136,7 @@ updatePreparedChannelMember db cxt user@User {userId} member@GroupMember {groupM
|
||||
|
||||
updateUnknownMemberAnnounced :: DB.Connection -> StoreCxt -> User -> GroupMember -> GroupMember -> MemberInfo -> GroupMemberStatus -> ExceptT StoreError IO GroupMember
|
||||
updateUnknownMemberAnnounced db cxt user@User {userId} invitingMember unknownMember@GroupMember {groupMemberId, memberChatVRange} MemberInfo {memberRole, v, profile, memberKey} status = do
|
||||
_ <- updateMemberProfile db user unknownMember profile
|
||||
_ <- updateMemberProfile db cxt user unknownMember profile
|
||||
currentTs <- liftIO getCurrentTime
|
||||
liftIO $
|
||||
DB.execute
|
||||
|
||||
Reference in new issue
Block a user