aws-amplify / amplify-flutter

A declarative library with an easy-to-use interface for building Flutter applications on AWS.
https://docs.amplify.aws
Apache License 2.0
1.32k stars 247 forks source link

Few Issues with 1.0.0-0 developer preview #2009

Closed PfernFSU closed 2 years ago

PfernFSU commented 2 years ago

Description

We read the blog post announcing the developer preview, so we decided to upgrade as we were experiencing some of the race conditions you guys mentioned as fixed. However, we experienced two distinct issues. I am not sure where to write them, so I thought it best to condense it into a single bug/issue report. I briefly scanned the open issues and did not see any. We are only using mobile and not targeting web.

Relevant pubspec.yaml:

  amplify_auth_cognito: ^1.0.0-next.0
  amplify_api: ^1.0.0-next.0
  amplify_datastore: ^1.0.0-next.0
  amplify_flutter: ^1.0.0-next.0

Issue 1

We have MFA set up in Cognito and any log in from a new device should trigger an SMS verification with the 6-digit code being sent. This is working well, and the code works. However, the code is always sent now upon login. Before, the device used to be remembered. I can log out and then log back in and each time I will have to follow the flow to enter the 6-digit passcode that was sent via SMS. I was not expecting to be required to enter the SMS code each time, and before the developer preview branch I was never required to do so.

Issue 2

If I log in as person A, then sign out, then log in as person B, I will have person A's datastore on my computer and inspecting their user I can see their email/username from Cognito. We have custom fields in Cognito (like a user's company) so the old user is still held somewhere. It is like the whole session is stored on the device and never cleansed, which results in the datastore being refetched for the wrong user. We call clear() on the datastore while signing out via: Amplify.DataStore.clear(); so it leads me to believe the AWS token is stored when it should not be and therefor fetching the wrong datastore. Logging in with person C after person A and B will still display person A's AWS info taken from Cognito (we display their email/phone number on a profile screen). To recap, this below line returns the first person to ever log in on the device, no matter who is logged in: Amplify.Auth.getCurrentUser();

These two issues only appear on the developer preview branch, and are not on the latest stable branch.

Amplify config (with sensitive info asterisk'ed out):

const amplifyConfigStr = '''
{
    "UserAgent": "aws-amplify-cli/2.0",
    "Version": "1.0",
    "api": {
        "plugins": {
            "awsAPIPlugin": {
                "Addventure": {
                    "endpointType": "GraphQL",
                    "endpoint": "https://***.appsync-api.us-east-1.amazonaws.com/graphql",
                    "region": "us-east-1",
                    "authorizationType": "AMAZON_COGNITO_USER_POOLS",
                    "apiKey": "***"
                }
            }
        }
    },
    "auth": {
        "plugins": {
            "awsCognitoAuthPlugin": {
                "UserAgent": "aws-amplify-cli/0.1.0",
                "Version": "0.1.0",
                "IdentityManager": {
                    "Default": {}
                },
                "AppSync": {
                    "Default": {
                        "ApiUrl": "https://***.appsync-api.us-east-1.amazonaws.com/graphql",
                        "Region": "us-east-1",
                        "AuthMode": "AMAZON_COGNITO_USER_POOLS",
                        "ClientDatabasePrefix": "***_AMAZON_COGNITO_USER_POOLS"
                    },
                    "Addventure_API_KEY": {
                        "ApiUrl": "https://***.appsync-api.us-east-1.amazonaws.com/graphql",
                        "Region": "us-east-1",
                        "AuthMode": "API_KEY",
                        "ApiKey": "***",
                        "ClientDatabasePrefix": "***_API_KEY"
                    },
                    "Addventure_AWS_IAM": {
                        "ApiUrl": "https://***.appsync-api.us-east-1.amazonaws.com/graphql",
                        "Region": "us-east-1",
                        "AuthMode": "AWS_IAM",
                        "ClientDatabasePrefix": "***_AWS_IAM"
                    }
                },
                "CredentialsProvider": {
                    "CognitoIdentity": {
                        "Default": {
                            "PoolId": "us-east-1:***",
                            "Region": "us-east-1"
                        }
                    }
                },
                "CognitoUserPool": {
                    "Default": {
                        "PoolId": "us-east-***",
                        "AppClientId": "***",
                        "Region": "us-east-1"
                    }
                },
                "Auth": {
                    "Default": {
                        "authenticationFlowType": "USER_SRP_AUTH"
                    }
                }
            }
        }
    }
}''';

Please let me know if I can help further. And thank you for all you do!

Categories

Steps to Reproduce

Issue 1:

  1. Set up Cognito User Pool to require MFA
  2. Under User Pools in AWS Console in Cognito, verify under General Settings -> Devices that you Always is selected for if we want to remember the user's device. Verify the second option to suppress MFA text's on remembered devices is set to Yes.
  3. Log in with a user on a mobile app. Get the text. Log out and then log in on the same device.

Issue 2:

  1. Log in with User A into a mobile app (repro'd in iPhone emulator and iPhone 11 actual device).
  2. Log out. Log in with a different user than step 1.
  3. In emulator, after logged in put a breakpoint on this line somewhere in your code and inspect the current user that comes back. It will be the first user you logged in as regardless of who is actually logged in. The userAttributes variable will always be the first user's information. final userAttributes = await Amplify.Auth.fetchUserAttributes();

Screenshots

No response

Platforms

Android Device/Emulator API Level

No response

Environment

Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.0.5, on macOS 12.4 21F79 darwin-arm, locale en-US)
[!] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
    ✗ cmdline-tools component is missing
      Run `path/to/sdkmanager --install "cmdline-tools;latest"`
      See https://developer.android.com/studio/command-line for more details.
    ✗ Android license status unknown.
      Run `flutter doctor --android-licenses` to accept the SDK licenses.
      See https://flutter.dev/docs/get-started/install/macos#android-setup for more details.
[✓] Xcode - develop for iOS and macOS (Xcode 13.4.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2021.2)
[✓] VS Code (version 1.69.2)
[✓] Connected device (3 available)
[✓] HTTP Host Availability

! Doctor found issues in 1 category.

Dependencies

flutter pub deps --no-dev --style=compact
Dart SDK 2.17.6
Flutter SDK 3.0.5
<AppName> 0.0.9+9

dependencies:
- amplify_api 1.0.0-next.0 [amplify_api_android amplify_api_ios amplify_core amplify_flutter aws_common collection flutter meta plugin_platform_interface]
- amplify_auth_cognito 1.0.0-next.0 [amplify_auth_cognito_android amplify_auth_cognito_dart amplify_auth_cognito_ios amplify_core amplify_flutter amplify_secure_storage async flutter flutter_web_plugins meta path plugin_platform_interface]
- amplify_datastore 1.0.0-next.0 [flutter amplify_datastore_plugin_interface amplify_core plugin_platform_interface meta collection async]
- amplify_flutter 1.0.0-next.0 [amplify_core amplify_datastore_plugin_interface amplify_flutter_android amplify_flutter_ios amplify_secure_storage aws_common collection flutter meta plugin_platform_interface]
- animations 2.0.3 [flutter]
- cached_network_image 3.2.1 [flutter flutter_cache_manager octo_image cached_network_image_platform_interface cached_network_image_web]
- cupertino_icons 1.0.5
- device_info_plus 4.0.1 [flutter device_info_plus_platform_interface device_info_plus_macos device_info_plus_linux device_info_plus_web device_info_plus_windows]
- dio 4.0.6 [http_parser path]
- flutter 0.0.0 [characters collection material_color_utilities meta vector_math sky_engine]
- flutter_local_notifications 9.7.0 [clock flutter flutter_local_notifications_linux flutter_local_notifications_platform_interface timezone]
- flutter_localizations 0.0.0 [flutter intl characters clock collection material_color_utilities meta path vector_math]
- flutter_native_splash 2.2.7 [args flutter flutter_web_plugins image js lint meta path universal_io xml yaml]
- flutter_native_timezone 2.0.0 [flutter_web_plugins flutter js]
- flutter_riverpod 1.0.4 [collection flutter meta riverpod state_notifier]
- flutter_secure_storage 5.1.0 [flutter flutter_secure_storage_linux flutter_secure_storage_macos flutter_secure_storage_platform_interface flutter_secure_storage_web flutter_secure_storage_windows meta]
- font_awesome_flutter 10.1.0 [flutter]
- freezed_annotation 2.1.0 [collection json_annotation meta]
- html 0.15.0 [csslib source_span]
- intl 0.17.0 [clock path]
- json_annotation 4.6.0 [meta]
- local_auth 2.1.1 [flutter intl local_auth_android local_auth_ios local_auth_platform_interface local_auth_windows]
- logging 1.0.2
- package_info_plus 1.4.3 [flutter package_info_plus_platform_interface package_info_plus_linux package_info_plus_macos package_info_plus_windows package_info_plus_web]
- permission_handler 10.0.0 [flutter meta permission_handler_android permission_handler_apple permission_handler_windows permission_handler_platform_interface]
- routemaster 1.0.1 [flutter flutter_web_plugins path collection]
- shared_preferences 2.0.15 [flutter shared_preferences_android shared_preferences_ios shared_preferences_linux shared_preferences_macos shared_preferences_platform_interface shared_preferences_web shared_preferences_windows]
- url_launcher 6.1.5 [flutter url_launcher_android url_launcher_ios url_launcher_linux url_launcher_macos url_launcher_platform_interface url_launcher_web url_launcher_windows]

transitive dependencies:
- amplify_api_android 1.0.0-next.0 [flutter]
- amplify_api_ios 1.0.0-next.0 [amplify_core flutter]
- amplify_auth_cognito_android 1.0.0-next.0 [flutter]
- amplify_auth_cognito_dart 0.1.1 [amplify_core amplify_secure_storage_dart async aws_common aws_signature_v4 built_collection built_value collection convert crypto fixnum http intl js json_annotation meta oauth2 path smithy smithy_aws stream_transform uuid worker_bee]
- amplify_auth_cognito_ios 1.0.0-next.0 [amplify_core flutter]
- amplify_core 1.0.0-next.0 [async aws_common aws_signature_v4 collection http intl json_annotation logging meta uuid]
- amplify_datastore_plugin_interface 1.0.0-next.0 [amplify_core collection flutter meta]
- amplify_flutter_android 1.0.0-next.0 [flutter]
- amplify_flutter_ios 1.0.0-next.0 [amplify_core flutter]
- amplify_secure_storage 0.1.0 [amplify_secure_storage_dart flutter]
- amplify_secure_storage_dart 0.1.0 [aws_common built_collection built_value ffi js meta win32 worker_bee]
- archive 3.3.0 [crypto path]
- args 2.3.1
- async 2.8.2 [collection meta]
- aws_common 0.2.1 [async collection http logging meta stream_transform uuid]
- aws_signature_v4 0.2.1 [async aws_common collection convert crypto http json_annotation meta path]
- built_collection 5.1.1
- built_value 8.3.2 [built_collection collection fixnum meta]
- cached_network_image_platform_interface 1.0.0 [flutter flutter_cache_manager]
- cached_network_image_web 1.0.1 [flutter flutter_cache_manager cached_network_image_platform_interface]
- characters 1.2.0
- charcode 1.3.1
- clock 1.1.0
- collection 1.16.0
- convert 3.0.2 [typed_data]
- crclib 3.0.0 [meta tuple]
- crypto 3.0.2 [typed_data]
- csslib 0.17.2 [source_span]
- dbus 0.7.7 [args ffi meta xml]
- device_info_plus_linux 2.1.1 [device_info_plus_platform_interface file flutter meta]
- device_info_plus_macos 2.2.3 [device_info_plus_platform_interface flutter]
- device_info_plus_platform_interface 2.3.0+1 [flutter meta plugin_platform_interface]
- device_info_plus_web 2.1.0 [device_info_plus_platform_interface flutter_web_plugins flutter]
- device_info_plus_windows 3.0.1 [device_info_plus_platform_interface ffi flutter win32]
- ffi 2.0.1
- file 6.1.2 [meta path]
- fixnum 1.0.1
- flutter_blurhash 0.7.0 [flutter]
- flutter_cache_manager 3.3.0 [clock collection file flutter http path path_provider pedantic rxdart sqflite uuid]
- flutter_local_notifications_linux 0.5.0+1 [flutter flutter_local_notifications_platform_interface dbus path xdg_directories]
- flutter_local_notifications_platform_interface 5.0.0 [flutter plugin_platform_interface]
- flutter_plugin_android_lifecycle 2.0.6 [flutter]
- flutter_secure_storage_linux 1.1.1 [flutter flutter_secure_storage_platform_interface]
- flutter_secure_storage_macos 1.1.1 [flutter flutter_secure_storage_platform_interface]
- flutter_secure_storage_platform_interface 1.0.0 [flutter plugin_platform_interface]
- flutter_secure_storage_web 1.0.2 [flutter flutter_web_plugins flutter_secure_storage_platform_interface js]
- flutter_secure_storage_windows 1.1.2 [flutter flutter_secure_storage_platform_interface]
- flutter_web_plugins 0.0.0 [flutter js characters collection material_color_utilities meta vector_math]
- http 0.13.4 [async http_parser meta path]
- http_parser 4.0.1 [collection source_span string_scanner typed_data]
- image 3.2.0 [archive meta xml]
- js 0.6.4
- lint 1.10.0
- local_auth_android 1.0.5 [flutter flutter_plugin_android_lifecycle intl local_auth_platform_interface]
- local_auth_ios 1.0.7 [flutter intl local_auth_platform_interface]
- local_auth_platform_interface 1.0.4 [flutter intl plugin_platform_interface]
- local_auth_windows 1.0.1 [flutter local_auth_platform_interface]
- matcher 0.12.11 [stack_trace]
- material_color_utilities 0.1.4
- meta 1.7.0
- oauth2 2.0.0 [collection crypto http http_parser]
- octo_image 1.0.2 [flutter flutter_blurhash]
- package_info_plus_linux 1.0.5 [package_info_plus_platform_interface flutter path]
- package_info_plus_macos 1.3.0 [flutter]
- package_info_plus_platform_interface 1.0.2 [flutter meta plugin_platform_interface]
- package_info_plus_web 1.0.5 [flutter flutter_web_plugins http meta package_info_plus_platform_interface]
- package_info_plus_windows 2.0.0 [package_info_plus_platform_interface ffi flutter win32]
- path 1.8.1
- path_provider 2.0.11 [flutter path_provider_android path_provider_ios path_provider_linux path_provider_macos path_provider_platform_interface path_provider_windows]
- path_provider_android 2.0.14 [flutter path_provider_platform_interface]
- path_provider_ios 2.0.9 [flutter path_provider_platform_interface]
- path_provider_linux 2.1.7 [ffi flutter path path_provider_platform_interface xdg_directories]
- path_provider_macos 2.0.6 [flutter path_provider_platform_interface]
- path_provider_platform_interface 2.0.4 [flutter platform plugin_platform_interface]
- path_provider_windows 2.1.0 [ffi flutter path path_provider_platform_interface win32]
- pedantic 1.11.1
- permission_handler_android 10.0.0 [flutter permission_handler_platform_interface]
- permission_handler_apple 9.0.4 [flutter permission_handler_platform_interface]
- permission_handler_platform_interface 3.7.0 [flutter meta plugin_platform_interface]
- permission_handler_windows 0.1.0 [flutter permission_handler_platform_interface]
- petitparser 5.0.0 [meta]
- platform 3.1.0
- plugin_platform_interface 2.1.2 [meta]
- process 4.2.4 [file path platform]
- quiver 3.1.0 [matcher]
- retry 3.1.0
- riverpod 1.0.3 [collection meta state_notifier]
- rxdart 0.27.4
- shared_preferences_android 2.0.12 [flutter shared_preferences_platform_interface]
- shared_preferences_ios 2.1.1 [flutter shared_preferences_platform_interface]
- shared_preferences_linux 2.1.1 [file flutter path path_provider_linux path_provider_platform_interface shared_preferences_platform_interface]
- shared_preferences_macos 2.0.4 [flutter shared_preferences_platform_interface]
- shared_preferences_platform_interface 2.0.0 [flutter]
- shared_preferences_web 2.0.4 [flutter flutter_web_plugins shared_preferences_platform_interface]
- shared_preferences_windows 2.1.1 [file flutter path path_provider_platform_interface path_provider_windows shared_preferences_platform_interface]
- shelf 1.3.0 [async collection http_parser path stack_trace stream_channel]
- sky_engine 0.0.99
- smithy 0.1.0 [aws_common built_collection built_value collection convert crypto fixnum http http_parser intl json_annotation meta path retry shelf typed_data xml]
- smithy_aws 0.1.1 [aws_common aws_signature_v4 built_collection built_value collection crclib http intl json_annotation meta path smithy xml]
- source_span 1.8.2 [collection path term_glyph]
- sqflite 2.0.2+1 [flutter sqflite_common path]
- sqflite_common 2.2.1+1 [synchronized path meta]
- stack_trace 1.10.0 [path]
- state_notifier 0.7.2+1 [meta]
- stream_channel 2.1.0 [async]
- stream_transform 2.0.0
- string_scanner 1.1.0 [charcode source_span]
- synchronized 3.0.0+2
- term_glyph 1.2.0
- timezone 0.8.0 [path]
- tuple 2.0.0 [quiver]
- typed_data 1.3.1 [collection]
- universal_io 2.0.4 [collection crypto meta typed_data]
- url_launcher_android 6.0.17 [flutter url_launcher_platform_interface]
- url_launcher_ios 6.0.17 [flutter url_launcher_platform_interface]
- url_launcher_linux 3.0.1 [flutter url_launcher_platform_interface]
- url_launcher_macos 3.0.1 [flutter url_launcher_platform_interface]
- url_launcher_platform_interface 2.1.0 [flutter plugin_platform_interface]
- url_launcher_web 2.0.11 [flutter flutter_web_plugins url_launcher_platform_interface]
- url_launcher_windows 3.0.1 [flutter url_launcher_platform_interface]
- uuid 3.0.6 [crypto]
- vector_math 2.1.2
- win32 2.7.0 [ffi]
- worker_bee 0.1.0 [async aws_common built_collection built_value collection js meta path stack_trace stream_channel stream_transform]
- xdg_directories 0.2.0+1 [meta path process]
- xml 6.1.0 [collection meta petitparser]
- yaml 3.1.1 [collection source_span string_scanner]

Device

iphone11 (physical device) and also iPhone 13 Pro Emulator running on a iMac

OS

15.5 (actual device)

CLI Version

N/A

Additional Context

No response

dnys1 commented 2 years ago

Hi @PfernFSU, thanks for trying out the dev-preview! I was able to isolate the cause of issue 1 and will have a fix out soon. I'll have a look at issue 2 afterwards. Cheers!

dnys1 commented 2 years ago

Hi @PfernFSU, I haven't been able to reproduce issue 2 yet. Are you using MultiAuth in DataStore? Could you run the app in Xcode and see if any error logs are bring produced in native code?

dnys1 commented 2 years ago

Could you also share the code you're using to sign out and clear DataStore?

PfernFSU commented 2 years ago

Hi @dnys1 - thank you again for your help. I did run it in XCode and saw something that may be an error. It is:

2022-08-06 17:43:25.126970-0400 Runner[80006:25079432] [db] _LSSchemaConfigureForStore failed with error Error Domain=NSOSStatusErrorDomain Code=-10817 "(null)" UserInfo={_LSFunction=_LSSchemaConfigureForStore, ExpectedSimulatorHash={length = 32, bytes = 0xc07f55ad aa617467 6e0bb79e c1a0d1c3 ... d5844058 fdbbc1ca }, _LSLine=405, WrongSimulatorHash={length = 32, bytes = 0x167f74be 8c26847b be1afbc4 d0f8127e ... 1d550b65 5d17b7d1 }}

I see the below error as well but believe it is expected because the user is signed out?

flutter: ⛔️   SEVERE: Emitted error
2022-08-06 17:43:25.639044-0400 Runner[80006:25080546] flutter: ERROR | _NativeAmplifyAuthCognito | Error fetching session for native plugin: NotAuthorizedException [Unauthenticated access is not supported for this identity pool., null, null]
2022-08-06 17:43:25.639310-0400 Runner[80006:25080546]

As far as the code to sign out, we do this:

  Future<void> signOut() {
    return authExceptionHandler(() async {
      await Amplify.Auth.signOut(
        options: const SignOutOptions(
          globalSignOut: true,
        ),
      );
      await Amplify.DataStore.clear();
    }());
  }

As far as using MultiAuth in the DataStore, I do not believe we are. I put my aws config in the original report if that helps? Here is how we configure everything:

  Future<void> _configureAmplify() async {
    try {
      await Amplify.addPlugins([
        AmplifyAPI(),
        AmplifyAuthCognito(),
        AmplifyDataStore(modelProvider: ModelProvider.instance),
      ]);
      await Amplify.configure(amplifyConfigStr);
    } on AmplifyAlreadyConfiguredException catch (e) {
      debugPrint('App already configured. Error: $e');
    }
    setState(() => _isAmplifyConfigured = true);
    FlutterNativeSplash.remove(); // clear splash
  }
}

Thanks again.

dnys1 commented 2 years ago

Hi @PfernFSU - my pleasure and thank you as well for your very detailed report and follow up. It's a huge help when going to look at these issues!

We've released a fix for issue 1 in the latest auth package!

I'm still working on reproducing issue 2. The error messages you posted look correct to me, since after calling DataStore.clear, DataStore will try to sync with the cloud. To do so, it needs credentials, but since you've just signed out, there are no credentials which is why the error is being thrown. This indicates to me also that credentials are being successfully cleared, since otherwise, we would not see that error message. It also means that DataStore.clear is successfully finishing, otherwise we would not see it try to access credentials. This makes it very difficult to guess why you could be seeing both credentials and DataStore not being cleared as expected.

PfernFSU commented 2 years ago

Hi @dnys1 - so we have done a ton of investigation on our side and I owe you a huge apology. Our riverpod state management was not correct and it was holding onto some of the old values. After we fix this, we no longer see the issue that was reported in #2. Once again, I am incredibly sorry to waste your time. And thank you again for fixing the first issue and being so responsive.

dnys1 commented 2 years ago

Honestly, it's been great working with you too, and I encourage you to always reach out if you face any issue whatsoever. It's great to know the ins and outs of how our customers use Amplify in real life and I always seem to learn something along the way :-) cheers!