member connection wip

This commit is contained in:
spaced4ndy committed 2025-11-06 22:25:54 +04:00
1 parent 679544afee
commit 768928a83e
5 files changed
+73 -18

No files matched your search

+21 -4
View File
@@ -1984,8 +1984,25 @@ processChatCommand vr nm = \case
Just sl -> pure sl
Nothing -> throwChatError $ CEException "failed to retrieve relays: no short link"
(_cReq, _cData@(ContactLinkData _ UserContactData {relays})) <- getShortLinkConnReq nm user sLnk
liftIO $ print $ "retrieved relays: " <> show relays
-- TODO [relays] member: connect to all relays
gVar <- asks random
-- TODO [relays] member: TBC concurrently/catch on each
forM_ relays $ \relayLink -> do
-- TODO [relays] member: check relay record already exists -> then decide based on connection
relayMember <- withFastStore $ \db -> createRelayForMember db vr gVar user gInfo
-- TODO [relays] member: pass same incognito profile to all relays
-- TODO - TBC welcomeSharedMsgId
(cReq, _cData) <- getShortLinkConnReq nm user relayLink -- this is network operation - consider recovery
let relayLinkToConnect = CCLink cReq (Just relayLink)
r <- connectViaContact user (Just $ PCEGroup gInfo relayMember) incognito relayLinkToConnect Nothing Nothing `catchAllErrors` \e -> do
-- TODO [relays] member: lock ability to change profile (see below)
throwError e
case r of
CVRSentInvitation _conn _customUserProfile -> do
_gInfo' <- withFastStore $ \db -> do
liftIO $ setPreparedGroupStartedConnection db groupId
getGroupInfo db vr user groupId
pure relayMember -- what should be in returned event?
CVRConnectedContact _ct -> pure relayMember -- error?
ok_
| otherwise -> do
msg_ <- forM msgContent_ $ \mc -> case requestSharedMsgId of
@@ -3605,9 +3622,9 @@ processChatCommand vr nm = \case
-- TODO [relays] owner: replace with async join (joinConnectionAsync currently prohibited for contact links)
-- TODO - or make "add relays" api retriable, via prepared connection
connId <- withAgent $ \a -> prepareConnectionToJoin a (aUserId user) True cReq PQSupportOff
(relayMember, conn, groupRelay) <- withStore $ \db -> do
(relayMember, conn, groupRelay) <- withFastStore $ \db -> do
groupRelay <- createGroupRelayRecord db gInfo relay
relayMember <- createRelayMemberRecord db vr gVar user gInfo relay groupRelay
relayMember <- createRelayForOwner db vr gVar user gInfo relay groupRelay
conn <- createRelayConnection db vr user (groupMemberId' relayMember) connId ConnPrepared chatV subMode
pure (relayMember, conn, groupRelay)
let GroupMember {memberRole = userRole, memberId = userMemberId} = membership
+11 -10
View File
@@ -828,7 +828,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
-- TODO [relays] owner: relay added chat item?
toView $ CEvtRelayJoined user gInfo m'' gLink relays
Nothing -> messageError "x.grp.relay.acpt: group link not updated"
Nothing -> do -- TODO [relays] relay: don't introduce new member to other members
Nothing -> do
(gInfo', mStatus) <-
if not (memberPending m)
then do
@@ -847,15 +847,16 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
let Connection {viaUserContactLink} = conn
when (isJust viaUserContactLink && isNothing (memberContactId m')) $ sendXGrpLinkMem gInfo''
when (connChatVersion < batchSend2Version) $ getAutoReplyMsg >>= mapM_ (\mc -> sendGroupAutoReply mc Nothing)
case mStatus of
GSMemPendingApproval -> pure ()
GSMemPendingReview -> introduceToModerators vr user gInfo'' m'
_ -> do
introduceToAll vr user gInfo'' m'
let memberIsCustomer = case businessChat gInfo'' of
Just BusinessChatInfo {chatType = BCCustomer, customerId} -> memberId' m' == customerId
_ -> False
when (groupFeatureAllowed SGFHistory gInfo'' && not memberIsCustomer) $ sendHistory user gInfo'' m'
unless (isRelay' membership) $
case mStatus of
GSMemPendingApproval -> pure ()
GSMemPendingReview -> introduceToModerators vr user gInfo'' m'
_ -> do
introduceToAll vr user gInfo'' m'
let memberIsCustomer = case businessChat gInfo'' of
Just BusinessChatInfo {chatType = BCCustomer, customerId} -> memberId' m' == customerId
_ -> False
when (groupFeatureAllowed SGFHistory gInfo'' && not memberIsCustomer) $ sendHistory user gInfo'' m'
where
sendXGrpLinkMem gInfo'' = do
let incognitoProfile = ExistingIncognito <$> incognitoMembershipProfile gInfo''
+33 -3
View File
@@ -77,7 +77,8 @@ module Simplex.Chat.Store.Groups
createGroupRelayRecord,
getGroupRelayById,
getGroupRelays,
createRelayMemberRecord,
createRelayForOwner,
createRelayForMember,
createRelayConnection,
updateRelayStatus,
updateRelayStatusFromTo,
@@ -1179,8 +1180,9 @@ toGroupRelay (groupRelayId, userChatRelayId, relayStatus, relayLink) =
-- TODO - GCInviteeMember -> GCRelayMember?
-- TODO - GRMember -> GRRelay?
-- TODO - create 1 profile per relay, link to chat_relays?
createRelayMemberRecord :: DB.Connection -> VersionRangeChat -> TVar ChaChaDRG -> User -> GroupInfo -> UserChatRelay -> GroupRelay -> ExceptT StoreError IO GroupMember
createRelayMemberRecord db vr gVar user@User {userId, userContactId} GroupInfo {groupId, membership} UserChatRelay {name} GroupRelay {groupRelayId} = do
-- TODO - retrieve profile from relay address
createRelayForOwner :: DB.Connection -> VersionRangeChat -> TVar ChaChaDRG -> User -> GroupInfo -> UserChatRelay -> GroupRelay -> ExceptT StoreError IO GroupMember
createRelayForOwner db vr gVar user@User {userId, userContactId} GroupInfo {groupId, membership} UserChatRelay {name} GroupRelay {groupRelayId} = do
currentTs <- liftIO getCurrentTime
let relayProfile = profileFromName name
(localDisplayName, memProfileId) <- createNewMemberProfile_ db user relayProfile currentTs
@@ -1202,6 +1204,34 @@ createRelayMemberRecord db vr gVar user@User {userId, userContactId} GroupInfo {
insertedRowId db
getGroupMemberById db vr user groupMemberId
-- TODO [relays] TBC role, category, relay profile
-- TODO - TBC retrieve profile from somewhere before connection
-- TODO - or update upon connection, as in regular prepared groups
-- TODO (current logic mimics insertHost_ from createPreparedGroup)
createRelayForMember :: DB.Connection -> VersionRangeChat -> TVar ChaChaDRG -> User -> GroupInfo -> ExceptT StoreError IO GroupMember
createRelayForMember db vr gVar user@User {userId, userContactId} GroupInfo {groupId, localDisplayName = groupLDN} = do
currentTs <- liftIO getCurrentTime
randRelayId <- liftIO $ encodedRandomBytes gVar 12
let memberId = MemberId $ encodeUtf8 groupLDN <> "_relay_" <> randRelayId <> "_unknown_id"
relayProfile = profileFromName $ nameFromMemberId memberId
(localDisplayName, profileId) <- createNewMemberProfile_ db user relayProfile currentTs
groupMemberId <- liftIO $ do
DB.execute
db
[sql|
INSERT INTO group_members
( group_id, member_id, member_role, member_category, member_status, invited_by,
user_id, local_display_name, contact_profile_id, created_at, updated_at,
is_relay
)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?)
|]
( (groupId, memberId, GRMember, GCHostMember, GSMemAccepted, fromInvitedBy userContactId IBUnknown)
:. (userId, localDisplayName, profileId, currentTs, currentTs, BI True)
)
insertedRowId db
getGroupMember db vr user groupId groupMemberId
createRelayConnection :: DB.Connection -> VersionRangeChat -> User -> Int64 -> ConnId -> ConnStatus -> VersionChat -> SubscriptionMode -> ExceptT StoreError IO Connection
createRelayConnection db vr user@User {userId} groupMemberId agentConnId connStatus chatV subMode = do
currentTs <- liftIO getCurrentTime
@@ -5,6 +5,13 @@ module Simplex.Chat.Store.SQLite.Migrations.M20251018_chat_relays where
import Database.SQLite.Simple (Query)
import Database.SQLite.Simple.QQ (sql)
-- TODO [relays] owner: consider flipping group_members.group_relay_id fkey to group_relays.group_member_id
-- TODO - pros: less joins in all member queries,
-- TODO - can discern relay by is_relay,
-- TODO - little places need additional relay data
-- TODO - cons: in some places will need extra query:
-- TODO - SELECT ... FROM group_relays WHERE group_member_id = ?
-- - chat_relays - user's list of chat relays to choose from (similar to protocol_servers)
-- - users.is_user_chat_relay - indicates that the user can serve as a chat relay
-- (TBC usage, e.g. agree to invitations to be relay)
+1 -1
View File
@@ -2015,7 +2015,7 @@ viewConnectionPlan ChatConfig {logLevel, testView} _connLink = \case
CPGroupLink glp -> case glp of
GLPOk direct groupSLinkData ->
[grpLink $ if direct then "ok to connect directly" else "ok to connect via relays"]
<> [viewJSON groupSLinkData | testView]
<> [viewJSON groupSLinkData] -- | testView]
GLPOwnLink g -> [grpLink "own link for group " <> ttyGroup' g]
GLPConnectingConfirmReconnect -> [grpLink "connecting, allowed to reconnect"]
GLPConnectingProhibit Nothing -> [grpLink "connecting"]