package api
import (
"time"
"github.com/keys-pub/keys"
"github.com/keys-pub/keys/dstore/events"
"github.com/keys-pub/keys/encoding"
"github.com/keys-pub/keys/tsutil"
"github.com/pkg/errors"
)
type Events struct {
Events []*events.Event `json:"events"`
Index int64 `json:"idx"`
Truncated bool `json:"truncated,omitempty"`
}
func (e Events) Decrypt(key *keys.EdX25519Key) ([]*Message, error) {
msgs := make([]*Message, 0, len(e.Events))
for _, event := range e.Events {
msg, err := DecryptMessageFromEvent(event, key)
if err != nil {
return nil, err
}
msgs = append(msgs, msg)
}
return msgs, nil
}
type Message struct {
ID string `json:"id,omitempty" msgpack:"id,omitempty"`
Prev string `json:"prev,omitempty" msgpack:"prev,omitempty"`
Timestamp int64 `json:"ts,omitempty" msgpack:"ts,omitempty"`
Sender keys.ID `json:"sender" msgpack:"sender"`
Text string `json:"text,omitempty" msgpack:"text,omitempty"`
ChannelInfo *ChannelInfo `json:"channelInfo,omitempty" msgpack:"channelInfo,omitempty"`
ChannelInvites []*ChannelInvite `json:"channelInvites,omitempty" msgpack:"channelInvites,omitempty"`
RemoteIndex int64 `json:"-" msgpack:"-"`
RemoteTimestamp int64 `json:"-" msgpack:"-"`
}
func NewID() string {
return encoding.MustEncode(keys.RandBytes(32), encoding.Base62)
}
func NewMessage(sender keys.ID) *Message {
return &Message{
ID: NewID(),
Sender: sender,
Timestamp: tsutil.Millis(time.Now()),
}
}
func (m *Message) WithPrev(prev string) *Message {
m.Prev = prev
return m
}
func (m *Message) WithText(text string) *Message {
m.Text = text
return m
}
func (m *Message) WithTimestamp(ts int64) *Message {
m.Timestamp = ts
return m
}
func (m *Message) Encrypt(sender *keys.EdX25519Key, recipient keys.ID) ([]byte, error) {
if m.RemoteTimestamp != 0 {
return nil, errors.Errorf("remote timestamp should be omitted on send")
}
if m.RemoteIndex != 0 {
return nil, errors.Errorf("remote index should be omitted on send")
}
if m.Timestamp == 0 {
return nil, errors.Errorf("message timestamp is not set")
}
if m.Sender == "" {
return nil, errors.Errorf("message sender not set")
}
if m.Sender != sender.ID() {
return nil, errors.Errorf("message sender mismatch")
}
return Encrypt(m, sender, recipient)
}
func NewMessageForChannelInfo(sender keys.ID, info *ChannelInfo) *Message {
msg := NewMessage(sender)
msg.ChannelInfo = info
return msg
}
func NewMessageForChannelInvites(sender keys.ID, invites []*ChannelInvite) *Message {
msg := NewMessage(sender)
msg.ChannelInvites = invites
return msg
}