diff --git a/.gitignore b/.gitignore index 70627d6..903265f 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ out/doc/server_deployment/server_deployment.png test id.enc invitation.png +client/test.cfg diff --git a/client/config.go b/client/config.go new file mode 100644 index 0000000..382ce56 --- /dev/null +++ b/client/config.go @@ -0,0 +1,76 @@ +package client + +import ( + "encoding/json" + "io/ioutil" + "sync" +) + +type Config struct { + // UserConfig + SavePassword bool `json:"save_password,omitempty"` + SavedPassword string `json:"saved_password,omitempty"` + // Technical + StoragePath string `json:"storage_path,omitempty"` + MaxIdsPerUser int `json:"max_ids_per_user,omitempty"` + MsgDbRollingPeriod int `json:"msg_db_rolling_period,omitempty"` + Chunksize int `json:"chunksize,omitempty"` + ServerPollInterval int `json:"server_poll_interval,omitempty"` + // GUI + LastOpenChat string `json:"last_open_chat,omitempty"` + SoundNotification bool `json:"sound_notification,omitempty"` + DefaultNotificationSound string `json:"default_notification_sound,omitempty"` + NotificationVibe string `json:"notification_vibe,omitempty"` + DefaultNotificationVibe string `json:"default_notification_vibe,omitempty"` + NotificationLED string `json:"notification_led,omitempty"` + DefaultNotificationLEDColor string `json:"default_notification_led_color,omitempty"` + VisualNotification bool `json:"visual_notification,omitempty"` + VisualNotifiactionModes string `json:"visual_notifiaction_modes,omitempty"` + PrivateChatNotifiactions bool `json:"private_chat_notifiactions,omitempty"` + GroupChatNotifiactions bool `json:"group_chat_notifiactions,omitempty"` + ChannelNotifications bool `json:"channel_notifications,omitempty"` + // Inner + memoryPassword string `json:"memory_password,omitempty"` +} + +var instance *Config +var once sync.Once + +func GetConfig() *Config { + once.Do(func() { + instance = &Config{} + }) + return instance +} + +func (c *Config) Load(filename string) error { + data, err := ioutil.ReadFile(filename) + if err != nil { + return err + } + err = json.Unmarshal(data, c) + if err != nil { + return err + } + return nil +} + +func (c *Config) Save(filename string) error { + data, err := json.Marshal(c) + if err != nil { + return err + } + ioutil.WriteFile(filename, data, 0644) + if err != nil { + return err + } + return nil +} + +func (c *Config) SetMemPass(pass string) { + c.memoryPassword = pass +} + +func (c *Config) GetMemPass() string { + return c.memoryPassword +} diff --git a/client/config_test.go b/client/config_test.go new file mode 100644 index 0000000..613871b --- /dev/null +++ b/client/config_test.go @@ -0,0 +1,19 @@ +package client + +import ( + "testing" +) + +func TestConfigSave(t *testing.T) { + c := GetConfig() + c.memoryPassword = "hideme" + c.Chunksize = 10000000 + c.SavePassword = true + c.SavedPassword = "stupid" + c.Save("test.cfg") +} + +func TestConfigLoad(t *testing.T) { + _ = GetConfig().Load("test.cfg") + println(GetConfig().Chunksize) +} diff --git a/client/identity.go b/client/identity.go index e75fac7..6908595 100644 --- a/client/identity.go +++ b/client/identity.go @@ -2,10 +2,12 @@ package client import ( "encoding/json" + "errors" "io/ioutil" "forge.redroom.link/yves/meowlib" "github.com/ProtonMail/gopenpgp/v2/helper" + "github.com/google/uuid" ) const key = "3pw0c8#6ZG8{75b5;3?fe80$2" @@ -31,30 +33,64 @@ func CreateIdentity(nickname string) *Identity { return &id } -func (id *Identity) InvitePeer(MyName string, ContactName string, MessageServerIdxs []int) (*Peer, *meowlib.ContactCard) { +func (id *Identity) InvitePeer(MyName string, ContactName string, MessageServerIdxs []int) *meowlib.ContactCard { var peer Peer var myContactCard meowlib.ContactCard - peer.Me = meowlib.NewKeyPair() - peer.EncryptionKp = meowlib.NewKeyPair() - peer.LookupKp = meowlib.NewKeyPair() + peer.MyIdentity = meowlib.NewKeyPair() + peer.MyEncryptionKp = meowlib.NewKeyPair() + peer.MyLookupKp = meowlib.NewKeyPair() peer.Name = ContactName + peer.InvitationId = uuid.New().String() for _, i := range MessageServerIdxs { srv := id.MessageServers.Servers[i].ServerData myContactCard.PullServers = append(myContactCard.PullServers, &srv) } myContactCard.Name = MyName - myContactCard.ContactPublicKey = peer.Me.Public - myContactCard.EncryptionPublicKey = peer.EncryptionKp.Public - myContactCard.LookupPublicKey = peer.LookupKp.Public + myContactCard.ContactPublicKey = peer.MyIdentity.Public + myContactCard.EncryptionPublicKey = peer.MyEncryptionKp.Public + myContactCard.LookupPublicKey = peer.MyLookupKp.Public + myContactCard.InvitationId = peer.InvitationId + id.Peers = append(id.Peers, peer) + + return &myContactCard +} + +func (id *Identity) AnswerInvitation(MyName string, ContactName string, MessageServerIdxs []int, ReceivedContact *meowlib.ContactCard) *meowlib.ContactCard { + var peer Peer + var myContactCard meowlib.ContactCard + peer.MyIdentity = meowlib.NewKeyPair() + peer.MyEncryptionKp = meowlib.NewKeyPair() + peer.MyLookupKp = meowlib.NewKeyPair() + if ContactName != "" { + peer.Name = ContactName + } else { + peer.Name = ReceivedContact.Name + } + peer.Contact = *ReceivedContact + + for _, i := range MessageServerIdxs { + srv := id.MessageServers.Servers[i].ServerData + myContactCard.PullServers = append(myContactCard.PullServers, &srv) + } + myContactCard.Name = MyName + myContactCard.ContactPublicKey = peer.MyIdentity.Public + myContactCard.EncryptionPublicKey = peer.MyEncryptionKp.Public + myContactCard.LookupPublicKey = peer.MyLookupKp.Public + myContactCard.InvitationId = peer.InvitationId id.Peers = append(id.Peers, peer) - return &id.Peers[len(id.Peers)-1], &myContactCard + return &myContactCard } -func (*Identity) FinalizeInvitation(peer *Peer, ReceivedContact *meowlib.ContactCard) { - peer.Contact = *ReceivedContact - +func (id *Identity) FinalizeInvitation(ReceivedContact *meowlib.ContactCard) error { + for i, p := range id.Peers { + if p.InvitationId == ReceivedContact.InvitationId { + id.Peers[i].Contact = *ReceivedContact + return nil + } + } + return errors.New("no matching contact found for invitationId " + ReceivedContact.InvitationId) } func LoadIdentity(file string) (*Identity, error) { diff --git a/client/peer.go b/client/peer.go index 9a384c8..453229a 100644 --- a/client/peer.go +++ b/client/peer.go @@ -2,6 +2,8 @@ package client import ( "fmt" + "io" + "os" "time" "forge.redroom.link/yves/meowlib" @@ -13,11 +15,13 @@ type Peer struct { Name string `json:"name,omitempty"` // Conversation []InternalMessage `json:"conversation,omitempty"` // My own keys for that peer - Me meowlib.KeyPair `json:"me,omitempty"` - EncryptionKp meowlib.KeyPair `json:"conversation_kp,omitempty"` - LookupKp meowlib.KeyPair `json:"lookup_kp,omitempty"` + MyIdentity meowlib.KeyPair `json:"my_identity,omitempty"` + MyEncryptionKp meowlib.KeyPair `json:"my_encryption_kp,omitempty"` + MyLookupKp meowlib.KeyPair `json:"my_lookup_kp,omitempty"` + MyPullServers []meowlib.Server `json:"my_pull_servers,omitempty"` // Peer keys and infos - Contact meowlib.ContactCard `json:"contact,omitempty"` + Contact meowlib.ContactCard `json:"contact,omitempty"` + InvitationId string `json:"invitation_id,omitempty"` // Internal management attributes Visible bool `json:"visible,omitempty"` VisiblePassword string `json:"visible_password,omitempty"` @@ -26,7 +30,7 @@ type Peer struct { MessageNotification string `json:"message_notification,omitempty"` OnionMode bool `json:"onion_mode,omitempty"` LastMessage time.Time `json:"last_message,omitempty"` - MessageDb string `json:"message_db,omitempty"` // sql url for messages storage + DbIds []string `json:"db_ids,omitempty"` DbPassword string `json:"db_password,omitempty"` } @@ -57,13 +61,59 @@ func (pl *PeerList) GetFromName(name string) *Peer { func (p *Peer) BuildSimpleUserUMessage(message []byte) (*meowlib.UserMessage, error) { var msg meowlib.UserMessage - msg.From = p.Me.Public + msg.From = p.MyIdentity.Public msg.Data = message msg.Type = "1" + msg.Status = &meowlib.UserMessage_ConversationStatus{} msg.Status.LocalUuid = uuid.New().String() return &msg, nil } +func (p *Peer) BuildFileMessage(filename string, message []byte) ([]meowlib.UserMessage, error) { + var msgs []meowlib.UserMessage + fi, err := os.Stat(filename) + if err != nil { + return nil, err + } + + file, err := os.Open(filename) + if err != nil { + return nil, err + } + defer file.Close() + + // declare chunk size + maxSz := GetConfig().Chunksize + + // create buffer + b := make([]byte, maxSz) + chunk := 0 + for { + // read content to buffer + readTotal, err := file.Read(b) + if err != nil { + if err != io.EOF { + return nil, err + } + break + } + var msg meowlib.UserMessage + msg.From = p.MyIdentity.Public + msg.File.Filename = fi.Name() + msg.File.Chunk = uint32(chunk) + msg.File.Data = b[:readTotal] + msg.File.Size = uint64(fi.Size()) + msg.Type = "2" + if chunk == 0 { + msg.Status = &meowlib.UserMessage_ConversationStatus{} + msg.Status.LocalUuid = uuid.New().String() + } + msgs = append(msgs, msg) + chunk++ + } + return msgs, nil +} + func (p *Peer) SerializeUserMessage(msg *meowlib.UserMessage) ([]byte, error) { out, err := proto.Marshal(msg) if err != nil { @@ -74,7 +124,7 @@ func (p *Peer) SerializeUserMessage(msg *meowlib.UserMessage) ([]byte, error) { // AsymEncryptMessage prepares a message to send to a specific peer contact func (p *Peer) AsymEncryptMessage(Message []byte) (EncryptedMessage []byte, Signature []byte, Servers []*meowlib.Server, err error) { - EncryptedMessage, Signature, err = meowlib.AsymEncryptAndSign(p.Contact.EncryptionPublicKey, p.Me.Private, Message) + EncryptedMessage, Signature, err = meowlib.AsymEncryptAndSign(p.Contact.EncryptionPublicKey, p.MyIdentity.Private, Message) if err != nil { fmt.Println(err.Error()) return nil, nil, nil, err @@ -84,7 +134,7 @@ func (p *Peer) AsymEncryptMessage(Message []byte) (EncryptedMessage []byte, Sign // AsymDecryptMessage reads a message from a specific peer contact func (p *Peer) AsymDecryptMessage(Message []byte, Signature []byte) (DecryptedMessage []byte, err error) { - DecryptedMessage, err = meowlib.AsymDecryptAndCheck(p.Me.Private, p.Contact.ContactPublicKey, Message, Signature) + DecryptedMessage, err = meowlib.AsymDecryptAndCheck(p.MyIdentity.Private, p.Contact.ContactPublicKey, Message, Signature) if err != nil { fmt.Println(err.Error()) return nil, err diff --git a/contactcard.go b/contactcard.go index 1745ecd..d842f3d 100644 --- a/contactcard.go +++ b/contactcard.go @@ -3,7 +3,6 @@ package meowlib import ( "bytes" "compress/gzip" - "encoding/json" "fmt" "image" "image/color" @@ -96,13 +95,14 @@ func (contact *ContactCard) WritePng(filename string) { } func (Contact *ContactCard) WriteQr(filename string) { - jsonContact, _ := json.Marshal(Contact) + //jsonContact, _ := json.Marshal(Contact) + jsonContact, _ := Contact.Compress() qwriter := qrcode.NewQRCodeWriter() code, err := qwriter.Encode(string(jsonContact), gozxing.BarcodeFormat_QR_CODE, 512, 512, nil) if err != nil { println(err.Error()) } - file, _ := os.Create("barcode.png") + file, _ := os.Create(filename) defer file.Close() // *BitMatrix implements the image.Image interface, diff --git a/endtoend_test.go b/endtoend_test.go index 54e4838..13b27ae 100644 --- a/endtoend_test.go +++ b/endtoend_test.go @@ -30,12 +30,18 @@ func TestEndToEnd(t *testing.T) { // Create an invitation for a friend, I want him/her to know me as Bender // //////////////////////////////////////////////////////////////////////////// fmt.Println("Creating an invitation for the first friend...") - MyFirstFriend, invitation := Me.InvitePeer("Bender", "myfirstfriend", []int{1, 2}) + invitation := Me.InvitePeer("Bender", "myfirstfriend", []int{1, 2}) // print my invitation a, _ := json.Marshal(invitation) fmt.Println(string(a)) // TODO : Convert invitation to QR Code invitation.WritePng("invitation.png") + data, err := invitation.Compress() + if err != nil { + println(err) + } + invitation.WriteQr("qrcode.png") + println("Compressed contact card :", len(data)) /////////////////////////////////////// // Simulate peer invitation response // /////////////////////////////////////// @@ -50,6 +56,7 @@ func TestEndToEnd(t *testing.T) { ReceivedContact.ContactPublicKey = FirstFriendContactKp.Public ReceivedContact.EncryptionPublicKey = FirstFriendEncryptionKp.Public ReceivedContact.LookupPublicKey = FirstFriendLookupKp.Public + ReceivedContact.InvitationId = invitation.InvitationId FriendServer1KP := meowlib.NewKeyPair() FriendServer1 := meowlib.Server{Name: "FriendServer1", Url: "http://myfriend.org/meow/", PublicKey: FriendServer1KP.Public, Description: "Fancy description", ConfidenceLevel: 1} ReceivedContact.PullServers = append(ReceivedContact.PullServers, &FriendServer1) @@ -57,7 +64,7 @@ func TestEndToEnd(t *testing.T) { /////////////////////////////////////////////////////// // Finalize the contact with the invitation response // /////////////////////////////////////////////////////// - Me.FinalizeInvitation(MyFirstFriend, &ReceivedContact) + Me.FinalizeInvitation(&ReceivedContact) /*err = Me.Save("id.enc") if err != nil { fmt.Println(err.Error()) @@ -69,6 +76,7 @@ func TestEndToEnd(t *testing.T) { ///////////////////////////////////// // Create a message to that friend // ///////////////////////////////////// + MyFirstFriend := Me.Peers[0] textmessage := "Hello friend!" // Creating User message usermessage, err := MyFirstFriend.BuildSimpleUserUMessage([]byte(textmessage)) diff --git a/message.go b/message.go new file mode 100644 index 0000000..69cd2a6 --- /dev/null +++ b/message.go @@ -0,0 +1,5 @@ +package meowlib + +func (*UserMessage) addFile(filename string) { + +} diff --git a/messages.pb.go b/messages.pb.go index 72e8dcb..4981765 100644 --- a/messages.pb.go +++ b/messages.pb.go @@ -286,7 +286,9 @@ type Server struct { Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` PublicKey string `protobuf:"bytes,3,opt,name=publicKey,proto3" json:"publicKey,omitempty"` Url string `protobuf:"bytes,4,opt,name=url,proto3" json:"url,omitempty"` - ConfidenceLevel int32 `protobuf:"varint,5,opt,name=confidenceLevel,proto3" json:"confidenceLevel,omitempty"` + Publish bool `protobuf:"varint,5,opt,name=publish,proto3" json:"publish,omitempty"` // publish this server when asked for a list by server + Signature []byte `protobuf:"bytes,6,opt,name=signature,proto3" json:"signature,omitempty"` // signature of all previous field by the server itself + ConfidenceLevel int32 `protobuf:"varint,7,opt,name=confidenceLevel,proto3" json:"confidenceLevel,omitempty"` // additional info from the user } func (x *Server) Reset() { @@ -349,6 +351,20 @@ func (x *Server) GetUrl() string { return "" } +func (x *Server) GetPublish() bool { + if x != nil { + return x.Publish + } + return false +} + +func (x *Server) GetSignature() []byte { + if x != nil { + return x.Signature + } + return nil +} + func (x *Server) GetConfidenceLevel() int32 { if x != nil { return x.ConfidenceLevel @@ -367,7 +383,8 @@ type ContactCard struct { EncryptionPublicKey string `protobuf:"bytes,3,opt,name=encryptionPublicKey,proto3" json:"encryptionPublicKey,omitempty"` LookupPublicKey string `protobuf:"bytes,4,opt,name=lookupPublicKey,proto3" json:"lookupPublicKey,omitempty"` PullServers []*Server `protobuf:"bytes,5,rep,name=pullServers,proto3" json:"pullServers,omitempty"` - Version int32 `protobuf:"varint,6,opt,name=version,proto3" json:"version,omitempty"` + Version uint32 `protobuf:"varint,6,opt,name=version,proto3" json:"version,omitempty"` + InvitationId string `protobuf:"bytes,7,opt,name=invitationId,proto3" json:"invitationId,omitempty"` } func (x *ContactCard) Reset() { @@ -437,13 +454,20 @@ func (x *ContactCard) GetPullServers() []*Server { return nil } -func (x *ContactCard) GetVersion() int32 { +func (x *ContactCard) GetVersion() uint32 { if x != nil { return x.Version } return 0 } +func (x *ContactCard) GetInvitationId() string { + if x != nil { + return x.InvitationId + } + return "" +} + // structure for sending a message to be forwarded to another user in protobuf format type PackedUserMessage struct { state protoimpl.MessageState @@ -531,6 +555,7 @@ type UserMessage struct { Contact *ContactCard `protobuf:"bytes,6,opt,name=contact,proto3" json:"contact,omitempty"` KnownServers *Server `protobuf:"bytes,7,opt,name=knownServers,proto3" json:"knownServers,omitempty"` Group *UserMessage_Group `protobuf:"bytes,8,opt,name=group,proto3" json:"group,omitempty"` + File *File `protobuf:"bytes,9,opt,name=file,proto3" json:"file,omitempty"` } func (x *UserMessage) Reset() { @@ -621,6 +646,84 @@ func (x *UserMessage) GetGroup() *UserMessage_Group { return nil } +func (x *UserMessage) GetFile() *File { + if x != nil { + return x.File + } + return nil +} + +type File struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Filename string `protobuf:"bytes,1,opt,name=filename,proto3" json:"filename,omitempty"` + Size uint64 `protobuf:"varint,2,opt,name=size,proto3" json:"size,omitempty"` + Chunk uint32 `protobuf:"varint,3,opt,name=chunk,proto3" json:"chunk,omitempty"` + Data []byte `protobuf:"bytes,4,opt,name=data,proto3" json:"data,omitempty"` +} + +func (x *File) Reset() { + *x = File{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *File) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*File) ProtoMessage() {} + +func (x *File) ProtoReflect() protoreflect.Message { + mi := &file_messages_proto_msgTypes[7] + 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 File.ProtoReflect.Descriptor instead. +func (*File) Descriptor() ([]byte, []int) { + return file_messages_proto_rawDescGZIP(), []int{7} +} + +func (x *File) GetFilename() string { + if x != nil { + return x.Filename + } + return "" +} + +func (x *File) GetSize() uint64 { + if x != nil { + return x.Size + } + return 0 +} + +func (x *File) GetChunk() uint32 { + if x != nil { + return x.Chunk + } + return 0 +} + +func (x *File) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + // structure for requesting incoming messages type ToServerMessage_ConversationRequest struct { state protoimpl.MessageState @@ -636,7 +739,7 @@ type ToServerMessage_ConversationRequest struct { func (x *ToServerMessage_ConversationRequest) Reset() { *x = ToServerMessage_ConversationRequest{} if protoimpl.UnsafeEnabled { - mi := &file_messages_proto_msgTypes[7] + mi := &file_messages_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -649,7 +752,7 @@ func (x *ToServerMessage_ConversationRequest) String() string { func (*ToServerMessage_ConversationRequest) ProtoMessage() {} func (x *ToServerMessage_ConversationRequest) ProtoReflect() protoreflect.Message { - mi := &file_messages_proto_msgTypes[7] + mi := &file_messages_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -704,7 +807,7 @@ type FromServerMessage_ConversationResponse struct { func (x *FromServerMessage_ConversationResponse) Reset() { *x = FromServerMessage_ConversationResponse{} if protoimpl.UnsafeEnabled { - mi := &file_messages_proto_msgTypes[8] + mi := &file_messages_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -717,7 +820,7 @@ func (x *FromServerMessage_ConversationResponse) String() string { func (*FromServerMessage_ConversationResponse) ProtoMessage() {} func (x *FromServerMessage_ConversationResponse) ProtoReflect() protoreflect.Message { - mi := &file_messages_proto_msgTypes[8] + mi := &file_messages_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -757,7 +860,7 @@ type UserMessage_ConversationStatus struct { func (x *UserMessage_ConversationStatus) Reset() { *x = UserMessage_ConversationStatus{} if protoimpl.UnsafeEnabled { - mi := &file_messages_proto_msgTypes[9] + mi := &file_messages_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -770,7 +873,7 @@ func (x *UserMessage_ConversationStatus) String() string { func (*UserMessage_ConversationStatus) ProtoMessage() {} func (x *UserMessage_ConversationStatus) ProtoReflect() protoreflect.Message { - mi := &file_messages_proto_msgTypes[9] + mi := &file_messages_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -847,7 +950,7 @@ type UserMessage_Group struct { func (x *UserMessage_Group) Reset() { *x = UserMessage_Group{} if protoimpl.UnsafeEnabled { - mi := &file_messages_proto_msgTypes[10] + mi := &file_messages_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -860,7 +963,7 @@ func (x *UserMessage_Group) String() string { func (*UserMessage_Group) ProtoMessage() {} func (x *UserMessage_Group) ProtoReflect() protoreflect.Message { - mi := &file_messages_proto_msgTypes[10] + mi := &file_messages_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -950,7 +1053,7 @@ var file_messages_proto_rawDesc = []byte{ 0x72, 0x73, 0x1a, 0x3a, 0x0a, 0x14, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x55, 0x75, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x0c, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x55, 0x75, 0x69, 0x64, 0x73, 0x22, 0x98, + 0x52, 0x0c, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x55, 0x75, 0x69, 0x64, 0x73, 0x22, 0xd0, 0x01, 0x0a, 0x06, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, @@ -958,80 +1061,94 @@ var file_messages_proto_rawDesc = []byte{ 0x1c, 0x0a, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, - 0x28, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x4c, 0x65, 0x76, - 0x65, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x64, - 0x65, 0x6e, 0x63, 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x22, 0xf6, 0x01, 0x0a, 0x0b, 0x43, 0x6f, - 0x6e, 0x74, 0x61, 0x63, 0x74, 0x43, 0x61, 0x72, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2a, 0x0a, + 0x18, 0x0a, 0x07, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x07, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, + 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x64, 0x65, 0x6e, 0x63, 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x4c, 0x65, 0x76, 0x65, + 0x6c, 0x22, 0x9a, 0x02, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x43, 0x61, 0x72, + 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, + 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, - 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, - 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x13, 0x65, 0x6e, 0x63, - 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x28, 0x0a, 0x0f, 0x6c, - 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x50, 0x75, 0x62, 0x6c, - 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x31, 0x0a, 0x0b, 0x70, 0x75, 0x6c, 0x6c, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6d, 0x65, 0x6f, - 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x0b, 0x70, 0x75, 0x6c, - 0x6c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x22, 0x97, 0x01, 0x0a, 0x11, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x55, 0x73, 0x65, + 0x79, 0x12, 0x30, 0x0a, 0x13, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x50, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, + 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x4b, 0x65, 0x79, 0x12, 0x28, 0x0a, 0x0f, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x50, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x6c, 0x6f, + 0x6f, 0x6b, 0x75, 0x70, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x31, 0x0a, + 0x0b, 0x70, 0x75, 0x6c, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x18, 0x05, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x52, 0x0b, 0x70, 0x75, 0x6c, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, + 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x0c, 0x69, 0x6e, + 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0c, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x97, + 0x01, 0x0a, 0x11, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, + 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, + 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x28, + 0x0a, 0x0f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x18, 0x04, 0x20, 0x03, 0x28, 0x03, 0x52, 0x0f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0xcc, 0x05, 0x0a, 0x0b, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, - 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, - 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x61, 0x79, - 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, - 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, - 0x72, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x03, 0x28, 0x03, 0x52, 0x0f, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0xa9, 0x05, 0x0a, - 0x0b, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x20, 0x0a, 0x0b, - 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, - 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x72, - 0x6f, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x3f, 0x0a, 0x06, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6d, 0x65, 0x6f, - 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x2e, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x52, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2e, 0x0a, 0x07, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, - 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x43, 0x61, - 0x72, 0x64, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x12, 0x33, 0x0a, 0x0c, 0x6b, - 0x6e, 0x6f, 0x77, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x0f, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x52, 0x0c, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, - 0x12, 0x30, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1a, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x05, 0x67, 0x72, 0x6f, - 0x75, 0x70, 0x1a, 0x96, 0x02, 0x0a, 0x12, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x6c, 0x6f, 0x63, - 0x61, 0x6c, 0x55, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6c, 0x6f, - 0x63, 0x61, 0x6c, 0x55, 0x75, 0x69, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, - 0x04, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x65, 0x6e, - 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x08, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x12, 0x1c, 0x0a, - 0x09, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x09, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x12, 0x3c, 0x0a, 0x0e, 0x6d, - 0x79, 0x4e, 0x65, 0x78, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x43, 0x6f, - 0x6e, 0x74, 0x61, 0x63, 0x74, 0x43, 0x61, 0x72, 0x64, 0x52, 0x0e, 0x6d, 0x79, 0x4e, 0x65, 0x78, - 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x30, 0x0a, 0x13, 0x70, 0x65, 0x65, - 0x72, 0x4e, 0x65, 0x78, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x41, 0x63, 0x6b, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x13, 0x70, 0x65, 0x65, 0x72, 0x4e, 0x65, 0x78, 0x74, - 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x41, 0x63, 0x6b, 0x1a, 0x4b, 0x0a, 0x05, 0x47, - 0x72, 0x6f, 0x75, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x07, 0x6d, 0x65, 0x6d, 0x62, - 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x65, 0x6f, 0x77, - 0x6c, 0x69, 0x62, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x43, 0x61, 0x72, 0x64, 0x52, - 0x07, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x42, 0x21, 0x5a, 0x1f, 0x66, 0x6f, 0x72, 0x67, - 0x65, 0x2e, 0x72, 0x65, 0x64, 0x72, 0x6f, 0x6f, 0x6d, 0x2e, 0x6c, 0x69, 0x6e, 0x6b, 0x2f, 0x79, - 0x76, 0x65, 0x73, 0x2f, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, + 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x12, + 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x3f, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, + 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x6f, 0x6e, + 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, + 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2e, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x61, + 0x63, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c, + 0x69, 0x62, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x43, 0x61, 0x72, 0x64, 0x52, 0x07, + 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x12, 0x33, 0x0a, 0x0c, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, + 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, + 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x0c, + 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, 0x30, 0x0a, 0x05, + 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6d, 0x65, + 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x21, + 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x6d, + 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x04, 0x66, 0x69, 0x6c, + 0x65, 0x1a, 0x96, 0x02, 0x0a, 0x12, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x55, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x55, 0x75, 0x69, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x53, + 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, + 0x73, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x65, 0x6e, 0x74, + 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x08, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x12, 0x1c, 0x0a, 0x09, + 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x09, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x12, 0x3c, 0x0a, 0x0e, 0x6d, 0x79, + 0x4e, 0x65, 0x78, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x43, 0x6f, 0x6e, + 0x74, 0x61, 0x63, 0x74, 0x43, 0x61, 0x72, 0x64, 0x52, 0x0e, 0x6d, 0x79, 0x4e, 0x65, 0x78, 0x74, + 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x30, 0x0a, 0x13, 0x70, 0x65, 0x65, 0x72, + 0x4e, 0x65, 0x78, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x41, 0x63, 0x6b, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x13, 0x70, 0x65, 0x65, 0x72, 0x4e, 0x65, 0x78, 0x74, 0x49, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x41, 0x63, 0x6b, 0x1a, 0x4b, 0x0a, 0x05, 0x47, 0x72, + 0x6f, 0x75, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x07, 0x6d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c, + 0x69, 0x62, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x43, 0x61, 0x72, 0x64, 0x52, 0x07, + 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x22, 0x60, 0x0a, 0x04, 0x46, 0x69, 0x6c, 0x65, 0x12, + 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, + 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, + 0x14, 0x0a, 0x05, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, + 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x42, 0x21, 0x5a, 0x1f, 0x66, 0x6f, 0x72, + 0x67, 0x65, 0x2e, 0x72, 0x65, 0x64, 0x72, 0x6f, 0x6f, 0x6d, 0x2e, 0x6c, 0x69, 0x6e, 0x6b, 0x2f, + 0x79, 0x76, 0x65, 0x73, 0x2f, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1046,7 +1163,7 @@ func file_messages_proto_rawDescGZIP() []byte { return file_messages_proto_rawDescData } -var file_messages_proto_msgTypes = make([]protoimpl.MessageInfo, 11) +var file_messages_proto_msgTypes = make([]protoimpl.MessageInfo, 12) var file_messages_proto_goTypes = []interface{}{ (*PackedServerMessage)(nil), // 0: meowlib.PackedServerMessage (*ToServerMessage)(nil), // 1: meowlib.ToServerMessage @@ -1055,29 +1172,31 @@ var file_messages_proto_goTypes = []interface{}{ (*ContactCard)(nil), // 4: meowlib.ContactCard (*PackedUserMessage)(nil), // 5: meowlib.PackedUserMessage (*UserMessage)(nil), // 6: meowlib.UserMessage - (*ToServerMessage_ConversationRequest)(nil), // 7: meowlib.ToServerMessage.ConversationRequest - (*FromServerMessage_ConversationResponse)(nil), // 8: meowlib.FromServerMessage.ConversationResponse - (*UserMessage_ConversationStatus)(nil), // 9: meowlib.UserMessage.ConversationStatus - (*UserMessage_Group)(nil), // 10: meowlib.UserMessage.Group + (*File)(nil), // 7: meowlib.File + (*ToServerMessage_ConversationRequest)(nil), // 8: meowlib.ToServerMessage.ConversationRequest + (*FromServerMessage_ConversationResponse)(nil), // 9: meowlib.FromServerMessage.ConversationResponse + (*UserMessage_ConversationStatus)(nil), // 10: meowlib.UserMessage.ConversationStatus + (*UserMessage_Group)(nil), // 11: meowlib.UserMessage.Group } var file_messages_proto_depIdxs = []int32{ - 7, // 0: meowlib.ToServerMessage.pullRequest:type_name -> meowlib.ToServerMessage.ConversationRequest + 8, // 0: meowlib.ToServerMessage.pullRequest:type_name -> meowlib.ToServerMessage.ConversationRequest 5, // 1: meowlib.ToServerMessage.messages:type_name -> meowlib.PackedUserMessage 3, // 2: meowlib.ToServerMessage.knownServers:type_name -> meowlib.Server 5, // 3: meowlib.FromServerMessage.chat:type_name -> meowlib.PackedUserMessage 3, // 4: meowlib.FromServerMessage.knownServers:type_name -> meowlib.Server 3, // 5: meowlib.ContactCard.pullServers:type_name -> meowlib.Server - 9, // 6: meowlib.UserMessage.Status:type_name -> meowlib.UserMessage.ConversationStatus + 10, // 6: meowlib.UserMessage.Status:type_name -> meowlib.UserMessage.ConversationStatus 4, // 7: meowlib.UserMessage.contact:type_name -> meowlib.ContactCard 3, // 8: meowlib.UserMessage.knownServers:type_name -> meowlib.Server - 10, // 9: meowlib.UserMessage.group:type_name -> meowlib.UserMessage.Group - 4, // 10: meowlib.UserMessage.ConversationStatus.myNextIdentity:type_name -> meowlib.ContactCard - 4, // 11: meowlib.UserMessage.Group.members:type_name -> meowlib.ContactCard - 12, // [12:12] is the sub-list for method output_type - 12, // [12:12] is the sub-list for method input_type - 12, // [12:12] is the sub-list for extension type_name - 12, // [12:12] is the sub-list for extension extendee - 0, // [0:12] is the sub-list for field type_name + 11, // 9: meowlib.UserMessage.group:type_name -> meowlib.UserMessage.Group + 7, // 10: meowlib.UserMessage.file:type_name -> meowlib.File + 4, // 11: meowlib.UserMessage.ConversationStatus.myNextIdentity:type_name -> meowlib.ContactCard + 4, // 12: meowlib.UserMessage.Group.members:type_name -> meowlib.ContactCard + 13, // [13:13] is the sub-list for method output_type + 13, // [13:13] is the sub-list for method input_type + 13, // [13:13] is the sub-list for extension type_name + 13, // [13:13] is the sub-list for extension extendee + 0, // [0:13] is the sub-list for field type_name } func init() { file_messages_proto_init() } @@ -1171,7 +1290,7 @@ func file_messages_proto_init() { } } file_messages_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ToServerMessage_ConversationRequest); i { + switch v := v.(*File); i { case 0: return &v.state case 1: @@ -1183,7 +1302,7 @@ func file_messages_proto_init() { } } file_messages_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FromServerMessage_ConversationResponse); i { + switch v := v.(*ToServerMessage_ConversationRequest); i { case 0: return &v.state case 1: @@ -1195,7 +1314,7 @@ func file_messages_proto_init() { } } file_messages_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserMessage_ConversationStatus); i { + switch v := v.(*FromServerMessage_ConversationResponse); i { case 0: return &v.state case 1: @@ -1207,6 +1326,18 @@ func file_messages_proto_init() { } } file_messages_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UserMessage_ConversationStatus); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UserMessage_Group); i { case 0: return &v.state @@ -1225,7 +1356,7 @@ func file_messages_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_messages_proto_rawDesc, NumEnums: 0, - NumMessages: 11, + NumMessages: 12, NumExtensions: 0, NumServices: 0, }, diff --git a/pb/messages.proto b/pb/messages.proto index d83bf43..3bbc2ce 100644 --- a/pb/messages.proto +++ b/pb/messages.proto @@ -58,7 +58,9 @@ message Server { string description=2; string publicKey = 3; string url = 4; - int32 confidenceLevel = 5; + bool publish = 5; // publish this server when asked for a list by server + bytes signature = 6; // signature of all previous field by the server itself + int32 confidenceLevel = 7; // additional info from the user } // structure describing a user contact card ie the minimum set of attributes for exchanging identities @@ -68,7 +70,8 @@ message ContactCard { string encryptionPublicKey= 3; string lookupPublicKey =4; repeated Server pullServers =5; - int32 version = 6; + uint32 version = 6; + string invitationId=7; } // structure for sending a message to be forwarded to another user in protobuf format @@ -106,4 +109,13 @@ message UserMessage { repeated ContactCard members = 2; } Group group = 8; + + File file = 9; +} + +message File { + string filename=1; + uint64 size=2; + uint32 chunk=3; + bytes data=4; } \ No newline at end of file