diff --git a/client/helpers/backgroundHelper.go b/client/helpers/backgroundHelper.go new file mode 100644 index 0000000..7665e39 --- /dev/null +++ b/client/helpers/backgroundHelper.go @@ -0,0 +1,226 @@ +package helpers + +import ( + "C" + + "forge.redroom.link/yves/meowlib" + "forge.redroom.link/yves/meowlib/client" +) +import ( + "encoding/json" + "errors" + "fmt" + "os" + "path/filepath" + "strconv" + "time" + + "github.com/google/uuid" + "google.golang.org/protobuf/proto" +) + +type ReceivedMessage struct { + Text string + files []string + Server string + Sent uint64 + Received uint64 + LocalUuid string + LocalSequence uint64 + AppData string + Location meowlib.Location +} + +// CheckForMessages +func CheckForMessages(message *C.char) (int, string, error) { + var jsonjob map[string]interface{} + count := 0 + err := json.Unmarshal([]byte(C.GoString(message)), &jsonjob) + if err != nil { + return -1, "CheckMessages: json.Unmarshal", err + } + //fmt.Println(jsonjob) + // if folder does not exist, create it + if _, err := os.Stat(filepath.Join(jsonjob["storage_path"].(string), "inbox")); os.IsNotExist(err) { + err := os.MkdirAll(filepath.Join(jsonjob["storage_path"].(string), "inbox"), 0700) + if err != nil { + return -1, "CheckMessages: MkdirAll", err + } + } + //convert server to a server object + var server client.Server + jsonServer, err := json.Marshal(jsonjob["server"]) + if err != nil { + return -1, "CheckMessages: json.Marshal server", err + } + err = json.Unmarshal(jsonServer, &server) + if err != nil { + return -1, "CheckMessages: json.Unmarshal server", err + } + var crl []*meowlib.ConversationRequest + // build conversation requests + if jsonjob["lookup_keys"] != nil { + for _, key := range jsonjob["lookup_keys"].([]interface{}) { + keymap := key.(map[string]interface{}) + var cr meowlib.ConversationRequest + cr.LookupKey = keymap["public"].(string) + cr.SendTimestamp = time.Now().UTC().Unix() + // todo sign it + //cr.LookupSignature = + crl = append(crl, &cr) + } + // build server message + + var toSrv meowlib.ToServerMessage + toSrv.PullRequest = crl + toSrv.From = server.UserKp.Public + data, err := server.ProcessOutboundMessage(&toSrv) + if err != nil { + return -1, "CheckMessages: ProcessOutboundMessage", err + } + + response, err := meowlib.HttpPostMessage(server.Url, data) + if err != nil { + return -1, "CheckMessages: httpPostMessage", err + } + fs_msg, err := server.ProcessInboundServerResponse(response) + if err != nil { + return -1, "CheckMessages: ProcessInboundServerResponse", err + } + if len(fs_msg.Chat) == 0 { + // todo: manage non usermessage, like serverlists + } else { + // for _, msg := range fs_msg.Chat { + // // Store messages + // out, err := proto.Marshal(msg) + // if err != nil { + // C.CString(errorToJson(err, "CheckMessages: protobuf marshal")) + // } + // if err := os.WriteFile(filepath.Join(jsonjob["storage_path"].(string), "inbox", strconv.FormatInt(time.Now().UTC().UnixNano(), 10)), out, 0644); err != nil { + // C.CString(errorToJson(err, "CheckMessages: WriteFile")) + // } + // } + out, err := proto.Marshal(fs_msg) + if err != nil { + return -1, "CheckMessages: protobuf marshal", err + } + if err := os.WriteFile(filepath.Join(jsonjob["storage_path"].(string), "inbox", strconv.FormatInt(time.Now().UTC().UnixNano(), 10)), out, 0644); err != nil { + return -1, "CheckMessages: WriteFile", err + } + } + count = len(fs_msg.Chat) + } + + return count, "", nil +} + +// SaveCheckJobs +func SaveCheckJobs() (string, error) { + me := client.GetConfig().GetIdentity() + err := me.SaveBackgroundJob() + if err != nil { + + return "CheckMessages: json.Marshal", err + } + return "", nil +} + +// ReadMessage +func ReadMessage(messageFilename string, storagePath string) (string, string, error) { + result := map[string]interface{}{} + + // read message file + msg, err := os.ReadFile(messageFilename) + if err != nil { + return "", "REadMessage: ReadFile", err + } + // protobuf unmarshal message + var fromServerMessage meowlib.FromServerMessage + err = proto.Unmarshal(msg, &fromServerMessage) + if err != nil { + return "", "ReadMessage: Unmarshal FromServerMessage", err + } + // Chat messages + if len(fromServerMessage.Chat) > 0 { + for _, packedUserMessage := range fromServerMessage.Chat { + + // find the peer with that lookup key + peer := client.GetConfig().GetIdentity().Peers.GetFromMyLookupKey(packedUserMessage.Destination) + if peer == nil { + return "", "ReadMessage: GetFromMyLookupKey", errors.New("no visible peer for that message") + } + // Unpack the message + usermsg, err := peer.ProcessInboundUserMessage(packedUserMessage.Payload, packedUserMessage.Signature) + if err != nil { + return "", "ReadMessage: ProcessInboundUserMessage", err + } + fmt.Println("From:", usermsg.From) + jsonUserMessage, _ := json.Marshal(usermsg) + fmt.Println(string(jsonUserMessage)) + // detach files + filenames := []string{} + if usermsg.Files != nil { + for _, file := range usermsg.Files { + filename := uuid.New().String() + "_" + file.Filename + filenames = append(filenames, filename) + // detach file + os.WriteFile(filepath.Join(storagePath, "files", filename), file.Data, 0600) + } + //? result["invitation finalized"] = peer.Name + } + // user message + result["message"] = string(usermsg.Data) + // add message to storage + err = peer.StoreMessage(usermsg, filenames) + if err != nil { + return "", "ReadMessage: StoreMessage", err + } + + } + } + + // fmt.Println("have read fromServerMessage, will unmarshal packed") + // // protobuf unmarshal message //! WRONG !!!! + // var packedMessage meowlib.PackedUserMessage + // err = proto.Unmarshal(userMessage, &packedMessage) + // if err != nil { + // return C.CString(errorToJson(err, "ReadMessage: Unmarshal PackedUserMessage")) + // } + // fmt.Println("Destination:", packedMessage.Destination) + // fmt.Println("Payload lengh:", len(packedMessage.Payload)) + // server invitation finalize or more ? + if fromServerMessage.Invitation != nil { + fmt.Println("Invitation from:", fromServerMessage.Invitation.From) + // find the peer with that lookup key + // todo get from invitation id + //! FOLOWING statement is WRONG ! + peer := client.GetConfig().GetIdentity().Peers.GetFromPublicKey(fromServerMessage.Invitation.From) + if peer == nil { + return "", "ReadMessage: GetFromPublicKey", errors.New("no visible peer for that message") + } + peer.ContactPublicKey = fromServerMessage.Invitation.From + str, _ := json.Marshal(peer) + fmt.Println("Peer:", string(str)) + // invitation message + var receivedContactCard meowlib.ContactCard + err := proto.Unmarshal(fromServerMessage.Invitation.Payload, &receivedContactCard) + if err != nil { + return "", "ReadMessage: Unmarshal ContactCard", err + } + err = client.GetConfig().GetIdentity().FinalizeInvitation(&receivedContactCard) + if err != nil { + return "", "ReadMessage: FinalizeInvitation", err + } + result["invitation finalized"] = peer.Name + + } + + // message + // including list of detached files + val, err := json.Marshal(result) + if err != nil { + return "", "ReadMessage: json.Marshal", err + } + os.Remove(messageFilename) + return string(val), "", nil +} diff --git a/client/helpers/contactHelper.go b/client/helpers/contactHelper.go new file mode 100644 index 0000000..345b806 --- /dev/null +++ b/client/helpers/contactHelper.go @@ -0,0 +1 @@ +package helpers diff --git a/client/helpers/invitationAnswerHelper.go b/client/helpers/invitationAnswerHelper.go new file mode 100644 index 0000000..fac6ec5 --- /dev/null +++ b/client/helpers/invitationAnswerHelper.go @@ -0,0 +1,147 @@ +package helpers + +import ( + "C" + "fmt" + "os" + "strings" + + "forge.redroom.link/yves/meowlib" + "forge.redroom.link/yves/meowlib/client" +) +import ( + "errors" + + "google.golang.org/protobuf/proto" +) + +// InvitationAnswer +func InvitationAnswer(cc *meowlib.ContactCard, nickname string, myNickname string, serverUids []string) (*client.Peer, string, error) { + + mynick := myNickname + // my nickname for that contact + + if myNickname == "" { + mynick = client.GetConfig().GetIdentity().Nickname + } + + // build my contact card for that friend + peer := client.GetConfig().GetIdentity().AnswerInvitation(mynick, nickname, serverUids, cc) + + //peerstr, err := json.Marshal(peer) + //fmt.Println("InvitationAnswer: " + string(peerstr)) + c := client.GetConfig() + c.GetIdentity().Save() + + return peer, "", nil +} + +// InvitationAnswerFile +func InvitationAnswerFile(invitationFile string, nickname string, myNickname string, serverUids []string) (string, error) { + format := "qr" + var filename string = "" + var cc *meowlib.ContactCard + c := client.GetConfig() + if _, err := os.Stat(invitationFile); os.IsNotExist(err) { + return "InvitationAnswerFile : os.Stat", err + } + if strings.HasSuffix(invitationFile, ".mwiv") { + format = "mwiv" + data, err := os.ReadFile(invitationFile) + if err != nil { + return "InvitationAnswerFile : os.ReadFile", err + } + cc, err = meowlib.NewContactCardFromCompressed(data) + if err != nil { + return "InvitationAnswerFile : NewContactCardFromCompressed", err + } + } + identity := client.GetConfig().GetIdentity() + if cc != nil { + isAnswer, proposed, received, _ := identity.CheckInvitation(cc) + if isAnswer { + fmt.Fprintln(os.Stdout, "This is already a response "+proposed+" to your invitation.") + fmt.Fprintln(os.Stdout, "You cannot answer again.") + fmt.Fprintln(os.Stdout, "You should finalize it by importing "+proposed+" contact card to your meow.") + fmt.Fprintln(os.Stdout, "Use : 'meow invitation finalize "+invitationFile+"' to do it.") + + } else { + mynick := myNickname + // my nickname for that contact + + if myNickname == "" { + mynick = client.GetConfig().GetIdentity().Nickname + } + + response := identity.AnswerInvitation(mynick, nickname, serverUids, cc) + fmt.Fprintln(os.Stdout, "Invitation sent by "+received) + if format == "qr" { + filename = c.StoragePath + string(os.PathSeparator) + mynick + "-" + nickname + ".png" + response.GetMyContact().WriteQr(filename) + } else { + filename = c.StoragePath + string(os.PathSeparator) + mynick + "-" + nickname + ".mwiv" + response.GetMyContact().WriteCompressed(filename) + } + client.GetConfig().GetIdentity().Save() + } + + } + return "", nil +} + +// InvitationAnswerMessage +func InvitationAnswerMessage(invitationId string, invitationServerUid string) ([]byte, string, error) { + + // find the peer with that invitation id + var peer *client.Peer + for i := len(client.GetConfig().GetIdentity().Peers) - 1; i >= 0; i-- { //! to allow self invitation : testing only, findinc the received peer before myself + // for i := 0; i < len(client.GetConfig().GetIdentity().Peers); i++ { + if client.GetConfig().GetIdentity().Peers[i].InvitationId == invitationId { + peer = client.GetConfig().GetIdentity().Peers[i] + break + } + } + if peer == nil { + // declare a custom go error for no peer found + return nil, "InvitationAnswerMessage: loop for peer", errors.New("no peer with that invitation id") + } + answermsg, err := peer.BuildInvitationAnswerMessage(peer.GetMyContact()) + if err != nil { + return nil, "InvitationAnswerMessage: BuildInvitationAnswserMessage", err + } + // Server: get the invitation server + invitationServer, err := client.GetConfig().GetIdentity().MessageServers.LoadServer(invitationServerUid) + if err != nil { + return nil, "InvitationAnswerMessage: LoadServer", err + } + + // jsonsrv, err := json.Marshal(peer) + // if err != nil { + // return gobin2c(berrorToJson(err, "InvitationAnswerMessage: Marshal")) + // } + //fmt.Println(string(jsonsrv)) + // Prepare cyphered + packed user message + packedMsg, err := peer.ProcessOutboundUserMessage(answermsg) + if err != nil { + return nil, "InvitationAnswerMessage: ProcessOutboundUserMessage", err + } + // jsonsrv, err = json.Marshal(invitationServer) + // if err != nil { + // return gobin2c(berrorToJson(err, "InvitationAnswerMessage: Marshal")) + // } + //fmt.Println(string(jsonsrv)) + // Creating Server message for transporting the user message + toServerMessage := invitationServer.BuildToServerMessageFromUserMessage(packedMsg) + toServerMessage.Invitation = &meowlib.Invitation{Step: 3} + toServerMessage.Invitation.From = peer.MyIdentity.Public + pld, err := proto.Marshal(packedMsg) + if err != nil { + return nil, "InvitationAnswerMessage: proto.Marshal", err + } + toServerMessage.Invitation.Payload = pld + bytemsg, err := invitationServer.ProcessOutboundMessage(toServerMessage) + if err != nil { + return nil, "InvitationAnswerMessage: ProcessOutboundMessage", err + } + return bytemsg, "", nil +} diff --git a/client/helpers/invitationCheckHelper.go b/client/helpers/invitationCheckHelper.go new file mode 100644 index 0000000..934e6c9 --- /dev/null +++ b/client/helpers/invitationCheckHelper.go @@ -0,0 +1,125 @@ +package helpers + +import ( + "strings" + + "forge.redroom.link/yves/meowlib" + "forge.redroom.link/yves/meowlib/client" +) + +// InvitationCheck +// todo +/* +func InvitationCheck(invitationdata []byte) *C.char { + var jsoninv map[string]interface{} + err := json.Unmarshal([]byte(C.GoString(invitationdata)), &jsoninv) + if err != nil { + return C.CString(errorToJson(err, "InvitationCheck: ")) + } + var cc *meowlib.ContactCard + if _, err := os.Stat(jsoninv["filename"].(string)); os.IsNotExist(err) { + return C.CString(errorToJson(err, "InvitationCheck: ")) + } + if strings.HasSuffix(jsoninv["filename"].(string), ".mwiv") { + data, err := os.ReadFile(jsoninv["filename"].(string)) + if err != nil { + return C.CString(errorToJson(err, "InvitationCheck: ")) + } + cc, err = meowlib.NewContactCardFromCompressed(data) + if err != nil { + return C.CString(errorToJson(err, "InvitationCheck: ")) + } + } + identity := client.GetConfig().GetIdentity() + result := map[string]string{} + if cc != nil { + isAnswer, proposed, received, invitationMessage := identity.CheckInvitation(cc) + if isAnswer { // answer to infitation + result["type"] = "answer" + result["to"] = proposed + result["from"] = received + result["invitation_message"] = invitationMessage + //fmt.Fprintln(os.Stdout, "Invitation sent to "+proposed+" received with "+received+" as suggested nickname") + } else { // finalization message + result["type"] = "finalize" + result["from"] = received + //fmt.Fprintln(os.Stdout, "Invitation sent by "+received) + } + + } + val, err := json.Marshal(result) + if err != nil { + return C.CString(errorToJson(err, "InvitationCheck: ")) + } + return C.CString(string(val)) +}*/ + +// InvitationGetMessage +// Called by the invitation receiver +// invitationUrl: the url of server holding the invitation +// serverPublicKey: the public key of the server holding the invitation +// invitationPassword: the password of the invitation +func InvitationGetMessage(invitationUrl string, serverPublicKey string, invitationPassword string) ([]byte, string, error) { + + meowurl := strings.Split(invitationUrl[7:], "?") + + serverurl := meowurl[0] + shortcode := meowurl[1] + srv := client.Server{} + // check if already in msg servers + dbsrv, err := client.GetConfig().GetIdentity().MessageServers.LoadServer(serverurl) + if err != nil { + return nil, "InvitationGetMessage: LoadServer", err + } + if dbsrv == nil { + // create a server object with url & pubkey + srv.Url = serverurl + srv.PublicKey = serverPublicKey + srv.UserKp = meowlib.NewKeyPair() + // save it + err = client.GetConfig().GetIdentity().MessageServers.StoreServer(&srv) + if err != nil { + return nil, "InvitationGetMessage: StoreServer", err + } + } else { + srv = *dbsrv + } + // buildserver message + toSrvMsg, err := srv.BuildToServerMessageInvitationRequest(shortcode, invitationPassword) + if err != nil { + return nil, "InvitationGetMessage: BuildToServerMessageInvitationRequest", err + } + // processoutbound + bytemsg, err := srv.ProcessOutboundMessage(toSrvMsg) + if err != nil { + return nil, "InvitationGetMessage: ProcessOutboundMessage", err + } + + return bytemsg, "", nil +} + +// InvitationGetMessageReadResponse +// Called by the invitation receiver +// invitationData: the data received from the server +// invitationServerUid: the uid of the server holding the invitation +func InvitationGetMessageReadResponse(invitationData []byte, invitationServerUid string) (*meowlib.ContactCard, string, error) { + + server, err := client.GetConfig().GetIdentity().MessageServers.LoadServer(invitationServerUid) + if err != nil { + return nil, "InvitationGetMessageReadResponse: LoadServer", err + } + // Server inbound processing : get the invitation server + serverMsg, err := server.ProcessInboundServerResponse(invitationData) + if err != nil { + return nil, "InvitationGetMessageReadResponse: ProcessInboundServerResponse", err + } + // fmt.Println("Inbound OK, Invitation Step: ", serverMsg.Invitation.Step, len(serverMsg.Invitation.Payload)) + // fmt.Println("Invitation Check") + // fmt.Println(hex.EncodeToString(serverMsg.Invitation.Payload)) + // contactCard decode + cc, err := meowlib.NewContactCardFromCompressed(serverMsg.Invitation.Payload) + if err != nil { + return nil, "InvitationGetMessageReadResponse: NewContactCardFromCompressed", err + } + return cc, "", nil +} diff --git a/client/helpers/invitationCreateHelper.go b/client/helpers/invitationCreateHelper.go new file mode 100644 index 0000000..5eff429 --- /dev/null +++ b/client/helpers/invitationCreateHelper.go @@ -0,0 +1,135 @@ +package helpers + +import ( + "os" + "time" + + "forge.redroom.link/yves/meowlib" + "forge.redroom.link/yves/meowlib/client" +) + +// InvitationCreatePeer creates a new peer and returns it +// Called by invitation initiator +// name: the name of the peer +// myNickname: my nickname for that peer +// invitationMessage: the message to send to the peer +// serverUids: the list of server uids +func InvitationCreatePeer(name string, myNickname string, invitationMessage string, serverUids []string) (*client.Peer, string, error) { + + mynick := myNickname + if myNickname == "" { + mynick = client.GetConfig().GetIdentity().Nickname + } + + // build my contact card for that friend + peer, err := client.GetConfig().GetIdentity().InvitePeer(mynick, myNickname, serverUids, invitationMessage) + if err != nil { + return nil, "InvitationCreate: InvitePeer", err + } + client.GetConfig().GetIdentity().Save() + + return peer, "", nil +} + +// InvitationCreateFile creates a new peer and writes the invitation to a file +// Called by invitation initiator +// name: the name of the peer +// myNickname: my nickname for that peer +// invitationMessage: the message to send to the peer +// serverUids: the list of server uids +// format: the format of the file (qr or mwiv) +func InvitationCreateFile(name string, myNickname string, invitationMessage string, serverUids []string, format string) (*client.Peer, string, error) { + + peer, errdata, err := InvitationCreatePeer(name, myNickname, invitationMessage, serverUids) + if err != nil { + return nil, errdata, err + } + c := client.GetConfig() + var filename string = "" + if format == "qr" { + filename = c.StoragePath + string(os.PathSeparator) + peer.MyName + "-" + peer.Name + ".png" + err := peer.GetMyContact().WriteQr(filename) + if err != nil { + return nil, "InvitationCreateFile: WriteQr", err + } + } else { + filename = c.StoragePath + string(os.PathSeparator) + peer.MyName + "-" + peer.Name + ".mwiv" + err := peer.GetMyContact().WriteCompressed(filename) + if err != nil { + return nil, "InvitationCreateFile: WriteCompressed", err + } + } + return peer, "", nil +} + +// InvitationCreateMessage creates a new invitation message for an invited peer +// Called by invitation initiator +// invitationId: the invitation id of the peer +// invitationServerUid: the uid of the server for sending the invitation +// timeOut: the timeout for the invitation +// urlLen: the length of the invitation url +// password: the password for the invitation +func InvitationCreateMessage(invitationId string, invitationServerUid string, timeOut int, urlLen int, password string) ([]byte, string, error) { + + // lookup for peer with "invitation_id" + var myContact *meowlib.ContactCard + for i := 0; i < len(client.GetConfig().GetIdentity().Peers); i++ { + if client.GetConfig().GetIdentity().Peers[i].InvitationId == invitationId { + myContact = client.GetConfig().GetIdentity().Peers[i].GetMyContact() + break + } + } + // todo handle not found !! + // lookup for message server with "invitation_server" + invitationServer, err := client.GetConfig().GetIdentity().MessageServers.LoadServer(invitationServerUid) //.GetServerByIdx(int(jsoninv["invitation_server"].(float64))) + if err != nil { + return nil, "InvitationCreateMessage: LoadServer", err + } + // call server.buildinviattion + msg, err := invitationServer.BuildToServerMessageInvitationCreation(myContact, password, timeOut, urlLen) + if err != nil { + return nil, "InvitationCreateMessage: BuildToServerMessageInvitationCreation", err + } + // fmt.Println("Invitation Create") + // fmt.Println(hex.EncodeToString(msg.Invitation.Payload)) + bytemsg, err := invitationServer.ProcessOutboundMessage(msg) + if err != nil { + return nil, "InvitationCreateMessage: ProcessOutboundMessage", err + } + return bytemsg, "", nil +} + +// InvitationCreateReadResponse reads the response of an invitation creation (url, expiry) +// Called by invitation initiator +// invitationServerUid: the uid of the server where we sent the invitation +// invitationResponse: the response we got from the server +func InvitationCreateReadResponse(invitationServerUid string, invitationResponse []byte) (*meowlib.Invitation, string, error) { + + server, err := client.GetConfig().GetIdentity().MessageServers.LoadServer(invitationServerUid) + if err != nil { + return nil, "InvitationCreateReadResponse: LoadServer", err + } + serverMsg, err := server.ProcessInboundServerResponse(invitationResponse) + if err != nil { + return nil, "InvitationCreateReadResponse: ProcessInboundServerResponse", err + } + + return serverMsg.Invitation, "", nil +} + +// InvitationSetUrlInfo sets the url info for an invitation +// Called by invitation initiator +// invitationId: the invitation id of the peer +// url: the url of the invitation we got from the server +func InvitationSetUrlInfo(invitationId string, url string, expiry int64) { + + for i := 0; i < len(client.GetConfig().GetIdentity().Peers); i++ { + if client.GetConfig().GetIdentity().Peers[i].InvitationId == invitationId { + client.GetConfig().GetIdentity().Peers[i].InvitationUrl = url + client.GetConfig().GetIdentity().Peers[i].InvitationExpiry = time.Unix(expiry, 0) + break + } + } + client.GetConfig().GetIdentity().Save() + +} diff --git a/client/helpers/messageHelper.go b/client/helpers/messageHelper.go new file mode 100644 index 0000000..f2c3595 --- /dev/null +++ b/client/helpers/messageHelper.go @@ -0,0 +1,37 @@ +package helpers + +import "forge.redroom.link/yves/meowlib/client" + +func PrepareUserMessage(message string, srvuid string, peer_idx int, filelist []string) ([]byte, string, error) { + + peer := client.GetConfig().GetIdentity().Peers[peer_idx] + srv, err := client.GetConfig().GetIdentity().MessageServers.LoadServer(srvuid) + if err != nil { + return nil, "PrepareServerMessage : LoadServer", err + } + // Creating User message + usermessage, err := peer.BuildSimpleUserMessage([]byte(message)) + if err != nil { + return nil, "PrepareServerMessage : BuildSimpleUserMessage", err + } + for _, file := range filelist { + err = usermessage.AddFile(file, client.GetConfig().Chunksize) + if err != nil { + return nil, "PrepareServerMessage : AddFile", err + } + } + // Store message + peer.StoreMessage(usermessage, filelist) + // Prepare cyphered + packed user message + packedMsg, err := peer.ProcessOutboundUserMessage(usermessage) + if err != nil { + return nil, "PrepareServerMessage : ProcessOutboundUserMessage", err + } + // Creating Server message for transporting the user message + toServerMessage := srv.BuildToServerMessageFromUserMessage(packedMsg) + data, err := srv.ProcessOutboundMessage(toServerMessage) + if err != nil { + return nil, "PrepareServerMessage : ProcessOutboundMessage", err + } + return data, "", nil +} diff --git a/client/helpers/serverHelper.go b/client/helpers/serverHelper.go new file mode 100644 index 0000000..345b806 --- /dev/null +++ b/client/helpers/serverHelper.go @@ -0,0 +1 @@ +package helpers diff --git a/client/identity.go b/client/identity.go index c71ea08..d940505 100644 --- a/client/identity.go +++ b/client/identity.go @@ -47,6 +47,7 @@ func CreateIdentity(nickname string) *Identity { // Creates an invitation for a peer, returns the newly created peer including infos to provide a ContactCard func (id *Identity) InvitePeer(MyName string, ContactName string, MessageServerUids []string, InvitationMessage string) (*Peer, error) { var peer Peer + peer.Uid = uuid.New().String() peer.MyIdentity = meowlib.NewKeyPair() peer.MyEncryptionKp = meowlib.NewKeyPair() peer.MyLookupKp = meowlib.NewKeyPair() @@ -93,6 +94,7 @@ func (id *Identity) CheckInvitation(ReceivedContact *meowlib.ContactCard) (isAns func (id *Identity) AnswerInvitation(MyName string, ContactName string, MessageServerIdxs []string, ReceivedContact *meowlib.ContactCard) *Peer { var peer Peer //var myContactCard meowlib.ContactCard + peer.Uid = uuid.New().String() peer.MyIdentity = meowlib.NewKeyPair() peer.MyEncryptionKp = meowlib.NewKeyPair() peer.MyLookupKp = meowlib.NewKeyPair() diff --git a/client/invitationhelpers.go b/client/invitationhelpers.go deleted file mode 100644 index da13c8e..0000000 --- a/client/invitationhelpers.go +++ /dev/null @@ -1 +0,0 @@ -package client diff --git a/client/peer.go b/client/peer.go index 83524e8..b7ceee5 100644 --- a/client/peer.go +++ b/client/peer.go @@ -15,6 +15,7 @@ import ( // - Building simple user messages // - Utility functions for packing/unpacking, encrypting/decrypting messages for peer communication type Peer struct { + Uid string `json:"uid,omitempty"` Name string `json:"name,omitempty"` Avatar string `json:"avatar,omitempty"` MyName string `json:"my_name,omitempty"` diff --git a/http.go b/http.go new file mode 100644 index 0000000..2890f62 --- /dev/null +++ b/http.go @@ -0,0 +1,40 @@ +package meowlib + +import ( + "bytes" + "encoding/json" + "io" + "net/http" +) + +func HttpGetId(url string) (response map[string]string, err error) { + srvId := make(map[string]string) + resp, err := http.Get(url + "/id") + if err != nil { + return nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + err = json.Unmarshal(body, &srvId) + if err != nil { + return nil, err + } + return srvId, nil +} + +func HttpPostMessage(url string, msg []byte) (response []byte, err error) { + resp, err := http.Post(url+"/msg", + "application/octet-stream", bytes.NewBuffer(msg)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + return body, nil +}