package meowlib_test import ( "encoding/json" "fmt" "os" "testing" "forge.redroom.link/yves/meowlib" "forge.redroom.link/yves/meowlib/client" "forge.redroom.link/yves/meowlib/server" ) func TestEndToEnd(t *testing.T) { // // Create my own identity // fmt.Println("Trying to load identity from file.") Me, err := client.LoadIdentity("id.enc", "Test") if err != nil { fmt.Println("Failed : creating New identity...") /////////////////////////// // Creating New Identity // /////////////////////////// Me, err = client.CreateIdentity("myname") // define my preferences (servers) srv := client.Server{Name: "MyServer", Url: "http://127.0.0.1/meow/"} Me.MessageServers.StoreServer(&srv) srv = client.Server{Name: "MyServer", Url: "mqtt://127.0.0.1"} Me.MessageServers.StoreServer(&srv) srv = client.Server{Name: "MyServer", Url: "meow://127.0.0.1"} Me.MessageServers.StoreServer(&srv) //////////////////////////////////////////////////////////////////////////// // STEP_1: Create an invitation — only a temp keypair, no full ContactCard // //////////////////////////////////////////////////////////////////////////// fmt.Println("Creating an invitation for the first friend...") initPayload, peer, err := Me.InvitationStep1("Bender", "myfirstfriend", []string{"http://127.0.0.1/meow/", "mqtt://127.0.0.1"}, "welcome, it's me!") if err != nil { println(err) } println(peer.Name) a, _ := json.Marshal(initPayload) fmt.Println("InvitationInitPayload:", string(a)) data, err := initPayload.Compress() if err != nil { println(err) } initPayload.WriteQr("qrcode.png") println("Compressed init payload :", len(data)) /////////////////////////////////////////////////////// // STEP_2: Simulate friend receiving the payload and answering // /////////////////////////////////////////////////////// fmt.Println("Simulating first friend answer (STEP_2)...") friendMe, err := client.CreateIdentity("friendname") if err != nil { t.Fatal(err) } friendPeer, err := friendMe.InvitationStep2("FriendNick", "Bender", []string{}, initPayload) if err != nil { t.Fatal(err) } friendCC := friendPeer.GetMyContact() FriendServer1KP, err := meowlib.NewKeyPair() if err != nil { t.Fatal(err) } FriendServer1 := meowlib.ServerCard{Name: "FriendServer1", Url: "http://myfriend.org/meow/", PublicKey: FriendServer1KP.Public, Description: "Fancy description"} friendCC.PullServers = append(friendCC.PullServers, &FriendServer1) ////////////////////////////////////////////////////////////////// // STEP_3: Initiator receives friend's CC, generates full keypairs // ////////////////////////////////////////////////////////////////// myCC, _, err := Me.InvitationStep3(friendCC) if err != nil { t.Fatal(err) } fmt.Println("Initiator ContactCard ready:", myCC.ContactPublicKey != "") //////////////////////////////////////////////////// // STEP_4: Friend finalizes initiator's ContactCard // //////////////////////////////////////////////////// err = friendMe.InvitationStep4(myCC) if err != nil { t.Fatal(err) } err = Me.Save() if err != nil { t.Fatal(err) } a, _ = json.Marshal(Me) os.WriteFile("id.json", a, 0644) fmt.Println(string(a)) ///////////////////////////////////// // Create a message to that friend // ///////////////////////////////////// peers, _ := Me.Peers.GetPeers() MyFirstFriend := peers[0] textmessage := "Hello friend!" // Creating User message usermessage, err := MyFirstFriend.BuildSimpleUserMessage([]byte(textmessage)) if err != nil { t.Fatal(err) } serializedMessage, err := MyFirstFriend.SerializeUserMessage(usermessage) if err != nil { t.Fatal(err) } // Encrypting it enc, err := MyFirstFriend.AsymEncryptMessage(serializedMessage) if err != nil { t.Fatal(err) } // Packing it packedMsg := MyFirstFriend.PackUserMessage(enc.Data, enc.Signature) intS1, err := Me.MessageServers.LoadServer("http://127.0.0.1/meow/") if err != nil { t.Fatal(err) } // Creating Server message for transporting the user message toServerMessage, err := intS1.BuildMessageSendingMessage(packedMsg) if err != nil { t.Fatal(err) } // Encrypting it encToServer, err := intS1.AsymEncryptMessage(toServerMessage) if err != nil { t.Fatal(err) } // Packing it protoPackedServerMsg, err := intS1.PackServerMessage(encToServer.Data, encToServer.Signature) if err != nil { t.Fatal(err) } /////////////////////// // Sending to server // /////////////////////// //=> fake action (network protocol transfer are not part of meowlib) // You have to implement the netwok layer // Just FYI printing final byte array size. Those bytes will be sent over the network. println(len(protoPackedServerMsg)) /////////////////////////////////////// // Simulating server side processing // /////////////////////////////////////// var server1 server.Identity server1.ServerName = intS1.Name server1.ServerKp = FriendServer1KP server1.ServerDesc = intS1.Description // Unpack srv_from, srv_encmsg, srv_signature, err := server1.UnpackReceived(protoPackedServerMsg) if err != nil { t.Fatal(err) } // Decrypt srv_clear, err := server1.AsymDecryptMessage(srv_from, srv_encmsg, srv_signature) if err != nil { t.Fatal(err) } // Decode msg srv_msg, err := server1.DeserializeToServerMessage(srv_clear) if err != nil { t.Fatal(err) } // Response : Ack received message srv_fromServerMessage, err := server1.BuildSimpleAckResponseMessage(srv_msg.Uuid) if err != nil { t.Fatal(err) } encoded_srv_fromServerMessage, err := server1.SerializeFromServerMessage(srv_fromServerMessage) if err != nil { t.Fatal(err) } srv_resp, err := server1.AsymEncryptMessage(srv_from, encoded_srv_fromServerMessage) if err != nil { t.Fatal(err) } resp, err := server1.PackForSending(srv_resp.Data, srv_resp.Signature) if err != nil { t.Fatal(err) } print(resp) ////////////////////////////////////////////// // Back to client, decoding server response // ////////////////////////////////////////////// // server unpack // server decrypt // server decode protobuf // user unpack // user decrypt /*decMess, err2 := MyFirstFriend.AsymDecryptMessage([]byte(enc.Data), enc.Signature) if err2 != nil { fmt.Println(err2.Error()) } fmt.Println(decMess)*/ // user decode protobuf } }