diff --git a/bindings/channels.go b/bindings/channels.go index 9a5dd53c55a565bb210eb3e284048b3f940e25b3..df88e79cbe92cce916953bdf997aabaec054eccd 100644 --- a/bindings/channels.go +++ b/bindings/channels.go @@ -1447,14 +1447,14 @@ func (cm *ChannelsManager) SendSilent(channelIdBytes []byte, validUntilMS int64, // then an error will be returned. // // Parameters: -// - channelIdBytes - Marshalled bytes of the channel's [id.ID]. -// - inviteToChannelBytes - Marshalled bytes of the invitee channel. +// - channelIdBytes - Marshalled bytes of the channel's [id.ID] +// This is invited channel. +// - inviteToChannelJSON - A JSON marshalled channel. This should be the data +// of the invitee channel. This can be retrieved from [GetChannelJSON]. // - message - The contents of the message. The message should be at most 510 // bytes. This is expected to be Unicode, and thus a string data type is // expected. // - host - The URL to append the channel info to. -// - maxUses - The maximum number of uses the link can be used (0 for -// unlimited). // - validUntilMS - The lease of the message. This will be how long the // message is available from the network, in milliseconds. As per the // [channels.Manager] documentation, this has different meanings depending @@ -1477,7 +1477,7 @@ func (cm *ChannelsManager) SendSilent(channelIdBytes []byte, validUntilMS int64, // Returns: // - []byte - JSON of [ChannelSendReport]. func (cm *ChannelsManager) SendInvite(channelIdBytes, - inviteToChannelBytes []byte, message string, host string, maxUses int, + inviteToJson []byte, message string, host string, validUntilMS int64, cmixParamsJSON []byte, pingsJSON []byte) ( []byte, error) { @@ -1488,12 +1488,6 @@ func (cm *ChannelsManager) SendInvite(channelIdBytes, return nil, err } - // Unmarshal channel to invite to - inviteTo, err := id.Unmarshal(inviteToChannelBytes) - if err != nil { - return nil, err - } - // Calculate lease lease := time.Duration(validUntilMS) * time.Millisecond if validUntilMS == ValidForeverBindings { @@ -1505,9 +1499,17 @@ func (cm *ChannelsManager) SendInvite(channelIdBytes, return nil, err } + // Retrieve channel that will be used for the invitation + var inviteToChan *cryptoBroadcast.Channel + err = json.Unmarshal(inviteToJson, &inviteToChan) + if err != nil { + return nil, + errors.WithMessage(err, "could not unmarshal channel json") + } + // Send invite messageID, rnd, ephID, err := cm.api.SendInvite(channelID, message, - inviteTo, host, maxUses, lease, params.CMIX, pings) + inviteToChan, host, lease, params.CMIX, pings) // Construct send report return constructChannelSendReport(&messageID, rnd.ID, &ephID) diff --git a/bindings/dm.go b/bindings/dm.go index a5ccf348b8ffd0d3ee8d95cefad4221d55711d6c..25c70049b4ebe9f3918284a134b387b0c6174376 100644 --- a/bindings/dm.go +++ b/bindings/dm.go @@ -12,6 +12,7 @@ import ( "encoding/base64" "encoding/json" "gitlab.com/elixxir/client/v4/dm/storage" + cryptoBroadcast "gitlab.com/elixxir/crypto/broadcast" "sync" "github.com/pkg/errors" @@ -545,34 +546,27 @@ func (dmc *DMClient) SendSilent(partnerPubKeyBytes []byte, // channel. // // Parameters: -// - channelsManagerId - ID of [ChannelsManager] object in tracker. This can -// be retrieved using [ChannelsManager.GetID]. // - partnerPubKeyBytes - The bytes of the public key of the partner's ED25519 // signing key. // - partnerToken - The token used to derive the reception ID for the partner. -// - inviteToChannelBytes - Marshalled bytes of the channel the user is -// inviting another user to. +// - inviteToChannelJson - A JSON marshalled channel. This should be the data +// of the invitee channel. This can be retrieved from [GetChannelJSON]. // - message - The contents of the message. The message should be at most 510 // bytes. This is expected to be Unicode, and thus a string data type is // expected. // - host - The URL to append the channel info to. -// - maxUses - The maximum number of uses the link can be used (0 for -// unlimited). // - cmixParamsJSON - A JSON marshalled [xxdk.CMIXParams]. This may be empty, // and GetDefaultCMixParams will be used internally. -func (dmc *DMClient) SendInvite(channelsManagerId int, partnerPubKeyBytes []byte, - partnerToken int32, inviteToChannelBytes []byte, message string, - host string, maxUses int, cmixParamsJSON []byte) ([]byte, error) { +func (dmc *DMClient) SendInvite(partnerPubKeyBytes []byte, + partnerToken int32, inviteToChannelJson []byte, message string, + host string, cmixParamsJSON []byte) ([]byte, error) { - chanMan, err := channelManagerTrackerSingleton.get(channelsManagerId) + // Retrieve channel that will be used for the invitation + var inviteToChan *cryptoBroadcast.Channel + err := json.Unmarshal(inviteToChannelJson, &inviteToChan) if err != nil { - return nil, err - } - - // Unmarshal channel ID - inviteToID, err := id.Unmarshal(inviteToChannelBytes) - if err != nil { - return nil, err + return nil, + errors.WithMessage(err, "could not unmarshal channel json") } // Unmarshal cmix params @@ -581,17 +575,11 @@ func (dmc *DMClient) SendInvite(channelsManagerId int, partnerPubKeyBytes []byte return nil, err } - // Retrieve channel from manager - inviteTo, err := chanMan.api.GetChannel(inviteToID) - if err != nil { - return nil, err - } - partnerPubKey := ed25519.PublicKey(partnerPubKeyBytes) // Send invite msgID, rnd, ephID, err := dmc.api.SendInvite(&partnerPubKey, - uint32(partnerToken), message, inviteTo, host, maxUses, params.CMIX) + uint32(partnerToken), message, inviteToChan, host, params.CMIX) if err != nil { return nil, err } diff --git a/channels/interface.go b/channels/interface.go index 00f14a629c82bc5cae2f0a1632f8b00a4532f87b..5c09907fc8ded1c1d2824feb47e7b1fecf1b558f 100644 --- a/channels/interface.go +++ b/channels/interface.go @@ -182,8 +182,9 @@ type Manager interface { // // See [Manager.SendGeneric] for details on payload size limitations and // elaboration of pings. - SendInvite(channelID *id.ID, msg string, inviteTo *id.ID, host string, - maxUses int, validUntil time.Duration, params cmix.CMIXParams, + SendInvite(channelID *id.ID, msg string, inviteTo *cryptoBroadcast.Channel, + host string, + validUntil time.Duration, params cmix.CMIXParams, pings []ed25519.PublicKey) ( cryptoMessage.ID, rounds.Round, ephemeral.Id, error) diff --git a/channels/send.go b/channels/send.go index 457051d693cceab6e2de1051e89da0a37aa419fd..2b4a25e2a88ad0f5dd8c9b0bf080e237b6faeac0 100644 --- a/channels/send.go +++ b/channels/send.go @@ -13,6 +13,7 @@ import ( "crypto/hmac" "encoding/base64" "fmt" + cryptoBroadcast "gitlab.com/elixxir/crypto/broadcast" "time" "github.com/pkg/errors" @@ -424,10 +425,19 @@ func (m *manager) SendSilent(channelID *id.ID, validUntil time.Duration, // // See [Manager.SendGeneric] for details on payload size limitations and // elaboration of pings. -func (m *manager) SendInvite(channelID *id.ID, msg string, inviteTo *id.ID, - host string, maxUses int, validUntil time.Duration, params cmix.CMIXParams, +func (m *manager) SendInvite(channelID *id.ID, msg string, + inviteTo *cryptoBroadcast.Channel, + host string, validUntil time.Duration, params cmix.CMIXParams, pings []ed25519.PublicKey) (message.ID, rounds.Round, ephemeral.Id, error) { + // fixme: As of writing, maxUses is not a functional parameter. It + // is passed down to the lower levels, but requires server side changes to + // enforce, which have not been implemented. Until that is done, + // maxUses will be hard-coded here. Once it is done, this function + // signature and all corresponding interface(s) should be modified + // such that maxUses is a parameter w/ proper documentation. + const maxUses = 0 + // Formulate custom tag tag := makeChaDebugTag( channelID, m.me.PubKey, []byte(msg), SendInviteTag) @@ -438,19 +448,10 @@ func (m *manager) SendInvite(channelID *id.ID, msg string, inviteTo *id.ID, jww.INFO.Printf( "[CH] [%s] SendInvite on to channel %s", tag, channelID) - // Retrieve channel that will be used for the invitation - ch, err := m.getChannel(inviteTo) - if err != nil { - return message.ID{}, rounds.Round{}, ephemeral.Id{}, - errors.WithMessage(err, - "could form invitation for a channel that has not been joined.") - - } - // Form link for invitation rng := m.rng.GetStream() defer rng.Close() - inviteUrl, password, err := ch.broadcast.Get().ShareURL(host, maxUses, rng) + inviteUrl, password, err := inviteTo.ShareURL(host, maxUses, rng) if err != nil { return message.ID{}, rounds.Round{}, ephemeral.Id{}, errors.WithMessage(err, "could not form URL") diff --git a/channels/send_test.go b/channels/send_test.go index c4ece7080d9a365f25314e458ba6a3a91da46d49..05eb074b5c0ee6fb2ca67da97f43ddd90ab2fb88 100644 --- a/channels/send_test.go +++ b/channels/send_test.go @@ -546,7 +546,7 @@ func Test_manager_SendInvite(t *testing.T) { ch, _, err := m.generateChannel("abc", "abc", cryptoBroadcast.Public, 1000) require.NoError(t, err) - invitedChannelID, inviteeChannelID := ch.ReceptionID, ch.ReceptionID + invitedChannelID, inviteeChannel := ch.ReceptionID, ch msg := "Dude check out this channel!" params := new(cmix.CMIXParams) @@ -558,7 +558,7 @@ func Test_manager_SendInvite(t *testing.T) { host := "https://internet.speakeasy.tech/" maxUses := 0 messageID, _, _, err := m.SendInvite(invitedChannelID, msg, - inviteeChannelID, host, maxUses, ValidForever, *params, nil) + inviteeChannel, host, ValidForever, *params, nil) require.NoError(t, err) // Verify the message was handled correctly diff --git a/channelsFileTransfer/utils_test.go b/channelsFileTransfer/utils_test.go index 02b1addd43ec39294e64c48b4815cc6e9677c8e5..656af2634d8eb3e68790e1e1f63b9901cde6f43f 100644 --- a/channelsFileTransfer/utils_test.go +++ b/channelsFileTransfer/utils_test.go @@ -586,7 +586,7 @@ func (m *mockChannelsManager) SendSilent(channelID *id.ID, validUntil time.Durat panic("implement me") } -func (m *mockChannelsManager) SendInvite(channelID *id.ID, msg string, inviteTo *id.ID, host string, maxUses int, validUntil time.Duration, params cmix.CMIXParams, pings []ed25519.PublicKey) (cryptoMessage.ID, rounds.Round, ephemeral.Id, error) { +func (m *mockChannelsManager) SendInvite(channelID *id.ID, msg string, inviteTo *cryptoBroadcast.Channel, host string, validUntil time.Duration, params cmix.CMIXParams, pings []ed25519.PublicKey) (cryptoMessage.ID, rounds.Round, ephemeral.Id, error) { panic("implement me") } diff --git a/dm/dm_test.go b/dm/dm_test.go index 3256468cdfd2a87f88393d890efb605c1a40d24a..5b7df2df577ce8ab961958373add71903d178658 100644 --- a/dm/dm_test.go +++ b/dm/dm_test.go @@ -106,9 +106,9 @@ func TestE2EDMs(t *testing.T) { pubKey = rcvB1.PubKey dmToken = rcvB1.DMToken host := "https://internet.speakeasy.tech/" - maxUses := 0 + _, _, _, err = clientA.SendInvite(&pubKey, dmToken, "Check this channel out!", - broadcastChan.Get(), host, maxUses, params) + broadcastChan.Get(), host, params) require.NoError(t, err) require.Equal(t, 5, len(receiverB.Msgs)) rcvB2 := receiverB.Msgs[4] diff --git a/dm/interfaces.go b/dm/interfaces.go index 498f130703018c129339fcaa2a4871bdda7b467e..c91104548e0e9a1b0d71db7084591de80d45ef0e 100644 --- a/dm/interfaces.go +++ b/dm/interfaces.go @@ -90,7 +90,7 @@ type Sender interface { // channel. SendInvite(partnerPubKey *ed25519.PublicKey, partnerToken uint32, msg string, inviteTo *cryptoBroadcast.Channel, - host string, maxUses int, params cmix.CMIXParams) ( + host string, params cmix.CMIXParams) ( cryptoMessage.ID, rounds.Round, ephemeral.Id, error) // SendSilent is used to send to a channel a message with no notifications. diff --git a/dm/send.go b/dm/send.go index 889bb13a92f814b49a9d836eab669a22fb74b168..c76f9c6bd15dc62300d4d8c5bd483bf44fc2c666 100644 --- a/dm/send.go +++ b/dm/send.go @@ -206,8 +206,16 @@ func (dc *dmClient) SendSilent(partnerPubKey *ed25519.PublicKey, // channel. func (dc *dmClient) SendInvite(partnerPubKey *ed25519.PublicKey, partnerToken uint32, msg string, inviteTo *cryptoBroadcast.Channel, - host string, maxUses int, params cmix.CMIXParams) ( + host string, params cmix.CMIXParams) ( cryptoMessage.ID, rounds.Round, ephemeral.Id, error) { + // fixme: As of writing, maxUses is not a functional parameter. It + // is passed down to the lower levels, but requires server side changes to + // enforce, which have not been implemented. Until that is done, + // maxUses will be hard-coded here. Once it is done, this function + // signature and all corresponding interface(s) should be modified + // such that maxUses is a parameter w/ proper documentation. + const maxUses = 0 + // Formulate custom tag tag := makeDebugTag( *partnerPubKey, []byte(msg),