diff --git a/.gitignore b/.gitignore index 8f74b07..15b75ab 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,10 @@ -doc/protocol.aux -doc/protocol.fdb_latexmk -doc/protocol.fls -doc/protocol.log -doc/protocol.pdf -doc/protocol.synctex.gz +doc/*.aux +doc/*.fdb_latexmk +doc/*.fls +doc/*.log +doc/*.pdf +doc/*.synctex.gz +doc/generated out/doc/general_deployment/general_deployment.png out/doc/server_deployment/server_deployment.png *.json diff --git a/README.md b/README.md index c6c9cfb..26008d9 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,21 @@ # MEOW lib -## Go Mobile setup - go install golang.org/x/mobile/cmd/gobind@latest - go install golang.org/x/mobile/cmd/gomobile@latest - go get golang.org/x/mobile/bind -Replace "Get" by "get" in messages.pb.go +# Documentation generation +## required tools +* protoc +* protoc-gen-doc +* protoc-gen-uml +* go-plantuml +* plantuml (plantuml command is as shell script : `java -jar //plantuml-mit-.jar "$@"`) +## generation +run the shell scripts - gomobile bind -target android -androidapi=19 + cd pb + ./protogen.sh + + cd doc + ./docgen.sh + +# Tests -Look at the exported API and cry... -## Other option - GOOS=android GOARCH=arm64 go build -buildmode=c-archive -o libmeow.a diff --git a/client/config.go b/client/config.go index 508e04c..c8c16c8 100644 --- a/client/config.go +++ b/client/config.go @@ -35,6 +35,7 @@ type Config struct { Theme string `json:"theme,omitempty"` FingerprintEnable bool `json:"fingerprint_enable,omitempty"` ShowFavoriteContacts bool `json:"show_favorite_contacts,omitempty"` + NightModeEnable bool `json:"night_mode_enable,omitempty"` // Debug DbSuffix string `json:"db_suffix,omitempty"` diff --git a/client/peer.go b/client/peer.go index 7ec33bd..09ee3a5 100644 --- a/client/peer.go +++ b/client/peer.go @@ -71,10 +71,10 @@ func (pl *PeerList) GetFromName(name string) *Peer { return nil } -func (pl *PeerList) GetConversationRequests() []*meowlib.ToServerMessage_ConversationRequest { - var list []*meowlib.ToServerMessage_ConversationRequest +func (pl *PeerList) GetConversationRequests() []*meowlib.ConversationRequest { + var list []*meowlib.ConversationRequest for _, peer := range *pl { - var cr meowlib.ToServerMessage_ConversationRequest + var cr meowlib.ConversationRequest cr.LookupKey = peer.MyLookupKp.Public // TODO Add key signature list = append(list, &cr) @@ -88,7 +88,7 @@ func (p *Peer) BuildSimpleUserMessage(message []byte) (*meowlib.UserMessage, err msg.From = p.MyIdentity.Public msg.Data = message msg.Type = "1" - msg.Status = &meowlib.UserMessage_ConversationStatus{} + msg.Status = &meowlib.ConversationStatus{} msg.Status.LocalUuid = uuid.New().String() return &msg, nil } @@ -132,7 +132,7 @@ func (p *Peer) BuildSingleFileMessage(filename string, message []byte) ([]meowli msg.Files = append(msg.Files, &file) msg.Type = "2" if chunk == 0 { - msg.Status = &meowlib.UserMessage_ConversationStatus{} + msg.Status = &meowlib.ConversationStatus{} msg.Status.LocalUuid = uuid.New().String() } msgs = append(msgs, msg) @@ -196,8 +196,8 @@ func (p *Peer) UnPackUserMessage(protoPackedMessage []byte) (payload []byte, sig return msg.Payload, msg.Signature, nil } -func (p *Peer) GetConversationRequest() *meowlib.ToServerMessage_ConversationRequest { - var cr meowlib.ToServerMessage_ConversationRequest +func (p *Peer) GetConversationRequest() *meowlib.ConversationRequest { + var cr meowlib.ConversationRequest return &cr } diff --git a/client/server.go b/client/server.go index 1954ba6..8c6d5d1 100644 --- a/client/server.go +++ b/client/server.go @@ -66,7 +66,7 @@ func (ints *InternalServer) AsymDecryptMessage(Message []byte, Signature []byte) return DecryptedMessage, err } -// Creates a basic message to server from a single packed user message and returns it as protobuf serialized byte array +// BuildToServerMessageFromUserMessage creates a basic message to server from a single packed user message and returns a meowlib.ToServerMessage func (ints *InternalServer) BuildToServerMessageFromUserMessage(usermsg *meowlib.PackedUserMessage) *meowlib.ToServerMessage { var msg meowlib.ToServerMessage msg.Uuid = uuid.New().String() @@ -76,7 +76,7 @@ func (ints *InternalServer) BuildToServerMessageFromUserMessage(usermsg *meowlib return &msg } -// Creates a basic message to server from a single packed user message and returns it as protobuf serialized byte array +// BuildMessageSendingMessage creates a basic message to server from a single packed user message and returns it as protobuf serialized byte array func (ints *InternalServer) BuildMessageSendingMessage(usermsg *meowlib.PackedUserMessage) ([]byte, error) { msg := ints.BuildToServerMessageFromUserMessage(usermsg) out, err := proto.Marshal(msg) @@ -86,7 +86,7 @@ func (ints *InternalServer) BuildMessageSendingMessage(usermsg *meowlib.PackedUs return out, nil } -// Creates a basic message to server from a single packed user message and returns it as protobuf serialized byte array +// BuildMessageRequestMessage creates a message lookup message to server and returns it as protobuf serialized byte array func (ints *InternalServer) BuildMessageRequestMessage(lookupKeys []string) ([]byte, error) { var msg meowlib.ToServerMessage msg.Uuid = uuid.New().String() @@ -100,7 +100,7 @@ func (ints *InternalServer) BuildMessageRequestMessage(lookupKeys []string) ([]b return out, nil } -// Creates a basic message to server from a single packed user message and returns it as protobuf serialized byte array +// BuildToServerMessageInvitation creates an invintatio message to server from a single packed user message and returns it as a meowlib.ToServerMessage func (ints *InternalServer) BuildToServerMessageInvitation(invitation *meowlib.ContactCard, password string, timeout int, urllen int) (*meowlib.ToServerMessage, error) { var msg meowlib.ToServerMessage var inv meowlib.Invitation diff --git a/doc/docgen.sh b/doc/docgen.sh new file mode 100755 index 0000000..f9c70a9 --- /dev/null +++ b/doc/docgen.sh @@ -0,0 +1,11 @@ +#!/bin/bash +go-plantuml generate -o generated/meowlib.puml -d .. +sed -i 's/\.\./meowlib\ /g' generated/meowlib.puml +go-plantuml generate -o generated/client.puml -d ../client +sed -i 's/\.\.\/client/client/g' generated/client.puml +go-plantuml generate -o generated/server.puml -d ../server +sed -i 's/\.\.\/server/server/g' generated/server.puml +cd generated +plantuml . + + diff --git a/doc/meow.tex b/doc/meow.tex new file mode 100644 index 0000000..7ad0b13 --- /dev/null +++ b/doc/meow.tex @@ -0,0 +1,223 @@ +\documentclass{article} +\usepackage{fetamont} +\begin{document} +\title{ + \textffm{Meow} messaging protocol} +\author{Author + \texttt{meow@redroom.link}} +\date{\today} + +\maketitle + +\begin{abstract} + + + The \textffm{Meow} protocol is a privacy driven instant messaging protocol. +That protocol might be used for creating secure and distributed chat services or allowing machine to machine communication. +This document describes the services provided by the protocol, the messaging structures and the transport protocols that might be used. +\begin{quote} + + \centering + \emph{"Nous ne vivrons pas d'utopie collective, nous arrivons trop tard, le grand marché est déjà là. +Nous devons élaborer des stratégies de survie et de contamination, par la prolifération d'utopies privées, cryptées, qui se substitueront à l'ancien ordre social. +Tout ce que je sais, c'est que nous vivons dans un monde dont on ne s'évade pas"}\\ +\footnotesize{Maurice G. Dantec for NOII (1997)} +\end{quote} +\end{abstract} + + +\section{Services} +\subsection{Unregulated identities} +The only requirement to get a valid \textffm{Meow} identity is to generate a user key pair. +No phone number or email check will be performed, unlike main instant messaging protocols, there is no central administration. + +\subsection{Fine grained privacy control} + +\subsubsection{Trustable server based communication} +Like most widely available messaging softwares, (Whatsapp, Signal, Viber, Telegram...), \textffm{Meow} provides a simple server based messaging. +The main difference is that \textffm{Meow} allows you to explicitly choose which server you want to use. +The server code being open source, we strongly encourage you to run your own server at home or in your company. +The server requires very few ressources and will run on any low cost single board computer. + +\subsubsection{Anonymized message transfer} +\textffm{Meow} also provides an anonymizing transfer service very similar to the Tor Onion protocol, we call it the Matriochka protocol. +Any server can be used for building the transfer chain. +Some of them might be marked as trusted. +Random delays might be set for each forwarding step, making the overall message tracking much more difficult, even with a global network survey. +It is strongly advised to use trusted servers as your first node and message server (the one that holds your incoming messages). + +\subsubsection{Presence protocol for direct messaging} +A presence service associating your conversation keys to your IP address for direct peer to peer connection is also provided. +The presence protocol is simply activated by setting a flag in the message poll requests. +If that flag is set, your encrypted IP will be published on the server, allowing your only your peer(s) to decrypt it and directly communicate with your terminal. + +\subsubsection{Peer based privacy settings} +You might define specific communication privacy preferences for each of your contacts: +\begin{itemize} + \item simple server based communication allowed for Joe, + \item preferred direct communication with Julian, fallback to my own server, + \item required matriochka protocol for Edward, first node is one of my trusted servers, my message node is my own server, randomly switch from trusted server lists for others. + \item ... +\end{itemize} + +\subsubsection{Resistance to device requisition / forensic} +All your contact information and discussion are encrypted on the device and password protected. +Password shall be asked on application startup and allows your identity file and contact decrytion. +That password is not recoverable, so you can't forget it, or you'll loose your whole configuration and identity. +Real security implies some constraints. +You might configure the app to save your password, but that is a security flaw. +In many authoritarian countries, you are required by law to provide your device passwords to authorities. +In a \textffm{Meow} device, you might set a specific password for some contacts. +Those contacts won't be visible when entering your main identity password. +You'll have to type their specific password in order to make them visible. +The \textffm{Meow} application will by default create a random set of fake hidden contacts and conversations. +Even in case of device storage analysis, authorities won't be able to differentiate a real hidden contact from an normal fake generated one. +It could be argued that this feature puts every user at risk, because authorities might think you're hiding something, even if you're not. +As every \textffm{Meow} user has the same constraint, users are not responsible for that. Moreover solidarity is also a requirement for real security. + +\subsection{Multiple devices support} +\textffm{Meow} allows you to be connected from multiple devices and offers chat synchronization capability. +A device might be revoqued anytime from any other one. Proof of your identity (password or other) shall be provided in order to grant device revocation. + +\subsection{Adding contacts} +If you want to add a new contact, keys will be generated, then a contact card will be created. +That contact card might be sent by any trustable communication means, or preferably from hand to hand, as a file on a flash disk or a QR code.\\ +In return your contact will provide a similar contact card as an answer to your invitation. + +\subsection{Contacts forwarding} +By using the \textffm{Meow} protocol a user won't be able to forward your contact information without your consent. +Each user knows you as a different identity, thus forwarding a known identity to another user is meaningless. Any message to that identity signed by another user than you would be discarded. + + +\subsection{Group conversation} +A very basic group messaging service is available. It allows to exchange group information between users. After that, a message to a group will send a copy of the message to each member. + + +\subsection{Emergency broadcast} +A local (server based) emergency broadcast service will be provided. It will provide the ability to send/receive broadcast messages to all users connected to the current server. + + +\subsection{Public networks shortage resilience} +\textffm{Meow} may run without Internet connection, either on an isolated wifi access point, or on a meshed network of wifi routers or even via serial IOT transport layers (LoRa,...) + + +\subsection{User directory service} +This service allows restoring a lost functionality of Internet historic chat services (like ICQ). You could simply set a "Free for chat" status that would allow other people to contact you, either randomly or based on a short description that you might provide. +Why providing that service while the internet is suffocating due to the abundance of social networks ?\\ +Well, that option offers a few advantages : +\begin{itemize} + \item you are still an anonymous user chatting with other anonymous users; + \item no social network algorithm will select people that think/behave/vote/eat... just like you. Diversity makes a better world; + \item a smaller community of users, skilled enough to operate a \textffm{Meow} chat app... that might provide a first filter; + It's a bit like in the early ages, when people had to be able to start a win98 computer, connect it to internet, then download and install ICQ... + If you lost some time in social networks, and experienced ICQ in the 2000's, you'll understand. +\end{itemize} + +\section{Identities and keys} + +\subsection{User identity} +Each \textffm{Meow} user has a unique identity. That identity is strictly private, only used to manage your own data (local encryption, devices, ...) +Let's call that one the User Key Pair (Ukp) + +\subsection{Contact identity} +Each of your contacts will know you under a different identity, we'll call that one the Contact Key Pair (Ckp) +That contact Key Pair will not change once it's agreed between both peers: an initial key will be exchanged as part of the peer invitation process. +As other people might have seen your key, this means that : +\begin{itemize} + \item none of your contacts will be able to forward your id to another person without your consent; + \item any message to that Ckp, not signed by its associated user, will be discarded. +\end{itemize} + +\subsection{Conversation encryption} +Each conversation with one of your contacts will be encrypted using an encryption keypair (Ekp) allowing cyphering your conversation. +The Ekp might be changed anytime by its owner and the new public key will be sent along the last message. + +\subsection{Conversation lookup} +A contact conversation Lookup Key Pair(Lkp) is also associated with your conversation. The Lkp public key is used to identify your conversation on a server. +The private key allows you to sign your request and prove the server that you are the legitimate recipient for a message. +This Lkp can be changed anytime by its owner and the new public key will be sent along the last message. +The Lkp and the Ekp are only changed once the change has beeen acknowledged by your contact. + +\subsection{Server identity} +Each server has a Server key (Skp). That key allows you to cypher the messages that you're sending to the server. + +\subsection{Device identity} +Each device is identified by a device key (Dkp) that allows you to perform secured exchanges between your devices for synchronization/revocation purposes. +Communication between devices is achieved using the same principle as the user to user communication. A device might be considered as any another user. The messages content is based on a synchronization protocol. + +\section{Contact management} +\subsection{Adding a contact} +Rendez-vous card, containing : +\begin{itemize} + \item Your public key for that contact; + \item An initial conversation public key for getting encrypted messages from that contact; + \item An initial conversation uuid that you'll use to lookup for incoming messages on the servers; + \item A list of your preferred message servers; + \item A signature to prevent transmission of tampered data. +\end{itemize} +\subsection{Sharing a contact} +If a user wants to forward one of his contacts to you, it will be handled as a double request: +\begin{enumerate} + \item I'm receiving a contact name, without any key + \item +\end{enumerate} + +\section{Messaging} +\subsection{User messages} +TODO + +\subsection{Server stored message} +TODO + +\subsection{Matriochka message packing} +TODO + +\subsection{Synchronization messages} +TODO + +\section{Transport protocols} +\subsection{URLs} +Server urls do define the protocol used for communicating with the server. +Some of the protocols will be described hereafter, but that list is not exhaustive and might be extended in the future.\\ +Examples of a valid url: +\begin{verbatim} +http://myserver.com +https://user:pass@myauthenticatedserver.net:8443 +mqtt://mymqttserver:6203 +udp://myudpserver.org:41325 +serial://dev/ttyS0 +\end{verbatim} + +\subsection{HTTP/S} +TODO + +\subsection{UDP} +TODO + +\subsection{Internetless alternative routing} +TODO + +\section{Server Features} +\subsection{Server catalog} +Each server will cache a list of all the servers that it is aware of. + +\subsection{Antispam} + +\subsection{Self defense} + + + + +\section{Backup} +\section{Recovery} + +\section{Very secure devices} +You don't trust your phone ? + +\section{Roadmap} +\subsection{Nations} +Beyond the scope of user directories, we plan to implement the concept of virtual Nations. +Today still, most people don't really choose the nation they live in. + + +\end{document} \ No newline at end of file diff --git a/doc/protocol.tex b/doc/protocol.tex index 7ad0b13..a049c28 100644 --- a/doc/protocol.tex +++ b/doc/protocol.tex @@ -1,16 +1,19 @@ \documentclass{article} \usepackage{fetamont} +\usepackage{listings} +\usepackage{protobuf/lang} % include language definition for protobuf +\usepackage{protobuf/style} % include custom style for proto declarations. \begin{document} \title{ - \textffm{Meow} messaging protocol} + \textffm{Meow} messaging protocol description} \author{Author - \texttt{meow@redroom.link}} + \texttt{meow@redroom.link}} \date{\today} \maketitle \begin{abstract} - + The \textffm{Meow} protocol is a privacy driven instant messaging protocol. That protocol might be used for creating secure and distributed chat services or allowing machine to machine communication. @@ -25,155 +28,13 @@ Tout ce que je sais, c'est que nous vivons dans un monde dont on ne s'évade pas \end{quote} \end{abstract} +\section{Identity creation} -\section{Services} -\subsection{Unregulated identities} -The only requirement to get a valid \textffm{Meow} identity is to generate a user key pair. -No phone number or email check will be performed, unlike main instant messaging protocols, there is no central administration. +\section{Messages structure} +\lstinputlisting[language=protobuf2,style=protobuf]{../pb/messages.proto} -\subsection{Fine grained privacy control} +\section{Invitation process} -\subsubsection{Trustable server based communication} -Like most widely available messaging softwares, (Whatsapp, Signal, Viber, Telegram...), \textffm{Meow} provides a simple server based messaging. -The main difference is that \textffm{Meow} allows you to explicitly choose which server you want to use. -The server code being open source, we strongly encourage you to run your own server at home or in your company. -The server requires very few ressources and will run on any low cost single board computer. - -\subsubsection{Anonymized message transfer} -\textffm{Meow} also provides an anonymizing transfer service very similar to the Tor Onion protocol, we call it the Matriochka protocol. -Any server can be used for building the transfer chain. -Some of them might be marked as trusted. -Random delays might be set for each forwarding step, making the overall message tracking much more difficult, even with a global network survey. -It is strongly advised to use trusted servers as your first node and message server (the one that holds your incoming messages). - -\subsubsection{Presence protocol for direct messaging} -A presence service associating your conversation keys to your IP address for direct peer to peer connection is also provided. -The presence protocol is simply activated by setting a flag in the message poll requests. -If that flag is set, your encrypted IP will be published on the server, allowing your only your peer(s) to decrypt it and directly communicate with your terminal. - -\subsubsection{Peer based privacy settings} -You might define specific communication privacy preferences for each of your contacts: -\begin{itemize} - \item simple server based communication allowed for Joe, - \item preferred direct communication with Julian, fallback to my own server, - \item required matriochka protocol for Edward, first node is one of my trusted servers, my message node is my own server, randomly switch from trusted server lists for others. - \item ... -\end{itemize} - -\subsubsection{Resistance to device requisition / forensic} -All your contact information and discussion are encrypted on the device and password protected. -Password shall be asked on application startup and allows your identity file and contact decrytion. -That password is not recoverable, so you can't forget it, or you'll loose your whole configuration and identity. -Real security implies some constraints. -You might configure the app to save your password, but that is a security flaw. -In many authoritarian countries, you are required by law to provide your device passwords to authorities. -In a \textffm{Meow} device, you might set a specific password for some contacts. -Those contacts won't be visible when entering your main identity password. -You'll have to type their specific password in order to make them visible. -The \textffm{Meow} application will by default create a random set of fake hidden contacts and conversations. -Even in case of device storage analysis, authorities won't be able to differentiate a real hidden contact from an normal fake generated one. -It could be argued that this feature puts every user at risk, because authorities might think you're hiding something, even if you're not. -As every \textffm{Meow} user has the same constraint, users are not responsible for that. Moreover solidarity is also a requirement for real security. - -\subsection{Multiple devices support} -\textffm{Meow} allows you to be connected from multiple devices and offers chat synchronization capability. -A device might be revoqued anytime from any other one. Proof of your identity (password or other) shall be provided in order to grant device revocation. - -\subsection{Adding contacts} -If you want to add a new contact, keys will be generated, then a contact card will be created. -That contact card might be sent by any trustable communication means, or preferably from hand to hand, as a file on a flash disk or a QR code.\\ -In return your contact will provide a similar contact card as an answer to your invitation. - -\subsection{Contacts forwarding} -By using the \textffm{Meow} protocol a user won't be able to forward your contact information without your consent. -Each user knows you as a different identity, thus forwarding a known identity to another user is meaningless. Any message to that identity signed by another user than you would be discarded. - - -\subsection{Group conversation} -A very basic group messaging service is available. It allows to exchange group information between users. After that, a message to a group will send a copy of the message to each member. - - -\subsection{Emergency broadcast} -A local (server based) emergency broadcast service will be provided. It will provide the ability to send/receive broadcast messages to all users connected to the current server. - - -\subsection{Public networks shortage resilience} -\textffm{Meow} may run without Internet connection, either on an isolated wifi access point, or on a meshed network of wifi routers or even via serial IOT transport layers (LoRa,...) - - -\subsection{User directory service} -This service allows restoring a lost functionality of Internet historic chat services (like ICQ). You could simply set a "Free for chat" status that would allow other people to contact you, either randomly or based on a short description that you might provide. -Why providing that service while the internet is suffocating due to the abundance of social networks ?\\ -Well, that option offers a few advantages : -\begin{itemize} - \item you are still an anonymous user chatting with other anonymous users; - \item no social network algorithm will select people that think/behave/vote/eat... just like you. Diversity makes a better world; - \item a smaller community of users, skilled enough to operate a \textffm{Meow} chat app... that might provide a first filter; - It's a bit like in the early ages, when people had to be able to start a win98 computer, connect it to internet, then download and install ICQ... - If you lost some time in social networks, and experienced ICQ in the 2000's, you'll understand. -\end{itemize} - -\section{Identities and keys} - -\subsection{User identity} -Each \textffm{Meow} user has a unique identity. That identity is strictly private, only used to manage your own data (local encryption, devices, ...) -Let's call that one the User Key Pair (Ukp) - -\subsection{Contact identity} -Each of your contacts will know you under a different identity, we'll call that one the Contact Key Pair (Ckp) -That contact Key Pair will not change once it's agreed between both peers: an initial key will be exchanged as part of the peer invitation process. -As other people might have seen your key, this means that : -\begin{itemize} - \item none of your contacts will be able to forward your id to another person without your consent; - \item any message to that Ckp, not signed by its associated user, will be discarded. -\end{itemize} - -\subsection{Conversation encryption} -Each conversation with one of your contacts will be encrypted using an encryption keypair (Ekp) allowing cyphering your conversation. -The Ekp might be changed anytime by its owner and the new public key will be sent along the last message. - -\subsection{Conversation lookup} -A contact conversation Lookup Key Pair(Lkp) is also associated with your conversation. The Lkp public key is used to identify your conversation on a server. -The private key allows you to sign your request and prove the server that you are the legitimate recipient for a message. -This Lkp can be changed anytime by its owner and the new public key will be sent along the last message. -The Lkp and the Ekp are only changed once the change has beeen acknowledged by your contact. - -\subsection{Server identity} -Each server has a Server key (Skp). That key allows you to cypher the messages that you're sending to the server. - -\subsection{Device identity} -Each device is identified by a device key (Dkp) that allows you to perform secured exchanges between your devices for synchronization/revocation purposes. -Communication between devices is achieved using the same principle as the user to user communication. A device might be considered as any another user. The messages content is based on a synchronization protocol. - -\section{Contact management} -\subsection{Adding a contact} -Rendez-vous card, containing : -\begin{itemize} - \item Your public key for that contact; - \item An initial conversation public key for getting encrypted messages from that contact; - \item An initial conversation uuid that you'll use to lookup for incoming messages on the servers; - \item A list of your preferred message servers; - \item A signature to prevent transmission of tampered data. -\end{itemize} -\subsection{Sharing a contact} -If a user wants to forward one of his contacts to you, it will be handled as a double request: -\begin{enumerate} - \item I'm receiving a contact name, without any key - \item -\end{enumerate} - -\section{Messaging} -\subsection{User messages} -TODO - -\subsection{Server stored message} -TODO - -\subsection{Matriochka message packing} -TODO - -\subsection{Synchronization messages} -TODO \section{Transport protocols} \subsection{URLs} diff --git a/message.go b/message.go index 0efa679..6ded4d0 100644 --- a/message.go +++ b/message.go @@ -35,7 +35,7 @@ func (msg *UserMessage) AddFile(filename string, maxMessageSize int64) error { file.Data = data msg.Files = append(msg.Files, &file) - msg.Status = &UserMessage_ConversationStatus{} + msg.Status = &ConversationStatus{} msg.Status.LocalUuid = uuid.New().String() return nil diff --git a/messages.pb.go b/messages.pb.go index ead12c1..75f24c7 100644 --- a/messages.pb.go +++ b/messages.pb.go @@ -4,6 +4,12 @@ // For example, field numbers in the range 1 through 15 take one byte to encode. // Field numbers in the range 16 through 2047 take two bytes. +//* +// Meow messages +// +// This is the Meow protocol protobuf messages description. +// + // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.26.0 @@ -96,13 +102,13 @@ type Invitation struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Payload []byte `protobuf:"bytes,1,opt,name=payload,proto3" json:"payload,omitempty"` - Timeout int32 `protobuf:"varint,2,opt,name=timeout,proto3" json:"timeout,omitempty"` - Idlen int32 `protobuf:"varint,3,opt,name=idlen,proto3" json:"idlen,omitempty"` - Password string `protobuf:"bytes,4,opt,name=password,proto3" json:"password,omitempty"` - Id string `protobuf:"bytes,5,opt,name=id,proto3" json:"id,omitempty"` - Expiry int64 `protobuf:"varint,6,opt,name=expiry,proto3" json:"expiry,omitempty"` - Step int32 `protobuf:"varint,7,opt,name=step,proto3" json:"step,omitempty"` + Payload []byte `protobuf:"bytes,1,opt,name=payload,proto3" json:"payload,omitempty"` // invitation payload, encrypted after step 2 + Timeout int32 `protobuf:"varint,2,opt,name=timeout,proto3" json:"timeout,omitempty"` // how long do I want the invitation to remain available on the server + Idlen int32 `protobuf:"varint,3,opt,name=idlen,proto3" json:"idlen,omitempty"` // len of the id you wish for short url transmission + Password string `protobuf:"bytes,4,opt,name=password,proto3" json:"password,omitempty"` // password tou set for accessin invitation (optional) + Id string `protobuf:"bytes,5,opt,name=id,proto3" json:"id,omitempty"` // id that the friend shall request to get teh invitation + Expiry int64 `protobuf:"varint,6,opt,name=expiry,proto3" json:"expiry,omitempty"` // the server allowed expiry date, it may be samller than the requested timeout according to server policy + Step int32 `protobuf:"varint,7,opt,name=step,proto3" json:"step,omitempty"` // progress in the inviattion process : 1=invite friend, 2=friend requests invitation, 3=friend's answer, 4=request answer } func (x *Invitation) Reset() { @@ -186,27 +192,99 @@ func (x *Invitation) GetStep() int32 { return 0 } +// structure for requesting incoming messages +type ConversationRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + LookupKey string `protobuf:"bytes,1,opt,name=lookupKey,proto3" json:"lookupKey,omitempty"` // lookup key for a conversation + LastServerUuidOK string `protobuf:"bytes,2,opt,name=lastServerUuidOK,proto3" json:"lastServerUuidOK,omitempty"` // Last Server message UUID received (send me all after that one) + PublishOnline bool `protobuf:"varint,3,opt,name=publishOnline,proto3" json:"publishOnline,omitempty"` // ?? Publish my online status for that contact ? + LookupSignature string `protobuf:"bytes,4,opt,name=lookupSignature,proto3" json:"lookupSignature,omitempty"` // prove that I own the private key by signing that block +} + +func (x *ConversationRequest) Reset() { + *x = ConversationRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ConversationRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConversationRequest) ProtoMessage() {} + +func (x *ConversationRequest) ProtoReflect() protoreflect.Message { + mi := &file_messages_proto_msgTypes[2] + 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 ConversationRequest.ProtoReflect.Descriptor instead. +func (*ConversationRequest) Descriptor() ([]byte, []int) { + return file_messages_proto_rawDescGZIP(), []int{2} +} + +func (x *ConversationRequest) GetLookupKey() string { + if x != nil { + return x.LookupKey + } + return "" +} + +func (x *ConversationRequest) GetLastServerUuidOK() string { + if x != nil { + return x.LastServerUuidOK + } + return "" +} + +func (x *ConversationRequest) GetPublishOnline() bool { + if x != nil { + return x.PublishOnline + } + return false +} + +func (x *ConversationRequest) GetLookupSignature() string { + if x != nil { + return x.LookupSignature + } + return "" +} + // structure defining a message for a server, that will be encrypted, then sent in a "packedmessage" payload type ToServerMessage struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` // Type 1 : final destination / 2 : forward - From string `protobuf:"bytes,2,opt,name=from,proto3" json:"from,omitempty"` // My pub key for the server to send me an encrypter answer - Payload []byte `protobuf:"bytes,3,opt,name=payload,proto3" json:"payload,omitempty"` // optional payload for server - PullRequest []*ToServerMessage_ConversationRequest `protobuf:"bytes,4,rep,name=pullRequest,proto3" json:"pullRequest,omitempty"` - Messages []*PackedUserMessage `protobuf:"bytes,5,rep,name=messages,proto3" json:"messages,omitempty"` - KnownServers []*Server `protobuf:"bytes,6,rep,name=knownServers,proto3" json:"knownServers,omitempty"` - MatriochkaMessage *Matriochka `protobuf:"bytes,7,opt,name=matriochkaMessage,proto3" json:"matriochkaMessage,omitempty"` - Uuid string `protobuf:"bytes,8,opt,name=uuid,proto3" json:"uuid,omitempty"` - Invitation *Invitation `protobuf:"bytes,9,opt,name=invitation,proto3" json:"invitation,omitempty"` + Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` // Type 1 : final destination / 2 : forward + From string `protobuf:"bytes,2,opt,name=from,proto3" json:"from,omitempty"` // My pub key for the server to send me an encrypter answer + Payload []byte `protobuf:"bytes,3,opt,name=payload,proto3" json:"payload,omitempty"` // optional payload for server + PullRequest []*ConversationRequest `protobuf:"bytes,4,rep,name=pullRequest,proto3" json:"pullRequest,omitempty"` + Messages []*PackedUserMessage `protobuf:"bytes,5,rep,name=messages,proto3" json:"messages,omitempty"` + KnownServers []*Server `protobuf:"bytes,6,rep,name=knownServers,proto3" json:"knownServers,omitempty"` + MatriochkaMessage *Matriochka `protobuf:"bytes,7,opt,name=matriochkaMessage,proto3" json:"matriochkaMessage,omitempty"` + Uuid string `protobuf:"bytes,8,opt,name=uuid,proto3" json:"uuid,omitempty"` + Invitation *Invitation `protobuf:"bytes,9,opt,name=invitation,proto3" json:"invitation,omitempty"` } func (x *ToServerMessage) Reset() { *x = ToServerMessage{} if protoimpl.UnsafeEnabled { - mi := &file_messages_proto_msgTypes[2] + mi := &file_messages_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -219,7 +297,7 @@ func (x *ToServerMessage) String() string { func (*ToServerMessage) ProtoMessage() {} func (x *ToServerMessage) ProtoReflect() protoreflect.Message { - mi := &file_messages_proto_msgTypes[2] + mi := &file_messages_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -232,7 +310,7 @@ func (x *ToServerMessage) ProtoReflect() protoreflect.Message { // Deprecated: Use ToServerMessage.ProtoReflect.Descriptor instead. func (*ToServerMessage) Descriptor() ([]byte, []int) { - return file_messages_proto_rawDescGZIP(), []int{2} + return file_messages_proto_rawDescGZIP(), []int{3} } func (x *ToServerMessage) GetType() string { @@ -256,7 +334,7 @@ func (x *ToServerMessage) GetPayload() []byte { return nil } -func (x *ToServerMessage) GetPullRequest() []*ToServerMessage_ConversationRequest { +func (x *ToServerMessage) GetPullRequest() []*ConversationRequest { if x != nil { return x.PullRequest } @@ -298,6 +376,53 @@ func (x *ToServerMessage) GetInvitation() *Invitation { return nil } +type ConversationResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + MessageUuids []string `protobuf:"bytes,1,rep,name=messageUuids,proto3" json:"messageUuids,omitempty"` +} + +func (x *ConversationResponse) Reset() { + *x = ConversationResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ConversationResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConversationResponse) ProtoMessage() {} + +func (x *ConversationResponse) ProtoReflect() protoreflect.Message { + mi := &file_messages_proto_msgTypes[4] + 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 ConversationResponse.ProtoReflect.Descriptor instead. +func (*ConversationResponse) Descriptor() ([]byte, []int) { + return file_messages_proto_rawDescGZIP(), []int{4} +} + +func (x *ConversationResponse) GetMessageUuids() []string { + if x != nil { + return x.MessageUuids + } + return nil +} + // structure defining a from server receiver message decrypted from a "packedmessage" payload type FromServerMessage struct { state protoimpl.MessageState @@ -317,7 +442,7 @@ type FromServerMessage struct { func (x *FromServerMessage) Reset() { *x = FromServerMessage{} if protoimpl.UnsafeEnabled { - mi := &file_messages_proto_msgTypes[3] + mi := &file_messages_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -330,7 +455,7 @@ func (x *FromServerMessage) String() string { func (*FromServerMessage) ProtoMessage() {} func (x *FromServerMessage) ProtoReflect() protoreflect.Message { - mi := &file_messages_proto_msgTypes[3] + mi := &file_messages_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -343,7 +468,7 @@ func (x *FromServerMessage) ProtoReflect() protoreflect.Message { // Deprecated: Use FromServerMessage.ProtoReflect.Descriptor instead. func (*FromServerMessage) Descriptor() ([]byte, []int) { - return file_messages_proto_rawDescGZIP(), []int{3} + return file_messages_proto_rawDescGZIP(), []int{5} } func (x *FromServerMessage) GetType() string { @@ -416,7 +541,7 @@ type MatriochkaServer struct { func (x *MatriochkaServer) Reset() { *x = MatriochkaServer{} if protoimpl.UnsafeEnabled { - mi := &file_messages_proto_msgTypes[4] + mi := &file_messages_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -429,7 +554,7 @@ func (x *MatriochkaServer) String() string { func (*MatriochkaServer) ProtoMessage() {} func (x *MatriochkaServer) ProtoReflect() protoreflect.Message { - mi := &file_messages_proto_msgTypes[4] + mi := &file_messages_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -442,7 +567,7 @@ func (x *MatriochkaServer) ProtoReflect() protoreflect.Message { // Deprecated: Use MatriochkaServer.ProtoReflect.Descriptor instead. func (*MatriochkaServer) Descriptor() ([]byte, []int) { - return file_messages_proto_rawDescGZIP(), []int{4} + return file_messages_proto_rawDescGZIP(), []int{6} } func (x *MatriochkaServer) GetUrl() string { @@ -487,7 +612,7 @@ type Matriochka struct { func (x *Matriochka) Reset() { *x = Matriochka{} if protoimpl.UnsafeEnabled { - mi := &file_messages_proto_msgTypes[5] + mi := &file_messages_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -500,7 +625,7 @@ func (x *Matriochka) String() string { func (*Matriochka) ProtoMessage() {} func (x *Matriochka) ProtoReflect() protoreflect.Message { - mi := &file_messages_proto_msgTypes[5] + mi := &file_messages_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -513,7 +638,7 @@ func (x *Matriochka) ProtoReflect() protoreflect.Message { // Deprecated: Use Matriochka.ProtoReflect.Descriptor instead. func (*Matriochka) Descriptor() ([]byte, []int) { - return file_messages_proto_rawDescGZIP(), []int{5} + return file_messages_proto_rawDescGZIP(), []int{7} } func (x *Matriochka) GetLookupKey() string { @@ -550,10 +675,10 @@ type Server struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - 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"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // friendly server name + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` // description : owner type (company/private/university...), + PublicKey string `protobuf:"bytes,3,opt,name=publicKey,proto3" json:"publicKey,omitempty"` // public key you must use to send encrypted messages to that server + Url string `protobuf:"bytes,4,opt,name=url,proto3" json:"url,omitempty"` // meow server url 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 fields by the server itself ConfidenceLevel int32 `protobuf:"varint,7,opt,name=confidenceLevel,proto3" json:"confidenceLevel,omitempty"` // additional info from the user @@ -562,7 +687,7 @@ type Server struct { func (x *Server) Reset() { *x = Server{} if protoimpl.UnsafeEnabled { - mi := &file_messages_proto_msgTypes[6] + mi := &file_messages_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -575,7 +700,7 @@ func (x *Server) String() string { func (*Server) ProtoMessage() {} func (x *Server) ProtoReflect() protoreflect.Message { - mi := &file_messages_proto_msgTypes[6] + mi := &file_messages_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -588,7 +713,7 @@ func (x *Server) ProtoReflect() protoreflect.Message { // Deprecated: Use Server.ProtoReflect.Descriptor instead. func (*Server) Descriptor() ([]byte, []int) { - return file_messages_proto_rawDescGZIP(), []int{6} + return file_messages_proto_rawDescGZIP(), []int{8} } func (x *Server) GetName() string { @@ -646,11 +771,11 @@ type ContactCard struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - ContactPublicKey string `protobuf:"bytes,2,opt,name=contactPublicKey,proto3" json:"contactPublicKey,omitempty"` - 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"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // contact nickname + ContactPublicKey string `protobuf:"bytes,2,opt,name=contactPublicKey,proto3" json:"contactPublicKey,omitempty"` // contact public key, will be used to authenticate her/his messages + EncryptionPublicKey string `protobuf:"bytes,3,opt,name=encryptionPublicKey,proto3" json:"encryptionPublicKey,omitempty"` // public key you must use to to write encrypted messages to that contact + LookupPublicKey string `protobuf:"bytes,4,opt,name=lookupPublicKey,proto3" json:"lookupPublicKey,omitempty"` // public key you will use as "destination identifier" for her/him to lookup for your messages on the servers + PullServers []*Server `protobuf:"bytes,5,rep,name=pullServers,proto3" json:"pullServers,omitempty"` // list the servers where the contact will look for messages from you Version uint32 `protobuf:"varint,6,opt,name=version,proto3" json:"version,omitempty"` InvitationId string `protobuf:"bytes,7,opt,name=invitationId,proto3" json:"invitationId,omitempty"` } @@ -658,7 +783,7 @@ type ContactCard struct { func (x *ContactCard) Reset() { *x = ContactCard{} if protoimpl.UnsafeEnabled { - mi := &file_messages_proto_msgTypes[7] + mi := &file_messages_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -671,7 +796,7 @@ func (x *ContactCard) String() string { func (*ContactCard) ProtoMessage() {} func (x *ContactCard) ProtoReflect() protoreflect.Message { - mi := &file_messages_proto_msgTypes[7] + mi := &file_messages_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -684,7 +809,7 @@ func (x *ContactCard) ProtoReflect() protoreflect.Message { // Deprecated: Use ContactCard.ProtoReflect.Descriptor instead. func (*ContactCard) Descriptor() ([]byte, []int) { - return file_messages_proto_rawDescGZIP(), []int{7} + return file_messages_proto_rawDescGZIP(), []int{9} } func (x *ContactCard) GetName() string { @@ -751,7 +876,7 @@ type PackedUserMessage struct { func (x *PackedUserMessage) Reset() { *x = PackedUserMessage{} if protoimpl.UnsafeEnabled { - mi := &file_messages_proto_msgTypes[8] + mi := &file_messages_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -764,7 +889,7 @@ func (x *PackedUserMessage) String() string { func (*PackedUserMessage) ProtoMessage() {} func (x *PackedUserMessage) ProtoReflect() protoreflect.Message { - mi := &file_messages_proto_msgTypes[8] + mi := &file_messages_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -777,7 +902,7 @@ func (x *PackedUserMessage) ProtoReflect() protoreflect.Message { // Deprecated: Use PackedUserMessage.ProtoReflect.Descriptor instead. func (*PackedUserMessage) Descriptor() ([]byte, []int) { - return file_messages_proto_rawDescGZIP(), []int{8} + return file_messages_proto_rawDescGZIP(), []int{10} } func (x *PackedUserMessage) GetDestination() string { @@ -808,29 +933,179 @@ func (x *PackedUserMessage) GetServerTimestamp() []int64 { return nil } +type ConversationStatus struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + LocalUuid string `protobuf:"bytes,1,opt,name=localUuid,proto3" json:"localUuid,omitempty"` + LocalSequence uint64 `protobuf:"varint,2,opt,name=localSequence,proto3" json:"localSequence,omitempty"` + Sent uint64 `protobuf:"varint,3,opt,name=sent,proto3" json:"sent,omitempty"` + Received uint64 `protobuf:"varint,4,opt,name=received,proto3" json:"received,omitempty"` + Processed uint64 `protobuf:"varint,5,opt,name=processed,proto3" json:"processed,omitempty"` + MyNextIdentity *ContactCard `protobuf:"bytes,6,opt,name=myNextIdentity,proto3" json:"myNextIdentity,omitempty"` + PeerNextIdentityAck int32 `protobuf:"varint,7,opt,name=peerNextIdentityAck,proto3" json:"peerNextIdentityAck,omitempty"` // version of the new peer accepted id +} + +func (x *ConversationStatus) Reset() { + *x = ConversationStatus{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ConversationStatus) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConversationStatus) ProtoMessage() {} + +func (x *ConversationStatus) ProtoReflect() protoreflect.Message { + mi := &file_messages_proto_msgTypes[11] + 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 ConversationStatus.ProtoReflect.Descriptor instead. +func (*ConversationStatus) Descriptor() ([]byte, []int) { + return file_messages_proto_rawDescGZIP(), []int{11} +} + +func (x *ConversationStatus) GetLocalUuid() string { + if x != nil { + return x.LocalUuid + } + return "" +} + +func (x *ConversationStatus) GetLocalSequence() uint64 { + if x != nil { + return x.LocalSequence + } + return 0 +} + +func (x *ConversationStatus) GetSent() uint64 { + if x != nil { + return x.Sent + } + return 0 +} + +func (x *ConversationStatus) GetReceived() uint64 { + if x != nil { + return x.Received + } + return 0 +} + +func (x *ConversationStatus) GetProcessed() uint64 { + if x != nil { + return x.Processed + } + return 0 +} + +func (x *ConversationStatus) GetMyNextIdentity() *ContactCard { + if x != nil { + return x.MyNextIdentity + } + return nil +} + +func (x *ConversationStatus) GetPeerNextIdentityAck() int32 { + if x != nil { + return x.PeerNextIdentityAck + } + return 0 +} + +type Group struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Members []*ContactCard `protobuf:"bytes,2,rep,name=members,proto3" json:"members,omitempty"` +} + +func (x *Group) Reset() { + *x = Group{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Group) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Group) ProtoMessage() {} + +func (x *Group) ProtoReflect() protoreflect.Message { + mi := &file_messages_proto_msgTypes[12] + 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 Group.ProtoReflect.Descriptor instead. +func (*Group) Descriptor() ([]byte, []int) { + return file_messages_proto_rawDescGZIP(), []int{12} +} + +func (x *Group) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Group) GetMembers() []*ContactCard { + if x != nil { + return x.Members + } + return nil +} + // structure defining information that might be exchanged between two peers. type UserMessage struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Destination string `protobuf:"bytes,1,opt,name=destination,proto3" json:"destination,omitempty"` // Lookupkey - From string `protobuf:"bytes,2,opt,name=from,proto3" json:"from,omitempty"` // My public key for that contact - Type string `protobuf:"bytes,3,opt,name=type,proto3" json:"type,omitempty"` - Data []byte `protobuf:"bytes,4,opt,name=data,proto3" json:"data,omitempty"` - Status *UserMessage_ConversationStatus `protobuf:"bytes,5,opt,name=Status,proto3" json:"Status,omitempty"` - 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"` - Files []*File `protobuf:"bytes,9,rep,name=files,proto3" json:"files,omitempty"` - CurrentLocation *Location `protobuf:"bytes,10,opt,name=currentLocation,proto3" json:"currentLocation,omitempty"` - Appdata []byte `protobuf:"bytes,11,opt,name=appdata,proto3" json:"appdata,omitempty"` + Destination string `protobuf:"bytes,1,opt,name=destination,proto3" json:"destination,omitempty"` // Lookupkey + From string `protobuf:"bytes,2,opt,name=from,proto3" json:"from,omitempty"` // My public key for that contact + Type string `protobuf:"bytes,3,opt,name=type,proto3" json:"type,omitempty"` + Data []byte `protobuf:"bytes,4,opt,name=data,proto3" json:"data,omitempty"` + Status *ConversationStatus `protobuf:"bytes,5,opt,name=Status,proto3" json:"Status,omitempty"` + 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 *Group `protobuf:"bytes,8,opt,name=group,proto3" json:"group,omitempty"` + Files []*File `protobuf:"bytes,9,rep,name=files,proto3" json:"files,omitempty"` + CurrentLocation *Location `protobuf:"bytes,10,opt,name=currentLocation,proto3" json:"currentLocation,omitempty"` + Appdata []byte `protobuf:"bytes,11,opt,name=appdata,proto3" json:"appdata,omitempty"` } func (x *UserMessage) Reset() { *x = UserMessage{} if protoimpl.UnsafeEnabled { - mi := &file_messages_proto_msgTypes[9] + mi := &file_messages_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -843,7 +1118,7 @@ func (x *UserMessage) String() string { func (*UserMessage) ProtoMessage() {} func (x *UserMessage) ProtoReflect() protoreflect.Message { - mi := &file_messages_proto_msgTypes[9] + mi := &file_messages_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -856,7 +1131,7 @@ func (x *UserMessage) ProtoReflect() protoreflect.Message { // Deprecated: Use UserMessage.ProtoReflect.Descriptor instead. func (*UserMessage) Descriptor() ([]byte, []int) { - return file_messages_proto_rawDescGZIP(), []int{9} + return file_messages_proto_rawDescGZIP(), []int{13} } func (x *UserMessage) GetDestination() string { @@ -887,7 +1162,7 @@ func (x *UserMessage) GetData() []byte { return nil } -func (x *UserMessage) GetStatus() *UserMessage_ConversationStatus { +func (x *UserMessage) GetStatus() *ConversationStatus { if x != nil { return x.Status } @@ -908,7 +1183,7 @@ func (x *UserMessage) GetKnownServers() *Server { return nil } -func (x *UserMessage) GetGroup() *UserMessage_Group { +func (x *UserMessage) GetGroup() *Group { if x != nil { return x.Group } @@ -950,7 +1225,7 @@ type File struct { func (x *File) Reset() { *x = File{} if protoimpl.UnsafeEnabled { - mi := &file_messages_proto_msgTypes[10] + mi := &file_messages_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -963,7 +1238,7 @@ func (x *File) String() string { func (*File) ProtoMessage() {} func (x *File) ProtoReflect() protoreflect.Message { - mi := &file_messages_proto_msgTypes[10] + mi := &file_messages_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -976,7 +1251,7 @@ func (x *File) ProtoReflect() protoreflect.Message { // Deprecated: Use File.ProtoReflect.Descriptor instead. func (*File) Descriptor() ([]byte, []int) { - return file_messages_proto_rawDescGZIP(), []int{10} + return file_messages_proto_rawDescGZIP(), []int{14} } func (x *File) GetFilename() string { @@ -1021,7 +1296,7 @@ type Location struct { func (x *Location) Reset() { *x = Location{} if protoimpl.UnsafeEnabled { - mi := &file_messages_proto_msgTypes[11] + mi := &file_messages_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1034,7 +1309,7 @@ func (x *Location) String() string { func (*Location) ProtoMessage() {} func (x *Location) ProtoReflect() protoreflect.Message { - mi := &file_messages_proto_msgTypes[11] + mi := &file_messages_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1047,7 +1322,7 @@ func (x *Location) ProtoReflect() protoreflect.Message { // Deprecated: Use Location.ProtoReflect.Descriptor instead. func (*Location) Descriptor() ([]byte, []int) { - return file_messages_proto_rawDescGZIP(), []int{11} + return file_messages_proto_rawDescGZIP(), []int{15} } func (x *Location) GetTime() uint64 { @@ -1078,275 +1353,6 @@ func (x *Location) GetAltitude() int32 { return 0 } -// structure for requesting incoming messages -type ToServerMessage_ConversationRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - LookupKey string `protobuf:"bytes,1,opt,name=lookupKey,proto3" json:"lookupKey,omitempty"` // lookup key for a conversation - LastServerUuidOK string `protobuf:"bytes,2,opt,name=lastServerUuidOK,proto3" json:"lastServerUuidOK,omitempty"` // Last Server message UUID received (send me all after that one) - PublishOnline bool `protobuf:"varint,3,opt,name=publishOnline,proto3" json:"publishOnline,omitempty"` // ?? Publish my online status for that contact ? - LookupSignature string `protobuf:"bytes,4,opt,name=lookupSignature,proto3" json:"lookupSignature,omitempty"` // prove that I own the private key by signing that block -} - -func (x *ToServerMessage_ConversationRequest) Reset() { - *x = ToServerMessage_ConversationRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_messages_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ToServerMessage_ConversationRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ToServerMessage_ConversationRequest) ProtoMessage() {} - -func (x *ToServerMessage_ConversationRequest) ProtoReflect() protoreflect.Message { - mi := &file_messages_proto_msgTypes[12] - 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 ToServerMessage_ConversationRequest.ProtoReflect.Descriptor instead. -func (*ToServerMessage_ConversationRequest) Descriptor() ([]byte, []int) { - return file_messages_proto_rawDescGZIP(), []int{2, 0} -} - -func (x *ToServerMessage_ConversationRequest) GetLookupKey() string { - if x != nil { - return x.LookupKey - } - return "" -} - -func (x *ToServerMessage_ConversationRequest) GetLastServerUuidOK() string { - if x != nil { - return x.LastServerUuidOK - } - return "" -} - -func (x *ToServerMessage_ConversationRequest) GetPublishOnline() bool { - if x != nil { - return x.PublishOnline - } - return false -} - -func (x *ToServerMessage_ConversationRequest) GetLookupSignature() string { - if x != nil { - return x.LookupSignature - } - return "" -} - -type FromServerMessage_ConversationResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - MessageUuids []string `protobuf:"bytes,1,rep,name=messageUuids,proto3" json:"messageUuids,omitempty"` -} - -func (x *FromServerMessage_ConversationResponse) Reset() { - *x = FromServerMessage_ConversationResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_messages_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *FromServerMessage_ConversationResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*FromServerMessage_ConversationResponse) ProtoMessage() {} - -func (x *FromServerMessage_ConversationResponse) ProtoReflect() protoreflect.Message { - mi := &file_messages_proto_msgTypes[13] - 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 FromServerMessage_ConversationResponse.ProtoReflect.Descriptor instead. -func (*FromServerMessage_ConversationResponse) Descriptor() ([]byte, []int) { - return file_messages_proto_rawDescGZIP(), []int{3, 0} -} - -func (x *FromServerMessage_ConversationResponse) GetMessageUuids() []string { - if x != nil { - return x.MessageUuids - } - return nil -} - -type UserMessage_ConversationStatus struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - LocalUuid string `protobuf:"bytes,1,opt,name=localUuid,proto3" json:"localUuid,omitempty"` - LocalSequence uint64 `protobuf:"varint,2,opt,name=localSequence,proto3" json:"localSequence,omitempty"` - Sent uint64 `protobuf:"varint,3,opt,name=sent,proto3" json:"sent,omitempty"` - Received uint64 `protobuf:"varint,4,opt,name=received,proto3" json:"received,omitempty"` - Processed uint64 `protobuf:"varint,5,opt,name=processed,proto3" json:"processed,omitempty"` - MyNextIdentity *ContactCard `protobuf:"bytes,6,opt,name=myNextIdentity,proto3" json:"myNextIdentity,omitempty"` - PeerNextIdentityAck int32 `protobuf:"varint,7,opt,name=peerNextIdentityAck,proto3" json:"peerNextIdentityAck,omitempty"` // version of the new peer accepted id -} - -func (x *UserMessage_ConversationStatus) Reset() { - *x = UserMessage_ConversationStatus{} - if protoimpl.UnsafeEnabled { - mi := &file_messages_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *UserMessage_ConversationStatus) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UserMessage_ConversationStatus) ProtoMessage() {} - -func (x *UserMessage_ConversationStatus) ProtoReflect() protoreflect.Message { - mi := &file_messages_proto_msgTypes[14] - 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 UserMessage_ConversationStatus.ProtoReflect.Descriptor instead. -func (*UserMessage_ConversationStatus) Descriptor() ([]byte, []int) { - return file_messages_proto_rawDescGZIP(), []int{9, 0} -} - -func (x *UserMessage_ConversationStatus) GetLocalUuid() string { - if x != nil { - return x.LocalUuid - } - return "" -} - -func (x *UserMessage_ConversationStatus) GetLocalSequence() uint64 { - if x != nil { - return x.LocalSequence - } - return 0 -} - -func (x *UserMessage_ConversationStatus) GetSent() uint64 { - if x != nil { - return x.Sent - } - return 0 -} - -func (x *UserMessage_ConversationStatus) GetReceived() uint64 { - if x != nil { - return x.Received - } - return 0 -} - -func (x *UserMessage_ConversationStatus) GetProcessed() uint64 { - if x != nil { - return x.Processed - } - return 0 -} - -func (x *UserMessage_ConversationStatus) GetMyNextIdentity() *ContactCard { - if x != nil { - return x.MyNextIdentity - } - return nil -} - -func (x *UserMessage_ConversationStatus) GetPeerNextIdentityAck() int32 { - if x != nil { - return x.PeerNextIdentityAck - } - return 0 -} - -type UserMessage_Group struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Members []*ContactCard `protobuf:"bytes,2,rep,name=members,proto3" json:"members,omitempty"` -} - -func (x *UserMessage_Group) Reset() { - *x = UserMessage_Group{} - if protoimpl.UnsafeEnabled { - mi := &file_messages_proto_msgTypes[15] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *UserMessage_Group) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UserMessage_Group) ProtoMessage() {} - -func (x *UserMessage_Group) ProtoReflect() protoreflect.Message { - mi := &file_messages_proto_msgTypes[15] - 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 UserMessage_Group.ProtoReflect.Descriptor instead. -func (*UserMessage_Group) Descriptor() ([]byte, []int) { - return file_messages_proto_rawDescGZIP(), []int{9, 1} -} - -func (x *UserMessage_Group) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *UserMessage_Group) GetMembers() []*ContactCard { - if x != nil { - return x.Members - } - return nil -} - var File_messages_proto protoreflect.FileDescriptor var file_messages_proto_rawDesc = []byte{ @@ -1368,68 +1374,67 @@ var file_messages_proto_rawDesc = []byte{ 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x74, 0x65, - 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x73, 0x74, 0x65, 0x70, 0x22, 0xce, 0x04, - 0x0a, 0x0f, 0x54, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, - 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, - 0x6f, 0x61, 0x64, 0x12, 0x4e, 0x0a, 0x0b, 0x70, 0x75, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c, - 0x69, 0x62, 0x2e, 0x54, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0b, 0x70, 0x75, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x36, 0x0a, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, - 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, - 0x50, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x52, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x33, 0x0a, 0x0c, 0x6b, - 0x6e, 0x6f, 0x77, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, 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, 0x41, 0x0a, 0x11, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x6f, 0x63, 0x68, 0x6b, 0x61, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6d, 0x65, - 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x6f, 0x63, 0x68, 0x6b, 0x61, - 0x52, 0x11, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x6f, 0x63, 0x68, 0x6b, 0x61, 0x4d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x33, 0x0a, 0x0a, 0x69, 0x6e, 0x76, 0x69, 0x74, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6d, 0x65, + 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x73, 0x74, 0x65, 0x70, 0x22, 0xaf, 0x01, + 0x0a, 0x13, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x4b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, + 0x4b, 0x65, 0x79, 0x12, 0x2a, 0x0a, 0x10, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x55, 0x75, 0x69, 0x64, 0x4f, 0x4b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x6c, + 0x61, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x55, 0x75, 0x69, 0x64, 0x4f, 0x4b, 0x12, + 0x24, 0x0a, 0x0d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x4f, + 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x53, + 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, + 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, + 0x8c, 0x03, 0x0a, 0x0f, 0x54, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x18, 0x0a, 0x07, 0x70, + 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x61, + 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x3e, 0x0a, 0x0b, 0x70, 0x75, 0x6c, 0x6c, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6d, 0x65, 0x6f, + 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0b, 0x70, 0x75, 0x6c, 0x6c, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x36, 0x0a, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, + 0x62, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x33, 0x0a, + 0x0c, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, + 0x03, 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, 0x41, 0x0a, 0x11, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x6f, 0x63, 0x68, 0x6b, 0x61, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, + 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x6f, 0x63, 0x68, + 0x6b, 0x61, 0x52, 0x11, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x6f, 0x63, 0x68, 0x6b, 0x61, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x08, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x33, 0x0a, 0x0a, 0x69, 0x6e, 0x76, + 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, + 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x0a, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 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, 0xbf, 0x02, 0x0a, 0x11, 0x46, + 0x72, 0x6f, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x74, 0x79, 0x70, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, 0x75, + 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x18, + 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x75, 0x75, 0x69, 0x64, + 0x41, 0x63, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x75, 0x75, 0x69, 0x64, 0x41, + 0x63, 0x6b, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x55, 0x75, 0x69, 0x64, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x55, 0x75, + 0x69, 0x64, 0x12, 0x2e, 0x0a, 0x04, 0x63, 0x68, 0x61, 0x74, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x65, + 0x64, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x04, 0x63, 0x68, + 0x61, 0x74, 0x12, 0x33, 0x0a, 0x0c, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x73, 0x18, 0x07, 0x20, 0x03, 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, 0x33, 0x0a, 0x0a, 0x69, 0x6e, 0x76, 0x69, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x0a, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0xaf, 0x01, 0x0a, - 0x13, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x4b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x4b, - 0x65, 0x79, 0x12, 0x2a, 0x0a, 0x10, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x55, 0x75, 0x69, 0x64, 0x4f, 0x4b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x6c, 0x61, - 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x55, 0x75, 0x69, 0x64, 0x4f, 0x4b, 0x12, 0x24, - 0x0a, 0x0d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x4f, 0x6e, - 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x53, 0x69, - 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x6c, - 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0xfb, - 0x02, 0x0a, 0x11, 0x46, 0x72, 0x6f, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, - 0x65, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x18, 0x0a, 0x07, - 0x75, 0x75, 0x69, 0x64, 0x41, 0x63, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x75, - 0x75, 0x69, 0x64, 0x41, 0x63, 0x6b, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x55, 0x75, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x55, 0x75, 0x69, 0x64, 0x12, 0x2e, 0x0a, 0x04, 0x63, 0x68, 0x61, 0x74, 0x18, 0x06, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x50, - 0x61, 0x63, 0x6b, 0x65, 0x64, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x52, 0x04, 0x63, 0x68, 0x61, 0x74, 0x12, 0x33, 0x0a, 0x0c, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x53, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x18, 0x07, 0x20, 0x03, 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, 0x33, 0x0a, 0x0a, 0x69, - 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x13, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 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, 0x6c, 0x0a, 0x10, + 0x52, 0x0a, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x6c, 0x0a, 0x10, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x6f, 0x63, 0x68, 0x6b, 0x61, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x18, @@ -1487,73 +1492,72 @@ var file_messages_proto_rawDesc = []byte{ 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, 0xa5, 0x06, 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, 0x12, 0x23, 0x0a, 0x05, 0x66, 0x69, 0x6c, - 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c, - 0x69, 0x62, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x05, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x3b, - 0x0a, 0x0f, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, - 0x62, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0f, 0x63, 0x75, 0x72, 0x72, - 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x61, - 0x70, 0x70, 0x64, 0x61, 0x74, 0x61, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x70, - 0x70, 0x64, 0x61, 0x74, 0x61, 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, 0x22, 0x74, 0x0a, - 0x08, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, 0x6d, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x1a, 0x0a, - 0x08, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x02, 0x52, - 0x08, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6c, 0x6f, 0x6e, - 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x02, 0x52, 0x09, 0x6c, 0x6f, - 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x6c, 0x74, 0x69, 0x74, - 0x75, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x61, 0x6c, 0x74, 0x69, 0x74, - 0x75, 0x64, 0x65, 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, + 0x61, 0x6d, 0x70, 0x22, 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, 0x22, 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, 0xa7, 0x03, 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, 0x33, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, + 0x62, 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, 0x24, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x0e, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, + 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x23, 0x0a, 0x05, 0x66, 0x69, 0x6c, 0x65, 0x73, + 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, + 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x05, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x3b, 0x0a, 0x0f, + 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, + 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0f, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, + 0x74, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x70, 0x70, + 0x64, 0x61, 0x74, 0x61, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x70, 0x70, 0x64, + 0x61, 0x74, 0x61, 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, 0x22, 0x74, 0x0a, 0x08, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x02, 0x52, 0x08, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, + 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x02, 0x52, 0x09, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x12, + 0x1a, 0x0a, 0x08, 0x61, 0x6c, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x08, 0x61, 0x6c, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 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 ( @@ -1570,43 +1574,43 @@ func file_messages_proto_rawDescGZIP() []byte { var file_messages_proto_msgTypes = make([]protoimpl.MessageInfo, 16) var file_messages_proto_goTypes = []interface{}{ - (*PackedServerMessage)(nil), // 0: meowlib.PackedServerMessage - (*Invitation)(nil), // 1: meowlib.Invitation - (*ToServerMessage)(nil), // 2: meowlib.ToServerMessage - (*FromServerMessage)(nil), // 3: meowlib.FromServerMessage - (*MatriochkaServer)(nil), // 4: meowlib.MatriochkaServer - (*Matriochka)(nil), // 5: meowlib.Matriochka - (*Server)(nil), // 6: meowlib.Server - (*ContactCard)(nil), // 7: meowlib.ContactCard - (*PackedUserMessage)(nil), // 8: meowlib.PackedUserMessage - (*UserMessage)(nil), // 9: meowlib.UserMessage - (*File)(nil), // 10: meowlib.File - (*Location)(nil), // 11: meowlib.Location - (*ToServerMessage_ConversationRequest)(nil), // 12: meowlib.ToServerMessage.ConversationRequest - (*FromServerMessage_ConversationResponse)(nil), // 13: meowlib.FromServerMessage.ConversationResponse - (*UserMessage_ConversationStatus)(nil), // 14: meowlib.UserMessage.ConversationStatus - (*UserMessage_Group)(nil), // 15: meowlib.UserMessage.Group + (*PackedServerMessage)(nil), // 0: meowlib.PackedServerMessage + (*Invitation)(nil), // 1: meowlib.Invitation + (*ConversationRequest)(nil), // 2: meowlib.ConversationRequest + (*ToServerMessage)(nil), // 3: meowlib.ToServerMessage + (*ConversationResponse)(nil), // 4: meowlib.ConversationResponse + (*FromServerMessage)(nil), // 5: meowlib.FromServerMessage + (*MatriochkaServer)(nil), // 6: meowlib.MatriochkaServer + (*Matriochka)(nil), // 7: meowlib.Matriochka + (*Server)(nil), // 8: meowlib.Server + (*ContactCard)(nil), // 9: meowlib.ContactCard + (*PackedUserMessage)(nil), // 10: meowlib.PackedUserMessage + (*ConversationStatus)(nil), // 11: meowlib.ConversationStatus + (*Group)(nil), // 12: meowlib.Group + (*UserMessage)(nil), // 13: meowlib.UserMessage + (*File)(nil), // 14: meowlib.File + (*Location)(nil), // 15: meowlib.Location } var file_messages_proto_depIdxs = []int32{ - 12, // 0: meowlib.ToServerMessage.pullRequest:type_name -> meowlib.ToServerMessage.ConversationRequest - 8, // 1: meowlib.ToServerMessage.messages:type_name -> meowlib.PackedUserMessage - 6, // 2: meowlib.ToServerMessage.knownServers:type_name -> meowlib.Server - 5, // 3: meowlib.ToServerMessage.matriochkaMessage:type_name -> meowlib.Matriochka + 2, // 0: meowlib.ToServerMessage.pullRequest:type_name -> meowlib.ConversationRequest + 10, // 1: meowlib.ToServerMessage.messages:type_name -> meowlib.PackedUserMessage + 8, // 2: meowlib.ToServerMessage.knownServers:type_name -> meowlib.Server + 7, // 3: meowlib.ToServerMessage.matriochkaMessage:type_name -> meowlib.Matriochka 1, // 4: meowlib.ToServerMessage.invitation:type_name -> meowlib.Invitation - 8, // 5: meowlib.FromServerMessage.chat:type_name -> meowlib.PackedUserMessage - 6, // 6: meowlib.FromServerMessage.knownServers:type_name -> meowlib.Server + 10, // 5: meowlib.FromServerMessage.chat:type_name -> meowlib.PackedUserMessage + 8, // 6: meowlib.FromServerMessage.knownServers:type_name -> meowlib.Server 1, // 7: meowlib.FromServerMessage.invitation:type_name -> meowlib.Invitation - 4, // 8: meowlib.Matriochka.prev:type_name -> meowlib.MatriochkaServer - 4, // 9: meowlib.Matriochka.next:type_name -> meowlib.MatriochkaServer - 6, // 10: meowlib.ContactCard.pullServers:type_name -> meowlib.Server - 14, // 11: meowlib.UserMessage.Status:type_name -> meowlib.UserMessage.ConversationStatus - 7, // 12: meowlib.UserMessage.contact:type_name -> meowlib.ContactCard - 6, // 13: meowlib.UserMessage.knownServers:type_name -> meowlib.Server - 15, // 14: meowlib.UserMessage.group:type_name -> meowlib.UserMessage.Group - 10, // 15: meowlib.UserMessage.files:type_name -> meowlib.File - 11, // 16: meowlib.UserMessage.currentLocation:type_name -> meowlib.Location - 7, // 17: meowlib.UserMessage.ConversationStatus.myNextIdentity:type_name -> meowlib.ContactCard - 7, // 18: meowlib.UserMessage.Group.members:type_name -> meowlib.ContactCard + 6, // 8: meowlib.Matriochka.prev:type_name -> meowlib.MatriochkaServer + 6, // 9: meowlib.Matriochka.next:type_name -> meowlib.MatriochkaServer + 8, // 10: meowlib.ContactCard.pullServers:type_name -> meowlib.Server + 9, // 11: meowlib.ConversationStatus.myNextIdentity:type_name -> meowlib.ContactCard + 9, // 12: meowlib.Group.members:type_name -> meowlib.ContactCard + 11, // 13: meowlib.UserMessage.Status:type_name -> meowlib.ConversationStatus + 9, // 14: meowlib.UserMessage.contact:type_name -> meowlib.ContactCard + 8, // 15: meowlib.UserMessage.knownServers:type_name -> meowlib.Server + 12, // 16: meowlib.UserMessage.group:type_name -> meowlib.Group + 14, // 17: meowlib.UserMessage.files:type_name -> meowlib.File + 15, // 18: meowlib.UserMessage.currentLocation:type_name -> meowlib.Location 19, // [19:19] is the sub-list for method output_type 19, // [19:19] is the sub-list for method input_type 19, // [19:19] is the sub-list for extension type_name @@ -1645,7 +1649,7 @@ func file_messages_proto_init() { } } file_messages_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ToServerMessage); i { + switch v := v.(*ConversationRequest); i { case 0: return &v.state case 1: @@ -1657,7 +1661,7 @@ func file_messages_proto_init() { } } file_messages_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FromServerMessage); i { + switch v := v.(*ToServerMessage); i { case 0: return &v.state case 1: @@ -1669,7 +1673,7 @@ func file_messages_proto_init() { } } file_messages_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MatriochkaServer); i { + switch v := v.(*ConversationResponse); i { case 0: return &v.state case 1: @@ -1681,7 +1685,7 @@ func file_messages_proto_init() { } } file_messages_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Matriochka); i { + switch v := v.(*FromServerMessage); i { case 0: return &v.state case 1: @@ -1693,7 +1697,7 @@ func file_messages_proto_init() { } } file_messages_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Server); i { + switch v := v.(*MatriochkaServer); i { case 0: return &v.state case 1: @@ -1705,7 +1709,7 @@ func file_messages_proto_init() { } } file_messages_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ContactCard); i { + switch v := v.(*Matriochka); i { case 0: return &v.state case 1: @@ -1717,7 +1721,7 @@ func file_messages_proto_init() { } } file_messages_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PackedUserMessage); i { + switch v := v.(*Server); i { case 0: return &v.state case 1: @@ -1729,7 +1733,7 @@ func file_messages_proto_init() { } } file_messages_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserMessage); i { + switch v := v.(*ContactCard); i { case 0: return &v.state case 1: @@ -1741,7 +1745,7 @@ func file_messages_proto_init() { } } file_messages_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*File); i { + switch v := v.(*PackedUserMessage); i { case 0: return &v.state case 1: @@ -1753,7 +1757,7 @@ func file_messages_proto_init() { } } file_messages_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Location); i { + switch v := v.(*ConversationStatus); i { case 0: return &v.state case 1: @@ -1765,7 +1769,7 @@ func file_messages_proto_init() { } } file_messages_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ToServerMessage_ConversationRequest); i { + switch v := v.(*Group); i { case 0: return &v.state case 1: @@ -1777,7 +1781,7 @@ func file_messages_proto_init() { } } file_messages_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FromServerMessage_ConversationResponse); i { + switch v := v.(*UserMessage); i { case 0: return &v.state case 1: @@ -1789,7 +1793,7 @@ func file_messages_proto_init() { } } file_messages_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserMessage_ConversationStatus); i { + switch v := v.(*File); i { case 0: return &v.state case 1: @@ -1801,7 +1805,7 @@ func file_messages_proto_init() { } } file_messages_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserMessage_Group); i { + switch v := v.(*Location); i { case 0: return &v.state case 1: diff --git a/pb/messages.proto b/pb/messages.proto index 7aa4822..767a046 100644 --- a/pb/messages.proto +++ b/pb/messages.proto @@ -3,7 +3,12 @@ // Lower field number values take less space in the wire format. // For example, field numbers in the range 1 through 15 take one byte to encode. // Field numbers in the range 16 through 2047 take two bytes. - +/** + * Meow messages + * + * This is the Meow protocol protobuf messages description. + * + */ syntax = "proto3"; package meowlib; option go_package = "forge.redroom.link/yves/meowlib"; @@ -17,29 +22,31 @@ message PackedServerMessage { // structure to hold an invitation through a server message Invitation { - bytes payload = 1; - int32 timeout = 2; - int32 idlen = 3; - string password = 4; - string id = 5; - int64 expiry = 6; - int32 step = 7; + bytes payload = 1; // invitation payload, encrypted after step 2 + int32 timeout = 2; // how long do I want the invitation to remain available on the server + int32 idlen = 3; // len of the id you wish for short url transmission + string password = 4; // password tou set for accessin invitation (optional) + string id = 5; // id that the friend shall request to get teh invitation + int64 expiry = 6; // the server allowed expiry date, it may be samller than the requested timeout according to server policy + int32 step = 7; // progress in the inviattion process : 1=invite friend, 2=friend requests invitation, 3=friend's answer, 4=request answer } + +// structure for requesting incoming messages +message ConversationRequest { + string lookupKey = 1; // lookup key for a conversation + string lastServerUuidOK = 2; // Last Server message UUID received (send me all after that one) + bool publishOnline = 3; // ?? Publish my online status for that contact ? + string lookupSignature = 4; // prove that I own the private key by signing that block +} + + // structure defining a message for a server, that will be encrypted, then sent in a "packedmessage" payload message ToServerMessage { string type = 1; // Type 1 : final destination / 2 : forward string from = 2 ; // My pub key for the server to send me an encrypter answer bytes payload = 3 ; // optional payload for server - // structure for requesting incoming messages - message ConversationRequest { - string lookupKey = 1; // lookup key for a conversation - string lastServerUuidOK = 2; // Last Server message UUID received (send me all after that one) - bool publishOnline = 3; // ?? Publish my online status for that contact ? - string lookupSignature = 4; // prove that I own the private key by signing that block - } - repeated ConversationRequest pullRequest = 4; repeated PackedUserMessage messages = 5; @@ -54,6 +61,10 @@ message ToServerMessage { } + message ConversationResponse { + repeated string messageUuids = 1; + } + // structure defining a from server receiver message decrypted from a "packedmessage" payload message FromServerMessage { string type = 1; // Type @@ -62,10 +73,6 @@ message FromServerMessage { string uuidAck = 4 ; // Ack for the last received ToServerMessage Uuid string serverUuid = 5 ; // Provides the server uuid that replaced the client uuid - message ConversationResponse { - repeated string messageUuids = 1; - } - repeated PackedUserMessage chat = 6; repeated Server knownServers = 7; @@ -90,10 +97,10 @@ message Matriochka { // structure describing required server attributes message Server { - string name = 1; - string description=2; - string publicKey = 3; - string url = 4; + string name = 1; // friendly server name + string description=2; // description : owner type (company/private/university...), + string publicKey = 3; // public key you must use to send encrypted messages to that server + string url = 4; // meow server url bool publish = 5; // publish this server when asked for a list by server bytes signature = 6; // signature of all previous fields by the server itself int32 confidenceLevel = 7; // additional info from the user @@ -101,11 +108,11 @@ message Server { // structure describing a user contact card ie the minimum set of attributes for exchanging identities message ContactCard { - string name=1; - string contactPublicKey =2; - string encryptionPublicKey= 3; - string lookupPublicKey =4; - repeated Server pullServers =5; + string name=1; // contact nickname + string contactPublicKey =2; // contact public key, will be used to authenticate her/his messages + string encryptionPublicKey= 3; // public key you must use to to write encrypted messages to that contact + string lookupPublicKey =4; // public key you will use as "destination identifier" for her/him to lookup for your messages on the servers + repeated Server pullServers =5; // list the servers where the contact will look for messages from you uint32 version = 6; string invitationId=7; } @@ -118,6 +125,20 @@ message PackedUserMessage { repeated int64 serverTimestamp=4; // server time stamp, might be several in matriochka mode } +message ConversationStatus { + string localUuid = 1; + uint64 localSequence = 2 ; + uint64 sent = 3 ; + uint64 received = 4; + uint64 processed = 5; + ContactCard myNextIdentity = 6; + int32 peerNextIdentityAck = 7; // version of the new peer accepted id + } + +message Group{ + string name=1; + repeated ContactCard members = 2; +} // structure defining information that might be exchanged between two peers. message UserMessage { @@ -125,25 +146,13 @@ message UserMessage { string from = 2; // My public key for that contact string type = 3; bytes data = 4; - message ConversationStatus { - string localUuid = 1; - uint64 localSequence = 2 ; - uint64 sent = 3 ; - uint64 received = 4; - uint64 processed = 5; - ContactCard myNextIdentity = 6; - int32 peerNextIdentityAck = 7; // version of the new peer accepted id - } + ConversationStatus Status = 5; ContactCard contact = 6; Server knownServers = 7; - message Group{ - string name=1; - repeated ContactCard members = 2; - } Group group = 8; repeated File files = 9; diff --git a/pb/protogen.sh b/pb/protogen.sh index 4b7d93a..01519d3 100755 --- a/pb/protogen.sh +++ b/pb/protogen.sh @@ -3,4 +3,10 @@ protoc -I=. --go_out=.. messages.proto mv ../forge.redroom.link/yves/meowlib/messages.pb.go ../ rm -rf ../forge.redroom.link -#protoc -I=. --dart_out=../../../flutter/meowlib/lib/ messages.proto +protoc --plugin=protoc-gen-doc=/usr/bin/protoc-gen-doc \ + --doc_out=../doc/generated \ + --doc_opt=html,index.html \ + *.proto + +protoc --plugin=protoc-gen-uml=/usr/bin/protoc-gen-uml \ + --uml_out=../doc/generated -I=. *.proto