diff --git a/.gitignore b/.gitignore index 968065b469..a062c2bc7a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,14 @@ .dart_tool/ .DS_Store build/ -ios/.generated/ +**/ios/.generated/ +**/android/.settings/ pubspec.lock Podfile.lock *.iml *.jar +Podfile.lock + # IDEs .idea/ diff --git a/packages/amplify_analytics_pinpoint/example/lib/main.dart b/packages/amplify_analytics_pinpoint/example/lib/main.dart index 88925a6056..0e69214cda 100644 --- a/packages/amplify_analytics_pinpoint/example/lib/main.dart +++ b/packages/amplify_analytics_pinpoint/example/lib/main.dart @@ -38,7 +38,7 @@ class _MyAppState extends State { // Configure analytics plugin AmplifyAnalyticsPinpointPlugin analyticsPlugin = new AmplifyAnalyticsPinpointPlugin(); - amplifyInstance.addPlugin(analyticsPlugin); + amplifyInstance.addPlugin(analyticsPlugin: [analyticsPlugin]); var isConfigured = await amplifyInstance.configure(amplifyconfig); try { diff --git a/packages/amplify_auth_cognito/.gitignore b/packages/amplify_auth_cognito/.gitignore new file mode 100644 index 0000000000..e9dc58d3d6 --- /dev/null +++ b/packages/amplify_auth_cognito/.gitignore @@ -0,0 +1,7 @@ +.DS_Store +.dart_tool/ + +.packages +.pub/ + +build/ diff --git a/packages/amplify_auth_cognito/.metadata b/packages/amplify_auth_cognito/.metadata new file mode 100644 index 0000000000..c59c04e367 --- /dev/null +++ b/packages/amplify_auth_cognito/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: 599566177736e6b30af922a8f06e8a260acafc36 + channel: master + +project_type: plugin diff --git a/packages/amplify_auth_cognito/CHANGELOG.md b/packages/amplify_auth_cognito/CHANGELOG.md new file mode 100644 index 0000000000..41cc7d8192 --- /dev/null +++ b/packages/amplify_auth_cognito/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.0.1 + +* TODO: Describe initial release. diff --git a/packages/amplify_auth_cognito/LICENSE b/packages/amplify_auth_cognito/LICENSE new file mode 100644 index 0000000000..19dc35b243 --- /dev/null +++ b/packages/amplify_auth_cognito/LICENSE @@ -0,0 +1,175 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. \ No newline at end of file diff --git a/packages/amplify_auth_cognito/README.md b/packages/amplify_auth_cognito/README.md new file mode 100644 index 0000000000..9df098d4e5 --- /dev/null +++ b/packages/amplify_auth_cognito/README.md @@ -0,0 +1,3 @@ +# amplify_auth_cognito + +The Amazon Cognito plugin for Amplify-Flutter diff --git a/packages/amplify_auth_cognito/android/.classpath b/packages/amplify_auth_cognito/android/.classpath new file mode 100644 index 0000000000..eb19361b57 --- /dev/null +++ b/packages/amplify_auth_cognito/android/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/packages/amplify_auth_cognito/android/.gitignore b/packages/amplify_auth_cognito/android/.gitignore new file mode 100644 index 0000000000..c6cbe562a4 --- /dev/null +++ b/packages/amplify_auth_cognito/android/.gitignore @@ -0,0 +1,8 @@ +*.iml +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures diff --git a/packages/amplify_auth_cognito/android/.project b/packages/amplify_auth_cognito/android/.project new file mode 100644 index 0000000000..b061f2dc81 --- /dev/null +++ b/packages/amplify_auth_cognito/android/.project @@ -0,0 +1,23 @@ + + + amplify_auth_cognito + Project android___ created by Buildship. + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.buildship.core.gradleprojectbuilder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.buildship.core.gradleprojectnature + + diff --git a/packages/amplify_auth_cognito/android/.settings/org.eclipse.buildship.core.prefs b/packages/amplify_auth_cognito/android/.settings/org.eclipse.buildship.core.prefs new file mode 100644 index 0000000000..4c33546741 --- /dev/null +++ b/packages/amplify_auth_cognito/android/.settings/org.eclipse.buildship.core.prefs @@ -0,0 +1,13 @@ +arguments= +auto.sync=false +build.scans.enabled=false +connection.gradle.distribution=GRADLE_DISTRIBUTION(VERSION(6.3)) +connection.project.dir= +eclipse.preferences.version=1 +gradle.user.home= +java.home=/Users/dnnoyes/.sdkman/candidates/java/current +jvm.arguments= +offline.mode=false +override.workspace.settings=true +show.console.view=true +show.executions.view=true diff --git a/packages/amplify_auth_cognito/android/build.gradle b/packages/amplify_auth_cognito/android/build.gradle new file mode 100644 index 0000000000..2c7dfe285c --- /dev/null +++ b/packages/amplify_auth_cognito/android/build.gradle @@ -0,0 +1,53 @@ +group 'com.amazonaws.amplify.amplify_auth_cognito' +version '1.0-SNAPSHOT' + +buildscript { + ext.kotlin_version = '1.3.50' + repositories { + google() + jcenter() + mavenCentral() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.5.0' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +rootProject.allprojects { + repositories { + google() + jcenter() + } +} + +apply plugin: 'com.android.library' +apply plugin: 'kotlin-android' + +android { + compileSdkVersion 28 + + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + } + defaultConfig { + minSdkVersion 16 + } + lintOptions { + disable 'InvalidPackage' + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + implementation 'com.amplifyframework:aws-auth-cognito:1.0.+' + testImplementation 'junit:junit:4.13' + testImplementation 'org.mockito:mockito-core:3.1.0' + testImplementation 'androidx.test:core:1.2.0' + testImplementation 'org.robolectric:robolectric:4.3.1' +} diff --git a/packages/amplify_auth_cognito/android/gradle.properties b/packages/amplify_auth_cognito/android/gradle.properties new file mode 100644 index 0000000000..38c8d4544f --- /dev/null +++ b/packages/amplify_auth_cognito/android/gradle.properties @@ -0,0 +1,4 @@ +org.gradle.jvmargs=-Xmx1536M +android.enableR8=true +android.useAndroidX=true +android.enableJetifier=true diff --git a/packages/amplify_auth_cognito/android/gradle/wrapper/gradle-wrapper.properties b/packages/amplify_auth_cognito/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000..01a286e96a --- /dev/null +++ b/packages/amplify_auth_cognito/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip diff --git a/packages/amplify_auth_cognito/android/settings.gradle b/packages/amplify_auth_cognito/android/settings.gradle new file mode 100644 index 0000000000..d53ec9dc31 --- /dev/null +++ b/packages/amplify_auth_cognito/android/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'amplify_auth_cognito' diff --git a/packages/amplify_auth_cognito/android/src/main/AndroidManifest.xml b/packages/amplify_auth_cognito/android/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..19fb19e0c8 --- /dev/null +++ b/packages/amplify_auth_cognito/android/src/main/AndroidManifest.xml @@ -0,0 +1,3 @@ + + diff --git a/packages/amplify_auth_cognito/android/src/main/kotlin/com/amazonaws/amplify/amplify_auth_cognito/AuthCognito.kt b/packages/amplify_auth_cognito/android/src/main/kotlin/com/amazonaws/amplify/amplify_auth_cognito/AuthCognito.kt new file mode 100644 index 0000000000..c777524ddb --- /dev/null +++ b/packages/amplify_auth_cognito/android/src/main/kotlin/com/amazonaws/amplify/amplify_auth_cognito/AuthCognito.kt @@ -0,0 +1,277 @@ +package com.amazonaws.amplify.amplify_auth_cognito + +import FlutterConfirmSignInRequest +import FlutterSignInRequest +import FlutterSignOutRequest +import android.app.Activity +import android.content.Context +import android.util.Log +import androidx.annotation.NonNull +import com.amazonaws.amplify.amplify_auth_cognito.types.* +import com.amazonaws.AmazonClientException +import com.amazonaws.AmazonServiceException +import com.amazonaws.amplify.amplify_auth_cognito.types.FlutterAuthFailureMessage +import com.amazonaws.amplify.amplify_auth_cognito.types.FlutterSignUpRequest +import com.amazonaws.amplify.amplify_auth_cognito.types.FlutterSignUpResult +import com.amazonaws.services.cognitoidentityprovider.model.* +import com.amplifyframework.auth.AuthException +import com.amplifyframework.auth.cognito.AWSCognitoAuthPlugin +import com.amplifyframework.auth.result.AuthSignInResult +import com.amplifyframework.auth.result.AuthSignUpResult +import com.amplifyframework.core.Amplify +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import io.flutter.embedding.engine.plugins.FlutterPlugin +import io.flutter.embedding.engine.plugins.activity.ActivityAware +import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding +import io.flutter.plugin.common.MethodCall +import io.flutter.plugin.common.MethodChannel +import io.flutter.plugin.common.MethodChannel.MethodCallHandler +import io.flutter.plugin.common.MethodChannel.Result +import io.flutter.plugin.common.PluginRegistry.Registrar + + +/** AuthCognito */ +public class AuthCognito : FlutterPlugin, ActivityAware, MethodCallHandler { + + private lateinit var channel: MethodChannel + private lateinit var context: Context + var gson = Gson() + private var mainActivity: Activity? = null + + override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) { + channel = MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(), "com.amazonaws.amplify/auth_cognito") + channel.setMethodCallHandler(this); + context = flutterPluginBinding.applicationContext; + Amplify.addPlugin(AWSCognitoAuthPlugin()) + Log.i("Amplify Flutter", "Added AuthCognito plugin") + } + + companion object { + @JvmStatic + fun registerWith(registrar: Registrar) { + val channel = MethodChannel(registrar.messenger(), "com.amazonaws.amplify/auth_cognito") + Amplify.addPlugin(AWSCognitoAuthPlugin()) + Log.i("Amplify Flutter", "Added AuthCognito plugin") + } + } + + override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) { + when (call.method) { + "signUp" -> + try { + onSignUp(result, (call.arguments as HashMap)["data"] as? HashMap) + } + catch (e: Exception) { + prepareError(result, e, FlutterAuthFailureMessage.CASTING.toString() ) + } + "confirmSignUp" -> + try { + onConfirmSignUp(result, (call.arguments as HashMap)["data"] as? HashMap) + } catch (e: Exception) { + result.error("AmplifyException", "Error casting confirmSignUp parameter map", e.message ) + } + "signIn" -> + try { + onSignIn(result, (call.arguments as HashMap)["data"] as? HashMap) + } catch (e: Exception) { + result.error("AmplifyException", "Error casting signIn parameter map", e.message ) + } + "confirmSignIn" -> + try { + onConfirmSignIn(result, (call.arguments as HashMap)["data"] as? HashMap) + } catch (e: Exception) { + result.error("AmplifyException", "Error casting confirmSignIn parameter map", e.message ) + } + "signOut" -> + try { + var args: HashMap = hashMapOf(); + if ((call.arguments as HashMap)["data"] != null) { + args = (call.arguments as HashMap)["data"] as HashMap + } + onSignOut(result, args); + } catch (e: Exception) { + result.error("AmplifyException", "Error casting signOut parameter map", e.message ) + } + else -> result.notImplemented() + } + } + + override fun onAttachedToActivity(binding: ActivityPluginBinding) { + this.mainActivity = binding.activity + } + + override fun onDetachedFromActivity() { + this.mainActivity = null + } + + override fun onDetachedFromActivityForConfigChanges() { + onDetachedFromActivity() + } + + override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) { + onAttachedToActivity(binding) + } + + override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) { + channel.setMethodCallHandler(null) + } + + private fun onSignUp (@NonNull flutterResult: Result, @NonNull request: HashMap?) { + if (FlutterSignUpRequest.validate(request)) { + + var req = FlutterSignUpRequest(request as HashMap); + try { + Amplify.Auth.signUp( + req.username, + req.password, + req.options, + { result -> this.mainActivity?.runOnUiThread({ prepareSignUpResult(flutterResult, result)}) }, + { error -> this.mainActivity?.runOnUiThread({ prepareError(flutterResult, error, FlutterAuthFailureMessage.SIGNUP.toString())}) } + ); + } catch(e: Exception) { + prepareError(flutterResult, e, FlutterAuthFailureMessage.SIGNUP.toString()) + } + } else { + prepareError(flutterResult, java.lang.Exception(FlutterAuthFailureMessage.MALFORMED.toString()), FlutterAuthFailureMessage.MALFORMED.toString()) + } + } + + private fun onConfirmSignUp(@NonNull flutterResult: Result, @NonNull request: HashMap?){ + if (FlutterConfirmSignUpRequest.validate(request)) { + var req = FlutterConfirmSignUpRequest(request as HashMap); + try { + Amplify.Auth.confirmSignUp( + req.userKey, + req.confirmationCode, + { result -> this.mainActivity?.runOnUiThread({ prepareSignUpResult(flutterResult, result) }) }, + { error -> this.mainActivity?.runOnUiThread({ prepareError(flutterResult, error, FlutterAuthFailureMessage.CONFIRM_SIGNUP.toString()) }) } + ) + } catch (e: Exception) { + prepareError(flutterResult, e, FlutterAuthFailureMessage.CONFIRM_SIGNUP.toString()) + } + } else { + prepareError(flutterResult, java.lang.Exception(FlutterAuthFailureMessage.MALFORMED.toString()), FlutterAuthFailureMessage.MALFORMED.toString()) + } + } + + private fun onSignIn (@NonNull flutterResult: Result, @NonNull request: HashMap?) { + if (FlutterSignInRequest.validate(request)) { + var req = FlutterSignInRequest(request as HashMap) + try { + Amplify.Auth.signIn( + req.username, + req.password, + { result -> this.mainActivity?.runOnUiThread({ prepareSignInResult(flutterResult, result) }) }, + { error -> this.mainActivity?.runOnUiThread({ prepareError(flutterResult, error, FlutterAuthFailureMessage.SIGNIN.toString()) }) } + ); + } catch (e: Exception) { + prepareError(flutterResult, e, FlutterAuthFailureMessage.SIGNIN.toString()) + } + } else { + prepareError(flutterResult, java.lang.Exception(FlutterAuthFailureMessage.MALFORMED.toString()), FlutterAuthFailureMessage.MALFORMED.toString()) + } + } + + private fun onConfirmSignIn (@NonNull flutterResult: Result, @NonNull request: HashMap?) { + if (FlutterConfirmSignInRequest.validate(request)) { + var req = FlutterConfirmSignInRequest(request as HashMap) + try { + Amplify.Auth.confirmSignIn( + req.confirmationCode, + { result -> this.mainActivity?.runOnUiThread({ prepareSignInResult(flutterResult, result)}) }, + { error -> this.mainActivity?.runOnUiThread({ prepareError(flutterResult, error, FlutterAuthFailureMessage.CONFIRM_SIGNIN.toString())}) } + ); + } catch(e: Exception) { + prepareError(flutterResult, e, FlutterAuthFailureMessage.CONFIRM_SIGNIN.toString()) + } + } else { + prepareError(flutterResult, java.lang.Exception(FlutterAuthFailureMessage.MALFORMED.toString()), FlutterAuthFailureMessage.MALFORMED.toString()) + } + } + + private fun onSignOut (@NonNull flutterResult: Result, @NonNull request: HashMap) { + var req = FlutterSignOutRequest(request) + try { + Amplify.Auth.signOut( + req.signOutOptions, + { -> this.mainActivity?.runOnUiThread({ prepareSignOutResult(flutterResult)}) }, + { error -> this.mainActivity?.runOnUiThread({ prepareError(flutterResult, error, FlutterAuthFailureMessage.SIGNOUT.toString())}) } + ); + } catch(e: Exception) { + prepareError(flutterResult, e, FlutterAuthFailureMessage.SIGNOUT.toString()) + } + } + + + private fun prepareError(@NonNull flutterResult: Result, @NonNull error: Exception, @NonNull msg: String) { + var errorMap: HashMap = HashMap(); + if (error is AuthException) { + when (error.cause) { + is InvalidParameterException -> errorMap.put("INVALID_PARAMETER", (error.cause as InvalidParameterException).errorMessage) + is UsernameExistsException -> errorMap.put("USERNAME_EXISTS", (error.cause as UsernameExistsException).errorMessage) + is AliasExistsException -> errorMap.put("ALIAS_EXISTS", (error.cause as AliasExistsException).errorMessage) + is CodeDeliveryFailureException -> errorMap.put("CODE_DELIVERY_FAILURE", (error.cause as CodeDeliveryFailureException).errorMessage) + is InternalErrorException -> errorMap.put("INTERNAL_ERROR", (error.cause as InternalErrorException).errorMessage) + is InvalidLambdaResponseException -> errorMap.put("INVALID_LAMBDA_RESPONSE", (error.cause as InvalidLambdaResponseException).errorMessage) + is InvalidPasswordException -> errorMap.put("INVALID_PASSWORD", (error.cause as InvalidPasswordException).errorMessage) + is NotAuthorizedException -> errorMap.put("NOT_AUTHORIZED", (error.cause as NotAuthorizedException).errorMessage) + is ResourceNotFoundException -> errorMap.put("RESOURCE_NOT_FOUND", (error.cause as ResourceNotFoundException).errorMessage) + is TooManyRequestsException -> errorMap.put("TOO_MANY_REQUESTS", (error.cause as TooManyRequestsException).errorMessage) + is UnexpectedLambdaException -> errorMap.put("UNEXPECTED_LAMBDA", (error.cause as UnexpectedLambdaException).errorMessage) + is UserLambdaValidationException -> errorMap.put("USER_LAMBDA_VALIDATION", (error.cause as UserLambdaValidationException).errorMessage) + is TooManyFailedAttemptsException -> errorMap.put("TOO_MANY_FAILED_REQUESTS", (error.cause as TooManyFailedAttemptsException).errorMessage) + is AmazonClientException -> errorMap.put("AMAZON_CLIENT_EXCEPTION", (error.cause as AmazonClientException).localizedMessage) + is AmazonServiceException -> errorMap.put("AMAZON_SERVICE_EXCEPTION", (error.cause as AmazonServiceException).localizedMessage) + else -> errorMap.put("UNKNOWN", "Unknown Auth Error.") + } + } + + var localizedError: String = ""; + var recoverySuggestion: String =""; + if (error is AuthException) { + recoverySuggestion = error.recoverySuggestion; + } + if (error.localizedMessage != null) { + localizedError = error.localizedMessage; + } + errorMap.put("PLATFORM_EXCEPTIONS" , mapOf( + "platform" to "Android", + "localizedError" to localizedError, + "recoverySuggestion" to recoverySuggestion, + "errorString" to error.toString() + )) + flutterResult.error("AmplifyException", msg, errorMap) + } + + private fun prepareSignUpResult(@NonNull flutterResult: Result, @NonNull result: AuthSignUpResult) { + var signUpData = FlutterSignUpResult(result); + flutterResult.success(signUpData.serializeToMap()); + } + + private fun prepareSignInResult(@NonNull flutterResult: Result, @NonNull result: AuthSignInResult) { + var signInData = FlutterSignInResult(result); + flutterResult.success(signInData.serializeToMap()); + } + + private fun prepareSignOutResult(@NonNull flutterResult: Result) { + var parsedResult = mutableMapOf(); + flutterResult.success(parsedResult); + } + + //convert a data class to a map + fun T.serializeToMap(): Map { + return convert() + } + + //convert a map to a data class + inline fun Map.toDataClass(): T { + return convert() + } + + //convert an object of type I to type O + inline fun I.convert(): O { + val json = gson.toJson(this) + return gson.fromJson(json, object : TypeToken() {}.type) + } +} diff --git a/packages/amplify_auth_cognito/android/src/main/kotlin/com/amazonaws/amplify/amplify_auth_cognito/types/FlutterAuthErrorMessage.kt b/packages/amplify_auth_cognito/android/src/main/kotlin/com/amazonaws/amplify/amplify_auth_cognito/types/FlutterAuthErrorMessage.kt new file mode 100644 index 0000000000..aabf3fed5d --- /dev/null +++ b/packages/amplify_auth_cognito/android/src/main/kotlin/com/amazonaws/amplify/amplify_auth_cognito/types/FlutterAuthErrorMessage.kt @@ -0,0 +1,39 @@ +package com.amazonaws.amplify.amplify_auth_cognito.types + +enum class FlutterAuthFailureMessage { + SIGNUP { + override fun toString(): String { + return "AMPLIFY_SIGNUP_FAILED" + } + }, + CASTING { + override fun toString(): String { + return "ERROR_CASTING_INPUT_IN_PLATFORM_CODE" + } + }, + CONFIRM_SIGNUP { + override fun toString(): String { + return "AMPLIFY_CONFIRM_SIGNUP_FAILED" + } + }, + SIGNIN { + override fun toString(): String { + return "AMPLIFY_SIGNIN_FAILED" + } + }, + CONFIRM_SIGNIN { + override fun toString(): String { + return "AMPLIFY_CONFIRM_SIGNIN_FAILED" + } + }, + SIGNOUT { + override fun toString(): String { + return "AMPLIFY_SIGNOUT_FAILED" + } + }, + MALFORMED { + override fun toString(): String { + return "AMPLIFY_REQUEST_MALFORMED" + } + } +} diff --git a/packages/amplify_auth_cognito/android/src/main/kotlin/com/amazonaws/amplify/amplify_auth_cognito/types/FlutterConfirmSignInRequest.kt b/packages/amplify_auth_cognito/android/src/main/kotlin/com/amazonaws/amplify/amplify_auth_cognito/types/FlutterConfirmSignInRequest.kt new file mode 100644 index 0000000000..c48dd4da35 --- /dev/null +++ b/packages/amplify_auth_cognito/android/src/main/kotlin/com/amazonaws/amplify/amplify_auth_cognito/types/FlutterConfirmSignInRequest.kt @@ -0,0 +1,16 @@ +data class FlutterConfirmSignInRequest(val map: HashMap) { + val confirmationCode: String = map["confirmationCode"] as String; + val providerOptions: HashMap? = map["providerOptions"] as HashMap?; + + companion object { + fun validate(req : HashMap?): Boolean { + var valid: Boolean = true; + if (req == null || req !is HashMap) { + valid = false; + } + return valid; + } + } + +} + diff --git a/packages/amplify_auth_cognito/android/src/main/kotlin/com/amazonaws/amplify/amplify_auth_cognito/types/FlutterConfirmSignUpRequest.kt b/packages/amplify_auth_cognito/android/src/main/kotlin/com/amazonaws/amplify/amplify_auth_cognito/types/FlutterConfirmSignUpRequest.kt new file mode 100644 index 0000000000..f5de4b2986 --- /dev/null +++ b/packages/amplify_auth_cognito/android/src/main/kotlin/com/amazonaws/amplify/amplify_auth_cognito/types/FlutterConfirmSignUpRequest.kt @@ -0,0 +1,25 @@ +package com.amazonaws.amplify.amplify_auth_cognito.types + +data class FlutterConfirmSignUpRequest(val map: HashMap) { + val userKey: String = map["userKey"] as String; + val confirmationCode: String = map["confirmationCode"] as String; + val providerOptions: HashMap? = map["providerOptions"] as HashMap?; + + companion object { + fun validate(req : HashMap?): Boolean { + var valid: Boolean = true; + if (req == null) { + valid = false; + } else { + if (!req.containsKey("userKey")) { + valid = false; + } + if (!req.containsKey("confirmationCode")) { + valid = false; + } + } + return valid; + } + } +} + diff --git a/packages/amplify_auth_cognito/android/src/main/kotlin/com/amazonaws/amplify/amplify_auth_cognito/types/FlutterSignInRequest.kt b/packages/amplify_auth_cognito/android/src/main/kotlin/com/amazonaws/amplify/amplify_auth_cognito/types/FlutterSignInRequest.kt new file mode 100644 index 0000000000..14e24163db --- /dev/null +++ b/packages/amplify_auth_cognito/android/src/main/kotlin/com/amazonaws/amplify/amplify_auth_cognito/types/FlutterSignInRequest.kt @@ -0,0 +1,15 @@ +data class FlutterSignInRequest(val map: HashMap) { + val username: String = map["username"] as String; + val password: String = map["password"] as String; + val providerOptions: HashMap? = map["providerOptions"] as HashMap?; + + companion object { + fun validate(req : HashMap?): Boolean { + var valid: Boolean = true; + if (req == null || req !is HashMap) { + valid = false; + } + return valid; + } + } +} diff --git a/packages/amplify_auth_cognito/android/src/main/kotlin/com/amazonaws/amplify/amplify_auth_cognito/types/FlutterSignInResult.kt b/packages/amplify_auth_cognito/android/src/main/kotlin/com/amazonaws/amplify/amplify_auth_cognito/types/FlutterSignInResult.kt new file mode 100644 index 0000000000..2004e8142f --- /dev/null +++ b/packages/amplify_auth_cognito/android/src/main/kotlin/com/amazonaws/amplify/amplify_auth_cognito/types/FlutterSignInResult.kt @@ -0,0 +1,23 @@ +package com.amazonaws.amplify.amplify_auth_cognito.types + +import com.amplifyframework.auth.result.AuthSignInResult +import com.google.gson.Gson + +data class FlutterSignInResult(private val raw: AuthSignInResult) { + val isSignedIn: Boolean = raw.isSignInComplete + val nextStep: Map = setNextStep(); + + private fun setNextStep(): Map { + val res: Map = emptyMap(); + + return mapOf( + "signInStep" to raw.nextStep.signInStep.toString(), + "additionalInfo" to Gson().toJson(raw.nextStep.additionalInfo), + "codeDeliveryDetails" to mapOf( + "destination" to (raw.nextStep.codeDeliveryDetails?.destination ?: ""), + "deliveryMedium" to (raw.nextStep.codeDeliveryDetails?.deliveryMedium ?: ""), + "attributeName" to (raw.nextStep.codeDeliveryDetails?.attributeName ?: "") + ) + ) + } +} \ No newline at end of file diff --git a/packages/amplify_auth_cognito/android/src/main/kotlin/com/amazonaws/amplify/amplify_auth_cognito/types/FlutterSignOutRequest.kt b/packages/amplify_auth_cognito/android/src/main/kotlin/com/amazonaws/amplify/amplify_auth_cognito/types/FlutterSignOutRequest.kt new file mode 100644 index 0000000000..4065e9227b --- /dev/null +++ b/packages/amplify_auth_cognito/android/src/main/kotlin/com/amazonaws/amplify/amplify_auth_cognito/types/FlutterSignOutRequest.kt @@ -0,0 +1,14 @@ +import com.amplifyframework.auth.options.AuthSignOutOptions; + +data class FlutterSignOutRequest(val map: HashMap) { + var signOutOptions: AuthSignOutOptions = setOptions() + val providerOptions: HashMap? = map["providerOptions"] as HashMap?; + + fun setOptions(): AuthSignOutOptions { + var globalSignOut: Boolean = false; + if (providerOptions != null && providerOptions.get("globalSignOut") != null) { + globalSignOut = providerOptions.get("globalSignOut") as Boolean; + } + return AuthSignOutOptions.builder().globalSignOut(globalSignOut).build() + } +} diff --git a/packages/amplify_auth_cognito/android/src/main/kotlin/com/amazonaws/amplify/amplify_auth_cognito/types/FlutterSignUpRequest.kt b/packages/amplify_auth_cognito/android/src/main/kotlin/com/amazonaws/amplify/amplify_auth_cognito/types/FlutterSignUpRequest.kt new file mode 100644 index 0000000000..2329947a33 --- /dev/null +++ b/packages/amplify_auth_cognito/android/src/main/kotlin/com/amazonaws/amplify/amplify_auth_cognito/types/FlutterSignUpRequest.kt @@ -0,0 +1,94 @@ +package com.amazonaws.amplify.amplify_auth_cognito.types + +import androidx.annotation.NonNull +import com.amplifyframework.auth.AuthUserAttribute +import com.amplifyframework.auth.AuthUserAttributeKey +import com.amplifyframework.auth.options.AuthSignUpOptions +import java.lang.reflect.Method + +data class FlutterSignUpRequest(val map: HashMap) { + var standardAttributes: Array = arrayOf("address", "birthdate", "email", "family_name", "gender", "given_name", "locale", "middle_name", "name", "nickname", "phone_number", "preferred_username", "picture", "profile", "updated_at", "website", "zoneinfo") + val username: String = setUserName(map); + val password: String = map["password"] as String; + val options: AuthSignUpOptions = formatOptions(map["options"] as HashMap); + + private fun setUserName(@NonNull request: HashMap): String { + var username: String = ""; + if (request.containsKey("options")) { + var options = request["options"] as HashMap; + var userAttributes = options["userAttributes"] as HashMap; + if (options != null && options.containsKey("usernameAttribute")) { + when (options["usernameAttribute"]) { + "email" -> { + username = userAttributes["email"] as String; + } + "phone_number" -> { + username = userAttributes["phone_number"] as String; + } + } + } else { + username = request["username"] as String; + } + } else if (request.containsKey("username")) { + username = request["username"] as String; + } + return username; + }; + + private fun formatOptions(@NonNull rawOptions: HashMap): AuthSignUpOptions { + var options: AuthSignUpOptions.Builder<*> = AuthSignUpOptions.builder(); + var authUserAttributes: MutableList = mutableListOf(); + var attributeMethods = AuthUserAttributeKey::class.java.declaredMethods; + var validationData = rawOptions["validationData"]; + + (rawOptions["userAttributes"] as HashMap).forEach { (key, value) -> + var keyCopy: String = key; + if(!standardAttributes.contains(keyCopy)){ + if (!key.startsWith("custom:")){ + keyCopy = "custom:" + keyCopy; + } + authUserAttributes.add(AuthUserAttribute(AuthUserAttributeKey.custom(keyCopy), value)) + } else { + var t: Method = attributeMethods.asIterable().find { it.name.equals(convertSnakeToCamel(key)) } as Method; + var attr: AuthUserAttributeKey = t.invoke(null) as AuthUserAttributeKey; + authUserAttributes.add(AuthUserAttribute(attr, value)); + } + } + options.userAttributes(authUserAttributes); + //TODO: Add validationData + return options.build(); + } + + // Amplify Android expects camel case, while iOS expects snake. So at least one plugin implementation should convert. + private fun convertSnakeToCamel(@NonNull string: String): String { + val camelCase = StringBuilder() + var prevChar = '$' + string.forEach { + if(prevChar.equals('_')){ + camelCase.append(it.toUpperCase()) + }else if(!it.equals('_')){ + camelCase.append(it) + } + prevChar = it + } + return camelCase.toString(); + } + + companion object { + fun validate(req : HashMap?): Boolean { + var valid: Boolean = true; + if (req == null) { + valid = false; + } + if (!(req?.get("options") as HashMap).containsKey("userAttributes")) { + valid = false; + } + if (!req.containsKey("password")) { + valid = false; + } + return valid; + } + } + +} + diff --git a/packages/amplify_auth_cognito/android/src/main/kotlin/com/amazonaws/amplify/amplify_auth_cognito/types/FlutterSignUpResult.kt b/packages/amplify_auth_cognito/android/src/main/kotlin/com/amazonaws/amplify/amplify_auth_cognito/types/FlutterSignUpResult.kt new file mode 100644 index 0000000000..53054a3696 --- /dev/null +++ b/packages/amplify_auth_cognito/android/src/main/kotlin/com/amazonaws/amplify/amplify_auth_cognito/types/FlutterSignUpResult.kt @@ -0,0 +1,25 @@ +package com.amazonaws.amplify.amplify_auth_cognito.types + +import com.amplifyframework.auth.result.AuthSignUpResult +import com.google.gson.Gson + + + +data class FlutterSignUpResult(private val raw: AuthSignUpResult) { + val isSignUpComplete: Boolean = raw.isSignUpComplete + val nextStep: Map = setNextStep(); + + private fun setNextStep(): Map { + val res: Map = emptyMap(); + + return mapOf( + "signUpStep" to raw.nextStep.signUpStep.toString(), + "additionalInfo" to Gson().toJson(raw.nextStep.additionalInfo), + "codeDeliveryDetails" to mapOf( + "destination" to (raw.nextStep.codeDeliveryDetails?.destination ?: ""), + "deliveryMedium" to (raw.nextStep.codeDeliveryDetails?.deliveryMedium ?: ""), + "attributeName" to (raw.nextStep.codeDeliveryDetails?.attributeName ?: "") + ) + ) + } +} \ No newline at end of file diff --git a/packages/amplify_auth_cognito/android/src/test/AuthCognitoTest.kt b/packages/amplify_auth_cognito/android/src/test/AuthCognitoTest.kt new file mode 100644 index 0000000000..49e6bfd2ef --- /dev/null +++ b/packages/amplify_auth_cognito/android/src/test/AuthCognitoTest.kt @@ -0,0 +1,14 @@ +package com.amazonaws.amplify.amplify_auth_cognito + +import io.flutter.plugin.common.MethodCall +import io.flutter.plugin.common.MethodChannel.Result +import org.junit.Test +import org.mockito.Mockito.* + +class AuthCognitoTest { + @Test + fun onTestRun() { + print("Hello, this is a test") + assertTrue(false) + } +} \ No newline at end of file diff --git a/packages/amplify_auth_cognito/example/.gitignore b/packages/amplify_auth_cognito/example/.gitignore new file mode 100644 index 0000000000..43414ac54f --- /dev/null +++ b/packages/amplify_auth_cognito/example/.gitignore @@ -0,0 +1,60 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Web related +lib/generated_plugin_registrant.dart + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Exceptions to above rules. +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages + +#amplify +amplify/\#current-cloud-backend +amplify/.config/local-* +amplify/mock-data +amplify/backend/amplify-meta.json +amplify/backend/awscloudformation +build/ +dist/ +node_modules/ +aws-exports.js +awsconfiguration.json +amplifyconfiguration.json +amplify-build-config.json +amplify-gradle-config.json +amplifytools.xcconfig \ No newline at end of file diff --git a/packages/amplify_auth_cognito/example/.metadata b/packages/amplify_auth_cognito/example/.metadata new file mode 100644 index 0000000000..2b7e4c10fb --- /dev/null +++ b/packages/amplify_auth_cognito/example/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: 599566177736e6b30af922a8f06e8a260acafc36 + channel: master + +project_type: app diff --git a/packages/amplify_auth_cognito/example/README.md b/packages/amplify_auth_cognito/example/README.md new file mode 100644 index 0000000000..1ce7e917ca --- /dev/null +++ b/packages/amplify_auth_cognito/example/README.md @@ -0,0 +1,16 @@ +# amplify_auth_cognito_example + +Demonstrates how to use the amplify_auth_cognito plugin. + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) + +For help getting started with Flutter, view our +[online documentation](https://flutter.dev/docs), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/packages/amplify_auth_cognito/example/amplify/.config/project-config.json b/packages/amplify_auth_cognito/example/amplify/.config/project-config.json new file mode 100644 index 0000000000..15b5dc0174 --- /dev/null +++ b/packages/amplify_auth_cognito/example/amplify/.config/project-config.json @@ -0,0 +1,13 @@ +{ + "projectName": "flutterauthrefactor", + "version": "3.0", + "frontend": "flutter", + "flutter": { + "config": { + "ResDir": "./lib/" + } + }, + "providers": [ + "awscloudformation" + ] +} \ No newline at end of file diff --git a/packages/amplify_auth_cognito/example/amplify/backend/auth/flutterauthrefactord017496f/flutterauthrefactord017496f-cloudformation-template.yml b/packages/amplify_auth_cognito/example/amplify/backend/auth/flutterauthrefactord017496f/flutterauthrefactord017496f-cloudformation-template.yml new file mode 100644 index 0000000000..7693fca395 --- /dev/null +++ b/packages/amplify_auth_cognito/example/amplify/backend/auth/flutterauthrefactord017496f/flutterauthrefactord017496f-cloudformation-template.yml @@ -0,0 +1,367 @@ +AWSTemplateFormatVersion: 2010-09-09 + +Parameters: + env: + Type: String + authRoleArn: + Type: String + unauthRoleArn: + Type: String + + + + + identityPoolName: + Type: String + + allowUnauthenticatedIdentities: + Type: String + + resourceNameTruncated: + Type: String + + userPoolName: + Type: String + + autoVerifiedAttributes: + Type: CommaDelimitedList + + mfaConfiguration: + Type: String + + mfaTypes: + Type: CommaDelimitedList + + smsAuthenticationMessage: + Type: String + + smsVerificationMessage: + Type: String + + emailVerificationSubject: + Type: String + + emailVerificationMessage: + Type: String + + defaultPasswordPolicy: + Type: String + + passwordPolicyMinLength: + Type: Number + + passwordPolicyCharacters: + Type: CommaDelimitedList + + requiredAttributes: + Type: CommaDelimitedList + + userpoolClientGenerateSecret: + Type: String + + userpoolClientRefreshTokenValidity: + Type: Number + + userpoolClientWriteAttributes: + Type: CommaDelimitedList + + userpoolClientReadAttributes: + Type: CommaDelimitedList + + userpoolClientLambdaRole: + Type: String + + userpoolClientSetAttributes: + Type: String + + sharedId: + Type: String + + resourceName: + Type: String + + authSelections: + Type: String + + useDefault: + Type: String + + userPoolGroupList: + Type: CommaDelimitedList + + dependsOn: + Type: CommaDelimitedList + +Conditions: + ShouldNotCreateEnvResources: !Equals [ !Ref env, NONE ] + +Resources: + + + # BEGIN SNS ROLE RESOURCE + SNSRole: + # Created to allow the UserPool SMS Config to publish via the Simple Notification Service during MFA Process + Type: AWS::IAM::Role + Properties: + RoleName: !If [ShouldNotCreateEnvResources, 'flutted017496f_sns-role', !Join ['',[ 'sns', 'd017496f', !Select [3, !Split ['-', !Ref 'AWS::StackName']], '-', !Ref env]]] + AssumeRolePolicyDocument: + Version: "2012-10-17" + Statement: + - Sid: "" + Effect: "Allow" + Principal: + Service: "cognito-idp.amazonaws.com" + Action: + - "sts:AssumeRole" + Condition: + StringEquals: + sts:ExternalId: flutted017496f_role_external_id + Policies: + - + PolicyName: flutted017496f-sns-policy + PolicyDocument: + Version: "2012-10-17" + Statement: + - + Effect: "Allow" + Action: + - "sns:Publish" + Resource: "*" + # BEGIN USER POOL RESOURCES + UserPool: + # Created upon user selection + # Depends on SNS Role for Arn if MFA is enabled + Type: AWS::Cognito::UserPool + UpdateReplacePolicy: Retain + Properties: + UserPoolName: !If [ShouldNotCreateEnvResources, !Ref userPoolName, !Join ['',[!Ref userPoolName, '-', !Ref env]]] + + Schema: + + - + Name: email + Required: true + Mutable: true + + + + + AutoVerifiedAttributes: !Ref autoVerifiedAttributes + + + EmailVerificationMessage: !Ref emailVerificationMessage + EmailVerificationSubject: !Ref emailVerificationSubject + + Policies: + PasswordPolicy: + MinimumLength: !Ref passwordPolicyMinLength + RequireLowercase: false + RequireNumbers: false + RequireSymbols: false + RequireUppercase: false + + MfaConfiguration: !Ref mfaConfiguration + SmsVerificationMessage: !Ref smsVerificationMessage + SmsConfiguration: + SnsCallerArn: !GetAtt SNSRole.Arn + ExternalId: flutted017496f_role_external_id + + + UserPoolClientWeb: + # Created provide application access to user pool + # Depends on UserPool for ID reference + Type: "AWS::Cognito::UserPoolClient" + Properties: + ClientName: flutted017496f_app_clientWeb + + RefreshTokenValidity: !Ref userpoolClientRefreshTokenValidity + UserPoolId: !Ref UserPool + DependsOn: UserPool + UserPoolClient: + # Created provide application access to user pool + # Depends on UserPool for ID reference + Type: "AWS::Cognito::UserPoolClient" + Properties: + ClientName: flutted017496f_app_client + + GenerateSecret: !Ref userpoolClientGenerateSecret + RefreshTokenValidity: !Ref userpoolClientRefreshTokenValidity + UserPoolId: !Ref UserPool + DependsOn: UserPool + # BEGIN USER POOL LAMBDA RESOURCES + UserPoolClientRole: + # Created to execute Lambda which gets userpool app client config values + Type: 'AWS::IAM::Role' + Properties: + RoleName: !If [ShouldNotCreateEnvResources, !Ref userpoolClientLambdaRole, !Join ['',['upClientLambdaRole', 'd017496f', !Select [3, !Split ['-', !Ref 'AWS::StackName']], '-', !Ref env]]] + AssumeRolePolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Principal: + Service: + - lambda.amazonaws.com + Action: + - 'sts:AssumeRole' + DependsOn: UserPoolClient + UserPoolClientLambda: + # Lambda which gets userpool app client config values + # Depends on UserPool for id + # Depends on UserPoolClientRole for role ARN + Type: 'AWS::Lambda::Function' + Properties: + Code: + ZipFile: !Join + - |+ + - - 'const response = require(''cfn-response'');' + - 'const aws = require(''aws-sdk'');' + - 'const identity = new aws.CognitoIdentityServiceProvider();' + - 'exports.handler = (event, context, callback) => {' + - ' if (event.RequestType == ''Delete'') { ' + - ' response.send(event, context, response.SUCCESS, {})' + - ' }' + - ' if (event.RequestType == ''Update'' || event.RequestType == ''Create'') {' + - ' const params = {' + - ' ClientId: event.ResourceProperties.clientId,' + - ' UserPoolId: event.ResourceProperties.userpoolId' + - ' };' + - ' identity.describeUserPoolClient(params).promise()' + - ' .then((res) => {' + - ' response.send(event, context, response.SUCCESS, {''appSecret'': res.UserPoolClient.ClientSecret});' + - ' })' + - ' .catch((err) => {' + - ' response.send(event, context, response.FAILED, {err});' + - ' });' + - ' }' + - '};' + Handler: index.handler + Runtime: nodejs10.x + Timeout: '300' + Role: !GetAtt + - UserPoolClientRole + - Arn + DependsOn: UserPoolClientRole + UserPoolClientLambdaPolicy: + # Sets userpool policy for the role that executes the Userpool Client Lambda + # Depends on UserPool for Arn + # Marked as depending on UserPoolClientRole for easier to understand CFN sequencing + Type: 'AWS::IAM::Policy' + Properties: + PolicyName: flutted017496f_userpoolclient_lambda_iam_policy + Roles: + - !Ref UserPoolClientRole + PolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Action: + - 'cognito-idp:DescribeUserPoolClient' + Resource: !GetAtt UserPool.Arn + DependsOn: UserPoolClientLambda + UserPoolClientLogPolicy: + # Sets log policy for the role that executes the Userpool Client Lambda + # Depends on UserPool for Arn + # Marked as depending on UserPoolClientLambdaPolicy for easier to understand CFN sequencing + Type: 'AWS::IAM::Policy' + Properties: + PolicyName: flutted017496f_userpoolclient_lambda_log_policy + Roles: + - !Ref UserPoolClientRole + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - 'logs:CreateLogGroup' + - 'logs:CreateLogStream' + - 'logs:PutLogEvents' + Resource: !Sub + - arn:aws:logs:${region}:${account}:log-group:/aws/lambda/${lambda}:log-stream:* + - { region: !Ref "AWS::Region", account: !Ref "AWS::AccountId", lambda: !Ref UserPoolClientLambda} + DependsOn: UserPoolClientLambdaPolicy + UserPoolClientInputs: + # Values passed to Userpool client Lambda + # Depends on UserPool for Id + # Depends on UserPoolClient for Id + # Marked as depending on UserPoolClientLambdaPolicy for easier to understand CFN sequencing + Type: 'Custom::LambdaCallout' + Properties: + ServiceToken: !GetAtt UserPoolClientLambda.Arn + clientId: !Ref UserPoolClient + userpoolId: !Ref UserPool + DependsOn: UserPoolClientLogPolicy + + + + + + + + # BEGIN IDENTITY POOL RESOURCES + + + IdentityPool: + # Always created + Type: AWS::Cognito::IdentityPool + Properties: + IdentityPoolName: !If [ShouldNotCreateEnvResources, 'flutterauthrefactord017496f_identitypool_d017496f', !Join ['',['flutterauthrefactord017496f_identitypool_d017496f', '__', !Ref env]]] + + CognitoIdentityProviders: + - ClientId: !Ref UserPoolClient + ProviderName: !Sub + - cognito-idp.${region}.amazonaws.com/${client} + - { region: !Ref "AWS::Region", client: !Ref UserPool} + - ClientId: !Ref UserPoolClientWeb + ProviderName: !Sub + - cognito-idp.${region}.amazonaws.com/${client} + - { region: !Ref "AWS::Region", client: !Ref UserPool} + + AllowUnauthenticatedIdentities: !Ref allowUnauthenticatedIdentities + + + DependsOn: UserPoolClientInputs + + + IdentityPoolRoleMap: + # Created to map Auth and Unauth roles to the identity pool + # Depends on Identity Pool for ID ref + Type: AWS::Cognito::IdentityPoolRoleAttachment + Properties: + IdentityPoolId: !Ref IdentityPool + Roles: + unauthenticated: !Ref unauthRoleArn + authenticated: !Ref authRoleArn + DependsOn: IdentityPool + + +Outputs : + + IdentityPoolId: + Value: !Ref 'IdentityPool' + Description: Id for the identity pool + IdentityPoolName: + Value: !GetAtt IdentityPool.Name + + + + + UserPoolId: + Value: !Ref 'UserPool' + Description: Id for the user pool + UserPoolName: + Value: !Ref userPoolName + AppClientIDWeb: + Value: !Ref 'UserPoolClientWeb' + Description: The user pool app client id for web + AppClientID: + Value: !Ref 'UserPoolClient' + Description: The user pool app client id + AppClientSecret: + Value: !GetAtt UserPoolClientInputs.appSecret + + + + + + + diff --git a/packages/amplify_auth_cognito/example/amplify/backend/auth/flutterauthrefactord017496f/parameters.json b/packages/amplify_auth_cognito/example/amplify/backend/auth/flutterauthrefactord017496f/parameters.json new file mode 100644 index 0000000000..a619200c83 --- /dev/null +++ b/packages/amplify_auth_cognito/example/amplify/backend/auth/flutterauthrefactord017496f/parameters.json @@ -0,0 +1,51 @@ +{ + "identityPoolName": "flutterauthrefactord017496f_identitypool_d017496f", + "allowUnauthenticatedIdentities": false, + "resourceNameTruncated": "flutted017496f", + "userPoolName": "flutterauthrefactord017496f_userpool_d017496f", + "autoVerifiedAttributes": [ + "email" + ], + "mfaConfiguration": "OFF", + "mfaTypes": [ + "SMS Text Message" + ], + "smsAuthenticationMessage": "Your authentication code is {####}", + "smsVerificationMessage": "Your verification code is {####}", + "emailVerificationSubject": "Your verification code", + "emailVerificationMessage": "Your verification code is {####}", + "defaultPasswordPolicy": false, + "passwordPolicyMinLength": 8, + "passwordPolicyCharacters": [], + "requiredAttributes": [ + "email" + ], + "userpoolClientGenerateSecret": true, + "userpoolClientRefreshTokenValidity": 30, + "userpoolClientWriteAttributes": [ + "email" + ], + "userpoolClientReadAttributes": [ + "email" + ], + "userpoolClientLambdaRole": "flutted017496f_userpoolclient_lambda_role", + "userpoolClientSetAttributes": false, + "sharedId": "d017496f", + "resourceName": "flutterauthrefactord017496f", + "authSelections": "identityPoolAndUserPool", + "authRoleArn": { + "Fn::GetAtt": [ + "AuthRole", + "Arn" + ] + }, + "unauthRoleArn": { + "Fn::GetAtt": [ + "UnauthRole", + "Arn" + ] + }, + "useDefault": "default", + "userPoolGroupList": [], + "dependsOn": [] +} \ No newline at end of file diff --git a/packages/amplify_auth_cognito/example/amplify/backend/auth/fluttoauth4b399c0d4b399c0d/fluttoauth4b399c0d4b399c0d-cloudformation-template.yml b/packages/amplify_auth_cognito/example/amplify/backend/auth/fluttoauth4b399c0d4b399c0d/fluttoauth4b399c0d4b399c0d-cloudformation-template.yml new file mode 100644 index 0000000000..81f9d124b1 --- /dev/null +++ b/packages/amplify_auth_cognito/example/amplify/backend/auth/fluttoauth4b399c0d4b399c0d/fluttoauth4b399c0d4b399c0d-cloudformation-template.yml @@ -0,0 +1,534 @@ +AWSTemplateFormatVersion: 2010-09-09 + +Parameters: + env: + Type: String + authRoleArn: + Type: String + unauthRoleArn: + Type: String + + + + + identityPoolName: + Type: String + + allowUnauthenticatedIdentities: + Type: String + + resourceNameTruncated: + Type: String + + userPoolName: + Type: String + + autoVerifiedAttributes: + Type: CommaDelimitedList + + mfaConfiguration: + Type: String + + mfaTypes: + Type: CommaDelimitedList + + smsAuthenticationMessage: + Type: String + + smsVerificationMessage: + Type: String + + emailVerificationSubject: + Type: String + + emailVerificationMessage: + Type: String + + defaultPasswordPolicy: + Type: String + + passwordPolicyMinLength: + Type: Number + + passwordPolicyCharacters: + Type: CommaDelimitedList + + requiredAttributes: + Type: CommaDelimitedList + + userpoolClientGenerateSecret: + Type: String + + userpoolClientRefreshTokenValidity: + Type: Number + + userpoolClientWriteAttributes: + Type: CommaDelimitedList + + userpoolClientReadAttributes: + Type: CommaDelimitedList + + userpoolClientLambdaRole: + Type: String + + userpoolClientSetAttributes: + Type: String + + useDefault: + Type: String + + authSelections: + Type: String + + resourceName: + Type: String + + thirdPartyAuth: + Type: String + + userPoolGroups: + Type: String + + adminQueries: + Type: String + + triggers: + Type: String + + hostedUI: + Type: String + + userPoolGroupList: + Type: CommaDelimitedList + + parentStack: + Type: String + + permissions: + Type: CommaDelimitedList + + dependsOn: + Type: CommaDelimitedList + +Conditions: + ShouldNotCreateEnvResources: !Equals [ !Ref env, NONE ] + +Resources: + + + # BEGIN SNS ROLE RESOURCE + SNSRole: + # Created to allow the UserPool SMS Config to publish via the Simple Notification Service during MFA Process + Type: AWS::IAM::Role + Properties: + RoleName: !If [ShouldNotCreateEnvResources, 'flutto4b399c0d_sns-role', !Join ['',[ 'sns', 'undefined', !Select [3, !Split ['-', !Ref 'AWS::StackName']], '-', !Ref env]]] + AssumeRolePolicyDocument: + Version: "2012-10-17" + Statement: + - Sid: "" + Effect: "Allow" + Principal: + Service: "cognito-idp.amazonaws.com" + Action: + - "sts:AssumeRole" + Condition: + StringEquals: + sts:ExternalId: flutto4b399c0d_role_external_id + Policies: + - + PolicyName: flutto4b399c0d-sns-policy + PolicyDocument: + Version: "2012-10-17" + Statement: + - + Effect: "Allow" + Action: + - "sns:Publish" + Resource: "*" + # BEGIN USER POOL RESOURCES + UserPool: + # Created upon user selection + # Depends on SNS Role for Arn if MFA is enabled + Type: AWS::Cognito::UserPool + UpdateReplacePolicy: Retain + Properties: + UserPoolName: !If [ShouldNotCreateEnvResources, !Ref userPoolName, !Join ['',[!Ref userPoolName, '-', !Ref env]]] + + Schema: + + - + Name: email + Required: true + Mutable: true + + - + Name: phone_number + Required: true + Mutable: true + + + + + AutoVerifiedAttributes: !Ref autoVerifiedAttributes + + + EmailVerificationMessage: !Ref emailVerificationMessage + EmailVerificationSubject: !Ref emailVerificationSubject + + Policies: + PasswordPolicy: + MinimumLength: !Ref passwordPolicyMinLength + RequireLowercase: false + RequireNumbers: false + RequireSymbols: false + RequireUppercase: false + + MfaConfiguration: !Ref mfaConfiguration + SmsVerificationMessage: !Ref smsVerificationMessage + SmsConfiguration: + SnsCallerArn: !GetAtt SNSRole.Arn + ExternalId: flutto4b399c0d_role_external_id + + DependsOn: SNSRole + + + + + + + + + + + + # Updating lambda role with permissions to Cognito + + + UserPoolClientWeb: + # Created provide application access to user pool + # Depends on UserPool for ID reference + Type: "AWS::Cognito::UserPoolClient" + Properties: + ClientName: flutto4b399c0d_app_clientWeb + + RefreshTokenValidity: !Ref userpoolClientRefreshTokenValidity + UserPoolId: !Ref UserPool + DependsOn: UserPool + UserPoolClient: + # Created provide application access to user pool + # Depends on UserPool for ID reference + Type: "AWS::Cognito::UserPoolClient" + Properties: + ClientName: flutto4b399c0d_app_client + + GenerateSecret: !Ref userpoolClientGenerateSecret + RefreshTokenValidity: !Ref userpoolClientRefreshTokenValidity + UserPoolId: !Ref UserPool + DependsOn: UserPool + # BEGIN USER POOL LAMBDA RESOURCES + UserPoolClientRole: + # Created to execute Lambda which gets userpool app client config values + Type: 'AWS::IAM::Role' + Properties: + RoleName: !If [ShouldNotCreateEnvResources, !Ref userpoolClientLambdaRole, !Join ['',['upClientLambdaRole', 'undefined', !Select [3, !Split ['-', !Ref 'AWS::StackName']], '-', !Ref env]]] + AssumeRolePolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Principal: + Service: + - lambda.amazonaws.com + Action: + - 'sts:AssumeRole' + DependsOn: UserPoolClient + UserPoolClientLambda: + # Lambda which gets userpool app client config values + # Depends on UserPool for id + # Depends on UserPoolClientRole for role ARN + Type: 'AWS::Lambda::Function' + Properties: + Code: + ZipFile: !Join + - |+ + - - 'const response = require(''cfn-response'');' + - 'const aws = require(''aws-sdk'');' + - 'const identity = new aws.CognitoIdentityServiceProvider();' + - 'exports.handler = (event, context, callback) => {' + - ' if (event.RequestType == ''Delete'') { ' + - ' response.send(event, context, response.SUCCESS, {})' + - ' }' + - ' if (event.RequestType == ''Update'' || event.RequestType == ''Create'') {' + - ' const params = {' + - ' ClientId: event.ResourceProperties.clientId,' + - ' UserPoolId: event.ResourceProperties.userpoolId' + - ' };' + - ' identity.describeUserPoolClient(params).promise()' + - ' .then((res) => {' + - ' response.send(event, context, response.SUCCESS, {''appSecret'': res.UserPoolClient.ClientSecret});' + - ' })' + - ' .catch((err) => {' + - ' response.send(event, context, response.FAILED, {err});' + - ' });' + - ' }' + - '};' + Handler: index.handler + Runtime: nodejs10.x + Timeout: '300' + Role: !GetAtt + - UserPoolClientRole + - Arn + DependsOn: UserPoolClientRole + UserPoolClientLambdaPolicy: + # Sets userpool policy for the role that executes the Userpool Client Lambda + # Depends on UserPool for Arn + # Marked as depending on UserPoolClientRole for easier to understand CFN sequencing + Type: 'AWS::IAM::Policy' + Properties: + PolicyName: flutto4b399c0d_userpoolclient_lambda_iam_policy + Roles: + - !Ref UserPoolClientRole + PolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Action: + - 'cognito-idp:DescribeUserPoolClient' + Resource: !GetAtt UserPool.Arn + DependsOn: UserPoolClientLambda + UserPoolClientLogPolicy: + # Sets log policy for the role that executes the Userpool Client Lambda + # Depends on UserPool for Arn + # Marked as depending on UserPoolClientLambdaPolicy for easier to understand CFN sequencing + Type: 'AWS::IAM::Policy' + Properties: + PolicyName: flutto4b399c0d_userpoolclient_lambda_log_policy + Roles: + - !Ref UserPoolClientRole + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - 'logs:CreateLogGroup' + - 'logs:CreateLogStream' + - 'logs:PutLogEvents' + Resource: !Sub + - arn:aws:logs:${region}:${account}:log-group:/aws/lambda/${lambda}:log-stream:* + - { region: !Ref "AWS::Region", account: !Ref "AWS::AccountId", lambda: !Ref UserPoolClientLambda} + DependsOn: UserPoolClientLambdaPolicy + UserPoolClientInputs: + # Values passed to Userpool client Lambda + # Depends on UserPool for Id + # Depends on UserPoolClient for Id + # Marked as depending on UserPoolClientLambdaPolicy for easier to understand CFN sequencing + Type: 'Custom::LambdaCallout' + Properties: + ServiceToken: !GetAtt UserPoolClientLambda.Arn + clientId: !Ref UserPoolClient + userpoolId: !Ref UserPool + DependsOn: UserPoolClientLogPolicy + + + + + + + # BEGIN MFA LAMBDA RESOURCES + MFALambdaRole: + # Created to execute Lambda which sets MFA config values + Type: 'AWS::IAM::Role' + Properties: + RoleName: !If [ShouldNotCreateEnvResources, 'flutto4b399c0d_totp_lambda_role', !Join ['',['flutto4b399c0d_totp_lambda_role', '-', !Ref env]]] + AssumeRolePolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Principal: + Service: + - lambda.amazonaws.com + Action: + - 'sts:AssumeRole' + Policies: + - PolicyName: flutto4b399c0d_totp_pass_role_policy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - 'iam:PassRole' + Resource: !If [ShouldNotCreateEnvResources, 'arn:aws:iam:::role/flutto4b399c0d_totp_lambda_role', !Join ['',['arn:aws:iam:::role/flutto4b399c0d_totp_lambda_role', '-', !Ref env]]] + MFALambda: + # Lambda which sets MFA config values + # Depends on MFALambdaRole for role ARN + Type: 'AWS::Lambda::Function' + Properties: + Code: + ZipFile: !Join + - |+ + - - 'const response = require(''cfn-response'');' + - 'const aws = require(''aws-sdk'');' + - 'const identity = new aws.CognitoIdentityServiceProvider();' + - 'exports.handler = (event, context, callback) => {' + - ' if (event.RequestType == ''Delete'') { ' + - ' response.send(event, context, response.SUCCESS, {})' + - ' }' + - ' if (event.RequestType == ''Update'' || event.RequestType == ''Create'') {' + - ' let totpParams = {};' + - ' try {' + - ' totpParams = {' + - ' UserPoolId: event.ResourceProperties.userPoolId,' + - ' MfaConfiguration: event.ResourceProperties.mfaConfiguration,' + - ' SmsMfaConfiguration: {' + - ' SmsAuthenticationMessage: event.ResourceProperties.smsAuthenticationMessage,' + - ' SmsConfiguration: {' + - ' SnsCallerArn: event.ResourceProperties.smsConfigCaller,' + - ' ExternalId: event.ResourceProperties.smsConfigExternalId' + - ' }' + - ' },' + - ' SoftwareTokenMfaConfiguration: {Enabled: event.ResourceProperties.totpEnabled.toLowerCase() === ''true'' ? true : false}' + - ' };' + - ' } catch(e) {' + - ' response.send(event, context, response.FAILED, {e});' + - ' };' + - ' identity.setUserPoolMfaConfig(totpParams).promise()' + - ' .then((res) => {' + - ' response.send(event, context, response.SUCCESS, {res});' + - ' })' + - ' .catch((err) => {' + - ' response.send(event, context, response.FAILED, {err});' + - ' });' + - ' }' + - '};' + Handler: index.handler + Runtime: nodejs10.x + Timeout: '300' + Role: !GetAtt + - MFALambdaRole + - Arn + DependsOn: MFALambdaRole + MFALambdaPolicy: + # Sets policy for the role that executes the MFA Lambda + # Depends on Userpool for Arn + # Marked as depending on MFALambda for easier to understand CFN sequencing + Type: 'AWS::IAM::Policy' + Properties: + PolicyName: flutto4b399c0d_totp_lambda_iam_policy + Roles: + - !If [ShouldNotCreateEnvResources, 'flutto4b399c0d_totp_lambda_role', !Join ['',['flutto4b399c0d_totp_lambda_role', '-', !Ref env]]] + PolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Action: + - 'cognito-idp:SetUserPoolMfaConfig' + Resource: !GetAtt UserPool.Arn + DependsOn: MFALambda + MFALogPolicy: + # Sets log policy for the role that executes the MFA Lambda + # Marked as depending on MFALambdaPolicy for easier to understand CFN sequencing + Type: 'AWS::IAM::Policy' + Properties: + PolicyName: flutto4b399c0d_totp_lambda_log_policy + Roles: + - !If [ShouldNotCreateEnvResources, 'flutto4b399c0d_totp_lambda_role', !Join ['',['flutto4b399c0d_totp_lambda_role', '-', !Ref env]]] + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - 'logs:CreateLogGroup' + - 'logs:CreateLogStream' + - 'logs:PutLogEvents' + Resource: !Sub + - arn:aws:logs:${region}:${account}:log-group:/aws/lambda/${lambda}:log-stream:* + - { region: !Ref "AWS::Region", account: !Ref "AWS::AccountId", lambda: !Ref MFALambda} + DependsOn: MFALambdaPolicy + MFALambdaInputs: + # Values passed to MFA Lambda + # Depends on UserPool for Arn + # Depends on MFALambda for Arn + # Marked as depending on MFALambdaPolicy for easier to understand CFN sequencing + Type: 'Custom::LambdaCallout' + Properties: + ServiceToken: !GetAtt MFALambda.Arn + userPoolId: !Ref UserPool + mfaConfiguration: !Ref mfaConfiguration + totpEnabled: false + smsConfigCaller: !GetAtt SNSRole.Arn + smsAuthenticationMessage: !Ref smsAuthenticationMessage + smsConfigExternalId: flutto4b399c0d_role_external_id + DependsOn: MFALogPolicy + + + # BEGIN IDENTITY POOL RESOURCES + + + IdentityPool: + # Always created + Type: AWS::Cognito::IdentityPool + Properties: + IdentityPoolName: !If [ShouldNotCreateEnvResources, 'fluttoauth4b399c0d_identitypool_4b399c0d', !Join ['',['fluttoauth4b399c0d_identitypool_4b399c0d', '__', !Ref env]]] + + CognitoIdentityProviders: + - ClientId: !Ref UserPoolClient + ProviderName: !Sub + - cognito-idp.${region}.amazonaws.com/${client} + - { region: !Ref "AWS::Region", client: !Ref UserPool} + - ClientId: !Ref UserPoolClientWeb + ProviderName: !Sub + - cognito-idp.${region}.amazonaws.com/${client} + - { region: !Ref "AWS::Region", client: !Ref UserPool} + + AllowUnauthenticatedIdentities: !Ref allowUnauthenticatedIdentities + + + DependsOn: UserPoolClientInputs + + + IdentityPoolRoleMap: + # Created to map Auth and Unauth roles to the identity pool + # Depends on Identity Pool for ID ref + Type: AWS::Cognito::IdentityPoolRoleAttachment + Properties: + IdentityPoolId: !Ref IdentityPool + Roles: + unauthenticated: !Ref unauthRoleArn + authenticated: !Ref authRoleArn + DependsOn: IdentityPool + + +Outputs : + + IdentityPoolId: + Value: !Ref 'IdentityPool' + Description: Id for the identity pool + IdentityPoolName: + Value: !GetAtt IdentityPool.Name + + + + + UserPoolId: + Value: !Ref 'UserPool' + Description: Id for the user pool + UserPoolName: + Value: !Ref userPoolName + AppClientIDWeb: + Value: !Ref 'UserPoolClientWeb' + Description: The user pool app client id for web + AppClientID: + Value: !Ref 'UserPoolClient' + Description: The user pool app client id + AppClientSecret: + Value: !GetAtt UserPoolClientInputs.appSecret + + CreatedSNSRole: + Value: !GetAtt SNSRole.Arn + Description: role arn + + + + + + + diff --git a/packages/amplify_auth_cognito/example/amplify/backend/auth/fluttoauth4b399c0d4b399c0d/parameters.json b/packages/amplify_auth_cognito/example/amplify/backend/auth/fluttoauth4b399c0d4b399c0d/parameters.json new file mode 100644 index 0000000000..1f05e23c32 --- /dev/null +++ b/packages/amplify_auth_cognito/example/amplify/backend/auth/fluttoauth4b399c0d4b399c0d/parameters.json @@ -0,0 +1,60 @@ +{ + "identityPoolName": "fluttoauth4b399c0d_identitypool_4b399c0d", + "allowUnauthenticatedIdentities": false, + "resourceNameTruncated": "flutto4b399c0d", + "userPoolName": "fluttoauth4b399c0d_userpool_4b399c0d", + "autoVerifiedAttributes": [ + "email" + ], + "mfaConfiguration": "ON", + "mfaTypes": [ + "SMS Text Message" + ], + "smsAuthenticationMessage": "Your authentication code is {####}", + "smsVerificationMessage": "Your verification code is {####}", + "emailVerificationSubject": "Your verification code", + "emailVerificationMessage": "Your verification code is {####}", + "defaultPasswordPolicy": false, + "passwordPolicyMinLength": 8, + "passwordPolicyCharacters": [], + "requiredAttributes": [ + "email", + "phone_number" + ], + "userpoolClientGenerateSecret": true, + "userpoolClientRefreshTokenValidity": 30, + "userpoolClientWriteAttributes": [ + "email" + ], + "userpoolClientReadAttributes": [ + "email" + ], + "userpoolClientLambdaRole": "flutto4b399c0d_userpoolclient_lambda_role", + "userpoolClientSetAttributes": false, + "useDefault": "manual", + "authSelections": "identityPoolAndUserPool", + "resourceName": "fluttoauth4b399c0d4b399c0d", + "thirdPartyAuth": false, + "userPoolGroups": false, + "adminQueries": false, + "triggers": "{}", + "hostedUI": false, + "userPoolGroupList": [], + "authRoleArn": { + "Fn::GetAtt": [ + "AuthRole", + "Arn" + ] + }, + "unauthRoleArn": { + "Fn::GetAtt": [ + "UnauthRole", + "Arn" + ] + }, + "parentStack": { + "Ref": "AWS::StackId" + }, + "permissions": [], + "dependsOn": [] +} \ No newline at end of file diff --git a/packages/amplify_auth_cognito/example/amplify/backend/backend-config.json b/packages/amplify_auth_cognito/example/amplify/backend/backend-config.json new file mode 100644 index 0000000000..a90344dd62 --- /dev/null +++ b/packages/amplify_auth_cognito/example/amplify/backend/backend-config.json @@ -0,0 +1,10 @@ +{ + "auth": { + "flutterauthrefactord017496f": { + "service": "Cognito", + "providerPlugin": "awscloudformation", + "dependsOn": [], + "customAuth": false + } + } +} \ No newline at end of file diff --git a/packages/amplify_auth_cognito/example/amplify/team-provider-info.json b/packages/amplify_auth_cognito/example/amplify/team-provider-info.json new file mode 100644 index 0000000000..da78a46c92 --- /dev/null +++ b/packages/amplify_auth_cognito/example/amplify/team-provider-info.json @@ -0,0 +1,19 @@ +{ + "dev": { + "awscloudformation": { + "AuthRoleName": "amplify-flutterauthrefactor-dev-160301-authRole", + "UnauthRoleArn": "arn:aws:iam::444407295970:role/amplify-flutterauthrefactor-dev-160301-unauthRole", + "AuthRoleArn": "arn:aws:iam::444407295970:role/amplify-flutterauthrefactor-dev-160301-authRole", + "Region": "us-west-2", + "DeploymentBucketName": "amplify-flutterauthrefactor-dev-160301-deployment", + "UnauthRoleName": "amplify-flutterauthrefactor-dev-160301-unauthRole", + "StackName": "amplify-flutterauthrefactor-dev-160301", + "StackId": "arn:aws:cloudformation:us-west-2:444407295970:stack/amplify-flutterauthrefactor-dev-160301/55600ff0-cba6-11ea-b2d9-0af4fb34eba2" + }, + "categories": { + "auth": { + "flutterauthrefactord017496f": {} + } + } + } +} \ No newline at end of file diff --git a/packages/amplify_auth_cognito/example/android/.gitignore b/packages/amplify_auth_cognito/example/android/.gitignore new file mode 100644 index 0000000000..0a741cb43d --- /dev/null +++ b/packages/amplify_auth_cognito/example/android/.gitignore @@ -0,0 +1,11 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +GeneratedPluginRegistrant.java + +# Remember to never publicly share your keystore. +# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +key.properties diff --git a/packages/amplify_auth_cognito/example/android/.project b/packages/amplify_auth_cognito/example/android/.project new file mode 100644 index 0000000000..f9492f8a3a --- /dev/null +++ b/packages/amplify_auth_cognito/example/android/.project @@ -0,0 +1,17 @@ + + + android__ + Amplify-Flutter: amplify_auth_plugin + + + + + org.eclipse.buildship.core.gradleprojectbuilder + + + + + + org.eclipse.buildship.core.gradleprojectnature + + diff --git a/packages/amplify_auth_cognito/example/android/app/build.gradle b/packages/amplify_auth_cognito/example/android/app/build.gradle new file mode 100644 index 0000000000..d8b15dc969 --- /dev/null +++ b/packages/amplify_auth_cognito/example/android/app/build.gradle @@ -0,0 +1,63 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 28 + + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + } + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.amazonaws.amplify.amplify_auth_cognito_example" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" +} diff --git a/packages/amplify_auth_cognito/example/android/app/src/debug/AndroidManifest.xml b/packages/amplify_auth_cognito/example/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 0000000000..a15cb64d45 --- /dev/null +++ b/packages/amplify_auth_cognito/example/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/packages/amplify_auth_cognito/example/android/app/src/main/AndroidManifest.xml b/packages/amplify_auth_cognito/example/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..34c11ce80a --- /dev/null +++ b/packages/amplify_auth_cognito/example/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + diff --git a/packages/amplify_auth_cognito/example/android/app/src/main/kotlin/com/amazonaws/amplify/amplify_auth_cognito_example/MainActivity.kt b/packages/amplify_auth_cognito/example/android/app/src/main/kotlin/com/amazonaws/amplify/amplify_auth_cognito_example/MainActivity.kt new file mode 100644 index 0000000000..a061bbdd14 --- /dev/null +++ b/packages/amplify_auth_cognito/example/android/app/src/main/kotlin/com/amazonaws/amplify/amplify_auth_cognito_example/MainActivity.kt @@ -0,0 +1,6 @@ +package com.amazonaws.amplify.amplify_auth_cognito_example + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity: FlutterActivity() { +} diff --git a/packages/amplify_auth_cognito/example/android/app/src/main/res/drawable/launch_background.xml b/packages/amplify_auth_cognito/example/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 0000000000..304732f884 --- /dev/null +++ b/packages/amplify_auth_cognito/example/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/packages/amplify_auth_cognito/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/packages/amplify_auth_cognito/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000..db77bb4b7b Binary files /dev/null and b/packages/amplify_auth_cognito/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/packages/amplify_auth_cognito/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/packages/amplify_auth_cognito/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000000..17987b79bb Binary files /dev/null and b/packages/amplify_auth_cognito/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/packages/amplify_auth_cognito/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/packages/amplify_auth_cognito/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000000..09d4391482 Binary files /dev/null and b/packages/amplify_auth_cognito/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/packages/amplify_auth_cognito/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/packages/amplify_auth_cognito/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000..d5f1c8d34e Binary files /dev/null and b/packages/amplify_auth_cognito/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/packages/amplify_auth_cognito/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/packages/amplify_auth_cognito/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000000..4d6372eebd Binary files /dev/null and b/packages/amplify_auth_cognito/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/packages/amplify_auth_cognito/example/android/app/src/main/res/values/styles.xml b/packages/amplify_auth_cognito/example/android/app/src/main/res/values/styles.xml new file mode 100644 index 0000000000..1f83a33fd4 --- /dev/null +++ b/packages/amplify_auth_cognito/example/android/app/src/main/res/values/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/packages/amplify_auth_cognito/example/android/app/src/profile/AndroidManifest.xml b/packages/amplify_auth_cognito/example/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 0000000000..a15cb64d45 --- /dev/null +++ b/packages/amplify_auth_cognito/example/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/packages/amplify_auth_cognito/example/android/build.gradle b/packages/amplify_auth_cognito/example/android/build.gradle new file mode 100644 index 0000000000..04ec3490bd --- /dev/null +++ b/packages/amplify_auth_cognito/example/android/build.gradle @@ -0,0 +1,31 @@ +buildscript { + ext.kotlin_version = '1.3.50' + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:4.0.0' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/packages/amplify_auth_cognito/example/android/gradle.properties b/packages/amplify_auth_cognito/example/android/gradle.properties new file mode 100644 index 0000000000..38c8d4544f --- /dev/null +++ b/packages/amplify_auth_cognito/example/android/gradle.properties @@ -0,0 +1,4 @@ +org.gradle.jvmargs=-Xmx1536M +android.enableR8=true +android.useAndroidX=true +android.enableJetifier=true diff --git a/packages/amplify_auth_cognito/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/amplify_auth_cognito/example/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000..0ca36d498c --- /dev/null +++ b/packages/amplify_auth_cognito/example/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Tue Jul 14 08:52:17 PDT 2020 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip diff --git a/packages/amplify_auth_cognito/example/android/settings.gradle b/packages/amplify_auth_cognito/example/android/settings.gradle new file mode 100644 index 0000000000..44e62bcf06 --- /dev/null +++ b/packages/amplify_auth_cognito/example/android/settings.gradle @@ -0,0 +1,11 @@ +include ':app' + +def localPropertiesFile = new File(rootProject.projectDir, "local.properties") +def properties = new Properties() + +assert localPropertiesFile.exists() +localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } + +def flutterSdkPath = properties.getProperty("flutter.sdk") +assert flutterSdkPath != null, "flutter.sdk not set in local.properties" +apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" diff --git a/packages/amplify_auth_cognito/example/ios/.gitignore b/packages/amplify_auth_cognito/example/ios/.gitignore new file mode 100644 index 0000000000..e96ef602b8 --- /dev/null +++ b/packages/amplify_auth_cognito/example/ios/.gitignore @@ -0,0 +1,32 @@ +*.mode1v3 +*.mode2v3 +*.moved-aside +*.pbxuser +*.perspectivev3 +**/*sync/ +.sconsign.dblite +.tags* +**/.vagrant/ +**/DerivedData/ +Icon? +**/Pods/ +**/.symlinks/ +profile +xcuserdata +**/.generated/ +Flutter/App.framework +Flutter/Flutter.framework +Flutter/Flutter.podspec +Flutter/Generated.xcconfig +Flutter/app.flx +Flutter/app.zip +Flutter/flutter_assets/ +Flutter/flutter_export_environment.sh +ServiceDefinitions.json +Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!default.mode1v3 +!default.mode2v3 +!default.pbxuser +!default.perspectivev3 diff --git a/packages/amplify_auth_cognito/example/ios/Flutter/AppFrameworkInfo.plist b/packages/amplify_auth_cognito/example/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 0000000000..6b4c0f78a7 --- /dev/null +++ b/packages/amplify_auth_cognito/example/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/packages/amplify_auth_cognito/example/ios/Flutter/Debug.xcconfig b/packages/amplify_auth_cognito/example/ios/Flutter/Debug.xcconfig new file mode 100644 index 0000000000..535ba0c5fb --- /dev/null +++ b/packages/amplify_auth_cognito/example/ios/Flutter/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "Generated.xcconfig" \ No newline at end of file diff --git a/packages/amplify_auth_cognito/example/ios/Flutter/Debug.xconfig b/packages/amplify_auth_cognito/example/ios/Flutter/Debug.xconfig new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/amplify_auth_cognito/example/ios/Flutter/Release.xcconfig b/packages/amplify_auth_cognito/example/ios/Flutter/Release.xcconfig new file mode 100644 index 0000000000..399e9340e6 --- /dev/null +++ b/packages/amplify_auth_cognito/example/ios/Flutter/Release.xcconfig @@ -0,0 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "Generated.xcconfig" diff --git a/packages/amplify_auth_cognito/example/ios/Podfile b/packages/amplify_auth_cognito/example/ios/Podfile new file mode 100644 index 0000000000..5a67826acc --- /dev/null +++ b/packages/amplify_auth_cognito/example/ios/Podfile @@ -0,0 +1,43 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +platform :ios, '11.0' + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + use_frameworks! + use_modular_headers! + + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/packages/amplify_auth_cognito/example/ios/Runner.xcodeproj/project.pbxproj b/packages/amplify_auth_cognito/example/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..bca50c7097 --- /dev/null +++ b/packages/amplify_auth_cognito/example/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,588 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 26AECB412893A7A959622364 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EE1727BF3FA0D464713D41A3 /* Pods_Runner.framework */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 0D7A73413D1932957B42A25E /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7F732F1CF7D7EF9EA74B414F /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + B9187703880B15C5125F5D1F /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + EE1727BF3FA0D464713D41A3 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 26AECB412893A7A959622364 /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + DEFD1397E6D457FBCF57AA48 /* Pods */, + F0E8B898AFD29D60F8C1EEDC /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, + ); + path = Runner; + sourceTree = ""; + }; + DEFD1397E6D457FBCF57AA48 /* Pods */ = { + isa = PBXGroup; + children = ( + 0D7A73413D1932957B42A25E /* Pods-Runner.debug.xcconfig */, + B9187703880B15C5125F5D1F /* Pods-Runner.release.xcconfig */, + 7F732F1CF7D7EF9EA74B414F /* Pods-Runner.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; + F0E8B898AFD29D60F8C1EEDC /* Frameworks */ = { + isa = PBXGroup; + children = ( + EE1727BF3FA0D464713D41A3 /* Pods_Runner.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 24D41A5CC7E22178A374BFD2 /* [CP] Check Pods Manifest.lock */, + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + AB8785FB87889321150A6CED /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1020; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 1100; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 24D41A5CC7E22178A374BFD2 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; + AB8785FB87889321150A6CED /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/AWSAuthCore/AWSAuthCore.framework", + "${BUILT_PRODUCTS_DIR}/AWSCognitoIdentityProvider/AWSCognitoIdentityProvider.framework", + "${BUILT_PRODUCTS_DIR}/AWSCognitoIdentityProviderASF/AWSCognitoIdentityProviderASF.framework", + "${BUILT_PRODUCTS_DIR}/AWSCore/AWSCore.framework", + "${BUILT_PRODUCTS_DIR}/AWSMobileClient/AWSMobileClient.framework", + "${BUILT_PRODUCTS_DIR}/AWSPluginsCore/AWSPluginsCore.framework", + "${BUILT_PRODUCTS_DIR}/Amplify/Amplify.framework", + "${BUILT_PRODUCTS_DIR}/AmplifyPlugins/AmplifyPlugins.framework", + "${PODS_ROOT}/../Flutter/Flutter.framework", + "${BUILT_PRODUCTS_DIR}/ObjectMapper/ObjectMapper.framework", + "${BUILT_PRODUCTS_DIR}/SwiftyJSON/SwiftyJSON.framework", + "${BUILT_PRODUCTS_DIR}/amplify_auth_cognito/amplify_auth_cognito.framework", + "${BUILT_PRODUCTS_DIR}/amplify_core/amplify_core.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AWSAuthCore.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AWSCognitoIdentityProvider.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AWSCognitoIdentityProviderASF.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AWSCore.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AWSMobileClient.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AWSPluginsCore.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Amplify.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AmplifyPlugins.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ObjectMapper.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftyJSON.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/amplify_auth_cognito.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/amplify_core.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 249021D4217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.amplify.amplifyAuthCognitoExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.amplify.amplifyAuthCognitoExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.amplify.amplifyAuthCognitoExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/packages/amplify_auth_cognito/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/amplify_auth_cognito/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000..1d526a16ed --- /dev/null +++ b/packages/amplify_auth_cognito/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/packages/amplify_auth_cognito/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/amplify_auth_cognito/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000000..18d981003d --- /dev/null +++ b/packages/amplify_auth_cognito/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/packages/amplify_auth_cognito/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/packages/amplify_auth_cognito/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000000..f9b0d7c5ea --- /dev/null +++ b/packages/amplify_auth_cognito/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/packages/amplify_auth_cognito/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/amplify_auth_cognito/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000000..a28140cfdb --- /dev/null +++ b/packages/amplify_auth_cognito/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/amplify_auth_cognito/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/packages/amplify_auth_cognito/example/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000..21a3cc14c7 --- /dev/null +++ b/packages/amplify_auth_cognito/example/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/packages/amplify_auth_cognito/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/amplify_auth_cognito/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000000..18d981003d --- /dev/null +++ b/packages/amplify_auth_cognito/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/packages/amplify_auth_cognito/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/packages/amplify_auth_cognito/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000000..f9b0d7c5ea --- /dev/null +++ b/packages/amplify_auth_cognito/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/packages/amplify_auth_cognito/example/ios/Runner/AppDelegate.swift b/packages/amplify_auth_cognito/example/ios/Runner/AppDelegate.swift new file mode 100644 index 0000000000..70693e4a8c --- /dev/null +++ b/packages/amplify_auth_cognito/example/ios/Runner/AppDelegate.swift @@ -0,0 +1,13 @@ +import UIKit +import Flutter + +@UIApplicationMain +@objc class AppDelegate: FlutterAppDelegate { + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + GeneratedPluginRegistrant.register(with: self) + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } +} diff --git a/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000000..d36b1fab2d --- /dev/null +++ b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Icon-App-1024x1024@1x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 0000000000..dc9ada4725 Binary files /dev/null and b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 0000000000..28c6bf0301 Binary files /dev/null and b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 0000000000..2ccbfd967d Binary files /dev/null and b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000000..f091b6b0bc Binary files /dev/null and b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 0000000000..4cde12118d Binary files /dev/null and b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000000..d0ef06e7ed Binary files /dev/null and b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 0000000000..dcdc2306c2 Binary files /dev/null and b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 0000000000..2ccbfd967d Binary files /dev/null and b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000000..c8f9ed8f5c Binary files /dev/null and b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000000..a6d6b8609d Binary files /dev/null and b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000000..a6d6b8609d Binary files /dev/null and b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000000..75b2d164a5 Binary files /dev/null and b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000000..c4df70d39d Binary files /dev/null and b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 0000000000..6a84f41e14 Binary files /dev/null and b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 0000000000..d0e1f58536 Binary files /dev/null and b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 0000000000..0bedcf2fd4 --- /dev/null +++ b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "LaunchImage.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 0000000000..9da19eacad Binary files /dev/null and b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 0000000000..9da19eacad Binary files /dev/null and b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 0000000000..9da19eacad Binary files /dev/null and b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 0000000000..89c2725b70 --- /dev/null +++ b/packages/amplify_auth_cognito/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/packages/amplify_auth_cognito/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/packages/amplify_auth_cognito/example/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000000..f2e259c7c9 --- /dev/null +++ b/packages/amplify_auth_cognito/example/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/amplify_auth_cognito/example/ios/Runner/Base.lproj/Main.storyboard b/packages/amplify_auth_cognito/example/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 0000000000..f3c28516fb --- /dev/null +++ b/packages/amplify_auth_cognito/example/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/amplify_auth_cognito/example/ios/Runner/Info.plist b/packages/amplify_auth_cognito/example/ios/Runner/Info.plist new file mode 100644 index 0000000000..c25a00b2c6 --- /dev/null +++ b/packages/amplify_auth_cognito/example/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + amplify_auth_cognito_example + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/packages/amplify_auth_cognito/example/ios/Runner/Runner-Bridging-Header.h b/packages/amplify_auth_cognito/example/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 0000000000..308a2a560b --- /dev/null +++ b/packages/amplify_auth_cognito/example/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" diff --git a/packages/amplify_auth_cognito/example/lib/main.dart b/packages/amplify_auth_cognito/example/lib/main.dart new file mode 100644 index 0000000000..d414589323 --- /dev/null +++ b/packages/amplify_auth_cognito/example/lib/main.dart @@ -0,0 +1,477 @@ +import 'dart:convert'; + +import 'package:flutter/material.dart'; +import 'package:amplify_auth_cognito/amplify_auth_cognito.dart'; +import 'package:amplify_core/amplify_core.dart'; +import 'amplifyconfiguration.dart'; + +void main() { + runApp(MyApp()); +} + +class MyApp extends StatefulWidget { + @override + _MyAppState createState() => _MyAppState(); +} + +class _MyAppState extends State { + final usernameController = TextEditingController(); + final passwordController = TextEditingController(); + final emailController = TextEditingController(); + final phoneController = TextEditingController(); + final confirmationCodeController = TextEditingController(); + + bool _isAmplifyConfigured = false; + Amplify amplify = new Amplify(); + String displayState; + String authState; + String error; + List exceptions = []; + + @override + void initState() { + super.initState(); + } + + void _configureAmplify() async { + AmplifyAuthCognito auth = new AmplifyAuthCognito(); + amplify.addPlugin(authPlugin: [auth]); + await amplify.configure(amplifyconfig); + setState(() { + _isAmplifyConfigured = true; + displayState = "SHOW_SIGN_IN"; + }); + } + + void _signUp() async { + setState(() { + error = ""; + exceptions = []; + }); + Map userAttributes = { + "email": emailController.text, + "phone_number": phoneController.text, + "address": "123 MyStreet" + }; + try { + SignUpResult res = await Amplify.Auth.signUp( + request: SignUpRequest( + username: usernameController.text.trim(), + password: passwordController.text.trim(), + options: CognitoSignUpOptions( + userAttributes: userAttributes, + usernameAttribute: "email" + ) + ), + ); + setState(() { + displayState = res.nextStep.signUpStep != "DONE" ? "SHOW_CONFIRM" : "SHOW_SIGN_UP"; + authState = "Signup: " + res.nextStep.signUpStep; + }); + } on AuthError catch (e) { + setState(() { + error = e.cause; + e.exceptionList.forEach((el) { + exceptions.add(el.exception); + }); + }); + print(e); + } + } + + void _confirmSignUp() async { + setState(() { + error = ""; + exceptions = []; + }); + try { + SignUpResult res = await Amplify.Auth.confirmSignUp( + request: ConfirmSignUpRequest( + userKey: usernameController.text.trim(), + confirmationCode: confirmationCodeController.text.trim() + ), + ); + setState(() { + displayState = res.nextStep.signUpStep != "DONE" ? "SHOW_CONFIRM" : "SHOW_SIGN_IN"; + authState = "ConfirmSignUp: " + res.nextStep.signUpStep; + }); + } on AuthError catch (e) { + setState(() { + error = e.cause; + e.exceptionList.forEach((el) { + exceptions.add(el.exception); + }); + }); + print(e); + } + } + + void _signIn() async { + setState(() { + error = ""; + exceptions = []; + }); + try { + SignInResult res = await Amplify.Auth.signIn( + request: SignInRequest( + username: usernameController.text.trim(), + password: passwordController.text.trim() + ), + ); + setState(() { + displayState = res.isSignedIn ? "SIGNED_IN" : "SHOW_CONFIRM_SIGN_IN" ; + authState = "Signin: " + res.nextStep.signInStep; + }); + } on AuthError catch (e) { + setState(() { + error = e.cause; + e.exceptionList.forEach((el) { + exceptions.add(el.exception); + }); + }); + print(e); + } + } + + void _confirmSignIn() async { + setState(() { + error = ""; + exceptions = []; + }); + try { + SignInResult res = await Amplify.Auth.confirmSignIn( + request: ConfirmSignInRequest( + userKey: usernameController.text.trim(), + confirmationValue: confirmationCodeController.text.trim() + ), + ); + setState(() { + displayState = res.nextStep.signInStep == "DONE" ? "SIGNED_IN" : "SHOW_CONFIRM_SIGN_IN"; + authState = "SignIn: " + res.nextStep.signInStep; + }); + } on AuthError catch (e) { + setState(() { + error = e.cause; + e.exceptionList.forEach((el) { + exceptions.add(el.exception); + }); + }); + print(e); + } + } + + void _signOut() async { + setState(() { + error = ""; + exceptions = []; + }); + try { + SignOutResult res = await Amplify.Auth.signOut(); + setState(() { + displayState = 'SHOW_SIGN_IN'; + authState = "SIGNED OUT"; + }); + } on AuthError catch (e) { + setState(() { + error = e.cause; + e.exceptionList.forEach((el) { + exceptions.add(el.exception); + }); + }); + print(e); + } + } + + void _createUser() async { + setState(() { + displayState = "SHOW_SIGN_UP"; + }); + } + + void _confirmUser() async { + setState(() { + displayState = "SHOW_CONFIRM"; + }); + } + + void _backToSignIn() async { + setState(() { + displayState = "SHOW_SIGN_IN"; + }); + } + +Widget showConfirmSignUp() { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Expanded( // wrap your Column in Expanded + child: Column ( + children: [ + const Padding(padding: EdgeInsets.all(10.0)), + TextFormField( + controller: usernameController, + decoration: const InputDecoration( + icon: Icon(Icons.person), + hintText: 'Your username', + labelText: 'Username *', + ) + ), + TextFormField( + controller: confirmationCodeController, + decoration: const InputDecoration( + icon: Icon(Icons.confirmation_number), + hintText: 'The code we sent you', + labelText: 'Confirmation Code *', + ) + ), + const Padding(padding: EdgeInsets.all(10.0)), + RaisedButton( + onPressed: _confirmSignUp, + child: const Text('Confirm SignUp'), + ), + const Padding(padding: EdgeInsets.all(10.0)), + RaisedButton( + onPressed:_backToSignIn, + child: const Text('Back to Sign In'), + ), + ], + ), + ), + ], + ); + } + + Widget showConfirmSignIn() { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Expanded( // wrap your Column in Expanded + child: Column( + children: [ + const Padding(padding: EdgeInsets.all(10.0)), + TextFormField( + controller: confirmationCodeController, + decoration: const InputDecoration( + icon: Icon(Icons.question_answer), + hintText: 'The secret answer to the auth challange', + labelText: 'Challange Response *', + ) + ), + const Padding(padding: EdgeInsets.all(10.0)), + RaisedButton( + onPressed: _confirmSignIn, + child: const Text('Confirm SignIn'), + ), + const Padding(padding: EdgeInsets.all(10.0)), + RaisedButton( + onPressed:_backToSignIn, + child: const Text('Back to Sign In'), + ), + ], + ), + ), + ], + ); + } + +Widget showSignIn() { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Expanded( // wrap your Column in Expanded + child: Column( + children: [ + TextFormField( + controller: usernameController, + decoration: const InputDecoration( + icon: Icon(Icons.person), + hintText: 'Your username', + labelText: 'Username *', + ) + ), + TextFormField( + obscureText: true, + controller: passwordController, + decoration: const InputDecoration( + icon: Icon(Icons.lock), + hintText: 'Your password', + labelText: 'Password *', + ) + ), + const Padding(padding: EdgeInsets.all(10.0)), + RaisedButton( + onPressed: _signIn, + child: const Text('Sign In'), + ), + const Padding(padding: EdgeInsets.all(10.0)), + RaisedButton( + onPressed: _createUser, + child: const Text('Create User'), + ), + const Padding(padding: EdgeInsets.all(10.0)), + RaisedButton( + onPressed: _confirmUser, + child: const Text('Confirm User'), + ), + const Padding(padding: EdgeInsets.all(10.0)), + RaisedButton( + onPressed: _signOut, + child: const Text('SignOut'), + ), + ], + ), + ), + ], + ); + } + + Widget showSignUp() { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Expanded( // wrap your Column in Expanded + child: Column( + children: [ + TextFormField( + controller: usernameController, + decoration: const InputDecoration( + icon: Icon(Icons.person), + hintText: 'The name you will use to login', + labelText: 'Username *', + ), + ), + TextFormField( + obscureText: true, + controller: passwordController, + decoration: const InputDecoration( + icon: Icon(Icons.lock), + hintText: 'The password you will use to login', + labelText: 'Password *', + ), + ), + TextFormField( + controller: emailController, + decoration: const InputDecoration( + icon: Icon(Icons.email), + hintText: 'Your email address', + labelText: 'Email *', + ), + ), + TextFormField( + controller: phoneController, + decoration: const InputDecoration( + icon: Icon(Icons.phone), + hintText: 'Your phone number', + labelText: 'Phone number *', + ), + ), + const Padding(padding: EdgeInsets.all(10.0)), + RaisedButton( + onPressed: _signUp, + child: const Text('Sign Up'), + ), + const Padding(padding: EdgeInsets.all(2.0)), + Text( + 'SignUpData: $authState', + textAlign: TextAlign.center, + overflow: TextOverflow.visible, + style: TextStyle(fontWeight: FontWeight.bold), + ), + const Padding(padding: EdgeInsets.all(10.0)), + RaisedButton( + onPressed:_backToSignIn, + child: const Text('Back to Sign In'), + ), + ], + ), + ), + ], + ); + } + + Widget showApp() { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Expanded( // wrap your Column in Expanded + child: Column( + children: [ + const Padding(padding: EdgeInsets.all(10.0)), + Text("You are signed in!"), + const Padding(padding: EdgeInsets.all(10.0)), + RaisedButton( + onPressed: _signOut, + child: const Text('Sign Out'), + ), + ], + ), + ), + ], + ); + } + + showAuthState() { + return Text( + 'Auth Status: $authState', + textAlign: TextAlign.center, + overflow: TextOverflow.visible, + style: TextStyle(fontWeight: FontWeight.bold), + ); + } + + Widget getTextWidgets(List strings) + { + if (strings != null) { + return new Row(children: strings.map((item) => new Text(item + " ")).toList()); + } + } + + showErrors() { + return Text( + 'Error: $error', + textAlign: TextAlign.center, + overflow: TextOverflow.visible, + style: TextStyle(fontWeight: FontWeight.bold) + ); + } + + showExceptions() { + return getTextWidgets(exceptions); + } + + @override + Widget build(BuildContext context) { + return MaterialApp( + home: Scaffold( + appBar: AppBar( + title: const Text('Plugin example app'), + ), + body: ListView( + padding: EdgeInsets.all(10.0), + children: [ + Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Padding(padding: EdgeInsets.all(10.0)), + RaisedButton( + onPressed: _isAmplifyConfigured ? null: _configureAmplify, + child: const Text('configure'), + ), + + const Padding(padding: EdgeInsets.all(10.0)), + if (this.displayState == "SHOW_SIGN_UP") showSignUp(), + if (this.displayState == "SHOW_CONFIRM") showConfirmSignUp(), + if (this.displayState == "SHOW_SIGN_IN") showSignIn(), + if (this.displayState == "SHOW_CONFIRM_SIGN_IN") showConfirmSignIn(), + if (this.displayState == 'SIGNED_IN') showApp(), + showAuthState(), + if (this.error != null) showErrors(), + showExceptions() + ] + ) + ], + ), + ), + ); + } +} \ No newline at end of file diff --git a/packages/amplify_auth_cognito/example/pubspec.yaml b/packages/amplify_auth_cognito/example/pubspec.yaml new file mode 100644 index 0000000000..a5a3012d38 --- /dev/null +++ b/packages/amplify_auth_cognito/example/pubspec.yaml @@ -0,0 +1,72 @@ +name: amplify_auth_cognito_example +description: Demonstrates how to use the amplify_auth_cognito plugin. + +# The following line prevents the package from being accidentally published to +# pub.dev using `pub publish`. This is preferred for private packages. +publish_to: 'none' # Remove this line if you wish to publish to pub.dev + +environment: + sdk: ">=2.7.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + amplify_core: + path: ../../amplify_core + amplify_auth_cognito: + # When depending on this package from a real application you should use: + # amplify_auth_cognito: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. + path: ../ + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^0.1.3 + +dev_dependencies: + flutter_test: + sdk: flutter + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages diff --git a/packages/amplify_auth_cognito/example/test/widget_test.dart b/packages/amplify_auth_cognito/example/test/widget_test.dart new file mode 100644 index 0000000000..d3f75b39d9 --- /dev/null +++ b/packages/amplify_auth_cognito/example/test/widget_test.dart @@ -0,0 +1,27 @@ +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:amplify_auth_cognito_example/main.dart'; + +void main() { + testWidgets('Verify Platform version', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(MyApp()); + + // Verify that platform version is retrieved. + expect( + find.byWidgetPredicate( + (Widget widget) => widget is Text && + widget.data.startsWith('Running on:'), + ), + findsOneWidget, + ); + }); +} diff --git a/packages/amplify_auth_cognito/ios/.gitignore b/packages/amplify_auth_cognito/ios/.gitignore new file mode 100644 index 0000000000..aa479fd3ce --- /dev/null +++ b/packages/amplify_auth_cognito/ios/.gitignore @@ -0,0 +1,37 @@ +.idea/ +.vagrant/ +.sconsign.dblite +.svn/ + +.DS_Store +*.swp +profile + +DerivedData/ +build/ +GeneratedPluginRegistrant.h +GeneratedPluginRegistrant.m + +.generated/ + +*.pbxuser +*.mode1v3 +*.mode2v3 +*.perspectivev3 + +!default.pbxuser +!default.mode1v3 +!default.mode2v3 +!default.perspectivev3 + +xcuserdata + +*.moved-aside + +*.pyc +*sync/ +Icon? +.tags* + +/Flutter/Generated.xcconfig +/Flutter/flutter_export_environment.sh \ No newline at end of file diff --git a/packages/amplify_auth_cognito/ios/Assets/.gitkeep b/packages/amplify_auth_cognito/ios/Assets/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/amplify_auth_cognito/ios/Classes/AuthCognito.h b/packages/amplify_auth_cognito/ios/Classes/AuthCognito.h new file mode 100644 index 0000000000..66a3d39ce9 --- /dev/null +++ b/packages/amplify_auth_cognito/ios/Classes/AuthCognito.h @@ -0,0 +1,4 @@ +#import + +@interface AuthCognito : NSObject +@end diff --git a/packages/amplify_auth_cognito/ios/Classes/AuthCognito.m b/packages/amplify_auth_cognito/ios/Classes/AuthCognito.m new file mode 100644 index 0000000000..cd7fb74fd2 --- /dev/null +++ b/packages/amplify_auth_cognito/ios/Classes/AuthCognito.m @@ -0,0 +1,15 @@ +#import "AuthCognito.h" +#if __has_include() +#import +#else +// Support project import fallback if the generated compatibility header +// is not copied when this plugin is created as a library. +// https://forums.swift.org/t/swift-static-libraries-dont-copy-generated-objective-c-header/19816 +#import "amplify_auth_cognito-Swift.h" +#endif + +@implementation AuthCognito ++ (void)registerWithRegistrar:(NSObject*)registrar { + [SwiftAuthCognito registerWithRegistrar:registrar]; +} +@end diff --git a/packages/amplify_auth_cognito/ios/Classes/FlutterAuthErrorMessage.swift b/packages/amplify_auth_cognito/ios/Classes/FlutterAuthErrorMessage.swift new file mode 100644 index 0000000000..9e18215d74 --- /dev/null +++ b/packages/amplify_auth_cognito/ios/Classes/FlutterAuthErrorMessage.swift @@ -0,0 +1,13 @@ +// +// FlutterAuthErrorMessage.swift +// amplify_auth_cognito +// +// Created by Noyes, Dustin on 7/27/20. +// + +import Foundation +enum FlutterAuthErrorMessage: String { + case SIGNUP = "AMPLIFY_SIGNUP_FAILED" + case MALFORMED = "AMPLIFY_SIGNUP_REQUEST_MALFORMED" + case CASTING = "ERROR_CASTING_INPUT_IN_PLATFORM_CODE" +} diff --git a/packages/amplify_auth_cognito/ios/Classes/FlutterConfirmSignInRequest.swift b/packages/amplify_auth_cognito/ios/Classes/FlutterConfirmSignInRequest.swift new file mode 100644 index 0000000000..0ad0ef505e --- /dev/null +++ b/packages/amplify_auth_cognito/ios/Classes/FlutterConfirmSignInRequest.swift @@ -0,0 +1,21 @@ +// +// FlutterConfirmSignInRequest.swift +// amplify_auth_cognito +// +// Created by Noyes, Dustin on 7/24/20. +// + +import Foundation +struct FlutterConfirmSignInRequest { + var confirmationCode: String + init(dict: NSMutableDictionary){ + self.confirmationCode = dict["confirmationCode"] as! String + } + static func validate(dict: NSMutableDictionary) -> Bool { + var valid: Bool = true; + if (dict["confirmationCode"] == nil && dict["options"] == nil) { + valid = false; + } + return valid; + } +} diff --git a/packages/amplify_auth_cognito/ios/Classes/FlutterConfirmSignUpRequest.swift b/packages/amplify_auth_cognito/ios/Classes/FlutterConfirmSignUpRequest.swift new file mode 100644 index 0000000000..2fa1662637 --- /dev/null +++ b/packages/amplify_auth_cognito/ios/Classes/FlutterConfirmSignUpRequest.swift @@ -0,0 +1,26 @@ +// +// FlutterConfirmSignUpRequest.swift +// amplify_auth +// +// Created by Noyes, Dustin on 7/2/20. +// + +import Foundation +struct FlutterConfirmSignUpRequest { + var username: String? + var confirmationCode: String? + init(dict: NSMutableDictionary){ + self.username = dict["userKey"] as! String? + self.confirmationCode = dict["confirmationCode"] as! String? + } + static func validate(dict: NSMutableDictionary) -> Bool { + var valid: Bool = true; + if (dict["userKey"] == nil && dict["options"] == nil) { + valid = false; + } + if (dict["confirmationCode"] == nil && dict["options"] == nil) { + valid = false; + } + return valid; + } +} diff --git a/packages/amplify_auth_cognito/ios/Classes/FlutterSignInRequest.swift b/packages/amplify_auth_cognito/ios/Classes/FlutterSignInRequest.swift new file mode 100644 index 0000000000..86274cafa8 --- /dev/null +++ b/packages/amplify_auth_cognito/ios/Classes/FlutterSignInRequest.swift @@ -0,0 +1,28 @@ +// +// SignIn.swift +// amplify_auth +// +// Created by Noyes, Dustin on 7/2/20. +// + +import Foundation +struct FlutterSignInRequest { + var username: String? + var password: String? + var options: Dictionary? = [:] + init(dict: NSMutableDictionary){ + self.username = dict["username"] as! String? + self.password = dict["password"] as! String? + self.options = dict["options"] as! Dictionary? + } + static func validate(dict: NSMutableDictionary) -> Bool { + var valid: Bool = true; + if (dict["username"] == nil && dict["options"] == nil) { + valid = false; + } + if (dict["password"] == nil && dict["options"] == nil) { + valid = false; + } + return valid; + } +} diff --git a/packages/amplify_auth_cognito/ios/Classes/FlutterSignInResult.swift b/packages/amplify_auth_cognito/ios/Classes/FlutterSignInResult.swift new file mode 100644 index 0000000000..bebf49410a --- /dev/null +++ b/packages/amplify_auth_cognito/ios/Classes/FlutterSignInResult.swift @@ -0,0 +1,127 @@ +// +// FlutterSignInResult.swift +// amplify_auth_cognito +// +// Created by Noyes, Dustin on 7/21/20. +// + +import Foundation +import Amplify + +struct FlutterSignInResult { + var isSignedIn: Bool + var signInStep: String + var additionalInfo: [String: String] + var codeDeliveryDetails: [String: String] + + init(res: AmplifyOperation.OperationResult){ + self.isSignedIn = isComplete(res: res) + self.signInStep = setState(res: res) + self.additionalInfo = setAdditionalInfo(res: res) + self.codeDeliveryDetails = setCodeDeliveryDetails(res: res) + } + + func toJSON() -> Dictionary { + return [ + "isSignedIn": self.isSignedIn, + "nextStep": [ + "signInStep": self.signInStep, + "additionalInfo": self.additionalInfo, + "codeDeliveryDetails": self.codeDeliveryDetails + ] + ] + } +} + +func isComplete(res: AmplifyOperation.OperationResult) -> Bool { + var complete: Bool = false; + switch res { + case .success(let signInResult): + complete = signInResult.isSignedIn + case .failure: + complete = false + } + return complete; +} + +func setCodeDeliveryDetails(res: AmplifyOperation.OperationResult) -> [String: String] { + var deliveryMap:[String: String] = [:] + switch res { + case .success(let signInResult): + if case let .confirmSignInWithSMSMFACode(deliveryDetails, _) = signInResult.nextStep { + if case let .sms(e) = deliveryDetails.destination { + deliveryMap["destination"] = e! as String + deliveryMap["attributeName"] = "sms" + deliveryMap["deliveryMedium"] = "SMS" + } + } + if case .resetPassword(_) = signInResult.nextStep { + deliveryMap = ["deliveryMedium" : "UNKNOWN"] + } + if case .confirmSignInWithCustomChallenge(_) = signInResult.nextStep { + deliveryMap = [:] + } + if case .confirmSignInWithNewPassword(_) = signInResult.nextStep { + deliveryMap = [:] + } + if case .done = signInResult.nextStep { + deliveryMap = [:] + } + case .failure: + deliveryMap = [:] + } + return deliveryMap +} + +func setAdditionalInfo(res: AmplifyOperation.OperationResult) -> [String: String] { + var infoMap: [String: String] = [:] + switch res { + case .success(let signInResult): + if case let .confirmSignInWithSMSMFACode(_, additionalInfo) = signInResult.nextStep { + infoMap = additionalInfo ?? [:] + } + if case let .resetPassword(additionalInfo) = signInResult.nextStep { + infoMap = additionalInfo ?? [:] + } + if case let .confirmSignInWithCustomChallenge(additionalInfo) = signInResult.nextStep { + infoMap = additionalInfo ?? [:] + } + if case let .confirmSignInWithNewPassword(additionalInfo) = signInResult.nextStep { + infoMap = additionalInfo ?? [:] + } + if case .done = signInResult.nextStep { + infoMap = [:] + } + case .failure: + infoMap = [:] + } + return infoMap +} + +func setState(res: AmplifyOperation.OperationResult) -> String { + let state: String = "ERROR" + switch res { + case .success(let signInResult): + if case .done = signInResult.nextStep { + return "DONE" + } + if case .confirmSignInWithSMSMFACode = signInResult.nextStep { + return "CONFIRM_SIGN_IN_WITH_SMS_MFA_CODE" + } + if case .confirmSignInWithNewPassword = signInResult.nextStep { + return "CONFIRM_SIGN_IN_WITH_NEW_PASSWORD" + } + if case .confirmSignInWithCustomChallenge = signInResult.nextStep { + return "CONFIRM_SIGN_IN_WITH_CUSTOM_CHALLENGE" + } + if case .resetPassword = signInResult.nextStep { + return "RESET_PASSWORD" + } + case .failure: + return "ERROR" + } + return state +} + + + diff --git a/packages/amplify_auth_cognito/ios/Classes/FlutterSignOutRequest.swift b/packages/amplify_auth_cognito/ios/Classes/FlutterSignOutRequest.swift new file mode 100644 index 0000000000..e9d90288c6 --- /dev/null +++ b/packages/amplify_auth_cognito/ios/Classes/FlutterSignOutRequest.swift @@ -0,0 +1,26 @@ +// +// FlutterSignOutRequest.swift +// amplify_auth_cognito +// +// Created by Noyes, Dustin on 7/23/20. +// + +import Foundation +import Amplify + +struct FlutterSignOutRequest { + var options: AuthSignOutRequest.Options? + var providerOptions: Dictionary? = [:] + init(dict: NSMutableDictionary){ + self.options = setOptions(dict: dict) + self.providerOptions = dict["providerOptions"] as! Dictionary? + } +} + +func setOptions(dict: NSMutableDictionary) -> AuthSignOutRequest.Options { + if (dict["providerOptions"] != nil) { + return AuthSignOutRequest.Options(globalSignOut: true) + } else { + return AuthSignOutRequest.Options(globalSignOut: false) + } +} diff --git a/packages/amplify_auth_cognito/ios/Classes/FlutterSignOutResult.swift b/packages/amplify_auth_cognito/ios/Classes/FlutterSignOutResult.swift new file mode 100644 index 0000000000..e4bc548f83 --- /dev/null +++ b/packages/amplify_auth_cognito/ios/Classes/FlutterSignOutResult.swift @@ -0,0 +1,36 @@ +// +// FlutterSignOutResult.swift +// amplify_auth_cognito +// +// Created by Noyes, Dustin on 7/23/20. +// + +import Foundation +import Amplify + +struct FlutterSignOutResult { + var signOutState: String + + init(res: AmplifyOperation.OperationResult){ + self.signOutState = setState(res: res) + } + + func toJSON() -> Dictionary { + return [ + "signOutState": self.signOutState, + "providerData": [] + ] + } +} + +func setState(res: AmplifyOperation.OperationResult) -> String { + let state: String = "ERROR" + switch res { + case .success: + return "DONE" + case .failure: + return "ERROR" + } + return state +} + diff --git a/packages/amplify_auth_cognito/ios/Classes/FlutterSignUpRequest.swift b/packages/amplify_auth_cognito/ios/Classes/FlutterSignUpRequest.swift new file mode 100644 index 0000000000..e27f794afc --- /dev/null +++ b/packages/amplify_auth_cognito/ios/Classes/FlutterSignUpRequest.swift @@ -0,0 +1,62 @@ +// +// FlutterSignUpRequest.swift +// amplify_auth +// +// Created by Noyes, Dustin on 7/2/20. +// + +import Foundation +import Amplify +import AmplifyPlugins + +struct FlutterSignUpRequest { + var username: String? + var password: String + var userAttributes: [AuthUserAttribute] = [] + var options: Dictionary? = [:] + let standardAttributes = ["address", "birthdate", "email", "family_name", "gender", "given_name", "locale", "middle_name", "name", "nickname", "phone_number", "preferred_username", "picture", "profile", "updated_at", "website", "zoneinfo"] + init(dict: NSMutableDictionary){ + self.username = dict["username"] as? String + self.password = dict["password"] as! String + self.options = dict["options"] as? Dictionary + self.userAttributes = self.formatUserAttributes(options: dict["options"] as! Dictionary) + } + + func formatUserAttributes(options: Dictionary) -> [AuthUserAttribute] { + let rawAttributes: Dictionary = options["userAttributes"] as! Dictionary + var formattedAttributes: Array = Array() + for attr in rawAttributes { + if (standardAttributes.contains(attr.key)) { + formattedAttributes.append(AuthUserAttribute(.unknown(attr.key), value: attr.value as! String)) + } else { + formattedAttributes.append(AuthUserAttribute(.custom(attr.key), value: attr.value as! String)) + } + } + return formattedAttributes + } + func getUsername() -> String { + var username: String = "" + let rawAttributes: Dictionary = options?["userAttributes"] as! Dictionary + + if (self.options?["usernameAttribute"] == nil && self.username != nil) { + username = self.username! as String; + } else if (self.options?["usernameAttribute"] != nil) { + if (self.options?["usernameAttribute"] as! String == "email") { + username = rawAttributes["email"] as! String + } else { + username = rawAttributes["phone_number"] as! String + } + } + return username + } + + static func validate(dict: NSMutableDictionary) -> Bool { + var valid: Bool = true; + if (dict["options"] == nil) { + valid = false; + } else if (dict["password"] == nil) { + valid = false; + } + return valid; + } +} diff --git a/packages/amplify_auth_cognito/ios/Classes/FlutterSignUpResult.swift b/packages/amplify_auth_cognito/ios/Classes/FlutterSignUpResult.swift new file mode 100644 index 0000000000..f34967259e --- /dev/null +++ b/packages/amplify_auth_cognito/ios/Classes/FlutterSignUpResult.swift @@ -0,0 +1,107 @@ +// +// FlutterSignUpResult.swift +// Amplify +// +// Created by Noyes, Dustin on 7/20/20. +// +import Flutter +import Foundation +import Amplify + +struct FlutterSignUpResult { + var isSignUpComplete: Bool + var signUpStep: String; + var additionalInfo: [String: String] + var codeDeliveryDetails: [String: String] + + init(res: AmplifyOperation.OperationResult){ + self.isSignUpComplete = isComplete(res: res) + self.signUpStep = setState(res: res) + self.additionalInfo = setAdditionalInfo(res: res) + self.codeDeliveryDetails = setCodeDeliveryDetails(res: res) + } + + func toJSON() -> Dictionary { + return [ + "isSignUpComplete": self.isSignUpComplete, + "nextStep": [ + "signUpStep": self.signUpStep, + "additionalInfo": self.additionalInfo, + "codeDeliveryDetails": self.codeDeliveryDetails + ] + ] + } +} + +func isComplete(res: AmplifyOperation.OperationResult) -> Bool { + var complete: Bool = false; + switch res { + case .success(let signUpResult): + complete = signUpResult.isSignupComplete + case .failure: + complete = false + } + return complete; +} + +func setCodeDeliveryDetails(res: AmplifyOperation.OperationResult) -> [String: String] { + var deliveryMap: [String: String] = [:] + switch res { + case .success(let signUpResult): + if case let .confirmUser(deliveryDetails, _) = signUpResult.nextStep { + if case let .email(e) = deliveryDetails?.destination { + deliveryMap["destination"] = e! as String + deliveryMap["attributeName"] = "email" + deliveryMap["deliveryMedium"] = "EMAIL" + } + + if case let .phone(e) = deliveryDetails?.destination { + deliveryMap["destination"] = e! as String + deliveryMap["attributeName"] = "phone" + } + + if case let .sms(e) = deliveryDetails?.destination { + deliveryMap["destination"] = e! as String + deliveryMap["attributeName"] = "sms" + deliveryMap["deliveryMedium"] = "SMS" + } + + if case let .unknown(e) = deliveryDetails?.destination { + deliveryMap["destination"] = e! as String + deliveryMap["attributeName"] = "unknown" + } + } + case .failure: + deliveryMap = [:] + } + return deliveryMap +} + +func setAdditionalInfo(res: AmplifyOperation.OperationResult) -> [String: String] { + var infoMap: [String: String] = [:] + switch res { + case .success(let signUpResult): + if case let .confirmUser(_, additionalInfo) = signUpResult.nextStep { + infoMap = additionalInfo ?? [:] + } + case .failure: + infoMap = [:] + } + return infoMap +} + +func setState(res: AmplifyOperation.OperationResult) -> String { + let state: String = "ERROR" + switch res { + case .success(let signUpResult): + if case .done = signUpResult.nextStep { + return "DONE" + } + if case .confirmUser = signUpResult.nextStep { + return "CONFIRM_SIGN_UP_STEP" + } + case .failure: + return "ERROR" + } + return state +} diff --git a/packages/amplify_auth_cognito/ios/Classes/SwiftAuthCognito.swift b/packages/amplify_auth_cognito/ios/Classes/SwiftAuthCognito.swift new file mode 100644 index 0000000000..2c435457ac --- /dev/null +++ b/packages/amplify_auth_cognito/ios/Classes/SwiftAuthCognito.swift @@ -0,0 +1,222 @@ +import Flutter +import UIKit +import Amplify +import AmplifyPlugins +import AWSCore + +public class SwiftAuthCognito: NSObject, FlutterPlugin { + + public static func register(with registrar: FlutterPluginRegistrar) { + let channel = FlutterMethodChannel(name: "com.amazonaws.amplify/auth_cognito", binaryMessenger: registrar.messenger()) + let instance = SwiftAuthCognito() + registrar.addMethodCallDelegate(instance, channel: channel) + let authPlugin = AWSCognitoAuthPlugin() + do { + try Amplify.add(plugin: authPlugin) + } catch { + print("Failed to add AWSCognitoAuthPlugin to Amplify \(error)") + } + } + + + public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { + switch call.method { + case "signUp": + let arguments = call.arguments as! Dictionary + if (FlutterSignUpRequest.validate(dict: arguments["data"] as! NSMutableDictionary)) { + let request = FlutterSignUpRequest(dict: arguments["data"] as! NSMutableDictionary) + onSignUp(flutterResult: result, request: request) + } else { + print("SignUp Request was malformed.") + let errorCode = "UNKNOWN" + self.prepareError(flutterResult: result, msg: FlutterAuthErrorMessage.MALFORMED.rawValue, errorMap: self.formatErrorMap(errorCode: errorCode)) + } + case "confirmSignUp": + let arguments = call.arguments as! Dictionary + if (FlutterConfirmSignUpRequest.validate(dict: arguments["data"] as! NSMutableDictionary)) { + let request = FlutterConfirmSignUpRequest(dict: arguments["data"] as! NSMutableDictionary) + onConfirmSignUp(flutterResult: result, request: request) + } else { + print("ConfirmSignUp Request was malformed.") + let errorCode = "UNKNOWN" + self.prepareError(flutterResult: result, msg: FlutterAuthErrorMessage.MALFORMED.rawValue, errorMap: self.formatErrorMap(errorCode: errorCode)) + } + case "signIn": + let arguments = call.arguments as! Dictionary + if (FlutterSignInRequest.validate(dict: arguments["data"] as! NSMutableDictionary)) { + let request = FlutterSignInRequest(dict: arguments["data"] as! NSMutableDictionary) + onSignIn(flutterResult: result, request: request) + } else { + print("SignIn Request was malformed.") + let errorCode = "UNKNOWN" + self.prepareError(flutterResult: result, msg: FlutterAuthErrorMessage.MALFORMED.rawValue, errorMap: self.formatErrorMap(errorCode: errorCode)) + } + case "confirmSignIn": + let arguments = call.arguments as! Dictionary + if (FlutterConfirmSignInRequest.validate(dict: arguments["data"] as! NSMutableDictionary)) { + let request = FlutterConfirmSignInRequest(dict: arguments["data"] as! NSMutableDictionary) + onConfirmSignIn(flutterResult: result, request: request) + } else { + print("ConfirmSignIn Request was malformed.") + let errorCode = "UNKNOWN" + self.prepareError(flutterResult: result, msg: FlutterAuthErrorMessage.MALFORMED.rawValue, errorMap: self.formatErrorMap(errorCode: errorCode)) + } + case "signOut": + let arguments = call.arguments as! Dictionary + let dict = arguments["data"] != nil && !(arguments["data"] is NSNull) ? arguments["data"] as! NSMutableDictionary : NSMutableDictionary() + let request = FlutterSignOutRequest(dict: dict) + onSignOut(flutterResult: result, request: request) + default: + result(FlutterMethodNotImplemented) + } + } + + + + private func onSignUp(flutterResult: @escaping FlutterResult, request: FlutterSignUpRequest) { + let options = AuthSignUpRequest.Options(userAttributes: request.userAttributes) + + _ = Amplify.Auth.signUp(username: request.getUsername(), password:request.password, options: options) { response in + switch response { + case .success: + let signUpData = FlutterSignUpResult(res: response) + flutterResult(signUpData.toJSON()) + case .failure(let signUpError): + print("An error occurred while registering a user") + if case .service( let localizedError, let recoverySuggestion, let error) = signUpError { + let errorCode = error != nil ? "\(error!)" : "UNKNOWN" + var errorMap: [String: Any] = self.formatErrorMap(errorCode: errorCode, localizedError: localizedError) + errorMap["PLATFORM_EXCEPTIONS"] = self.platformExceptions(localizedError: localizedError, recoverySuggestion: recoverySuggestion) + self.prepareError(flutterResult: flutterResult, msg: FlutterAuthErrorMessage.SIGNUP.rawValue, errorMap: errorMap) + } + } + } + } + + private func onConfirmSignUp(flutterResult: @escaping FlutterResult, request: FlutterConfirmSignUpRequest) { + _ = Amplify.Auth.confirmSignUp(for: request.username!, confirmationCode:request.confirmationCode!) { response in + switch response { + case .success: + let signUpData = FlutterSignUpResult(res: response) + flutterResult(signUpData.toJSON()) + + case .failure(let signUpError): + print("An error occurred while registering a user") + if case .service( let localizedError, let recoverySuggestion, let error) = signUpError { + let errorCode = error != nil ? "\(error!)" : "UNKNOWN" + var errorMap: [String: Any] = self.formatErrorMap(errorCode: errorCode, localizedError: localizedError) + errorMap["PLATFORM_EXCEPTIONS"] = self.platformExceptions(localizedError: localizedError, recoverySuggestion: recoverySuggestion) + self.prepareError(flutterResult: flutterResult, msg: FlutterAuthErrorMessage.SIGNUP.rawValue, errorMap: errorMap) + } + } + } + } + + private func onSignIn(flutterResult: @escaping FlutterResult, request: FlutterSignInRequest) { + _ = Amplify.Auth.signIn(username: request.username!, password:request.password!) { response in + switch response { + case .success: + let signInData = FlutterSignInResult(res: response) + flutterResult(signInData.toJSON()) + + case .failure(let signInError): + print("An error occurred while initiating auth") + if case .service( let localizedError, let recoverySuggestion, let error) = signInError { + let errorCode = error != nil ? "\(error!)" : "UNKNOWN" + var errorMap: [String: Any] = self.formatErrorMap(errorCode: errorCode, localizedError: localizedError) + errorMap["PLATFORM_EXCEPTIONS"] = self.platformExceptions(localizedError: localizedError, recoverySuggestion: recoverySuggestion) + self.prepareError(flutterResult: flutterResult, msg: FlutterAuthErrorMessage.SIGNUP.rawValue, errorMap: errorMap) + } + } + } + } + + private func onConfirmSignIn(flutterResult: @escaping FlutterResult, request: FlutterConfirmSignInRequest) { + _ = Amplify.Auth.confirmSignIn(challengeResponse: request.confirmationCode) { response in + switch response { + case .success: + let signInData = FlutterSignInResult(res: response) + flutterResult(signInData.toJSON()) + case .failure(let signInError): + print("An error occurred while confirming a sign in") + if case .service( let localizedError, let recoverySuggestion, let error) = signInError { + let errorCode = error != nil ? "\(error!)" : "UNKNOWN" + var errorMap: [String: Any] = self.formatErrorMap(errorCode: errorCode, localizedError: localizedError) + errorMap["PLATFORM_EXCEPTIONS"] = self.platformExceptions(localizedError: localizedError, recoverySuggestion: recoverySuggestion) + self.prepareError(flutterResult: flutterResult, msg: FlutterAuthErrorMessage.SIGNUP.rawValue, errorMap: errorMap) + } + } + } + } + + private func onSignOut(flutterResult: @escaping FlutterResult, request: FlutterSignOutRequest) { + _ = Amplify.Auth.signOut(options: request.options) { response in + switch response { + case .success: + let signOutData = FlutterSignOutResult(res: response) + flutterResult(signOutData.toJSON()) + + case .failure(let signOutError): + print("An error occurred while initiating auth") + if case .service( let localizedError, let recoverySuggestion, let error) = signOutError { + let errorCode = error != nil ? "\(error!)" : "UNKNOWN" + var errorMap: [String: Any] = self.formatErrorMap(errorCode: errorCode, localizedError: localizedError) + errorMap["PLATFORM_EXCEPTIONS"] = self.platformExceptions(localizedError: localizedError, recoverySuggestion: recoverySuggestion) + self.prepareError(flutterResult: flutterResult, msg: FlutterAuthErrorMessage.SIGNUP.rawValue, errorMap: errorMap) + } + } + } + } + + private func prepareError(flutterResult: FlutterResult, msg: String, errorMap: [String: Any]) { + flutterResult(FlutterError( + code: "AmplifyException", + message: msg, + details: errorMap)) + } + + private func platformExceptions(localizedError: String, recoverySuggestion: String) -> [String: String] { + var platformDict: [String: String] = [:] + platformDict["platform"] = "iOS" + platformDict["localalizedError"] = localizedError + platformDict["recoverySuggestion"] = recoverySuggestion + return platformDict + } + + private func formatErrorMap(errorCode: String, localizedError: String = "") -> [String: Any] { + var errorDict: [String: Any] = [:] + // should consider doing this with string manipulation, but that could be fragile + switch errorCode { + case "invalidParameter": + errorDict["INVALID_PARAMETER"] = localizedError + case "usernameExists": + errorDict["USERNAME_EXISTS"] = localizedError + case "aliasExists": + errorDict["ALIAS_EXISTS"] = localizedError + case "codeDeliveryFailure": + errorDict["CODE_DELIVERY_FAILURE"] = localizedError + case "internalError": + errorDict["INTERNAL_ERROR"] = localizedError + case "invalidLambdaResponse": + errorDict["INVALID_LAMBDA_RESPONSE"] = localizedError + case "invalidPassword": + errorDict["INVALID_PASSWORD"] = localizedError + case "notAuthorized": + errorDict["NOT_AUTHORIZED"] = localizedError + case "resourceNotFound": + errorDict["RESOURCE_NOT_FOUND"] = localizedError + case "tooManyRequests": + errorDict["TOO_MANY_REQUESTS"] = localizedError + case "unexpectedLambda": + errorDict["UNEXPECTED_LAMBDA"] = localizedError + case "userLambdaValidation": + errorDict["USER_LAMBDA_VALIDATION"] = localizedError + case "tooManyFailedAttempts": + errorDict["TOO_MANY_FAILED_ATTEMPTS"] = localizedError + default: + errorDict["UNKNOWN"] = "An unrecognized error has occurred. See logs for details." + } + return errorDict + } +} + diff --git a/packages/amplify_auth_cognito/ios/amplify_auth_cognito.podspec b/packages/amplify_auth_cognito/ios/amplify_auth_cognito.podspec new file mode 100644 index 0000000000..db14fdc408 --- /dev/null +++ b/packages/amplify_auth_cognito/ios/amplify_auth_cognito.podspec @@ -0,0 +1,27 @@ +# +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. +# Run `pod lib lint amplify_auth_cognito.podspec' to validate before publishing. +# +Pod::Spec.new do |s| + s.name = 'amplify_auth_cognito' + s.version = '0.0.1' + s.summary = 'The auth module for Amplify Flutter.' + s.description = <<-DESC + The auth module for Amplify Flutter. + DESC + s.homepage = 'https://github.com/aws-amplify/amplify-flutter' + s.license = 'Apache License, Version 2.0' + s.author = { 'Amazon Web Services' => 'amazonwebservices' } + s.source = { :git => 'https://github.com/aws-amplify/amplify-flutter.git' } + s.source_files = 'Classes/**/*' + s.dependency 'Flutter' + s.dependency 'Amplify' + s.dependency 'AmplifyPlugins/AWSCognitoAuthPlugin' + s.dependency 'ObjectMapper' + s.dependency 'SwiftyJSON' + s.platform = :ios, '11.0' + + # Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported. + s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' } + s.swift_version = '5.0' +end diff --git a/packages/amplify_auth_cognito/lib/amplify_auth_cognito.dart b/packages/amplify_auth_cognito/lib/amplify_auth_cognito.dart new file mode 100644 index 0000000000..862c7a32bf --- /dev/null +++ b/packages/amplify_auth_cognito/lib/amplify_auth_cognito.dart @@ -0,0 +1,53 @@ +import 'dart:async'; +import 'dart:core'; +import 'package:amplify_auth_plugin_interface/amplify_auth_plugin_interface.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/foundation.dart'; +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; +import './method_channel_auth_cognito.dart'; + + +export './src/types.dart'; +export 'package:amplify_auth_plugin_interface/src/types.dart'; + +class AmplifyAuthCognito extends AuthPluginInterface { + + static final Object _token = Object(); + + /// Constructs a AmplifyAuthCognito plugin + AmplifyAuthCognito() : super(token: _token); + + static AmplifyAuthCognito _instance = AmplifyAuthCognitoMethodChannel(); + + static set instance(AuthPluginInterface instance) { + PlatformInterface.verifyToken(instance, _token); + _instance = instance; + } + + Future signUp({@required SignUpRequest request}) async { + var res = await _instance.signUp(request: request); + return res; + } + + Future confirmSignUp({@required ConfirmSignUpRequest request}) async { + var res = await _instance.confirmSignUp(request: request); + return res; + } + + Future signIn({@required SignInRequest request}) async { + var res = await _instance.signIn(request: request); + return res; + } + + Future confirmSignIn({@required ConfirmSignInRequest request}) async { + var res = await _instance.confirmSignIn(request: request); + return res; + } + + Future signOut({SignOutRequest request}) async { + var res = await _instance.signOut(request: request); + return res; + } + +} + diff --git a/packages/amplify_auth_cognito/lib/method_channel_auth_cognito.dart b/packages/amplify_auth_cognito/lib/method_channel_auth_cognito.dart new file mode 100644 index 0000000000..255421fd75 --- /dev/null +++ b/packages/amplify_auth_cognito/lib/method_channel_auth_cognito.dart @@ -0,0 +1,142 @@ +import 'dart:collection'; + +import 'package:flutter/services.dart'; +import 'dart:convert'; +import 'package:amplify_auth_plugin_interface/amplify_auth_plugin_interface.dart'; +import 'amplify_auth_cognito.dart'; + +const MethodChannel _channel = MethodChannel('com.amazonaws.amplify/auth_cognito'); + +/// An implementation of [AmplifyPlatform] that uses method channels. +class AmplifyAuthCognitoMethodChannel extends AmplifyAuthCognito { + + @override + + Future signUp({SignUpRequest request}) async { + SignUpResult res; + try { + final Map data = + await _channel.invokeMapMethod( + 'signUp', + { + 'data': request.serializeAsMap(), + }, + ); + res = _formatSignUpResponse(data); + } on PlatformException catch(e) { + _throwError(e); + } + return res; + } + + @override + Future confirmSignUp({ConfirmSignUpRequest request}) async { + SignUpResult res; + try { + final Map data = + await _channel.invokeMapMethod( + 'confirmSignUp', + { + 'data': request.serializeAsMap(), + }, + ); + res = _formatSignUpResponse(data); + return res; + } on PlatformException catch(e) { + _throwError(e); + } + return res; + } + + + @override + Future signIn({SignInRequest request}) async { + SignInResult res; + try { + final Map data = + await _channel.invokeMapMethod( + 'signIn', + { + 'data': request.serializeAsMap(), + }, + ); + res = _formatSignInResponse(data); + return res; + } on PlatformException catch(e) { + _throwError(e); + } + return res; + } + + @override + Future confirmSignIn({ConfirmSignInRequest request}) async { + SignInResult res; + try { + final Map data = + await _channel.invokeMapMethod( + 'confirmSignIn', + { + 'data': request != null ? request.serializeAsMap() : null, + }, + ); + res = _formatSignInResponse(data); + return res; + } on PlatformException catch(e) { + _throwError(e); + } + return res; + } + + @override + Future signOut({SignOutRequest request}) async { + SignOutResult res; + try { + final Map data = + await _channel.invokeMapMethod( + 'signOut', + { + 'data': request != null ? request.serializeAsMap() : null, + }, + ); + res = _formatSignOutResponse(data); + return res; + } on PlatformException catch(e) { + _throwError(e); + } + return res; + } + + SignUpResult _formatSignUpResponse(Map res) { + return CognitoSignUpResult( isSignUpComplete: res["isSignUpComplete"], nextStep: AuthNextSignUpStep( + signUpStep: res["nextStep"]["signUpStep"], + codeDeliveryDetails: res["nextStep"]["codeDeliveryDetails"], + additionalInfo: res["nextStep"]["additionalInfo"] is String ? jsonDecode(res["nextStep"]["additionalInfo"]) : {} + )); + } + + SignInResult _formatSignInResponse(Map res) { + return CognitoSignInResult( isSignedIn: res["isSignedIn"], nextStep: AuthNextSignInStep( + signInStep: res["nextStep"]["signInStep"], + codeDeliveryDetails: res["nextStep"]["codeDeliveryDetails"], + additionalInfo: res["nextStep"]["additionalInfo"] is String ? jsonDecode(res["nextStep"]["additionalInfo"]) : {} + )); + } + + void _throwError(PlatformException e) { + LinkedHashMap eMap = new LinkedHashMap(); + e.details.forEach((k, v) => { + if (cognitoSignUpException.contains(k)) { + eMap.putIfAbsent(k, () => v) + } else { + eMap.putIfAbsent("UNRECOGNIZED EXCEPTION", () => "See logs for details") + } + }); + AuthError error = AuthError.init(cause: e.message, errorMap: eMap); + throw(error); + } + + SignOutResult _formatSignOutResponse(Map signOutResponse) { + return SignOutResult(); + } +} + diff --git a/packages/amplify_auth_cognito/lib/src/CognitoSignIn/CognitoConfirmSignInOptions.dart b/packages/amplify_auth_cognito/lib/src/CognitoSignIn/CognitoConfirmSignInOptions.dart new file mode 100644 index 0000000000..a97e35fa44 --- /dev/null +++ b/packages/amplify_auth_cognito/lib/src/CognitoSignIn/CognitoConfirmSignInOptions.dart @@ -0,0 +1,14 @@ +import 'package:amplify_auth_plugin_interface/amplify_auth_plugin_interface.dart'; + +class CognitoConfirmSignInOptions extends ConfirmSignInOptions { + Map clientMetadata; + CognitoConfirmSignInOptions({this.clientMetadata}) : super(); + Map serializeAsMap() { + final Map pendingRequest = {}; + if (this.clientMetadata != null) { + pendingRequest["validationData"] = clientMetadata; + } + return pendingRequest; + } +} + diff --git a/packages/amplify_auth_cognito/lib/src/CognitoSignIn/CognitoSignInExceptions.dart b/packages/amplify_auth_cognito/lib/src/CognitoSignIn/CognitoSignInExceptions.dart new file mode 100644 index 0000000000..9095429025 --- /dev/null +++ b/packages/amplify_auth_cognito/lib/src/CognitoSignIn/CognitoSignInExceptions.dart @@ -0,0 +1,16 @@ +enum CognitoSignInException { + INVALID_PARAMETER, + INTERNAL_ERROR, + INVALID_LAMBDA_RESPONSE, + INVALID_SMS_ROLE_ACCESS_POLICY, + INVALID_SMS_ROLE_TRUST_RELATIONSHIP, + INVALID_USER_POOL_CONFIGURATION, + NOT_AUTHORIZED, + PASSWORD_RESET_REQUIRED, + RESOURCE_NOT_FOUND, + TOO_MANY_REQUESTS, + UNEXPECTED_LAMBDA, + USER_LAMBDA_VALIDATION, + USER_NOT_CONFIRMED, + USER_NOT_FOUND_EXCEPTION, +} diff --git a/packages/amplify_auth_cognito/lib/src/CognitoSignIn/CognitoSignInOptions.dart b/packages/amplify_auth_cognito/lib/src/CognitoSignIn/CognitoSignInOptions.dart new file mode 100644 index 0000000000..bc753afd24 --- /dev/null +++ b/packages/amplify_auth_cognito/lib/src/CognitoSignIn/CognitoSignInOptions.dart @@ -0,0 +1,14 @@ +import 'package:amplify_auth_plugin_interface/amplify_auth_plugin_interface.dart'; + +class CognitoSignInOptions extends SignInOptions { + Map clientMetadata; + CognitoSignInOptions({this.clientMetadata}) : super(); + Map serializeAsMap() { + final Map pendingRequest = {}; + if (this.clientMetadata != null) { + pendingRequest["validationData"] = clientMetadata; + } + return pendingRequest; + } +} + diff --git a/packages/amplify_auth_cognito/lib/src/CognitoSignIn/CognitoSignInResult.dart b/packages/amplify_auth_cognito/lib/src/CognitoSignIn/CognitoSignInResult.dart new file mode 100644 index 0000000000..92228870ed --- /dev/null +++ b/packages/amplify_auth_cognito/lib/src/CognitoSignIn/CognitoSignInResult.dart @@ -0,0 +1,5 @@ +import 'package:amplify_auth_plugin_interface/amplify_auth_plugin_interface.dart'; + +class CognitoSignInResult extends SignInResult { + CognitoSignInResult({nextStep, isSignedIn}) : super(isSignedIn: isSignedIn, nextStep: nextStep); +} diff --git a/packages/amplify_auth_cognito/lib/src/CognitoSignOut/CognitoSignOutExceptions.dart b/packages/amplify_auth_cognito/lib/src/CognitoSignOut/CognitoSignOutExceptions.dart new file mode 100644 index 0000000000..6edaeac063 --- /dev/null +++ b/packages/amplify_auth_cognito/lib/src/CognitoSignOut/CognitoSignOutExceptions.dart @@ -0,0 +1,10 @@ +enum CognitoSignOutException { + INVALID_PARAMETER, + INTERNAL_ERROR, + NOT_AUTHORIZED, + PASSWORD_RESET_REQUIRED, + RESOURCE_NOT_FOUND, + TOO_MANY_REQUESTS, + USER_NOT_CONFIRMED, + UNKNOWN, +} diff --git a/packages/amplify_auth_cognito/lib/src/CognitoSignOut/CognitoSignOutOptions.dart b/packages/amplify_auth_cognito/lib/src/CognitoSignOut/CognitoSignOutOptions.dart new file mode 100644 index 0000000000..c30da97096 --- /dev/null +++ b/packages/amplify_auth_cognito/lib/src/CognitoSignOut/CognitoSignOutOptions.dart @@ -0,0 +1,13 @@ +import 'package:amplify_auth_plugin_interface/amplify_auth_plugin_interface.dart'; + +class CognitoSignOutOptions extends SignOutOptions { + bool globalSignOut; + CognitoSignOutOptions({this.globalSignOut}) : super(); + Map serializeAsMap() { + final Map pendingRequest = {}; + if (this.globalSignOut != null) { + pendingRequest["globalSignOut"] = globalSignOut; + } + return pendingRequest; + } +} \ No newline at end of file diff --git a/packages/amplify_auth_cognito/lib/src/CognitoSignUp/CognitoConfirmSignUpOptions.dart b/packages/amplify_auth_cognito/lib/src/CognitoSignUp/CognitoConfirmSignUpOptions.dart new file mode 100644 index 0000000000..aa1d371c3d --- /dev/null +++ b/packages/amplify_auth_cognito/lib/src/CognitoSignUp/CognitoConfirmSignUpOptions.dart @@ -0,0 +1,13 @@ +import 'package:amplify_auth_plugin_interface/amplify_auth_plugin_interface.dart'; + +class CognitoConfirmSignUpOptions extends ConfirmSignUpOptions { + Map validationData; + CognitoConfirmSignUpOptions({this.validationData}) : super(); + Map serializeAsMap() { + final Map pendingRequest = {}; + if (this.validationData != null) { + pendingRequest["validationData"] = validationData; + } + return pendingRequest; + } +} \ No newline at end of file diff --git a/packages/amplify_auth_cognito/lib/src/CognitoSignUp/CognitoSignUpExceptions.dart b/packages/amplify_auth_cognito/lib/src/CognitoSignUp/CognitoSignUpExceptions.dart new file mode 100644 index 0000000000..78184b5f80 --- /dev/null +++ b/packages/amplify_auth_cognito/lib/src/CognitoSignUp/CognitoSignUpExceptions.dart @@ -0,0 +1,19 @@ +var cognitoSignUpException = [ + "INVALID_PARAMETER", + "USERNAME_EXISTS", + "CODE_DELIVERY_FAILURE", + "INTERNAL_ERROR", + "INVALID_LAMBDA_RESPONSE", + "INVALID_PASSWORD", + "NOT_AUTHORIZED", + "RESOURCE_NOT_FOUND", + "TOO_MANY_REQUESTS", + "TOO_MANY_FAILED_REQUESTS", + "UNEXPECTED_LAMBDA", + "USER_LAMBDA_VALIDATION", + "VALIDATION", + "PLATFORM_EXCEPTIONS", + "AMAZON_CLIENT_EXCEPTION", + "AMAZON_SERVICE_EXCEPTION" +]; + diff --git a/packages/amplify_auth_cognito/lib/src/CognitoSignUp/CognitoSignUpOptions.dart b/packages/amplify_auth_cognito/lib/src/CognitoSignUp/CognitoSignUpOptions.dart new file mode 100644 index 0000000000..e5584c15d8 --- /dev/null +++ b/packages/amplify_auth_cognito/lib/src/CognitoSignUp/CognitoSignUpOptions.dart @@ -0,0 +1,19 @@ +import 'package:amplify_auth_plugin_interface/amplify_auth_plugin_interface.dart'; + +class CognitoSignUpOptions extends SignUpOptions { + String usernameAttribute; + Map validationData; + CognitoSignUpOptions({userAttributes, this.usernameAttribute, this.validationData}) : super(userAttributes: userAttributes); + Map serializeAsMap() { + final Map pendingRequest = {}; + if (this.usernameAttribute != null) { + pendingRequest["usernameAttribute"] = usernameAttribute; + } + if (this.validationData != null) { + pendingRequest["validationData"] = validationData; + } + pendingRequest["userAttributes"] = userAttributes; + return pendingRequest; + } +} + diff --git a/packages/amplify_auth_cognito/lib/src/CognitoSignUp/CognitoSignUpResult.dart b/packages/amplify_auth_cognito/lib/src/CognitoSignUp/CognitoSignUpResult.dart new file mode 100644 index 0000000000..bb7a462679 --- /dev/null +++ b/packages/amplify_auth_cognito/lib/src/CognitoSignUp/CognitoSignUpResult.dart @@ -0,0 +1,5 @@ +import 'package:amplify_auth_plugin_interface/amplify_auth_plugin_interface.dart'; + +class CognitoSignUpResult extends SignUpResult { + CognitoSignUpResult({nextStep, isSignUpComplete}) : super(isSignUpComplete: isSignUpComplete, nextStep: nextStep); +} diff --git a/packages/amplify_auth_cognito/lib/src/types.dart b/packages/amplify_auth_cognito/lib/src/types.dart new file mode 100644 index 0000000000..f9625be79a --- /dev/null +++ b/packages/amplify_auth_cognito/lib/src/types.dart @@ -0,0 +1,17 @@ +// SignUp +export 'CognitoSignUp/CognitoSignUpOptions.dart'; +export 'CognitoSignUp/CognitoSignUpResult.dart'; +export 'CognitoSignUp/CognitoSignUpExceptions.dart'; +export 'CognitoSignUp/CognitoConfirmSignUpOptions.dart'; + +// SignIn +export 'CognitoSignIn/CognitoSignInResult.dart'; +export 'CognitoSignIn/CognitoConfirmSignInOptions.dart'; +export 'CognitoSignIn/CognitoSignInOptions.dart'; + +// SignOut +export 'CognitoSignOut/CognitoSignOutExceptions.dart'; +export 'CognitoSignOut/CognitoSignOutOptions.dart'; +export 'CognitoSignUp/CognitoSignUpResult.dart'; +export 'CognitoSignUp/CognitoSignUpExceptions.dart'; +export 'CognitoSignUp/CognitoSignUpOptions.dart'; diff --git a/packages/amplify_auth_cognito/pubspec.yaml b/packages/amplify_auth_cognito/pubspec.yaml new file mode 100644 index 0000000000..3287c83f24 --- /dev/null +++ b/packages/amplify_auth_cognito/pubspec.yaml @@ -0,0 +1,71 @@ +name: amplify_auth_cognito +description: A new flutter plugin project. +version: 0.0.1 +author: +homepage: + +environment: + sdk: ">=2.7.0 <3.0.0" + flutter: ">=1.10.0" + +dependencies: + flutter: + sdk: flutter + amplify_auth_plugin_interface: + path: ../amplify_auth_plugin_interface + plugin_platform_interface: ^1.0.1 + # amplify_core included only for testing: should be removed after pub.dev up and running + amplify_core: + path: ../amplify_core + +dev_dependencies: + flutter_test: + sdk: flutter + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + # This section identifies this Flutter project as a plugin project. + # The 'pluginClass' and Android 'package' identifiers should not ordinarily + # be modified. They are used by the tooling to maintain consistency when + # adding or updating assets for this project. + plugin: + platforms: + android: + package: com.amazonaws.amplify.amplify_auth_cognito + pluginClass: AuthCognito + ios: + pluginClass: AuthCognito + + # To add assets to your plugin package, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + # + # For details regarding assets in packages, see + # https://flutter.dev/assets-and-images/#from-packages + # + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware. + + # To add custom fonts to your plugin package, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts in packages, see + # https://flutter.dev/custom-fonts/#from-packages diff --git a/packages/amplify_auth_cognito/test/amplify_auth_cognito_confirmSignup_test.dart b/packages/amplify_auth_cognito/test/amplify_auth_cognito_confirmSignup_test.dart new file mode 100644 index 0000000000..cb5715ccc8 --- /dev/null +++ b/packages/amplify_auth_cognito/test/amplify_auth_cognito_confirmSignup_test.dart @@ -0,0 +1,48 @@ +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:amplify_auth_cognito/amplify_auth_cognito.dart'; +import 'package:amplify_core/amplify_core.dart'; + +void main() { + const MethodChannel authChannel = MethodChannel('com.amazonaws.amplify/auth_cognito'); + const MethodChannel coreChannel = MethodChannel('com.amazonaws.amplify/core'); + + Amplify amplify = new Amplify(); + AmplifyAuthCognito auth = AmplifyAuthCognito(); + + TestWidgetsFlutterBinding.ensureInitialized(); + + setUp(() { + authChannel.setMockMethodCallHandler((MethodCall methodCall) async { + if (methodCall.method == "confirmSignUp") { + return { + "isSignUpComplete": false, + "nextStep": { + "signUpStep": "DONE", + "codeDeliveryDetails": { "atttibuteName": "email" } + } + }; + } else { + return true; + } + }); + coreChannel.setMockMethodCallHandler((MethodCall methodCall) async { + return true; + }); + }); + + tearDown(() { + authChannel.setMockMethodCallHandler(null); + coreChannel.setMockMethodCallHandler(null); + }); + + test('signUp request returns a ConfirmSignUpResult', () async { + await amplify.addPlugin(authPlugin: [auth]); + await amplify.configure("{}"); + ConfirmSignUpRequest req = ConfirmSignUpRequest( + userKey: 'testUser', + confirmationCode: '123', + ); + expect(await Amplify.Auth.confirmSignUp(request: req), isInstanceOf()); + }); +} diff --git a/packages/amplify_auth_cognito/test/amplify_auth_cognito_signOut_test.dart b/packages/amplify_auth_cognito/test/amplify_auth_cognito_signOut_test.dart new file mode 100644 index 0000000000..fd3cc6b1f7 --- /dev/null +++ b/packages/amplify_auth_cognito/test/amplify_auth_cognito_signOut_test.dart @@ -0,0 +1,39 @@ +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:amplify_auth_cognito/amplify_auth_cognito.dart'; +import 'package:amplify_core/amplify_core.dart'; + +void main() { + const MethodChannel authChannel = MethodChannel('com.amazonaws.amplify/auth_cognito'); + const MethodChannel coreChannel = MethodChannel('com.amazonaws.amplify/core'); + + Amplify amplify = new Amplify(); + AmplifyAuthCognito auth = AmplifyAuthCognito(); + + TestWidgetsFlutterBinding.ensureInitialized(); + + setUp(() { + authChannel.setMockMethodCallHandler((MethodCall methodCall) async { + if (methodCall.method == "signOut") { + return {}; + } else { + return true; + } + }); + coreChannel.setMockMethodCallHandler((MethodCall methodCall) async { + return true; + }); + }); + + tearDown(() { + authChannel.setMockMethodCallHandler(null); + coreChannel.setMockMethodCallHandler(null); + }); + + test('signUp request returns a SignOutResult', () async { + await amplify.addPlugin(authPlugin: [auth]); + await amplify.configure("{}"); + SignOutRequest req = SignOutRequest(); + expect(await Amplify.Auth.signOut(request: req), isInstanceOf()); + }); +} diff --git a/packages/amplify_auth_cognito/test/amplify_auth_cognito_signin_test.dart b/packages/amplify_auth_cognito/test/amplify_auth_cognito_signin_test.dart new file mode 100644 index 0000000000..3e3ab6829b --- /dev/null +++ b/packages/amplify_auth_cognito/test/amplify_auth_cognito_signin_test.dart @@ -0,0 +1,48 @@ +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:amplify_auth_cognito/amplify_auth_cognito.dart'; +import 'package:amplify_core/amplify_core.dart'; + +void main() { + const MethodChannel authChannel = MethodChannel('com.amazonaws.amplify/auth_cognito'); + const MethodChannel coreChannel = MethodChannel('com.amazonaws.amplify/core'); + + Amplify amplify = new Amplify(); + AmplifyAuthCognito auth = AmplifyAuthCognito(); + + TestWidgetsFlutterBinding.ensureInitialized(); + + setUp(() { + authChannel.setMockMethodCallHandler((MethodCall methodCall) async { + if (methodCall.method == "signIn") { + return { + "isSignedIn": false, + "nextStep": { + "signInStep": "DONE", + "codeDeliveryDetails": { "atttibuteName": "email" } + } + }; + } else { + return true; + } + }); + coreChannel.setMockMethodCallHandler((MethodCall methodCall) async { + return true; + }); + }); + + tearDown(() { + authChannel.setMockMethodCallHandler(null); + coreChannel.setMockMethodCallHandler(null); + }); + + test('signUp request returns a SignInResult', () async { + await amplify.addPlugin(authPlugin: [auth]); + await amplify.configure("{}"); + SignInRequest req = SignInRequest( + username: 'testUser', + password: '123', + ); + expect(await Amplify.Auth.signIn(request: req), isInstanceOf()); + }); +} diff --git a/packages/amplify_auth_cognito/test/amplify_auth_cognito_signup_test.dart b/packages/amplify_auth_cognito/test/amplify_auth_cognito_signup_test.dart new file mode 100644 index 0000000000..3b1f584cbc --- /dev/null +++ b/packages/amplify_auth_cognito/test/amplify_auth_cognito_signup_test.dart @@ -0,0 +1,55 @@ +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:amplify_auth_cognito/amplify_auth_cognito.dart'; +import 'package:amplify_core/amplify_core.dart'; + +void main() { + const MethodChannel authChannel = MethodChannel('com.amazonaws.amplify/auth_cognito'); + const MethodChannel coreChannel = MethodChannel('com.amazonaws.amplify/core'); + + Amplify amplify = new Amplify(); + AmplifyAuthCognito auth = AmplifyAuthCognito(); + + TestWidgetsFlutterBinding.ensureInitialized(); + + + + setUp(() { + authChannel.setMockMethodCallHandler((MethodCall methodCall) async { + if (methodCall.method == "signUp") { + return { + "isSignUpComplete": false, + "nextStep": { + "signUpStep": "DONE", + "codeDeliveryDetails": { "atttibuteName": "email" } + } + }; + } else { + return true; + } + }); + coreChannel.setMockMethodCallHandler((MethodCall methodCall) async { + return true; + }); + }); + + tearDown(() { + authChannel.setMockMethodCallHandler(null); + coreChannel.setMockMethodCallHandler(null); + }); + + test('signUp request returns a CognitoSignUpResult', () async { + await amplify.addPlugin(authPlugin: [auth]); + await amplify.configure("{}"); + SignUpRequest req = SignUpRequest( + username: 'testUser', + password: '123', + options: CognitoSignUpOptions( + userAttributes: { + "email": "test@test.com", + "testCode": 0 + }) + ); + expect(await Amplify.Auth.signUp(request: req), isInstanceOf()); + }); +} diff --git a/packages/amplify_auth_plugin_interface/.gitignore b/packages/amplify_auth_plugin_interface/.gitignore new file mode 100644 index 0000000000..bb431f0d5b --- /dev/null +++ b/packages/amplify_auth_plugin_interface/.gitignore @@ -0,0 +1,75 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +build/ + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Flutter.podspec +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/Flutter/flutter_export_environment.sh +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/packages/amplify_auth_plugin_interface/.metadata b/packages/amplify_auth_plugin_interface/.metadata new file mode 100644 index 0000000000..d648d69ac5 --- /dev/null +++ b/packages/amplify_auth_plugin_interface/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: 599566177736e6b30af922a8f06e8a260acafc36 + channel: master + +project_type: package diff --git a/packages/amplify_auth_plugin_interface/CHANGELOG.md b/packages/amplify_auth_plugin_interface/CHANGELOG.md new file mode 100644 index 0000000000..ac071598e5 --- /dev/null +++ b/packages/amplify_auth_plugin_interface/CHANGELOG.md @@ -0,0 +1,3 @@ +## [0.0.1] - TODO: Add release date. + +* TODO: Describe initial release. diff --git a/packages/amplify_auth_plugin_interface/LICENSE b/packages/amplify_auth_plugin_interface/LICENSE new file mode 100644 index 0000000000..19dc35b243 --- /dev/null +++ b/packages/amplify_auth_plugin_interface/LICENSE @@ -0,0 +1,175 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. \ No newline at end of file diff --git a/packages/amplify_auth_plugin_interface/README.md b/packages/amplify_auth_plugin_interface/README.md new file mode 100644 index 0000000000..69c9006fbc --- /dev/null +++ b/packages/amplify_auth_plugin_interface/README.md @@ -0,0 +1,14 @@ +# amplify_auth_plugin_interface + +A new Flutter package project. + +## Getting Started + +This project is a starting point for a Dart +[package](https://flutter.dev/developing-packages/), +a library module containing code that can be shared easily across +multiple Flutter or Dart projects. + +For help getting started with Flutter, view our +[online documentation](https://flutter.dev/docs), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/packages/amplify_auth_plugin_interface/lib/amplify_auth_plugin_interface.dart b/packages/amplify_auth_plugin_interface/lib/amplify_auth_plugin_interface.dart new file mode 100644 index 0000000000..90d2922fb4 --- /dev/null +++ b/packages/amplify_auth_plugin_interface/lib/amplify_auth_plugin_interface.dart @@ -0,0 +1,39 @@ +library amplify_auth_plugin_interface; + +import 'dart:async'; +import 'package:meta/meta.dart'; +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; + +import 'src/types.dart'; +export 'src/types.dart'; + + +abstract class AuthPluginInterface extends PlatformInterface { + /// Constructs a AmplifyPlatform. + AuthPluginInterface({@required Object token}) : super(token: token); + + /// Adds the configuration and return true if it was successful. + bool addPlugin(AuthPluginInterface configuration) { + throw UnimplementedError('configure() has not been implemented.'); + } + + Future signUp({@required SignUpRequest request}) { + throw UnimplementedError('signUp() has not been implemented.'); + } + + Future confirmSignUp({@required ConfirmSignUpRequest request}) { + throw UnimplementedError('confirmSignUp() has not been implemented.'); + } + + Future signIn({@required SignInRequest request}) { + throw UnimplementedError('signIn() has not been implemented.'); + } + + Future signOut({SignOutRequest request}) { + throw UnimplementedError('signOut() has not been implemented.'); + } + + Future confirmSignIn({ConfirmSignInRequest request}) { + throw UnimplementedError('confirmSignIn() has not been implemented.'); + } +} diff --git a/packages/amplify_auth_plugin_interface/lib/src/Errors/AuthError.dart b/packages/amplify_auth_plugin_interface/lib/src/Errors/AuthError.dart new file mode 100644 index 0000000000..0dfa22eedb --- /dev/null +++ b/packages/amplify_auth_plugin_interface/lib/src/Errors/AuthError.dart @@ -0,0 +1,27 @@ +import 'dart:collection'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; +import 'AuthErrorTypes.dart'; + +class AuthError implements Exception { + String cause; + List exceptionList = []; + AuthError.init({@required cause, @required LinkedHashMap errorMap, PlatformException platformException}) { + this.cause = recognizeAuthError(cause) ? cause : "UNRECOGNIZED_AUTH_ERROR"; + errorMap.forEach((k,v) => { + exceptionList.add(AuthException(exception: k, detail: v)) + }); + } +} + +class AuthException { + String exception; + dynamic detail; + AuthException({@required this.exception, this.detail}); +} + +bool recognizeAuthError(authErrorType) { + var match = authErrorTypes.contains(authErrorType); + if (!match) print("Unrecognized auth error returned from platform. See logs for details"); + return match; +} diff --git a/packages/amplify_auth_plugin_interface/lib/src/Errors/AuthErrorTypes.dart b/packages/amplify_auth_plugin_interface/lib/src/Errors/AuthErrorTypes.dart new file mode 100644 index 0000000000..aa680a5210 --- /dev/null +++ b/packages/amplify_auth_plugin_interface/lib/src/Errors/AuthErrorTypes.dart @@ -0,0 +1,10 @@ +var authErrorTypes = [ + "AMPLIFY_CONFIRM_SIGNIN_FAILED", + "AMPLIFY_CONFIRM_SIGNUP_FAILED", + "AMPLIFY_SIGNIN_FAILED", + "AMPLIFY_SIGNOUT_FAILED", + "AMPLIFY_SIGNUP_FAILED", + "AMPLIFY_REQUEST_MALFORMED", + "ERROR_CASTING_INPUT_IN_PLATFORM_CODE", + "PLATFORM_EXCEPTIONS" +]; diff --git a/packages/amplify_auth_plugin_interface/lib/src/SignIn/AuthNextSignInStep.dart b/packages/amplify_auth_plugin_interface/lib/src/SignIn/AuthNextSignInStep.dart new file mode 100644 index 0000000000..1fa0acca0a --- /dev/null +++ b/packages/amplify_auth_plugin_interface/lib/src/SignIn/AuthNextSignInStep.dart @@ -0,0 +1,7 @@ +import 'package:flutter/foundation.dart'; +import '../types/AuthNextStep.dart'; + +class AuthNextSignInStep extends AuthNextStep { + String signInStep; + AuthNextSignInStep({additionalInfo, @required codeDeliveryDetails, @required this.signInStep}) : super(additionalInfo: additionalInfo, codeDeliveryDetails: codeDeliveryDetails); +} diff --git a/packages/amplify_auth_plugin_interface/lib/src/SignIn/ConfirmSignInOptions.dart b/packages/amplify_auth_plugin_interface/lib/src/SignIn/ConfirmSignInOptions.dart new file mode 100644 index 0000000000..a2a9a1fbaf --- /dev/null +++ b/packages/amplify_auth_plugin_interface/lib/src/SignIn/ConfirmSignInOptions.dart @@ -0,0 +1,6 @@ +class ConfirmSignInOptions { + const ConfirmSignInOptions(); + Map serializeAsMap() { + throw UnimplementedError('serializeAsMap() has not been implemented on SignOutOptions.'); + } +} \ No newline at end of file diff --git a/packages/amplify_auth_plugin_interface/lib/src/SignIn/ConfirmSignInRequest.dart b/packages/amplify_auth_plugin_interface/lib/src/SignIn/ConfirmSignInRequest.dart new file mode 100644 index 0000000000..305ed6f8ed --- /dev/null +++ b/packages/amplify_auth_plugin_interface/lib/src/SignIn/ConfirmSignInRequest.dart @@ -0,0 +1,15 @@ +import 'package:flutter/foundation.dart'; + +class ConfirmSignInRequest { + String userKey; + String confirmationValue; + ConfirmSignInRequest({this.userKey, @required this.confirmationValue}); + Map serializeAsMap() { + final Map pendingRequest = {}; + if (userKey != null) { + pendingRequest['username'] = userKey; + } + pendingRequest["confirmationCode"] = confirmationValue; + return pendingRequest; + } +} \ No newline at end of file diff --git a/packages/amplify_auth_plugin_interface/lib/src/SignIn/SignInOptions.dart b/packages/amplify_auth_plugin_interface/lib/src/SignIn/SignInOptions.dart new file mode 100644 index 0000000000..13cec78d59 --- /dev/null +++ b/packages/amplify_auth_plugin_interface/lib/src/SignIn/SignInOptions.dart @@ -0,0 +1,6 @@ +class SignInOptions { + const SignInOptions(); + Map serializeAsMap() { + throw UnimplementedError('serializeAsMap() has not been implemented on SignOutOptions.'); + } +} \ No newline at end of file diff --git a/packages/amplify_auth_plugin_interface/lib/src/SignIn/SignInRequest.dart b/packages/amplify_auth_plugin_interface/lib/src/SignIn/SignInRequest.dart new file mode 100644 index 0000000000..977c49b19c --- /dev/null +++ b/packages/amplify_auth_plugin_interface/lib/src/SignIn/SignInRequest.dart @@ -0,0 +1,15 @@ +class SignInRequest { + String username; + String password; + SignInRequest({this.username, this.password}); + Map serializeAsMap() { + final Map pendingRequest = {}; + if (username != null) { + pendingRequest['username'] = username; + } + if (password != null) { + pendingRequest['password'] = password; + } + return pendingRequest; + } +} \ No newline at end of file diff --git a/packages/amplify_auth_plugin_interface/lib/src/SignIn/SignInResult.dart b/packages/amplify_auth_plugin_interface/lib/src/SignIn/SignInResult.dart new file mode 100644 index 0000000000..da3458375d --- /dev/null +++ b/packages/amplify_auth_plugin_interface/lib/src/SignIn/SignInResult.dart @@ -0,0 +1,12 @@ +import 'package:amplify_auth_plugin_interface/amplify_auth_plugin_interface.dart'; +import 'package:flutter/foundation.dart'; + + +class SignInResult { + bool isSignedIn; + AuthNextSignInStep nextStep; + SignInResult({@required this.isSignedIn, this.nextStep}) { + this.isSignedIn = isSignedIn; + this.nextStep = nextStep; + } +} \ No newline at end of file diff --git a/packages/amplify_auth_plugin_interface/lib/src/SignIn/SignInState.dart b/packages/amplify_auth_plugin_interface/lib/src/SignIn/SignInState.dart new file mode 100644 index 0000000000..070652f9ae --- /dev/null +++ b/packages/amplify_auth_plugin_interface/lib/src/SignIn/SignInState.dart @@ -0,0 +1,13 @@ +enum SignInState { + CONFIRM_SIGN_IN_WITH_SMS_MFA_CODE, + CONFIRM_SIGN_IN_WITH_CUSTOM_CHALLENGE, + CONFIRM_SIGN_IN_WITH_NEW_PASSWORD, + RESET_PASSWORD, + DONE, + ERROR +} + +String enumToString(Object o) => o.toString().split('.').last; + +T enumFromString(String key, List values) => + values.firstWhere((v) => key == enumToString(v), orElse: () => null); \ No newline at end of file diff --git a/packages/amplify_auth_plugin_interface/lib/src/SignOut/SignOutOptions.dart b/packages/amplify_auth_plugin_interface/lib/src/SignOut/SignOutOptions.dart new file mode 100644 index 0000000000..94eb201eda --- /dev/null +++ b/packages/amplify_auth_plugin_interface/lib/src/SignOut/SignOutOptions.dart @@ -0,0 +1,6 @@ +class SignOutOptions { + const SignOutOptions(); + Map serializeAsMap() { + throw UnimplementedError('serializeAsMap() has not been implemented on SignOutOptions.'); + } +} \ No newline at end of file diff --git a/packages/amplify_auth_plugin_interface/lib/src/SignOut/SignOutRequest.dart b/packages/amplify_auth_plugin_interface/lib/src/SignOut/SignOutRequest.dart new file mode 100644 index 0000000000..1b13c3e1e1 --- /dev/null +++ b/packages/amplify_auth_plugin_interface/lib/src/SignOut/SignOutRequest.dart @@ -0,0 +1,8 @@ + +class SignOutRequest { + SignOutRequest(); + Map serializeAsMap() { + final Map pendingRequest = {}; + return pendingRequest; + } +} diff --git a/packages/amplify_auth_plugin_interface/lib/src/SignOut/SignOutResult.dart b/packages/amplify_auth_plugin_interface/lib/src/SignOut/SignOutResult.dart new file mode 100644 index 0000000000..3e0bb7b32b --- /dev/null +++ b/packages/amplify_auth_plugin_interface/lib/src/SignOut/SignOutResult.dart @@ -0,0 +1,3 @@ +class SignOutResult { + SignOutResult() {} +} \ No newline at end of file diff --git a/packages/amplify_auth_plugin_interface/lib/src/SignUp/AuthNextSignUpStep.dart b/packages/amplify_auth_plugin_interface/lib/src/SignUp/AuthNextSignUpStep.dart new file mode 100644 index 0000000000..2b2fe426c0 --- /dev/null +++ b/packages/amplify_auth_plugin_interface/lib/src/SignUp/AuthNextSignUpStep.dart @@ -0,0 +1,7 @@ +import 'package:flutter/foundation.dart'; +import '../types/AuthNextStep.dart'; + +class AuthNextSignUpStep extends AuthNextStep { + String signUpStep; + AuthNextSignUpStep({additionalInfo, @required codeDeliveryDetails, @required this.signUpStep}) : super(additionalInfo: additionalInfo, codeDeliveryDetails: codeDeliveryDetails); +} diff --git a/packages/amplify_auth_plugin_interface/lib/src/SignUp/ConfirmSignUpOptions.dart b/packages/amplify_auth_plugin_interface/lib/src/SignUp/ConfirmSignUpOptions.dart new file mode 100644 index 0000000000..5661b76417 --- /dev/null +++ b/packages/amplify_auth_plugin_interface/lib/src/SignUp/ConfirmSignUpOptions.dart @@ -0,0 +1,6 @@ +class ConfirmSignUpOptions { + const ConfirmSignUpOptions(); + Map serializeAsMap() { + throw UnimplementedError('serializeAsMap() has not been implemented on SignUpOptions.'); + } +} \ No newline at end of file diff --git a/packages/amplify_auth_plugin_interface/lib/src/SignUp/ConfirmSignUpRequest.dart b/packages/amplify_auth_plugin_interface/lib/src/SignUp/ConfirmSignUpRequest.dart new file mode 100644 index 0000000000..0218900794 --- /dev/null +++ b/packages/amplify_auth_plugin_interface/lib/src/SignUp/ConfirmSignUpRequest.dart @@ -0,0 +1,13 @@ +import 'package:flutter/foundation.dart'; + +class ConfirmSignUpRequest { + String userKey; + String confirmationCode; + ConfirmSignUpRequest({@required this.userKey, @required this.confirmationCode}); + Map serializeAsMap() { + final Map pendingRequest = {}; + pendingRequest['userKey'] = userKey; + pendingRequest['confirmationCode'] = confirmationCode; + return pendingRequest; + } +} \ No newline at end of file diff --git a/packages/amplify_auth_plugin_interface/lib/src/SignUp/SignUpOptions.dart b/packages/amplify_auth_plugin_interface/lib/src/SignUp/SignUpOptions.dart new file mode 100644 index 0000000000..d687d8fb70 --- /dev/null +++ b/packages/amplify_auth_plugin_interface/lib/src/SignUp/SignUpOptions.dart @@ -0,0 +1,10 @@ +import 'package:flutter/foundation.dart'; + + class SignUpOptions { + final Map userAttributes; + const SignUpOptions({@required this.userAttributes}); + + Map serializeAsMap() { + throw UnimplementedError('serializeAsMap() has not been implemented on SignUpOptions.'); + } +} \ No newline at end of file diff --git a/packages/amplify_auth_plugin_interface/lib/src/SignUp/SignUpRequest.dart b/packages/amplify_auth_plugin_interface/lib/src/SignUp/SignUpRequest.dart new file mode 100644 index 0000000000..046b92672c --- /dev/null +++ b/packages/amplify_auth_plugin_interface/lib/src/SignUp/SignUpRequest.dart @@ -0,0 +1,19 @@ +import './SignUpOptions.dart'; +import 'package:flutter/foundation.dart'; + +class SignUpRequest { + String username; + String password; + SignUpOptions options; + + SignUpRequest({this.username, @required this.password, @required this.options}); + Map serializeAsMap() { + final Map pendingRequest = {}; + if (username != null) { + pendingRequest['username'] = username; + } + pendingRequest['password'] = password; + pendingRequest['options'] = options.serializeAsMap(); + return pendingRequest; + } +} diff --git a/packages/amplify_auth_plugin_interface/lib/src/SignUp/SignUpResult.dart b/packages/amplify_auth_plugin_interface/lib/src/SignUp/SignUpResult.dart new file mode 100644 index 0000000000..bbca93b1d8 --- /dev/null +++ b/packages/amplify_auth_plugin_interface/lib/src/SignUp/SignUpResult.dart @@ -0,0 +1,11 @@ +import './AuthNextSignUpStep.dart'; +import 'package:flutter/foundation.dart'; + +class SignUpResult { + bool isSignUpComplete; + AuthNextSignUpStep nextStep; + SignUpResult({@required this.isSignUpComplete, @required this.nextStep}) { + this.isSignUpComplete = isSignUpComplete; + this.nextStep = nextStep; + } +} diff --git a/packages/amplify_auth_plugin_interface/lib/src/SignUp/SignUpState.dart b/packages/amplify_auth_plugin_interface/lib/src/SignUp/SignUpState.dart new file mode 100644 index 0000000000..ed7600d438 --- /dev/null +++ b/packages/amplify_auth_plugin_interface/lib/src/SignUp/SignUpState.dart @@ -0,0 +1,5 @@ +enum SignUpState { + CONFIRM_SIGN_UP_STEP, + DONE, + ERROR +} \ No newline at end of file diff --git a/packages/amplify_auth_plugin_interface/lib/src/types.dart b/packages/amplify_auth_plugin_interface/lib/src/types.dart new file mode 100644 index 0000000000..d12428ba28 --- /dev/null +++ b/packages/amplify_auth_plugin_interface/lib/src/types.dart @@ -0,0 +1,32 @@ +// Request & Result Classes +export 'SignUp/SignUpRequest.dart'; +export 'SignUp/SignUpResult.dart'; +export 'SignUp/ConfirmSignUpRequest.dart'; +export 'SignUp/ConfirmSignUpOptions.dart'; +export 'SignUp/SignUpState.dart'; +export 'SignUp/SignUpOptions.dart'; +export 'SignUp/AuthNextSignUpStep.dart'; +export 'SignIn/SignInRequest.dart'; +export 'SignIn/SignInResult.dart'; +export 'SignIn/ConfirmSignInRequest.dart'; +export 'SignIn/ConfirmSignInOptions.dart'; +export 'SignIn/SignInState.dart'; +export 'SignIn/SignInOptions.dart'; +export 'SignIn/AuthNextSignInStep.dart'; +export 'SignOut/SignOutRequest.dart'; +export 'SignOut/SignOutResult.dart'; +export 'SignOut/SignOutOptions.dart'; + + + +// Error Classes +export 'Errors/AuthError.dart'; +export 'Errors/AuthErrorTypes.dart'; + +// Utility Classes +export 'types/AuthCodeDeliveryDetails.dart'; +export 'types/AuthNextStep.dart'; + +// Errors +export 'Errors/AuthError.dart'; +export 'Errors/AuthErrorTypes.dart'; diff --git a/packages/amplify_auth_plugin_interface/lib/src/types/AuthCodeDeliveryDetails.dart b/packages/amplify_auth_plugin_interface/lib/src/types/AuthCodeDeliveryDetails.dart new file mode 100644 index 0000000000..1411bc232b --- /dev/null +++ b/packages/amplify_auth_plugin_interface/lib/src/types/AuthCodeDeliveryDetails.dart @@ -0,0 +1,8 @@ +import 'package:flutter/foundation.dart'; + +class AuthCodeDeliveryDetails { + String attributeName; + String deliveryMedium; + String destination; + AuthCodeDeliveryDetails({@required this.attributeName, @required this.deliveryMedium, @required this.destination}); +} \ No newline at end of file diff --git a/packages/amplify_auth_plugin_interface/lib/src/types/AuthNextStep.dart b/packages/amplify_auth_plugin_interface/lib/src/types/AuthNextStep.dart new file mode 100644 index 0000000000..0904b4bf4a --- /dev/null +++ b/packages/amplify_auth_plugin_interface/lib/src/types/AuthNextStep.dart @@ -0,0 +1,15 @@ +import 'package:flutter/foundation.dart'; +import 'AuthCodeDeliveryDetails.dart'; + +class AuthNextStep { + Map additionalInfo; + AuthCodeDeliveryDetails codeDeliveryDetails; + AuthNextStep({@required codeDeliveryDetails, additionalInfo = const {}}) { + this.additionalInfo = additionalInfo; + this.codeDeliveryDetails = AuthCodeDeliveryDetails( + attributeName: codeDeliveryDetails["attributeName"] != null ? codeDeliveryDetails["attributeName"] : "", + deliveryMedium: codeDeliveryDetails["deliveryMedium"] != null ? codeDeliveryDetails["deliveryMedium"] : "", + destination: codeDeliveryDetails["destination"] != null ? codeDeliveryDetails["destination"] : "" + ); + } +} \ No newline at end of file diff --git a/packages/amplify_auth_plugin_interface/pubspec.yaml b/packages/amplify_auth_plugin_interface/pubspec.yaml new file mode 100644 index 0000000000..ce3e4d6380 --- /dev/null +++ b/packages/amplify_auth_plugin_interface/pubspec.yaml @@ -0,0 +1,57 @@ +name: amplify_auth_plugin_interface +description: The platform interface for the auth module of Amplify-Flutter. +version: 0.0.1 +author: +homepage: + +environment: + sdk: ">=2.7.0 <3.0.0" + +transformers: + - dartson + +dependencies: + flutter: + sdk: flutter + plugin_platform_interface: ^1.0.1 + +dev_dependencies: + flutter_test: + sdk: flutter + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # To add assets to your package, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + # + # For details regarding assets in packages, see + # https://flutter.dev/assets-and-images/#from-packages + # + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware. + + # To add custom fonts to your package, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts in packages, see + # https://flutter.dev/custom-fonts/#from-packages diff --git a/packages/amplify_core/android/.classpath b/packages/amplify_core/android/.classpath new file mode 100644 index 0000000000..eb19361b57 --- /dev/null +++ b/packages/amplify_core/android/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/packages/amplify_core/android/.settings/org.eclipse.buildship.core.prefs b/packages/amplify_core/android/.settings/org.eclipse.buildship.core.prefs new file mode 100644 index 0000000000..6aa97a90af --- /dev/null +++ b/packages/amplify_core/android/.settings/org.eclipse.buildship.core.prefs @@ -0,0 +1,2 @@ +connection.project.dir=../example/android +eclipse.preferences.version=1 diff --git a/packages/amplify_core/example/android/.project b/packages/amplify_core/example/android/.project new file mode 100644 index 0000000000..3964dd3f5b --- /dev/null +++ b/packages/amplify_core/example/android/.project @@ -0,0 +1,17 @@ + + + android + Project android created by Buildship. + + + + + org.eclipse.buildship.core.gradleprojectbuilder + + + + + + org.eclipse.buildship.core.gradleprojectnature + + diff --git a/packages/amplify_core/example/android/app/.classpath b/packages/amplify_core/example/android/app/.classpath new file mode 100644 index 0000000000..eb19361b57 --- /dev/null +++ b/packages/amplify_core/example/android/app/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/packages/amplify_core/example/android/app/.project b/packages/amplify_core/example/android/app/.project new file mode 100644 index 0000000000..ac485d7c3e --- /dev/null +++ b/packages/amplify_core/example/android/app/.project @@ -0,0 +1,23 @@ + + + app + Project app created by Buildship. + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.buildship.core.gradleprojectbuilder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.buildship.core.gradleprojectnature + + diff --git a/packages/amplify_core/example/android/app/.settings/org.eclipse.buildship.core.prefs b/packages/amplify_core/example/android/app/.settings/org.eclipse.buildship.core.prefs new file mode 100644 index 0000000000..b1886adb46 --- /dev/null +++ b/packages/amplify_core/example/android/app/.settings/org.eclipse.buildship.core.prefs @@ -0,0 +1,2 @@ +connection.project.dir=.. +eclipse.preferences.version=1 diff --git a/packages/amplify_core/example/ios/Podfile b/packages/amplify_core/example/ios/Podfile index 25cbd5cf9d..cf867d11df 100644 --- a/packages/amplify_core/example/ios/Podfile +++ b/packages/amplify_core/example/ios/Podfile @@ -10,6 +10,7 @@ project 'Runner', { 'Release' => :release, } + platform :ios, '11.0' def flutter_root @@ -32,7 +33,6 @@ flutter_ios_podfile_setup target 'Runner' do use_frameworks! use_modular_headers! - pod 'Amplify' flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) end diff --git a/packages/amplify_core/example/lib/main.dart b/packages/amplify_core/example/lib/main.dart index 649e82eed9..b5cf765297 100644 --- a/packages/amplify_core/example/lib/main.dart +++ b/packages/amplify_core/example/lib/main.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'dart:async'; - import 'package:flutter/services.dart'; import 'package:amplify_core/amplify_core.dart'; @@ -34,7 +33,7 @@ class _MyAppState extends State { var isConfigured = await amplifyInstance.configure(amplifyconfig); try { setState(() { - _amplifyConfigured = isConfigured; + _amplifyConfigured = true; }); } catch(e) { print(e); diff --git a/packages/amplify_core/lib/amplify_core.dart b/packages/amplify_core/lib/amplify_core.dart index 88b62054fc..2e8438c7c7 100644 --- a/packages/amplify_core/lib/amplify_core.dart +++ b/packages/amplify_core/lib/amplify_core.dart @@ -1,20 +1,54 @@ -import 'dart:async'; +library amplify_core; -import 'package:flutter/services.dart'; -import 'package:amplify_core_plugin_interface/amplify_core_plugin_interface.dart'; +import 'dart:async'; +import 'package:amplify_core_plugin_interface/amplify_core_plugin_interface.dart'; +import 'package:amplify_auth_plugin_interface/amplify_auth_plugin_interface.dart'; import 'package:amplify_analytics_plugin_interface/analytics_plugin_interface.dart'; class Amplify { - + static const AuthCategory Auth = const AuthCategory(); static const AnalyticsCategory Analytics = const AnalyticsCategory(); - bool addPlugin(AnalyticsPluginInterface analyticsPlugin){ - return Analytics.addPlugin(analyticsPlugin); + + bool _isConfigured = false; + var multiPluginWarning = "Concurrent usage of multiple plugins per category is not yet available"; + + Future addPlugin({ + List authPlugin, + List analyticsPlugin}) { + if (!_isConfigured) { + try { + if (authPlugin != null && authPlugin.length == 1) { + Auth.addPlugin(authPlugin[0]); + } else if (authPlugin.length > 1) { + throw(multiPluginWarning); + } + if (analyticsPlugin != null && analyticsPlugin.length == 1) { + Analytics.addPlugin(analyticsPlugin[0]); + } else if (authPlugin.length > 1) { + throw(multiPluginWarning); + } + if (analyticsPlugin != null && analyticsPlugin.length > 0) { + analyticsPlugin.forEach((el) { + Analytics.addPlugin(el); + }); + } + } catch(e) { + print(e); + throw("Amplify plugin was not added"); + } + } else { + throw("Amplify is already configured; additional plugins cannot be added."); + } + return null; } - Future configure(String configuration) async { + Future configure(String configuration) async { assert(configuration != null, 'configuration is null'); var res = await Core.instance.configure(configuration); - return res; + _isConfigured = res; + if (!res) { + throw("Amplify plugin was not added"); + } } } diff --git a/packages/amplify_core/test/.test_coverage.dart b/packages/amplify_core/test/.test_coverage.dart new file mode 100644 index 0000000000..513b0926d9 --- /dev/null +++ b/packages/amplify_core/test/.test_coverage.dart @@ -0,0 +1,8 @@ +// Auto-generated by test_coverage. Do not edit by hand. +// Consider adding this file to your .gitignore. + +import 'amplify_core_test.dart' as amplify_core_test; + +void main() { + amplify_core_test.main(); +} diff --git a/packages/amplify_core/test/amplify_core_test.dart b/packages/amplify_core/test/amplify_core_test.dart index 3e5a183437..bf2d3a8d3f 100644 --- a/packages/amplify_core/test/amplify_core_test.dart +++ b/packages/amplify_core/test/amplify_core_test.dart @@ -19,10 +19,6 @@ void main() { channel.setMockMethodCallHandler(null); }); - test('configure should return true when value is passed', () async { - expect(await amplify.configure("{}"), true); - }); - test('configure should result in assertion error when null value is not passed', () async { amplify.configure(null) .then((v) => expect(true, false)) diff --git a/packages/amplify_core_plugin_interface/lib/amplify_analytics_category.dart b/packages/amplify_core_plugin_interface/lib/amplify_analytics_category.dart index 1833c6fbb1..d17ca31a08 100644 --- a/packages/amplify_core_plugin_interface/lib/amplify_analytics_category.dart +++ b/packages/amplify_core_plugin_interface/lib/amplify_analytics_category.dart @@ -1,4 +1,4 @@ -part of amplify_flutter_platform_interface; +part of amplify_core_plugin_interface; class AnalyticsCategory{ diff --git a/packages/amplify_core_plugin_interface/lib/amplify_auth_category.dart b/packages/amplify_core_plugin_interface/lib/amplify_auth_category.dart new file mode 100644 index 0000000000..952c0cca45 --- /dev/null +++ b/packages/amplify_core_plugin_interface/lib/amplify_auth_category.dart @@ -0,0 +1,46 @@ +part of amplify_core_plugin_interface; + +/// Interface for Auth category. This expose all the APIs that +/// are supported by this category's plugins. This class will accept plugins to +/// be registered and configured and then subsequent API calls will be forwarded +/// to those plugins. +class AuthCategory { + const AuthCategory(); + static List plugins = []; + + /// `Add plugin` method + void addPlugin(AuthPluginInterface plugin) { + // TODO: Discuss and support multiple plugins + if (plugins.length == 0) { + plugins.add(plugin); + + } else { + throw("Auth plugin was not added"); + } + } + + Future signUp({@required SignUpRequest request, Function(SignUpResult) success, Function(SignUpResult) error}) { + /// call `signUp` on all the plugins + return plugins[0].signUp(request: request); + } + + Future confirmSignUp({@required ConfirmSignUpRequest request}) { + /// call `signUp` on all the plugins + return plugins.length == 1 ? plugins[0].confirmSignUp(request: request) : null; + } + + Future signIn({@required SignInRequest request}) { + /// call `signUp` on all the plugins + return plugins.length == 1 ? plugins[0].signIn(request: request) : null; + } + + Future confirmSignIn({@required ConfirmSignInRequest request}) { + /// call `signUp` on all the plugins + return plugins.length == 1 ? plugins[0].confirmSignIn(request: request) : null; + } + + Future signOut({SignOutRequest request}) { + /// call `signUp` on all the plugins + return plugins.length == 1 ? plugins[0].signOut(request: request) : null; + } +} diff --git a/packages/amplify_core_plugin_interface/lib/amplify_core_plugin_interface.dart b/packages/amplify_core_plugin_interface/lib/amplify_core_plugin_interface.dart index 172c624a9d..4e027283c2 100644 --- a/packages/amplify_core_plugin_interface/lib/amplify_core_plugin_interface.dart +++ b/packages/amplify_core_plugin_interface/lib/amplify_core_plugin_interface.dart @@ -1,19 +1,22 @@ -library amplify_flutter_platform_interface; +library amplify_core_plugin_interface; + import 'dart:async'; +import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; +import 'package:amplify_auth_plugin_interface/amplify_auth_plugin_interface.dart'; import 'package:amplify_analytics_plugin_interface/analytics_plugin_interface.dart'; part 'method_channel_amplify.dart'; -part 'amplify_analytics_category.dart'; /// category parts - - +part 'amplify_auth_category.dart'; +part 'amplify_analytics_category.dart'; abstract class Core extends PlatformInterface { - /// Constructs a AmplifyPlatform. + /// Constructs a Core platform. + Core() : super(token: _token); static final Object _token = Object(); @@ -33,8 +36,11 @@ abstract class Core extends PlatformInterface { } /// Categories + + final AuthCategory Auth = AuthCategory(); final AnalyticsCategory Analytics = AnalyticsCategory(); + /// Adds the configuration and return true if it was successful. Future configure(String configuration) { throw UnimplementedError('configure() has not been implemented.'); diff --git a/packages/amplify_core_plugin_interface/lib/method_channel_amplify.dart b/packages/amplify_core_plugin_interface/lib/method_channel_amplify.dart index f71e15097e..060ec4a6f4 100644 --- a/packages/amplify_core_plugin_interface/lib/method_channel_amplify.dart +++ b/packages/amplify_core_plugin_interface/lib/method_channel_amplify.dart @@ -1,4 +1,5 @@ -part of amplify_flutter_platform_interface; +part of amplify_core_plugin_interface; + const MethodChannel _channel = MethodChannel('com.amazonaws.amplify/core'); diff --git a/packages/amplify_core_plugin_interface/pubspec.yaml b/packages/amplify_core_plugin_interface/pubspec.yaml index 7041c38d8f..17f4317ed8 100644 --- a/packages/amplify_core_plugin_interface/pubspec.yaml +++ b/packages/amplify_core_plugin_interface/pubspec.yaml @@ -11,6 +11,8 @@ dependencies: flutter: sdk: flutter plugin_platform_interface: ^1.0.1 + amplify_auth_plugin_interface: + path: ../amplify_auth_plugin_interface amplify_analytics_plugin_interface: path: ../amplify_analytics_plugin_interface