diff --git a/go.mod b/go.mod index 0e2abb04b9db291dde75b9d43940411e80b86b4d..21f7d6b7a225aa35ef7cf568888238600319a2f4 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/pkg/errors v0.9.1 github.com/spf13/cobra v1.5.0 github.com/spf13/jwalterweatherman v1.1.0 - gitlab.com/elixxir/client/v4 v4.3.12-0.20230223233610-b55d5f3dd721 + gitlab.com/elixxir/client/v4 v4.3.12-0.20230302181743-042f9c941d2d gitlab.com/elixxir/crypto v0.0.7-0.20230214180106-72841fd1e426 gitlab.com/elixxir/primitives v0.0.3-0.20230214180039-9a25e2d3969c gitlab.com/xx_network/crypto v0.0.5-0.20230214003943-8a09396e95dd diff --git a/go.sum b/go.sum index a02bdd037d42e694e22df9ba9a218be1e14d4281..38feac4898ee3dd65e65957d0970ba40eec8e15a 100644 --- a/go.sum +++ b/go.sum @@ -523,6 +523,8 @@ gitlab.com/elixxir/client/v4 v4.3.12-0.20230301213027-a1f292f0d5b6 h1:z4hsdZMeUl gitlab.com/elixxir/client/v4 v4.3.12-0.20230301213027-a1f292f0d5b6/go.mod h1:Hjx99EdI86q67mHzZVR2Dw37fuTCzDaChM/NVX3CcPU= gitlab.com/elixxir/client/v4 v4.3.12-0.20230301220451-27e45ee98181 h1:61z1CLMvimf4TvZtMqVmYT3ALvHKyUueteFBQHutfZI= gitlab.com/elixxir/client/v4 v4.3.12-0.20230301220451-27e45ee98181/go.mod h1:Hjx99EdI86q67mHzZVR2Dw37fuTCzDaChM/NVX3CcPU= +gitlab.com/elixxir/client/v4 v4.3.12-0.20230302181743-042f9c941d2d h1:cGwKd4uFi2/CAwSUcymcMfyuNfBaYSyDnHYcd+Pqxp4= +gitlab.com/elixxir/client/v4 v4.3.12-0.20230302181743-042f9c941d2d/go.mod h1:Hjx99EdI86q67mHzZVR2Dw37fuTCzDaChM/NVX3CcPU= gitlab.com/elixxir/comms v0.0.4-0.20230214180204-3aba2e6795af h1:Eye4+gZEUbOfz4j51WplYD9d7Gnr1s3wKYkEnCfhPaw= gitlab.com/elixxir/comms v0.0.4-0.20230214180204-3aba2e6795af/go.mod h1:ud3s2aHx5zu7lJhBpUMUXxjLwl8PH8z8cl64Om9U7q8= gitlab.com/elixxir/crypto v0.0.7-0.20230214180106-72841fd1e426 h1:O9Xz/ioc9NAj5k/QUsR0W4LCz2uVHawJF89yPTI7NXk= diff --git a/indexedDb/impl/dm/implementation_test.go b/indexedDb/impl/dm/implementation_test.go new file mode 100644 index 0000000000000000000000000000000000000000..6f724b85ef9b5d9be23402f8a3f398c78c49f8fd --- /dev/null +++ b/indexedDb/impl/dm/implementation_test.go @@ -0,0 +1,62 @@ +//////////////////////////////////////////////////////////////////////////////// +// Copyright © 2022 xx foundation // +// // +// Use of this source code is governed by a license that can be found in the // +// LICENSE file. // +//////////////////////////////////////////////////////////////////////////////// + +package main + +import ( + "crypto/ed25519" + jww "github.com/spf13/jwalterweatherman" + "os" + "testing" +) + +func dummyReceivedMessageCB(uint64, ed25519.PublicKey, bool) {} +func dummyStoreDatabaseName(string) error { return nil } +func dummyStoreEncryptionStatus(_ string, encryptionStatus bool) (bool, error) { + return encryptionStatus, nil +} + +func TestMain(m *testing.M) { + jww.SetStdoutThreshold(jww.LevelDebug) + os.Exit(m.Run()) +} + +// Test happy path toggling between blocked/unblocked in a Conversation. +func TestWasmModel_BlockSender(t *testing.T) { + m, err := newWASMModel("test", nil, + dummyReceivedMessageCB, dummyStoreDatabaseName, dummyStoreEncryptionStatus) + if err != nil { + t.Fatal(err.Error()) + } + + // Insert a test convo + testPubKey := ed25519.PublicKey{} + err = m.joinConversation("test", testPubKey, 0, 0) + if err != nil { + t.Fatal(err.Error()) + } + + // Default to unblocked + result := m.GetConversation(testPubKey) + if result.Blocked { + t.Fatal("Expected blocked to be false") + } + + // Now toggle blocked + m.BlockSender(testPubKey) + result = m.GetConversation(testPubKey) + if !result.Blocked { + t.Fatal("Expected blocked to be true") + } + + // Now toggle blocked again + m.UnblockSender(testPubKey) + result = m.GetConversation(testPubKey) + if result.Blocked { + t.Fatal("Expected blocked to be false") + } +} diff --git a/indexedDb/worker/dm/implementation.go b/indexedDb/worker/dm/implementation.go index 650a22bff92bee49a18f4a7aae32298b45633d74..0dc9eb874c5078d08fe503085280ef5dd44dee6e 100644 --- a/indexedDb/worker/dm/implementation.go +++ b/indexedDb/worker/dm/implementation.go @@ -249,3 +249,23 @@ func (w *wasmModel) UpdateSentStatus(uuid uint64, messageID message.ID, w.wh.SendMessage(UpdateSentStatusTag, data, nil) } + +func (w *wasmModel) BlockSender(senderPubKey ed25519.PublicKey) { + //TODO implement me + panic("implement me") +} + +func (w *wasmModel) UnblockSender(senderPubKey ed25519.PublicKey) { + //TODO implement me + panic("implement me") +} + +func (w *wasmModel) GetConversation(senderPubKey ed25519.PublicKey) *dm.ModelConversation { + //TODO implement me + panic("implement me") +} + +func (w *wasmModel) GetConversations() []dm.ModelConversation { + //TODO implement me + panic("implement me") +} diff --git a/wasm/dm.go b/wasm/dm.go index 0393ac8eb41e1d7801ec26378f4e6e36b2d108f8..9f1793a76521dc43fd3af4b67a5f0449abfe176e 100644 --- a/wasm/dm.go +++ b/wasm/dm.go @@ -59,21 +59,21 @@ func newDMClientJS(api *bindings.DMClient) map[string]any { return dmClientMap } -// GetPublicKey returns the ecdh Public Key for this [DMClient] in the +// GetID returns the ecdh Public Key for this [DMClient] in the // [DMClient] tracker. // // Returns: // - Tracker ID (int). -func (ch *DMClient) GetID(js.Value, []js.Value) any { - return ch.api.GetID() +func (dmc *DMClient) GetID(js.Value, []js.Value) any { + return dmc.api.GetID() } -func (ch *DMClient) GetPublicKey(js.Value, []js.Value) any { - return ch.api.GetPublicKey() +func (dmc *DMClient) GetPublicKey(js.Value, []js.Value) any { + return dmc.api.GetPublicKey() } -func (ch *DMClient) GetToken(js.Value, []js.Value) any { - return ch.api.GetToken() +func (dmc *DMClient) GetToken(js.Value, []js.Value) any { + return dmc.api.GetToken() } // dmReceiverBuilder adheres to the [bindings.DMReceiverBuilder] interface. @@ -113,7 +113,7 @@ func (emb *dmReceiverBuilder) Build(path string) bindings.DMReceiver { func NewDMClient(_ js.Value, args []js.Value) any { privateIdentity := utils.CopyBytesToGo(args[1]) - em := &dmReceiverBuilder{args[2].Invoke} + em := &dmReceiverBuilder{args[2].IsNaN} cm, err := bindings.NewDMClient(args[0].Int(), privateIdentity, em) if err != nil { @@ -238,7 +238,7 @@ func newDMClientWithIndexedDb(cmixID int, wasmJsPath string, // Channel Sending Methods and Reports // //////////////////////////////////////////////////////////////////////////////// -// SendGeneric is used to send a raw message over a channel. In general, it +// Send is used to send a raw message over a channel. In general, it // should be wrapped in a function which defines the wire protocol. If the final // message, before being sent over the wire, is too long, this will return an // error. Due to the underlying encoding using compression, it isn't possible to @@ -262,7 +262,7 @@ func newDMClientWithIndexedDb(cmixID int, wasmJsPath string, // Returns a promise: // - Resolves to the JSON of [bindings.ChannelSendReport] (Uint8Array). // - Rejected with an error if sending fails. -func (ch *DMClient) Send(_ js.Value, args []js.Value) any { +func (dmc *DMClient) Send(_ js.Value, args []js.Value) any { messageType := args[0].Int() partnerPubKeyBytes := utils.CopyBytesToGo(args[1]) partnerToken := args[2].Int() @@ -271,7 +271,7 @@ func (ch *DMClient) Send(_ js.Value, args []js.Value) any { cmixParamsJSON := utils.CopyBytesToGo(args[5]) promiseFn := func(resolve, reject func(args ...any) js.Value) { - sendReport, err := ch.api.Send(messageType, partnerPubKeyBytes, + sendReport, err := dmc.api.Send(messageType, partnerPubKeyBytes, uint32(partnerToken), message, leaseTimeMS, cmixParamsJSON) if err != nil { @@ -284,7 +284,7 @@ func (ch *DMClient) Send(_ js.Value, args []js.Value) any { return utils.CreatePromise(promiseFn) } -// SendMessage is used to send a formatted message over a channel. +// SendText is used to send a formatted message over a channel. // Due to the underlying encoding using compression, it isn't possible to define // the largest payload that can be sent, but it will always be possible to send // a payload of 798 bytes at minimum. @@ -306,7 +306,7 @@ func (ch *DMClient) Send(_ js.Value, args []js.Value) any { // Returns a promise: // - Resolves to the JSON of [bindings.ChannelSendReport] (Uint8Array). // - Rejected with an error if sending fails. -func (ch *DMClient) SendText(_ js.Value, args []js.Value) any { +func (dmc *DMClient) SendText(_ js.Value, args []js.Value) any { partnerPubKeyBytes := utils.CopyBytesToGo(args[0]) partnerToken := args[1].Int() message := args[2].String() @@ -314,7 +314,7 @@ func (ch *DMClient) SendText(_ js.Value, args []js.Value) any { cmixParamsJSON := utils.CopyBytesToGo(args[4]) promiseFn := func(resolve, reject func(args ...any) js.Value) { - sendReport, err := ch.api.SendText(partnerPubKeyBytes, + sendReport, err := dmc.api.SendText(partnerPubKeyBytes, uint32(partnerToken), message, leaseTimeMS, cmixParamsJSON) if err != nil { @@ -358,7 +358,7 @@ func (ch *DMClient) SendText(_ js.Value, args []js.Value) any { // Returns a promise: // - Resolves to the JSON of [bindings.ChannelSendReport] (Uint8Array). // - Rejected with an error if sending fails. -func (ch *DMClient) SendReply(_ js.Value, args []js.Value) any { +func (dmc *DMClient) SendReply(_ js.Value, args []js.Value) any { partnerPubKeyBytes := utils.CopyBytesToGo(args[0]) partnerToken := args[1].Int() replyID := utils.CopyBytesToGo(args[2]) @@ -367,7 +367,7 @@ func (ch *DMClient) SendReply(_ js.Value, args []js.Value) any { cmixParamsJSON := utils.CopyBytesToGo(args[5]) promiseFn := func(resolve, reject func(args ...any) js.Value) { - sendReport, err := ch.api.SendReply(partnerPubKeyBytes, + sendReport, err := dmc.api.SendReply(partnerPubKeyBytes, uint32(partnerToken), message, replyID, leaseTimeMS, cmixParamsJSON) if err != nil { @@ -400,7 +400,7 @@ func (ch *DMClient) SendReply(_ js.Value, args []js.Value) any { // Returns a promise: // - Resolves to the JSON of [bindings.ChannelSendReport] (Uint8Array). // - Rejected with an error if sending fails. -func (ch *DMClient) SendReaction(_ js.Value, args []js.Value) any { +func (dmc *DMClient) SendReaction(_ js.Value, args []js.Value) any { partnerPubKeyBytes := utils.CopyBytesToGo(args[0]) partnerToken := args[1].Int() replyID := utils.CopyBytesToGo(args[2]) @@ -408,7 +408,7 @@ func (ch *DMClient) SendReaction(_ js.Value, args []js.Value) any { cmixParamsJSON := utils.CopyBytesToGo(args[4]) promiseFn := func(resolve, reject func(args ...any) js.Value) { - sendReport, err := ch.api.SendReaction(partnerPubKeyBytes, + sendReport, err := dmc.api.SendReaction(partnerPubKeyBytes, uint32(partnerToken), message, replyID, cmixParamsJSON) if err != nil { @@ -427,8 +427,8 @@ func (ch *DMClient) SendReaction(_ js.Value, args []js.Value) any { // Returns: // - JSON of the [channel.Identity] (Uint8Array). // - Throws TypeError if marshalling the identity fails. -func (ch *DMClient) GetIdentity(js.Value, []js.Value) any { - i := ch.api.GetIdentity() +func (dmc *DMClient) GetIdentity(js.Value, []js.Value) any { + i := dmc.api.GetIdentity() return utils.CopyBytesToJS(i) } @@ -442,8 +442,8 @@ func (ch *DMClient) GetIdentity(js.Value, []js.Value) any { // Returns: // - JSON of the encrypted private identity (Uint8Array). // - Throws TypeError if exporting the identity fails. -func (ch *DMClient) ExportPrivateIdentity(_ js.Value, args []js.Value) any { - i, err := ch.api.ExportPrivateIdentity(args[0].String()) +func (dmc *DMClient) ExportPrivateIdentity(_ js.Value, args []js.Value) any { + i, err := dmc.api.ExportPrivateIdentity(args[0].String()) if err != nil { utils.Throw(utils.TypeError, err) return nil @@ -462,8 +462,8 @@ func (ch *DMClient) ExportPrivateIdentity(_ js.Value, args []js.Value) any { // Returns: // - Throws TypeError if unmarshalling the ID fails or the nickname is // invalid. -func (ch *DMClient) SetNickname(_ js.Value, args []js.Value) any { - ch.api.SetNickname(args[0].String()) +func (dmc *DMClient) SetNickname(_ js.Value, args []js.Value) any { + dmc.api.SetNickname(args[0].String()) return nil } @@ -476,8 +476,8 @@ func (ch *DMClient) SetNickname(_ js.Value, args []js.Value) any { // Returns: // - The nickname (string). // - Throws TypeError if the channel has no nickname set. -func (ch *DMClient) GetNickname(_ js.Value, args []js.Value) any { - nickname, err := ch.api.GetNickname(utils.CopyBytesToGo(args[0])) +func (dmc *DMClient) GetNickname(_ js.Value, _ []js.Value) any { + nickname, err := dmc.api.GetNickname() if err != nil { utils.Throw(utils.TypeError, err) return nil @@ -494,8 +494,8 @@ func (ch *DMClient) GetNickname(_ js.Value, args []js.Value) any { // Returns: // - The storage tag (string). func (dmc *DMClient) GetDatabaseName(_ js.Value, args []js.Value) any { - return (base64.RawStdEncoding.EncodeToString(dmc.api.GetPublicKey()) + - "_speakeasy_dm") + return base64.RawStdEncoding.EncodeToString(dmc.api.GetPublicKey()) + + "_speakeasy_dm" } //////////////////////////////////////////////////////////////////////////////// @@ -541,7 +541,7 @@ type dmReceiver struct { updateSentStatus func(args ...any) js.Value } -// ReceiveMessage is called whenever a message is received on a given channel. +// Receive is called whenever a message is received on a given channel. // It may be called multiple times on the same message. It is incumbent on the // user of the API to filter such called by message ID. // @@ -733,6 +733,26 @@ func (em *dmReceiver) UpdateSentStatus(uuid int64, messageID []byte, timestamp, roundID, status) } +func (em *dmReceiver) BlockSender(senderPubKey []byte) { + //TODO implement me + panic("implement me") +} + +func (em *dmReceiver) UnblockSender(senderPubKey []byte) { + //TODO implement me + panic("implement me") +} + +func (em *dmReceiver) GetConversation(senderPubKey []byte) []byte { + //TODO implement me + panic("implement me") +} + +func (em *dmReceiver) GetConversations() []byte { + //TODO implement me + panic("implement me") +} + //////////////////////////////////////////////////////////////////////////////// // DM DB Cipher // ////////////////////////////////////////////////////////////////////////////////