@@ -10,56 +10,53 @@ var crypto = require('crypto')
10
10
, q = require ( 'q' )
11
11
, request = require ( 'request-promise' ) ;
12
12
13
- var bc
14
- , validatePassword = function ( ) { return false ; }
15
- , randomBytes = crypto . randomBytes ( BYTES_PER_HASH ) ;
13
+ var randomBytes = crypto . randomBytes ( BYTES_PER_HASH ) ;
16
14
17
15
function WalletCache ( ) {
18
- this . loggingIn = false ;
16
+ this . loggingIn = { } ;
17
+ this . instanceStore = { } ;
18
+ this . pwHashStore = { } ;
19
19
}
20
20
21
21
WalletCache . prototype . login = function ( guid , options ) {
22
- if ( this . loggingIn ) return q . reject ( 'ERR_LOGIN_BUSY' ) ;
22
+ if ( this . loggingIn [ guid ] ) return q . reject ( 'ERR_LOGIN_BUSY' ) ;
23
23
24
24
var deferred = q . defer ( )
25
25
, needs2FA = deferred . reject . bind ( null , 'ERR_2FA' )
26
26
, needsAuth = deferred . reject . bind ( null , 'ERR_AUTH' )
27
27
, error = deferred . reject
28
+ , fetched = deferred . resolve . bind ( null , { guid : guid , success : true } )
28
29
, timeout = setTimeout ( deferred . reject . bind ( null , 'ERR_TIMEOUT' ) , TIMEOUT_MS ) ;
29
30
30
31
var success = function ( ) {
31
- var fetchedHistory = deferred . resolve . bind ( null , { guid : guid , success : true } )
32
- , pwHash = generatePwHash ( options . password ) ;
33
- validatePassword = function ( p ) { return generatePwHash ( p ) . compare ( pwHash ) === 0 ; } ;
34
- bc . MyWallet . wallet . getHistory ( ) . then ( fetchedHistory ) . catch ( error ) ;
35
- } ;
32
+ var pwHash = generatePwHash ( options . password ) ;
33
+ this . pwHashStore [ guid ] = pwHash ;
34
+ this . instanceStore [ guid ] . MyWallet . wallet . getHistory ( ) . then ( fetched ) . catch ( error ) ;
35
+ } . bind ( this ) ;
36
36
37
37
var login = function ( ) {
38
- this . loggingIn = true ;
39
- safeReset ( ) . then ( function ( ) {
40
- bc . API . API_CODE = options . api_code ;
41
- bc . WalletStore . setAPICode ( options . api_code ) ;
42
- bc . WalletStore . isLogoutDisabled = function ( ) { return true ; } ;
43
- bc . MyWallet . login ( guid , null , options . password , null , success , needs2FA , null , needsAuth , error ) ;
44
- } ) ;
38
+ this . loggingIn [ guid ] = true ;
39
+ var instance = generateInstance ( ) ;
40
+ instance . API . API_CODE = options . api_code ;
41
+ instance . WalletStore . setAPICode ( options . api_code ) ;
42
+ instance . WalletStore . isLogoutDisabled = function ( ) { return true ; } ;
43
+ instance . MyWallet . login ( guid , null , options . password , null , success , needs2FA , null , needsAuth , error ) ;
44
+ this . instanceStore [ guid ] = instance ;
45
45
} . bind ( this ) ;
46
46
47
47
var done = function ( ) {
48
48
clearTimeout ( timeout ) ;
49
- this . loggingIn = false ;
49
+ this . loggingIn [ guid ] = false ;
50
50
} . bind ( this ) ;
51
51
52
52
this . getWallet ( guid , options ) . then ( function ( wallet ) {
53
- var fetchedHistory = deferred . resolve . bind ( null , { guid : guid , success : true } ) ;
54
- wallet . guid === guid ? wallet . getHistory ( ) . then ( fetchedHistory ) : login ( ) ;
53
+ wallet . guid === guid ? wallet . getHistory ( ) . then ( fetched ) : login ( ) ;
55
54
} ) . catch ( login ) ;
56
55
57
56
return deferred . promise . fin ( done ) ;
58
57
} ;
59
58
60
59
WalletCache . prototype . createWallet = function ( options ) {
61
- if ( this . loggingIn ) return q . reject ( 'ERR_LOGIN_BUSY' ) ;
62
-
63
60
var lang , currency
64
61
, email = options . email || ''
65
62
, pass = options . password
@@ -68,76 +65,65 @@ WalletCache.prototype.createWallet = function (options) {
68
65
, deferred = q . defer ( )
69
66
, timeout = setTimeout ( deferred . reject . bind ( null , 'ERR_TIMEOUT' ) , TIMEOUT_MS ) ;
70
67
68
+ var instance = generateInstance ( ) ;
69
+ instance . API . API_CODE = options . api_code ;
70
+ instance . WalletStore . setAPICode ( options . api_code ) ;
71
+ instance . WalletStore . isLogoutDisabled = function ( ) { return true ; } ;
72
+
71
73
var success = function ( guid , sharedKey , password ) {
72
- var fetchedHistory = deferred . resolve . bind ( null , guid )
73
- , errorHistory = deferred . reject . bind ( null , 'ERR_HISTORY' )
74
- , pwHash = generatePwHash ( password ) ;
74
+ var fetched = deferred . resolve . bind ( null , guid )
75
+ , error = deferred . reject . bind ( null , 'ERR_HISTORY' )
76
+ , pwHash = generatePwHash ( password ) ;
75
77
76
- if ( bc . MyWallet . detectPrivateKeyFormat ( options . priv ) !== null ) {
77
- bc . MyWallet . wallet . deleteLegacyAddress ( bc . MyWallet . wallet . keys [ 0 ] ) ;
78
- bc . MyWallet . wallet . importLegacyAddress ( options . priv , options . label ) ;
79
- }
78
+ this . pwHashStore [ guid ] = pwHash ;
79
+ this . instanceStore [ guid ] = instance ;
80
80
81
- validatePassword = function ( p ) { return generatePwHash ( p ) . compare ( pwHash ) === 0 ; } ;
82
- bc . MyWallet . wallet . getHistory ( ) . then ( fetchedHistory ) . catch ( errorHistory ) ;
83
- } ;
81
+ if ( instance . MyWallet . detectPrivateKeyFormat ( options . priv ) !== null ) {
82
+ instance . MyWallet . wallet . deleteLegacyAddress ( instance . MyWallet . wallet . keys [ 0 ] ) ;
83
+ instance . MyWallet . wallet . importLegacyAddress ( options . priv , options . label ) ;
84
+ }
84
85
85
- var done = function ( ) {
86
- clearTimeout ( timeout ) ;
87
- this . loggingIn = false ;
86
+ instance . MyWallet . wallet . getHistory ( ) . then ( fetched ) . catch ( error ) ;
88
87
} . bind ( this ) ;
89
88
90
- safeReset ( ) . then ( function ( ) {
91
- this . loggingIn = true ;
92
- bc . API . API_CODE = options . api_code ;
93
- bc . WalletStore . setAPICode ( options . api_code ) ;
94
- bc . WalletStore . isLogoutDisabled = function ( ) { return true ; } ;
95
- bc . MyWallet . createNewWallet ( email , pass , label , lang , currency , success , deferred . reject , isHD ) ;
96
- } . bind ( this ) ) ;
89
+ instance . MyWallet . createNewWallet (
90
+ email , pass , label , lang , currency , success , deferred . reject , isHD ) ;
97
91
98
- return deferred . promise . fin ( done ) ;
92
+ return deferred . promise . fin ( clearTimeout . bind ( null , timeout ) ) ;
99
93
} ;
100
94
101
95
WalletCache . prototype . getWallet = function ( guid , options ) {
102
- var exists = bc && bc . MyWallet && bc . MyWallet . wallet && bc . MyWallet . wallet . guid === guid
103
- , validpw = validatePassword ( options . password )
96
+ var inst = this . instanceStore [ guid ]
97
+ , exists = inst && inst . MyWallet . wallet && inst . MyWallet . wallet . guid === guid
98
+ , validpw = validatePassword ( this . pwHashStore [ guid ] , options . password )
104
99
, err = ! exists && 'ERR_WALLET_ID' || ! validpw && 'ERR_PASSWORD' ;
105
- return err ? q . reject ( err ) : q ( bc . MyWallet . wallet ) ;
100
+ return err ? q . reject ( err ) : q ( inst . MyWallet . wallet ) ;
106
101
} ;
107
102
108
- WalletCache . prototype . walletPayment = function ( ) {
109
- return new bc . Payment ( ) ;
103
+ WalletCache . prototype . walletPayment = function ( guid ) {
104
+ var instance = this . instanceStore [ guid ] ;
105
+ if ( ! instance || ! instance . Payment ) throw 'ERR_PAYMENT' ;
106
+ return new instance . Payment ( ) ;
110
107
} ;
111
108
112
109
module . exports = WalletCache ;
113
110
114
- function safeReset ( ) {
115
- var deferred = q . defer ( ) ;
116
- if ( bc && bc . MyWallet && bc . MyWallet . wallet ) {
117
- if ( ! bc . WalletStore . isSynchronizedWithServer ( ) ) {
118
- bc . MyWallet . syncWallet ( refreshCache , deferred . reject ) ;
119
- } else {
120
- refreshCache ( ) ;
121
- }
122
- } else {
123
- refreshCache ( ) ;
124
- }
125
- function refreshCache ( ) {
126
- if ( require . cache ) {
127
- Object . keys ( require . cache )
128
- . filter ( function ( module ) {
129
- return ( module . indexOf ( 'blockchain-wallet-client-prebuilt/index' ) > - 1 ||
130
- module . indexOf ( 'blockchain-wallet-client-prebuilt/src' ) > - 1 ) ;
131
- } )
132
- . forEach ( function ( module ) { delete require . cache [ module ] ; } ) ;
133
- }
134
- bc = require ( 'blockchain-wallet-client-prebuilt' ) ;
135
- deferred . resolve ( true ) ;
136
- }
137
- return deferred . promise ;
111
+ function generateInstance ( ) {
112
+ Object . keys ( require . cache )
113
+ . filter ( function ( module ) {
114
+ return ( module . indexOf ( 'blockchain-wallet-client-prebuilt/index' ) > - 1 ||
115
+ module . indexOf ( 'blockchain-wallet-client-prebuilt/src' ) > - 1 ) ;
116
+ } )
117
+ . forEach ( function ( module ) { require . cache [ module ] = undefined ; } ) ;
118
+ return require ( 'blockchain-wallet-client-prebuilt' ) ;
138
119
}
139
120
140
121
function generatePwHash ( pw ) {
141
122
var iterations = 5000 ;
142
123
return crypto . pbkdf2Sync ( pw , randomBytes , iterations , BYTES_PER_HASH , 'sha256' ) ;
143
124
}
125
+
126
+ function validatePassword ( hash , maybePw ) {
127
+ if ( ! Buffer . isBuffer ( hash ) || ! maybePw ) return false ;
128
+ return generatePwHash ( maybePw ) . compare ( hash ) === 0 ;
129
+ }
0 commit comments