core: support contact addresses with DR keys, service requests (#7310)

* core: use double ratchet keys in contact address (#7278)

* core: use double ratchet keys in contact address

* use PQ from the first message

* query plans

* update simplexmq

* api to rotate keys, option to show full links in CLI

* shorter description

* ui: add error parameters

* disable DR in addresses

* core: parameter for create address command to configure ratchet keys

* add pqRatchet param to address-related commands

* query plan

* fix parser

* fix kotlin

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>

* core: contact request rejection and service requests (#7292)

* update simplexmq

* implement service requests and rejections

* tests

* migration

* fix migration

* add api event and response

* bot api, postgres migration

* nix shas

* bot types, rename property

* update bot type

* sign service requests

* update bots api

* query plan

* update plan

* update simplexmq

* fix test, update bot api

* fix bot api

* resolve name for service request

* refactor

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>

* update simplexmq

* update simplexmq

* test delays

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
This commit is contained in:
Evgeny
2026-08-01 12:51:03 +01:00
committed by GitHub
co-authored by Evgeny @ SimpleX Chat
parent 61012d208e
commit e1a349b90f
55 changed files with 1229 additions and 248 deletions
+19 -9
View File
@@ -90,7 +90,7 @@ import Simplex.Messaging.Crypto.Ratchet (PQEncryption)
import Simplex.Messaging.Encoding.String
import Simplex.Messaging.Notifications.Protocol (DeviceToken (..), NtfTknStatus)
import Simplex.Messaging.Parsers (defaultJSON, dropPrefix, enumJSON, parseAll, parseString, sumTypeJSON)
import Simplex.Messaging.Protocol (AProtoServerWithAuth, AProtocolType (..), MsgId, NMsgMeta (..), NtfServer, ProtocolType (..), QueueId, SMPMsgMeta (..), SMPServerWithAuth, SubscriptionMode (..), XFTPServer)
import Simplex.Messaging.Protocol (AProtoServerWithAuth, AProtocolType (..), MsgId, NMsgMeta (..), NtfServer, ProtocolType (..), QueueId, SMPMsgMeta (..), SubscriptionMode (..), XFTPServer)
import Simplex.Messaging.TMap (TMap)
import Simplex.Messaging.Transport (TLS, TransportPeer (..), simplexMQVersion)
import Simplex.Messaging.Transport.Client (SocksProxyWithAuth, TransportHost)
@@ -152,6 +152,7 @@ data ChatConfig = ChatConfig
inlineFiles :: InlineFilesConfig,
autoAcceptFileSize :: Integer,
showReactions :: Bool,
showFullLinks :: Bool,
showReceipts :: Bool,
subscriptionEvents :: Bool,
hostEvents :: Bool,
@@ -288,6 +289,7 @@ data ChatController = ChatController
inputQ :: TBQueue String,
outputQ :: TBQueue (Maybe RemoteHostId, Either ChatError ChatEvent),
subscriptionMode :: TVar SubscriptionMode,
processServiceRequests :: TVar Bool,
chatLock :: Lock,
entityLocks :: TMap ChatLockEntity Lock,
sndFiles :: TVar (Map Int64 Handle),
@@ -347,7 +349,7 @@ data ChatCommand
| SetClientService UserId ContactName Bool
| APIDeleteUser {userId :: UserId, delSMPQueues :: Bool, viewPwd :: Maybe UserPwd}
| DeleteUser UserName Bool (Maybe UserPwd)
| StartChat {mainApp :: Bool, enableSndFiles :: Bool} -- enableSndFiles has no effect when mainApp is True
| StartChat {mainApp :: Bool, enableSndFiles :: Bool, serviceRequests :: Bool} -- enableSndFiles has no effect when mainApp is True
| CheckChatRunning
| APIStopChat
| APIActivateChat {restoreChat :: Bool}
@@ -407,7 +409,9 @@ data ChatCommand
| APIDeleteChat {chatRef :: ChatRef, chatDeleteMode :: ChatDeleteMode} -- currently delete mode settings are only applied to direct chats
| APIClearChat {chatRef :: ChatRef}
| APIAcceptContact {incognito :: IncognitoEnabled, contactReqId :: Int64}
| APIRejectContact {contactReqId :: Int64}
| APIRejectContact {contactReqId :: Int64, notify :: Bool}
| APISendServiceRequest {userId :: UserId, sendTarget :: ConnectTarget 'CMContact, requestTimeout :: Maybe NominalDiffTime, signKey :: Maybe (C.StoredPrivateKey 'C.Ed25519), request :: J.Object}
| APISendServiceResponse {userId :: UserId, requestId :: AgentInvId, responseData :: J.Object}
| APISendCallInvitation ContactId CallType
| SendCallInvitation ContactName CallType
| APIRejectCall ContactId
@@ -547,19 +551,20 @@ data ChatCommand
| ClearContact ContactName
| APIListContacts {userId :: UserId}
| ListContacts
| APICreateMyAddress {userId :: UserId, server_ :: Maybe SMPServerWithAuth}
| CreateMyAddress
| APICreateMyAddress {userId :: UserId, server_ :: Maybe SMPServerWithAuth, pqRatchet :: Maybe Bool}
| CreateMyAddress {pqRatchet :: Maybe Bool}
| APIDeleteMyAddress {userId :: UserId}
| DeleteMyAddress
| APIShowMyAddress {userId :: UserId}
| ShowMyAddress
| APIAddMyAddressShortLink UserId
| APIAddMyAddressShortLink {userId :: UserId, pqRatchet :: Maybe Bool}
| APIRotateAddressRatchetKeys UserId
| APISetProfileAddress {userId :: UserId, enable :: Bool}
| SetProfileAddress Bool
| APISetAddressSettings {userId :: UserId, settings :: AddressSettings}
| SetAddressSettings AddressSettings
| APISetAddressSettings {userId :: UserId, pqRatchet :: Maybe Bool, settings :: AddressSettings}
| SetAddressSettings {pqRatchet :: Maybe Bool, settings :: AddressSettings}
| AcceptContact IncognitoEnabled ContactName
| RejectContact ContactName
| RejectContact ContactName Bool
| ForwardMessage {toChatName :: ChatName, fromContactName :: ContactName, forwardedMsg :: Text}
| ForwardGroupMessage {toChatName :: ChatName, fromGroupName :: GroupName, fromMemberName_ :: Maybe ContactName, forwardedMsg :: Text}
| ForwardLocalMessage {toChatName :: ChatName, forwardedMsg :: Text}
@@ -826,6 +831,8 @@ data ChatResponse
| CRUserContactLink {user :: User, contactLink :: UserContactLink}
| CRUserContactLinkUpdated {user :: User, contactLink :: UserContactLink}
| CRContactRequestRejected {user :: User, contactRequest :: UserContactRequest, contact_ :: Maybe Contact}
| CRServiceResponse {user :: User, responseData :: J.Object}
| CRServiceReplyAccepted {user :: User, connectionId :: AgentConnId}
| CRUserAcceptedGroupSent {user :: User, groupInfo :: GroupInfo, hostContact :: Maybe Contact}
| CRUserDeletedMembers {user :: User, groupInfo :: GroupInfo, members :: [GroupMember], withMessages :: Bool, msgSigned :: Bool}
| CRGroupsList {user :: User, groups :: [GroupInfo]}
@@ -941,6 +948,9 @@ data ChatEvent
| CEvtGroupMemberUpdated {user :: User, groupInfo :: GroupInfo, fromMember :: GroupMember, toMember :: GroupMember}
| CEvtContactDeletedByContact {user :: User, contact :: Contact}
| CEvtReceivedContactRequest {user :: User, contactRequest :: UserContactRequest, chat_ :: Maybe AChat}
| CEvtServiceRequest {user :: User, requestId :: AgentInvId, signerKey :: Maybe C.PublicKeyEd25519, requestData :: J.Object}
| CEvtServiceReplySent {connectionId :: AgentConnId}
| CEvtContactRequestRejected {user :: User, contact :: Contact, rejectionReason :: Maybe ContactRejectionReason}
| CEvtAcceptingContactRequest {user :: User, contact :: Contact} -- there is the same command response
| CEvtAcceptingBusinessRequest {user :: User, groupInfo :: GroupInfo}
| CEvtContactRequestAlreadyAccepted {user :: User, contact :: Contact}