Skip to content
This repository has been archived by the owner on Apr 11, 2023. It is now read-only.

Commit

Permalink
fix: Store vc directly in indexeddb
Browse files Browse the repository at this point in the history
closes #43

Signed-off-by: Firas Qutishat <[email protected]>
  • Loading branch information
fqutishat committed Jan 30, 2020
1 parent b518422 commit 64a4b5b
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 64 deletions.
4 changes: 2 additions & 2 deletions ci/version_var.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@


# Release Parameters
BASE_VERSION=0.1.2
IS_RELEASE=false
BASE_VERSION=0.1.1
IS_RELEASE=true

ARCH=$(go env GOARCH)

Expand Down
54 changes: 29 additions & 25 deletions pkg/store/vc/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,12 @@ SPDX-License-Identifier: Apache-2.0
package vc

import (
"encoding/json"
"fmt"
"strings"
"syscall/js"

"github.com/hyperledger/aries-framework-go/pkg/doc/verifiable"
"github.com/hyperledger/aries-framework-go/pkg/storage"
verifiablestore "github.com/hyperledger/aries-framework-go/pkg/store/verifiable"
)

const (
Expand All @@ -26,24 +25,19 @@ type provider interface {
StorageProvider() storage.Provider
}

type vcStore interface {
SaveVC(vc *verifiable.Credential) error
GetVC(vcID string) (*verifiable.Credential, error)
}

// RegisterHandleJSCallback register handle vc store js callback
func RegisterHandleJSCallback(ctx provider) error {
store, err := verifiablestore.New(ctx)
vcFriendlyNameStore, err := ctx.StorageProvider().OpenStore("vc-friendlyname")
if err != nil {
return fmt.Errorf("failed to create new instance of verifiable store: %w", err)
return fmt.Errorf("failed to open vc frindly name store: %w", err)
}

vcFriendlyNameStore, err := ctx.StorageProvider().OpenStore("vc-friendlyname")
vcStore, err := ctx.StorageProvider().OpenStore("verifiable")
if err != nil {
return fmt.Errorf("failed to open vc frindly name store: %w", err)
}

c := callback{store: store, vcFriendlyNameStore: vcFriendlyNameStore, jsDoc: js.Global().Get("document")}
c := callback{vcStore: vcStore, vcFriendlyNameStore: vcFriendlyNameStore, jsDoc: js.Global().Get("document")}
js.Global().Set("storeVC", js.FuncOf(c.storeVC))
js.Global().Set("populateVC", js.FuncOf(c.populateVC))
js.Global().Set("getVC", js.FuncOf(c.getVC))
Expand All @@ -52,7 +46,7 @@ func RegisterHandleJSCallback(ctx provider) error {
}

type callback struct {
store vcStore
vcStore storage.Store
vcFriendlyNameStore storage.Store
jsDoc js.Value
}
Expand All @@ -64,20 +58,28 @@ func (c *callback) storeVC(this js.Value, inputs []js.Value) interface{} {
m["dataType"] = "Response"
m["data"] = "success"
vcData := inputs[0].Get("credential").Get("data").String()
vc, _, err := verifiable.NewCredential([]byte(vcData))
if err != nil {
m["data"] = fmt.Sprintf("failed to create new credential: %s", err.Error())

var vcMap map[string]interface{}
if err := json.Unmarshal([]byte(vcData), &vcMap); err != nil {
m["data"] = fmt.Sprintf("failed to unmarshal vc json: %s", err.Error())
inputs[0].Call("respondWith", js.Global().Get("Promise").Call("resolve", m))
return
}

vcID := stringEntry(vcMap["id"])
if vcID == "" {
m["data"] = fmt.Sprintf("vc id not exist")
inputs[0].Call("respondWith", js.Global().Get("Promise").Call("resolve", m))
return
}

if err := c.store.SaveVC(vc); err != nil {
if err := c.vcStore.Put(vcID, []byte(vcData)); err != nil {
m["data"] = fmt.Sprintf("failed to put in vc store: %s", err.Error())
inputs[0].Call("respondWith", js.Global().Get("Promise").Call("resolve", m))
return
}

if err := c.vcFriendlyNameStore.Put(friendlyNamePreFix+inputs[1].String(), []byte(vc.ID)); err != nil {
if err := c.vcFriendlyNameStore.Put(friendlyNamePreFix+inputs[1].String(), []byte(vcID)); err != nil {
m["data"] = fmt.Sprintf("failed to put in vc friendly name store: %s", err.Error())
}

Expand Down Expand Up @@ -116,23 +118,25 @@ func (c *callback) getVC(this js.Value, inputs []js.Value) interface{} {
return
}

vc, err := c.store.GetVC(string(vcID))
vcBytes, err := c.vcStore.Get(string(vcID))
if err != nil {
m["data"] = fmt.Sprintf("failed to get in vc store: %s", err.Error())
inputs[0].Call("respondWith", js.Global().Get("Promise").Call("resolve", m))
return
}

vcBytes, err := vc.MarshalJSON()
if err != nil {
m["data"] = fmt.Sprintf("failed to marshal vc: %s", err.Error())
inputs[0].Call("respondWith", js.Global().Get("Promise").Call("resolve", m))
return
}

m["data"] = string(vcBytes)
inputs[0].Call("respondWith", js.Global().Get("Promise").Call("resolve", m))
}()

return nil
}

// stringEntry
func stringEntry(entry interface{}) string {
if entry == nil {
return ""
}

return entry.(string)
}
55 changes: 18 additions & 37 deletions pkg/store/vc/store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import (
"testing"
"time"

"github.com/hyperledger/aries-framework-go/pkg/doc/verifiable"
"github.com/hyperledger/aries-framework-go/pkg/storage"

"github.com/stretchr/testify/require"
mockstorage "github.com/trustbloc/edge-agent/pkg/internal/mock/storage"
)
Expand Down Expand Up @@ -54,23 +54,15 @@ var credential = `

func TestRegisterHandleInvitationJSCallback(t *testing.T) {
t.Run("test success", func(t *testing.T) {
require.NoError(t, RegisterHandleJSCallback(&mockProvider{
storageProviderValue: &mockstorage.MockStoreProvider{}}))
require.NoError(t, RegisterHandleJSCallback(
&mockProvider{storageProviderValue: &mockstorage.MockStoreProvider{}}))
require.True(t, js.Global().Get("storeVC").Truthy())
})

t.Run("test error from open store", func(t *testing.T) {
err := RegisterHandleJSCallback(&mockProvider{
storageProviderValue: &mockstorage.MockStoreProvider{
ErrOpenStoreHandle: fmt.Errorf("open store error")}})
require.Error(t, err)
require.Contains(t, err.Error(), "open store error")
})
}

func TestStoreVC(t *testing.T) {
t.Run("test error from new credential", func(t *testing.T) {
c := callback{store: &mockVCStore{}}
c := callback{vcStore: &mockstorage.MockStore{}}
m := make(map[string]interface{})
m1 := make(map[string]interface{})
m1["data"] = "wrongVC"
Expand All @@ -93,14 +85,14 @@ func TestStoreVC(t *testing.T) {
select {
case value := <-valueFlag:
require.Equal(t, "Response", value.Get("dataType").String())
require.Contains(t, value.Get("data").String(), "failed to create new credential")
require.Contains(t, value.Get("data").String(), "failed to unmarshal vc json")
case <-time.After(2 * time.Second):
require.Fail(t, "timeout waiting for response")
}
})

t.Run("test error from vc store", func(t *testing.T) {
c := callback{store: &mockVCStore{saveVCError: fmt.Errorf("put error")}}
c := callback{vcStore: &mockstorage.MockStore{ErrPut: fmt.Errorf("put error")}}
m := make(map[string]interface{})
m1 := make(map[string]interface{})
m1["data"] = credential
Expand Down Expand Up @@ -130,7 +122,8 @@ func TestStoreVC(t *testing.T) {
})

t.Run("test error from vc friendly name store", func(t *testing.T) {
c := callback{store: &mockVCStore{}, vcFriendlyNameStore: &mockstorage.MockStore{ErrPut: fmt.Errorf("error put")}}
c := callback{vcStore: &mockstorage.MockStore{
Store: make(map[string][]byte)}, vcFriendlyNameStore: &mockstorage.MockStore{ErrPut: fmt.Errorf("error put")}}
m := make(map[string]interface{})
m1 := make(map[string]interface{})
m1["data"] = credential
Expand Down Expand Up @@ -160,7 +153,8 @@ func TestStoreVC(t *testing.T) {
})

t.Run("test success", func(t *testing.T) {
c := callback{store: &mockVCStore{}, vcFriendlyNameStore: &mockstorage.MockStore{
c := callback{vcStore: &mockstorage.MockStore{
Store: make(map[string][]byte)}, vcFriendlyNameStore: &mockstorage.MockStore{
Store: make(map[string][]byte)}}
m := make(map[string]interface{})
m1 := make(map[string]interface{})
Expand Down Expand Up @@ -195,7 +189,8 @@ func TestPopulateVC(t *testing.T) {
t.Run("test success", func(t *testing.T) {
s := make(map[string][]byte)
js.Global().Set("document1", make(map[string]interface{}))
c := callback{store: &mockVCStore{}, vcFriendlyNameStore: &mockstorage.MockStore{
c := callback{vcStore: &mockstorage.MockStore{
Store: make(map[string][]byte)}, vcFriendlyNameStore: &mockstorage.MockStore{
Store: s}, jsDoc: js.Global().Get("document")}
c.jsDoc.Set("createElement", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
m := make(map[string]interface{})
Expand Down Expand Up @@ -225,7 +220,8 @@ func TestPopulateVC(t *testing.T) {

func TestGetVC(t *testing.T) {
t.Run("test error from vc friendly name store", func(t *testing.T) {
c := callback{store: &mockVCStore{}, vcFriendlyNameStore: &mockstorage.MockStore{ErrGet: fmt.Errorf("error get")}}
c := callback{vcStore: &mockstorage.MockStore{
Store: make(map[string][]byte)}, vcFriendlyNameStore: &mockstorage.MockStore{ErrGet: fmt.Errorf("error get")}}

m := make(map[string]interface{})
vcEvent := js.ValueOf(m)
Expand Down Expand Up @@ -254,9 +250,7 @@ func TestGetVC(t *testing.T) {

t.Run("test error from vc store", func(t *testing.T) {
s := make(map[string][]byte)
c := callback{store: &mockVCStore{getVCFunc: func(vcID string) (v *verifiable.Credential, err error) {
return nil, fmt.Errorf("vc store error")
}},
c := callback{vcStore: &mockstorage.MockStore{ErrGet: fmt.Errorf("vc store error")},
vcFriendlyNameStore: &mockstorage.MockStore{Store: s}}

s[friendlyNamePreFix+"key"] = []byte("vcKey")
Expand Down Expand Up @@ -288,11 +282,11 @@ func TestGetVC(t *testing.T) {

t.Run("test success", func(t *testing.T) {
s := make(map[string][]byte)
c := callback{store: &mockVCStore{getVCFunc: func(vcID string) (v *verifiable.Credential, err error) {
return &verifiable.Credential{ID: "vcID"}, nil
}},
c := callback{vcStore: &mockstorage.MockStore{
Store: s},
vcFriendlyNameStore: &mockstorage.MockStore{Store: s}}

s["vcKey"] = []byte("vcID")
s[friendlyNamePreFix+"key"] = []byte("vcKey")

m := make(map[string]interface{})
Expand Down Expand Up @@ -328,16 +322,3 @@ type mockProvider struct {
func (m *mockProvider) StorageProvider() storage.Provider {
return m.storageProviderValue
}

type mockVCStore struct {
saveVCError error
getVCFunc func(vcID string) (*verifiable.Credential, error)
}

func (m *mockVCStore) SaveVC(vc *verifiable.Credential) error {
return m.saveVCError
}

func (m *mockVCStore) GetVC(vcID string) (*verifiable.Credential, error) {
return m.getVCFunc(vcID)
}

0 comments on commit 64a4b5b

Please sign in to comment.