@@ -20,6 +20,7 @@ const logger = log4js.getLogger('auth/components/AuthModal.js')
20
20
function mapStateToProps ( state ) {
21
21
return {
22
22
localIdentities : state . profiles . identity . localIdentities ,
23
+ defaultIdentity : state . profiles . identity . default ,
23
24
identityKeypairs : state . account . identityAccount . keypairs ,
24
25
appManifest : state . auth . appManifest ,
25
26
appManifestLoading : state . auth . appManifestLoading ,
@@ -42,6 +43,8 @@ class AuthModal extends Component {
42
43
router : PropTypes . object
43
44
}
44
45
static propTypes = {
46
+ defaultIdentity : PropTypes . string . isRequired ,
47
+ localIdentities : PropTypes . object . isRequired ,
45
48
loadAppManifest : PropTypes . func . isRequired ,
46
49
clearSessionToken : PropTypes . func . isRequired ,
47
50
getCoreSessionToken : PropTypes . func . isRequired ,
@@ -55,6 +58,7 @@ class AuthModal extends Component {
55
58
super ( props )
56
59
57
60
this . state = {
61
+ currentIdentity : null ,
58
62
authRequest : null ,
59
63
appManifest : null ,
60
64
coreSessionToken : null ,
@@ -79,39 +83,52 @@ class AuthModal extends Component {
79
83
componentWillReceiveProps ( nextProps ) {
80
84
const storageConnected = this . props . api . dropboxAccessToken !== null
81
85
this . setState ( {
82
- storageConnected
86
+ storageConnected,
87
+ currentIdentity : this . state . currentIdentity || nextProps . defaultIdentity || undefined
83
88
} )
84
89
85
90
const appDomain = this . state . decodedToken . payload . domain_name
86
91
const localIdentities = nextProps . localIdentities
87
92
const identityKeypairs = nextProps . identityKeypairs
88
- if ( appDomain && nextProps . coreSessionTokens [ appDomain ] ) {
89
- logger . trace ( 'componentWillReceiveProps: received coreSessionToken' )
90
- if ( Object . keys ( localIdentities ) . length > 0 ) {
91
- let userDomainName = Object . keys ( localIdentities ) [ 0 ]
92
-
93
- let hasUsername = true
94
- if ( userDomainName === localIdentities [ userDomainName ] . ownerAddress ) {
95
- logger . debug ( `login(): this profile ${ userDomainName } has no username` )
96
- hasUsername = false
97
- }
98
- const blockchainId = ( hasUsername ? userDomainName : null )
99
- const identity = localIdentities [ userDomainName ]
100
- const profile = identity . profile
101
- const privateKey = identityKeypairs [ 0 ] . key
102
- const appsNodeKey = identityKeypairs [ 0 ] . appsNodeKey
103
- const salt = identityKeypairs [ 0 ] . salt
104
- const appsNode = new AppsNode ( HDNode . fromBase58 ( appsNodeKey ) , salt )
105
- const appPrivateKey = appsNode . getAppNode ( appDomain ) . getAppPrivateKey ( )
106
-
107
- // TODO: what if the token is expired?
108
- const authResponse = makeAuthResponse ( privateKey , profile , blockchainId ,
109
- nextProps . coreSessionTokens [ appDomain ] , appPrivateKey )
110
-
111
- this . props . clearSessionToken ( appDomain )
112
- redirectUserToApp ( this . state . authRequest , authResponse )
113
- }
93
+ if ( ! appDomain || ! nextProps . coreSessionTokens [ appDomain ] ) {
94
+ return
95
+ }
96
+
97
+ logger . trace ( 'componentWillReceiveProps: received coreSessionToken' )
98
+ if ( ! Object . keys ( localIdentities ) . length ) {
99
+ return
100
+ }
101
+ // Careful with this.state, as the above this.setState is async. But
102
+ // there shouldn't be any problem with the above check.
103
+ // TODO: Side-effects to avoid confusion.
104
+ const userDomainName = this . state . currentIdentity
105
+
106
+ let hasUsername = true
107
+ if ( userDomainName === localIdentities [ userDomainName ] . ownerAddress ) {
108
+ logger . debug ( `login(): this profile ${ userDomainName } has no username` )
109
+ hasUsername = false
114
110
}
111
+
112
+ // Get keypair corresponding to the current user identity
113
+ const profileSigningKeypair = identityKeypairs . find ( ( keypair ) => keypair . address === localIdentities [ userDomainName ] . ownerAddress )
114
+
115
+ const blockchainId = ( hasUsername ? userDomainName : null )
116
+ const identity = localIdentities [ userDomainName ]
117
+ const profile = identity . profile
118
+ const privateKey = profileSigningKeypair . key
119
+ const appsNodeKey = profileSigningKeypair . appsNodeKey
120
+ const salt = profileSigningKeypair . salt
121
+ const appsNode = new AppsNode ( HDNode . fromBase58 ( appsNodeKey ) , salt )
122
+ const appPrivateKey = appsNode . getAppNode ( appDomain ) . getAppPrivateKey ( )
123
+
124
+ // TODO: what if the token is expired?
125
+ const authResponse = makeAuthResponse ( privateKey , profile , blockchainId ,
126
+ nextProps . coreSessionTokens [ appDomain ] , appPrivateKey )
127
+
128
+ this . props . clearSessionToken ( appDomain )
129
+
130
+ logger . trace ( `login(): profile ${ userDomainName } is logging in` )
131
+ redirectUserToApp ( this . state . authRequest , authResponse )
115
132
}
116
133
117
134
closeModal ( ) {
@@ -120,35 +137,38 @@ class AuthModal extends Component {
120
137
121
138
login ( ) {
122
139
this . props . loginToApp ( )
123
- if ( Object . keys ( this . props . localIdentities ) . length > 0 ) {
124
- const localIdentities = this . props . localIdentities
125
- let userDomainName = Object . keys ( localIdentities ) [ 0 ]
126
- let hasUsername = true
127
- if ( userDomainName === localIdentities [ userDomainName ] . ownerAddress ) {
128
- logger . debug ( `login(): this profile ${ userDomainName } has no username` )
129
- hasUsername = false
130
- }
131
- const identity = localIdentities [ userDomainName ]
132
- const profile = identity . profile
133
- const profileSigningKeypair = this . props . identityKeypairs [ 0 ]
134
- const appDomain = this . state . decodedToken . payload . domain_name
135
- const scopes = this . state . decodedToken . payload . scopes
136
- const appsNodeKey = this . props . identityKeypairs [ 0 ] . appsNodeKey
137
- const salt = this . props . identityKeypairs [ 0 ] . salt
138
- const appsNode = new AppsNode ( HDNode . fromBase58 ( appsNodeKey ) , salt )
139
- const appPrivateKey = appsNode . getAppNode ( appDomain ) . getAppPrivateKey ( )
140
- const blockchainId = ( hasUsername ? userDomainName : null )
141
- logger . trace ( `login(): Calling setCoreStorageConfig()...` )
142
- setCoreStorageConfig ( this . props . api , blockchainId ,
143
- localIdentities [ userDomainName ] . profile , profileSigningKeypair )
144
- . then ( ( ) => {
145
- logger . trace ( 'login(): Core storage successfully configured.' )
146
- logger . trace ( 'login(): Calling getCoreSessionToken()...' )
147
- this . props . getCoreSessionToken ( this . props . coreHost ,
148
- this . props . corePort , this . props . coreAPIPassword , appPrivateKey ,
149
- appDomain , this . state . authRequest , blockchainId )
150
- } )
140
+ if ( ! Object . keys ( this . props . localIdentities ) . length ) {
141
+ return
142
+ }
143
+ const localIdentities = this . props . localIdentities
144
+ const userDomainName = this . state . currentIdentity
145
+
146
+ let hasUsername = true
147
+ if ( userDomainName === localIdentities [ userDomainName ] . ownerAddress ) {
148
+ logger . debug ( `login(): this profile ${ userDomainName } has no username` )
149
+ hasUsername = false
151
150
}
151
+
152
+ // Get keypair corresponding to the current user identity
153
+ const profileSigningKeypair = this . props . identityKeypairs . find ( ( keypair ) => keypair . address === localIdentities [ userDomainName ] . ownerAddress )
154
+
155
+ const appDomain = this . state . decodedToken . payload . domain_name
156
+ const scopes = this . state . decodedToken . payload . scopes
157
+ const appsNodeKey = profileSigningKeypair . appsNodeKey
158
+ const salt = profileSigningKeypair . salt
159
+ const appsNode = new AppsNode ( HDNode . fromBase58 ( appsNodeKey ) , salt )
160
+ const appPrivateKey = appsNode . getAppNode ( appDomain ) . getAppPrivateKey ( )
161
+ const blockchainId = ( hasUsername ? userDomainName : null )
162
+ logger . trace ( `login(): Calling setCoreStorageConfig()...` )
163
+ setCoreStorageConfig ( this . props . api , blockchainId ,
164
+ localIdentities [ userDomainName ] . profile , profileSigningKeypair )
165
+ . then ( ( ) => {
166
+ logger . trace ( 'login(): Core storage successfully configured.' )
167
+ logger . trace ( 'login(): Calling getCoreSessionToken()...' )
168
+ this . props . getCoreSessionToken ( this . props . coreHost ,
169
+ this . props . corePort , this . props . coreAPIPassword , appPrivateKey ,
170
+ appDomain , this . state . authRequest , blockchainId )
171
+ } )
152
172
}
153
173
154
174
render ( ) {
@@ -196,9 +216,21 @@ class AuthModal extends Component {
196
216
< div >
197
217
{ this . state . storageConnected ?
198
218
< div >
199
- < p >
200
- Click below to log in.
201
- </ p >
219
+ < p > Choose a profile to log in with.</ p >
220
+ < select
221
+ className = "form-control profile-select"
222
+ onChange = { ( event ) => this . setState ( { currentIdentity : event . target . value } ) }
223
+ value = { this . state . currentIdentity }
224
+ >
225
+ { Object . keys ( this . props . localIdentities ) . map ( ( domainName ) => (
226
+ < option
227
+ key = { domainName }
228
+ value = { this . props . localIdentities [ domainName ] . domainName }
229
+ >
230
+ { this . props . localIdentities [ domainName ] . domainName }
231
+ </ option >
232
+ ) ) }
233
+ </ select >
202
234
< div >
203
235
< button className = "btn btn-primary btn-block" onClick = { this . login } >
204
236
Approve
0 commit comments