diff --git a/indexedDb/impl/dm/implementation.go b/indexedDb/impl/dm/implementation.go index f40791ece46d05b397dadd6766ec455045168452..09303bcfa7747ef203d262c4da8e36b62c3daabe 100644 --- a/indexedDb/impl/dm/implementation.go +++ b/indexedDb/impl/dm/implementation.go @@ -179,13 +179,7 @@ func (w *wasmModel) UpdateSentStatus(uuid uint64, messageID message.ID, } // Extract the existing Message and update the Status - newMessage := &Message{} - err = json.Unmarshal([]byte(utils.JsToJson(currentMsg)), newMessage) - if err != nil { - jww.ERROR.Printf("%+v", errors.WithMessagef(parentErr, - "Could not JSON unmarshal message: %+v", err)) - return - } + newMessage, err := valueToMessage(currentMsg) newMessage.Status = uint8(status) if !messageID.Equals(message.ID{}) { @@ -365,6 +359,45 @@ func (w *wasmModel) setBlocked(senderPubKey ed25519.PublicKey, isBlocked bool) e resultConvo.Token, resultConvo.CodesetVersion, timeBlocked) } +// DeleteMessage deletes the message with the given message.ID belonging to +// the sender. If the message exists and belongs to the sender, then it is +// deleted and DeleteMessage returns true. If it does not exist, it returns +// false. +func (w *wasmModel) DeleteMessage(messageID message.ID, senderPubKey ed25519.PublicKey) bool { + parentErr := "failed to DeleteMessage" + msgId := impl.EncodeBytes(messageID.Marshal()) + + // Use the key to get the existing Message + currentMsg, err := impl.GetIndex(w.db, messageStoreName, + messageStoreMessageIndex, msgId) + if err != nil { + jww.ERROR.Printf("%s: %+v", parentErr, err) + return false + } + + // Convert the js.Value to a proper object + msgObj, err := valueToMessage(currentMsg) + if err != nil { + jww.ERROR.Printf("%s: %+v", parentErr, err) + return false + } + + // Ensure the public keys match + if !bytes.Equal(msgObj.SenderPubKey, senderPubKey) { + jww.ERROR.Printf("%s: %s", parentErr, "Public keys do not match") + return false + } + + // Perform the delete + err = impl.DeleteIndex(w.db, messageStoreName, messageStoreMessageIndex, + msgPkeyName, msgId) + if err != nil { + jww.ERROR.Printf("%s: %+v", parentErr, err) + return false + } + return true +} + // GetConversation returns the conversation held by the model (receiver). func (w *wasmModel) GetConversation(senderPubKey ed25519.PublicKey) *dm.ModelConversation { parentErr := "failed to GetConversation" @@ -426,3 +459,9 @@ func (w *wasmModel) GetConversations() []dm.ModelConversation { } return conversations } + +// valueToMessage is a helper for converting js.Value to Message. +func valueToMessage(msgObj js.Value) (*Message, error) { + resultMsg := &Message{} + return resultMsg, json.Unmarshal([]byte(utils.JsToJson(msgObj)), resultMsg) +} diff --git a/indexedDb/impl/dm/implementation_test.go b/indexedDb/impl/dm/implementation_test.go index c8f42c3871bcfc841683e93b57e2ed4105ab000b..39ca0036a078382ca232a2a725ff7a5ff412dddf 100644 --- a/indexedDb/impl/dm/implementation_test.go +++ b/indexedDb/impl/dm/implementation_test.go @@ -14,6 +14,7 @@ import ( "crypto/ed25519" "encoding/json" "fmt" + "github.com/stretchr/testify/require" "gitlab.com/elixxir/client/v4/cmix/rounds" "gitlab.com/elixxir/client/v4/dm" "gitlab.com/elixxir/crypto/message" @@ -158,3 +159,36 @@ func TestWasmModel_BlockSender(t *testing.T) { t.Fatal("Expected blocked to be false") } } + +// Test failed and successful deletes +func TestWasmModel_DeleteMessage(t *testing.T) { + m, err := newWASMModel("TestWasmModel_DeleteMessage", nil, dummyReceivedMessageCB) + if err != nil { + t.Fatal(err.Error()) + } + + // Insert test message + testBytes := []byte("test") + testBadBytes := []byte("uwu") + testMsgId := message.DeriveChannelMessageID(&id.ID{1}, 0, testBytes) + testMsg := &Message{ + MessageID: testMsgId.Marshal(), + ConversationPubKey: testBytes, + ParentMessageID: nil, + Timestamp: time.Now(), + SenderPubKey: testBytes, + CodesetVersion: 5, + Status: 5, + Text: "", + Type: 5, + Round: 5, + } + _, err = m.upsertMessage(testMsg) + require.NoError(t, err) + + // Non-matching pub key, should fail to delete + require.False(t, m.DeleteMessage(testMsgId, testBadBytes)) + + // Correct pub key, should have deleted + require.True(t, m.DeleteMessage(testMsgId, testBytes)) +}