|
|
@@ -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. |
|
|
|