AKASHAorg / secure-webstore

A secure IndexedDB store with built-in encryption
MIT License
44 stars 6 forks source link

Webstore instance lost on page refresh #16

Closed Master-Y0da closed 3 years ago

Master-Y0da commented 3 years ago

I'm using vue js 2. I have a main file with this code:

 import Vue from 'vue'
 import App from './App.vue'
 import router from './router'

const Store = require('secure-webstore').Store

const store = new Store('user_data', 'lachiquichiqui89')

store.init().then(() => {
  // store is ready
})

Vue.prototype.$store = store

new Vue({
  router,
  render: h => h(App)
}).$mount('#app')

This is working fine...I already store some data in indexeddb....but when I refresh the page, I think maybe the instance is lost, because I'm getting this error trying to get the store object inside a component:

Error: Master key not initialized
at Store.get key [as key] (secure-webstore.js?ee28:31)
at Store.eval (secure-webstore.js?ee28:87)
at Generator.next (<anonymous>)
at fulfilled (secure-webstore.js?ee28:4)

And data it's ok!!, so I don't know how to solve it...please help! cap

deiu commented 3 years ago

At which point does that error show up in your code? What line?

Something else you can check is if you're properly using Promises -- either with .then() or the more modern async/await. This library requires the use of Promises. Check this link to learn how to do that: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises.

Master-Y0da commented 3 years ago

@deiu The error is showing up at this point:

   Vue.prototype.$store.get('user')
      .then(function(data){

        if(Object.entries(data.info).length === 0){
            data.info = {
               id: response.data.id,
                nombre: response.data.nombre,
                email: response.data.email,
                is_superuser: response.data.is_superuser
             }

              Vue.prototype.$store.set('user',  data)
              next()
            }

          })
          .catch(err => console.log(err))

This run without problems first time...but if the user reloads the page, gives the error.

deiu commented 3 years ago

Yeah, but at which line in that code? What exactly in that code is triggering the error?

Master-Y0da commented 3 years ago

@deiu oh!...the first one:

Vue.prototype.$store.get('user')

deiu commented 3 years ago

It looks to me like a race condition. The get("user") code is running before the store finished initializing. You should either use await when initializing the store, or do the get() call inside the init promise:

store.init().then(() => {
  store.get() // your get function here
})
Master-Y0da commented 3 years ago

@deiu your suggestion solves part of my problem, but gives me another. After init secure webstore, the first time I interact with the store object is in my Login component, for storing user data, like this:

  //Axios call over here
  info.token = response.data
  self.$store.set('user',  info)

I try your suggest like this on my main.js file:

const start = async() => { 
  await store.init().then(() => {
     // store is ready
     Vue.prototype.$store = store
  })
 }

But now I'm getting this error at login component:

TypeError: Cannot read property 'set' of undefined at eval (Login.vue?7463:99)

Master-Y0da commented 3 years ago

@deiu Solved!!...I just add a setTimeOut function and wait by 2 seconds...and now it's working...However would be nice if this kind of issues could be considered at next release. Thanks for your time and help!!

deiu commented 3 years ago

I'm glad you found a solution to your problem. However, what you have encountered is not really an issue with this library. If you'd permit, I would like to suggest that you look more into Javascript Promises and the async/await approach. This library requires Promises due to its use of the browser's native Webcrypto API.

I will mark this issue as closed.