diff --git a/go.mod b/go.mod index 7f9e5c583559f7ee9f5a36ac7ec509b8bd3aa73f..e054815c165089872d18d5b341793ca0e0adb66b 100644 --- a/go.mod +++ b/go.mod @@ -7,11 +7,11 @@ require ( github.com/hack-pad/go-indexeddb v0.2.0 github.com/pkg/errors v0.9.1 github.com/spf13/jwalterweatherman v1.1.0 - gitlab.com/elixxir/client v1.5.1-0.20221015023821-51c0e575f5fa - gitlab.com/elixxir/crypto v0.0.7-0.20221015023742-e1108df47b6b - gitlab.com/elixxir/primitives v0.0.3-0.20220901220638-1acc75fabdc6 - gitlab.com/xx_network/crypto v0.0.5-0.20220913213008-98764f5b3287 - gitlab.com/xx_network/primitives v0.0.4-0.20221010192422-3479f09b7769 + gitlab.com/elixxir/client v1.5.1-0.20221017175256-aedcb7c137b7 + gitlab.com/elixxir/crypto v0.0.7-0.20221017173452-565da4101a3b + gitlab.com/elixxir/primitives v0.0.3-0.20221017172918-6176818d1aba + gitlab.com/xx_network/crypto v0.0.5-0.20221017172404-b384a8d8b171 + gitlab.com/xx_network/primitives v0.0.4-0.20221017171439-42169a3e5c0d golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa ) @@ -34,6 +34,7 @@ require ( github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect github.com/rs/cors v1.8.2 // indirect + github.com/sethvargo/go-diceware v0.3.0 // indirect github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect github.com/soheilhy/cmux v0.1.5 // indirect github.com/ttacon/builder v0.0.0-20170518171403-c099f663e1c2 // indirect @@ -41,9 +42,9 @@ require ( github.com/tyler-smith/go-bip39 v1.1.0 // indirect github.com/zeebo/blake3 v0.2.3 // indirect gitlab.com/elixxir/bloomfilter v0.0.0-20211222005329-7d931ceead6f // indirect - gitlab.com/elixxir/comms v0.0.4-0.20221011183106-8c4450ba3cfb // indirect + gitlab.com/elixxir/comms v0.0.4-0.20221017173926-4eaa6061dfaa // indirect gitlab.com/elixxir/ekv v0.2.1 // indirect - gitlab.com/xx_network/comms v0.0.4-0.20221005205845-b34d538ffd85 // indirect + gitlab.com/xx_network/comms v0.0.4-0.20221017172508-09e33697dc15 // indirect gitlab.com/xx_network/ring v0.0.3-0.20220222211904-da613960ad93 // indirect go.uber.org/atomic v1.10.0 // indirect go.uber.org/ratelimit v0.2.0 // indirect diff --git a/go.sum b/go.sum index c7f1f5e0e03df1e12195094cff77f2abce09a3ab..ec4e5411d0c0049fa833a4918748e1bc1240dc47 100644 --- a/go.sum +++ b/go.sum @@ -538,6 +538,8 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb github.com/sagikazarmark/crypt v0.6.0/go.mod h1:U8+INwJo3nBv1m6A/8OBXAq7Jnpspk5AxSgDyEQcea8= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/sethvargo/go-diceware v0.3.0 h1:UVVEfmN/uF50JfWAN7nbY6CiAlp5xeSx+5U0lWKkMCQ= +github.com/sethvargo/go-diceware v0.3.0/go.mod h1:lH5Q/oSPMivseNdhMERAC7Ti5oOPqsaVddU1BcN1CY0= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -614,39 +616,34 @@ github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= gitlab.com/elixxir/bloomfilter v0.0.0-20211222005329-7d931ceead6f h1:yXGvNBqzZwAhDYlSnxPRbgor6JWoOt1Z7s3z1O9JR40= gitlab.com/elixxir/bloomfilter v0.0.0-20211222005329-7d931ceead6f/go.mod h1:H6jztdm0k+wEV2QGK/KYA+MY9nj9Zzatux/qIvDDv3k= -gitlab.com/elixxir/client v1.5.1-0.20221015023821-51c0e575f5fa h1:xg69Eo15D+UoTaJGDwBee8puRhurGesXNWmIR4ma1Uc= -gitlab.com/elixxir/client v1.5.1-0.20221015023821-51c0e575f5fa/go.mod h1:aYFQ0Tgrei+IgmFQi9R3gqfYO5IZzFgGDLJhyJS75/c= -gitlab.com/elixxir/comms v0.0.4-0.20221011183106-8c4450ba3cfb h1:aw7Ao1oqho+97gO35HkzBmv2e25qluRXEiNXw/oD8MM= -gitlab.com/elixxir/comms v0.0.4-0.20221011183106-8c4450ba3cfb/go.mod h1:oRteMH+R5t1j/FZ+KJJnZUcqJO2sLXnWksN5HPkZUIo= +gitlab.com/elixxir/client v1.5.1-0.20221017175256-aedcb7c137b7 h1:NLsGSE/zZwXlMBxzIT7enoj9TRm6jkdfD+2MtsopwSM= +gitlab.com/elixxir/client v1.5.1-0.20221017175256-aedcb7c137b7/go.mod h1:C/BcaLL/hDtub1wj10B8U6Ln6N5S/Q83/zOrE6VIMpE= +gitlab.com/elixxir/comms v0.0.4-0.20221017173926-4eaa6061dfaa h1:/FEpu0N0rAyq74FkvO3uY8BcQoWLSbVPhj/s5QfscZw= +gitlab.com/elixxir/comms v0.0.4-0.20221017173926-4eaa6061dfaa/go.mod h1:rW7xdbHntP2MoF3q+2+f+IR8OHol94MRyviotfR5rXg= gitlab.com/elixxir/crypto v0.0.0-20200804182833-984246dea2c4/go.mod h1:ucm9SFKJo+K0N2GwRRpaNr+tKXMIOVWzmyUD0SbOu2c= gitlab.com/elixxir/crypto v0.0.3/go.mod h1:ZNgBOblhYToR4m8tj4cMvJ9UsJAUKq+p0gCp07WQmhA= -gitlab.com/elixxir/crypto v0.0.7-0.20220913220142-ab0771bad0af/go.mod h1:QF8SzsrYh9Elip9EUYUDAhPjqO9DGrrrQxYHvn+VXok= -gitlab.com/elixxir/crypto v0.0.7-0.20221015023742-e1108df47b6b h1:gWB95fteva1kMYR/qzdkxMMAs771wIvYd97D9nPy/xI= -gitlab.com/elixxir/crypto v0.0.7-0.20221015023742-e1108df47b6b/go.mod h1:QF8SzsrYh9Elip9EUYUDAhPjqO9DGrrrQxYHvn+VXok= +gitlab.com/elixxir/crypto v0.0.7-0.20221017173452-565da4101a3b h1:5VBuenFNKOq0omDYmUet3Deu3pAkzNIkveQBtNO/o0k= +gitlab.com/elixxir/crypto v0.0.7-0.20221017173452-565da4101a3b/go.mod h1:1rftbwSVdy49LkBIkPr+w+P2mDOerYeBKoZuB3r0yqI= 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= gitlab.com/elixxir/primitives v0.0.1/go.mod h1:kNp47yPqja2lHSiS4DddTvFpB/4D9dB2YKnw5c+LJCE= -gitlab.com/elixxir/primitives v0.0.3-0.20220606195757-40f7a589347f/go.mod h1:9Bb2+u+CDSwsEU5Droo6saDAXuBDvLRjexpBhPAYxhA= -gitlab.com/elixxir/primitives v0.0.3-0.20220810173935-592f34a88326/go.mod h1:9Bb2+u+CDSwsEU5Droo6saDAXuBDvLRjexpBhPAYxhA= -gitlab.com/elixxir/primitives v0.0.3-0.20220901220638-1acc75fabdc6 h1:/cxxZBP5jTPDpC3zgOx9vV1ojmJyG8pYtkl3IbcewNQ= -gitlab.com/elixxir/primitives v0.0.3-0.20220901220638-1acc75fabdc6/go.mod h1:9Bb2+u+CDSwsEU5Droo6saDAXuBDvLRjexpBhPAYxhA= +gitlab.com/elixxir/primitives v0.0.3-0.20221017172918-6176818d1aba h1:skhrlmHdEQfuT/4Ip2IVcI4ToNzPlmAxTYlTk034Il0= +gitlab.com/elixxir/primitives v0.0.3-0.20221017172918-6176818d1aba/go.mod h1:Rqbl8ToZxPn86RyqrpjIE9FJbFHoJgQfg68iSOTPcz8= gitlab.com/xx_network/comms v0.0.0-20200805174823-841427dd5023/go.mod h1:owEcxTRl7gsoM8c3RQ5KAm5GstxrJp5tn+6JfQ4z5Hw= -gitlab.com/xx_network/comms v0.0.4-0.20221005205845-b34d538ffd85 h1:bX2IYFnEbWTNGhZHfzHME19pkfD4Q7oTxFGI70PM2PM= -gitlab.com/xx_network/comms v0.0.4-0.20221005205845-b34d538ffd85/go.mod h1:E2QKOKyPKLRjLUwMxgZpTKueEsHDEqshfqOHJ54ttxU= +gitlab.com/xx_network/comms v0.0.4-0.20221017172508-09e33697dc15 h1:H2OptkCpcGAgplz5PYMqUiA4aH/LUcjc9nLbGM+vUus= +gitlab.com/xx_network/comms v0.0.4-0.20221017172508-09e33697dc15/go.mod h1:yBDaXAWiPGGv2zXQgP35Ks/ek800Uaah4roVFyvMkWU= gitlab.com/xx_network/crypto v0.0.3/go.mod h1:DF2HYvvCw9wkBybXcXAgQMzX+MiGbFPjwt3t17VRqRE= gitlab.com/xx_network/crypto v0.0.4/go.mod h1:+lcQEy+Th4eswFgQDwT0EXKp4AXrlubxalwQFH5O0Mk= -gitlab.com/xx_network/crypto v0.0.5-0.20220913213008-98764f5b3287 h1:Jd71F8f/8rieWybMqkxpKKZVVyGkeCNZWZcviGGnQ9A= -gitlab.com/xx_network/crypto v0.0.5-0.20220913213008-98764f5b3287/go.mod h1:/SJf+R75E+QepdTLh0H1/udsovxx2Q5ru34q1v0umKk= +gitlab.com/xx_network/crypto v0.0.5-0.20221017172404-b384a8d8b171 h1:zGrUU8U6pMl5J4yzKzJ3QOAoo6g0Nna7Z+vVxxijpLg= +gitlab.com/xx_network/crypto v0.0.5-0.20221017172404-b384a8d8b171/go.mod h1:sZ5bMKbb6v+Qx3zwXsWsbhVikOte/1ibflLpbCVuboQ= gitlab.com/xx_network/primitives v0.0.0-20200803231956-9b192c57ea7c/go.mod h1:wtdCMr7DPePz9qwctNoAUzZtbOSHSedcK++3Df3psjA= gitlab.com/xx_network/primitives v0.0.0-20200804183002-f99f7a7284da/go.mod h1:OK9xevzWCaPO7b1wiluVJGk7R5ZsuC7pHY5hteZFQug= gitlab.com/xx_network/primitives v0.0.2/go.mod h1:cs0QlFpdMDI6lAo61lDRH2JZz+3aVkHy+QogOB6F/qc= -gitlab.com/xx_network/primitives v0.0.4-0.20220222211843-901fa4a2d72b/go.mod h1:9imZHvYwNFobxueSvVtHneZLk9wTK7HQTzxPm+zhFhE= -gitlab.com/xx_network/primitives v0.0.4-0.20220809193445-9fc0a5209548/go.mod h1:AXVVFt7dDAeIUpOGPiStCcUIKsBXLWbmV/BgZ4T+tOo= -gitlab.com/xx_network/primitives v0.0.4-0.20221010192422-3479f09b7769 h1:BBYSog3VSKudey4rhWnCw54PcGcD4YRjTrnwzOhJ/GE= -gitlab.com/xx_network/primitives v0.0.4-0.20221010192422-3479f09b7769/go.mod h1:AXVVFt7dDAeIUpOGPiStCcUIKsBXLWbmV/BgZ4T+tOo= +gitlab.com/xx_network/primitives v0.0.4-0.20221017171439-42169a3e5c0d h1:rOcGGx5SrhBkbD1P8JqbtqBBeuGhOSZxETytNGJcf/U= +gitlab.com/xx_network/primitives v0.0.4-0.20221017171439-42169a3e5c0d/go.mod h1:AXVVFt7dDAeIUpOGPiStCcUIKsBXLWbmV/BgZ4T+tOo= gitlab.com/xx_network/ring v0.0.3-0.20220222211904-da613960ad93 h1:eJZrXqHsMmmejEPWw8gNAt0I8CGAMNO/7C339Zco3TM= gitlab.com/xx_network/ring v0.0.3-0.20220222211904-da613960ad93/go.mod h1:aLzpP2TiZTQut/PVHR40EJAomzugDdHXetbieRClXIM= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= diff --git a/main.go b/main.go index 6397758038f8ddddb10a2f8f11262af7e331917f..0e067b2e46c0193c0f05907fa23fbd6a6e3c34d5 100644 --- a/main.go +++ b/main.go @@ -64,6 +64,7 @@ func main() { js.FuncOf(wasm.LoadChannelsManagerWithIndexedDb)) js.Global().Set("GenerateChannel", js.FuncOf(wasm.GenerateChannel)) js.Global().Set("GetChannelInfo", js.FuncOf(wasm.GetChannelInfo)) + js.Global().Set("GetShareUrlType", js.FuncOf(wasm.GetShareUrlType)) js.Global().Set("IsNicknameValid", js.FuncOf(wasm.IsNicknameValid)) // wasm/cmix.go diff --git a/wasm/channels.go b/wasm/channels.go index 951e36dc3ece27fd5310216a2f1ccfec71b4b62f..7c24054fe13ba833c5819012a8a72ab35eea8a12 100644 --- a/wasm/channels.go +++ b/wasm/channels.go @@ -34,11 +34,15 @@ func newChannelsManagerJS(api *bindings.ChannelsManager) map[string]interface{} cm := ChannelsManager{api} channelsManagerMap := map[string]interface{}{ // Basic Channel API - "GetID": js.FuncOf(cm.GetID), - "JoinChannel": js.FuncOf(cm.JoinChannel), - "GetChannels": js.FuncOf(cm.GetChannels), - "LeaveChannel": js.FuncOf(cm.LeaveChannel), - "ReplayChannel": js.FuncOf(cm.ReplayChannel), + "GetID": js.FuncOf(cm.GetID), + "JoinChannel": js.FuncOf(cm.JoinChannel), + "JoinChannelFromURL": js.FuncOf(cm.JoinChannelFromURL), + "GetChannels": js.FuncOf(cm.GetChannels), + "LeaveChannel": js.FuncOf(cm.LeaveChannel), + "ReplayChannel": js.FuncOf(cm.ReplayChannel), + + // Share URL + "GetShareURL": js.FuncOf(cm.GetShareURL), // Channel Sending Methods and Reports "SendGeneric": js.FuncOf(cm.SendGeneric), @@ -348,21 +352,35 @@ func LoadChannelsManagerWithIndexedDb(_ js.Value, args []js.Value) interface{} { // // Parameters: // - args[0] - ID of [Cmix] object in tracker (int). -// - args[1] - The name of the new channel. The name cannot be longer than __ -// characters and must contain only _____ characters. It cannot be changed -// once a channel is created. (string). -// - args[2] - The description of a channel. The description cannot be longer -// than __ characters and must contain only __ characters. It cannot be -// changed once a channel is created (string). +// - args[1] - The name of the new channel (string). The name must be between 3 +// and 24 characters inclusive. It can only include upper and lowercase +// unicode letters, digits 0 through 9, and underscores (_). It cannot be +// changed once a channel is created. +// - args[2] - The description of a channel (string). The description is +// optional but cannot be longer than 144 characters and can include all +// unicode characters. It cannot be changed once a channel is created. +// - args[3] - The [broadcast.PrivacyLevel] of the channel (int). 0 = public, +// 1 = private, and 2 = secret. Refer to the comment below for more +// information. // // Returns: // - JSON of [bindings.ChannelGeneration], which describes a generated channel. // It contains both the public channel info and the private key for the // channel in PEM format (Uint8Array). // - Throws a TypeError if generating the channel fails. +// +// The [broadcast.PrivacyLevel] of a channel indicates the level of channel +// information revealed when sharing it via URL. For any channel besides public +// channels, the secret information is encrypted and a password is required to +// share and join a channel. +// - A privacy level of [broadcast.Public] reveals all the information +// including the name, description, privacy level, public key and salt. +// - A privacy level of [broadcast.Private] reveals only the name and +// description. +// - A privacy level of [broadcast.Secret] reveals nothing. func GenerateChannel(_ js.Value, args []js.Value) interface{} { gen, err := bindings.GenerateChannel( - args[0].Int(), args[1].String(), args[2].String()) + args[0].Int(), args[1].String(), args[2].String(), args[3].Int()) if err != nil { utils.Throw(utils.TypeError, err) return nil @@ -377,7 +395,7 @@ func GenerateChannel(_ js.Value, args []js.Value) interface{} { // - args[0] - The pretty print of the channel (string). // // The pretty print will be of the format: -// <XXChannel-v1:Test Channel,description:This is a test channel,secrets:pn0kIs6P1pHvAe7u8kUyf33GYVKmkoCX9LhCtvKJZQI=,3A5eB5pzSHyxN09w1kOVrTIEr5UyBbzmmd9Ga5Dx0XA=,0,0,/zChIlLr2p3Vsm2X4+3TiFapoapaTi8EJIisJSqwfGc=> +// <Speakeasy-v1:Test Channel,description:This is a test channel,secrets:YxHhRAKy2D4XU2oW5xnW/3yaqOeh8nO+ZSd3nUmiQ3c=,6pXN2H9FXcOj7pjJIZoq6nMi4tGX2s53fWH5ze2dU1g=,493,1,MVjkHlm0JuPxQNAn6WHsPdOw9M/BUF39p7XB/QEkQyc=> // // Returns: // - JSON of [bindings.ChannelInfo], which describes all relevant channel info @@ -401,7 +419,7 @@ func GetChannelInfo(_ js.Value, args []js.Value) interface{} { // or generated via GenerateChannel (string). // // The pretty print will be of the format: -// <XXChannel-v1:Test Channel,description:This is a test channel,secrets:pn0kIs6P1pHvAe7u8kUyf33GYVKmkoCX9LhCtvKJZQI=,3A5eB5pzSHyxN09w1kOVrTIEr5UyBbzmmd9Ga5Dx0XA=,0,0,/zChIlLr2p3Vsm2X4+3TiFapoapaTi8EJIisJSqwfGc=>" +// <Speakeasy-v1:Test Channel,description:This is a test channel,secrets:YxHhRAKy2D4XU2oW5xnW/3yaqOeh8nO+ZSd3nUmiQ3c=,6pXN2H9FXcOj7pjJIZoq6nMi4tGX2s53fWH5ze2dU1g=,493,1,MVjkHlm0JuPxQNAn6WHsPdOw9M/BUF39p7XB/QEkQyc=> // // Returns: // - JSON of [bindings.ChannelInfo], which describes all relevant channel info @@ -417,6 +435,32 @@ func (ch *ChannelsManager) JoinChannel(_ js.Value, args []js.Value) interface{} return utils.CopyBytesToJS(ci) } +// JoinChannelFromURL joins the given channel from a URL. It will fail if the +// channel has already been joined. A password is required unless it is of the +// privacy level [broadcast.Public], in which case it can be left empty. To get +// the privacy level of a channel URL, use [GetShareUrlType]. +// +// Parameters: +// - args[0] - The channel's share URL. Should be received from another user +// or generated via [ChannelsManager.GetShareURL] (string). +// - args[1] - The password needed to decrypt the secret data in the URL +// (string). Only required for private or secret channels. Use empty string +// ("") for public channels. +// +// Returns: +// - JSON of [bindings.ChannelInfo], which describes all relevant channel info +// (Uint8Array). +// - Throws a TypeError if joining the channel fails. +func (ch *ChannelsManager) JoinChannelFromURL(_ js.Value, args []js.Value) interface{} { + ci, err := ch.api.JoinChannelFromURL(args[0].String(), args[1].String()) + if err != nil { + utils.Throw(utils.TypeError, err) + return nil + } + + return utils.CopyBytesToJS(ci) +} + // GetChannels returns the IDs of all channels that have been joined. // // Returns: @@ -478,6 +522,81 @@ func (ch *ChannelsManager) ReplayChannel(_ js.Value, args []js.Value) interface{ return nil } +//////////////////////////////////////////////////////////////////////////////// +// Channel Share URL // +//////////////////////////////////////////////////////////////////////////////// + +type ShareURL struct { + URL string `json:"url"` + Password string `json:"password"` +} + +// GetShareURL generates a URL that can be used to share this channel with +// others on the given host. +// +// A URL comes in one of three forms based on the privacy level set when +// generating the channel. Each privacy level hides more information than the +// last with the lowest level revealing everything and the highest level +// revealing nothing. For any level above the lowest, a password is returned, +// which will be required when decoding the URL. +// +// The maxUses is the maximum number of times this URL can be used to join a +// channel. If it is set to 0, then it can be shared unlimited times. The max +// uses is set as a URL parameter using the key [broadcast.MaxUsesKey]. Note +// that this number is also encoded in the secret data for private and secret +// URLs, so if the number is changed in the URL, is will be verified when +// calling [ChannelsManager.JoinChannelFromURL]. There is no enforcement for +// public URLs. +// +// Parameters: +// - args[0] - ID of [Cmix] object in tracker (int). +// - args[1] - The URL to append the channel info to (string). +// - args[2] - The maximum number of uses the link can be used (0 for +// unlimited) (int). +// - args[3] - Marshalled bytes of the channel [id.ID] (Uint8Array). +// +// Returns: +// - JSON of [bindings.ShareURL] (Uint8Array). +// - Throws a TypeError if generating the URL fails. +func (ch *ChannelsManager) GetShareURL(_ js.Value, args []js.Value) interface{} { + cmixID := args[0].Int() + host := args[1].String() + maxUses := args[2].Int() + marshalledChanId := utils.CopyBytesToGo(args[3]) + + su, err := ch.api.GetShareURL(cmixID, host, maxUses, marshalledChanId) + if err != nil { + utils.Throw(utils.TypeError, err) + return nil + } + + return utils.CopyBytesToJS(su) +} + +// GetShareUrlType determines the [broadcast.PrivacyLevel] of the channel URL. +// If the URL is an invalid channel URL, an error is returned. +// +// Parameters: +// - args[0] - The channel share URL (string). +// +// Returns: +// - An int that corresponds to the [broadcast.PrivacyLevel] as outlined below. +// - Throws a TypeError if parsing the URL fails. +// +// Possible returns: +// 0 = public channel +// 1 = private channel +// 2 = secret channel +func GetShareUrlType(_ js.Value, args []js.Value) interface{} { + level, err := bindings.GetShareUrlType(args[0].String()) + if err != nil { + utils.Throw(utils.TypeError, err) + return nil + } + + return level +} + //////////////////////////////////////////////////////////////////////////////// // Channel Sending Methods and Reports // ////////////////////////////////////////////////////////////////////////////////