@@ -12,6 +12,7 @@ import type {
1212 UserWithSecrets ,
1313} from '@localfirst/crdx'
1414import {
15+ createKeyring ,
1516 createKeyset ,
1617 createStore ,
1718 getLatestGeneration ,
@@ -137,11 +138,11 @@ export class Team extends EventEmitter<TeamEvents> {
137138 }
138139
139140 this . state = this . store . getState ( )
140- this . checkForNewUserKeysGeneration ( )
141+ this . updateUserKeys ( )
141142
142143 // Wire up event listeners
143144 this . on ( 'updated' , ( ) => {
144- this . checkForNewUserKeysGeneration ( )
145+ this . updateUserKeys ( )
145146
146147 // If we're admin, check for pending key rotations
147148 this . checkForPendingKeyRotations ( )
@@ -505,21 +506,17 @@ export class Team extends EventEmitter<TeamEvents> {
505506 const invitation = invitations . create ( { seed, expiration, maxUses, userId : this . userId } )
506507
507508 // In order for the invited device to be able to access the user's keys, we put the user keys in
508- // lockboxes that can be opened by an ephemeral keyset generated from the secret invitation
509- // seed.
509+ // lockboxes that can be opened by an ephemeral keyset generated from the secret invitation seed.
510510 const starterKeys = invitations . generateStarterKeys ( seed )
511- const lockboxesUserKeysForDeviceStarterKeys = this . allUserKeys ( )
512- . map ( keys => lockbox . create ( keys , starterKeys ) )
511+ const allUserKeys = Object . values ( this . userKeyring ( ) )
512+ const lockboxes = allUserKeys . map ( keys => lockbox . create ( keys , starterKeys ) )
513513
514514 const { id } = invitation
515515
516516 // Post invitation to graph
517517 this . dispatch ( {
518518 type : 'INVITE_DEVICE' ,
519- payload : {
520- invitation,
521- lockboxes : lockboxesUserKeysForDeviceStarterKeys ,
522- } ,
519+ payload : { invitation, lockboxes } ,
523520 } )
524521
525522 // Return the secret invitation seed (to pass on to invitee) and the invitation id (which could be used to revoke later)
@@ -570,8 +567,8 @@ export class Team extends EventEmitter<TeamEvents> {
570567 const { id } = proof
571568
572569 // we know the team keys, so we can put them in lockboxes for the new member now (even if we're not an admin)
573- const lockboxesTeamKeysForMember = Object . values ( this . teamKeyring ( ) )
574- . map ( keys => lockbox . create ( keys , memberKeys ) )
570+ const allTeamKeys = Object . values ( this . teamKeyring ( ) )
571+ const lockboxes = allTeamKeys . map ( keys => lockbox . create ( keys , memberKeys ) )
575572
576573 // Post admission to the graph
577574 this . dispatch ( {
@@ -580,7 +577,7 @@ export class Team extends EventEmitter<TeamEvents> {
580577 id,
581578 userName,
582579 memberKeys : redactKeys ( memberKeys ) ,
583- lockboxes : lockboxesTeamKeysForMember ,
580+ lockboxes,
584581 } ,
585582 } )
586583 }
@@ -608,20 +605,21 @@ export class Team extends EventEmitter<TeamEvents> {
608605 }
609606
610607 /** Once the new member has received the graph and can instantiate the team, they call this to add their device. */
611- public join = ( teamKeyring : Keyring , allUserKeys = [ this . context . user . keys ] ) => {
608+ public join = ( teamKeyring : Keyring , userKeyring = createKeyring ( this . context . user . keys ) ) => {
612609 assert ( ! this . isServer , "Can't join as member on server" )
613610
614611 const { device } = this . context
615612 const teamKeys = getLatestGeneration ( teamKeyring )
616613
617- const lockboxesUserKeysForDevice = allUserKeys . map ( keys => lockbox . create ( keys , device . keys ) )
614+ // Create a lockbox for each generation of user keys
615+ const lockboxes = Object . values ( userKeyring ) . map ( keys => lockbox . create ( keys , device . keys ) )
618616
619617 this . dispatch (
620618 {
621619 type : 'ADD_DEVICE' ,
622620 payload : {
623621 device : redactDevice ( device ) ,
624- lockboxes : lockboxesUserKeysForDevice ,
622+ lockboxes,
625623 } ,
626624 } ,
627625 teamKeys
@@ -767,8 +765,8 @@ export class Team extends EventEmitter<TeamEvents> {
767765 public keys = ( scope : KeyMetadata | KeyScope ) =>
768766 select . keys ( this . state , this . context . device . keys , scope )
769767
770- public allUserKeys = ( userId = this . userId ) =>
771- select . keyMap ( this . state , this . context . device . keys ) [ USER ] ?. [ userId ] || [ ]
768+ public userKeyring = ( userId = this . userId ) =>
769+ select . keyring ( this . state , { type : USER , name : userId } , this . context . device . keys )
772770
773771 /** Returns the keys for the given role. */
774772 public roleKeys = ( roleName : string , generation ?: number ) =>
@@ -811,9 +809,9 @@ export class Team extends EventEmitter<TeamEvents> {
811809 if ( isForServer ) device . keys = newKeys // (a server plays the role of both a user and a device)
812810 }
813811
814- private checkForNewUserKeysGeneration ( ) {
812+ private updateUserKeys ( ) {
815813 const { user } = this . context
816- const latestUserKeys = this . allUserKeys ( ) . at ( - 1 )
814+ const latestUserKeys = getLatestGeneration ( this . userKeyring ( ) )
817815
818816 if ( latestUserKeys && user . keys . generation < latestUserKeys . generation ) {
819817 user . keys = latestUserKeys
0 commit comments