mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-05-25 14:14:39 +00:00
Revert "core: relay key and member id as immutable relay link data (#6711)"
This reverts commit d665b1f5d8.
This commit is contained in:
@@ -1111,7 +1111,6 @@ enum ChatEvent: Decodable, ChatAPIResult {
|
||||
case connectedToGroupMember(user: UserRef, groupInfo: GroupInfo, member: GroupMember, memberContact: Contact?)
|
||||
case groupUpdated(user: UserRef, toGroup: GroupInfo)
|
||||
case groupLinkDataUpdated(user: UserRef, groupInfo: GroupInfo, groupLink: GroupLink, groupRelays: [GroupRelay], relaysChanged: Bool)
|
||||
case groupRelayUpdated(user: UserRef, groupInfo: GroupInfo, member: GroupMember, groupRelay: GroupRelay)
|
||||
case newMemberContactReceivedInv(user: UserRef, contact: Contact, groupInfo: GroupInfo, member: GroupMember)
|
||||
// receiving file events
|
||||
case rcvFileAccepted(user: UserRef, chatItem: AChatItem)
|
||||
@@ -1189,7 +1188,6 @@ enum ChatEvent: Decodable, ChatAPIResult {
|
||||
case .connectedToGroupMember: "connectedToGroupMember"
|
||||
case .groupUpdated: "groupUpdated"
|
||||
case .groupLinkDataUpdated: "groupLinkDataUpdated"
|
||||
case .groupRelayUpdated: "groupRelayUpdated"
|
||||
case .newMemberContactReceivedInv: "newMemberContactReceivedInv"
|
||||
case .rcvFileAccepted: "rcvFileAccepted"
|
||||
case .rcvFileAcceptedSndCancelled: "rcvFileAcceptedSndCancelled"
|
||||
@@ -1271,7 +1269,6 @@ enum ChatEvent: Decodable, ChatAPIResult {
|
||||
case let .connectedToGroupMember(u, groupInfo, member, memberContact): return withUser(u, "groupInfo: \(groupInfo)\nmember: \(member)\nmemberContact: \(String(describing: memberContact))")
|
||||
case let .groupUpdated(u, toGroup): return withUser(u, String(describing: toGroup))
|
||||
case let .groupLinkDataUpdated(u, groupInfo, groupLink, groupRelays, relaysChanged): return withUser(u, "groupInfo: \(groupInfo)\ngroupLink: \(groupLink)\ngroupRelays: \(groupRelays)\nrelaysChanged: \(relaysChanged)")
|
||||
case let .groupRelayUpdated(u, groupInfo, member, groupRelay): return withUser(u, "groupInfo: \(groupInfo)\nmember: \(member)\ngroupRelay: \(groupRelay)")
|
||||
case let .newMemberContactReceivedInv(u, contact, groupInfo, member): return withUser(u, "contact: \(contact)\ngroupInfo: \(groupInfo)\nmember: \(member)")
|
||||
case let .rcvFileAccepted(u, chatItem): return withUser(u, String(describing: chatItem))
|
||||
case .rcvFileAcceptedSndCancelled: return noDetails
|
||||
|
||||
@@ -343,13 +343,6 @@ class ChannelRelaysModel: ObservableObject {
|
||||
self.groupRelays = groupRelays
|
||||
}
|
||||
|
||||
func updateRelay(_ groupInfo: GroupInfo, _ relay: GroupRelay) {
|
||||
if groupId == groupInfo.groupId,
|
||||
let i = groupRelays.firstIndex(where: { $0.groupRelayId == relay.groupRelayId }) {
|
||||
groupRelays[i] = relay
|
||||
}
|
||||
}
|
||||
|
||||
func reset() {
|
||||
groupId = nil
|
||||
groupRelays = []
|
||||
|
||||
@@ -2594,13 +2594,6 @@ func processReceivedMsg(_ res: ChatEvent) async {
|
||||
}
|
||||
}
|
||||
}
|
||||
case let .groupRelayUpdated(user, groupInfo, member, groupRelay):
|
||||
if active(user) {
|
||||
await MainActor.run {
|
||||
_ = m.upsertGroupMember(groupInfo, member)
|
||||
ChannelRelaysModel.shared.updateRelay(groupInfo, groupRelay)
|
||||
}
|
||||
}
|
||||
case let .memberRole(user, groupInfo, byMember: _, member: member, fromRole: _, toRole: _):
|
||||
if active(user) {
|
||||
await MainActor.run {
|
||||
|
||||
@@ -105,6 +105,7 @@ struct GroupLinkView: View {
|
||||
Label("Share link", systemImage: "square.and.arrow.up")
|
||||
}
|
||||
|
||||
// TODO [relays] review: channel link deletion is only possible together with deleting the channel
|
||||
if !creatingGroup && !isChannel {
|
||||
Button(role: .destructive) { alert = .deleteLink } label: {
|
||||
Label("Delete link", systemImage: "trash")
|
||||
|
||||
@@ -172,6 +172,7 @@ struct GroupMemberInfoView: View {
|
||||
let label: LocalizedStringKey = groupInfo.useRelays ? "Channel" : groupInfo.businessChat == nil ? "Group" : "Chat"
|
||||
infoRow(label, groupInfo.displayName)
|
||||
|
||||
// TODO [relays] review: role changing is not supported for channels currently
|
||||
if !groupInfo.useRelays, let roles = member.canChangeRoleTo(groupInfo: groupInfo) {
|
||||
Picker("Change role", selection: $newRole) {
|
||||
ForEach(roles) { role in
|
||||
@@ -636,7 +637,7 @@ struct GroupMemberInfoView: View {
|
||||
}
|
||||
}
|
||||
// TODO [relays] removing relay should also remove its link from group link data;
|
||||
// TODO - removing last relay should be prohibited or show warning
|
||||
// removing last relay should be prohibited or show warning
|
||||
if canRemove && mem.memberRole != .relay {
|
||||
if mem.memberStatus == .memRemoved || mem.memberStatus == .memLeft {
|
||||
deleteMemberMessagesButton(mem)
|
||||
|
||||
@@ -50,6 +50,7 @@ func validRelayAddress(_ address: String) -> Bool {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO [relays] TBC matching relay to operator by domain (relay address can be hosted on operator server)
|
||||
func addChatRelay(
|
||||
_ relay: UserChatRelay,
|
||||
_ userServers: Binding<[UserOperatorServers]>,
|
||||
|
||||
@@ -182,8 +182,8 @@
|
||||
64C3B0212A0D359700E19930 /* CustomTimePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64C3B0202A0D359700E19930 /* CustomTimePicker.swift */; };
|
||||
64C8299D2D54AEEE006B9E89 /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64C829982D54AEED006B9E89 /* libgmp.a */; };
|
||||
64C8299E2D54AEEE006B9E89 /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64C829992D54AEEE006B9E89 /* libffi.a */; };
|
||||
64C8299F2D54AEEE006B9E89 /* libHSsimplex-chat-6.5.0.9-1LMKtNtYaECIyeIru99CUt-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64C8299A2D54AEEE006B9E89 /* libHSsimplex-chat-6.5.0.9-1LMKtNtYaECIyeIru99CUt-ghc9.6.3.a */; };
|
||||
64C829A02D54AEEE006B9E89 /* libHSsimplex-chat-6.5.0.9-1LMKtNtYaECIyeIru99CUt.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64C8299B2D54AEEE006B9E89 /* libHSsimplex-chat-6.5.0.9-1LMKtNtYaECIyeIru99CUt.a */; };
|
||||
64C8299F2D54AEEE006B9E89 /* libHSsimplex-chat-6.5.0.9-IckAKQLBKZZ3c4EBa1qhzo-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64C8299A2D54AEEE006B9E89 /* libHSsimplex-chat-6.5.0.9-IckAKQLBKZZ3c4EBa1qhzo-ghc9.6.3.a */; };
|
||||
64C829A02D54AEEE006B9E89 /* libHSsimplex-chat-6.5.0.9-IckAKQLBKZZ3c4EBa1qhzo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64C8299B2D54AEEE006B9E89 /* libHSsimplex-chat-6.5.0.9-IckAKQLBKZZ3c4EBa1qhzo.a */; };
|
||||
64C829A12D54AEEE006B9E89 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64C8299C2D54AEEE006B9E89 /* libgmpxx.a */; };
|
||||
64D0C2C029F9688300B38D5F /* UserAddressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64D0C2BF29F9688300B38D5F /* UserAddressView.swift */; };
|
||||
64D0C2C229FA57AB00B38D5F /* UserAddressLearnMore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64D0C2C129FA57AB00B38D5F /* UserAddressLearnMore.swift */; };
|
||||
@@ -553,8 +553,8 @@
|
||||
64C3B0202A0D359700E19930 /* CustomTimePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomTimePicker.swift; sourceTree = "<group>"; };
|
||||
64C829982D54AEED006B9E89 /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = "<group>"; };
|
||||
64C829992D54AEEE006B9E89 /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = "<group>"; };
|
||||
64C8299A2D54AEEE006B9E89 /* libHSsimplex-chat-6.5.0.9-1LMKtNtYaECIyeIru99CUt-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.5.0.9-1LMKtNtYaECIyeIru99CUt-ghc9.6.3.a"; sourceTree = "<group>"; };
|
||||
64C8299B2D54AEEE006B9E89 /* libHSsimplex-chat-6.5.0.9-1LMKtNtYaECIyeIru99CUt.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.5.0.9-1LMKtNtYaECIyeIru99CUt.a"; sourceTree = "<group>"; };
|
||||
64C8299A2D54AEEE006B9E89 /* libHSsimplex-chat-6.5.0.9-IckAKQLBKZZ3c4EBa1qhzo-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.5.0.9-IckAKQLBKZZ3c4EBa1qhzo-ghc9.6.3.a"; sourceTree = "<group>"; };
|
||||
64C8299B2D54AEEE006B9E89 /* libHSsimplex-chat-6.5.0.9-IckAKQLBKZZ3c4EBa1qhzo.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.5.0.9-IckAKQLBKZZ3c4EBa1qhzo.a"; sourceTree = "<group>"; };
|
||||
64C8299C2D54AEEE006B9E89 /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = "<group>"; };
|
||||
64D0C2BF29F9688300B38D5F /* UserAddressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserAddressView.swift; sourceTree = "<group>"; };
|
||||
64D0C2C129FA57AB00B38D5F /* UserAddressLearnMore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserAddressLearnMore.swift; sourceTree = "<group>"; };
|
||||
@@ -716,8 +716,8 @@
|
||||
64C8299D2D54AEEE006B9E89 /* libgmp.a in Frameworks */,
|
||||
64C8299E2D54AEEE006B9E89 /* libffi.a in Frameworks */,
|
||||
64C829A12D54AEEE006B9E89 /* libgmpxx.a in Frameworks */,
|
||||
64C8299F2D54AEEE006B9E89 /* libHSsimplex-chat-6.5.0.9-1LMKtNtYaECIyeIru99CUt-ghc9.6.3.a in Frameworks */,
|
||||
64C829A02D54AEEE006B9E89 /* libHSsimplex-chat-6.5.0.9-1LMKtNtYaECIyeIru99CUt.a in Frameworks */,
|
||||
64C8299F2D54AEEE006B9E89 /* libHSsimplex-chat-6.5.0.9-IckAKQLBKZZ3c4EBa1qhzo-ghc9.6.3.a in Frameworks */,
|
||||
64C829A02D54AEEE006B9E89 /* libHSsimplex-chat-6.5.0.9-IckAKQLBKZZ3c4EBa1qhzo.a in Frameworks */,
|
||||
CE38A29C2C3FCD72005ED185 /* SwiftyGif in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -803,8 +803,8 @@
|
||||
64C829992D54AEEE006B9E89 /* libffi.a */,
|
||||
64C829982D54AEED006B9E89 /* libgmp.a */,
|
||||
64C8299C2D54AEEE006B9E89 /* libgmpxx.a */,
|
||||
64C8299A2D54AEEE006B9E89 /* libHSsimplex-chat-6.5.0.9-1LMKtNtYaECIyeIru99CUt-ghc9.6.3.a */,
|
||||
64C8299B2D54AEEE006B9E89 /* libHSsimplex-chat-6.5.0.9-1LMKtNtYaECIyeIru99CUt.a */,
|
||||
64C8299A2D54AEEE006B9E89 /* libHSsimplex-chat-6.5.0.9-IckAKQLBKZZ3c4EBa1qhzo-ghc9.6.3.a */,
|
||||
64C8299B2D54AEEE006B9E89 /* libHSsimplex-chat-6.5.0.9-IckAKQLBKZZ3c4EBa1qhzo.a */,
|
||||
);
|
||||
path = Libraries;
|
||||
sourceTree = "<group>";
|
||||
|
||||
@@ -88,13 +88,6 @@ object ChannelRelaysModel {
|
||||
this.groupRelays.addAll(groupRelays)
|
||||
}
|
||||
|
||||
fun updateRelay(groupInfo: GroupInfo, relay: GroupRelay) {
|
||||
if (groupId.value == groupInfo.groupId) {
|
||||
val i = groupRelays.indexOfFirst { it.groupRelayId == relay.groupRelayId }
|
||||
if (i >= 0) groupRelays[i] = relay
|
||||
}
|
||||
}
|
||||
|
||||
fun reset() {
|
||||
groupId.value = null
|
||||
groupRelays.clear()
|
||||
|
||||
-10
@@ -2993,13 +2993,6 @@ object ChatController {
|
||||
}
|
||||
}
|
||||
}
|
||||
is CR.GroupRelayUpdated ->
|
||||
if (active(r.user)) {
|
||||
withContext(Dispatchers.Main) {
|
||||
chatModel.chatsContext.upsertGroupMember(rhId, r.groupInfo, r.member)
|
||||
ChannelRelaysModel.updateRelay(r.groupInfo, r.groupRelay)
|
||||
}
|
||||
}
|
||||
is CR.NewMemberContactReceivedInv ->
|
||||
if (active(r.user)) {
|
||||
withContext(Dispatchers.Main) {
|
||||
@@ -6308,7 +6301,6 @@ sealed class CR {
|
||||
@Serializable @SerialName("connectedToGroupMember") class ConnectedToGroupMember(val user: UserRef, val groupInfo: GroupInfo, val member: GroupMember, val memberContact: Contact? = null): CR()
|
||||
@Serializable @SerialName("groupUpdated") class GroupUpdated(val user: UserRef, val toGroup: GroupInfo): CR()
|
||||
@Serializable @SerialName("groupLinkDataUpdated") class GroupLinkDataUpdated(val user: UserRef, val groupInfo: GroupInfo, val groupLink: GroupLink, val groupRelays: List<GroupRelay>, val relaysChanged: Boolean): CR()
|
||||
@Serializable @SerialName("groupRelayUpdated") class GroupRelayUpdated(val user: UserRef, val groupInfo: GroupInfo, val member: GroupMember, val groupRelay: GroupRelay): CR()
|
||||
@Serializable @SerialName("groupLinkCreated") class GroupLinkCreated(val user: UserRef, val groupInfo: GroupInfo, val groupLink: GroupLink): CR()
|
||||
@Serializable @SerialName("groupLink") class CRGroupLink(val user: UserRef, val groupInfo: GroupInfo, val groupLink: GroupLink): CR()
|
||||
@Serializable @SerialName("groupLinkDeleted") class GroupLinkDeleted(val user: UserRef, val groupInfo: GroupInfo): CR()
|
||||
@@ -6494,7 +6486,6 @@ sealed class CR {
|
||||
is ConnectedToGroupMember -> "connectedToGroupMember"
|
||||
is GroupUpdated -> "groupUpdated"
|
||||
is GroupLinkDataUpdated -> "groupLinkDataUpdated"
|
||||
is GroupRelayUpdated -> "groupRelayUpdated"
|
||||
is GroupLinkCreated -> "groupLinkCreated"
|
||||
is CRGroupLink -> "groupLink"
|
||||
is GroupLinkDeleted -> "groupLinkDeleted"
|
||||
@@ -6673,7 +6664,6 @@ sealed class CR {
|
||||
is ConnectedToGroupMember -> withUser(user, "groupInfo: $groupInfo\nmember: $member\nmemberContact: $memberContact")
|
||||
is GroupUpdated -> withUser(user, json.encodeToString(toGroup))
|
||||
is GroupLinkDataUpdated -> withUser(user, "groupInfo: $groupInfo\ngroupLink: $groupLink\ngroupRelays: $groupRelays\nrelaysChanged: $relaysChanged")
|
||||
is GroupRelayUpdated -> withUser(user, "groupInfo: $groupInfo\nmember: $member\ngroupRelay: $groupRelay")
|
||||
is GroupLinkCreated -> withUser(user, "groupInfo: $groupInfo\ngroupLink: $groupLink")
|
||||
is CRGroupLink -> withUser(user, "groupInfo: $groupInfo\ngroupLink: $groupLink")
|
||||
is GroupLinkDeleted -> withUser(user, json.encodeToString(groupInfo))
|
||||
|
||||
+1
@@ -62,6 +62,7 @@ fun validRelayAddress(address: String): Boolean {
|
||||
(parsedMd.first().format as Format.SimplexLink).linkType == SimplexLinkType.relay
|
||||
}
|
||||
|
||||
// TODO [relays] TBC matching relay to operator by domain (relay address can be hosted on operator server)
|
||||
fun addChatRelay(
|
||||
relay: UserChatRelay,
|
||||
userServers: MutableState<List<UserOperatorServers>>,
|
||||
|
||||
@@ -39,7 +39,6 @@ This file is generated automatically.
|
||||
- [MemberBlockedForAll](#memberblockedforall)
|
||||
- [GroupMemberUpdated](#groupmemberupdated)
|
||||
- [GroupLinkDataUpdated](#grouplinkdataupdated)
|
||||
- [GroupRelayUpdated](#grouprelayupdated)
|
||||
|
||||
[File events](#file-events)
|
||||
- Main events
|
||||
@@ -469,20 +468,6 @@ Group link data updated.
|
||||
---
|
||||
|
||||
|
||||
### GroupRelayUpdated
|
||||
|
||||
Group relay member updated.
|
||||
|
||||
**Record type**:
|
||||
- type: "groupRelayUpdated"
|
||||
- user: [User](./TYPES.md#user)
|
||||
- groupInfo: [GroupInfo](./TYPES.md#groupinfo)
|
||||
- member: [GroupMember](./TYPES.md#groupmember)
|
||||
- groupRelay: [GroupRelay](./TYPES.md#grouprelay)
|
||||
|
||||
---
|
||||
|
||||
|
||||
## File events
|
||||
|
||||
Bots that send or receive files may process these events to track delivery status and to process completion.
|
||||
|
||||
@@ -98,8 +98,7 @@ chatEventsDocsData =
|
||||
("CEvtMemberAcceptedByOther", "Another group owner, admin or moderator accepted member to the group after review (\"knocking\")."),
|
||||
("CEvtMemberBlockedForAll", "Another member blocked for all members."),
|
||||
("CEvtGroupMemberUpdated", "Another group member profile updated."),
|
||||
("CEvtGroupLinkDataUpdated", "Group link data updated."),
|
||||
("CEvtGroupRelayUpdated", "Group relay member updated.")
|
||||
("CEvtGroupLinkDataUpdated", "Group link data updated.")
|
||||
]
|
||||
),
|
||||
( "File events",
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ constraints: zip +disable-bzip2 +disable-zstd
|
||||
source-repository-package
|
||||
type: git
|
||||
location: https://github.com/simplex-chat/simplexmq.git
|
||||
tag: fc1272d6144f13fa7e92b3dd6202e35c52cd75e2
|
||||
tag: 782cacfb3cc57883465eecc0b9b30662daf2b81f
|
||||
|
||||
source-repository-package
|
||||
type: git
|
||||
|
||||
@@ -30,7 +30,6 @@ export type ChatEvent =
|
||||
| CEvt.MemberBlockedForAll
|
||||
| CEvt.GroupMemberUpdated
|
||||
| CEvt.GroupLinkDataUpdated
|
||||
| CEvt.GroupRelayUpdated
|
||||
| CEvt.RcvFileDescrReady
|
||||
| CEvt.RcvFileComplete
|
||||
| CEvt.SndFileCompleteXFTP
|
||||
@@ -83,7 +82,6 @@ export namespace CEvt {
|
||||
| "memberBlockedForAll"
|
||||
| "groupMemberUpdated"
|
||||
| "groupLinkDataUpdated"
|
||||
| "groupRelayUpdated"
|
||||
| "rcvFileDescrReady"
|
||||
| "rcvFileComplete"
|
||||
| "sndFileCompleteXFTP"
|
||||
@@ -316,14 +314,6 @@ export namespace CEvt {
|
||||
relaysChanged: boolean
|
||||
}
|
||||
|
||||
export interface GroupRelayUpdated extends Interface {
|
||||
type: "groupRelayUpdated"
|
||||
user: T.User
|
||||
groupInfo: T.GroupInfo
|
||||
member: T.GroupMember
|
||||
groupRelay: T.GroupRelay
|
||||
}
|
||||
|
||||
export interface RcvFileDescrReady extends Interface {
|
||||
type: "rcvFileDescrReady"
|
||||
user: T.User
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"https://github.com/simplex-chat/simplexmq.git"."fc1272d6144f13fa7e92b3dd6202e35c52cd75e2" = "072bgw44fsq2r9vbrphr2xkydcksfvxna7m6ln5rfc60dbkajisl";
|
||||
"https://github.com/simplex-chat/simplexmq.git"."782cacfb3cc57883465eecc0b9b30662daf2b81f" = "0ck5hcj2yn540l11bbhn0ghgk49mfyqy0c4xqkbw1kk0fd9hhxs6";
|
||||
"https://github.com/simplex-chat/hs-socks.git"."a30cc7a79a08d8108316094f8f2f82a0c5e1ac51" = "0yasvnr7g91k76mjkamvzab2kvlb1g5pspjyjn2fr6v83swjhj38";
|
||||
"https://github.com/simplex-chat/direct-sqlcipher.git"."f814ee68b16a9447fbb467ccc8f29bdd3546bfd9" = "1ql13f4kfwkbaq7nygkxgw84213i0zm7c1a8hwvramayxl38dq5d";
|
||||
"https://github.com/simplex-chat/sqlcipher-simple.git"."a46bd361a19376c5211f1058908fc0ae6bf42446" = "1z0r78d8f0812kxbgsm735qf6xx8lvaz27k1a0b4a2m0sshpd5gl";
|
||||
|
||||
@@ -858,7 +858,6 @@ data ChatEvent
|
||||
| CEvtReceivedGroupInvitation {user :: User, groupInfo :: GroupInfo, contact :: Contact, fromMemberRole :: GroupMemberRole, memberRole :: GroupMemberRole}
|
||||
| CEvtUserJoinedGroup {user :: User, groupInfo :: GroupInfo, hostMember :: GroupMember}
|
||||
| CEvtGroupLinkDataUpdated {user :: User, groupInfo :: GroupInfo, groupLink :: GroupLink, groupRelays :: [GroupRelay], relaysChanged :: Bool}
|
||||
| CEvtGroupRelayUpdated {user :: User, groupInfo :: GroupInfo, member :: GroupMember, groupRelay :: GroupRelay}
|
||||
| CEvtJoinedGroupMember {user :: User, groupInfo :: GroupInfo, member :: GroupMember} -- there is the same command response
|
||||
| CEvtJoinedGroupMemberConnecting {user :: User, groupInfo :: GroupInfo, hostMember :: GroupMember, member :: GroupMember}
|
||||
| CEvtMemberAcceptedByOther {user :: User, groupInfo :: GroupInfo, acceptingMember :: GroupMember, member :: GroupMember}
|
||||
|
||||
@@ -1841,7 +1841,7 @@ processChatCommand vr nm = \case
|
||||
let userData = contactShortLinkData (userProfileDirect user incognitoProfile Nothing True) Nothing
|
||||
userLinkData = UserInvLinkData userData
|
||||
-- TODO [certs rcv]
|
||||
(connId, (_, ccLink, _serviceId)) <- withAgent $ \a -> createConnection a nm (aUserId user) Nothing True False SCMInvitation (Just userLinkData) Nothing IKPQOn subMode
|
||||
(connId, (ccLink, _serviceId)) <- withAgent $ \a -> createConnection a nm (aUserId user) True False SCMInvitation (Just userLinkData) Nothing IKPQOn subMode
|
||||
ccLink' <- shortenCreatedLink ccLink
|
||||
-- TODO PQ pass minVersion from the current range
|
||||
conn <- withFastStore' $ \db -> createDirectConnection db user connId ccLink' Nothing ConnNew incognitoProfile subMode initialChatVersion PQSupportOn
|
||||
@@ -1883,7 +1883,7 @@ processChatCommand vr nm = \case
|
||||
| short = Just $ UserInvLinkData $ contactShortLinkData (userProfileDirect newUser Nothing Nothing True) Nothing
|
||||
| otherwise = Nothing
|
||||
-- TODO [certs rcv]
|
||||
(agConnId, (_, ccLink, _serviceId)) <- withAgent $ \a -> createConnection a nm (aUserId newUser) Nothing True False SCMInvitation userLinkData_ Nothing IKPQOn subMode
|
||||
(agConnId, (ccLink, _serviceId)) <- withAgent $ \a -> createConnection a nm (aUserId newUser) True False SCMInvitation userLinkData_ Nothing IKPQOn subMode
|
||||
ccLink' <- shortenCreatedLink ccLink
|
||||
conn' <- withFastStore' $ \db -> do
|
||||
deleteConnectionRecord db user connId
|
||||
@@ -2067,19 +2067,18 @@ processChatCommand vr nm = \case
|
||||
_ -> False
|
||||
connectToRelay gInfo' relayLink = do
|
||||
gVar <- asks random
|
||||
-- TODO [relays] member: set relay profile before/during connection
|
||||
-- TODO - on fetching relay link data? (-> relay should add profile to relay link)
|
||||
-- TODO - or update upon connection, as in regular prepared groups
|
||||
-- TODO (current logic mimics insertHost_ from createPreparedGroup)
|
||||
-- Save relayLink to re-use relay member record on retry (check by relayLink)
|
||||
relayMember <- withFastStore $ \db -> getCreateRelayForMember db vr gVar user gInfo' relayLink
|
||||
r <- tryAllErrors $ do
|
||||
(fd@FixedLinkData {rootKey = relayKey, linkEntityId}, cData) <- getShortLinkConnReq nm user relayLink
|
||||
relayLinkData_ <- liftIO $ decodeLinkUserData cData
|
||||
case (relayLinkData_, linkEntityId) of
|
||||
(Just RelayShortLinkData {relayProfile = p}, Just entityId) ->
|
||||
withFastStore $ \db -> updateRelayMemberData db user relayMember (MemberId entityId) (MemberKey relayKey) p
|
||||
_ -> throwChatError $ CEException "relay link: no relay link data or entity id"
|
||||
(fd, _cData) <- getShortLinkConnReq nm user relayLink
|
||||
let cReq = linkConnReq fd
|
||||
relayLinkToConnect = CCLink cReq (Just relayLink)
|
||||
void $ connectViaContact user (Just $ PCEGroup gInfo' relayMember) incognito relayLinkToConnect Nothing Nothing
|
||||
-- Re-read member to get updated activeConn and updated data (from updateRelayMemberData)
|
||||
-- Re-read member to get updated activeConn
|
||||
relayMember' <- withFastStore $ \db -> getGroupMember db vr user groupId (groupMemberId' relayMember)
|
||||
pure (relayLink, relayMember', r)
|
||||
retryRelayConnectionAsync gInfo' relayLink relayMember@GroupMember {activeConn} = do
|
||||
@@ -2087,7 +2086,7 @@ processChatCommand vr nm = \case
|
||||
deleteAgentConnectionAsync $ aConnId conn
|
||||
withStore' $ \db -> deleteConnectionRecord db user (dbConnId conn)
|
||||
subMode <- chatReadVar subscriptionMode
|
||||
newConnIds <- getAgentConnShortLinkAsync user CFGetRelayDataJoin Nothing relayLink
|
||||
newConnIds <- getAgentConnShortLinkAsync user relayLink
|
||||
withStore' $ \db -> createRelayMemberConnectionAsync db user gInfo' relayMember relayLink newConnIds subMode
|
||||
GroupInfo {preparedGroup = Just PreparedGroup {connLinkToConnect, welcomeSharedMsgId, requestSharedMsgId}} -> do
|
||||
hostMember <- withFastStore $ \db -> getHostMember db vr user groupId
|
||||
@@ -2162,11 +2161,13 @@ processChatCommand vr nm = \case
|
||||
Left e -> throwError $ ChatErrorStore e
|
||||
Right _ -> throwError $ ChatErrorStore SEDuplicateContactLink
|
||||
subMode <- chatReadVar subscriptionMode
|
||||
-- TODO [relays] relay: add relay profile, identity, key to link data?
|
||||
-- TODO [relays] relay: address creation
|
||||
-- TODO - add relay key, identity to link data
|
||||
-- TODO - validate short link is created (returned by agent)
|
||||
let userData = contactShortLinkData (userProfileDirect user Nothing Nothing True) Nothing
|
||||
userLinkData = UserContactLinkData UserContactData {direct = True, owners = [], relays = [], userData}
|
||||
-- TODO [certs rcv]
|
||||
(connId, (_, ccLink, _serviceId)) <- withAgent $ \a -> createConnection a nm (aUserId user) Nothing True True SCMContact (Just userLinkData) Nothing IKPQOn subMode
|
||||
(connId, (ccLink, _serviceId)) <- withAgent $ \a -> createConnection a nm (aUserId user) True True SCMContact (Just userLinkData) Nothing IKPQOn subMode
|
||||
ccLink' <- shortenCreatedLink ccLink
|
||||
let ccLink'' = if isTrue userChatRelay then createdRelayLink ccLink' else ccLink'
|
||||
withFastStore $ \db -> createUserContactLink db user connId ccLink'' subMode
|
||||
@@ -2432,7 +2433,7 @@ processChatCommand vr nm = \case
|
||||
gVar <- asks random
|
||||
subMode <- chatReadVar subscriptionMode
|
||||
-- TODO [certs rcv]
|
||||
(agentConnId, (_, CCLink cReq _, _serviceId)) <- withAgent $ \a -> createConnection a nm (aUserId user) Nothing True False SCMInvitation Nothing Nothing IKPQOff subMode
|
||||
(agentConnId, (CCLink cReq _, _serviceId)) <- withAgent $ \a -> createConnection a nm (aUserId user) True False SCMInvitation Nothing Nothing IKPQOff subMode
|
||||
member <- withFastStore $ \db -> createNewContactMember db gVar user gInfo contact memRole agentConnId cReq subMode
|
||||
sendInvitation member cReq
|
||||
pure $ CRSentGroupInvitation user gInfo contact member
|
||||
@@ -2856,7 +2857,7 @@ processChatCommand vr nm = \case
|
||||
userLinkData = UserContactLinkData UserContactData {direct = True, owners = [], relays = [], userData}
|
||||
crClientData = encodeJSON $ CRDataGroup groupLinkId
|
||||
-- TODO [certs rcv]
|
||||
(connId, (_, ccLink, _serviceId)) <- withAgent $ \a -> createConnection a nm (aUserId user) Nothing True True SCMContact (Just userLinkData) (Just crClientData) IKPQOff subMode
|
||||
(connId, (ccLink, _serviceId)) <- withAgent $ \a -> createConnection a nm (aUserId user) True True SCMContact (Just userLinkData) (Just crClientData) IKPQOff subMode
|
||||
ccLink' <- createdGroupLink <$> shortenCreatedLink ccLink
|
||||
gVar <- asks random
|
||||
gLink <- withFastStore $ \db -> createGroupLink db gVar user gInfo connId ccLink' groupLinkId mRole subMode
|
||||
@@ -2897,7 +2898,7 @@ processChatCommand vr nm = \case
|
||||
subMode <- chatReadVar subscriptionMode
|
||||
-- TODO PQ should negotitate contact connection with PQSupportOn?
|
||||
-- TODO [certs rcv]
|
||||
(connId, (_, CCLink cReq _, _serviceId)) <- withAgent $ \a -> createConnection a nm (aUserId user) Nothing True False SCMInvitation Nothing Nothing IKPQOff subMode
|
||||
(connId, (CCLink cReq _, _serviceId)) <- withAgent $ \a -> createConnection a nm (aUserId user) True False SCMInvitation Nothing Nothing IKPQOff subMode
|
||||
-- [incognito] reuse membership incognito profile
|
||||
ct <- withFastStore' $ \db -> createMemberContact db user connId cReq g m mConn subMode
|
||||
void $ createChatItem user (CDDirectSnd ct) False CIChatBanner Nothing (Just epochStart)
|
||||
|
||||
@@ -1032,7 +1032,7 @@ acceptBusinessJoinRequestAsync
|
||||
-- TODO [short links] get updated business chat group and member? (currently not used)
|
||||
pure (gInfo, clientMember)
|
||||
|
||||
acceptRelayJoinRequestAsync :: User -> Int64 -> GroupInfo -> GroupMember -> InvitationId -> VersionRangeChat -> ShortLinkContact -> CM (GroupInfo, GroupMember)
|
||||
acceptRelayJoinRequestAsync :: User -> Int64 -> GroupInfo -> GroupMember -> InvitationId -> VersionRangeChat -> ShortLinkContact -> MemberKey -> CM (GroupInfo, GroupMember)
|
||||
acceptRelayJoinRequestAsync
|
||||
user
|
||||
uclId
|
||||
@@ -1040,8 +1040,9 @@ acceptRelayJoinRequestAsync
|
||||
_ownerMember@GroupMember {groupMemberId}
|
||||
cReqInvId
|
||||
cReqChatVRange
|
||||
relayLink = do
|
||||
let msg = XGrpRelayAcpt relayLink
|
||||
relayLink
|
||||
memberKey = do
|
||||
let msg = XGrpRelayAcpt relayLink memberKey
|
||||
subMode <- chatReadVar subscriptionMode
|
||||
vr <- chatVersionRange
|
||||
let chatV = vr `peerConnChatVersion` cReqChatVRange
|
||||
@@ -1322,7 +1323,7 @@ updatePublicGroupData user gInfo
|
||||
pure gInfo'
|
||||
| otherwise = pure gInfo
|
||||
|
||||
-- TODO [relays] owner: set owners on updating link data (multi-owner)
|
||||
-- TODO [relays] owner: set owners on updating link data
|
||||
groupLinkData :: GroupInfo -> GroupLink -> [GroupRelay] -> (UserConnLinkData 'CMContact, CRClientData)
|
||||
groupLinkData gInfo@GroupInfo {groupProfile, groupSummary = GroupSummary {publicMemberCount}} GroupLink {groupLinkId} groupRelays =
|
||||
let direct = not $ useRelays' gInfo
|
||||
@@ -2447,11 +2448,11 @@ setAgentConnShortLinkAsync user conn@Connection {connId} userLinkData crClientDa
|
||||
cmdId <- withStore' $ \db -> createCommand db user (Just connId) CFSetShortLink
|
||||
withAgent $ \a -> setConnShortLinkAsync a (aCorrId cmdId) (aConnId conn) userLinkData crClientData_
|
||||
|
||||
getAgentConnShortLinkAsync :: User -> CommandFunction -> Maybe Connection -> ShortLinkContact -> CM (CommandId, ConnId)
|
||||
getAgentConnShortLinkAsync user cmdFunc conn_ shortLink = do
|
||||
getAgentConnShortLinkAsync :: User -> ShortLinkContact -> CM (CommandId, ConnId)
|
||||
getAgentConnShortLinkAsync user shortLink = do
|
||||
shortLink' <- restoreShortLink' shortLink
|
||||
cmdId <- withStore' $ \db -> createCommand db user (dbConnId <$> conn_) cmdFunc
|
||||
connId <- withAgent $ \a -> getConnShortLinkAsync a (aUserId user) (aCorrId cmdId) (aConnId <$> conn_) shortLink'
|
||||
cmdId <- withStore' $ \db -> createCommand db user Nothing CFGetShortLink
|
||||
connId <- withAgent $ \a -> getConnShortLinkAsync a (aUserId user) (aCorrId cmdId) shortLink'
|
||||
pure (cmdId, connId)
|
||||
|
||||
agentXFTPDeleteRcvFile :: RcvFileId -> FileTransferId -> CM ()
|
||||
|
||||
@@ -735,10 +735,13 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
|
||||
-- [async agent commands] no continuation needed, but command should be asynchronous for stability
|
||||
allowAgentConnectionAsync user conn' confId XOk
|
||||
| otherwise -> messageError "x.grp.acpt: memberId is different from expected"
|
||||
XGrpRelayAcpt relayLink
|
||||
XGrpRelayAcpt relayLink memberKey
|
||||
| memberRole' membership == GROwner && isRelay m -> do
|
||||
withStore' $ \db -> setRelayLinkConfId db m confId relayLink
|
||||
void $ getAgentConnShortLinkAsync user CFGetRelayDataAccept (Just conn') relayLink
|
||||
withStore $ \db -> do
|
||||
relay <- getGroupRelayByGMId db (groupMemberId' m)
|
||||
liftIO $ updateGroupMemberStatus db userId m GSMemAccepted
|
||||
void $ liftIO $ setRelayLinkAccepted db relay relayLink memberKey
|
||||
allowAgentConnectionAsync user conn' confId XOk
|
||||
| otherwise -> messageError "x.grp.relay.acpt: only owner can add relay"
|
||||
_ -> messageError "CONF from invited member must have x.grp.acpt"
|
||||
GCHostMember ->
|
||||
@@ -863,9 +866,11 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
|
||||
when (groupFeatureAllowed SGFHistory gInfo'' && not memberIsCustomer) $ sendHistory user gInfo'' m'
|
||||
where
|
||||
sendXGrpLinkMem gInfo'' = do
|
||||
let incognitoProfile = ExistingIncognito <$> incognitoMembershipProfile gInfo''
|
||||
let GroupInfo {membership = membership'} = gInfo''
|
||||
incognitoProfile = ExistingIncognito <$> incognitoMembershipProfile gInfo''
|
||||
profileToSend = userProfileInGroup user gInfo (fromIncognitoProfile <$> incognitoProfile)
|
||||
void $ sendDirectMemberMessage conn (XGrpLinkMem profileToSend) groupId
|
||||
memberKey = MemberKey <$> memberPubKey membership'
|
||||
void $ sendDirectMemberMessage conn (XGrpLinkMem profileToSend memberKey) groupId
|
||||
_ -> do
|
||||
unless (memberPending m) $ withStore' $ \db -> updateGroupMemberStatus db userId m GSMemConnected
|
||||
notifyMemberConnected gInfo m Nothing
|
||||
@@ -963,7 +968,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
|
||||
XFileCancel sharedMsgId -> xFileCancelGroup gInfo' (Just m'') sharedMsgId
|
||||
XFileAcptInv sharedMsgId fileConnReq_ fName -> Nothing <$ xFileAcptInvGroup gInfo' m'' sharedMsgId fileConnReq_ fName
|
||||
XInfo p -> fmap ctx <$> xInfoMember gInfo' m'' p msg brokerTs
|
||||
XGrpLinkMem p -> Nothing <$ xGrpLinkMem gInfo' m'' conn' p
|
||||
XGrpLinkMem p memberKey -> Nothing <$ xGrpLinkMem gInfo' m'' conn' p memberKey
|
||||
XGrpLinkAcpt acceptance role memberId -> Nothing <$ xGrpLinkAcpt gInfo' m'' acceptance role memberId msg brokerTs
|
||||
XGrpMemNew memInfo msgScope -> fmap ctx <$> xGrpMemNew gInfo' m'' memInfo msgScope msg brokerTs
|
||||
XGrpMemIntro memInfo memRestrictions_ -> Nothing <$ xGrpMemIntro gInfo' m'' memInfo memRestrictions_
|
||||
@@ -1083,53 +1088,30 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
|
||||
forM_ mc_ $ \mc -> do
|
||||
connReq_ <- withStore' $ \db -> getBusinessContactRequest db user groupId
|
||||
sendGroupAutoReply mc connReq_
|
||||
LDATA FixedLinkData {linkConnReq = cReq, rootKey = relayKey, linkEntityId} cData ->
|
||||
LDATA FixedLinkData {linkConnReq = cReq} _cData ->
|
||||
-- [async agent commands] CFGetConnShortLink continuation - join relay connection with resolved link
|
||||
withCompletedCommand conn agentMsg $ \CommandData {cmdFunction} ->
|
||||
case cmdFunction of
|
||||
CFGetRelayDataJoin -> do
|
||||
-- Update relay member with key, memberId and profile from link
|
||||
relayLinkData_ <- liftIO $ decodeLinkUserData cData
|
||||
case (relayLinkData_, linkEntityId) of
|
||||
(Just RelayShortLinkData {relayProfile = p}, Just entityId) ->
|
||||
withStore $ \db -> updateRelayMemberData db user m (MemberId entityId) (MemberKey relayKey) p
|
||||
_ -> throwChatError $ CEException "relay link: no relay link data or entity id"
|
||||
case cReq of
|
||||
CRContactUri crData@ConnReqUriData {crClientData} -> do
|
||||
let pqSup = PQSupportOff
|
||||
lift (withAgent' $ \a -> connRequestPQSupport a pqSup cReq) >>= \case
|
||||
Nothing -> throwChatError CEInvalidConnReq
|
||||
Just (agentV, _) -> do
|
||||
let chatV = agentToChatVersion agentV
|
||||
groupLinkId = crClientData >>= decodeJSON >>= \(CRDataGroup gli) -> Just gli
|
||||
cReqHash = contactCReqHash $ CRContactUri crData {crScheme = SSSimplex}
|
||||
-- Update connection with data derived from cReq, now available after getConnShortLinkAsync
|
||||
withStore' $ \db -> updateConnLinkData db user conn cReq cReqHash groupLinkId chatV pqSup
|
||||
let GroupMember {memberId = membershipMemId} = membership
|
||||
incognitoProfile = fromLocalProfile <$> incognitoMembershipProfile gInfo
|
||||
profileToSend = userProfileInGroup user gInfo incognitoProfile
|
||||
memberPubKey <- case groupKeys gInfo of
|
||||
Just GroupKeys {memberPrivKey} -> pure $ C.publicKey memberPrivKey
|
||||
Nothing -> throwChatError $ CEInternalError "no group keys for channel membership"
|
||||
dm <- encodeConnInfo $ XMember profileToSend membershipMemId (MemberKey memberPubKey)
|
||||
subMode <- chatReadVar subscriptionMode
|
||||
void $ joinAgentConnectionAsync user (Just conn) True cReq dm subMode
|
||||
CFGetRelayDataAccept -> do
|
||||
let GroupMember {memberId = MemberId expectedMemberId} = m
|
||||
if linkEntityId == Just expectedMemberId
|
||||
then do
|
||||
relayProfile <- liftIO (decodeLinkUserData cData) >>= \case
|
||||
Just RelayShortLinkData {relayProfile = p} -> pure p
|
||||
Nothing -> throwChatError $ CEException "relay link: no relay link data"
|
||||
(confId, m', relay) <- withStore $ \db -> do
|
||||
confId <- getRelayConfId db m
|
||||
liftIO $ updateGroupMemberStatus db userId m GSMemAccepted
|
||||
(m', relay) <- setRelayLinkAccepted db vr user m (MemberKey relayKey) relayProfile
|
||||
pure (confId, m', relay)
|
||||
allowAgentConnectionAsync user conn confId XOk
|
||||
toView $ CEvtGroupRelayUpdated user gInfo m' relay
|
||||
else
|
||||
-- TODO [relays] owner: TBC failed RelayStatus?
|
||||
messageError "relay link: relay member ID mismatch"
|
||||
CFGetShortLink -> case cReq of
|
||||
CRContactUri crData@ConnReqUriData {crClientData} -> do
|
||||
let pqSup = PQSupportOff
|
||||
lift (withAgent' $ \a -> connRequestPQSupport a pqSup cReq) >>= \case
|
||||
Nothing -> throwChatError CEInvalidConnReq
|
||||
Just (agentV, _) -> do
|
||||
let chatV = agentToChatVersion agentV
|
||||
groupLinkId = crClientData >>= decodeJSON >>= \(CRDataGroup gli) -> Just gli
|
||||
cReqHash = contactCReqHash $ CRContactUri crData {crScheme = SSSimplex}
|
||||
-- Update connection with data derived from cReq, now available after getConnShortLinkAsync
|
||||
withStore' $ \db -> updateConnLinkData db user conn cReq cReqHash groupLinkId chatV pqSup
|
||||
let GroupMember {memberId = membershipMemId} = membership
|
||||
incognitoProfile = fromLocalProfile <$> incognitoMembershipProfile gInfo
|
||||
profileToSend = userProfileInGroup user gInfo incognitoProfile
|
||||
memberPubKey <- case groupKeys gInfo of
|
||||
Just GroupKeys {memberPrivKey} -> pure $ C.publicKey memberPrivKey
|
||||
Nothing -> throwChatError $ CEInternalError "no group keys for channel membership"
|
||||
dm <- encodeConnInfo $ XMember profileToSend membershipMemId (MemberKey memberPubKey)
|
||||
subMode <- chatReadVar subscriptionMode
|
||||
void $ joinAgentConnectionAsync user (Just conn) True cReq dm subMode
|
||||
_ -> throwChatError $ CECommandError "unexpected cmdFunction"
|
||||
QCONT -> do
|
||||
continued <- continueSending connEntity conn
|
||||
@@ -2420,13 +2402,13 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
|
||||
void $ processMemberProfileUpdate gInfo m p' (Just (msg, brokerTs))
|
||||
pure $ memberEventDeliveryScope m
|
||||
|
||||
xGrpLinkMem :: GroupInfo -> GroupMember -> Connection -> Profile -> CM ()
|
||||
xGrpLinkMem gInfo@GroupInfo {membership, businessChat} m@GroupMember {groupMemberId, memberCategory} Connection {viaGroupLink} p' = do
|
||||
xGrpLinkMem :: GroupInfo -> GroupMember -> Connection -> Profile -> Maybe MemberKey -> CM ()
|
||||
xGrpLinkMem gInfo@GroupInfo {membership, businessChat} m@GroupMember {groupMemberId, memberCategory} Connection {viaGroupLink} p' memberKey_ = do
|
||||
xGrpLinkMemReceived <- withStore $ \db -> getXGrpLinkMemReceived db groupMemberId
|
||||
if (viaGroupLink || isJust businessChat) && isNothing (memberContactId m) && memberCategory == GCHostMember && not xGrpLinkMemReceived
|
||||
then do
|
||||
m' <- processMemberProfileUpdate gInfo m p' Nothing
|
||||
withStore' $ \db -> setXGrpLinkMemReceived db groupMemberId True
|
||||
withStore' $ \db -> setXGrpLinkMemReceived db groupMemberId True memberKey_
|
||||
let connectedIncognito = memberIncognito membership
|
||||
probeMatchingMemberContact m' connectedIncognito
|
||||
else messageError "x.grp.link.mem error: invalid group link host profile update"
|
||||
@@ -3614,52 +3596,56 @@ runRelayRequestWorker a Worker {doWork} = do
|
||||
-- Check if relay link already exists (recovery case)
|
||||
case groupLink_ of
|
||||
Right GroupLink {connLinkContact = CCLink _ sLnk_} ->
|
||||
case sLnk_ of
|
||||
Just sLnk -> acceptOwnerConnection rrd gInfo sLnk
|
||||
Nothing -> throwChatError $ CEException "processRelayRequest: relay link doesn't have short link"
|
||||
case (sLnk_, memberPubKey $ membership gInfo) of
|
||||
(Just sLnk, Just k) -> acceptOwnerConnection rrd gInfo sLnk (MemberKey k)
|
||||
(Nothing, _) -> throwChatError $ CEException "processRelayRequest: relay link doesn't have short link"
|
||||
(_, Nothing) -> throwChatError $ CEException "processRelayRequest: no member key"
|
||||
Left _ -> do
|
||||
(gInfo', sLnk) <- getLinkDataCreateRelayLink rrd gInfo
|
||||
acceptOwnerConnection rrd gInfo' sLnk
|
||||
(gInfo', sLnk, memberKey) <- getLinkDataCreateRelayLink rrd gInfo
|
||||
acceptOwnerConnection rrd gInfo' sLnk memberKey
|
||||
where
|
||||
getLinkDataCreateRelayLink :: RelayRequestData -> GroupInfo -> CM (GroupInfo, ShortLinkContact)
|
||||
getLinkDataCreateRelayLink :: RelayRequestData -> GroupInfo -> CM (GroupInfo, ShortLinkContact, MemberKey)
|
||||
getLinkDataCreateRelayLink RelayRequestData {reqGroupLink} gInfo = do
|
||||
(FixedLinkData {linkEntityId, rootKey}, cData@(ContactLinkData _ UserContactData {owners})) <- getShortLinkConnReq NRMBackground user reqGroupLink
|
||||
liftIO (decodeLinkUserData cData) >>= \case
|
||||
Nothing -> throwChatError $ CEException "getLinkDataCreateRelayLink: no group link data"
|
||||
Just GroupShortLinkData {groupProfile = gp} -> do
|
||||
validateGroupProfile gp
|
||||
((_, memberPrivKey), sLnk) <- createRelayLink gInfo
|
||||
gVar <- asks random
|
||||
(_, memberPrivKey) <- liftIO $ atomically $ C.generateKeyPair gVar
|
||||
gInfo' <- withStore $ \db -> do
|
||||
void $ updateGroupProfile db user gInfo gp
|
||||
updateRelayGroupKeys db user gInfo linkEntityId rootKey memberPrivKey owners
|
||||
getGroupInfo db vr user groupId
|
||||
pure (gInfo', sLnk)
|
||||
sLnk <- createRelayLink gInfo'
|
||||
pure (gInfo', sLnk, MemberKey $ C.publicKey memberPrivKey)
|
||||
where
|
||||
validateGroupProfile :: GroupProfile -> CM ()
|
||||
validateGroupProfile _groupProfile = do
|
||||
-- TODO [relays] relay: validate group profile, verify owner's signature
|
||||
pure ()
|
||||
createRelayLink :: GroupInfo -> CM (C.KeyPairEd25519, ShortLinkContact)
|
||||
createRelayLink gi = do
|
||||
let GroupInfo {membership = relayMem} = gi
|
||||
GroupMember {memberId = relayMemId, memberProfile = relayLP} = relayMem
|
||||
MemberId relayMemberIdBS = relayMemId
|
||||
userData = encodeShortLinkData $ RelayShortLinkData {relayProfile = fromLocalProfile relayLP}
|
||||
userLinkData = UserContactLinkData UserContactData {direct = True, owners = [], relays = [], userData}
|
||||
createRelayLink :: GroupInfo -> CM ShortLinkContact
|
||||
createRelayLink gi@GroupInfo {groupProfile} = do
|
||||
-- TODO [relays] relay: set relay link data
|
||||
-- TODO - link data: relay key for group, relay identity (profile, certificate, relay identity key)
|
||||
-- TODO - starting role should be communicated in protocol from owner to relays
|
||||
groupLinkId <- GroupLinkId <$> drgRandomBytes 16
|
||||
subMode <- chatReadVar subscriptionMode
|
||||
-- TODO [relays] starting role should be communicated in protocol from owner to relays
|
||||
subRole <- asks $ channelSubscriberRole . config
|
||||
let crClientData = encodeJSON $ CRDataGroup groupLinkId
|
||||
(connId, (Just sigKeys, ccLink, _serviceId)) <- withAgent $ \a' -> createConnection a' NRMBackground (aUserId user) (Just relayMemberIdBS) True True SCMContact (Just userLinkData) (Just crClientData) CR.IKPQOff subMode
|
||||
let userData = encodeShortLinkData $ GroupShortLinkData {groupProfile, publicGroupData = Nothing}
|
||||
userLinkData = UserContactLinkData UserContactData {direct = True, owners = [], relays = [], userData}
|
||||
crClientData = encodeJSON $ CRDataGroup groupLinkId
|
||||
(connId, (ccLink, _serviceId)) <- withAgent $ \a' -> createConnection a' NRMBackground (aUserId user) True True SCMContact (Just userLinkData) (Just crClientData) CR.IKPQOff subMode
|
||||
ccLink' <- createdGroupLink <$> shortenCreatedLink ccLink
|
||||
sLnk <- case toShortLinkContact ccLink' of
|
||||
Just sl -> pure sl
|
||||
Nothing -> throwChatError $ CEException "failed to create relay link: no short link"
|
||||
gVar <- asks random
|
||||
void $ withFastStore $ \db -> createGroupLink db gVar user gi connId ccLink' groupLinkId subRole subMode
|
||||
pure (sigKeys, sLnk)
|
||||
acceptOwnerConnection :: RelayRequestData -> GroupInfo -> ShortLinkContact -> CM ()
|
||||
acceptOwnerConnection RelayRequestData {relayInvId, reqChatVRange} gi relayLink = do
|
||||
pure sLnk
|
||||
acceptOwnerConnection :: RelayRequestData -> GroupInfo -> ShortLinkContact -> MemberKey -> CM ()
|
||||
acceptOwnerConnection RelayRequestData {relayInvId, reqChatVRange} gi relayLink memberKey = do
|
||||
ownerMember <- withStore $ \db -> getHostMember db vr user groupId
|
||||
void $ acceptRelayJoinRequestAsync user uclId gi ownerMember relayInvId reqChatVRange relayLink
|
||||
void $ acceptRelayJoinRequestAsync user uclId gi ownerMember relayInvId reqChatVRange relayLink memberKey
|
||||
-- TODO [relays] relay: group invite accepted event, chat item (?)
|
||||
pure ()
|
||||
|
||||
@@ -432,10 +432,10 @@ data ChatMsgEvent (e :: MsgEncoding) where
|
||||
XGrpAcpt :: MemberId -> ChatMsgEvent 'Json
|
||||
XGrpLinkInv :: GroupLinkInvitation -> ChatMsgEvent 'Json
|
||||
XGrpLinkReject :: GroupLinkRejection -> ChatMsgEvent 'Json
|
||||
XGrpLinkMem :: Profile -> ChatMsgEvent 'Json
|
||||
XGrpLinkMem :: Profile -> Maybe MemberKey -> ChatMsgEvent 'Json
|
||||
XGrpLinkAcpt :: GroupAcceptance -> GroupMemberRole -> MemberId -> ChatMsgEvent 'Json
|
||||
XGrpRelayInv :: GroupRelayInvitation -> ChatMsgEvent 'Json
|
||||
XGrpRelayAcpt :: ShortLinkContact -> ChatMsgEvent 'Json
|
||||
XGrpRelayAcpt :: ShortLinkContact -> MemberKey -> ChatMsgEvent 'Json
|
||||
XGrpMemNew :: MemberInfo -> Maybe MsgScope -> ChatMsgEvent 'Json
|
||||
XGrpMemIntro :: MemberInfo -> Maybe MemberRestrictions -> ChatMsgEvent 'Json
|
||||
XGrpMemInv :: MemberId -> IntroInvitation -> ChatMsgEvent 'Json
|
||||
@@ -1126,10 +1126,10 @@ toCMEventTag msg = case msg of
|
||||
XGrpAcpt _ -> XGrpAcpt_
|
||||
XGrpLinkInv _ -> XGrpLinkInv_
|
||||
XGrpLinkReject _ -> XGrpLinkReject_
|
||||
XGrpLinkMem _ -> XGrpLinkMem_
|
||||
XGrpLinkMem _ _ -> XGrpLinkMem_
|
||||
XGrpLinkAcpt {} -> XGrpLinkAcpt_
|
||||
XGrpRelayInv _ -> XGrpRelayInv_
|
||||
XGrpRelayAcpt _ -> XGrpRelayAcpt_
|
||||
XGrpRelayAcpt _ _ -> XGrpRelayAcpt_
|
||||
XGrpMemNew {} -> XGrpMemNew_
|
||||
XGrpMemIntro _ _ -> XGrpMemIntro_
|
||||
XGrpMemInv _ _ -> XGrpMemInv_
|
||||
@@ -1278,10 +1278,10 @@ appJsonToCM AppMessageJson {v, msgId, event, params} = do
|
||||
XGrpAcpt_ -> XGrpAcpt <$> p "memberId"
|
||||
XGrpLinkInv_ -> XGrpLinkInv <$> p "groupLinkInvitation"
|
||||
XGrpLinkReject_ -> XGrpLinkReject <$> p "groupLinkRejection"
|
||||
XGrpLinkMem_ -> XGrpLinkMem <$> p "profile"
|
||||
XGrpLinkMem_ -> XGrpLinkMem <$> p "profile" <*> opt "memberKey"
|
||||
XGrpLinkAcpt_ -> XGrpLinkAcpt <$> p "acceptance" <*> p "role" <*> p "memberId"
|
||||
XGrpRelayInv_ -> XGrpRelayInv <$> p "groupRelayInvitation"
|
||||
XGrpRelayAcpt_ -> XGrpRelayAcpt <$> p "relayLink"
|
||||
XGrpRelayAcpt_ -> XGrpRelayAcpt <$> p "relayLink" <*> p "memberKey"
|
||||
XGrpMemNew_ -> XGrpMemNew <$> p "memberInfo" <*> opt "scope"
|
||||
XGrpMemIntro_ -> XGrpMemIntro <$> p "memberInfo" <*> opt "memberRestrictions"
|
||||
XGrpMemInv_ -> XGrpMemInv <$> p "memberId" <*> p "memberIntro"
|
||||
@@ -1345,10 +1345,10 @@ chatToAppMessage chatMsg@ChatMessage {chatVRange, msgId, chatMsgEvent} = case en
|
||||
XGrpAcpt memId -> o ["memberId" .= memId]
|
||||
XGrpLinkInv groupLinkInv -> o ["groupLinkInvitation" .= groupLinkInv]
|
||||
XGrpLinkReject groupLinkRjct -> o ["groupLinkRejection" .= groupLinkRjct]
|
||||
XGrpLinkMem profile -> o ["profile" .= profile]
|
||||
XGrpLinkMem profile memberKey -> o $ ("memberKey" .=? memberKey) ["profile" .= profile]
|
||||
XGrpLinkAcpt acceptance role memberId -> o ["acceptance" .= acceptance, "role" .= role, "memberId" .= memberId]
|
||||
XGrpRelayInv groupRelayInv -> o ["groupRelayInvitation" .= groupRelayInv]
|
||||
XGrpRelayAcpt relayLink -> o ["relayLink" .= relayLink]
|
||||
XGrpRelayAcpt relayLink memberKey -> o ["relayLink" .= relayLink, "memberKey" .= memberKey]
|
||||
XGrpMemNew memInfo scope -> o $ ("scope" .=? scope) ["memberInfo" .= memInfo]
|
||||
XGrpMemIntro memInfo memRestrictions -> o $ ("memberRestrictions" .=? memRestrictions) ["memberInfo" .= memInfo]
|
||||
XGrpMemInv memId memIntro -> o ["memberId" .= memId, "memberIntro" .= memIntro]
|
||||
@@ -1436,10 +1436,3 @@ $(JQ.deriveJSON defaultJSON ''PublicGroupData)
|
||||
|
||||
$(JQ.deriveJSON defaultJSON ''GroupShortLinkData)
|
||||
|
||||
data RelayShortLinkData = RelayShortLinkData
|
||||
{ relayProfile :: Profile
|
||||
}
|
||||
deriving (Show)
|
||||
|
||||
$(JQ.deriveJSON defaultJSON ''RelayShortLinkData)
|
||||
|
||||
|
||||
@@ -88,9 +88,6 @@ module Simplex.Chat.Store.Groups
|
||||
updateRelayStatus,
|
||||
updateRelayStatusFromTo,
|
||||
setRelayLinkAccepted,
|
||||
setRelayLinkConfId,
|
||||
getRelayConfId,
|
||||
updateRelayMemberData,
|
||||
setGroupInProgressDone,
|
||||
createRelayRequestGroup,
|
||||
updateRelayOwnStatusFromTo,
|
||||
@@ -200,7 +197,7 @@ import Simplex.Chat.Types.MemberRelations (IntroductionDirection (..), MemberRel
|
||||
import Simplex.Chat.Types.Preferences
|
||||
import Simplex.Chat.Types.Shared
|
||||
import Simplex.Chat.Types.UITheme
|
||||
import Simplex.Messaging.Agent.Protocol (ConfirmationId, ConnId, CreatedConnLink (..), InvitationId, OwnerAuth (..), UserId)
|
||||
import Simplex.Messaging.Agent.Protocol (ConnId, CreatedConnLink (..), InvitationId, OwnerAuth (..), UserId)
|
||||
import Simplex.Messaging.Agent.Store.AgentStore (firstRow, fromOnlyBI, maybeFirstRow)
|
||||
import Simplex.Messaging.Agent.Store.DB (Binary (..), BoolInt (..))
|
||||
import Simplex.Messaging.Agent.Store.Entity (DBEntityId)
|
||||
@@ -1420,74 +1417,26 @@ updateRelayStatus_ db relayId relayStatus = do
|
||||
currentTs <- getCurrentTime
|
||||
DB.execute db "UPDATE group_relays SET relay_status = ?, updated_at = ? WHERE group_relay_id = ?" (relayStatus, currentTs, relayId)
|
||||
|
||||
setRelayLinkAccepted :: DB.Connection -> VersionRangeChat -> User -> GroupMember -> MemberKey -> Profile -> ExceptT StoreError IO (GroupMember, GroupRelay)
|
||||
setRelayLinkAccepted db vr user m (MemberKey relayKey) profile = do
|
||||
let gmId = groupMemberId' m
|
||||
currentTs <- liftIO getCurrentTime
|
||||
liftIO $ DB.execute
|
||||
db
|
||||
[sql|
|
||||
UPDATE group_relays
|
||||
SET relay_status = ?, updated_at = ?
|
||||
WHERE group_member_id = ?
|
||||
|]
|
||||
(RSAccepted, currentTs, gmId)
|
||||
liftIO $ DB.execute
|
||||
db
|
||||
[sql|
|
||||
UPDATE group_members
|
||||
SET member_pub_key = ?, updated_at = ?
|
||||
WHERE group_member_id = ?
|
||||
|]
|
||||
(relayKey, currentTs, gmId)
|
||||
void $ updateMemberProfile db user m profile
|
||||
(,) <$> getGroupMemberById db vr user gmId <*> getGroupRelayByGMId db gmId
|
||||
|
||||
setRelayLinkConfId :: DB.Connection -> GroupMember -> ConfirmationId -> ShortLinkContact -> IO ()
|
||||
setRelayLinkConfId db m confId relayLink = do
|
||||
setRelayLinkAccepted :: DB.Connection -> GroupRelay -> ShortLinkContact -> MemberKey -> IO GroupRelay
|
||||
setRelayLinkAccepted db relay@GroupRelay {groupRelayId, groupMemberId} relayLink (MemberKey k) = do
|
||||
currentTs <- getCurrentTime
|
||||
DB.execute
|
||||
db
|
||||
[sql|
|
||||
UPDATE group_relays
|
||||
SET conf_id = ?, relay_link = ?, updated_at = ?
|
||||
WHERE group_member_id = ?
|
||||
SET relay_link = ?, relay_status = ?, updated_at = ?
|
||||
WHERE group_relay_id = ?
|
||||
|]
|
||||
(confId, relayLink, currentTs, groupMemberId' m)
|
||||
(relayLink, RSAccepted, currentTs, groupRelayId)
|
||||
DB.execute
|
||||
db
|
||||
[sql|
|
||||
UPDATE group_members
|
||||
SET relay_link = ?, updated_at = ?
|
||||
SET relay_link = ?, member_pub_key = ?, updated_at = ?
|
||||
WHERE group_member_id = ?
|
||||
|]
|
||||
(relayLink, currentTs, groupMemberId' m)
|
||||
|
||||
getRelayConfId :: DB.Connection -> GroupMember -> ExceptT StoreError IO ConfirmationId
|
||||
getRelayConfId db m =
|
||||
ExceptT . firstRow fromOnly (SEGroupRelayNotFoundByMemberId $ groupMemberId' m) $
|
||||
DB.query
|
||||
db
|
||||
[sql|
|
||||
SELECT conf_id
|
||||
FROM group_relays
|
||||
WHERE group_member_id = ? AND conf_id IS NOT NULL
|
||||
|]
|
||||
(Only (groupMemberId' m))
|
||||
|
||||
updateRelayMemberData :: DB.Connection -> User -> GroupMember -> MemberId -> MemberKey -> Profile -> ExceptT StoreError IO ()
|
||||
updateRelayMemberData db user m memberId (MemberKey relayKey) profile = do
|
||||
currentTs <- liftIO getCurrentTime
|
||||
liftIO $
|
||||
DB.execute
|
||||
db
|
||||
[sql|
|
||||
UPDATE group_members
|
||||
SET member_id = ?, member_pub_key = ?, updated_at = ?
|
||||
WHERE group_member_id = ?
|
||||
|]
|
||||
(memberId, relayKey, currentTs, groupMemberId' m)
|
||||
void $ updateMemberProfile db user m profile
|
||||
(relayLink, k, currentTs, groupMemberId)
|
||||
pure relay {relayStatus = RSAccepted, relayLink = Just relayLink}
|
||||
|
||||
setGroupInProgressDone :: DB.Connection -> GroupInfo -> IO ()
|
||||
setGroupInProgressDone db GroupInfo {groupId} = do
|
||||
@@ -2902,13 +2851,14 @@ getXGrpLinkMemReceived db mId =
|
||||
ExceptT . firstRow fromOnlyBI (SEGroupMemberNotFound mId) $
|
||||
DB.query db "SELECT xgrplinkmem_received FROM group_members WHERE group_member_id = ?" (Only mId)
|
||||
|
||||
setXGrpLinkMemReceived :: DB.Connection -> GroupMemberId -> Bool -> IO ()
|
||||
setXGrpLinkMemReceived db mId xGrpLinkMemReceived = do
|
||||
setXGrpLinkMemReceived :: DB.Connection -> GroupMemberId -> Bool -> Maybe MemberKey -> IO ()
|
||||
setXGrpLinkMemReceived db mId xGrpLinkMemReceived memberKey_ = do
|
||||
currentTs <- getCurrentTime
|
||||
let k = (\(MemberKey k') -> k') <$> memberKey_
|
||||
DB.execute
|
||||
db
|
||||
"UPDATE group_members SET xgrplinkmem_received = ?, updated_at = ? WHERE group_member_id = ?"
|
||||
(BI xGrpLinkMemReceived, currentTs, mId)
|
||||
"UPDATE group_members SET xgrplinkmem_received = ?, member_pub_key = ?, updated_at = ? WHERE group_member_id = ?"
|
||||
(BI xGrpLinkMemReceived, k, currentTs, mId)
|
||||
|
||||
createNewUnknownGroupMember :: DB.Connection -> VersionRangeChat -> User -> GroupInfo -> MemberId -> Text -> GroupMemberRole -> ExceptT StoreError IO GroupMember
|
||||
createNewUnknownGroupMember db vr user@User {userId, userContactId} GroupInfo {groupId} memberId memberName unknownMemberRole = do
|
||||
|
||||
@@ -54,7 +54,6 @@ CREATE TABLE group_relays(
|
||||
chat_relay_id BIGINT NOT NULL REFERENCES chat_relays ON DELETE CASCADE,
|
||||
relay_status TEXT NOT NULL,
|
||||
relay_link BYTEA,
|
||||
conf_id BYTEA,
|
||||
created_at TEXT NOT NULL DEFAULT (now()),
|
||||
updated_at TEXT NOT NULL DEFAULT (now())
|
||||
);
|
||||
|
||||
@@ -5,6 +5,10 @@ module Simplex.Chat.Store.SQLite.Migrations.M20250813_delivery_tasks where
|
||||
import Database.SQLite.Simple (Query)
|
||||
import Database.SQLite.Simple.QQ (sql)
|
||||
|
||||
-- TODO [relays] add later in new migration for MemberProfileUpdate delivery jobs:
|
||||
-- TODO - ALTER TABLE group_members ADD COLUMN last_profile_delivery_ts TEXT;
|
||||
-- TODO - ALTER TABLE group_members ADD COLUMN join_ts TEXT;
|
||||
|
||||
-- How columns correspond to types:
|
||||
|
||||
-- both tables:
|
||||
|
||||
@@ -67,7 +67,6 @@ CREATE TABLE group_relays(
|
||||
chat_relay_id INTEGER NOT NULL REFERENCES chat_relays ON DELETE CASCADE,
|
||||
relay_status TEXT NOT NULL,
|
||||
relay_link BLOB,
|
||||
conf_id BLOB,
|
||||
created_at TEXT NOT NULL DEFAULT(datetime('now')),
|
||||
updated_at TEXT NOT NULL DEFAULT(datetime('now'))
|
||||
) STRICT;
|
||||
|
||||
@@ -3472,14 +3472,6 @@ Query:
|
||||
Plan:
|
||||
SEARCH commands USING INTEGER PRIMARY KEY (rowid=?)
|
||||
|
||||
Query:
|
||||
SELECT conf_id
|
||||
FROM group_relays
|
||||
WHERE group_member_id = ? AND conf_id IS NOT NULL
|
||||
|
||||
Plan:
|
||||
SEARCH group_relays USING INDEX idx_group_relays_group_member_id (group_member_id=?)
|
||||
|
||||
Query:
|
||||
SELECT connection_id, agent_conn_id, conn_level, via_contact, via_user_contact_link, via_group_link, group_link_id, xcontact_id, custom_user_profile_id,
|
||||
conn_status, conn_type, contact_conn_initiated, local_alias, contact_id, group_member_id, user_contact_link_id,
|
||||
@@ -3919,14 +3911,6 @@ Query:
|
||||
Plan:
|
||||
SEARCH group_members USING INTEGER PRIMARY KEY (rowid=?)
|
||||
|
||||
Query:
|
||||
UPDATE group_members
|
||||
SET member_id = ?, member_pub_key = ?, updated_at = ?
|
||||
WHERE group_member_id = ?
|
||||
|
||||
Plan:
|
||||
SEARCH group_members USING INTEGER PRIMARY KEY (rowid=?)
|
||||
|
||||
Query:
|
||||
UPDATE group_members
|
||||
SET member_relations_vector = ?
|
||||
@@ -4895,14 +4879,6 @@ Query:
|
||||
Plan:
|
||||
SEARCH contacts USING INTEGER PRIMARY KEY (rowid=?)
|
||||
|
||||
Query:
|
||||
UPDATE group_members
|
||||
SET member_pub_key = ?, updated_at = ?
|
||||
WHERE group_member_id = ?
|
||||
|
||||
Plan:
|
||||
SEARCH group_members USING INTEGER PRIMARY KEY (rowid=?)
|
||||
|
||||
Query:
|
||||
UPDATE group_members
|
||||
SET member_relations_vector = ?, updated_at = ?
|
||||
@@ -4945,7 +4921,7 @@ SEARCH group_members USING INTEGER PRIMARY KEY (rowid=?)
|
||||
|
||||
Query:
|
||||
UPDATE group_members
|
||||
SET relay_link = ?, updated_at = ?
|
||||
SET relay_link = ?, member_pub_key = ?, updated_at = ?
|
||||
WHERE group_member_id = ?
|
||||
|
||||
Plan:
|
||||
@@ -4988,19 +4964,11 @@ SEARCH groups USING INTEGER PRIMARY KEY (rowid=?)
|
||||
|
||||
Query:
|
||||
UPDATE group_relays
|
||||
SET conf_id = ?, relay_link = ?, updated_at = ?
|
||||
WHERE group_member_id = ?
|
||||
SET relay_link = ?, relay_status = ?, updated_at = ?
|
||||
WHERE group_relay_id = ?
|
||||
|
||||
Plan:
|
||||
SEARCH group_relays USING INDEX idx_group_relays_group_member_id (group_member_id=?)
|
||||
|
||||
Query:
|
||||
UPDATE group_relays
|
||||
SET relay_status = ?, updated_at = ?
|
||||
WHERE group_member_id = ?
|
||||
|
||||
Plan:
|
||||
SEARCH group_relays USING INDEX idx_group_relays_group_member_id (group_member_id=?)
|
||||
SEARCH group_relays USING INTEGER PRIMARY KEY (rowid=?)
|
||||
|
||||
Query:
|
||||
UPDATE group_snd_item_statuses
|
||||
@@ -6991,7 +6959,7 @@ Query: UPDATE group_members SET support_chat_ts = ? WHERE group_member_id = ?
|
||||
Plan:
|
||||
SEARCH group_members USING INTEGER PRIMARY KEY (rowid=?)
|
||||
|
||||
Query: UPDATE group_members SET xgrplinkmem_received = ?, updated_at = ? WHERE group_member_id = ?
|
||||
Query: UPDATE group_members SET xgrplinkmem_received = ?, member_pub_key = ?, updated_at = ? WHERE group_member_id = ?
|
||||
Plan:
|
||||
SEARCH group_members USING INTEGER PRIMARY KEY (rowid=?)
|
||||
|
||||
|
||||
@@ -765,7 +765,6 @@ CREATE TABLE group_relays(
|
||||
chat_relay_id INTEGER NOT NULL REFERENCES chat_relays ON DELETE CASCADE,
|
||||
relay_status TEXT NOT NULL,
|
||||
relay_link BLOB,
|
||||
conf_id BLOB,
|
||||
created_at TEXT NOT NULL DEFAULT(datetime('now')),
|
||||
updated_at TEXT NOT NULL DEFAULT(datetime('now'))
|
||||
) STRICT;
|
||||
|
||||
@@ -121,6 +121,7 @@ instance ToField AgentUserId where toField (AgentUserId uId) = toField uId
|
||||
aUserId :: User -> UserId
|
||||
aUserId User {agentUserId = AgentUserId uId} = uId
|
||||
|
||||
-- TODO [relays] filter out chat relay users where necessary (e.g. loading list of users for UI)
|
||||
data User = User
|
||||
{ userId :: UserId,
|
||||
agentUserId :: AgentUserId,
|
||||
@@ -1855,8 +1856,7 @@ data CommandFunction
|
||||
| CFAckMessage -- not used
|
||||
| CFDeleteConn -- not used
|
||||
| CFSetShortLink
|
||||
| CFGetRelayDataJoin
|
||||
| CFGetRelayDataAccept
|
||||
| CFGetShortLink
|
||||
deriving (Eq, Show)
|
||||
|
||||
instance FromField CommandFunction where fromField = fromTextField_ textDecode
|
||||
@@ -1875,8 +1875,7 @@ instance TextEncoding CommandFunction where
|
||||
"ack_message" -> Just CFAckMessage
|
||||
"delete_conn" -> Just CFDeleteConn
|
||||
"set_short_link" -> Just CFSetShortLink
|
||||
"get_relay_data_join" -> Just CFGetRelayDataJoin
|
||||
"get_relay_data_accept" -> Just CFGetRelayDataAccept
|
||||
"get_short_link" -> Just CFGetShortLink
|
||||
_ -> Nothing
|
||||
textEncode = \case
|
||||
CFCreateConnGrpMemInv -> "create_conn"
|
||||
@@ -1889,8 +1888,7 @@ instance TextEncoding CommandFunction where
|
||||
CFAckMessage -> "ack_message"
|
||||
CFDeleteConn -> "delete_conn"
|
||||
CFSetShortLink -> "set_short_link"
|
||||
CFGetRelayDataJoin -> "get_relay_data_join"
|
||||
CFGetRelayDataAccept -> "get_relay_data_accept"
|
||||
CFGetShortLink -> "get_short_link"
|
||||
|
||||
commandExpectedResponse :: CommandFunction -> AEvtTag
|
||||
commandExpectedResponse = \case
|
||||
@@ -1904,8 +1902,7 @@ commandExpectedResponse = \case
|
||||
CFAckMessage -> t OK_
|
||||
CFDeleteConn -> t OK_
|
||||
CFSetShortLink -> t LINK_
|
||||
CFGetRelayDataJoin -> t LDATA_
|
||||
CFGetRelayDataAccept -> t LDATA_
|
||||
CFGetShortLink -> t LDATA_
|
||||
where
|
||||
t = AEvtTag SAEConn
|
||||
|
||||
|
||||
@@ -474,7 +474,6 @@ chatEventToView hu ChatConfig {logLevel, showReactions, showReceipts, testView}
|
||||
CEvtGroupLinkDataUpdated u g groupLink relays relaysChanged
|
||||
| relaysChanged -> ttyUser u $ viewGroupLinkRelaysUpdated g groupLink relays
|
||||
| otherwise -> []
|
||||
CEvtGroupRelayUpdated {} -> []
|
||||
CEvtJoinedGroupMember u g m -> ttyUser u $ viewJoinedGroupMember g m
|
||||
CEvtHostConnected p h -> [plain $ "connected to " <> viewHostEvent p h]
|
||||
CEvtHostDisconnected p h -> [plain $ "disconnected from " <> viewHostEvent p h]
|
||||
@@ -2063,7 +2062,7 @@ viewConnectionPlan ChatConfig {logLevel, testView} _connLink = \case
|
||||
GLPOk groupSLinkInfo_ groupSLinkData ->
|
||||
let direct = maybe True (\(GroupShortLinkInfo {direct = d}) -> d) groupSLinkInfo_
|
||||
in [grpLink $ if direct then "ok to connect directly" else "ok to connect via relays"]
|
||||
<> [viewJSON groupSLinkData | testView]
|
||||
<> [viewJSON groupSLinkData] -- | testView] -- TODO [relays] disable link data output in cli (uncomment testView)
|
||||
GLPOwnLink g -> [grpLink "own link for group " <> ttyGroup' g]
|
||||
GLPConnectingConfirmReconnect -> [grpLink "connecting, allowed to reconnect"]
|
||||
GLPConnectingProhibit Nothing -> [grpLink "connecting"]
|
||||
|
||||
+1
-1
@@ -210,7 +210,7 @@ testCfg =
|
||||
shortLinkPresetServers = ["smp://LcJUMfVhwD8yxjAiSaDzzGF3-kLG4Uh0Fl_ZIjrRwjI=@localhost:7001"],
|
||||
testView = True,
|
||||
tbqSize = 16,
|
||||
channelSubscriberRole = GRMember, -- starting role is GRMember to test members sending messages
|
||||
channelSubscriberRole = GRMember,
|
||||
confirmMigrations = MCYesUp
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user