Browse Source

Keeping track of anack'd group messages

Sarah Jamie Lewis 3 months ago
parent
commit
83faab35a3
2 changed files with 44 additions and 14 deletions
  1. 43 14
      model/group.go
  2. 1 0
      model/profile.go

+ 43 - 14
model/group.go

@@ -17,19 +17,19 @@ import (
 // Group defines and encapsulates Cwtch's conception of group chat. Which are sessions
 // tied to a server under a given group key. Each group has a set of Messages.
 type Group struct {
-	GroupID        string
-	SignedGroupID  []byte
-	GroupKey       [32]byte
-	GroupServer    string
-	Timeline       Timeline
-	Accepted       bool
-	Owner          string
-	IsCompromised  bool
-	InitialMessage []byte
-	Attributes     map[string]string
-	lock           sync.Mutex
-	NewMessage     chan Message `json:"-"`
-	LocalID        string
+	GroupID                string
+	SignedGroupID          []byte
+	GroupKey               [32]byte
+	GroupServer            string
+	Timeline               Timeline
+	Accepted               bool
+	Owner                  string
+	IsCompromised          bool
+	InitialMessage         []byte
+	Attributes             map[string]string
+	lock                   sync.Mutex
+	LocalID                string
+	unacknowledgedMessages []Message
 }
 
 // NewGroup initializes a new group associated with a given CwtchServer
@@ -103,8 +103,36 @@ func (g *Group) Invite(initialMessage []byte) ([]byte, error) {
 	return invite, err
 }
 
+// AddSentMessage takes a DecryptedGroupMessage and adds it to the Groups Timeline
+func (g *Group) AddSentMessage(message *protocol.DecryptedGroupMessage, sig []byte) Message {
+	g.lock.Lock()
+	defer g.lock.Unlock()
+	timelineMessage := Message{
+		Message:            message.GetText(),
+		Timestamp:          time.Unix(int64(message.GetTimestamp()), 0),
+		Received:           time.Unix(0, 0),
+		Signature:          sig,
+		PeerID:             message.GetOnion(),
+		PreviousMessageSig: message.GetPreviousMessageSig(),
+	}
+	g.unacknowledgedMessages = append(g.unacknowledgedMessages, timelineMessage)
+	return timelineMessage
+}
+
 // AddMessage takes a DecryptedGroupMessage and adds it to the Groups Timeline
 func (g *Group) AddMessage(message *protocol.DecryptedGroupMessage, sig []byte) (*Message, bool) {
+
+	g.lock.Lock()
+	defer g.lock.Unlock()
+
+	// Delete the message from the unack'd buffer if it exists
+	for i, unAckedMessage := range g.unacknowledgedMessages {
+		if compareSignatures(unAckedMessage.Signature, sig) {
+			g.unacknowledgedMessages = append(g.unacknowledgedMessages[:i], g.unacknowledgedMessages[i+1:]...)
+			break
+		}
+	}
+
 	timelineMessage := &Message{
 		Message:            message.GetText(),
 		Timestamp:          time.Unix(int64(message.GetTimestamp()), 0),
@@ -114,6 +142,7 @@ func (g *Group) AddMessage(message *protocol.DecryptedGroupMessage, sig []byte)
 		PreviousMessageSig: message.GetPreviousMessageSig(),
 	}
 	seen := g.Timeline.Insert(timelineMessage)
+
 	return timelineMessage, seen
 }
 
@@ -121,7 +150,7 @@ func (g *Group) AddMessage(message *protocol.DecryptedGroupMessage, sig []byte)
 func (g *Group) GetTimeline() (timeline []Message) {
 	g.lock.Lock()
 	defer g.lock.Unlock()
-	return g.Timeline.GetMessages()
+	return append(g.Timeline.GetMessages(), g.unacknowledgedMessages...)
 }
 
 //EncryptMessage takes a message and encrypts the message under the group key.

+ 1 - 0
model/profile.go

@@ -365,6 +365,7 @@ func (p *Profile) EncryptMessageToGroup(message string, groupID string) ([]byte,
 			return nil, nil, err
 		}
 		signature := p.SignMessage(groupID + group.GroupServer + string(ciphertext))
+		group.AddSentMessage(dm, signature)
 		return ciphertext, signature, nil
 	}
 	return nil, nil, errors.New("group does not exist")