fix_:sync contact request decision (#5130)

* fix_:sync contact request decision

* chore_:optimise test

* chore_:address feedback from review
This commit is contained in:
frank 2024-05-15 08:01:47 +08:00 committed by GitHub
parent c46e395a58
commit 3b5eab3bf1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 2779 additions and 4317 deletions

View File

@ -951,19 +951,19 @@ func (db sqlitePersistence) LatestPendingContactRequestIDForContact(contactID st
return id, nil
}
func (db sqlitePersistence) LatestContactRequestIDs() (map[string]common.ContactRequestState, error) {
res := map[string]common.ContactRequestState{}
func (db sqlitePersistence) LatestContactRequests() ([]LatestContactRequest, error) {
res := make([]LatestContactRequest, 0)
rows, err := db.db.Query(
fmt.Sprintf(
`
SELECT
id, contact_request_state
id, contact_request_state, local_chat_id
FROM
user_messages m1
WHERE
m1.content_type = ?
ORDER BY %s DESC
LIMIT 20
LIMIT 200
`, cursor), protobuf.ChatMessage_CONTACT_REQUEST)
if err != nil {
@ -975,12 +975,17 @@ func (db sqlitePersistence) LatestContactRequestIDs() (map[string]common.Contact
for rows.Next() {
var id string
var contactRequestState sql.NullInt64
err := rows.Scan(&id, &contactRequestState)
var localChatID string
err := rows.Scan(&id, &contactRequestState, &localChatID)
if err != nil {
return nil, err
}
res[id] = common.ContactRequestState(contactRequestState.Int64)
res = append(res, LatestContactRequest{
MessageID: id,
ContactRequestState: common.ContactRequestState(contactRequestState.Int64),
ContactID: localChatID,
})
}
return res, nil

View File

@ -219,6 +219,12 @@ type EnvelopeEventsInterceptor struct {
Messenger *Messenger
}
type LatestContactRequest struct {
MessageID string
ContactRequestState common.ContactRequestState
ContactID string
}
func (m *Messenger) GetOwnPrimaryName() (string, error) {
ensName, err := m.settings.ENSName()
if err != nil {
@ -2714,22 +2720,10 @@ func (m *Messenger) SyncDevices(ctx context.Context, ensName, photoPath string,
return err
}
ids, err := m.persistence.LatestContactRequestIDs()
if err != nil {
if err = m.syncLatestContactRequests(ctx, rawMessageHandler); err != nil {
return err
}
for id, state := range ids {
if state == common.ContactRequestStateAccepted || state == common.ContactRequestStateDismissed {
accepted := state == common.ContactRequestStateAccepted
err := m.syncContactRequestDecision(ctx, id, accepted, rawMessageHandler)
if err != nil {
return err
}
}
}
// we have to sync deleted keypairs as well
keypairs, err := m.settings.GetAllKeypairs()
if err != nil {
@ -2796,7 +2790,26 @@ func (m *Messenger) SyncDevices(ctx context.Context, ensName, photoPath string,
return nil
}
func (m *Messenger) syncContactRequestDecision(ctx context.Context, requestID string, accepted bool, rawMessageHandler RawMessageHandler) error {
func (m *Messenger) syncLatestContactRequests(ctx context.Context, rawMessageHandler RawMessageHandler) error {
latestContactRequests, err := m.persistence.LatestContactRequests()
if err != nil {
return err
}
for _, r := range latestContactRequests {
if r.ContactRequestState == common.ContactRequestStateAccepted || r.ContactRequestState == common.ContactRequestStateDismissed {
accepted := r.ContactRequestState == common.ContactRequestStateAccepted
err = m.syncContactRequestDecision(ctx, r.MessageID, r.ContactID, accepted, rawMessageHandler)
if err != nil {
return err
}
}
}
return nil
}
func (m *Messenger) syncContactRequestDecision(ctx context.Context, requestID, contactId string, accepted bool, rawMessageHandler RawMessageHandler) error {
m.logger.Info("syncContactRequestDecision", zap.Any("from", requestID))
if !m.hasPairedDevices() {
return nil
@ -2813,6 +2826,7 @@ func (m *Messenger) syncContactRequestDecision(ctx context.Context, requestID st
message := &protobuf.SyncContactRequestDecision{
RequestId: requestID,
ContactId: contactId,
Clock: clock,
DecisionStatus: status,
}

View File

@ -153,7 +153,7 @@ func (m *Messenger) AcceptContactRequest(ctx context.Context, request *requests.
return nil, err
}
err = m.syncContactRequestDecision(ctx, request.ID.String(), true, m.dispatchMessage)
err = m.syncContactRequestDecision(ctx, request.ID.String(), "", true, m.dispatchMessage)
if err != nil {
return nil, err
}
@ -161,19 +161,33 @@ func (m *Messenger) AcceptContactRequest(ctx context.Context, request *requests.
return response, nil
}
func (m *Messenger) declineContactRequest(requestID string, fromSyncing bool) (*MessengerResponse, error) {
func (m *Messenger) declineContactRequest(requestID, contactID string, fromSyncing bool) (*MessengerResponse, error) {
m.logger.Info("declineContactRequest")
contactRequest, err := m.persistence.MessageByID(requestID)
if err != nil {
return nil, err
}
contact, err := m.BuildContact(&requests.BuildContact{PublicKey: contactRequest.From})
contactRequest, err := m.persistence.MessageByID(requestID)
if err == common.ErrRecordNotFound && fromSyncing {
// original requestID(Message ID) is useless since we don't sync UserMessage in this case
requestID = defaultContactRequestID(contactID)
contactRequest, err = m.persistence.MessageByID(requestID)
}
if err != nil {
return nil, err
}
response := &MessengerResponse{}
var contact *Contact
if contactRequest != nil {
contact, err = m.BuildContact(&requests.BuildContact{PublicKey: contactRequest.From})
if err != nil {
return nil, err
}
contactRequest.ContactRequestState = common.ContactRequestStateDismissed
err = m.persistence.SetContactRequestState(contactRequest.ID, contactRequest.ContactRequestState)
if err != nil {
return nil, err
}
response.AddMessage(contactRequest)
}
if !fromSyncing {
_, clock, err := m.getOneToOneAndNextClock(contact)
@ -189,15 +203,9 @@ func (m *Messenger) declineContactRequest(requestID string, fromSyncing bool) (*
response.AddContact(contact)
}
contactRequest.ContactRequestState = common.ContactRequestStateDismissed
err = m.persistence.SetContactRequestState(contactRequest.ID, contactRequest.ContactRequestState)
if err != nil {
return nil, err
}
// update notification with the correct status
notification, err := m.persistence.GetActivityCenterNotificationByID(types.FromHex(contactRequest.ID))
notification, err := m.persistence.GetActivityCenterNotificationByID(types.FromHex(requestID))
if err != nil {
return nil, err
}
@ -214,7 +222,6 @@ func (m *Messenger) declineContactRequest(requestID string, fromSyncing bool) (*
return nil, err
}
}
response.AddMessage(contactRequest)
return response, nil
}
@ -224,12 +231,12 @@ func (m *Messenger) DeclineContactRequest(ctx context.Context, request *requests
return nil, err
}
response, err := m.declineContactRequest(request.ID.String(), false)
response, err := m.declineContactRequest(request.ID.String(), "", false)
if err != nil {
return nil, err
}
err = m.syncContactRequestDecision(ctx, request.ID.String(), false, m.dispatchMessage)
err = m.syncContactRequestDecision(ctx, request.ID.String(), "", false, m.dispatchMessage)
if err != nil {
return nil, err
}
@ -273,11 +280,15 @@ func (m *Messenger) SendContactRequest(ctx context.Context, request *requests.Se
)
}
func (m *Messenger) updateAcceptedContactRequest(response *MessengerResponse, contactRequestID string, fromSyncing bool) (*MessengerResponse, error) {
m.logger.Debug("updateAcceptedContactRequest", zap.String("contactRequestID", contactRequestID))
func (m *Messenger) updateAcceptedContactRequest(response *MessengerResponse, contactRequestID, contactID string, fromSyncing bool) (*MessengerResponse, error) {
m.logger.Debug("updateAcceptedContactRequest", zap.String("contactRequestID", contactRequestID), zap.String("contactID", contactID), zap.Bool("fromSyncing", fromSyncing))
contactRequest, err := m.persistence.MessageByID(contactRequestID)
if err == common.ErrRecordNotFound && fromSyncing {
// original requestID(Message ID) is useless since we don't sync UserMessage in this case
contactRequestID = defaultContactRequestID(contactID)
contactRequest, err = m.persistence.MessageByID(contactRequestID)
}
if err != nil {
m.logger.Error("contact request not found", zap.String("contactRequestID", contactRequestID), zap.Error(err))
return nil, err
@ -493,7 +504,7 @@ func (m *Messenger) addContact(ctx context.Context,
}
if len(contactRequestID) != 0 {
updatedResponse, err := m.updateAcceptedContactRequest(response, contactRequestID, false)
updatedResponse, err := m.updateAcceptedContactRequest(response, contactRequestID, "", false)
if err != nil {
return nil, err
}

View File

@ -3784,17 +3784,15 @@ func (m *Messenger) HandleSyncContactRequestDecision(state *ReceivedMessageState
var response *MessengerResponse
if message.DecisionStatus == protobuf.SyncContactRequestDecision_ACCEPTED {
response, err = m.updateAcceptedContactRequest(nil, message.RequestId, true)
response, err = m.updateAcceptedContactRequest(nil, message.RequestId, message.ContactId, true)
} else {
response, err = m.declineContactRequest(message.RequestId, true)
response, err = m.declineContactRequest(message.RequestId, message.ContactId, true)
}
if err != nil {
return err
}
state.Response = response
return nil
return state.Response.Merge(response)
}
func (m *Messenger) HandlePushNotificationRegistration(state *ReceivedMessageState, encryptedRegistration []byte, statusMessage *v1protocol.StatusMessage) error {

View File

@ -279,8 +279,11 @@ func (s *MessengerInstallationSuite) TestSyncInstallation() {
}
allChats = append(allChats, response.Chats()...)
if len(response.Contacts) == 1 {
actualContact = response.Contacts[0]
for _, c := range response.Contacts {
if c.LocalNickname == contact.LocalNickname {
actualContact = c
break
}
}
bookmarks = append(bookmarks, response.GetBookmarks()...)

View File

@ -1,24 +1,24 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.31.0
// protoc v3.20.3
// source: community_privileged_user_sync_message.proto
package protobuf
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
fmt "fmt"
proto "github.com/golang/protobuf/proto"
math "math"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
type CommunityPrivilegedUserSyncMessage_EventType int32
@ -29,250 +29,135 @@ const (
CommunityPrivilegedUserSyncMessage_CONTROL_NODE_ALL_SYNC_REQUESTS_TO_JOIN CommunityPrivilegedUserSyncMessage_EventType = 3
)
// Enum value maps for CommunityPrivilegedUserSyncMessage_EventType.
var (
CommunityPrivilegedUserSyncMessage_EventType_name = map[int32]string{
var CommunityPrivilegedUserSyncMessage_EventType_name = map[int32]string{
0: "UNKNOWN",
1: "CONTROL_NODE_ACCEPT_REQUEST_TO_JOIN",
2: "CONTROL_NODE_REJECT_REQUEST_TO_JOIN",
3: "CONTROL_NODE_ALL_SYNC_REQUESTS_TO_JOIN",
}
CommunityPrivilegedUserSyncMessage_EventType_value = map[string]int32{
var CommunityPrivilegedUserSyncMessage_EventType_value = map[string]int32{
"UNKNOWN": 0,
"CONTROL_NODE_ACCEPT_REQUEST_TO_JOIN": 1,
"CONTROL_NODE_REJECT_REQUEST_TO_JOIN": 2,
"CONTROL_NODE_ALL_SYNC_REQUESTS_TO_JOIN": 3,
}
)
func (x CommunityPrivilegedUserSyncMessage_EventType) Enum() *CommunityPrivilegedUserSyncMessage_EventType {
p := new(CommunityPrivilegedUserSyncMessage_EventType)
*p = x
return p
}
func (x CommunityPrivilegedUserSyncMessage_EventType) String() string {
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
return proto.EnumName(CommunityPrivilegedUserSyncMessage_EventType_name, int32(x))
}
func (CommunityPrivilegedUserSyncMessage_EventType) Descriptor() protoreflect.EnumDescriptor {
return file_community_privileged_user_sync_message_proto_enumTypes[0].Descriptor()
}
func (CommunityPrivilegedUserSyncMessage_EventType) Type() protoreflect.EnumType {
return &file_community_privileged_user_sync_message_proto_enumTypes[0]
}
func (x CommunityPrivilegedUserSyncMessage_EventType) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
// Deprecated: Use CommunityPrivilegedUserSyncMessage_EventType.Descriptor instead.
func (CommunityPrivilegedUserSyncMessage_EventType) EnumDescriptor() ([]byte, []int) {
return file_community_privileged_user_sync_message_proto_rawDescGZIP(), []int{0, 0}
return fileDescriptor_158595055b4cfee2, []int{0, 0}
}
type CommunityPrivilegedUserSyncMessage struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Clock uint64 `protobuf:"varint,1,opt,name=clock,proto3" json:"clock,omitempty"`
Type CommunityPrivilegedUserSyncMessage_EventType `protobuf:"varint,2,opt,name=type,proto3,enum=protobuf.CommunityPrivilegedUserSyncMessage_EventType" json:"type,omitempty"`
CommunityId []byte `protobuf:"bytes,3,opt,name=community_id,json=communityId,proto3" json:"community_id,omitempty"`
RequestToJoin map[string]*CommunityRequestToJoin `protobuf:"bytes,4,rep,name=request_to_join,json=requestToJoin,proto3" json:"request_to_join,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
SyncRequestsToJoin []*SyncCommunityRequestsToJoin `protobuf:"bytes,5,rep,name=sync_requests_to_join,json=syncRequestsToJoin,proto3" json:"sync_requests_to_join,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (x *CommunityPrivilegedUserSyncMessage) Reset() {
*x = CommunityPrivilegedUserSyncMessage{}
if protoimpl.UnsafeEnabled {
mi := &file_community_privileged_user_sync_message_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CommunityPrivilegedUserSyncMessage) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (m *CommunityPrivilegedUserSyncMessage) Reset() { *m = CommunityPrivilegedUserSyncMessage{} }
func (m *CommunityPrivilegedUserSyncMessage) String() string { return proto.CompactTextString(m) }
func (*CommunityPrivilegedUserSyncMessage) ProtoMessage() {}
func (x *CommunityPrivilegedUserSyncMessage) ProtoReflect() protoreflect.Message {
mi := &file_community_privileged_user_sync_message_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CommunityPrivilegedUserSyncMessage.ProtoReflect.Descriptor instead.
func (*CommunityPrivilegedUserSyncMessage) Descriptor() ([]byte, []int) {
return file_community_privileged_user_sync_message_proto_rawDescGZIP(), []int{0}
return fileDescriptor_158595055b4cfee2, []int{0}
}
func (x *CommunityPrivilegedUserSyncMessage) GetClock() uint64 {
if x != nil {
return x.Clock
func (m *CommunityPrivilegedUserSyncMessage) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_CommunityPrivilegedUserSyncMessage.Unmarshal(m, b)
}
func (m *CommunityPrivilegedUserSyncMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_CommunityPrivilegedUserSyncMessage.Marshal(b, m, deterministic)
}
func (m *CommunityPrivilegedUserSyncMessage) XXX_Merge(src proto.Message) {
xxx_messageInfo_CommunityPrivilegedUserSyncMessage.Merge(m, src)
}
func (m *CommunityPrivilegedUserSyncMessage) XXX_Size() int {
return xxx_messageInfo_CommunityPrivilegedUserSyncMessage.Size(m)
}
func (m *CommunityPrivilegedUserSyncMessage) XXX_DiscardUnknown() {
xxx_messageInfo_CommunityPrivilegedUserSyncMessage.DiscardUnknown(m)
}
var xxx_messageInfo_CommunityPrivilegedUserSyncMessage proto.InternalMessageInfo
func (m *CommunityPrivilegedUserSyncMessage) GetClock() uint64 {
if m != nil {
return m.Clock
}
return 0
}
func (x *CommunityPrivilegedUserSyncMessage) GetType() CommunityPrivilegedUserSyncMessage_EventType {
if x != nil {
return x.Type
func (m *CommunityPrivilegedUserSyncMessage) GetType() CommunityPrivilegedUserSyncMessage_EventType {
if m != nil {
return m.Type
}
return CommunityPrivilegedUserSyncMessage_UNKNOWN
}
func (x *CommunityPrivilegedUserSyncMessage) GetCommunityId() []byte {
if x != nil {
return x.CommunityId
func (m *CommunityPrivilegedUserSyncMessage) GetCommunityId() []byte {
if m != nil {
return m.CommunityId
}
return nil
}
func (x *CommunityPrivilegedUserSyncMessage) GetRequestToJoin() map[string]*CommunityRequestToJoin {
if x != nil {
return x.RequestToJoin
func (m *CommunityPrivilegedUserSyncMessage) GetRequestToJoin() map[string]*CommunityRequestToJoin {
if m != nil {
return m.RequestToJoin
}
return nil
}
func (x *CommunityPrivilegedUserSyncMessage) GetSyncRequestsToJoin() []*SyncCommunityRequestsToJoin {
if x != nil {
return x.SyncRequestsToJoin
func (m *CommunityPrivilegedUserSyncMessage) GetSyncRequestsToJoin() []*SyncCommunityRequestsToJoin {
if m != nil {
return m.SyncRequestsToJoin
}
return nil
}
var File_community_privileged_user_sync_message_proto protoreflect.FileDescriptor
var file_community_privileged_user_sync_message_proto_rawDesc = []byte{
0x0a, 0x2c, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x5f, 0x70, 0x72, 0x69, 0x76,
0x69, 0x6c, 0x65, 0x67, 0x65, 0x64, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x73, 0x79, 0x6e, 0x63,
0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x1a, 0x11, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e,
0x69, 0x74, 0x69, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0d, 0x70, 0x61, 0x69,
0x72, 0x69, 0x6e, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe9, 0x04, 0x0a, 0x22, 0x43,
0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x50, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67,
0x65, 0x64, 0x55, 0x73, 0x65, 0x72, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04,
0x52, 0x05, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x4a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18,
0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x36, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x50, 0x72, 0x69, 0x76, 0x69, 0x6c,
0x65, 0x67, 0x65, 0x64, 0x55, 0x73, 0x65, 0x72, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73,
0x61, 0x67, 0x65, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74,
0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79,
0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x6d, 0x75,
0x6e, 0x69, 0x74, 0x79, 0x49, 0x64, 0x12, 0x67, 0x0a, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x5f, 0x74, 0x6f, 0x5f, 0x6a, 0x6f, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32,
0x3f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x75,
0x6e, 0x69, 0x74, 0x79, 0x50, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x64, 0x55, 0x73,
0x65, 0x72, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x6f, 0x4a, 0x6f, 0x69, 0x6e, 0x45, 0x6e, 0x74, 0x72, 0x79,
0x52, 0x0d, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x6f, 0x4a, 0x6f, 0x69, 0x6e, 0x12,
0x58, 0x0a, 0x15, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73,
0x5f, 0x74, 0x6f, 0x5f, 0x6a, 0x6f, 0x69, 0x6e, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f,
0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x54,
0x6f, 0x4a, 0x6f, 0x69, 0x6e, 0x52, 0x12, 0x73, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x73, 0x54, 0x6f, 0x4a, 0x6f, 0x69, 0x6e, 0x1a, 0x62, 0x0a, 0x12, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x54, 0x6f, 0x4a, 0x6f, 0x69, 0x6e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12,
0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65,
0x79, 0x12, 0x36, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x20, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x43, 0x6f, 0x6d, 0x6d,
0x75, 0x6e, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x6f, 0x4a, 0x6f,
0x69, 0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x96, 0x01,
0x0a, 0x09, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55,
0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x27, 0x0a, 0x23, 0x43, 0x4f, 0x4e, 0x54,
0x52, 0x4f, 0x4c, 0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x5f,
0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x5f, 0x54, 0x4f, 0x5f, 0x4a, 0x4f, 0x49, 0x4e, 0x10,
0x01, 0x12, 0x27, 0x0a, 0x23, 0x43, 0x4f, 0x4e, 0x54, 0x52, 0x4f, 0x4c, 0x5f, 0x4e, 0x4f, 0x44,
0x45, 0x5f, 0x52, 0x45, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54,
0x5f, 0x54, 0x4f, 0x5f, 0x4a, 0x4f, 0x49, 0x4e, 0x10, 0x02, 0x12, 0x2a, 0x0a, 0x26, 0x43, 0x4f,
0x4e, 0x54, 0x52, 0x4f, 0x4c, 0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x5f, 0x41, 0x4c, 0x4c, 0x5f, 0x53,
0x59, 0x4e, 0x43, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x53, 0x5f, 0x54, 0x4f, 0x5f,
0x4a, 0x4f, 0x49, 0x4e, 0x10, 0x03, 0x42, 0x0d, 0x5a, 0x0b, 0x2e, 0x2f, 0x3b, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x62, 0x75, 0x66, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
func init() {
proto.RegisterEnum("protobuf.CommunityPrivilegedUserSyncMessage_EventType", CommunityPrivilegedUserSyncMessage_EventType_name, CommunityPrivilegedUserSyncMessage_EventType_value)
proto.RegisterType((*CommunityPrivilegedUserSyncMessage)(nil), "protobuf.CommunityPrivilegedUserSyncMessage")
proto.RegisterMapType((map[string]*CommunityRequestToJoin)(nil), "protobuf.CommunityPrivilegedUserSyncMessage.RequestToJoinEntry")
}
var (
file_community_privileged_user_sync_message_proto_rawDescOnce sync.Once
file_community_privileged_user_sync_message_proto_rawDescData = file_community_privileged_user_sync_message_proto_rawDesc
)
func file_community_privileged_user_sync_message_proto_rawDescGZIP() []byte {
file_community_privileged_user_sync_message_proto_rawDescOnce.Do(func() {
file_community_privileged_user_sync_message_proto_rawDescData = protoimpl.X.CompressGZIP(file_community_privileged_user_sync_message_proto_rawDescData)
})
return file_community_privileged_user_sync_message_proto_rawDescData
func init() {
proto.RegisterFile("community_privileged_user_sync_message.proto", fileDescriptor_158595055b4cfee2)
}
var file_community_privileged_user_sync_message_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_community_privileged_user_sync_message_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_community_privileged_user_sync_message_proto_goTypes = []interface{}{
(CommunityPrivilegedUserSyncMessage_EventType)(0), // 0: protobuf.CommunityPrivilegedUserSyncMessage.EventType
(*CommunityPrivilegedUserSyncMessage)(nil), // 1: protobuf.CommunityPrivilegedUserSyncMessage
nil, // 2: protobuf.CommunityPrivilegedUserSyncMessage.RequestToJoinEntry
(*SyncCommunityRequestsToJoin)(nil), // 3: protobuf.SyncCommunityRequestsToJoin
(*CommunityRequestToJoin)(nil), // 4: protobuf.CommunityRequestToJoin
}
var file_community_privileged_user_sync_message_proto_depIdxs = []int32{
0, // 0: protobuf.CommunityPrivilegedUserSyncMessage.type:type_name -> protobuf.CommunityPrivilegedUserSyncMessage.EventType
2, // 1: protobuf.CommunityPrivilegedUserSyncMessage.request_to_join:type_name -> protobuf.CommunityPrivilegedUserSyncMessage.RequestToJoinEntry
3, // 2: protobuf.CommunityPrivilegedUserSyncMessage.sync_requests_to_join:type_name -> protobuf.SyncCommunityRequestsToJoin
4, // 3: protobuf.CommunityPrivilegedUserSyncMessage.RequestToJoinEntry.value:type_name -> protobuf.CommunityRequestToJoin
4, // [4:4] is the sub-list for method output_type
4, // [4:4] is the sub-list for method input_type
4, // [4:4] is the sub-list for extension type_name
4, // [4:4] is the sub-list for extension extendee
0, // [0:4] is the sub-list for field type_name
}
func init() { file_community_privileged_user_sync_message_proto_init() }
func file_community_privileged_user_sync_message_proto_init() {
if File_community_privileged_user_sync_message_proto != nil {
return
}
file_communities_proto_init()
file_pairing_proto_init()
if !protoimpl.UnsafeEnabled {
file_community_privileged_user_sync_message_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CommunityPrivilegedUserSyncMessage); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_community_privileged_user_sync_message_proto_rawDesc,
NumEnums: 1,
NumMessages: 2,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_community_privileged_user_sync_message_proto_goTypes,
DependencyIndexes: file_community_privileged_user_sync_message_proto_depIdxs,
EnumInfos: file_community_privileged_user_sync_message_proto_enumTypes,
MessageInfos: file_community_privileged_user_sync_message_proto_msgTypes,
}.Build()
File_community_privileged_user_sync_message_proto = out.File
file_community_privileged_user_sync_message_proto_rawDesc = nil
file_community_privileged_user_sync_message_proto_goTypes = nil
file_community_privileged_user_sync_message_proto_depIdxs = nil
var fileDescriptor_158595055b4cfee2 = []byte{
// 407 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x90, 0x5f, 0xab, 0xd3, 0x30,
0x18, 0xc6, 0xed, 0xda, 0xa9, 0x27, 0x3d, 0xd3, 0x19, 0x14, 0xca, 0xae, 0xea, 0x44, 0x2d, 0x22,
0x15, 0x26, 0x1c, 0x44, 0x2f, 0x44, 0x6b, 0x2e, 0x4e, 0x9d, 0xed, 0x31, 0xed, 0xf0, 0xcf, 0x4d,
0xd8, 0xba, 0x58, 0xe2, 0xb6, 0xa4, 0x26, 0xed, 0xa0, 0x5f, 0xc4, 0xef, 0xe8, 0xb7, 0x90, 0x35,
0x6b, 0xe7, 0x98, 0x20, 0x5e, 0xf5, 0x7d, 0x9f, 0x3e, 0xf9, 0x3d, 0xbc, 0x0f, 0x78, 0x9a, 0x89,
0xcd, 0xa6, 0xe2, 0xac, 0xac, 0x49, 0x21, 0xd9, 0x96, 0xad, 0x69, 0x4e, 0x97, 0xa4, 0x52, 0x54,
0x12, 0x55, 0xf3, 0x8c, 0x6c, 0xa8, 0x52, 0xf3, 0x9c, 0xfa, 0x85, 0x14, 0xa5, 0x80, 0x37, 0x9b,
0xcf, 0xa2, 0xfa, 0x36, 0xba, 0xd3, 0xbe, 0x63, 0x54, 0xe9, 0x9f, 0xa3, 0x41, 0x31, 0x67, 0x92,
0xf1, 0x5c, 0xaf, 0xe3, 0x5f, 0x16, 0x18, 0x07, 0x2d, 0xfc, 0xaa, 0x63, 0xcf, 0x14, 0x95, 0x49,
0xcd, 0xb3, 0x0f, 0x1a, 0x0c, 0xef, 0x82, 0x7e, 0xb6, 0x16, 0xd9, 0xca, 0x31, 0x5c, 0xc3, 0xb3,
0xb0, 0x5e, 0x60, 0x08, 0xac, 0xb2, 0x2e, 0xa8, 0xd3, 0x73, 0x0d, 0xef, 0xd6, 0xe4, 0xc2, 0x6f,
0x73, 0xfd, 0x7f, 0x13, 0x7d, 0xb4, 0xa5, 0xbc, 0x4c, 0xeb, 0x82, 0xe2, 0x86, 0x01, 0xef, 0x83,
0xf3, 0xc3, 0x91, 0x6c, 0xe9, 0x98, 0xae, 0xe1, 0x9d, 0x63, 0xbb, 0xd3, 0x2e, 0x97, 0x30, 0x07,
0xb7, 0x25, 0xfd, 0x51, 0x51, 0x55, 0x92, 0x52, 0x90, 0xef, 0x82, 0x71, 0xc7, 0x72, 0x4d, 0xcf,
0x9e, 0xbc, 0xfe, 0xaf, 0x64, 0xac, 0x19, 0xa9, 0x08, 0x05, 0xe3, 0x88, 0x97, 0xb2, 0xc6, 0x03,
0xf9, 0xa7, 0x06, 0x3f, 0x83, 0x7b, 0x4d, 0xad, 0x7b, 0x55, 0x75, 0x71, 0xfd, 0x26, 0xee, 0xe1,
0x21, 0x6e, 0xc7, 0xed, 0x22, 0xf7, 0x60, 0xa5, 0x29, 0x18, 0xee, 0x18, 0xc7, 0xda, 0x68, 0x01,
0xe0, 0x69, 0x3c, 0x1c, 0x02, 0x73, 0x45, 0xeb, 0xa6, 0xdb, 0x33, 0xbc, 0x1b, 0xe1, 0x05, 0xe8,
0x6f, 0xe7, 0xeb, 0x4a, 0x57, 0x6b, 0x4f, 0xdc, 0xbf, 0x1c, 0x78, 0xc4, 0xc1, 0xda, 0xfe, 0xb2,
0xf7, 0xc2, 0x18, 0xff, 0x34, 0xc0, 0x59, 0xd7, 0x2e, 0xb4, 0xc1, 0x8d, 0x59, 0xf4, 0x3e, 0x8a,
0x3f, 0x45, 0xc3, 0x6b, 0xf0, 0x31, 0x78, 0x10, 0xc4, 0x51, 0x8a, 0xe3, 0x29, 0x89, 0xe2, 0x77,
0x88, 0xbc, 0x09, 0x02, 0x74, 0x95, 0x12, 0x8c, 0x3e, 0xce, 0x50, 0x92, 0x92, 0x34, 0x26, 0x61,
0x7c, 0x19, 0x0d, 0x8d, 0x13, 0x23, 0x46, 0x21, 0x0a, 0x4e, 0x8d, 0x3d, 0xf8, 0x04, 0x3c, 0x3a,
0x26, 0x4e, 0xa7, 0x24, 0xf9, 0x12, 0x05, 0xad, 0x35, 0xe9, 0xbc, 0xe6, 0xdb, 0xc1, 0x57, 0xdb,
0x7f, 0xf6, 0xaa, 0xbd, 0x64, 0x71, 0xbd, 0x99, 0x9e, 0xff, 0x0e, 0x00, 0x00, 0xff, 0xff, 0x83,
0x24, 0x18, 0xbe, 0xdd, 0x02, 0x00, 0x00,
}

File diff suppressed because it is too large Load Diff

View File

@ -364,8 +364,19 @@ message SyncVerificationRequest {
message SyncContactRequestDecision {
uint64 clock = 1;
/* common.Message.ID */
string requestId = 2;
DecisionStatus decision_status = 3;
/*
The `contactId` is solely utilized during local pair synchronization.
We cannot use `requestId` to locate the corresponding UserMessage and AC notification in the database
because UserMessages are not synchronized. Specifically, during local pair sync, `contactId` is essential
for managing AC notifications generated by `syncContactRequestForInstallationContact`. These notifications
undergo special processing via the function `defaultContactRequestID`, necessitating the use of `contactId`
to correctly link related records.
*/
string contactId = 4;
enum DecisionStatus {
ACCEPTED = 0;

View File

@ -678,6 +678,79 @@ func (s *SyncDeviceSuite) TestPairPendingContactRequest() {
ensurePendingContact(alice2Backend.Messenger())
}
type contactRequestAction func(messenger *protocol.Messenger, contactRequestID string) (*protocol.MessengerResponse, error)
type notificationValidateFunc func(r *protocol.ActivityCenterPaginationResponse)
func (s *SyncDeviceSuite) testPairContactRequest(requestAction contactRequestAction, validateFunc notificationValidateFunc) {
bobBackend, _ := s.createUser("bob")
defer func() {
s.Require().NoError(bobBackend.Logout())
}()
alice1Backend, alice1TmpDir := s.createUser("alice1")
defer func() {
s.Require().NoError(alice1Backend.Logout())
}()
alicePublicKey := alice1Backend.Messenger().IdentityPublicKeyString()
request := &requests.SendContactRequest{
ID: alicePublicKey,
Message: protocol.RandomLettersString(5),
}
s.sendContactRequest(request, bobBackend.Messenger())
contactRequest := s.receiveContactRequest(request.Message, alice1Backend.Messenger())
s.Require().Equal(request.Message, contactRequest.Text)
_, err := requestAction(alice1Backend.Messenger(), contactRequest.ID)
s.Require().NoError(err)
alice2TmpDir := filepath.Join(s.tmpdir, "alice2")
alice2Backend := s.prepareBackendWithoutAccount(alice2TmpDir)
defer func() {
s.Require().NoError(alice2Backend.Logout())
}()
s.pairAccounts(alice1Backend, alice1TmpDir, alice2Backend, alice2TmpDir)
internalNotificationValidateFunc := func(m *protocol.Messenger) {
acRequest := protocol.ActivityCenterNotificationsRequest{
ActivityTypes: []protocol.ActivityCenterType{
protocol.ActivityCenterNotificationTypeContactRequest,
},
ReadType: protocol.ActivityCenterQueryParamsReadAll,
Limit: 10,
}
r, err := m.ActivityCenterNotifications(acRequest)
s.Require().NoError(err)
validateFunc(r)
}
internalNotificationValidateFunc(alice1Backend.Messenger())
internalNotificationValidateFunc(alice2Backend.Messenger())
}
func (s *SyncDeviceSuite) TestPairDeclineContactRequest() {
declineContactRequest := func(messenger *protocol.Messenger, contactRequestID string) (*protocol.MessengerResponse, error) {
return messenger.DeclineContactRequest(context.Background(), &requests.DeclineContactRequest{ID: types.Hex2Bytes(contactRequestID)})
}
s.testPairContactRequest(declineContactRequest, func(r *protocol.ActivityCenterPaginationResponse) {
s.Require().Len(r.Notifications, 1)
s.Require().False(r.Notifications[0].Accepted)
s.Require().True(r.Notifications[0].Dismissed)
s.Require().True(r.Notifications[0].Read)
})
}
func (s *SyncDeviceSuite) TestPairAcceptContactRequest() {
acceptContactRequest := func(messenger *protocol.Messenger, contactRequestID string) (*protocol.MessengerResponse, error) {
return messenger.AcceptContactRequest(context.Background(), &requests.AcceptContactRequest{ID: types.Hex2Bytes(contactRequestID)})
}
s.testPairContactRequest(acceptContactRequest, func(r *protocol.ActivityCenterPaginationResponse) {
s.Require().Len(r.Notifications, 1)
s.Require().True(r.Notifications[0].Accepted)
s.Require().False(r.Notifications[0].Dismissed)
s.Require().True(r.Notifications[0].Read)
})
}
func defaultSettings(generatedAccountInfo generator.GeneratedAccountInfo, derivedAddresses map[string]generator.AccountInfo, mnemonic *string) (*settings.Settings, error) {
chatKeyString := derivedAddresses[pathDefaultChat].PublicKey