Stacks-wallet-web: Ensure availability of user profile data

Created on 3 Apr 2020  ·  10Comments  ·  Source: blockstack/stacks-wallet-web

userData from userSession.loadUserData() does not work the same as the legacy blockstack.js methods.
With the previous auth I could let person = new blockstack.Person(userData) to get browser-set 'name' and 'avatar' profile data. ie. person.name() and person.avatarUrl().

With connect, the process above returns null for both person.name() and person.avatarUrl(), even if they exist.

This is a regression for those apps that want to allow some semblance of personalization.

🐛 Bug!

All 10 comments

The issue is that the legacy blockstack browser returns the profile in the authReponse token fetched from the profile url, while the new blockstack app/authenticator does not do this lookup.

Apps that still want to see the profile of a user should call lookup profile (http://blockstack.github.io/blockstack.js/globals.html#lookupprofile) I guess.

loadUserData still does the same, it loads the user data that is available in the local cache (localstorage) provided by the authenticator.

Interestingly, for apps that request publish_data the connect authenticator does return the profile.

@hstove thoughts on adding this support back in for single-player apps?

@friedger using lookupProfile still does not give access to name() and avatarUrl() needed for personalization.

@dantrevino lookupProfile returns a promise of a profile with property name and image[i].contentUrl if provided by the user.

@friedger I dont see it. What am I missing?

          const userData = userSession.loadUserData();
          const profile = blockstack.lookupProfile(userData.username);
          console.log("profile loaded: ", profile);

profile loaded: _proto__: Promise constructor: ƒ Promise() then: ƒ then() catch: ƒ catch() finally: ƒ finally() Symbol(Symbol.toStringTag): "Promise" __proto__: Object @type: "Person" @context: "http://schema.org" apps: {http://localhost:8080: "https://gaia.blockstack.org/hub/1AdqWQnAMsb8uQsrZy96G2P7HYd1zkpMnr/", https://reclaim.gg: "https://gaia.blockstack.org/hub/1PcbTDbgybtTjkETvo9j5jr92VFKJ4rwWC/", https://boom-money-daily.runkodapps.com: "https://gaia.blockstack.org/hub/19wdVbKFyNqVVSuJf8ppt8P92LjUMdJjpz/", https://noteriot-daily.runkodapps.com: "https://gaia.blockstack.org/hub/1Br9sxhdSw6xQJ3x8vvQNkuAz5X5oAq7a5/", https://runkod.com: "https://gaia.blockstack.org/hub/1NpdmvGsNyisR56CUiZHfZHnZukMYiSjJ5/", …} api: {gaiaHubConfig: {…}, gaiaHubUrl: "https://hub.blockstack.org"} __proto__: constructor: ƒ Object() __defineGetter__: ƒ __defineGetter__() __defineSetter__: ƒ __defineSetter__() hasOwnProperty: ƒ hasOwnProperty() __lookupGetter__: ƒ __lookupGetter__() __lookupSetter__: ƒ __lookupSetter__() isPrototypeOf: ƒ isPrototypeOf() propertyIsEnumerable: ƒ propertyIsEnumerable() toString: ƒ toString() valueOf: ƒ valueOf() toLocaleString: ƒ toLocaleString() get __proto__: ƒ __proto__() set __proto__: ƒ __proto__()

For missing profile details see https://github.com/blockstack/ux/issues/322

I've pushed a fix to the authenticator - there were some issues where we weren't properly fetching the profile before the authResponse. Please try this again, and let me know if you see the same issue.

@hstove fyi, this is still not working using the class methods. i've made sure that my profile has a name and avatar:

https://gaia.blockstack.org/hub/1JE8MjzuSi19cBifCvrbsyAjx8PvwhakZp/profile.json

my sign in method:

    signIn() {
      const authOptions = {
        // The URL you want the user to be redirected to after authentication.
        redirectTo: "/wallet",
        manifestPath: "/manifest.json",
        sendToSignIn: true,
        finished: ({ userSession }) => {
          this.logInUser(userSession);
        },
        appDetails: {
          name: "Boom.Webby",
          icon: `${location.origin}/app-icon.png`,
        },
      };
      authenticate(authOptions);
    },

logInUser():

  logInUser(context, session) {
    console.log("user session: ", session);
    let userData = session.loadUserData();
    let person = new blockstack.Person(userData);
    userData.name = person.name();
    userData.avatar = person.avatarUrl();
    userData.authenticated = true;
    console.log("userData: ", userData);
    context.dispatch("setUser", userData);
  },

and the output of console.log() .. note the name and avatar are still null when using the class methods:

{username: "fibonacci.id", profile: {…}, email: null, decentralizedID: "did:btc-addr:1JE8MjzuSi19cBifCvrbsyAjx8PvwhakZp", identityAddress: "1JE8MjzuSi19cBifCvrbsyAjx8PvwhakZp", …}
appPrivateKey: (...)
authResponseToken: (...)
authenticated: (...)
avatar: null
coreSessionToken: (...)
decentralizedID: (...)
email: (...)
gaiaAssociationToken: (...)
hubUrl: (...)
identityAddress: (...)
name: null
profile: (...)
username: (...)

However, when i look at blockstack-session in Local Storage, the name and image props are there.

userData: {username: "fibonacci.id", profile: {@type: "Person", @context: "http://schema.org",…}, email: null,…}
appPrivateKey: "..."
.
.
.
profile: {@type: "Person", @context: "http://schema.org",…}
.
.
.
image: [{@type: "ImageObject", name: "avatar",…}]
name: "Fibonacci"
username: "fibonacci.id"
version: "1.0.0"

I dont see it. What am I missing?

@dantravino the problem here is that lookupProfile returns a Promise, and you're not using await. So, what you're getting back is a Promise.

Thanks for following up on the issue still persisting when you use the Person class - I'll look into that.

Hey @dantravino - looks like you need to just call new Person(userData.profile), instead of new Person(userData). Maybe it worked differently for you before? But this is in line with the docs here:

https://blockstack.github.io/blockstack.js/index.html#quickstart-build-an-application

Was this page helpful?
0 / 5 - 0 ratings