aws-sdk-ios
aws-sdk-ios copied to clipboard
AWSCognitoIdentityPasswordAuthentication Crashing on iOS 13 after Refresh Token Revoked
Describe the bug Starting in iOS 13, if the refresh token is revoked, AWSCognitoIdentityPasswordAuthentication causes the app to crash due to the SignInViewcontroller being called in the main thread. Using the 2nd block of code below, I've been able to prevent the crash, however things still do not act as anticipated. If a logout is performed, tapping "Sign In" again after entering login info, does not dismiss the SignInViewController and route to the main view controller. There seems to be an issue with the navigation routing for startPasswordAuthentication, but it may be deeper in the SDK.
To Reproduce Steps to reproduce the behavior:
- Revoke the token (user global sign out on a different device/simulator) then wait for the session token to expire. After this time, close app and re-open; crash occurs. This crash can be fixed with the 2nd block of code, which then presents the 2nd issue (#2)
- Logout and attempt to log back in, using the AWS Cognito sample code. Then utilize the 2nd block of code in replacement of this and repeat the process.
Which AWS service(s) are affected? AWSCognitoIdentityPasswordAuthentication
Expected behavior
- On expiration of the refresh token on app load, the user should be directed to the signin ViewController.
- When a user logs out, they should be able to log back in
Additional context Here's the code in the AppDelegate from the AWS Cognito example: extension AppDelegate: AWSCognitoIdentityInteractiveAuthenticationDelegate {
func startPasswordAuthentication() -> AWSCognitoIdentityPasswordAuthentication {
print("Starting Cognito Password Authentication")
if (self.navigationController?.restorationIdentifier != "signinController") {
self.navigationController = self.authstoryboard?.instantiateViewController(withIdentifier: "signinController") as? UINavigationController <--- APP CRASHES HERE
}
if (self.signInViewController == nil) {
self.signInViewController = self.navigationController?.viewControllers[0] as? SignInViewController
}
DispatchQueue.main.async {
self.window?.rootViewController = self.navigationController
self.navigationController!.popToRootViewController(animated: true)
if (!self.navigationController!.isViewLoaded
|| self.navigationController!.view.window == nil) {
self.window?.rootViewController?.present(self.navigationController!,
animated: true,
completion: nil)
}
}
return self.signInViewController!
}
This is the block of code that prevents a crash, but still doesn't function properly.
func startPasswordAuthentication() -> AWSCognitoIdentityPasswordAuthentication {
print("Starting Cognito Password Authentication on thread: \(Thread.current)")
if (!Thread.current.isMainThread) {
DispatchQueue.main.sync {
if (self.navigationController?.restorationIdentifier != "signinController") {
self.navigationController = self.authstoryboard?.instantiateViewController(withIdentifier: "signinController") as? UINavigationController
}
if (self.signInViewController == nil) {
self.signInViewController = self.navigationController?.viewControllers[0] as? SignInViewController
}
}
} else {
if (self.navigationController?.restorationIdentifier != "signinController") {
self.navigationController = self.authstoryboard?.instantiateViewController(withIdentifier: "signinController") as? UINavigationController
}
if (self.signInViewController == nil) {
self.signInViewController = self.navigationController?.viewControllers[0] as? SignInViewController
}
}
DispatchQueue.main.async {
self.window?.rootViewController = self.navigationController
self.navigationController!.popToRootViewController(animated: true)
if (!self.navigationController!.isViewLoaded
|| self.navigationController!.view.window == nil) {
self.window?.rootViewController?.present(self.navigationController!,
animated: true,
completion: nil)
}
}
return self.signInViewController!
}
debugger crash log:
{
"Content-Length" = 78;
"Content-Type" = "application/x-amz-json-1.1";
Date = "Fri, 08 Nov 2019 11:29:50 GMT";
"x-amzn-errormessage" = "Refresh Token has been revoked";
"x-amzn-errortype" = "NotAuthorizedException:";
"x-amzn-requestid" = "fd38c884-efbb-4f73-a907-8427fd811ef6";
}
2019-11-08 11:29:50:426 iParcelBox[4332:1445137] Response body:
{"__type":"NotAuthorizedException","message":"Refresh Token has been revoked"}
Starting Cognito Password Authentication
Main Thread Checker: UI API called on a background thread: -[UIViewController initWithCoder:]
PID: 4332, TID: 1445137, Thread name: (none), Queue name: NSOperationQueue 0x1080103a0 (QOS: UNSPECIFIED), QoS: 0
Backtrace:
4 iParcelBox 0x00000001021f1124 $s10iParcelBox20SignInViewControllerC5coderACSgSo7NSCoderC_tcfc + 1124
5 iParcelBox 0x00000001021f11e4 $s10iParcelBox20SignInViewControllerC5coderACSgSo7NSCoderC_tcfcTo + 60
6 UIKitCore 0x00000001c708e108 B856439D-6DF2-38FE-9689-E4C590AF1442 + 7123208
7 UIFoundation 0x00000001c694d300 601DB17B-4B17-30A9-962A-D27A531F470C + 447232
8 UIFoundation 0x00000001c694d534 601DB17B-4B17-30A9-962A-D27A531F470C + 447796
9 UIFoundation 0x00000001c68e7fe4 601DB17B-4B17-30A9-962A-D27A531F470C + 32740
10 UIKitCore 0x00000001c708d3fc B856439D-6DF2-38FE-9689-E4C590AF1442 + 7119868
11 UIKitCore 0x00000001c6dbd260 B856439D-6DF2-38FE-9689-E4C590AF1442 + 4170336
12 UIKitCore 0x00000001c6d17698 B856439D-6DF2-38FE-9689-E4C590AF1442 + 3491480
13 UIKitCore 0x00000001c708e108 B856439D-6DF2-38FE-9689-E4C590AF1442 + 7123208
14 UIFoundation 0x00000001c694d300 601DB17B-4B17-30A9-962A-D27A531F470C + 447232
15 UIFoundation 0x00000001c68e7fe4 601DB17B-4B17-30A9-962A-D27A531F470C + 32740
16 UIKitCore 0x00000001c70922b4 B856439D-6DF2-38FE-9689-E4C590AF1442 + 7140020
17 UIFoundation 0x00000001c694d300 601DB17B-4B17-30A9-962A-D27A531F470C + 447232
18 UIFoundation 0x00000001c694d534 601DB17B-4B17-30A9-962A-D27A531F470C + 447796
19 UIFoundation 0x00000001c68e7fe4 601DB17B-4B17-30A9-962A-D27A531F470C + 32740
20 UIKitCore 0x00000001c708d1e0 B856439D-6DF2-38FE-9689-E4C590AF1442 + 7119328
21 UIKitCore 0x00000001c708fe18 B856439D-6DF2-38FE-9689-E4C590AF1442 + 7130648
22 UIKitCore 0x00000001c7562054 B856439D-6DF2-38FE-9689-E4C590AF1442 + 12185684
23 iParcelBox 0x000000010235a1f8 $s10iParcelBox11AppDelegateC27startPasswordAuthenticationSo018AWSCognitoIdentityfG0_pyF + 964
24 iParcelBox 0x000000010235b628 $s10iParcelBox11AppDelegateC27startPasswordAuthenticationSo018AWSCognitoIdentityfG0_pyFTo + 40
25 AWSCognitoIdentityProvider 0x00000001061363fc -[AWSCognitoIdentityUser interactiveAuth] + 1312
26 AWSCognitoIdentityProvider 0x000000010612fd7c __36-[AWSCognitoIdentityUser getSession]_block_invoke + 224
27 AWSCore 0x0000000106405708 __56-[AWSTask continueWithExecutor:block:cancellationToken:]_block_invoke + 108
28 AWSCore 0x00000001063ae444 __30+[AWSExecutor defaultExecutor]_block_invoke_2 + 164
29 AWSCore 0x00000001063aed0c -[AWSExecutor execute:] + 120
30 AWSCore 0x0000000106405b7c __56-[AWSTask continueWithExecutor:block:cancellationToken:]_block_invoke.105 + 52
31 AWSCore 0x000000010640515c -[AWSTask runContinuations] + 532
32 AWSCore 0x0000000106404c28 -[AWSTask trySetError:] + 256
33 AWSCore 0x0000000106406b78 -[AWSTaskCompletionSource setError:] + 112
34 AWSCore 0x0000000106430f08 __61-[AWSURLSessionManager URLSession:task:didCompleteWithError:]_block_invoke + 6908
35 AWSCore 0x000000010640600c __63-[AWSTask continueWithExecutor:successBlock:cancellationToken:]_block_invoke + 160
36 AWSCore 0x0000000106405708 __56-[AWSTask continueWithExecutor:block:cancellationToken:]_block_invoke + 108
37 AWSCore 0x00000001063ae444 __30+[AWSExecutor defaultExecut2019-11-08 11:29:50.480369+0000 iParcelBox[4332:1445137] [reports] Main Thread Checker: UI API called on a background thread: -[UIViewController initWithCoder:]
PID: 4332, TID: 1445137, Thread name: (none), Queue name: NSOperationQueue 0x1080103a0 (QOS: UNSPECIFIED), QoS: 0
I'm having exactly the same issue.
In my case, AWSCognitoIdentityUser.getSession() is causing app crash. (Session Token expired and Refresh Token is revoked)
@kneekey23 can you assist? Opened a new ticket as requested. Looks like it's more than just gadget-man and I having issues.
This problem persists with the latest updates.
Looking at the stack trace, on the following line
25 AWSCognitoIdentityProvider 0x00000001061363fc -[AWSCognitoIdentityUser interactiveAuth] + 1312
it calls into:
24 iParcelBox 0x000000010235b628 $s10iParcelBox11AppDelegateC27startPasswordAuthenticationSo018AWSCognitoIdentityfG0_pyFTo + 40
iParcelBox is your application code, which I believe is responsible for updating some elements on the UI. Can you ensure that this code is being run on the main thread?
To do this, you can wrap your code in a DispatchQueue.main.async call. For example:
DispatchQueue.main.async {
//put your code here which updates ui elements
}
Looking at the stack trace, on the following line
25 AWSCognitoIdentityProvider 0x00000001061363fc -[AWSCognitoIdentityUser interactiveAuth] + 1312it calls into:
24 iParcelBox 0x000000010235b628 $s10iParcelBox11AppDelegateC27startPasswordAuthenticationSo018AWSCognitoIdentityfG0_pyFTo + 40iParcelBox is your application code, which I believe is responsible for updating some elements on the UI. Can you ensure that this code is being run on the main thread?
To do this, you can wrap your code in a
DispatchQueue.main.asynccall. For example:DispatchQueue.main.async { //put your code here which updates ui elements }
@wooj2 Please see code in my original post, that should answer your question. Everything seems wrapped accordingly already.
If you have recommendations of a different way to setup the CognitoYourUserPoolsSample, I will happily try.
Hi @rtnlsltn ,
My bad-- sorry for the confusion.
I was able to reproduce the crash you are seeing using the first block of code in a sample application. It makes sense that this code is crashing since our framework calls startPasswordAuthentication on a thread that is not guaranteed to be on the main thread.
Looking at your workaround (your 2nd code block), it seems that you are:
- Synchronous instantiation of the navigation controller and the sign in view controller on the main thread.
- Asynchronously presenting this the navigation controller containing the sign in view controller.
This seems like a reasonable workaround, but I am confused as why your workaround is still a problem. You mention that "If a logout is performed, tapping "Sign In" again after entering login info, does not dismiss the SignInViewController and route to the main view controller". Can you be more specific here, or perhaps help me so that I can reproduce this?
Here is what I'm doing:
- Use the sample application here: https://github.com/awslabs/aws-sdk-ios-samples/tree/main/CognitoYourUserPools-Sample/Swift
- Use the following code for startPasswordAuthentication (should be the same as your code from the 2nd block):
func startPasswordAuthentication() -> AWSCognitoIdentityPasswordAuthentication {
if (!Thread.current.isMainThread) {
DispatchQueue.main.sync {
if (self.navigationController == nil) {
self.navigationController = self.storyboard?.instantiateViewController(withIdentifier: "signinController") as? UINavigationController
}
if (self.signInViewController == nil) {
self.signInViewController = self.navigationController?.viewControllers[0] as? SignInViewController
}
}
} else {
if (self.navigationController == nil) {
self.navigationController = self.storyboard?.instantiateViewController(withIdentifier: "signinController") as? UINavigationController
}
if (self.signInViewController == nil) {
self.signInViewController = self.navigationController?.viewControllers[0] as? SignInViewController
}
}
DispatchQueue.main.async {
self.navigationController!.popToRootViewController(animated: true)
if (!self.navigationController!.isViewLoaded
|| self.navigationController!.view.window == nil) {
self.window?.rootViewController?.present(self.navigationController!,
animated: true,
completion: nil)
}
}
return self.signInViewController!
}
- Add the following code to
UserDetailTableViewController.swiftto be able to logout and make calls which require authorization. Tapping section0,row0 will log out, tapping anything else will attempt to make a network call :) -
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.section == 0 && indexPath.row == 0 {
self.user?.signOut()
} else {
self.user!.listDevices(10, paginationToken: nil).continueWith { (task) -> Any? in
print("this should issue a call to startPasswordAuthentication() if we are signed out")
}
}
tableView.deselectRow(at: indexPath, animated: true)
}
- Build and launch the app
- Sign in with your user name and password
- Tap indexPath.section ==0 && indexPath.row ==0 in order to sign out()
- Tap any other row to force a call without having credentials. This should cause the sign in view controller to appear, and you should be able to log in again.
@wooj2
- Please use the original cognitoyouruserpoolssample with the original login/logout methods and use a different user account when logging back in. Logging back in with the same account seems to be more reliable, which may be related to the session token? I'm currently out of town and away from a mac for a while, but I believe this example code does have a built-in logout function. I'd prefer to keep our examples as simple as possible.
- Please also try running 2 simulators with the same login and doing a user.globalsignout() on device 1. Wait for the session token to expire on device 2, then close/reopen the app (background/foreground may also work).
My real application's code in app delegate to survive this crash is much more complex (unnecessarily so). The "fix" code that myself and other users have implemented is creating unintended side-effects and possibly causing orphaned VC's, shuffling the VC stack, or causing some other unintended issue that prevents the login VC from passing to the main VC after logout and re-login attempt.
In either case, this issue needs a real fix from AWS, likely in the SDK itself. Something seems goofy in the way the login navigation is being handled. I'm at a point where my users are starting to complain. I will need to migrate my company's application and 2 others I'm involved with to another provider if this cannot be resolved in short time. It seems Amazon is quick to hype new services, then quickly abandon them, only to hype the latest service very shortly after e.g. Cognito -> Amplify, Mobile -> Appsync.
I digress. I appreciate your help and hope we can reach a resolution, not only for myself, but other applications suffering from this long-existing bug.
Hi @rtnlsltn,
I was able to reproduce the crash following your instructions in a sample application.
Looks like our framework doesn't make any assumption about from which thread will be calling the startPasswordAuthentication delegate's method. It leaves entirely to the client the responsibility of how to handle any UI update which seems quite reasonable to me.
Unfortunately I couldn't reproduce your 2nd issue, can you share more info about your VCs stack, or perhaps help me so that I can reproduce this?
The following fix solves the 1st issue and I was also able to login and logout repeatedly (with different users) without incurring in any other issue.
func startPasswordAuthentication() -> AWSCognitoIdentityPasswordAuthentication {
if (!Thread.current.isMainThread) {
DispatchQueue.main.sync {
if (self.navigationController == nil) {
self.navigationController = self.storyboard?.instantiateViewController(withIdentifier: "signinController") as? UINavigationController
}
if (self.signInViewController == nil) {
self.signInViewController = self.navigationController?.viewControllers[0] as? SignInViewController
}
}
} else {
if (self.navigationController == nil) {
self.navigationController = self.storyboard?.instantiateViewController(withIdentifier: "signinController") as? UINavigationController
}
if (self.signInViewController == nil) {
self.signInViewController = self.navigationController?.viewControllers[0] as? SignInViewController
}
}
DispatchQueue.main.async {
self.navigationController!.popToRootViewController(animated: true)
if (!self.navigationController!.isViewLoaded
|| self.navigationController!.view.window == nil) {
self.window?.rootViewController?.present(self.navigationController!,
animated: true,
completion: nil)
}
}
return self.signInViewController!
}
Hi @rtnlsltn, I was able to reproduce the crash following your instructions in a sample application. Looks like our framework doesn't make any assumption about from which thread will be calling the
startPasswordAuthenticationdelegate's method. It leaves entirely to the client the responsibility of how to handle any UI update which seems quite reasonable to me.Unfortunately I couldn't reproduce your 2nd issue, can you share more info about your VCs stack, or perhaps help me so that I can reproduce this?
The following fix solves the 1st issue and I was also able to login and logout repeatedly (with different users) without incurring in any other issue.
func startPasswordAuthentication() -> AWSCognitoIdentityPasswordAuthentication { if (!Thread.current.isMainThread) { DispatchQueue.main.sync { if (self.navigationController == nil) { self.navigationController = self.storyboard?.instantiateViewController(withIdentifier: "signinController") as? UINavigationController } if (self.signInViewController == nil) { self.signInViewController = self.navigationController?.viewControllers[0] as? SignInViewController } } } else { if (self.navigationController == nil) { self.navigationController = self.storyboard?.instantiateViewController(withIdentifier: "signinController") as? UINavigationController } if (self.signInViewController == nil) { self.signInViewController = self.navigationController?.viewControllers[0] as? SignInViewController } } DispatchQueue.main.async { self.navigationController!.popToRootViewController(animated: true) if (!self.navigationController!.isViewLoaded || self.navigationController!.view.window == nil) { self.window?.rootViewController?.present(self.navigationController!, animated: true, completion: nil) } } return self.signInViewController! }
@diegocstn
-
Can you confirm that you've pasted my exact code and nothing was changed in this code block? Please confirm your pod versions.
-
I'm literally able to test/reproduce this with your cognotoyouruserpoolssample. I've given details on how to reproduce, please confirmed you've followed them precisely.
This issue has been passed to 3-4 different AWS representatives now with varying amounts of repeatability. Can a 1:1 Zoom session be held so the issues can be clearly demonstrated?
@rtnlsltn
- Yes, I've replaced the implementation of
startPasswordAuthenticationwith the exact code snippet you provided. - This is what I've done to reproduce the issue on the
CognitoYourUserPools-Sampleapp using AWSCognitoIdentityProvider 2.22.0 on two different devices running iOS 13.7:- logged in on both device1 and device2 with user1
- global signed out user1 on device2
- after token expiration (1h), re-opened the app on device1 (no crash occurred thanks to the workaround you provided)
- signout user1 from device1
- signin and signout repeatedly with a different user user2
- signin and signout repeatedly with user user1
To better further assist you, it'd be helpful to validate:
- if the above repro steps are correct
- the version of
AWSCognitoIdentityProvideryou're experiencing the issue
@diegocstn my apologies for not responding to this. I've been 'dealing' with this error, but it is still existing. The easiest way to replicate is: Login with User1. Logout with User1. Repeat 2X. This seem sto be your Item vi above.
This leaves the user stranded at the sign-in page.
I've tried multiple versions of AWSCognitoIdentityProvider and am currently on '2.27.2'.
@royjit @ruisebas who can help with this?
To help you debug further will you be able to provide us with the verbose logs when the issue is happening. Also please update the code with the latest SDK since we have made some changes with the AWSMobileClient logic in versions 2.27.4 and in latest versions.
You can enable verbose logging by:
AWSDDLog.sharedInstance.add(AWSDDTTYLogger())
AWSDDLog.sharedInstance.logLevel = .verbose
Redact sensitive information before posting the log information here.
@rtnlsltn Can you please provide an update?
I can confirm this is still happening, using 2.27.10. I can consistently replicate simply by logging out, then logging in again with the same user. The login page then simply hangs. Force quitting the app then reloading - it goes straight in without having to login again.
Here's a redacted extract from the code - let me know if you need anything else:
`2022-07-15 18:32:46:423 iParcelBox-2[57878:4542387] -[AWSMQTTSession drainSenderQueue] [Line 715], Thread:<NSThread: 0x28208d780>{number = 11, name = (null)} waiting on drainSenderQueueSemaphore
2022-07-15 18:32:46:423 iParcelBox-2[57878:4542387] -[AWSMQTTSession drainSenderQueue] [Line 717], Thread:<NSThread: 0x28208d780>{number = 11, name = (null)} passed drainSenderQueueSemaphore
2022-07-15 18:32:46:423 iParcelBox-2[57878:4542387] -[AWSMQTTSession drainSenderQueue] [Line 728], Thread:<NSThread: 0x28208d780>{number = 11, name = (null)} signaling on drainSenderQueueSemaphore
2022-07-15 18:32:46:423 iParcelBox-2[57878:4542387] -[AWSMQTTSession drainSenderQueue] [Line 730], Thread:<NSThread: 0x28208d780>{number = 11, name = (null)} finished draining messages
2022-07-15 18:32:46:423 iParcelBox-2[57878:4542387] ClockTick:19: nothing to republish
2022-07-15 18:32:46:423 iParcelBox-2[57878:4542387] Connection Age: 19
Phone number has changed: +xxxxxx
2022-07-15 18:32:46:919 iParcelBox-2[57878:4542005] Request headers:
{
"Content-Type" = "application/x-amz-json-1.1";
Host = "cognito-idp.eu-west-1.amazonaws.com";
"User-Agent" = "aws-sdk-iOS/2.27.10 iOS/15.5 en_GB";
"X-Amz-Date" = 20220715T173246Z;
"X-Amz-Target" = "AWSCognitoIdentityProviderService.UpdateUserAttributes";
}
2022-07-15 18:32:46:919 iParcelBox-2[57878:4542005] Request body:
{"UserAttributes":[{"Value":"+xxx”,”Name":"phone_number"}],"AccessToken”:”xxxxx”}
Updating Stripe
Stripe URL: https://s18bveeh14.execute-api.eu-west-1.amazonaws.com/api/Stripe_update_user
CustomerId: xxxxx
Starting Cognito Password Authentication on thread: <_NSMainThread: 0x2820141c0>{number = 1, name = main}
Phone number has changed: +xxxx
Starting Cognito Password Authentication on thread: <_NSMainThread: 0x2820141c0>{number = 1, name = main}
Updating Stripe
Starting Cognito Password Authentication on thread: <_NSMainThread: 0x2820141c0>{number = 1, name = main}
Stripe URL: https://s18bveeh14.execute-api.eu-west-1.amazonaws.com/api/Stripe_update_user
CustomerId: xxxxxx
Starting Cognito Password Authentication on thread: <_NSMainThread: 0x2820141c0>{number = 1, name = main}
Subscribing to topics for: xxxxxx
2022-07-15 18:32:46:937 iParcelBox-2[57878:4542005] Subscribing to topic $aws/things/iParcelBox-xxxxxxx/shadow/+/accepted with messageCallback
2022-07-15 18:32:46:937 iParcelBox-2[57878:4542005] messageId sending now 8
2022-07-15 18:32:46:937 iParcelBox-2[57878:4542005] -[AWSMQTTSession drainSenderQueue] [Line 715], Thread:<_NSMainThread: 0x2820141c0>{number = 1, name = main} waiting on drainSenderQueueSemaphore
2022-07-15 18:32:46:937 iParcelBox-2[57878:4542005] -[AWSMQTTSession drainSenderQueue] [Line 717], Thread:<_NSMainThread: 0x2820141c0>{number = 1, name = main} passed drainSenderQueueSemaphore
2022-07-15 18:32:46:937 iParcelBox-2[57878:4542005] -[AWSMQTTSession drainSenderQueue] [Line 728], Thread:<_NSMainThread: 0x2820141c0>{number = 1, name = main} signaling on drainSenderQueueSemaphore
2022-07-15 18:32:46:937 iParcelBox-2[57878:4542005] -[AWSMQTTSession drainSenderQueue] [Line 730], Thread:<_NSMainThread: 0x2820141c0>{number = 1, name = main} finished draining messages
2022-07-15 18:32:46:937 iParcelBox-2[57878:4542005] <<<_NSMainThread: 0x2820141c0>{number = 1, name = main}>>: MQTTSession.send msg to server
2022-07-15 18:32:46:937 iParcelBox-2[57878:4542005] ***** waiting on encodeSemaphore *****
2022-07-15 18:32:46:937 iParcelBox-2[57878:4542005] ***** passed encodeSempahore. *****
2022-07-15 18:32:46:937 iParcelBox-2[57878:4542005] ***** signaling encodeSemaphore *****
Password Authentication started
Login Completed
Password Authentication started
Login Completed
Password Authentication started
Login Completed
Password Authentication started
Login Completed
2022-07-15 18:32:47:030 iParcelBox-2[57878:4542364] Response headers:
{
"Content-Length" = 2;
"Content-Type" = "application/x-amz-json-1.1";
Date = "Fri, 15 Jul 2022 17:32:47 GMT";
"x-amzn-requestid" = “XXXXXXXX”;
}
2022-07-15 18:32:47:030 iParcelBox-2[57878:4542364] Response body:
{}
2022-07-15 18:32:47:049 iParcelBox-2[57878:4542387] -[AWSMQTTDecoder stream:handleEvent:] [Line 63] EventCode:2, status:1, stream: <__NSCFInputStream: 0x2807301b0>, Thread: <NSThread: 0x28208d780>{number = 11, name = (null)}
2022-07-15 18:32:47:049 iParcelBox-2[57878:4542387] -[AWSMQTTSession decoder:newMessage:] [Line 396] messageType=11, status=2
2022-07-15 18:32:47:049 iParcelBox-2[57878:4542387] MQTTSession- newMessage msg type is 11
2022-07-15 18:32:47:049 iParcelBox-2[57878:4542387] -[AWSMQTTSession handleUnsuback:] [Line 494]
2022-07-15 18:32:47:049 iParcelBox-2[57878:4542387] Unsub Ack messageId 9
2022-07-15 18:32:47:049 iParcelBox-2[57878:4542387] MQTTSessionDelegate new ack for msgId: 9
2022-07-15 18:32:47:049 iParcelBox-2[57878:4542387] Received unsupported message type: 11
Response: SUCCESS:
Success 2022-07-15 18:32:49.694416+0100 iParcelBox-2[57878:4542005] Keyboard cannot present view controllers (attempted to present <UIKeyboardHiddenViewController_Autofill: 0x15fd91820>) Success
2022-07-15 18:33:33:422 iParcelBox-2[57878:4542387] ClockTick:66: nothing to republish Trying to login... Error Domain=NSOSStatusErrorDomain Code=-25293 ""account.iparcelbox.com" failed to approve "QXKJW97P67.com.iparcelbox.iparcelbox-2"" UserInfo={numberOfErrorsDeep=0, NSDescription="account.iparcelbox.com" failed to approve "QXKJW97P67.com.iparcelbox.iparcelbox-2"} 2022-07-15 18:33:33:779 iParcelBox-2[57878:4542005] Request headers: { "Content-Type" = "application/x-amz-json-1.1"; Host = "cognito-idp.eu-west-1.amazonaws.com"; "User-Agent" = "aws-sdk-iOS/2.27.10 iOS/15.5 en_GB"; "X-Amz-Date" = 20220715T173333Z; "X-Amz-Target" = "AWSCognitoIdentityProviderService.InitiateAuth"; } 2022-07-15 18:33:33:779 iParcelBox-2[57878:4542005] Request body: {"UserContextData":{"EncodedData”:”XXXXX”},”ClientMetadata":{"cognito:deviceName”:”XXX12","cognito:bundleShortV":"1.2.2","cognito:idForVendor”:”XXX”,”cognito:bundleVersion":"216","cognito:bundleId":"com.iparcelbox.iparcelbox-2","cognito:model":"iPhone","cognito:systemName":"iOS","cognito:iOSVersion":"15.5"},"AuthParameters":{"SRP_A”:”XXXXXX”,”SECRET_HASH”:”/XXXX=","USERNAME”:”XXXXX”},”AuthFlow":"USER_SRP_AUTH","ClientId”:”XXXXX”} 2022-07-15 18:33:33:869 iParcelBox-2[57878:4543162] Response headers: { "Content-Length" = 2731; "Content-Type" = "application/x-amz-json-1.1"; Date = "Fri, 15 Jul 2022 17:33:33 GMT"; "x-amzn-requestid" = “XXXXX”; } 2022-07-15 18:33:33:869 iParcelBox-2[57878:4543162] Response body:
Trying to login... Error Domain=NSOSStatusErrorDomain Code=-25293 ""account.iparcelbox.com" failed to approve "QXKJW97P67.com.iparcelbox.iparcelbox-2"" UserInfo={numberOfErrorsDeep=0, NSDescription="account.iparcelbox.com" failed to approve "QXKJW97P67.com.iparcelbox.iparcelbox-2"} 2022-07-15 18:33:51:587 iParcelBox-2[57878:4542005] Request headers: { "Content-Type" = "application/x-amz-json-1.1"; Host = "cognito-idp.eu-west-1.amazonaws.com"; "User-Agent" = "aws-sdk-iOS/2.27.10 iOS/15.5 en_GB"; "X-Amz-Date" = 20220715T173351Z; "X-Amz-Target" = "AWSCognitoIdentityProviderService.InitiateAuth"; } Password Authentication started Login Completed
Trying to login... Error Domain=NSOSStatusErrorDomain Code=-25293 ""account.iparcelbox.com" failed to approve "QXKJW97P67.com.iparcelbox.iparcelbox-2"" UserInfo={numberOfErrorsDeep=0, NSDescription="account.iparcelbox.com" failed to approve "QXKJW97P67.com.iparcelbox.iparcelbox-2"} 2022-07-15 18:34:16:507 iParcelBox-2[57878:4542005] Request headers: { "Content-Type" = "application/x-amz-json-1.1"; Host = "cognito-idp.eu-west-1.amazonaws.com"; "User-Agent" = "aws-sdk-iOS/2.27.10 iOS/15.5 en_GB"; "X-Amz-Date" = 20220715T173416Z; "X-Amz-Target" = "AWSCognitoIdentityProviderService.InitiateAuth"; } 2022-07-15 18:34:16:507 iParcelBox-2[57878:4542005] Request body: {"UserContextData":{"EncodedData":"XXXXXXX ="},"ClientMetadata":{"cognito:deviceName":"PN’s iPhone 12","cognito:bundleShortV":"1.2.2","cognito:idForVendor":"XXXXXXX","cognito:bundleVersion":"216","cognito:bundleId":"com.iparcelbox.iparcelbox-2","cognito:model":"iPhone","cognito:systemName":"iOS","cognito:iOSVersion":"15.5"},"AuthParameters":{"SRP_A":"XXXXXXX","SECRET_HASH":"/XXXXXXX =","USERNAME":"[email protected]"},"AuthFlow":"USER_SRP_AUTH","ClientId":"XXXXXXX"} 2022-07-15 18:34:16:736 iParcelBox-2[57878:4542361] Response headers: { "Content-Length" = 2731; "Content-Type" = "application/x-amz-json-1.1"; Date = "Fri, 15 Jul 2022 17:34:16 GMT"; "x-amzn-requestid" = "ca74e020-15eb-4786-860b-8d24942e183f"; } 2022-07-15 18:34:16:737 iParcelBox-2[57878:4542361] Response body: {"ChallengeName":"PASSWORD_VERIFIER","ChallengeParameters":{"SALT":"XXXXXXX","SECRET_BLOCK":"XXXXXXX","USERNAME":"XXXXXXX","USER_ID_FOR_SRP":"XXXXXXX"}}
2022-07-15 18:34:16:749 iParcelBox-2[57878:4542361] Request headers: { "Content-Type" = "application/x-amz-json-1.1"; Host = "cognito-idp.eu-west-1.amazonaws.com"; "User-Agent" = "aws-sdk-iOS/2.27.10 iOS/15.5 en_GB"; "X-Amz-Date" = 20220715T173416Z; "X-Amz-Target" = "AWSCognitoIdentityProviderService.RespondToAuthChallenge"; } 2022-07-15 18:34:16:749 iParcelBox-2[57878:4542361] Request body: {"UserContextData":{"EncodedData”:”XXXXXXX”},”ChallengeResponses":{"PASSWORD_CLAIM_SECRET_BLOCK":"XXXXXXX/XXXXXXX","USERNAME":"XXXXXXX","SECRET_HASH":"XXXXXXX =","PASSWORD_CLAIM_SIGNATURE":"XXXXXXX =","DEVICE_KEY":"XXXXXXX","TIMESTAMP":"Fri Jul 15 17:34:16 UTC 2022"},"ChallengeName":"PASSWORD_VERIFIER","ClientId":"XXXXXXX"} 2022-07-15 18:34:17:140 iParcelBox-2[57878:4543688] Response headers: { "Content-Length" = 1366; "Content-Type" = "application/x-amz-json-1.1"; Date = "Fri, 15 Jul 2022 17:34:17 GMT"; "x-amzn-requestid" = "777fb3f9-3dff-4937-966d-99c01857888f"; } 2022-07-15 18:34:17:140 iParcelBox-2[57878:4543688] Response body: {"ChallengeName":"SMS_MFA","ChallengeParameters":{"CODE_DELIVERY_DELIVERY_MEDIUM":"SMS","CODE_DELIVERY_DESTINATION":"+********1978"},"Session":"XXXXXXX"} Starting Cognito MFA on thread: <NSThread: 0x2820d1440>{number = 22, name = (null)}
2022-07-15 18:34:22:888 iParcelBox-2[57878:4542005] Request headers: { "Content-Type" = "application/x-amz-json-1.1"; Host = "cognito-idp.eu-west-1.amazonaws.com"; "User-Agent" = "aws-sdk-iOS/2.27.10 iOS/15.5 en_GB"; "X-Amz-Date" = 20220715T173422Z; "X-Amz-Target" = "AWSCognitoIdentityProviderService.RespondToAuthChallenge"; } 2022-07-15 18:34:22:888 iParcelBox-2[57878:4542005] Request body: {"UserContextData":{"EncodedData":"XXXXXXX"},"ChallengeResponses":{"USERNAME":"XXXXXXX","DEVICE_KEY":"eu XXXXXXX","SECRET_HASH":"XXXXXXX =","SMS_MFA_CODE":"XXXXXXX"},"ChallengeName":"SMS_MFA","Session":"XXXXXXX","ClientId":"XXXXXXX"} 2022-07-15 18:34:23:113 iParcelBox-2[57878:4543888] Response headers: { "Content-Length" = 1359; "Content-Type" = "application/x-amz-json-1.1"; Date = "Fri, 15 Jul 2022 17:34:23 GMT"; "x-amzn-requestid" = "aaec6366-4ed1-4dc8-b69f-02e06fd8e3b7"; } 2022-07-15 18:34:23:113 iParcelBox-2[57878:4543888] Response body: {"ChallengeName":"DEVICE_SRP_AUTH","ChallengeParameters":{},"Session":"XXXXXXX"} 2022-07-15 18:34:23:125 iParcelBox-2[57878:4543888] Request headers: { "Content-Type" = "application/x-amz-json-1.1"; Host = "cognito-idp.eu-west-1.amazonaws.com"; "User-Agent" = "aws-sdk-iOS/2.27.10 iOS/15.5 en_GB"; "X-Amz-Date" = 20220715T173423Z; "X-Amz-Target" = "AWSCognitoIdentityProviderService.RespondToAuthChallenge"; } 2022-07-15 18:34:23:125 iParcelBox-2[57878:4543888] Request body: {"UserContextData":{"EncodedData":"XXXXXXX =="},"ChallengeResponses":{"USERNAME":"XXXXXXX","DEVICE_KEY":"eu XXXXXXX","XXXXXXX =","SRP_A":"XXXXXXX"},"ChallengeName":"DEVICE_SRP_AUTH","Session":"AYABe XXXXXXX","ClientId":"XXXXXXX"} 2022-07-15 18:34:23:286 iParcelBox-2[57878:4543688] Response headers: { "Content-Length" = 2743; "Content-Type" = "application/x-amz-json-1.1"; Date = "Fri, 15 Jul 2022 17:34:23 GMT"; "x-amzn-requestid" = "de6cf6fd-4b40-4eee-aea8-c6ede884c43f"; } 2022-07-15 18:34:23:286 iParcelBox-2[57878:4543688] Response body: {"ChallengeName":"DEVICE_PASSWORD_VERIFIER","ChallengeParameters":{"DEVICE_KEY":"XXXXXXX","SALT":"XXXXXXX","SECRET_BLOCK":"XXXXXXX","USERNAME":"XXXXXXX"}} 2022-07-15 18:34:23:299 iParcelBox-2[57878:4543688] Request headers: { "Content-Type" = "application/x-amz-json-1.1"; Host = "cognito-idp.eu-west-1.amazonaws.com"; "User-Agent" = "aws-sdk-iOS/2.27.10 iOS/15.5 en_GB"; "X-Amz-Date" = 20220715T173423Z; "X-Amz-Target" = "AWSCognitoIdentityProviderService.RespondToAuthChallenge"; } 2022-07-15 18:34:23:299 iParcelBox-2[57878:4543688] Request body: {"UserContextData":{"EncodedData":"XXXXXXX =="},"ChallengeResponses":{"PASSWORD_CLAIM_SECRET_BLOCK":"XXXXXXX =","USERNAME":"XXXXXXX","SECRET_HASH":"XXXXXXX =","PASSWORD_CLAIM_SIGNATURE":"XXXXXXX =","DEVICE_KEY":"XXXXXXX","TIMESTAMP":"Fri Jul 15 17:34:23 UTC 2022"},"ChallengeName":"DEVICE_PASSWORD_VERIFIER","ClientId":"XXXXXXX"} 2022-07-15 18:34:23:423 iParcelBox-2[57878:4542387] -[AWSMQTTSession drainSenderQueue] [Line 715], Thread:<NSThread: 0x28208d780>{number = 11, name = (null)} waiting on drainSenderQueueSemaphore 2022-07-15 18:34:23:423 iParcelBox-2[57878:4542387] -[AWSMQTTSession drainSenderQueue] [Line 717], Thread:<NSThread: 0x28208d780>{number = 11, name = (null)} passed drainSenderQueueSemaphore 2022-07-15 18:34:23:423 iParcelBox-2[57878:4542387] -[AWSMQTTSession drainSenderQueue] [Line 728], Thread:<NSThread: 0x28208d780>{number = 11, name = (null)} signaling on drainSenderQueueSemaphore 2022-07-15 18:34:23:423 iParcelBox-2[57878:4542387] -[AWSMQTTSession drainSenderQueue] [Line 730], Thread:<NSThread: 0x28208d780>{number = 11, name = (null)} finished draining messages 2022-07-15 18:34:23:423 iParcelBox-2[57878:4542387] ClockTick:116: nothing to republish 2022-07-15 18:34:23:493 iParcelBox-2[57878:4543688] Response headers: { "Content-Length" = 4044; "Content-Type" = "application/x-amz-json-1.1"; Date = "Fri, 15 Jul 2022 17:34:23 GMT"; "x-amzn-requestid" = "4c28651c-fb49-4497-b88b-7c218e299733"; } 2022-07-15 18:34:23:493 iParcelBox-2[57878:4543688] Response body: {"AuthenticationResult":{"AccessToken":"XXXXXXX","TokenType":"Bearer"},"ChallengeParameters":{}} 2022-07-15 18:34:24:422 iParcelBox-2[57878:4542387] -[AWSMQTTSession drainSenderQueue] [Line 715], Thread:<NSThread: 0x28208d780>{number = 11, name = (null)} waiting on drainSenderQueueSemaphore 2022-07-15 18:34:24:422 iParcelBox-2[57878:4542387] -[AWSMQTTSession drainSenderQueue] [Line 717], Thread:<NSThread: 0x28208d780>{number = 11, name = (null)} passed drainSenderQueueSemaphore 2022-07-15 18:34:24:422 iParcelBox-2[57878:4542387] -[AWSMQTTSession drainSenderQueue] [Line 728], Thread:<NSThread: 0x28208d780>{number = 11, name = (null)} signaling on drainSenderQueueSemaphore 2022-07-15 18:34:24:422 iParcelBox-2[57878:4542387] -[AWSMQTTSession drainSenderQueue] [Line 730], Thread:<NSThread: 0x28208d780>{number = 11, name = (null)} finished draining messages 2022-07-15 18:34:24:422 iParcelBox-2[57878:4542387] ClockTick:117: nothing to republish
2022-07-15 18:34:30.488469+0100 iParcelBox-2[57878:4542005] [] nehelper sent invalid result code [1] for Wi-Fi information request 2022-07-15 18:34:31.094072+0100 iParcelBox-2[57878:4542005] [Snapshotting] Snapshotting a view (0x16089de00, UIKeyboardImpl) that is not in a visible window requires afterScreenUpdates:YES. `
@royjit @harsh62 see above, is this sufficient?
@diegocstn @royjit @harsh62 please update, as it's been almost a month...
@gadget-man any traction on this from your end? Can't seem to get any AWS rep to respond.
Hi @rtnlsltn, sorry for the late response.
Unfortunately I was also unable to reproduce the 2nd issue (that being SignInViewController not dismissing after successful login) following @diegocstn's steps and the code snippets you provided.
One thing to have in mind is that, as with the first issue you were encountering, the SDK leaves the responsibility of dealing with the UI up to the client.
In this case, I assume SignInViewController implements the didCompleteStepWithError(_:) method that takes care of that, probably something like:
func didCompleteStepWithError(_ error: Error?) {
DispatchQueue.main.async {
if let error = error as NSError? {
// Handle error...
} else {
// On success, dismiss this view controller
self.presentingViewController?.dismiss(animated: true)
}
}
}
Would you mind checking if it looks like that? And also that presentingViewController is not nil when this method is called.
If all looks well, would you be able to provide us with a Sample app in which you can consistently reproduce the issue? It could very well that we're missing some additional precondition.
Thanks!
@ruisebas ill try to get to this in the next few days.
@ruisebas Sorry for delay.
My method looks similar to that. There is no error called. I logout, then log back in with the same user. The button press is called, as is the passwordAuthenticationCompletion call, then nothing happens. There is no error thrown and didCompleteStepWithError is not thrown. Any user can attempt to login at this state and it responds the same.
public func didCompleteStepWithError(_ error: Error?) {
DispatchQueue.main.async {
if let error = error as NSError? {
let alertController = UIAlertController(title: error.userInfo["__type"] as? String,
message: error.userInfo["message"] as? String,
preferredStyle: .alert)
let retryAction = UIAlertAction(title: "Retry", style: .default, handler: nil)
alertController.addAction(retryAction)
self.present(alertController, animated: true, completion: nil)
} else {
UserDefaults.standard.set(self.txtUsername.text, forKey: Constants.SignIn.username)
UserDefaults.standard.set(self.txtPassword.text, forKey: Constants.SignIn.password)
self.txtUsername.text = nil
self.dismiss(animated: true, completion: nil)
}
}
}
@IBAction func btnLoginPress(_ sender: Any) {
//logoAnimationIn()
if (self.txtUsername.text != nil && self.txtPassword.text != nil) {
let authDetails = AWSCognitoIdentityPasswordAuthenticationDetails(username: self.txtUsername.text!, password: self.txtPassword.text! )
self.passwordAuthenticationCompletion?.set(result: authDetails)
} else {
let alertController = UIAlertController(title: "Missing information",
message: "Please enter a valid user name and password",
preferredStyle: .alert)
let retryAction = UIAlertAction(title: "Retry", style: .default, handler: nil)
alertController.addAction(retryAction)
}
}
Hi @rtnlsltn, thanks for the update.
So that we're on the same page, the behaviour you are seeing is the didCompleteStepWithError function not being called at all after you call self.passwordAuthenticationCompletion?.set(result: authDetails), correct?
If that's the case, that's definitely unexpected, as it should be called on both success and error.
Could if be that you are using an outdated passwordAuthenticationCompletion reference? Are you always overriding it in the getDetails function?
It should look like this:
public func getDetails(_ authenticationInput: AWSCognitoIdentityPasswordAuthenticationInput,
passwordAuthenticationCompletionSource: AWSTaskCompletionSource<AWSCognitoIdentityPasswordAuthenticationDetails>) {
self.passwordAuthenticationCompletion = passwordAuthenticationCompletionSource
// ...
}
It this looks the same, would you be able to provide us with a Sample app in which you can consistently reproduce the issue? Since we are unable to reproduce it, this would be the best path forward.
@ruisebas have you tried using the aws-sdk-ios-samples-master repo and the CognitoYourUserPoolsSample.xcodeproj? This should be reproducible there. This has been mentioned many times, going back to December 2020.
Yes, my getDetails function is identical.
Hi @rtnlsltn! Are you sure you are using the suggested code block provided by wooj2 and diegocstn? Because I was finally able to reproduce your issue, but it only happened using the original code you provided in the issue description.
The problem seems to be this line:
self.window?.rootViewController = self.navigationController
This would mess up the view hierarchy and likely cause your issue. I don't see this line being present in the original CognitoYourUserPools-Sample project, so please double check that you don't have it in yours.
I also have self.window?.rootViewController = self.navigationController in my code. If I remove it, when logging out I get an error:
Application tried to present modally a view controller <UINavigationController: 0x10896c400> that is already being presented by <iParcelBox_2.myBoxNavController: 0x1090e8800>.
Perhaps this is because my login page is in a different storyboard (and therefore navigation controller) to the main page?
Looking into this further, I've identified that whenever the app hangs on the 'Login' screen which doesn't get dismissed, didCompleteStepWithError is being called, but error is nil. I'm already calling self.presentingViewController?.dismiss(animated: true) if error = nil, however it's not dismissing the SignInViewController. Running a check on self.presentingViewController at this point is returning nil - so I think this is part of the problem.
So the problem seems to be that AWS is calling didCompleteStepWithError even though there is no error.
Also if I call self.dismiss or self.presentingViewController?.dismiss within didCompleteStepWithError, I can see the code from the underlying ViewController run correctly (so it must be in the stack somewhere), however the login page just fails to dismiss.
Anything else I can do to force the Login screen to dismiss?
Hi @gadget-man!
As I mentioned in my previous comment, didCompleteStepWithError is called on both success and error.
Having a nil error just means the operation was successful, it is a common Objective-C naming pattern for delegate methods.
Also, the responsibility of handling any UI update is up to the client, AWSCognitoIdentityPasswordAuthentication does not (and cannot) handle it.
The issues you are facing seem to be the result of a corrupted navigation stack and/or outdated references in your code.
I'd advice to check on any other place where you manually manipulate the UI (like the previously mentioned self.window?.rootViewController = self.navigationController) and see if refactoring/removing them solves the problem.