@@ -25,39 +25,37 @@ export default {
25
25
updateVaultKey : async ( parent , { entries, hash } , { me, models } ) => {
26
26
if ( ! me ) throw new GqlAuthenticationError ( )
27
27
if ( ! hash ) throw new GqlInputError ( 'hash required' )
28
- const txs = [ ]
29
28
30
29
const { vaultKeyHash : oldKeyHash } = await models . user . findUnique ( { where : { id : me . id } } )
31
30
if ( oldKeyHash ) {
32
- if ( oldKeyHash !== hash ) {
33
- throw new GqlInputError ( 'vault key already set' , E_VAULT_KEY_EXISTS )
34
- } else {
31
+ if ( oldKeyHash === hash ) {
35
32
return true
36
33
}
37
- } else {
38
- txs . push ( models . user . update ( {
39
- where : { id : me . id } ,
40
- data : { vaultKeyHash : hash }
41
- } ) )
34
+ throw new GqlInputError ( 'vault key already set' , E_VAULT_KEY_EXISTS )
42
35
}
43
36
44
- const wallets = await models . wallet . findMany ( { where : { userId : me . id } } )
45
- for ( const wallet of wallets ) {
46
- const def = getWalletByType ( wallet . type )
47
- txs . push (
48
- models . wallet . update ( {
37
+ return await models . $transaction ( async tx => {
38
+ const wallets = await tx . wallet . findMany ( { where : { userId : me . id } } )
39
+ for ( const wallet of wallets ) {
40
+ const def = getWalletByType ( wallet . type )
41
+ await tx . wallet . update ( {
49
42
where : { id : wallet . id } ,
50
43
data : {
51
44
[ def . walletField ] : {
52
45
update : vaultPrismaFragments . upsert ( { ...wallet , vaultEntries : entries } )
53
46
}
54
47
}
55
48
} )
56
- )
57
- }
49
+ }
58
50
59
- await models . $transaction ( txs )
60
- return true
51
+ // optimistic concurrency control: make sure the user's vault key didn't change while we were updating the wallets
52
+ await tx . user . update ( {
53
+ where : { id : me . id , vaultKeyHash : oldKeyHash } ,
54
+ data : { vaultKeyHash : hash }
55
+ } )
56
+
57
+ return true
58
+ } )
61
59
} ,
62
60
clearVault : async ( parent , args , { me, models } ) => {
63
61
if ( ! me ) throw new GqlAuthenticationError ( )
0 commit comments