add uid to peer + helper methods + http
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
parent
0a70206b11
commit
f80411bf21
226
client/helpers/backgroundHelper.go
Normal file
226
client/helpers/backgroundHelper.go
Normal file
@ -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
|
||||||
|
}
|
1
client/helpers/contactHelper.go
Normal file
1
client/helpers/contactHelper.go
Normal file
@ -0,0 +1 @@
|
|||||||
|
package helpers
|
147
client/helpers/invitationAnswerHelper.go
Normal file
147
client/helpers/invitationAnswerHelper.go
Normal file
@ -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
|
||||||
|
}
|
125
client/helpers/invitationCheckHelper.go
Normal file
125
client/helpers/invitationCheckHelper.go
Normal file
@ -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
|
||||||
|
}
|
135
client/helpers/invitationCreateHelper.go
Normal file
135
client/helpers/invitationCreateHelper.go
Normal file
@ -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()
|
||||||
|
|
||||||
|
}
|
37
client/helpers/messageHelper.go
Normal file
37
client/helpers/messageHelper.go
Normal file
@ -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
|
||||||
|
}
|
1
client/helpers/serverHelper.go
Normal file
1
client/helpers/serverHelper.go
Normal file
@ -0,0 +1 @@
|
|||||||
|
package helpers
|
@ -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
|
// 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) {
|
func (id *Identity) InvitePeer(MyName string, ContactName string, MessageServerUids []string, InvitationMessage string) (*Peer, error) {
|
||||||
var peer Peer
|
var peer Peer
|
||||||
|
peer.Uid = uuid.New().String()
|
||||||
peer.MyIdentity = meowlib.NewKeyPair()
|
peer.MyIdentity = meowlib.NewKeyPair()
|
||||||
peer.MyEncryptionKp = meowlib.NewKeyPair()
|
peer.MyEncryptionKp = meowlib.NewKeyPair()
|
||||||
peer.MyLookupKp = 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 {
|
func (id *Identity) AnswerInvitation(MyName string, ContactName string, MessageServerIdxs []string, ReceivedContact *meowlib.ContactCard) *Peer {
|
||||||
var peer Peer
|
var peer Peer
|
||||||
//var myContactCard meowlib.ContactCard
|
//var myContactCard meowlib.ContactCard
|
||||||
|
peer.Uid = uuid.New().String()
|
||||||
peer.MyIdentity = meowlib.NewKeyPair()
|
peer.MyIdentity = meowlib.NewKeyPair()
|
||||||
peer.MyEncryptionKp = meowlib.NewKeyPair()
|
peer.MyEncryptionKp = meowlib.NewKeyPair()
|
||||||
peer.MyLookupKp = meowlib.NewKeyPair()
|
peer.MyLookupKp = meowlib.NewKeyPair()
|
||||||
|
@ -1 +0,0 @@
|
|||||||
package client
|
|
@ -15,6 +15,7 @@ import (
|
|||||||
// - Building simple user messages
|
// - Building simple user messages
|
||||||
// - Utility functions for packing/unpacking, encrypting/decrypting messages for peer communication
|
// - Utility functions for packing/unpacking, encrypting/decrypting messages for peer communication
|
||||||
type Peer struct {
|
type Peer struct {
|
||||||
|
Uid string `json:"uid,omitempty"`
|
||||||
Name string `json:"name,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
Avatar string `json:"avatar,omitempty"`
|
Avatar string `json:"avatar,omitempty"`
|
||||||
MyName string `json:"my_name,omitempty"`
|
MyName string `json:"my_name,omitempty"`
|
||||||
|
40
http.go
Normal file
40
http.go
Normal file
@ -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
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user