package messages import ( "errors" "forge.redroom.link/yves/meowlib" "forge.redroom.link/yves/meowlib/client" "google.golang.org/protobuf/proto" ) // Step3InitiatorFinalizesInviteeAndCreatesContactCard is called by the initiator when the // step-2 answer (serialized Invitation bytes) arrives. It decrypts the invitee's ContactCard, // upgrades the pending peer with the invitee's real keys, and returns a serialized Invitation // (step=3) whose Payload is the initiator's ContactCard, ready to be consumed directly by // Step4InviteeFinalizesInitiator on the invitee side. func Step3InitiatorFinalizesInviteeAndCreatesContactCard(invitationBytes []byte) ([]byte, error) { var invitation meowlib.Invitation if err := proto.Unmarshal(invitationBytes, &invitation); err != nil { return nil, err } var invitationAnswer meowlib.PackedUserMessage if err := proto.Unmarshal(invitation.Payload, &invitationAnswer); err != nil { return nil, err } peer := client.GetConfig().GetIdentity().Peers.GetFromInvitationId(invitation.Uuid) if peer == nil { return nil, errors.New("no peer for invitation uuid " + invitation.Uuid) } // Guard against duplicate delivery (e.g., same answer from multiple servers). if peer.InvitationKp == nil { return nil, nil } usermsg, err := peer.ProcessInboundStep2UserMessage(&invitationAnswer, invitation.From) if err != nil { return nil, err } var inviteeCC meowlib.ContactCard if err := proto.Unmarshal(usermsg.Invitation.Payload, &inviteeCC); err != nil { return nil, err } myCC, _, err := client.GetConfig().GetIdentity().InvitationStep3(&inviteeCC) if err != nil { return nil, err } client.GetConfig().GetIdentity().Save() ccBytes, err := proto.Marshal(myCC) if err != nil { return nil, err } inv := &meowlib.Invitation{ Uuid: myCC.InvitationId, Step: 3, Payload: ccBytes, } return proto.Marshal(inv) }