@@ -118,6 +118,9 @@ internal class AuthenticatorViewModel(application: Application, private val auth
118
118
)
119
119
val events = _events .asSharedFlow()
120
120
121
+ // Is there a current Amplify call in progress that could result in a signed in event?
122
+ private var expectingSignInEvent: Boolean = false
123
+
121
124
fun start (configuration : AuthenticatorConfiguration ) {
122
125
if (::configuration.isInitialized) {
123
126
return
@@ -242,24 +245,30 @@ internal class AuthenticatorViewModel(application: Application, private val auth
242
245
}
243
246
244
247
private suspend fun handleAutoSignIn (username : String , password : String ) {
245
- when (val result = authProvider.autoSignIn()) {
246
- is AmplifyResult .Error -> {
247
- // If auto sign in fails then proceed with manually trying to sign in the user. If this also fails the
248
- // user will end up back on the sign in screen.
249
- logger.warn(" Unable to complete auto-signIn" )
250
- handleSignedUp(username, password)
248
+ startSignInJob {
249
+ when (val result = authProvider.autoSignIn()) {
250
+ is AmplifyResult .Error -> {
251
+ // If auto sign in fails then proceed with manually trying to sign in the user. If this also fails the
252
+ // user will end up back on the sign in screen.
253
+ logger.warn(" Unable to complete auto-signIn" )
254
+ handleSignedUp(username, password)
255
+ }
256
+
257
+ is AmplifyResult .Success -> handleSignInSuccess(username, password, result.data)
251
258
}
252
- is AmplifyResult .Success -> handleSignInSuccess(username, password, result.data)
253
259
}
254
260
}
255
261
256
262
private suspend fun handleSignedUp (username : String , password : String ) {
257
- when (val result = authProvider.signIn(username, password)) {
258
- is AmplifyResult .Error -> {
259
- moveTo(AuthenticatorStep .SignIn )
260
- handleSignInFailure(username, password, result.error)
263
+ startSignInJob {
264
+ when (val result = authProvider.signIn(username, password)) {
265
+ is AmplifyResult .Error -> {
266
+ moveTo(AuthenticatorStep .SignIn )
267
+ handleSignInFailure(username, password, result.error)
268
+ }
269
+
270
+ is AmplifyResult .Success -> handleSignInSuccess(username, password, result.data)
261
271
}
262
- is AmplifyResult .Success -> handleSignInSuccess(username, password, result.data)
263
272
}
264
273
}
265
274
@@ -268,31 +277,31 @@ internal class AuthenticatorViewModel(application: Application, private val auth
268
277
269
278
@VisibleForTesting
270
279
suspend fun signIn (username : String , password : String ) {
271
- viewModelScope.launch {
280
+ startSignInJob {
272
281
when (val result = authProvider.signIn(username, password)) {
273
282
is AmplifyResult .Error -> handleSignInFailure(username, password, result.error)
274
283
is AmplifyResult .Success -> handleSignInSuccess(username, password, result.data)
275
284
}
276
- }.join()
285
+ }
277
286
}
278
287
279
288
private suspend fun confirmSignIn (username : String , password : String , challengeResponse : String ) {
280
- viewModelScope.launch {
289
+ startSignInJob {
281
290
when (val result = authProvider.confirmSignIn(challengeResponse)) {
282
291
is AmplifyResult .Error -> handleSignInFailure(username, password, result.error)
283
292
is AmplifyResult .Success -> handleSignInSuccess(username, password, result.data)
284
293
}
285
- }.join()
294
+ }
286
295
}
287
296
288
297
private suspend fun setNewSignInPassword (username : String , password : String ) {
289
- viewModelScope.launch {
298
+ startSignInJob {
290
299
when (val result = authProvider.confirmSignIn(password)) {
291
300
// an error here is more similar to a sign up error
292
301
is AmplifyResult .Error -> handleSignUpFailure(result.error)
293
302
is AmplifyResult .Success -> handleSignInSuccess(username, password, result.data)
294
303
}
295
- }.join()
304
+ }
296
305
}
297
306
298
307
private suspend fun handleSignInFailure (username : String , password : String , error : AuthException ) {
@@ -520,9 +529,11 @@ internal class AuthenticatorViewModel(application: Application, private val auth
520
529
logger.debug(" Password reset complete" )
521
530
sendMessage(PasswordResetMessage )
522
531
if (username != null && password != null ) {
523
- when (val result = authProvider.signIn(username, password)) {
524
- is AmplifyResult .Error -> moveTo(stateFactory.newSignInState(this ::signIn))
525
- is AmplifyResult .Success -> handleSignInSuccess(username, password, result.data)
532
+ startSignInJob {
533
+ when (val result = authProvider.signIn(username, password)) {
534
+ is AmplifyResult .Error -> moveTo(stateFactory.newSignInState(this ::signIn))
535
+ is AmplifyResult .Success -> handleSignInSuccess(username, password, result.data)
536
+ }
526
537
}
527
538
} else {
528
539
moveTo(stateFactory.newSignInState(this ::signIn))
@@ -636,9 +647,27 @@ internal class AuthenticatorViewModel(application: Application, private val auth
636
647
}
637
648
}
638
649
650
+ private suspend fun startSignInJob (body : suspend () -> Unit ) {
651
+ expectingSignInEvent = true
652
+ viewModelScope.launch { body() }.join()
653
+ expectingSignInEvent = false
654
+ }
655
+
639
656
// Amplify has told us the user signed in.
640
657
private suspend fun handleSignedInEvent () {
641
- // TODO : move the user to signedInState *if* we are not in the process of signing in or verifying the user
658
+ if (! expectingSignInEvent && ! inPostSignInState()) {
659
+ handleSignedIn()
660
+ }
661
+ }
662
+
663
+ private fun inPostSignInState (): Boolean {
664
+ val step = currentState.step
665
+ return when (step) {
666
+ is AuthenticatorStep .VerifyUser ,
667
+ is AuthenticatorStep .VerifyUserConfirm ,
668
+ is AuthenticatorStep .SignedIn -> true
669
+ else -> false
670
+ }
642
671
}
643
672
644
673
private fun handleSignedOut () {
0 commit comments