VueJS app out of sync after role updated externally via Netlify functions

original deleted b/c this was a question in reply not a standalone question.

Rewrite:
Netlify Identity appears to use a static user value.
(from localstorage perhaps?)

There doesn’t appear to be a method to call for a refresh of the current user object, only to refresh the token.

The token does get the current real (Identity) state of the user, but only contains some of the values.

// token has something like:
{
  sub
  email
  exp
  app_metadata: {
       roles: []
  }
  user_metadata: {
     full_name
  }
}

So, refreshing the jwt, decoding it, and storing those values in-app works, as long as it isn’t a value from the larger user object not contained in the jwt.
As noted in this approach:

The original question in reply to @jonsully was in regards to his library’s approach to resolving the perceived static (or cached as the other question put it) user object.

Whether he was essentially

  1. calling GoTrue's update({}) with an empty POST body to get the user object
  2. saving that object in app
  3. then calling GoTrue’s refresh(true) to force update the jwt (which, as noted above, will already have partial and possibly sufficient, user object data.

Cheers and thanks

Hey @hwlmatt Welcome to Netlify Community!

I’ve moved your post to a new thread since it varied to much from the previous post. I’m sure @jonsully will be able to help you with this.

Greetings @hwlmatt!

And welcome to The Community :netliheart:

@kylesloper — I received an email from @hwlmatt’s response in the other thread and luckily that email contains the reply content but in shifting this reply to a new thread that content was lost… so had I not gotten the email, I would have no way to know what @hwlmatt is asking :confused: Not sure why that happened — I tend to just reply in-line instead of pushing replies out to new threads, but that may be something I should do better about too. Maybe Perry can inform us on how to retain the content of the reply when making a new thread.

Anywho, here’s the question that was asked:

hey jon!
was looking to resolve the same issue (vuejs app out of sync after role updated externally via netlify functions) and wound up here.

Read through your library linked above. Very nice.

Just to be sure I’m following correctly,

This note:

and the corresponding update()

Am i correct that what you’re doing to refresh the user’s data for the app is:

  1. calling GoTrue’s user.update() without passing any attributes - an empty POST body
  2. setting the returned user in the app (b/c it has the updated app_metadata , etc, etc)
  3. forcing a refresh via GoTrue’s .jwt(true) (so that the token is correct now too)

That’s the 1,2,3 of it, yeah?

Cheers and thanks

And I’ll respond to that here next in a separate response


Jon

2 Likes

Read through your library linked above. Very nice.

Thank ya :relaxed: was a big, but good, project!

Lol at my comment that was orphaned somewhere. Sitting between blank lines like a sad, sad little code block :cry: (the “NOTE: The one trick at play”).

Am i correct that what you’re doing to refresh the user’s data for the app is:

  1. calling GoTrue’s user.update() without passing any attributes - an empty POST body

Almost! The update method actually uses a PUT not a POST — in traditional REST parlance, PUT means “edit or update an existing entity” and POST means “create a new entity with these values” IIRC. But yes, it’s a PUT with an empty body.

  1. setting the returned user in the app (b/c it has the updated app_metadata , etc, etc)

Yes, correct :+1:t2:

  1. forcing a refresh via GoTrue’s .jwt(true) (so that the token is correct now too)

Well I’m not using the gotrue-js library — mine’s written in pure JS / React (the goal of the project was to have a pure-React GoTrue client so that it didn’t need to interop with gotrue-js [which is not react] as to avoid any weird state / sync issues and open up more methods to the app), but all that aside, the premise is essentially the same, yes. Step three is getting a new JWT token since it contains the embedded user details we got in step 1+2 and unless we update the token the AuthorizedFetch premise will send out-of-date credentials.

This is actually demo’d in the gatsby-identity-demo.jonsully.net site (the demo for the library) (code here, specific code here:

In the demo site you can click a button to have “member” or “admin” roles added to your Netlify Identity User (via a Function I wrote) but that happens external to the current user — when you click the button and the Function runs, it adds the role to your user in GoTrue, but that doesn’t automatically update your role info client-side even though you clicked the button. So once that Function call completes, I run the refreshUser method to force the user data to refresh with the new role info. Similar premise.

Hope that makes sense and provides some answers!


Jon

2 Likes

Thanks for re-writing your initial question in the opening message of this new thread, @hwlmatt — hopefully I’ve given you the answers you need in my prior responses!

Seeing your context a little more, it seems like the issue is that even doing a forced refresh via the gotrue-js library only refreshes the literal JWT token and not the actual user object. Is that correct? I can’t say I’ve done that specific test with that particular library before, though frankly I wouldn’t be entirely surprised :stuck_out_tongue: there’s a reason I wrote one myself :laughing: I’m not really sure how to alleviate that issue with that specific library if that is the case though :confused:

1 Like

Ah! I was rewriting for fuller context when you posted this.

Thanks for re-writing your initial question in the opening message of this new thread, @hwlmatt — hopefully I’ve given you the answers you need in my prior responses!

Yes, very much so, thank you.
I have a feeling that PUT not POST might have been a culprit when I was trying to implement.

Seeing your context a little more, it seems like the issue is that even doing a forced refresh via the gotrue-js library only refreshes the literal JWT token and not the actual user object. Is that correct?

As I understand it, yes. The saving grace being that email, app_metadata, user_metadata, are in the jwt, and calling .refresh(true) refreshes those values as well (naturally).

But since it isn’t an actual refresh of the user object, there is that potential disconnect between app state and what .currentUser() returns (decoded token from localstorage I believe) and the user object created on log in.

Again, the refresh then decode approach linked to in the opening seems to be workable. Trying to discern if an actual refresh of full user object (as your approach provides) is doable (and/or necessary?) within the GoTrue and GoTrue wrapping universe though. :slight_smile:

Thanks again!

Yeah… it’s tricky! If you ever want to rewrite in React, there’s a great library waiting for you :laughing: but otherwise I hope you can find a path forward (and hopefully post back here for others in the future)!


And thus was born react-netlify-identity-gotrue :grin:


Jon

1 Like

Sorry about that, I did copy over everything must of been an issue somewhere along the line :thinking:
Yea I think that’s a good idea for us to take up with Perry :slightly_smiling_face:

1 Like

Hey hey, @kylesloper! Yeah, my full question to Jon was there before I edited it. Just an FYI, so you know there wasn’t an issue in copying it over.

Edited it because the original was a specific question re: the library he had mentioned in his answer to someone else having the static/cache user issue. The line regarding Vuejs was just to clarify I wasn’t asking how to use his (React) library etc., and not meant as a “how do i do this in vuejs?” or the more general “why is this happening?” framing.
I may have worded that poorly.

Sorry for any confusion!
Thanks! :slight_smile:

2 Likes

Aha thank you for clearing that up :grinning:

1 Like