diff --git a/bindings/broadcast.go b/bindings/broadcast.go index 9dc521d03a88ecb523c7f2aaf9f911e144f10aa4..97def13f6a1f337a8de6518c50eb7f72d7699468 100644 --- a/bindings/broadcast.go +++ b/bindings/broadcast.go @@ -44,9 +44,11 @@ type ChannelDef struct { // BroadcastMessage is the bindings representation of a broadcast message. // -// Example JSON: -// {"RoundID":42, +// BroadcastMessage Example JSON: +// { +// "RoundID":42, // "EphID":[0,0,0,0,0,0,24,61], +// "RoundURL":"https://dashboard.xx.network/rounds/25?xxmessenger=true", // "Payload":"SGVsbG8sIGJyb2FkY2FzdCBmcmllbmRzIQ==" // } type BroadcastMessage struct { @@ -57,13 +59,16 @@ type BroadcastMessage struct { // BroadcastReport is the bindings representation of the info on how a broadcast // message was sent // -// Example JSON: -// {"RoundID":42, -// "EphID":[0,0,0,0,0,0,24,61] +// BroadcastReport Example JSON: +// { +// "Rounds": [25, 26, 29], +// "EphID":[0,0,0,0,0,0,24,61], +// "RoundURL":"https://dashboard.xx.network/rounds/25?xxmessenger=true" // } type BroadcastReport struct { RoundsList - EphID ephemeral.Id + RoundURL string + EphID ephemeral.Id } // BroadcastListener is the public function type bindings can use to listen for @@ -131,6 +136,7 @@ func (c *Channel) Listen(l BroadcastListener, method int) error { l.Callback(json.Marshal(&BroadcastMessage{ BroadcastReport: BroadcastReport{ RoundsList: makeRoundsList(round.ID), + RoundURL: getRoundURL(round.ID), EphID: receptionID.EphId, }, Payload: payload, @@ -152,6 +158,7 @@ func (c *Channel) Broadcast(payload []byte) ([]byte, error) { return nil, err } return json.Marshal(BroadcastReport{ + RoundURL: getRoundURL(rid), RoundsList: makeRoundsList(rid.ID), EphID: eid, }) @@ -174,6 +181,7 @@ func (c *Channel) BroadcastAsymmetric(payload, pk []byte) ([]byte, error) { } return json.Marshal(BroadcastReport{ RoundsList: makeRoundsList(rid.ID), + RoundURL: getRoundURL(rid), EphID: eid, }) } diff --git a/bindings/connect.go b/bindings/connect.go index faaffc1956afc88ef17762cf52bd22fc09ae737e..df3d4ae46c7f7c0a016ecd75fb576e0e48c98e87 100644 --- a/bindings/connect.go +++ b/bindings/connect.go @@ -94,6 +94,7 @@ func (c *Connection) SendE2E(mt int, payload []byte) ([]byte, error) { sr := E2ESendReport{ RoundsList: makeRoundsList(sendReport.RoundList...), + RoundURL: getRoundURL(sendReport.RoundList[0]), MessageID: sendReport.MessageId.Marshal(), Timestamp: sendReport.SentTime.UnixNano(), KeyResidue: sendReport.KeyResidue.Marshal(), diff --git a/bindings/delivery.go b/bindings/delivery.go index 89521d887175367d6fd40966363b8e12a7fbd89a..6420196d4e16f34edae4510cb7d1d228f7e0b2d2 100644 --- a/bindings/delivery.go +++ b/bindings/delivery.go @@ -9,6 +9,7 @@ package bindings import ( "encoding/json" + "fmt" "time" "github.com/pkg/errors" @@ -17,9 +18,33 @@ import ( "gitlab.com/xx_network/primitives/id" ) +// dashboardBaseURL is the base of the xx network's round dashboard URL. +// This should be used by any type of send report's GetRoundURL method. +var dashboardBaseURL = "https://dashboard.xx.network" + +// SetDashboardURL is a function which modifies the base dashboard URL +// that is returned as part of any send report. Internally, this is defaulted +// to "https://dashboard.xx.network". This should only be called if the user +// explicitly wants to modify the dashboard URL. This function is not +// thread-safe, and as such should only be called on setup. +// +// Parameters: +// - newURL - A valid URL that will be used for round look up on any send +// report. +func SetDashboardURL(newURL string) { + dashboardBaseURL = newURL +} + +// getRoundURL is a helper function which returns the specific round +// within any type of send report, if they have a round in their RoundsList. +// This helper function is messenger specific. +func getRoundURL(round id.Round) string { + return fmt.Sprintf("%s/rounds/%d?xxmessenger=true", dashboardBaseURL, round) +} + // RoundsList contains a list of round IDs. // -// Example marshalled roundList object: +// JSON Example: // [1001,1003,1006] type RoundsList struct { Rounds []uint64 diff --git a/bindings/e2eHandler.go b/bindings/e2eHandler.go index 3eeffdd546b2acdb8934c485ed76b8c7b6dcda08..4b63407520f8e1aa756f2e749e4b0971fc72fdd2 100644 --- a/bindings/e2eHandler.go +++ b/bindings/e2eHandler.go @@ -23,15 +23,17 @@ import ( // E2ESendReport is the bindings' representation of the return values of // SendE2E. // -// Example E2ESendReport: -//{ -//"Rounds": [ 1, 4, 9], -//"MessageID": "iM34yCIr4Je8ZIzL9iAAG1UWAeDiHybxMTioMAaezvs=", -//"Timestamp": 1661532254302612000, -//"KeyResidue": "9q2/A69EAuFM1hFAT7Bzy5uGOQ4T6bPFF72h5PlgCWE=" -//} +// E2ESendReport Example JSON: +// { +// "Rounds": [ 1, 4, 9], +// "RoundURL":"https://dashboard.xx.network/rounds/25?xxmessenger=true", +// "MessageID": "iM34yCIr4Je8ZIzL9iAAG1UWAeDiHybxMTioMAaezvs=", +// "Timestamp": 1661532254302612000, +// "KeyResidue": "9q2/A69EAuFM1hFAT7Bzy5uGOQ4T6bPFF72h5PlgCWE=" +// } type E2ESendReport struct { RoundsList + RoundURL string MessageID []byte Timestamp int64 KeyResidue []byte @@ -160,6 +162,7 @@ func (e *E2e) SendE2E(messageType int, recipientId, payload, result := E2ESendReport{ RoundsList: makeRoundsList(sendReport.RoundList...), + RoundURL: getRoundURL(sendReport.RoundList[0]), MessageID: sendReport.MessageId.Marshal(), Timestamp: sendReport.SentTime.UnixNano(), KeyResidue: sendReport.KeyResidue.Marshal(), diff --git a/bindings/group.go b/bindings/group.go index 6b2041bdb548f3d3f9ccb5b6758e1be45c28faca..7ecd29558fdb3aeeeb449b3635b43cee15516806 100644 --- a/bindings/group.go +++ b/bindings/group.go @@ -157,6 +157,7 @@ func (g *GroupChat) MakeGroup( report := GroupReport{ Id: grp.ID.Bytes(), RoundsList: makeRoundsList(roundIDs...), + RoundURL: getRoundURL(roundIDs[0]), Status: int(status), } @@ -199,6 +200,7 @@ func (g *GroupChat) ResendRequest(groupId []byte) ([]byte, error) { report := &GroupReport{ Id: grp.ID.Bytes(), RoundsList: makeRoundsList(rnds...), + RoundURL: getRoundURL(rnds[0]), Status: int(status), } @@ -269,6 +271,7 @@ func (g *GroupChat) Send(groupId, message []byte, tag string) ([]byte, error) { // Construct send report sendReport := &GroupSendReport{ + RoundURL: getRoundURL(round), RoundsList: makeRoundsList(round.ID), Timestamp: timestamp.UnixNano(), MessageID: msgID.Bytes(), @@ -407,6 +410,7 @@ type GroupRequest interface { } // GroupChatProcessor manages the handling of received group chat messages. +// The decryptedMessage field will be a JSON marshalled GroupChatMessage. type GroupChatProcessor interface { Process(decryptedMessage, msg, receptionId []byte, ephemeralId, roundId int64, err error) @@ -419,13 +423,53 @@ type groupChatProcessor struct { bindingsCb GroupChatProcessor } +// GroupChatMessage is the bindings layer representation of the +// [groupChat.MessageReceive]. +// +// GroupChatMessage Example JSON: +// { +// "GroupId": "AAAAAAAJlasAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE", +// "SenderId": "AAAAAAAAB8gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD", +// "MessageId": "Zm9ydHkgZml2ZQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=", +// "Payload": "Zm9ydHkgZml2ZQ==", +// "Timestamp": 1663009269474079000 +// } +type GroupChatMessage struct { + // GroupId is the ID of the group that this message was sent on. + GroupId []byte + + // SenderId is the ID of the sender of this message. + SenderId []byte + + // MessageId is the ID of this group message. + MessageId []byte + + // Payload is the content of the message. + Payload []byte + + // Timestamp is the time this message was sent on. + Timestamp int64 +} + +// convertMessageReceive is a helper function which converts a +// [groupChat.MessageReceive] to the bindings-layer representation GroupChatMessage. +func convertMessageReceive(decryptedMsg gc.MessageReceive) GroupChatMessage { + return GroupChatMessage{ + GroupId: decryptedMsg.GroupID.Bytes(), + SenderId: decryptedMsg.SenderID.Bytes(), + MessageId: decryptedMsg.ID.Bytes(), + Payload: decryptedMsg.Payload, + Timestamp: decryptedMsg.Timestamp.UnixNano(), + } +} + // convertProcessor turns the input of a groupChat.Processor to the // binding-layer primitives equivalents within the GroupChatProcessor.Process. func convertGroupChatProcessor(decryptedMsg gc.MessageReceive, msg format.Message, receptionID receptionID.EphemeralIdentity, round rounds.Round) ( decryptedMessage, message, receptionId []byte, ephemeralId, roundId int64, err error) { - decryptedMessage, err = json.Marshal(decryptedMsg) + decryptedMessage, err = json.Marshal(convertMessageReceive(decryptedMsg)) message = msg.Marshal() receptionId = receptionID.Source.Marshal() ephemeralId = receptionID.EphId.Int64() @@ -451,16 +495,34 @@ func (gcp *groupChatProcessor) String() string { // GroupReport is returned when creating a new group and contains the ID of // the group, a list of rounds that the group requests were sent on, and the // status of the send operation. +// +// Example GroupReport JSON: +// { +// "Id": "AAAAAAAAAM0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE", +// "Rounds": [25, 64], +// "RoundURL": "https://dashboard.xx.network/rounds/25?xxmessenger=true", +// "Status": 1 +// } type GroupReport struct { Id []byte RoundsList - Status int + RoundURL string + Status int } // GroupSendReport is returned when sending a group message. It contains the // round ID sent on and the timestamp of the send operation. +// +// Example GroupSendReport JSON: +// { +// "Rounds": [25, 64], +// "RoundURL": "https://dashboard.xx.network/rounds/25?xxmessenger=true", +// "Timestamp": 1662577352813112000, +// "MessageID": "69ug6FA50UT2q6MWH3hne9PkHQ+H9DnEDsBhc0m0Aww=" +// } type GroupSendReport struct { RoundsList + RoundURL string Timestamp int64 MessageID []byte } diff --git a/bindings/json_test.go b/bindings/json_test.go deleted file mode 100644 index 4dd6eeadcfe5f789aa59ef1f2a1ba7b372e2b709..0000000000000000000000000000000000000000 --- a/bindings/json_test.go +++ /dev/null @@ -1,40 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// Copyright © 2022 xx foundation // -// // -// Use of this source code is governed by a license that can be found in the // -// LICENSE file. // -//////////////////////////////////////////////////////////////////////////////// - -package bindings - -import ( - "encoding/json" - "gitlab.com/elixxir/crypto/e2e" - "math/rand" - "testing" - "time" -) - -func TestName(t *testing.T) { - rl := []uint64{1, 4, 9} - prng := rand.New(rand.NewSource(42)) - rfp := make([]byte, 32) - prng.Read(rfp) - mid := e2e.NewMessageID(rfp, prng.Uint64()) - - randData := make([]byte, 32) - prng.Read(randData) - k := e2e.Key{} - copy(k[:], randData) - kr := e2e.NewKeyResidue(k) - - report := E2ESendReport{ - RoundsList: RoundsList{rl}, - MessageID: mid.Marshal(), - Timestamp: time.Now().UnixNano(), - KeyResidue: kr.Marshal(), - } - - marshal, _ := json.Marshal(report) - t.Logf("%s", marshal) -} diff --git a/bindings/listener.go b/bindings/listener.go index cc2bba18222e19a6f4bbf0f3f57948e7e9899872..8eaf0faff2e58bb188a9451f624d2eae1926bd9c 100644 --- a/bindings/listener.go +++ b/bindings/listener.go @@ -62,6 +62,7 @@ type Message struct { Encrypted bool RoundId int + RoundURL string } // Hear is called to receive a message in the UI. @@ -76,6 +77,7 @@ func (l listener) Hear(item receive.Message) { Timestamp: item.Timestamp.UnixNano(), Encrypted: item.Encrypted, RoundId: int(item.Round.ID), + RoundURL: getRoundURL(item.Round.ID), } result, err := json.Marshal(&m) if err != nil { diff --git a/bindings/single.go b/bindings/single.go index 71c4420148dcf7049a4b4fdc911afd990b810838..d6625cd71d8fe027fa2a64ca1b146d30e6f6eef0 100644 --- a/bindings/single.go +++ b/bindings/single.go @@ -64,6 +64,7 @@ func TransmitSingleUse(e2eID int, recipient []byte, tag string, payload, EphID: eid.EphId.Int64(), ReceptionID: eid.Source, RoundsList: makeRoundsList(rids...), + RoundURL: getRoundURL(rids[0]), } return json.Marshal(sr) } @@ -99,14 +100,16 @@ func Listen(e2eID int, tag string, cb SingleUseCallback) (Stopper, error) { // SingleUseSendReport is the bindings-layer struct used to represent // information returned by single.TransmitRequest. // -// JSON example: +// SingleUseSendReport JSON example: // { // "Rounds":[1,5,9], +// "RoundURL": "https://dashboard.xx.network/rounds/25?xxmessenger=true", // "EphID":1655533, // "ReceptionID":"emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD"} // } type SingleUseSendReport struct { RoundsList + RoundURL string ReceptionID *id.ID EphID int64 } @@ -115,9 +118,10 @@ type SingleUseSendReport struct { // information passed to the single.Response callback interface in response to // single.TransmitRequest. // -// JSON example: +// SingleUseResponseReport JSON example: // { // "Rounds":[1,5,9], +// "RoundURL": "https://dashboard.xx.network/rounds/25?xxmessenger=true", // "Payload":"rSuPD35ELWwm5KTR9ViKIz/r1YGRgXIl5792SF8o8piZzN6sT4Liq4rUU/nfOPvQEjbfWNh/NYxdJ72VctDnWw==", // "EphID":1655533, // "ReceptionID":"emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD"}, @@ -125,6 +129,7 @@ type SingleUseSendReport struct { // } type SingleUseResponseReport struct { RoundsList + RoundURL string Payload []byte ReceptionID *id.ID EphID int64 @@ -134,16 +139,18 @@ type SingleUseResponseReport struct { // SingleUseCallbackReport is the bindings-layer struct used to represent // single -use messages received by a callback passed into single.Listen. // -// JSON example: -// { -// "Rounds":[1,5,9], -// "Payload":"rSuPD35ELWwm5KTR9ViKIz/r1YGRgXIl5792SF8o8piZzN6sT4Liq4rUU/nfOPvQEjbfWNh/NYxdJ72VctDnWw==", -// "Partner":"emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD", -// "EphID":1655533, -// "ReceptionID":"emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD"} -// } +// SingleUseCallbackReport JSON example: +// { +// "Rounds":[1,5,9], +// "RoundURL": "https://dashboard.xx.network/rounds/25?xxmessenger=true", +// "Payload":"rSuPD35ELWwm5KTR9ViKIz/r1YGRgXIl5792SF8o8piZzN6sT4Liq4rUU/nfOPvQEjbfWNh/NYxdJ72VctDnWw==", +// "Partner":"emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD", +// "EphID":1655533, +// "ReceptionID":"emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD"} +// } type SingleUseCallbackReport struct { RoundsList + RoundURL string Payload []byte Partner *id.ID EphID int64 @@ -208,6 +215,7 @@ func (sl singleUseListener) Callback( scr := SingleUseCallbackReport{ Payload: req.GetPayload(), RoundsList: makeRoundsList(rids...), + RoundURL: getRoundURL(rids[0]), Partner: req.GetPartner(), EphID: eid.EphId.Int64(), ReceptionID: eid.Source, @@ -246,6 +254,7 @@ func (sr singleUseResponse) Callback(payload []byte, } sendReport := SingleUseResponseReport{ RoundsList: makeRoundsList(rids...), + RoundURL: getRoundURL(rids[0]), ReceptionID: receptionID.Source, EphID: receptionID.EphId.Int64(), Payload: payload, diff --git a/bindings/ud.go b/bindings/ud.go index a49031ad7fd9752a99315c6606c04706cbb1b800..d167e145daf1e110bf0728cf13bc28c54287538a 100644 --- a/bindings/ud.go +++ b/bindings/ud.go @@ -414,6 +414,7 @@ func LookupUD(e2eID int, udContact []byte, cb UdLookupCallback, EphID: eid.EphId.Int64(), ReceptionID: eid.Source, RoundsList: makeRoundsList(rids...), + RoundURL: getRoundURL(rids[0]), } return json.Marshal(sr) @@ -517,6 +518,7 @@ func SearchUD(e2eID int, udContact []byte, cb UdSearchCallback, EphID: eid.EphId.Int64(), ReceptionID: eid.Source, RoundsList: makeRoundsList(rids...), + RoundURL: getRoundURL(rids[0]), } return json.Marshal(sr) diff --git a/cmd/callbacks.go b/cmd/callbacks.go index 79ea1931d349b3c056c29ce33a6dfdbddc60cb7e..058c79dd0430b81243a4077f167694b37a909c3d 100644 --- a/cmd/callbacks.go +++ b/cmd/callbacks.go @@ -27,6 +27,7 @@ import ( type authCallbacks struct { autoConfirm bool confCh chan *id.ID + reqCh chan *id.ID params xxdk.E2EParams } @@ -34,6 +35,7 @@ func makeAuthCallbacks(autoConfirm bool, params xxdk.E2EParams) *authCallbacks { return &authCallbacks{ autoConfirm: autoConfirm, confCh: make(chan *id.ID, 10), + reqCh: make(chan *id.ID, 10), params: params, } } @@ -44,7 +46,7 @@ func (a *authCallbacks) Request(requestor contact.Contact, msg := fmt.Sprintf("Authentication channel request from: %s\n", requestor.ID) jww.INFO.Printf(msg) - fmt.Printf(msg) + fmt.Print(msg) if a.autoConfirm { jww.INFO.Printf("Channel Request: %s", requestor.ID) @@ -55,8 +57,9 @@ func (a *authCallbacks) Request(requestor contact.Contact, } a.confCh <- requestor.ID + } else { + a.reqCh <- requestor.ID } - } func (a *authCallbacks) Confirm(requestor contact.Contact, @@ -72,7 +75,7 @@ func (a *authCallbacks) Reset(requestor contact.Contact, msg := fmt.Sprintf("Authentication channel reset from: %s\n", requestor.ID) jww.INFO.Printf(msg) - fmt.Printf(msg) + fmt.Print(msg) } func registerMessageListener(user *xxdk.E2e) chan receive.Message { diff --git a/cmd/root.go b/cmd/root.go index 66240fdb9b20a332daaca3d7a77ff24a9186a6e6..33ae2745e7a35176a14d1b1bc39f057cbaa85de6 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -14,11 +14,12 @@ import ( "encoding/hex" "encoding/json" "fmt" - cryptoE2e "gitlab.com/elixxir/crypto/e2e" "io/ioutil" "log" "os" + cryptoE2e "gitlab.com/elixxir/crypto/e2e" + "github.com/pkg/profile" "strconv" @@ -76,8 +77,13 @@ var rootCmd = &cobra.Command{ cmixParams, e2eParams := initParams() - authCbs := makeAuthCallbacks( - viper.GetBool(unsafeChannelCreationFlag), e2eParams) + autoConfirm := viper.GetBool(unsafeChannelCreationFlag) + acceptChannels := viper.GetBool(acceptChannelFlag) + if acceptChannels { + autoConfirm = false + } + + authCbs := makeAuthCallbacks(autoConfirm, e2eParams) user := initE2e(cmixParams, e2eParams, authCbs) jww.INFO.Printf("Client Initialized...") @@ -96,12 +102,14 @@ var rootCmd = &cobra.Command{ recipientContact = readContact(destFile) recipientID = recipientContact.ID } else if destId == "0" || sendId == destId { - jww.INFO.Printf("Sending message to self") + jww.INFO.Printf("Sending message to self, " + + "this will timeout unless authrequest is sent") recipientID = receptionIdentity.ID recipientContact = receptionIdentity.GetContact() } else { recipientID = parseRecipient(destId) - jww.INFO.Printf("destId: %v\nrecipientId: %v", destId, recipientID) + jww.INFO.Printf("destId: %v\nrecipientId: %v", destId, + recipientID) } isPrecanPartner := isPrecanID(recipientID) @@ -151,11 +159,42 @@ var rootCmd = &cobra.Command{ // Send Messages msgBody := viper.GetString(messageFlag) + hasMsgs := true + if msgBody == "" { + hasMsgs = false + } time.Sleep(10 * time.Second) // Accept auth request for this recipient + authSecs := viper.GetUint(authTimeoutFlag) authConfirmed := false - if viper.GetBool(acceptChannelFlag) { + jww.INFO.Printf("Preexisting E2e partners: %+v", user.GetE2E().GetAllPartnerIDs()) + if user.GetE2E().HasAuthenticatedChannel(recipientID) { + jww.INFO.Printf("Authenticated channel already in "+ + "place for %s", recipientID) + authConfirmed = true + } else { + jww.INFO.Printf("No authenticated channel in "+ + "place for %s", recipientID) + } + + if acceptChannels && !authConfirmed { + for reqDone := false; !reqDone; { + select { + case reqID := <-authCbs.reqCh: + if recipientID.Cmp(reqID) { + reqDone = true + } else { + fmt.Printf( + "unexpected request:"+ + " %s", reqID) + } + case <-time.After(time.Duration(authSecs) * + time.Second): + fmt.Print("timed out on auth request") + reqDone = true + } + } // Verify that the confirmation message makes it to the // original sender if viper.GetBool(verifySendFlag) { @@ -171,16 +210,6 @@ var rootCmd = &cobra.Command{ authConfirmed = true } - jww.INFO.Printf("Preexisting E2e partners: %+v", user.GetE2E().GetAllPartnerIDs()) - if user.GetE2E().HasAuthenticatedChannel(recipientID) { - jww.INFO.Printf("Authenticated channel already in "+ - "place for %s", recipientID) - authConfirmed = true - } else { - jww.INFO.Printf("No authenticated channel in "+ - "place for %s", recipientID) - } - // Send unsafe messages or not? unsafe := viper.GetBool(unsafeFlag) sendAuthReq := viper.GetBool(sendAuthRequestFlag) @@ -200,7 +229,7 @@ var rootCmd = &cobra.Command{ authConfirmed = false } - if !unsafe && !authConfirmed { + if !unsafe && !authConfirmed && hasMsgs { // Signal for authConfirm callback in a separate thread go func() { for { @@ -216,16 +245,15 @@ var rootCmd = &cobra.Command{ scnt := uint(0) // Wait until authConfirmed - waitSecs := viper.GetUint(authTimeoutFlag) - for !authConfirmed && scnt < waitSecs { + for !authConfirmed && scnt < authSecs { time.Sleep(1 * time.Second) scnt++ } - if scnt == waitSecs { + if scnt == authSecs { jww.FATAL.Panicf("Could not confirm "+ "authentication channel for %s, "+ "waited %d seconds.", recipientID, - waitSecs) + authSecs) } jww.INFO.Printf("Authentication channel confirmation"+ " took %d seconds", scnt) @@ -278,6 +306,13 @@ var rootCmd = &cobra.Command{ wg := &sync.WaitGroup{} sendCnt := int(viper.GetUint(sendCountFlag)) + if !hasMsgs && sendCnt != 0 { + msg := "No message to send, please set your message" + + "or set sendCount to 0 to suppress this warning" + jww.WARN.Printf(msg) + fmt.Print(msg) + sendCnt = 0 + } wg.Add(sendCnt) go func() { sendDelay := time.Duration(viper.GetUint(sendDelayFlag)) @@ -556,7 +591,7 @@ func addAuthenticatedChannel(user *xxdk.E2e, recipientID *id.ID, msg := fmt.Sprintf("Adding authenticated channel for: %s\n", recipientID) jww.INFO.Printf(msg) - fmt.Printf(msg) + fmt.Print(msg) recipientContact := recipient diff --git a/go.sum b/go.sum index bb0d85da6ed772424c60be27552323b8d8f05621..25ccb95846b43d260308ccb8aae526bd3b1bafa7 100644 --- a/go.sum +++ b/go.sum @@ -637,6 +637,8 @@ gitlab.com/elixxir/crypto v0.0.7-0.20220902165412-5c5e3e990e84 h1:sQCoZ+w09X/8Lj gitlab.com/elixxir/crypto v0.0.7-0.20220902165412-5c5e3e990e84/go.mod h1:Sfb4ceEoWLLYNT8V6isZa5k87NfUecM8i34Z+hDYTgg= gitlab.com/elixxir/ekv v0.2.1-0.20220901224437-ab4cbf94bf8b h1:0cN/WHbFaonJEN+odqyjtSrkuEbBnEnWfggT91svPGc= gitlab.com/elixxir/ekv v0.2.1-0.20220901224437-ab4cbf94bf8b/go.mod h1:USLD7xeDnuZEavygdrgzNEwZXeLQJK/w1a+htpN+JEU= +gitlab.com/elixxir/ekv v0.2.1 h1:dtwbt6KmAXG2Tik5d60iDz2fLhoFBgWwST03p7T+9Is= +gitlab.com/elixxir/ekv v0.2.1/go.mod h1:USLD7xeDnuZEavygdrgzNEwZXeLQJK/w1a+htpN+JEU= gitlab.com/elixxir/primitives v0.0.0-20200731184040-494269b53b4d/go.mod h1:OQgUZq7SjnE0b+8+iIAT2eqQF+2IFHn73tOo+aV11mg= gitlab.com/elixxir/primitives v0.0.0-20200804170709-a1896d262cd9/go.mod h1:p0VelQda72OzoUckr1O+vPW0AiFe0nyKQ6gYcmFSuF8= gitlab.com/elixxir/primitives v0.0.0-20200804182913-788f47bded40/go.mod h1:tzdFFvb1ESmuTCOl1z6+yf6oAICDxH2NPUemVgoNLxc=