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

Issue with retrieving UserGroups #45

Open
erikwlarsen opened this issue Aug 9, 2019 · 13 comments · Fixed by #89
Open

Issue with retrieving UserGroups #45

erikwlarsen opened this issue Aug 9, 2019 · 13 comments · Fixed by #89

Comments

@erikwlarsen
Copy link

I'm having an issue with retrieving UserGroups within my app after logging out and then logging in. If I create a UserGroup, I'm able to access that user group while still logged in with my current session. However, upon logging out and logging back in to the same app, when I retrieve my group memberships, decryption errors are thrown, and the name and members do not get decrypted.

Steps to reproduce:

After user is logged in, create a new group:
const group = new UserGroup({ name: 'my new group' }); await group.create();
Check to make sure I have group membership:
UserGroup.myGroups().then(console.log);
This shows an array with the group I just created (with attrs.name === 'my new group').

Log out
const { userSession } = getConfig(); userSession.signUserOut();

Log back into app, then log my groups again:
UserGroup.myGroups().then(console.log);

Now the same group I just created does show up (the _id property matches), but the name and members properties (under attrs) are encrypted (They are objects with cipherTask, ephemeralPK, iv, and mac properties.) I see error logs from their retrieval:
Decryption error for key: 'members': num.words is null
Decryption error for key: 'name': num.words is null

One other strange thing: at this point, if I create a group and retrieve it using UserGroup.myGroups, I will only see the group I just created, and it will be properly decrypted. I will not see the group that I created during my last session. However, if I log out and log back in again, I'll see both of the groups that I have created, and both will be encrypted (with attendant Decryption error messages).

Thanks for your help, this is a really cool library! Please let me know if I'm doing anything incorrectly.

@MarkGeeRomano
Copy link

I'm having this issue as well, +1

@erikwlarsen
Copy link
Author

Hello again Blockstack, any thoughts on this? Haven't been able to find a work-around.

@stackatron stackatron added this to the DX Q3 Sprint 3 milestone Aug 22, 2019
@stackatron
Copy link

@hstove any chance you can advise on the best path forward here? Should you or DevX try to solve this? Is this best solved by a community PR?

@erikwlarsen
Copy link
Author

erikwlarsen commented Aug 26, 2019

@jeffdomke @hstove it's possible that the issue is coming from the GroupInvitation activate instance method.

This method gets called as part of new UserGroup().create(). That first conditional expression will always return true because the UserGroup keys are already stored in local storage by the time this method is called. But this means that if the user logs out of the app (thus deleting local storage) and then logs back in, no groupMembership was created in the db, and thus the keys needed to decrypt the groups retrieved by UserGroup.myGroups do not exist.

async activate() {
    const { userGroups } = userGroupKeys();
    const groupId: string = this.attrs.userGroupId as string;
    if (userGroups[groupId]) {
      return true;
    }
    const groupMembership = new GroupMembership({
      userGroupId: this.attrs.userGroupId,
      username: loadUserData().username,
      signingKeyPrivateKey: this.attrs.signingKeyPrivateKey,
      signingKeyId: this.attrs.signingKeyId,
    });
    await groupMembership.save();
    await GroupMembership.cacheKeys();
    return groupMembership;
  }

@stackatron stackatron removed this from the DX Q3 Sprint 3 milestone Oct 4, 2019
@babyrusa
Copy link

still facing this problem is jan 24, 2020

@xanderjakeq
Copy link

xanderjakeq commented Feb 4, 2020

Been struggling with trying to use UserGroups for over a week now.

I experienced this issue too. And these are my observations.

After you log in, GROUP_MEMBERSHIPS_STORAGE_KEY is added to localStorage. And it gets populated as you create UserGroups and would look something like this.

image

If you lose those values, then you will experience the issue above. What I'm saying is that somehow, GROUP_MEMBERSHIPS_STORAGE_KEY gets reset to the default. Which would look something like this.

image

When that happens... I don't know if you could decrypt your UserGroups ever again.

My workaround for this problem is to create a Model for saving the GROUP_MEMBERSHIPS_STORAGE_KEY values. When the localStorage gets updated, sync your model with the new value. When you sign out and log back in, fetch your model then set it to localStorage.

After doing this I've been able to consistently retrieve my UserGroups.

@gzelda
Copy link

gzelda commented Feb 12, 2020

Been struggling with trying to use UserGroups for over a week now.

I experienced this issue too. And these are my observations.

After you log in, GROUP_MEMBERSHIPS_STORAGE_KEY is added to localStorage. And it gets populated as you create UserGroups and would look something like this.

image

If you lose those values, then you will experience the issue above. What I'm saying is that somehow, GROUP_MEMBERSHIPS_STORAGE_KEY gets reset to the default. Which would look something like this.

image

When that happens... I don't know if you could decrypt your UserGroups ever again.

My workaround for this problem is to create a Model for saving the GROUP_MEMBERSHIPS_STORAGE_KEY values. When the localStorage gets updated, sync your model with the new value. When you sign out and log back in, fetch your model then set it to localStorage.

After doing this I've been able to consistently retrieve my UserGroups.

I have met the same problem as well, my another question is how can i get my invitation from other people's userGroup

@erikwlarsen
Copy link
Author

erikwlarsen commented Feb 12, 2020 via email

@xanderjakeq
Copy link

xanderjakeq commented Feb 12, 2020

I have met the same problem as well, my another question is how can i get my invitation from other people's userGroup

You could create a model that looks like this

{
 from: `username of admin`,
 to: `username of invitee`,
 id: `invitation id`
}

Then you could query the to field with your username.

Maybe?

@friedger
Copy link
Collaborator

friedger commented Feb 25, 2020

As a fix for this issue I suggest to remove

 addUserGroupKey(this);

from UserGroup.create. This will enforce to create a GroupMembership for the owner.

Furthermore, I suggest to use a deterministically derived signing key ("personal") so that users will always be able to decrypt their models. See #77

@erikwlarsen @xanderjakeq Re finding invitations, storing this publicly is a privacy concern.

@friedger
Copy link
Collaborator

The fix does not work :-/ due to missing keys for the GroupMembership.

@friedger
Copy link
Collaborator

A better solution is to check the server in GroupInvitation.activate:

async activate() {
    const { username } = loadUserData();
    const existingMemberships = await GroupMembership.fetchList({
      username,
      signingKeyId: this.attrs.signingKeyId
    });
    if (existingMemberships.length > 0) {
      return true;
    }
...

@pacificsoftdevld
Copy link

use UserGroups.find(id) to retrieving UserGroup decrypted

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants