diff --git a/.gitattributes b/.gitattributes index 3fcc994970..ab23572ce9 100644 --- a/.gitattributes +++ b/.gitattributes @@ -74,6 +74,7 @@ ## Generated SDK files packages/**/lib/src/sdk/src/** linguist-generated +packages/auth/amplify_auth_cognito_dart/lib/src/sdk/sdk_exception.dart linguist-generated ## Generated Swift Plugins packages/amplify_datastore/ios/internal/** linguist-generated diff --git a/infra-gen2/backends/auth/mfa-optional-email-sms/.gitignore b/infra-gen2/backends/auth/mfa-optional-email-sms/.gitignore new file mode 100644 index 0000000000..03d4668c65 --- /dev/null +++ b/infra-gen2/backends/auth/mfa-optional-email-sms/.gitignore @@ -0,0 +1,5 @@ +# amplify +node_modules +.amplify +amplify_outputs* +amplifyconfiguration* diff --git a/infra-gen2/backends/auth/mfa-optional-email-sms/amplify/auth/resource.ts b/infra-gen2/backends/auth/mfa-optional-email-sms/amplify/auth/resource.ts new file mode 100644 index 0000000000..43ddc18eec --- /dev/null +++ b/infra-gen2/backends/auth/mfa-optional-email-sms/amplify/auth/resource.ts @@ -0,0 +1,18 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { defineAuth } from "@aws-amplify/backend"; + +export const auth = defineAuth({ + name: "mfa-optional-email-sms", + loginWith: { + email: true, + }, + + // TODO(khatruong2009): Uncomment the following line when the feature is ready. + // multifactor: { + // mode: "OPTIONAL", + // email: true, + // sms: true, + // }, +}); diff --git a/infra-gen2/backends/auth/mfa-optional-email-sms/amplify/backend.ts b/infra-gen2/backends/auth/mfa-optional-email-sms/amplify/backend.ts new file mode 100644 index 0000000000..d6b854225f --- /dev/null +++ b/infra-gen2/backends/auth/mfa-optional-email-sms/amplify/backend.ts @@ -0,0 +1,25 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { defineBackend } from "@aws-amplify/backend"; +import { addAuthUserExtensions } from "infra-common"; +import { auth } from "./auth/resource"; + +const backend = defineBackend({ + auth, +}); + +const resources = backend.auth.resources; +const { userPool, cfnResources } = resources; +const { stack } = userPool; +const { cfnUserPool } = cfnResources; + +// Adds infra for creating/deleting users via App Sync and fetching confirmation +// and MFA codes from App Sync. +const customOutputs = addAuthUserExtensions({ + name: "mfa-optional-email-sms", + stack, + userPool, + cfnUserPool, +}); +backend.addOutput(customOutputs); diff --git a/infra-gen2/backends/auth/mfa-optional-email-sms/amplify/package.json b/infra-gen2/backends/auth/mfa-optional-email-sms/amplify/package.json new file mode 100644 index 0000000000..aead43de36 --- /dev/null +++ b/infra-gen2/backends/auth/mfa-optional-email-sms/amplify/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} \ No newline at end of file diff --git a/infra-gen2/backends/auth/mfa-optional-email-sms/amplify/tsconfig.json b/infra-gen2/backends/auth/mfa-optional-email-sms/amplify/tsconfig.json new file mode 100644 index 0000000000..4eb4ab26ca --- /dev/null +++ b/infra-gen2/backends/auth/mfa-optional-email-sms/amplify/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "es2022", + "module": "es2022", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "paths": { + "$amplify/*": [ + "../.amplify/generated/*" + ] + } + } +} \ No newline at end of file diff --git a/infra-gen2/backends/auth/mfa-optional-email-sms/package.json b/infra-gen2/backends/auth/mfa-optional-email-sms/package.json new file mode 100644 index 0000000000..f8ffc5b939 --- /dev/null +++ b/infra-gen2/backends/auth/mfa-optional-email-sms/package.json @@ -0,0 +1,5 @@ +{ + "name": "mfa-optional-email-sms", + "version": "1.0.0", + "main": "index.js" +} diff --git a/infra-gen2/backends/auth/mfa-optional-email-totp/.gitignore b/infra-gen2/backends/auth/mfa-optional-email-totp/.gitignore new file mode 100644 index 0000000000..03d4668c65 --- /dev/null +++ b/infra-gen2/backends/auth/mfa-optional-email-totp/.gitignore @@ -0,0 +1,5 @@ +# amplify +node_modules +.amplify +amplify_outputs* +amplifyconfiguration* diff --git a/infra-gen2/backends/auth/mfa-optional-email-totp/amplify/auth/resource.ts b/infra-gen2/backends/auth/mfa-optional-email-totp/amplify/auth/resource.ts new file mode 100644 index 0000000000..ae1765e5d0 --- /dev/null +++ b/infra-gen2/backends/auth/mfa-optional-email-totp/amplify/auth/resource.ts @@ -0,0 +1,18 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { defineAuth } from "@aws-amplify/backend"; + +export const auth = defineAuth({ + name: "mfa-optional-email-totp", + loginWith: { + email: true, + }, + + // TODO(khatruong2009): Uncomment the following line when the feature is ready. + // multifactor: { + // mode: "OPTIONAL", + // email: true, + // totp: true, + // }, +}); diff --git a/infra-gen2/backends/auth/mfa-optional-email-totp/amplify/backend.ts b/infra-gen2/backends/auth/mfa-optional-email-totp/amplify/backend.ts new file mode 100644 index 0000000000..a3f1f19985 --- /dev/null +++ b/infra-gen2/backends/auth/mfa-optional-email-totp/amplify/backend.ts @@ -0,0 +1,25 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { defineBackend } from "@aws-amplify/backend"; +import { addAuthUserExtensions } from "infra-common"; +import { auth } from "./auth/resource"; + +const backend = defineBackend({ + auth, +}); + +const resources = backend.auth.resources; +const { userPool, cfnResources } = resources; +const { stack } = userPool; +const { cfnUserPool } = cfnResources; + +// Adds infra for creating/deleting users via App Sync and fetching confirmation +// and MFA codes from App Sync. +const customOutputs = addAuthUserExtensions({ + name: "mfa-optional-email-totp", + stack, + userPool, + cfnUserPool, +}); +backend.addOutput(customOutputs); diff --git a/infra-gen2/backends/auth/mfa-optional-email-totp/amplify/package.json b/infra-gen2/backends/auth/mfa-optional-email-totp/amplify/package.json new file mode 100644 index 0000000000..aead43de36 --- /dev/null +++ b/infra-gen2/backends/auth/mfa-optional-email-totp/amplify/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} \ No newline at end of file diff --git a/infra-gen2/backends/auth/mfa-optional-email-totp/amplify/tsconfig.json b/infra-gen2/backends/auth/mfa-optional-email-totp/amplify/tsconfig.json new file mode 100644 index 0000000000..4eb4ab26ca --- /dev/null +++ b/infra-gen2/backends/auth/mfa-optional-email-totp/amplify/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "es2022", + "module": "es2022", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "paths": { + "$amplify/*": [ + "../.amplify/generated/*" + ] + } + } +} \ No newline at end of file diff --git a/infra-gen2/backends/auth/mfa-optional-email-totp/package.json b/infra-gen2/backends/auth/mfa-optional-email-totp/package.json new file mode 100644 index 0000000000..20be47dae0 --- /dev/null +++ b/infra-gen2/backends/auth/mfa-optional-email-totp/package.json @@ -0,0 +1,5 @@ +{ + "name": "mfa-optional-email-totp", + "version": "1.0.0", + "main": "index.js" +} diff --git a/infra-gen2/backends/auth/mfa-optional-email/.gitignore b/infra-gen2/backends/auth/mfa-optional-email/.gitignore new file mode 100644 index 0000000000..03d4668c65 --- /dev/null +++ b/infra-gen2/backends/auth/mfa-optional-email/.gitignore @@ -0,0 +1,5 @@ +# amplify +node_modules +.amplify +amplify_outputs* +amplifyconfiguration* diff --git a/infra-gen2/backends/auth/mfa-optional-email/amplify/auth/resource.ts b/infra-gen2/backends/auth/mfa-optional-email/amplify/auth/resource.ts new file mode 100644 index 0000000000..1e33905c1d --- /dev/null +++ b/infra-gen2/backends/auth/mfa-optional-email/amplify/auth/resource.ts @@ -0,0 +1,17 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { defineAuth } from "@aws-amplify/backend"; + +export const auth = defineAuth({ + name: "mfa-optional-email", + loginWith: { + email: true, + }, + + // TODO(khatruong2009): Uncomment the following line when the feature is ready. + // multifactor: { + // mode: "OPTIONAL", + // email: true, + // }, +}); diff --git a/infra-gen2/backends/auth/mfa-optional-email/amplify/backend.ts b/infra-gen2/backends/auth/mfa-optional-email/amplify/backend.ts new file mode 100644 index 0000000000..ceb5e2a90a --- /dev/null +++ b/infra-gen2/backends/auth/mfa-optional-email/amplify/backend.ts @@ -0,0 +1,25 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { defineBackend } from "@aws-amplify/backend"; +import { addAuthUserExtensions } from "infra-common"; +import { auth } from "./auth/resource"; + +const backend = defineBackend({ + auth, +}); + +const resources = backend.auth.resources; +const { userPool, cfnResources } = resources; +const { stack } = userPool; +const { cfnUserPool } = cfnResources; + +// Adds infra for creating/deleting users via App Sync and fetching confirmation +// and MFA codes from App Sync. +const customOutputs = addAuthUserExtensions({ + name: "mfa-optional-email", + stack, + userPool, + cfnUserPool, +}); +backend.addOutput(customOutputs); diff --git a/infra-gen2/backends/auth/mfa-optional-email/amplify/package.json b/infra-gen2/backends/auth/mfa-optional-email/amplify/package.json new file mode 100644 index 0000000000..aead43de36 --- /dev/null +++ b/infra-gen2/backends/auth/mfa-optional-email/amplify/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} \ No newline at end of file diff --git a/infra-gen2/backends/auth/mfa-optional-email/amplify/tsconfig.json b/infra-gen2/backends/auth/mfa-optional-email/amplify/tsconfig.json new file mode 100644 index 0000000000..4eb4ab26ca --- /dev/null +++ b/infra-gen2/backends/auth/mfa-optional-email/amplify/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "es2022", + "module": "es2022", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "paths": { + "$amplify/*": [ + "../.amplify/generated/*" + ] + } + } +} \ No newline at end of file diff --git a/infra-gen2/backends/auth/mfa-optional-email/package.json b/infra-gen2/backends/auth/mfa-optional-email/package.json new file mode 100644 index 0000000000..a716d71dd4 --- /dev/null +++ b/infra-gen2/backends/auth/mfa-optional-email/package.json @@ -0,0 +1,5 @@ +{ + "name": "mfa-optional-email", + "version": "1.0.0", + "main": "index.js" +} diff --git a/infra-gen2/backends/auth/mfa-required-email-sms/.gitignore b/infra-gen2/backends/auth/mfa-required-email-sms/.gitignore new file mode 100644 index 0000000000..03d4668c65 --- /dev/null +++ b/infra-gen2/backends/auth/mfa-required-email-sms/.gitignore @@ -0,0 +1,5 @@ +# amplify +node_modules +.amplify +amplify_outputs* +amplifyconfiguration* diff --git a/infra-gen2/backends/auth/mfa-required-email-sms/amplify/auth/resource.ts b/infra-gen2/backends/auth/mfa-required-email-sms/amplify/auth/resource.ts new file mode 100644 index 0000000000..e90924c42e --- /dev/null +++ b/infra-gen2/backends/auth/mfa-required-email-sms/amplify/auth/resource.ts @@ -0,0 +1,17 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { defineAuth } from "@aws-amplify/backend"; + +export const auth = defineAuth({ + name: "mfa-required-email-sms", + loginWith: { + email: true, + }, + // TODO(khatruong2009): Uncomment the following line when the feature is ready. + // multifactor: { + // mode: "REQUIRED", + // email: true, + // sms: true, + // }, +}); diff --git a/infra-gen2/backends/auth/mfa-required-email-sms/amplify/backend.ts b/infra-gen2/backends/auth/mfa-required-email-sms/amplify/backend.ts new file mode 100644 index 0000000000..397b7b4a6e --- /dev/null +++ b/infra-gen2/backends/auth/mfa-required-email-sms/amplify/backend.ts @@ -0,0 +1,25 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { defineBackend } from "@aws-amplify/backend"; +import { addAuthUserExtensions } from "infra-common"; +import { auth } from "./auth/resource"; + +const backend = defineBackend({ + auth, +}); + +const resources = backend.auth.resources; +const { userPool, cfnResources } = resources; +const { stack } = userPool; +const { cfnUserPool } = cfnResources; + +// Adds infra for creating/deleting users via App Sync and fetching confirmation +// and MFA codes from App Sync. +const customOutputs = addAuthUserExtensions({ + name: "mfa-required-email-sms", + stack, + userPool, + cfnUserPool, +}); +backend.addOutput(customOutputs); diff --git a/infra-gen2/backends/auth/mfa-required-email-sms/amplify/package.json b/infra-gen2/backends/auth/mfa-required-email-sms/amplify/package.json new file mode 100644 index 0000000000..aead43de36 --- /dev/null +++ b/infra-gen2/backends/auth/mfa-required-email-sms/amplify/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} \ No newline at end of file diff --git a/infra-gen2/backends/auth/mfa-required-email-sms/amplify/tsconfig.json b/infra-gen2/backends/auth/mfa-required-email-sms/amplify/tsconfig.json new file mode 100644 index 0000000000..4eb4ab26ca --- /dev/null +++ b/infra-gen2/backends/auth/mfa-required-email-sms/amplify/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "es2022", + "module": "es2022", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "paths": { + "$amplify/*": [ + "../.amplify/generated/*" + ] + } + } +} \ No newline at end of file diff --git a/infra-gen2/backends/auth/mfa-required-email-sms/package.json b/infra-gen2/backends/auth/mfa-required-email-sms/package.json new file mode 100644 index 0000000000..b2e8c9c4c7 --- /dev/null +++ b/infra-gen2/backends/auth/mfa-required-email-sms/package.json @@ -0,0 +1,5 @@ +{ + "name": "mfa-required-email-sms", + "version": "1.0.0", + "main": "index.js" +} diff --git a/infra-gen2/backends/auth/mfa-required-email-totp/.gitignore b/infra-gen2/backends/auth/mfa-required-email-totp/.gitignore new file mode 100644 index 0000000000..03d4668c65 --- /dev/null +++ b/infra-gen2/backends/auth/mfa-required-email-totp/.gitignore @@ -0,0 +1,5 @@ +# amplify +node_modules +.amplify +amplify_outputs* +amplifyconfiguration* diff --git a/infra-gen2/backends/auth/mfa-required-email-totp/amplify/auth/resource.ts b/infra-gen2/backends/auth/mfa-required-email-totp/amplify/auth/resource.ts new file mode 100644 index 0000000000..bf09fd7dc7 --- /dev/null +++ b/infra-gen2/backends/auth/mfa-required-email-totp/amplify/auth/resource.ts @@ -0,0 +1,17 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { defineAuth } from "@aws-amplify/backend"; + +export const auth = defineAuth({ + name: "mfa-required-email-totp", + loginWith: { + email: true, + }, + // TODO(khatruong2009): Uncomment the following line when the feature is ready. + // multifactor: { + // mode: "REQUIRED", + // email: true, + // totp: true, + // }, +}); diff --git a/infra-gen2/backends/auth/mfa-required-email-totp/amplify/backend.ts b/infra-gen2/backends/auth/mfa-required-email-totp/amplify/backend.ts new file mode 100644 index 0000000000..c9e3bd79c1 --- /dev/null +++ b/infra-gen2/backends/auth/mfa-required-email-totp/amplify/backend.ts @@ -0,0 +1,25 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { defineBackend } from "@aws-amplify/backend"; +import { addAuthUserExtensions } from "infra-common"; +import { auth } from "./auth/resource"; + +const backend = defineBackend({ + auth, +}); + +const resources = backend.auth.resources; +const { userPool, cfnResources } = resources; +const { stack } = userPool; +const { cfnUserPool } = cfnResources; + +// Adds infra for creating/deleting users via App Sync and fetching confirmation +// and MFA codes from App Sync. +const customOutputs = addAuthUserExtensions({ + name: "mfa-required-email-totp", + stack, + userPool, + cfnUserPool, +}); +backend.addOutput(customOutputs); diff --git a/infra-gen2/backends/auth/mfa-required-email-totp/amplify/package.json b/infra-gen2/backends/auth/mfa-required-email-totp/amplify/package.json new file mode 100644 index 0000000000..aead43de36 --- /dev/null +++ b/infra-gen2/backends/auth/mfa-required-email-totp/amplify/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} \ No newline at end of file diff --git a/infra-gen2/backends/auth/mfa-required-email-totp/amplify/tsconfig.json b/infra-gen2/backends/auth/mfa-required-email-totp/amplify/tsconfig.json new file mode 100644 index 0000000000..4eb4ab26ca --- /dev/null +++ b/infra-gen2/backends/auth/mfa-required-email-totp/amplify/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "es2022", + "module": "es2022", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "paths": { + "$amplify/*": [ + "../.amplify/generated/*" + ] + } + } +} \ No newline at end of file diff --git a/infra-gen2/backends/auth/mfa-required-email-totp/package.json b/infra-gen2/backends/auth/mfa-required-email-totp/package.json new file mode 100644 index 0000000000..1ebbbbb859 --- /dev/null +++ b/infra-gen2/backends/auth/mfa-required-email-totp/package.json @@ -0,0 +1,5 @@ +{ + "name": "mfa-required-email-totp", + "version": "1.0.0", + "main": "index.js" +} diff --git a/infra-gen2/backends/auth/mfa-required-email/.gitignore b/infra-gen2/backends/auth/mfa-required-email/.gitignore new file mode 100644 index 0000000000..03d4668c65 --- /dev/null +++ b/infra-gen2/backends/auth/mfa-required-email/.gitignore @@ -0,0 +1,5 @@ +# amplify +node_modules +.amplify +amplify_outputs* +amplifyconfiguration* diff --git a/infra-gen2/backends/auth/mfa-required-email/amplify/auth/resource.ts b/infra-gen2/backends/auth/mfa-required-email/amplify/auth/resource.ts new file mode 100644 index 0000000000..ba859af386 --- /dev/null +++ b/infra-gen2/backends/auth/mfa-required-email/amplify/auth/resource.ts @@ -0,0 +1,16 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { defineAuth } from "@aws-amplify/backend"; + +export const auth = defineAuth({ + name: "mfa-required-email", + loginWith: { + email: true, + }, + // TODO(khatruong2009): Uncomment the following line when the feature is ready. + // multifactor: { + // mode: "REQUIRED", + // email: true, + // }, +}); diff --git a/infra-gen2/backends/auth/mfa-required-email/amplify/backend.ts b/infra-gen2/backends/auth/mfa-required-email/amplify/backend.ts new file mode 100644 index 0000000000..e9299cf711 --- /dev/null +++ b/infra-gen2/backends/auth/mfa-required-email/amplify/backend.ts @@ -0,0 +1,25 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { defineBackend } from "@aws-amplify/backend"; +import { addAuthUserExtensions } from "infra-common"; +import { auth } from "./auth/resource"; + +const backend = defineBackend({ + auth, +}); + +const resources = backend.auth.resources; +const { userPool, cfnResources } = resources; +const { stack } = userPool; +const { cfnUserPool } = cfnResources; + +// Adds infra for creating/deleting users via App Sync and fetching confirmation +// and MFA codes from App Sync. +const customOutputs = addAuthUserExtensions({ + name: "mfa-required-email", + stack, + userPool, + cfnUserPool, +}); +backend.addOutput(customOutputs); diff --git a/infra-gen2/backends/auth/mfa-required-email/amplify/package.json b/infra-gen2/backends/auth/mfa-required-email/amplify/package.json new file mode 100644 index 0000000000..aead43de36 --- /dev/null +++ b/infra-gen2/backends/auth/mfa-required-email/amplify/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} \ No newline at end of file diff --git a/infra-gen2/backends/auth/mfa-required-email/amplify/tsconfig.json b/infra-gen2/backends/auth/mfa-required-email/amplify/tsconfig.json new file mode 100644 index 0000000000..4eb4ab26ca --- /dev/null +++ b/infra-gen2/backends/auth/mfa-required-email/amplify/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "es2022", + "module": "es2022", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "paths": { + "$amplify/*": [ + "../.amplify/generated/*" + ] + } + } +} \ No newline at end of file diff --git a/infra-gen2/backends/auth/mfa-required-email/package.json b/infra-gen2/backends/auth/mfa-required-email/package.json new file mode 100644 index 0000000000..3d30b5522b --- /dev/null +++ b/infra-gen2/backends/auth/mfa-required-email/package.json @@ -0,0 +1,5 @@ +{ + "name": "mfa-required-email", + "version": "1.0.0", + "main": "index.js" +} diff --git a/infra-gen2/backends/auth/username-login-mfa/.gitignore b/infra-gen2/backends/auth/username-login-mfa/.gitignore new file mode 100644 index 0000000000..03d4668c65 --- /dev/null +++ b/infra-gen2/backends/auth/username-login-mfa/.gitignore @@ -0,0 +1,5 @@ +# amplify +node_modules +.amplify +amplify_outputs* +amplifyconfiguration* diff --git a/infra-gen2/backends/auth/username-login-mfa/amplify/auth/resource.ts b/infra-gen2/backends/auth/username-login-mfa/amplify/auth/resource.ts new file mode 100644 index 0000000000..94d78b3d4b --- /dev/null +++ b/infra-gen2/backends/auth/username-login-mfa/amplify/auth/resource.ts @@ -0,0 +1,19 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { defineAuth } from "@aws-amplify/backend"; + +export const auth = defineAuth({ + name: "mfa-username-login", + loginWith: { + phone: true, + }, + // TODO(khatruong2009): Uncomment the following line when the feature is ready. + // multifactor: { + // mode: "REQUIRED", + // email: true, + // sms: true, + // totp: true, + // }, + accountRecovery: "PHONE_WITHOUT_MFA_AND_EMAIL", +}); diff --git a/infra-gen2/backends/auth/username-login-mfa/amplify/backend.ts b/infra-gen2/backends/auth/username-login-mfa/amplify/backend.ts new file mode 100644 index 0000000000..ce86475882 --- /dev/null +++ b/infra-gen2/backends/auth/username-login-mfa/amplify/backend.ts @@ -0,0 +1,40 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { defineBackend } from "@aws-amplify/backend"; +import { addAuthUserExtensions } from "infra-common"; +import { auth } from "./auth/resource"; + +const backend = defineBackend({ + auth, +}); + +const resources = backend.auth.resources; +const { userPool, cfnResources } = resources; +const { stack } = userPool; +const { cfnUserPool } = cfnResources; + +// Adds infra for creating/deleting users via App Sync and fetching confirmation +// and MFA codes from App Sync. +const customOutputs = addAuthUserExtensions({ + name: "username-login-mfa", + stack, + userPool, + cfnUserPool, +}); +backend.addOutput(customOutputs); + +cfnUserPool.schema = undefined; +cfnUserPool.usernameAttributes = []; +cfnUserPool.emailConfiguration = { + emailSendingAccount: "DEVELOPER", + from: "ktruon@amazon.com", + sourceArn: `arn:aws:ses:${stack.region}:${stack.account}:identity/ktruon@amazon.com`, +}; +cfnUserPool.adminCreateUserConfig = { + allowAdminCreateUserOnly: true, +}; +cfnUserPool.autoVerifiedAttributes = []; +cfnUserPool.userAttributeUpdateSettings = { + attributesRequireVerificationBeforeUpdate: [], +}; diff --git a/infra-gen2/backends/auth/username-login-mfa/amplify/package.json b/infra-gen2/backends/auth/username-login-mfa/amplify/package.json new file mode 100644 index 0000000000..aead43de36 --- /dev/null +++ b/infra-gen2/backends/auth/username-login-mfa/amplify/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} \ No newline at end of file diff --git a/infra-gen2/backends/auth/username-login-mfa/amplify/tsconfig.json b/infra-gen2/backends/auth/username-login-mfa/amplify/tsconfig.json new file mode 100644 index 0000000000..4eb4ab26ca --- /dev/null +++ b/infra-gen2/backends/auth/username-login-mfa/amplify/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "es2022", + "module": "es2022", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "paths": { + "$amplify/*": [ + "../.amplify/generated/*" + ] + } + } +} \ No newline at end of file diff --git a/infra-gen2/backends/auth/username-login-mfa/package.json b/infra-gen2/backends/auth/username-login-mfa/package.json new file mode 100644 index 0000000000..e604512607 --- /dev/null +++ b/infra-gen2/backends/auth/username-login-mfa/package.json @@ -0,0 +1,5 @@ +{ + "name": "username-login-mfa", + "version": "1.0.0", + "main": "index.js" +} diff --git a/infra-gen2/package-lock.json b/infra-gen2/package-lock.json index a4fb252803..f56c0348d5 100644 --- a/infra-gen2/package-lock.json +++ b/infra-gen2/package-lock.json @@ -45,9 +45,15 @@ "backends/auth/email-sign-in": { "version": "1.0.0" }, + "backends/auth/mfa-optional-email": { + "version": "1.0.0" + }, "backends/auth/mfa-optional-sms": { "version": "1.0.0" }, + "backends/auth/mfa-required-email": { + "version": "1.0.0" + }, "backends/auth/mfa-required-sms": { "version": "1.0.0" }, @@ -6905,7 +6911,7 @@ "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/util-utf8": { @@ -6919,7 +6925,7 @@ "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-crypto/sha256-browser": { @@ -6946,7 +6952,7 @@ "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-buffer-from": { @@ -6959,7 +6965,7 @@ "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-utf8": { @@ -6972,7 +6978,7 @@ "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-crypto/sha256-js": { @@ -7018,7 +7024,7 @@ "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-crypto/util/node_modules/@smithy/util-buffer-from": { @@ -7031,7 +7037,7 @@ "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-crypto/util/node_modules/@smithy/util-utf8": { @@ -7044,7 +7050,7 @@ "tslib": "^2.6.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0" } }, "node_modules/@aws-sdk/client-amplify": { @@ -10069,7 +10075,7 @@ "@aws-sdk/middleware-user-agent": "3.620.0", "@aws-sdk/region-config-resolver": "3.614.0", "@aws-sdk/types": "3.609.0", - "@aws-sdk/util-endpoints": "3.614.0", + "@aws-sdk/util-endpoints": "3.637.0", "@aws-sdk/util-user-agent-browser": "3.609.0", "@aws-sdk/util-user-agent-node": "3.614.0", "@smithy/config-resolver": "^3.0.5", @@ -10118,7 +10124,7 @@ "@aws-sdk/middleware-user-agent": "3.620.0", "@aws-sdk/region-config-resolver": "3.614.0", "@aws-sdk/types": "3.609.0", - "@aws-sdk/util-endpoints": "3.614.0", + "@aws-sdk/util-endpoints": "3.637.0", "@aws-sdk/util-user-agent-browser": "3.609.0", "@aws-sdk/util-user-agent-node": "3.614.0", "@smithy/config-resolver": "^3.0.5", @@ -10168,7 +10174,7 @@ "@aws-sdk/middleware-user-agent": "3.620.0", "@aws-sdk/region-config-resolver": "3.614.0", "@aws-sdk/types": "3.609.0", - "@aws-sdk/util-endpoints": "3.614.0", + "@aws-sdk/util-endpoints": "3.637.0", "@aws-sdk/util-user-agent-browser": "3.609.0", "@aws-sdk/util-user-agent-node": "3.614.0", "@smithy/config-resolver": "^3.0.5", @@ -10222,7 +10228,7 @@ "@aws-sdk/middleware-user-agent": "3.620.0", "@aws-sdk/region-config-resolver": "3.614.0", "@aws-sdk/types": "3.609.0", - "@aws-sdk/util-endpoints": "3.614.0", + "@aws-sdk/util-endpoints": "3.637.0", "@aws-sdk/util-user-agent-browser": "3.609.0", "@aws-sdk/util-user-agent-node": "3.614.0", "@smithy/config-resolver": "^3.0.5", @@ -10471,6 +10477,20 @@ "node": ">=16.0.0" } }, + "node_modules/@aws-sdk/client-personalize-events/node_modules/@aws-sdk/middleware-user-agent/node_modules/@aws-sdk/util-endpoints": { + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.614.0.tgz", + "integrity": "sha512-wK2cdrXHH4oz4IomV/yrGkftU9A+ITB6nFL+rxxyO78is2ifHJpFdV4aqk4LSkXYPi6CXWNru/Dqc7yiKXgJPw==", + "dependencies": { + "@aws-sdk/types": "3.609.0", + "@smithy/types": "^3.3.0", + "@smithy/util-endpoints": "^2.0.5", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/@aws-sdk/client-personalize-events/node_modules/@aws-sdk/region-config-resolver": { "version": "3.614.0", "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.614.0.tgz", @@ -10521,10 +10541,9 @@ } }, "node_modules/@aws-sdk/client-personalize-events/node_modules/@aws-sdk/util-endpoints": { - "version": "3.614.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.614.0.tgz", - "integrity": "sha512-wK2cdrXHH4oz4IomV/yrGkftU9A+ITB6nFL+rxxyO78is2ifHJpFdV4aqk4LSkXYPi6CXWNru/Dqc7yiKXgJPw==", - "license": "Apache-2.0", + "version": "3.637.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.637.0.tgz", + "integrity": "sha512-pAqOKUHeVWHEXXDIp/qoMk/6jyxIb6GGjnK1/f8dKHtKIEs4tKsnnL563gceEvdad53OPXIt86uoevCcCzmBnw==", "dependencies": { "@aws-sdk/types": "3.609.0", "@smithy/types": "^3.3.0", @@ -20087,10 +20106,18 @@ "node": ">= 8" } }, + "node_modules/mfa-optional-email": { + "resolved": "backends/auth/mfa-optional-email", + "link": true + }, "node_modules/mfa-optional-sms": { "resolved": "backends/auth/mfa-optional-sms", "link": true }, + "node_modules/mfa-required-email": { + "resolved": "backends/auth/mfa-required-email", + "link": true + }, "node_modules/mfa-required-sms": { "resolved": "backends/auth/mfa-required-sms", "link": true diff --git a/infra-gen2/tool/deploy_gen2.dart b/infra-gen2/tool/deploy_gen2.dart index 15ffcf10f4..b83efb7c60 100644 --- a/infra-gen2/tool/deploy_gen2.dart +++ b/infra-gen2/tool/deploy_gen2.dart @@ -19,11 +19,6 @@ import 'package:path/path.dart' as p; /// 3. Add the backend to a category or create a new category /// 4. Run `dart tool/deploy_gen2.dart` to deploy the backend const List infraConfig = [ - AmplifyBackendGroup( - category: Category.analytics, - defaultOutput: '', - backends: [], - ), AmplifyBackendGroup( category: Category.api, defaultOutput: 'packages/api/amplify_api/example/lib', @@ -63,6 +58,41 @@ const List infraConfig = [ identifier: 'mfa-req-sms', pathToSource: 'infra-gen2/backends/auth/mfa-required-sms', ), + AmplifyBackend( + name: 'mfa-required-email', + identifier: 'mfa-req-email', + pathToSource: 'infra-gen2/backends/auth/mfa-required-email', + ), + AmplifyBackend( + name: 'mfa-required-email-sms', + identifier: 'mfa-req-ema-sms', + pathToSource: 'infra-gen2/backends/auth/mfa-required-email-sms', + ), + AmplifyBackend( + name: 'mfa-optional-email', + identifier: 'mfa-opt-email', + pathToSource: 'infra-gen2/backends/auth/mfa-optional-email', + ), + AmplifyBackend( + name: 'mfa-optional-email-sms', + identifier: 'mfa-opt-ema-sms', + pathToSource: 'infra-gen2/backends/auth/mfa-optional-email-sms', + ), + AmplifyBackend( + name: 'mfa-required-email-totp', + identifier: 'mfa-req-ema-tot', + pathToSource: 'infra-gen2/backends/auth/mfa-required-email-totp', + ), + AmplifyBackend( + name: 'mfa-optional-email-totp', + identifier: 'mfa-opt-ema-tot', + pathToSource: 'infra-gen2/backends/auth/mfa-optional-email-totp', + ), + AmplifyBackend( + name: 'username-login-mfa', + identifier: 'user-login-mfa', + pathToSource: 'infra-gen2/backends/auth/username-login-mfa', + ), ], ), AmplifyBackendGroup( diff --git a/packages/amplify_core/doc/lib/auth.dart b/packages/amplify_core/doc/lib/auth.dart index 6e48014a9b..d4f33ab4c7 100644 --- a/packages/amplify_core/doc/lib/auth.dart +++ b/packages/amplify_core/doc/lib/auth.dart @@ -104,22 +104,38 @@ Future resendSignUpCode(String username) async { } // #enddocregion resend-signup-code -// #docregion handle-signin, handle-confirm-signin-sms, handle-confirm-signin-new-password, handle-confirm-signin-custom-challenge, handle-confirm-signin-reset-password, handle-confirm-signin-confirm-signup, handle-confirm-signin-done, handle-confirm-signin-mfa-selection, handle-confirm-signin-totp-setup, handle-confirm-signin-totp-code +// #docregion handle-signin, handle-confirm-signin-sms, handle-confirm-signin-new-password, handle-confirm-signin-custom-challenge, handle-confirm-signin-reset-password, handle-confirm-signin-confirm-signup, handle-confirm-signin-done, handle-confirm-signin-mfa-selection, handle-confirm-signin-totp-setup, handle-confirm-signin-totp-code, handle-confirm-signin-email-code, handle-confirm-signin-mfa-setup-selection, handle-confirm-signin-email-setup Future _handleSignInResult(SignInResult result) async { switch (result.nextStep.signInStep) { - // #enddocregion handle-signin, handle-confirm-signin-sms, handle-confirm-signin-new-password, handle-confirm-signin-custom-challenge, handle-confirm-signin-reset-password, handle-confirm-signin-confirm-signup, handle-confirm-signin-done, handle-confirm-signin-mfa-selection, handle-confirm-signin-totp-setup, handle-confirm-signin-totp-code + // #enddocregion handle-signin, handle-confirm-signin-sms, handle-confirm-signin-new-password, handle-confirm-signin-custom-challenge, handle-confirm-signin-reset-password, handle-confirm-signin-confirm-signup, handle-confirm-signin-done, handle-confirm-signin-mfa-selection, handle-confirm-signin-totp-setup, handle-confirm-signin-totp-code, handle-confirm-signin-email-code, handle-confirm-signin-mfa-setup-selection, handle-confirm-signin-email-setup // #docregion handle-confirm-signin-mfa-selection case AuthSignInStep.continueSignInWithMfaSelection: final allowedMfaTypes = result.nextStep.allowedMfaTypes!; final selection = await _promptUserPreference(allowedMfaTypes); return _handleMfaSelection(selection); // #enddocregion handle-confirm-signin-mfa-selection + // #docregion handle-confirm-signin-mfa-setup-selection + case AuthSignInStep.continueSignInWithMfaSetupSelection: + final allowedMfaTypes = result.nextStep.allowedMfaTypes!; + if (allowedMfaTypes.length == 1) { + return _handleMfaSelection(allowedMfaTypes.first); + } + final selection = await _promptUserPreference(allowedMfaTypes); + safePrint('Selected MFA type: $selection'); + return _handleMfaSelection(selection); + // #enddocregion handle-confirm-signin-mfa-setup-selection // #docregion handle-confirm-signin-totp-setup case AuthSignInStep.continueSignInWithTotpSetup: final totpSetupDetails = result.nextStep.totpSetupDetails!; final setupUri = totpSetupDetails.getSetupUri(appName: 'MyApp'); safePrint('Open URI to complete setup: $setupUri'); // #enddocregion handle-confirm-signin-totp-setup + // #docregion handle-confirm-signin-email-setup + case AuthSignInStep.continueSignInWithEmailMfaSetup: + safePrint( + 'Enter the email address you want to use for two-factor authentication', + ); + // #enddocregion handle-confirm-signin-email-setup // #docregion handle-confirm-signin-totp-code case AuthSignInStep.confirmSignInWithTotpMfaCode: safePrint('Enter a one-time code from your registered Authenticator app'); @@ -129,6 +145,11 @@ Future _handleSignInResult(SignInResult result) async { final codeDeliveryDetails = result.nextStep.codeDeliveryDetails!; _handleCodeDelivery(codeDeliveryDetails); // #enddocregion handle-confirm-signin-sms + // #docregion handle-confirm-signin-email + case AuthSignInStep.confirmSignInWithOtpCode: + final codeDeliveryDetails = result.nextStep.codeDeliveryDetails!; + _handleCodeDelivery(codeDeliveryDetails); + // #enddocregion handle-confirm-signin-email // #docregion handle-confirm-signin-new-password case AuthSignInStep.confirmSignInWithNewPassword: safePrint('Enter a new password to continue signing in'); @@ -158,10 +179,10 @@ Future _handleSignInResult(SignInResult result) async { case AuthSignInStep.done: safePrint('Sign in is complete'); // #enddocregion handle-confirm-signin-done - // #docregion handle-signin, handle-confirm-signin-sms, handle-confirm-signin-new-password, handle-confirm-signin-custom-challenge, handle-confirm-signin-reset-password, handle-confirm-signin-confirm-signup, handle-confirm-signin-done, handle-confirm-signin-mfa-selection, handle-confirm-signin-totp-setup, handle-confirm-signin-totp-code + // #docregion handle-signin, handle-confirm-signin-sms, handle-confirm-signin-new-password, handle-confirm-signin-custom-challenge, handle-confirm-signin-reset-password, handle-confirm-signin-confirm-signup, handle-confirm-signin-done, handle-confirm-signin-mfa-selection, handle-confirm-signin-totp-setup, handle-confirm-signin-totp-code, handle-confirm-signin-email-code, handle-confirm-signin-mfa-setup-selection, handle-confirm-signin-email-setup } } -// #enddocregion handle-signin, handle-confirm-signin-sms, handle-confirm-signin-new-password, handle-confirm-signin-custom-challenge, handle-confirm-signin-reset-password, handle-confirm-signin-confirm-signup, handle-confirm-signin-done, handle-confirm-signin-mfa-selection, handle-confirm-signin-totp-setup, handle-confirm-signin-totp-code +// #enddocregion handle-signin, handle-confirm-signin-sms, handle-confirm-signin-new-password, handle-confirm-signin-custom-challenge, handle-confirm-signin-reset-password, handle-confirm-signin-confirm-signup, handle-confirm-signin-done, handle-confirm-signin-mfa-selection, handle-confirm-signin-totp-setup, handle-confirm-signin-totp-code, handle-confirm-signin-email-code, handle-confirm-signin-mfa-setup-selection, handle-confirm-signin-email-setup // #docregion signin Future signInUser(String username, String password) async { diff --git a/packages/amplify_core/lib/src/config/amplify_outputs/auth/auth_outputs.g.dart b/packages/amplify_core/lib/src/config/amplify_outputs/auth/auth_outputs.g.dart index f278972143..9c9639f654 100644 --- a/packages/amplify_core/lib/src/config/amplify_outputs/auth/auth_outputs.g.dart +++ b/packages/amplify_core/lib/src/config/amplify_outputs/auth/auth_outputs.g.dart @@ -128,4 +128,5 @@ const _$MfaEnforcementEnumMap = { const _$MfaMethodEnumMap = { MfaMethod.sms: 'SMS', MfaMethod.totp: 'TOTP', + MfaMethod.email: 'EMAIL', }; diff --git a/packages/amplify_core/lib/src/config/amplify_outputs/auth/mfa.dart b/packages/amplify_core/lib/src/config/amplify_outputs/auth/mfa.dart index e82d3327d7..92fee3d781 100644 --- a/packages/amplify_core/lib/src/config/amplify_outputs/auth/mfa.dart +++ b/packages/amplify_core/lib/src/config/amplify_outputs/auth/mfa.dart @@ -11,7 +11,10 @@ enum MfaMethod { sms, @JsonValue('TOTP') - totp; + totp, + + @JsonValue('EMAIL') + email; /// The value to pass to `Amplify.Auth.confirmSignIn` when /// selecting an MFA type. diff --git a/packages/amplify_core/lib/src/config/auth/cognito/auth.g.dart b/packages/amplify_core/lib/src/config/auth/cognito/auth.g.dart index 51926ead53..6bbb532080 100644 --- a/packages/amplify_core/lib/src/config/auth/cognito/auth.g.dart +++ b/packages/amplify_core/lib/src/config/auth/cognito/auth.g.dart @@ -119,4 +119,5 @@ const _$MfaConfigurationEnumMap = { const _$MfaTypeEnumMap = { MfaType.sms: 'SMS', MfaType.totp: 'TOTP', + MfaType.email: 'EMAIL', }; diff --git a/packages/amplify_core/lib/src/config/auth/cognito/mfa.dart b/packages/amplify_core/lib/src/config/auth/cognito/mfa.dart index 6d33bd00b3..292c5e184f 100644 --- a/packages/amplify_core/lib/src/config/auth/cognito/mfa.dart +++ b/packages/amplify_core/lib/src/config/auth/cognito/mfa.dart @@ -9,7 +9,10 @@ enum MfaType { sms, @JsonValue('TOTP') - totp; + totp, + + @JsonValue('EMAIL') + email; /// The value to pass to `Amplify.Auth.confirmSignIn` when /// selecting an MFA type. @@ -21,6 +24,7 @@ extension ToMfaMethod on MfaType { return switch (this) { MfaType.sms => MfaMethod.sms, MfaType.totp => MfaMethod.totp, + MfaType.email => MfaMethod.email, }; } } diff --git a/packages/amplify_core/lib/src/types/auth/sign_in/auth_next_sign_in_step.g.dart b/packages/amplify_core/lib/src/types/auth/sign_in/auth_next_sign_in_step.g.dart index 46d7e2de61..6d480f1414 100644 --- a/packages/amplify_core/lib/src/types/auth/sign_in/auth_next_sign_in_step.g.dart +++ b/packages/amplify_core/lib/src/types/auth/sign_in/auth_next_sign_in_step.g.dart @@ -75,9 +75,14 @@ Map _$AuthNextSignInStepToJson(AuthNextSignInStep instance) { const _$AuthSignInStepEnumMap = { AuthSignInStep.continueSignInWithMfaSelection: 'continueSignInWithMfaSelection', + AuthSignInStep.continueSignInWithMfaSetupSelection: + 'continueSignInWithMfaSetupSelection', AuthSignInStep.continueSignInWithTotpSetup: 'continueSignInWithTotpSetup', + AuthSignInStep.continueSignInWithEmailMfaSetup: + 'continueSignInWithEmailMfaSetup', AuthSignInStep.confirmSignInWithSmsMfaCode: 'confirmSignInWithSmsMfaCode', AuthSignInStep.confirmSignInWithTotpMfaCode: 'confirmSignInWithTotpMfaCode', + AuthSignInStep.confirmSignInWithOtpCode: 'confirmSignInWithOtpCode', AuthSignInStep.confirmSignInWithNewPassword: 'confirmSignInWithNewPassword', AuthSignInStep.confirmSignInWithCustomChallenge: 'confirmSignInWithCustomChallenge', @@ -89,4 +94,5 @@ const _$AuthSignInStepEnumMap = { const _$MfaTypeEnumMap = { MfaType.sms: 'SMS', MfaType.totp: 'TOTP', + MfaType.email: 'EMAIL', }; diff --git a/packages/amplify_core/lib/src/types/auth/sign_in/auth_sign_in_step.dart b/packages/amplify_core/lib/src/types/auth/sign_in/auth_sign_in_step.dart index 7474f4be5e..e63cb3a58f 100644 --- a/packages/amplify_core/lib/src/types/auth/sign_in/auth_sign_in_step.dart +++ b/packages/amplify_core/lib/src/types/auth/sign_in/auth_sign_in_step.dart @@ -10,10 +10,17 @@ enum AuthSignInStep { /// an MFA method. continueSignInWithMfaSelection, + /// The sign-in is not complete and the user must select an MFA method to setup. + continueSignInWithMfaSetupSelection, + /// The sign-in is not complete and a TOTP authenticator app must be /// registered before continuing. continueSignInWithTotpSetup, + /// The sign-in is not complete and an Email MFA must be set up before + /// continuing. + continueSignInWithEmailMfaSetup, + /// The sign-in is not complete and must be confirmed with an SMS code. confirmSignInWithSmsMfaCode, @@ -21,6 +28,9 @@ enum AuthSignInStep { /// from a registered authenticator app. confirmSignInWithTotpMfaCode, + /// The sign-in is not complete and must be confirmed with an email code. + confirmSignInWithOtpCode, + /// The sign-in is not complete and must be confirmed with the user's new /// password. confirmSignInWithNewPassword, diff --git a/packages/auth/amplify_auth_cognito/example/integration_test/main_test.dart b/packages/auth/amplify_auth_cognito/example/integration_test/main_test.dart index 192d73db19..4c2bcec0ba 100644 --- a/packages/auth/amplify_auth_cognito/example/integration_test/main_test.dart +++ b/packages/auth/amplify_auth_cognito/example/integration_test/main_test.dart @@ -15,11 +15,19 @@ import 'fetch_auth_session_test.dart' as fetch_auth_session_tests; import 'get_current_user_test.dart' as get_current_user_tests; import 'hosted_ui_webview_test.dart' as hosted_ui_webview_tests; import 'hub_events_test.dart' as hub_events_tests; +import 'mfa_email_optional_test.dart' as mfa_email_optional_tests; +import 'mfa_email_required_test.dart' as mfa_email_required_tests; +import 'mfa_email_totp_optional_test.dart' as mfa_email_totp_optional_tests; +import 'mfa_email_totp_required_test.dart' as mfa_email_totp_required_tests; +import 'mfa_sms_email_optional_test.dart' as mfa_sms_email_optional_tests; +import 'mfa_sms_email_required_test.dart' as mfa_sms_email_required_tests; import 'mfa_sms_test.dart' as mfa_sms_tests; import 'mfa_sms_totp_optional_test.dart' as mfa_sms_totp_optional_tests; import 'mfa_sms_totp_required_test.dart' as mfa_sms_totp_required_tests; import 'mfa_totp_optional_test.dart' as mfa_totp_optional_tests; import 'mfa_totp_required_test.dart' as mfa_totp_required_tests; +import 'mfa_username_login_required_test.dart' + as mfa_username_login_required_tests; import 'native_auth_bridge_test.dart' as native_auth_bridge_tests; import 'reset_password_test.dart' as reset_password_tests; import 'security_test.dart' as security_tests; @@ -36,6 +44,18 @@ void main() async { group('amplify_auth_cognito', () { asf_tests.main(); + mfa_username_login_required_tests.main(); + mfa_sms_tests.main(); + mfa_sms_totp_optional_tests.main(); + mfa_sms_totp_required_tests.main(); + mfa_totp_optional_tests.main(); + mfa_totp_required_tests.main(); + mfa_email_optional_tests.main(); + mfa_email_required_tests.main(); + mfa_sms_email_optional_tests.main(); + mfa_sms_email_required_tests.main(); + mfa_email_totp_optional_tests.main(); + mfa_email_totp_required_tests.main(); confirm_sign_in_tests.main(); confirm_sign_up_tests.main(); custom_auth_tests.main(); @@ -47,11 +67,6 @@ void main() async { get_current_user_tests.main(); hosted_ui_webview_tests.main(); hub_events_tests.main(); - mfa_sms_tests.main(); - mfa_sms_totp_optional_tests.main(); - mfa_sms_totp_required_tests.main(); - mfa_totp_optional_tests.main(); - mfa_totp_required_tests.main(); native_auth_bridge_tests.main(); reset_password_tests.main(); security_tests.main(); diff --git a/packages/auth/amplify_auth_cognito/example/integration_test/mfa_email_optional_test.dart b/packages/auth/amplify_auth_cognito/example/integration_test/mfa_email_optional_test.dart new file mode 100644 index 0000000000..0fed40593b --- /dev/null +++ b/packages/auth/amplify_auth_cognito/example/integration_test/mfa_email_optional_test.dart @@ -0,0 +1,79 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import 'package:amplify_auth_integration_test/amplify_auth_integration_test.dart'; +import 'package:amplify_flutter/amplify_flutter.dart'; +import 'package:amplify_integration_test/amplify_integration_test.dart'; +import 'package:checks/checks.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'test_runner.dart'; + +void main() { + testRunner.setupTests(); + + group('MFA (Email)', () { + testRunner.withEnvironment(mfaOptionalEmail, (env) { + asyncTest('can sign in with Email MFA', (_) async { + final username = env.generateUsername(); + final password = generatePassword(); + + await adminCreateUser( + username, + password, + autoConfirm: true, + verifyAttributes: true, + attributes: { + AuthUserAttributeKey.email: username, + }, + ); + + final signInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + check( + signInRes.nextStep.signInStep, + because: 'MFA is optional', + ).equals(AuthSignInStep.done); + + await cognitoPlugin.updateMfaPreference( + email: MfaPreference.preferred, + ); + + check(await cognitoPlugin.fetchMfaPreference()).equals( + const UserMfaPreference( + enabled: {MfaType.email}, + preferred: MfaType.email, + ), + ); + + Future signInWithEmail() async { + await signOutUser(assertComplete: true); + + final otpResult = await getOtpCode( + env.getLoginAttribute(username), + ); + + final signInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + check(signInRes.nextStep.signInStep) + .equals(AuthSignInStep.confirmSignInWithOtpCode); + check(signInRes.nextStep.codeDeliveryDetails) + .isNotNull() + .has((d) => d.deliveryMedium, 'deliveryMedium') + .equals(DeliveryMedium.email); + final mfaSetupRes = await Amplify.Auth.confirmSignIn( + confirmationValue: await otpResult.code, + ); + check(mfaSetupRes.nextStep.signInStep).equals(AuthSignInStep.done); + } + + await signInWithEmail(); + await signInWithEmail(); + }); + }); + }); +} diff --git a/packages/auth/amplify_auth_cognito/example/integration_test/mfa_email_required_test.dart b/packages/auth/amplify_auth_cognito/example/integration_test/mfa_email_required_test.dart new file mode 100644 index 0000000000..5cd4809ad6 --- /dev/null +++ b/packages/auth/amplify_auth_cognito/example/integration_test/mfa_email_required_test.dart @@ -0,0 +1,82 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import 'package:amplify_auth_integration_test/amplify_auth_integration_test.dart'; +import 'package:amplify_flutter/amplify_flutter.dart'; +import 'package:amplify_integration_test/amplify_integration_test.dart'; +import 'package:checks/checks.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'test_runner.dart'; + +void main() { + testRunner.setupTests(); + + group('MFA (Email)', () { + testRunner.withEnvironment(mfaRequiredEmail, (env) { + asyncTest('can sign in with Email MFA', (_) async { + final username = env.generateUsername(); + final password = generatePassword(); + + final otpResult = await getOtpCode( + env.getLoginAttribute(username), + ); + + await adminCreateUser( + username, + password, + autoConfirm: true, + verifyAttributes: true, + attributes: { + AuthUserAttributeKey.email: username, + }, + ); + + final signInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + check(signInRes.nextStep.signInStep) + .equals(AuthSignInStep.confirmSignInWithOtpCode); + + final confirmRes = await Amplify.Auth.confirmSignIn( + confirmationValue: await otpResult.code, + ); + check(confirmRes.nextStep.signInStep).equals(AuthSignInStep.done); + + check(await cognitoPlugin.fetchMfaPreference()).equals( + const UserMfaPreference( + enabled: {MfaType.email}, + preferred: MfaType.email, + ), + ); + + Future signInWithEmail() async { + await signOutUser(assertComplete: true); + + final otpResult = await getOtpCode( + env.getLoginAttribute(username), + ); + + final signInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + check(signInRes.nextStep.signInStep) + .equals(AuthSignInStep.confirmSignInWithOtpCode); + check(signInRes.nextStep.codeDeliveryDetails) + .isNotNull() + .has((d) => d.deliveryMedium, 'deliveryMedium') + .equals(DeliveryMedium.email); + final mfaSetupRes = await Amplify.Auth.confirmSignIn( + confirmationValue: await otpResult.code, + ); + check(mfaSetupRes.nextStep.signInStep).equals(AuthSignInStep.done); + } + + await signInWithEmail(); + await signInWithEmail(); + }); + }); + }); +} diff --git a/packages/auth/amplify_auth_cognito/example/integration_test/mfa_email_totp_optional_test.dart b/packages/auth/amplify_auth_cognito/example/integration_test/mfa_email_totp_optional_test.dart new file mode 100644 index 0000000000..16a9987e1c --- /dev/null +++ b/packages/auth/amplify_auth_cognito/example/integration_test/mfa_email_totp_optional_test.dart @@ -0,0 +1,490 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import 'package:amplify_auth_integration_test/amplify_auth_integration_test.dart'; +import 'package:amplify_flutter/amplify_flutter.dart'; +import 'package:amplify_integration_test/amplify_integration_test.dart'; +import 'package:checks/checks.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'test_runner.dart'; + +void main() { + testRunner.setupTests(); + + group('MFA (EMAIL + TOTP)', () { + testRunner.withEnvironment(mfaOptionalEmailTotp, (env) { + asyncTest('can set up TOTP MFA', (_) async { + final username = env.generateUsername(); + final password = generatePassword(); + + // Create user with no phone number. + await adminCreateUser( + username, + password, + autoConfirm: true, + autoFillAttributes: false, + attributes: { + AuthUserAttributeKey.email: username, + }, + ); + + final signInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + check( + because: 'MFA is optional', + signInRes.nextStep.signInStep, + ).equals(AuthSignInStep.done); + + check(await cognitoPlugin.fetchMfaPreference()) + .equals(const UserMfaPreference()); + + await setUpTotp(); + + check(await cognitoPlugin.fetchMfaPreference()).equals( + const UserMfaPreference( + enabled: {MfaType.totp}, + preferred: MfaType.totp, + ), + ); + + Future signInWithTotp() async { + await signOutUser(assertComplete: true); + final signInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + check( + signInRes.nextStep.signInStep, + because: 'Once TOTP MFA is preferred, it is performed ' + 'on every sign-in attempt.', + ).equals(AuthSignInStep.confirmSignInWithTotpMfaCode); + check(signInRes.nextStep.codeDeliveryDetails).isNotNull() + ..has((d) => d.deliveryMedium, 'deliveryMedium') + .equals(DeliveryMedium.totp) + ..has((d) => d.destination, 'destination') + .equals(friendlyDeviceName); + + final confirmRes = await Amplify.Auth.confirmSignIn( + confirmationValue: await generateTotpCode(), + ); + check(confirmRes.nextStep.signInStep).equals(AuthSignInStep.done); + } + + await signInWithTotp(); + await signInWithTotp(); + + await check( + because: 'TOTP can be disabled when optional', + cognitoPlugin.updateMfaPreference(totp: MfaPreference.disabled), + ).completes(); + + check( + because: 'Disabling TOTP should mark it as not preferred', + await cognitoPlugin.fetchMfaPreference(), + ).equals( + const UserMfaPreference(enabled: {}, preferred: null), + ); + }); + + asyncTest('can select TOTP MFA', (_) async { + final username = env.generateUsername(); + final password = generatePassword(); + + // Create a user with an unverified phone number. + await adminCreateUser( + username, + password, + autoConfirm: true, + verifyAttributes: false, + attributes: { + AuthUserAttributeKey.email: username, + }, + ); + + final signInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + check( + signInRes.nextStep.signInStep, + because: 'MFA is optional', + ).equals(AuthSignInStep.done); + + check(await cognitoPlugin.fetchMfaPreference()) + .equals(const UserMfaPreference()); + + await setUpTotp(); + + check(await cognitoPlugin.fetchMfaPreference()).equals( + const UserMfaPreference( + enabled: {MfaType.totp}, + preferred: MfaType.totp, + ), + ); + + await cognitoPlugin.updateMfaPreference( + email: MfaPreference.enabled, + totp: MfaPreference.enabled, + ); + check(await cognitoPlugin.fetchMfaPreference()).equals( + const UserMfaPreference( + enabled: {MfaType.email, MfaType.totp}, + preferred: null, + ), + ); + + { + await signOutUser(assertComplete: true); + + final signInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + check(signInRes.nextStep.signInStep) + .equals(AuthSignInStep.continueSignInWithMfaSelection); + check(signInRes.nextStep.allowedMfaTypes) + .isNotNull() + .deepEquals({MfaType.email, MfaType.totp}); + + final selectRes = await Amplify.Auth.confirmSignIn( + confirmationValue: 'TOTP', + ); + check(selectRes.nextStep.signInStep) + .equals(AuthSignInStep.confirmSignInWithTotpMfaCode); + check(selectRes.nextStep.codeDeliveryDetails).isNotNull() + ..has((d) => d.deliveryMedium, 'deliveryMedium') + .equals(DeliveryMedium.totp) + ..has((d) => d.destination, 'destination') + .equals(friendlyDeviceName); + + final confirmRes = await Amplify.Auth.confirmSignIn( + confirmationValue: await generateTotpCode(), + ); + check(confirmRes.nextStep.signInStep).equals(AuthSignInStep.done); + } + + check(await cognitoPlugin.fetchMfaPreference()).equals( + const UserMfaPreference( + enabled: {MfaType.email, MfaType.totp}, + preferred: null, + ), + ); + + // Verify we can set TOTP as preferred and forego selection. + + await cognitoPlugin.updateMfaPreference( + totp: MfaPreference.preferred, + ); + check( + await cognitoPlugin.fetchMfaPreference(), + because: 'TOTP should be marked preferred', + ).equals( + const UserMfaPreference( + enabled: {MfaType.email, MfaType.totp}, + preferred: MfaType.totp, + ), + ); + + { + await signOutUser(assertComplete: true); + + final signInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + check(signInRes.nextStep.signInStep) + .equals(AuthSignInStep.confirmSignInWithTotpMfaCode); + check(signInRes.nextStep.codeDeliveryDetails).isNotNull() + ..has((d) => d.deliveryMedium, 'deliveryMedium') + .equals(DeliveryMedium.totp) + ..has((d) => d.destination, 'destination') + .equals(friendlyDeviceName); + + final confirmRes = await Amplify.Auth.confirmSignIn( + confirmationValue: await generateTotpCode(), + ); + check(confirmRes.nextStep.signInStep).equals(AuthSignInStep.done); + } + + // Verify we can switch to EMAIL as preferred. + + await cognitoPlugin.updateMfaPreference( + email: MfaPreference.preferred, + ); + check(await cognitoPlugin.fetchMfaPreference()).equals( + const UserMfaPreference( + enabled: {MfaType.email, MfaType.totp}, + preferred: MfaType.email, + ), + ); + + { + await signOutUser(assertComplete: true); + + final otpRes = await getOtpCode(env.getLoginAttribute(username)); + final signInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + check(signInRes.nextStep.signInStep) + .equals(AuthSignInStep.confirmSignInWithOtpCode); + check(signInRes.nextStep.codeDeliveryDetails) + .isNotNull() + .has((d) => d.deliveryMedium, 'deliveryMedium') + .equals(DeliveryMedium.email); + + final confirmRes = await Amplify.Auth.confirmSignIn( + confirmationValue: await otpRes.code, + ); + check(confirmRes.nextStep.signInStep).equals(AuthSignInStep.done); + } + + // Verify marking enabled does not change preference. + await cognitoPlugin.updateMfaPreference( + email: MfaPreference.enabled, + totp: MfaPreference.enabled, + ); + check( + await cognitoPlugin.fetchMfaPreference(), + because: 'EMAIL should still be marked preferred', + ).equals( + const UserMfaPreference( + enabled: {MfaType.email, MfaType.totp}, + preferred: MfaType.email, + ), + ); + + // Verify we can mark neither as preferred + await cognitoPlugin.updateMfaPreference( + email: MfaPreference.notPreferred, + ); + check( + await cognitoPlugin.fetchMfaPreference(), + because: 'EMAIL should be marked not preferred', + ).equals( + const UserMfaPreference( + enabled: {MfaType.email, MfaType.totp}, + preferred: null, + ), + ); + + // Verify that we can disable both + await check( + because: 'MFA can be disabled when optional', + cognitoPlugin.updateMfaPreference( + email: MfaPreference.disabled, + totp: MfaPreference.disabled, + ), + ).completes(); + + check( + because: 'Disabling MFA should mark it as not preferred', + await cognitoPlugin.fetchMfaPreference(), + ).equals( + const UserMfaPreference(enabled: {}, preferred: null), + ); + }); + + asyncTest('can select EMAIL MFA', (_) async { + final username = env.generateUsername(); + final password = generatePassword(); + + // Create a user with an unverified phone number. + await adminCreateUser( + username, + password, + autoConfirm: true, + verifyAttributes: false, + attributes: { + AuthUserAttributeKey.email: username, + }, + ); + + final signInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + check( + signInRes.nextStep.signInStep, + because: 'MFA is optional', + ).equals(AuthSignInStep.done); + + check(await cognitoPlugin.fetchMfaPreference()) + .equals(const UserMfaPreference()); + + await setUpTotp(); + + check(await cognitoPlugin.fetchMfaPreference()).equals( + const UserMfaPreference( + enabled: {MfaType.totp}, + preferred: MfaType.totp, + ), + ); + + await cognitoPlugin.updateMfaPreference( + email: MfaPreference.enabled, + totp: MfaPreference.enabled, + ); + check(await cognitoPlugin.fetchMfaPreference()).equals( + const UserMfaPreference( + enabled: {MfaType.email, MfaType.totp}, + preferred: null, + ), + ); + + await signOutUser(assertComplete: true); + + final otpResult = await getOtpCode(UserAttribute.email(username)); + + final resignInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + check(resignInRes.nextStep.signInStep) + .equals(AuthSignInStep.continueSignInWithMfaSelection); + check(resignInRes.nextStep.allowedMfaTypes) + .isNotNull() + .deepEquals({MfaType.email, MfaType.totp}); + + final selectRes = await Amplify.Auth.confirmSignIn( + confirmationValue: 'EMAIL', + ); + check(selectRes.nextStep.signInStep) + .equals(AuthSignInStep.confirmSignInWithOtpCode); + check(selectRes.nextStep.codeDeliveryDetails) + .isNotNull() + .has((d) => d.deliveryMedium, 'deliveryMedium') + .equals(DeliveryMedium.email); + + final confirmRes = await Amplify.Auth.confirmSignIn( + confirmationValue: await otpResult.code, + ); + check(confirmRes.nextStep.signInStep).equals(AuthSignInStep.done); + + check(await cognitoPlugin.fetchMfaPreference()).equals( + const UserMfaPreference( + enabled: {MfaType.email, MfaType.totp}, + preferred: null, + ), + ); + + // Verify we can set EMAIL as preferred and forego selection. + + await cognitoPlugin.updateMfaPreference( + email: MfaPreference.preferred, + ); + check(await cognitoPlugin.fetchMfaPreference()).equals( + const UserMfaPreference( + enabled: {MfaType.email, MfaType.totp}, + preferred: MfaType.email, + ), + ); + + { + await signOutUser(assertComplete: true); + + final otpResult = await getOtpCode(UserAttribute.email(username)); + final signInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + check(signInRes.nextStep.signInStep) + .equals(AuthSignInStep.confirmSignInWithOtpCode); + check(signInRes.nextStep.codeDeliveryDetails) + .isNotNull() + .has((d) => d.deliveryMedium, 'deliveryMedium') + .equals(DeliveryMedium.email); + + final confirmRes = await Amplify.Auth.confirmSignIn( + confirmationValue: await otpResult.code, + ); + check(confirmRes.nextStep.signInStep).equals(AuthSignInStep.done); + } + + // Verify we can switch to TOTP as preferred. + + await cognitoPlugin.updateMfaPreference( + totp: MfaPreference.preferred, + ); + check( + await cognitoPlugin.fetchMfaPreference(), + because: 'TOTP should be marked preferred', + ).equals( + const UserMfaPreference( + enabled: {MfaType.email, MfaType.totp}, + preferred: MfaType.totp, + ), + ); + + { + await signOutUser(assertComplete: true); + + final signInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + check(signInRes.nextStep.signInStep) + .equals(AuthSignInStep.confirmSignInWithTotpMfaCode); + check(signInRes.nextStep.codeDeliveryDetails).isNotNull() + ..has((d) => d.deliveryMedium, 'deliveryMedium') + .equals(DeliveryMedium.totp) + ..has((d) => d.destination, 'destination') + .equals(friendlyDeviceName); + + final confirmRes = await Amplify.Auth.confirmSignIn( + confirmationValue: await generateTotpCode(), + ); + check(confirmRes.nextStep.signInStep).equals(AuthSignInStep.done); + } + + // Verify marking enabled does not change preference. + await cognitoPlugin.updateMfaPreference( + email: MfaPreference.enabled, + totp: MfaPreference.enabled, + ); + check( + await cognitoPlugin.fetchMfaPreference(), + because: 'TOTP should still be marked preferred', + ).equals( + const UserMfaPreference( + enabled: {MfaType.email, MfaType.totp}, + preferred: MfaType.totp, + ), + ); + + // Verify we can mark neither as preferred + await cognitoPlugin.updateMfaPreference( + totp: MfaPreference.notPreferred, + ); + check( + await cognitoPlugin.fetchMfaPreference(), + because: 'TOTP should be marked not preferred', + ).equals( + const UserMfaPreference( + enabled: {MfaType.email, MfaType.totp}, + preferred: null, + ), + ); + + // Verify that we can disable both + await check( + because: 'MFA can be disabled when optional', + cognitoPlugin.updateMfaPreference( + email: MfaPreference.disabled, + totp: MfaPreference.disabled, + ), + ).completes(); + + check( + because: 'Disabling MFA should mark it as not preferred', + await cognitoPlugin.fetchMfaPreference(), + ).equals( + const UserMfaPreference(enabled: {}, preferred: null), + ); + }); + }); + }); +} diff --git a/packages/auth/amplify_auth_cognito/example/integration_test/mfa_email_totp_required_test.dart b/packages/auth/amplify_auth_cognito/example/integration_test/mfa_email_totp_required_test.dart new file mode 100644 index 0000000000..b7f49da0e6 --- /dev/null +++ b/packages/auth/amplify_auth_cognito/example/integration_test/mfa_email_totp_required_test.dart @@ -0,0 +1,292 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import 'package:amplify_auth_integration_test/amplify_auth_integration_test.dart'; +import 'package:amplify_flutter/amplify_flutter.dart'; +import 'package:amplify_integration_test/amplify_integration_test.dart'; +import 'package:checks/checks.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'test_runner.dart'; + +void main() { + testRunner.setupTests(); + + group('MFA (EMAIL + TOTP)', () { + testRunner.withEnvironment(mfaRequiredEmailTotp, (env) { + asyncTest('can set up EMAIL MFA', (_) async { + final username = env.generateUsername(); + final password = generatePassword(); + + final otpResult = await getOtpCode(UserAttribute.email(username)); + + // Create a user with no phone number. + await adminCreateUser( + username, + password, + autoConfirm: true, + autoFillAttributes: false, + verifyAttributes: false, + ); + + final signInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + check( + signInRes.nextStep.signInStep, + because: + 'When an email is registered and the userpool has email MFA enabled, Cognito will automatically enable email MFA as the preferred MFA method.', + ).equals(AuthSignInStep.confirmSignInWithOtpCode); + + final setupRes = await Amplify.Auth.confirmSignIn( + confirmationValue: await otpResult.code, + ); + check(setupRes.nextStep.signInStep).equals(AuthSignInStep.done); + + check(await cognitoPlugin.fetchMfaPreference()).equals( + const UserMfaPreference( + enabled: {MfaType.email}, + preferred: MfaType.email, + ), + ); + + await signOutUser(assertComplete: true); + + final otpResult2 = await getOtpCode(UserAttribute.email(username)); + + final resignInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + check(resignInRes.nextStep.signInStep) + .equals(AuthSignInStep.confirmSignInWithOtpCode); + check(resignInRes.nextStep.codeDeliveryDetails) + .isNotNull() + .has((d) => d.deliveryMedium, 'deliveryMedium') + .equals(DeliveryMedium.email); + + final confirmRes = await Amplify.Auth.confirmSignIn( + confirmationValue: await otpResult2.code, + ); + check(confirmRes.nextStep.signInStep).equals(AuthSignInStep.done); + }); + + asyncTest('can select TOTP MFA', (_) async { + final username = env.generateUsername(); + final password = generatePassword(); + + final otpResult = await getOtpCode(UserAttribute.email(username)); + + // Create a user with an unverified phone number. + await adminCreateUser( + username, + password, + autoConfirm: true, + verifyAttributes: false, + attributes: { + AuthUserAttributeKey.email: username, + }, + ); + + { + final signInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + check( + signInRes.nextStep.signInStep, + because: + 'MFA is required so Cognito automatically enables EMAIL MFA', + ).equals(AuthSignInStep.confirmSignInWithOtpCode); + + final confirmRes = await Amplify.Auth.confirmSignIn( + confirmationValue: await otpResult.code, + ); + check(confirmRes.nextStep.signInStep).equals(AuthSignInStep.done); + } + + check( + await cognitoPlugin.fetchMfaPreference(), + because: + 'MFA is required so Cognito automatically enables EMAIL MFA, this is expected behavior', + ).equals( + const UserMfaPreference( + enabled: {MfaType.email}, + preferred: MfaType.email, + ), + ); + + await setUpTotp(); + + check(await cognitoPlugin.fetchMfaPreference()).equals( + const UserMfaPreference( + enabled: {MfaType.email, MfaType.totp}, + preferred: null, + ), + ); + + await signOutUser(assertComplete: true); + + { + final resignInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + check( + resignInRes.nextStep.signInStep, + because: 'Both EMAIL + TOTP are activated with no preference', + ).equals(AuthSignInStep.continueSignInWithMfaSelection); + check(resignInRes.nextStep.allowedMfaTypes) + .isNotNull() + .deepEquals({MfaType.email, MfaType.totp}); + + final selectRes = await Amplify.Auth.confirmSignIn( + confirmationValue: 'TOTP', + ); + check(selectRes.nextStep.signInStep) + .equals(AuthSignInStep.confirmSignInWithTotpMfaCode); + check(selectRes.nextStep.codeDeliveryDetails).isNotNull() + ..has((d) => d.deliveryMedium, 'deliveryMedium') + .equals(DeliveryMedium.totp) + ..has((d) => d.destination, 'destination') + .equals(friendlyDeviceName); + + final confirmRes = await Amplify.Auth.confirmSignIn( + confirmationValue: await generateTotpCode(), + ); + check(confirmRes.nextStep.signInStep).equals(AuthSignInStep.done); + } + + check(await cognitoPlugin.fetchMfaPreference()).equals( + const UserMfaPreference( + enabled: {MfaType.email, MfaType.totp}, + preferred: null, + ), + ); + + // Verify we can set TOTP as preferred and forego selection. + + await cognitoPlugin.updateMfaPreference( + totp: MfaPreference.preferred, + ); + check(await cognitoPlugin.fetchMfaPreference()).equals( + const UserMfaPreference( + enabled: {MfaType.email, MfaType.totp}, + preferred: MfaType.totp, + ), + ); + + { + await signOutUser(assertComplete: true); + + final signInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + check( + signInRes.nextStep.signInStep, + because: 'Preference is TOTP MFA now', + ).equals(AuthSignInStep.confirmSignInWithTotpMfaCode); + check(signInRes.nextStep.codeDeliveryDetails).isNotNull() + ..has((d) => d.deliveryMedium, 'deliveryMedium') + .equals(DeliveryMedium.totp) + ..has((d) => d.destination, 'destination') + .equals(friendlyDeviceName); + + final confirmRes = await Amplify.Auth.confirmSignIn( + confirmationValue: await generateTotpCode(), + ); + check(confirmRes.nextStep.signInStep).equals(AuthSignInStep.done); + } + + // Verify we can switch to EMAIL as preferred. + + await cognitoPlugin.updateMfaPreference( + email: MfaPreference.preferred, + ); + check(await cognitoPlugin.fetchMfaPreference()).equals( + const UserMfaPreference( + enabled: {MfaType.email, MfaType.totp}, + preferred: MfaType.email, + ), + ); + + { + await signOutUser(assertComplete: true); + + final otpResult = await getOtpCode(UserAttribute.email(username)); + + final signInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + check( + signInRes.nextStep.signInStep, + because: 'Preference is EMAIL MFA now', + ).equals(AuthSignInStep.confirmSignInWithOtpCode); + check(signInRes.nextStep.codeDeliveryDetails) + .isNotNull() + .has((d) => d.deliveryMedium, 'deliveryMedium') + .equals(DeliveryMedium.email); + + final confirmRes = await Amplify.Auth.confirmSignIn( + confirmationValue: await otpResult.code, + ); + check(confirmRes.nextStep.signInStep).equals(AuthSignInStep.done); + } + + // Verify marking enabled does not change preference. + await cognitoPlugin.updateMfaPreference( + email: MfaPreference.enabled, + totp: MfaPreference.enabled, + ); + check( + await cognitoPlugin.fetchMfaPreference(), + because: 'EMAIL should still be marked preferred', + ).equals( + const UserMfaPreference( + enabled: {MfaType.email, MfaType.totp}, + preferred: MfaType.email, + ), + ); + + // Verify we can mark neither as preferred + await cognitoPlugin.updateMfaPreference( + email: MfaPreference.notPreferred, + ); + check( + await cognitoPlugin.fetchMfaPreference(), + because: 'EMAIL should be marked not preferred', + ).equals( + const UserMfaPreference( + enabled: {MfaType.email, MfaType.totp}, + preferred: null, + ), + ); + + // Verify that we can disable MFA + { + await check( + because: 'Interestingly, Cognito does not throw and allows ' + 'MFA to be disabled even when required.', + cognitoPlugin.updateMfaPreference( + email: MfaPreference.disabled, + totp: MfaPreference.disabled, + ), + ).completes(); + + check( + because: 'Disabling MFA should mark it as not preferred', + await cognitoPlugin.fetchMfaPreference(), + ).equals( + const UserMfaPreference( + enabled: {}, + preferred: null, + ), + ); + } + }); + }); + }); +} diff --git a/packages/auth/amplify_auth_cognito/example/integration_test/mfa_sms_email_optional_test.dart b/packages/auth/amplify_auth_cognito/example/integration_test/mfa_sms_email_optional_test.dart new file mode 100644 index 0000000000..4be77b4f06 --- /dev/null +++ b/packages/auth/amplify_auth_cognito/example/integration_test/mfa_sms_email_optional_test.dart @@ -0,0 +1,434 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import 'package:amplify_auth_integration_test/amplify_auth_integration_test.dart'; +import 'package:amplify_flutter/amplify_flutter.dart'; +import 'package:amplify_integration_test/amplify_integration_test.dart'; +import 'package:checks/checks.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'test_runner.dart'; + +void main() { + testRunner.setupTests(); + + group('MFA (SMS + EMAIL)', () { + testRunner.withEnvironment(mfaOptionalEmailSms, (env) { + asyncTest('can set up EMAIL MFA', (_) async { + final username = env.generateUsername(); + final password = generatePassword(); + + // Create user with no phone number. + await adminCreateUser( + username, + password, + autoConfirm: true, + autoFillAttributes: false, + ); + + final signInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + check( + because: 'MFA is optional', + signInRes.nextStep.signInStep, + ).equals(AuthSignInStep.done); + + check(await cognitoPlugin.fetchMfaPreference()) + .equals(const UserMfaPreference()); + + await cognitoPlugin.updateMfaPreference( + email: MfaPreference.preferred, + ); + + check(await cognitoPlugin.fetchMfaPreference()).equals( + const UserMfaPreference( + enabled: {MfaType.email}, + preferred: MfaType.email, + ), + ); + + Future signInWithEmail() async { + await signOutUser(assertComplete: true); + + final otpResult = await getOtpCode( + env.getLoginAttribute(username), + ); + + final signInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + check( + signInRes.nextStep.signInStep, + because: 'Once Email MFA is preferred, it is performed ' + 'on every sign-in attempt.', + ).equals(AuthSignInStep.confirmSignInWithOtpCode); + check(signInRes.nextStep.codeDeliveryDetails) + .isNotNull() + .has((d) => d.deliveryMedium, 'deliveryMedium') + .equals(DeliveryMedium.email); + + final confirmRes = await Amplify.Auth.confirmSignIn( + confirmationValue: await otpResult.code, + ); + check(confirmRes.nextStep.signInStep).equals(AuthSignInStep.done); + } + + await signInWithEmail(); + await signInWithEmail(); + + await check( + because: 'EMAIL can be disabled when optional', + cognitoPlugin.updateMfaPreference(email: MfaPreference.disabled), + ).completes(); + + check( + because: 'Disabling EMAIL should mark it as not preferred', + await cognitoPlugin.fetchMfaPreference(), + ).equals( + const UserMfaPreference(enabled: {}, preferred: null), + ); + }); + + asyncTest('can select EMAIL MFA', (_) async { + final username = env.generateUsername(); + final password = generatePassword(); + final phoneNumber = generatePhoneNumber(); + + final otpResult = await getOtpCode( + env.getLoginAttribute(username), + ); + + // Create a user with an unverified phone number. + await adminCreateUser( + username, + password, + autoConfirm: true, + verifyAttributes: false, + attributes: { + AuthUserAttributeKey.phoneNumber: phoneNumber, + AuthUserAttributeKey.email: username, + }, + ); + + final signInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + check( + signInRes.nextStep.signInStep, + because: 'MFA is optional', + ).equals(AuthSignInStep.done); + + check(await cognitoPlugin.fetchMfaPreference()) + .equals(const UserMfaPreference()); + + await cognitoPlugin.updateMfaPreference( + email: MfaPreference.preferred, + ); + + check(await cognitoPlugin.fetchMfaPreference()).equals( + const UserMfaPreference( + enabled: {MfaType.email}, + preferred: MfaType.email, + ), + ); + + await cognitoPlugin.updateMfaPreference( + sms: MfaPreference.enabled, + ); + + check(await cognitoPlugin.fetchMfaPreference()).equals( + const UserMfaPreference( + enabled: {MfaType.sms, MfaType.email}, + preferred: MfaType.email, + ), + ); + + { + await signOutUser(assertComplete: true); + + final signInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + check(signInRes.nextStep.signInStep) + .equals(AuthSignInStep.confirmSignInWithOtpCode); + check(signInRes.nextStep.codeDeliveryDetails) + .isNotNull() + .has((d) => d.deliveryMedium, 'deliveryMedium') + .equals(DeliveryMedium.email); + + final confirmRes = await Amplify.Auth.confirmSignIn( + confirmationValue: await otpResult.code, + ); + check(confirmRes.nextStep.signInStep).equals(AuthSignInStep.done); + } + + check(await cognitoPlugin.fetchMfaPreference()).equals( + const UserMfaPreference( + enabled: {MfaType.sms, MfaType.email}, + preferred: MfaType.email, + ), + ); + + // Verify we can switch to SMS as preferred. + + await cognitoPlugin.updateMfaPreference( + sms: MfaPreference.preferred, + ); + check(await cognitoPlugin.fetchMfaPreference()).equals( + const UserMfaPreference( + enabled: {MfaType.sms, MfaType.email}, + preferred: MfaType.sms, + ), + ); + + { + await signOutUser(assertComplete: true); + + final mfaCode = await getOtpCode(UserAttribute.phone(phoneNumber)); + final signInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + check(signInRes.nextStep.signInStep) + .equals(AuthSignInStep.confirmSignInWithSmsMfaCode); + check(signInRes.nextStep.codeDeliveryDetails).isNotNull() + ..has((d) => d.deliveryMedium, 'deliveryMedium') + .equals(DeliveryMedium.sms) + ..has((d) => d.destination, 'destination') + .isNotNull() + .startsWith('+'); + + final confirmRes = await Amplify.Auth.confirmSignIn( + confirmationValue: await mfaCode.code, + ); + check(confirmRes.nextStep.signInStep).equals(AuthSignInStep.done); + } + + // Verify marking enabled does not change preference. + await cognitoPlugin.updateMfaPreference( + sms: MfaPreference.enabled, + email: MfaPreference.enabled, + ); + check( + await cognitoPlugin.fetchMfaPreference(), + because: 'SMS should still be marked preferred', + ).equals( + const UserMfaPreference( + enabled: {MfaType.sms, MfaType.email}, + preferred: MfaType.sms, + ), + ); + + // Verify that we can disable both + await check( + because: 'MFA can be disabled when optional', + cognitoPlugin.updateMfaPreference( + sms: MfaPreference.disabled, + email: MfaPreference.disabled, + ), + ).completes(); + + check( + because: 'Disabling MFA should mark it as not preferred', + await cognitoPlugin.fetchMfaPreference(), + ).equals( + const UserMfaPreference(enabled: {}, preferred: null), + ); + }); + + asyncTest('can select SMS MFA', (_) async { + final username = env.generateUsername(); + final password = generatePassword(); + final phoneNumber = generatePhoneNumber(); + + // Create a user with an unverified phone number. + await adminCreateUser( + username, + password, + autoConfirm: true, + verifyAttributes: false, + attributes: { + AuthUserAttributeKey.phoneNumber: phoneNumber, + AuthUserAttributeKey.email: username, + }, + ); + + final signInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + check( + signInRes.nextStep.signInStep, + because: 'MFA is optional', + ).equals(AuthSignInStep.done); + + check(await cognitoPlugin.fetchMfaPreference()) + .equals(const UserMfaPreference()); + + await cognitoPlugin.updateMfaPreference( + sms: MfaPreference.preferred, + email: MfaPreference.enabled, + ); + + check(await cognitoPlugin.fetchMfaPreference()).equals( + const UserMfaPreference( + enabled: {MfaType.email, MfaType.sms}, + preferred: MfaType.sms, + ), + ); + + await cognitoPlugin.updateMfaPreference( + sms: MfaPreference.enabled, + email: MfaPreference.enabled, + ); + check(await cognitoPlugin.fetchMfaPreference()).equals( + const UserMfaPreference( + enabled: {MfaType.sms, MfaType.email}, + preferred: MfaType.sms, + ), + ); + + await signOutUser(assertComplete: true); + + final mfaCode = await getOtpCode(UserAttribute.phone(phoneNumber)); + + final resignInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + check(resignInRes.nextStep.signInStep) + .equals(AuthSignInStep.confirmSignInWithSmsMfaCode); + check(resignInRes.nextStep.codeDeliveryDetails).isNotNull() + ..has((d) => d.deliveryMedium, 'deliveryMedium') + .equals(DeliveryMedium.sms) + ..has((d) => d.destination, 'destination') + .isNotNull() + .startsWith('+'); + + final confirmRes = await Amplify.Auth.confirmSignIn( + confirmationValue: await mfaCode.code, + ); + + check(confirmRes.nextStep.signInStep).equals(AuthSignInStep.done); + + check(await cognitoPlugin.fetchMfaPreference()).equals( + const UserMfaPreference( + enabled: {MfaType.sms, MfaType.email}, + preferred: MfaType.sms, + ), + ); + + // Verify we can set SMS as preferred and forego selection. + + await cognitoPlugin.updateMfaPreference( + sms: MfaPreference.preferred, + ); + check(await cognitoPlugin.fetchMfaPreference()).equals( + const UserMfaPreference( + enabled: {MfaType.sms, MfaType.email}, + preferred: MfaType.sms, + ), + ); + + { + await signOutUser(assertComplete: true); + + final mfaCode = await getOtpCode(UserAttribute.phone(phoneNumber)); + final signInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + check(signInRes.nextStep.signInStep) + .equals(AuthSignInStep.confirmSignInWithSmsMfaCode); + check(signInRes.nextStep.codeDeliveryDetails).isNotNull() + ..has((d) => d.deliveryMedium, 'deliveryMedium') + .equals(DeliveryMedium.sms) + ..has((d) => d.destination, 'destination') + .isNotNull() + .startsWith('+'); + + final confirmRes = await Amplify.Auth.confirmSignIn( + confirmationValue: await mfaCode.code, + ); + check(confirmRes.nextStep.signInStep).equals(AuthSignInStep.done); + } + + // Verify we can switch to EMAIL as preferred. + + await cognitoPlugin.updateMfaPreference( + email: MfaPreference.preferred, + ); + check( + await cognitoPlugin.fetchMfaPreference(), + because: 'EMAIL should be marked preferred', + ).equals( + const UserMfaPreference( + enabled: {MfaType.sms, MfaType.email}, + preferred: MfaType.email, + ), + ); + + { + await signOutUser(assertComplete: true); + + final otpResult = await getOtpCode( + env.getLoginAttribute(username), + ); + + final signInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + + check(signInRes.nextStep.signInStep) + .equals(AuthSignInStep.confirmSignInWithOtpCode); + check(signInRes.nextStep.codeDeliveryDetails) + .isNotNull() + .has((d) => d.deliveryMedium, 'deliveryMedium') + .equals(DeliveryMedium.email); + + final confirmRes = await Amplify.Auth.confirmSignIn( + confirmationValue: await otpResult.code, + ); + check(confirmRes.nextStep.signInStep).equals(AuthSignInStep.done); + } + + // Verify marking enabled does not change preference. + await cognitoPlugin.updateMfaPreference( + sms: MfaPreference.enabled, + email: MfaPreference.enabled, + ); + check( + await cognitoPlugin.fetchMfaPreference(), + because: 'EMAIL should still be marked preferred', + ).equals( + const UserMfaPreference( + enabled: {MfaType.sms, MfaType.email}, + preferred: MfaType.email, + ), + ); + + // Verify that we can disable both + await check( + because: 'MFA can be disabled when optional', + cognitoPlugin.updateMfaPreference( + sms: MfaPreference.disabled, + email: MfaPreference.disabled, + ), + ).completes(); + + check( + because: 'Disabling MFA should mark it as not preferred', + await cognitoPlugin.fetchMfaPreference(), + ).equals( + const UserMfaPreference(enabled: {}, preferred: null), + ); + }); + }); + }); +} diff --git a/packages/auth/amplify_auth_cognito/example/integration_test/mfa_sms_email_required_test.dart b/packages/auth/amplify_auth_cognito/example/integration_test/mfa_sms_email_required_test.dart new file mode 100644 index 0000000000..6a3da16919 --- /dev/null +++ b/packages/auth/amplify_auth_cognito/example/integration_test/mfa_sms_email_required_test.dart @@ -0,0 +1,354 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import 'package:amplify_auth_integration_test/amplify_auth_integration_test.dart'; +import 'package:amplify_flutter/amplify_flutter.dart'; +import 'package:amplify_integration_test/amplify_integration_test.dart'; +import 'package:checks/checks.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'test_runner.dart'; + +void main() { + testRunner.setupTests(); + + group('MFA (EMAIL + SMS)', () { + testRunner.withEnvironment(mfaRequiredEmailSms, (env) { + asyncTest('can set up EMAIL MFA', (_) async { + final username = env.generateUsername(); + final password = generatePassword(); + + final otpResult = await getOtpCode( + env.getLoginAttribute(username), + ); + + // Create a user with no phone number. + await adminCreateUser( + username, + password, + autoConfirm: true, + attributes: { + AuthUserAttributeKey.email: username, + }, + autoFillAttributes: false, + ); + + final signInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + check( + signInRes.nextStep.signInStep, + because: 'MFA is required, and EMAIL is chosen when ' + 'no phone number is registered', + ).equals(AuthSignInStep.confirmSignInWithOtpCode); + + final setupRes = await Amplify.Auth.confirmSignIn( + confirmationValue: await otpResult.code, + ); + check(setupRes.nextStep.signInStep).equals(AuthSignInStep.done); + + check(await cognitoPlugin.fetchMfaPreference()).equals( + const UserMfaPreference( + enabled: {MfaType.email}, + preferred: MfaType.email, + ), + ); + + await signOutUser(assertComplete: true); + + // Verify we can sign in with EMAIL MFA as the preferred method and forego selection. + + final otpResult2 = await getOtpCode( + env.getLoginAttribute(username), + ); + + final resignInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + check(resignInRes.nextStep.signInStep) + .equals(AuthSignInStep.confirmSignInWithOtpCode); + check(resignInRes.nextStep.codeDeliveryDetails) + .isNotNull() + .has((d) => d.deliveryMedium, 'deliveryMedium') + .equals(DeliveryMedium.email); + + final confirmRes = await Amplify.Auth.confirmSignIn( + confirmationValue: await otpResult2.code, + ); + check(confirmRes.nextStep.signInStep).equals(AuthSignInStep.done); + }); + + asyncTest('can select EMAIL MFA', (_) async { + final username = env.generateUsername(); + final password = generatePassword(); + final phoneNumber = generatePhoneNumber(); + + final mfaCode = await getOtpCode(UserAttribute.phone(phoneNumber)); + + // Verify we can set EMAIL as preferred and forego selection. + await adminCreateUser( + username, + password, + autoConfirm: true, + verifyAttributes: false, + attributes: { + AuthUserAttributeKey.phoneNumber: phoneNumber, + AuthUserAttributeKey.email: username, + }, + ); + + final signInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + check( + signInRes.nextStep.signInStep, + because: 'MFA is required so Cognito automatically enables SMS MFA', + ).equals(AuthSignInStep.confirmSignInWithSmsMfaCode); + + final confirmRes = await Amplify.Auth.confirmSignIn( + confirmationValue: await mfaCode.code, + ); + check(confirmRes.nextStep.signInStep).equals(AuthSignInStep.done); + + check( + await cognitoPlugin.fetchMfaPreference(), + because: 'MFA is required so Cognito automatically enables SMS MFA', + ).equals( + const UserMfaPreference( + enabled: {MfaType.sms}, + preferred: MfaType.sms, + ), + ); + + await cognitoPlugin.updateMfaPreference( + email: MfaPreference.preferred, + ); + + check(await cognitoPlugin.fetchMfaPreference()).equals( + const UserMfaPreference( + enabled: {MfaType.sms, MfaType.email}, + preferred: MfaType.email, + ), + ); + + await signOutUser(assertComplete: true); + + { + final otpResult = await getOtpCode( + env.getLoginAttribute(username), + ); + final resignInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + check( + resignInRes.nextStep.signInStep, + because: 'Preference is EMAIL MFA now', + ).equals(AuthSignInStep.confirmSignInWithOtpCode); + check(resignInRes.nextStep.codeDeliveryDetails) + .isNotNull() + .has((d) => d.deliveryMedium, 'deliveryMedium') + .equals(DeliveryMedium.email); + + final confirmRes = await Amplify.Auth.confirmSignIn( + confirmationValue: await otpResult.code, + ); + check(confirmRes.nextStep.signInStep).equals(AuthSignInStep.done); + } + + check(await cognitoPlugin.fetchMfaPreference()).equals( + const UserMfaPreference( + enabled: {MfaType.sms, MfaType.email}, + preferred: MfaType.email, + ), + ); + + // Verify marking enabled does not change preference. + await cognitoPlugin.updateMfaPreference( + sms: MfaPreference.enabled, + email: MfaPreference.enabled, + ); + check( + await cognitoPlugin.fetchMfaPreference(), + because: 'SMS should still be marked preferred', + ).equals( + const UserMfaPreference( + enabled: {MfaType.sms, MfaType.email}, + preferred: MfaType.email, + ), + ); + + // Verify that we can disable MFA + { + await check( + because: 'Interestingly, Cognito does not throw and allows ' + 'MFA to be disabled even when required.', + cognitoPlugin.updateMfaPreference( + sms: MfaPreference.disabled, + email: MfaPreference.disabled, + ), + ).completes(); + + check( + because: 'Disabling MFA should mark it as not preferred', + await cognitoPlugin.fetchMfaPreference(), + ).equals( + const UserMfaPreference( + enabled: {}, + preferred: null, + ), + ); + } + }); + + asyncTest('can select SMS MFA', (_) async { + final username = env.generateUsername(); + final password = generatePassword(); + final phoneNumber = generatePhoneNumber(); + + final mfaCode = await getOtpCode(UserAttribute.phone(phoneNumber)); + + // Create a user with an unverified phone number. + await adminCreateUser( + username, + password, + autoConfirm: true, + verifyAttributes: false, + attributes: { + AuthUserAttributeKey.phoneNumber: phoneNumber, + AuthUserAttributeKey.email: username, + }, + ); + + final signInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + check( + signInRes.nextStep.signInStep, + because: 'MFA is required so Cognito automatically enables SMS MFA', + ).equals(AuthSignInStep.confirmSignInWithSmsMfaCode); + + final confirmRes = await Amplify.Auth.confirmSignIn( + confirmationValue: await mfaCode.code, + ); + check(confirmRes.nextStep.signInStep).equals(AuthSignInStep.done); + + check( + await cognitoPlugin.fetchMfaPreference(), + because: 'MFA is required so Cognito automatically enables SMS MFA', + ).equals( + const UserMfaPreference( + enabled: {MfaType.sms}, + preferred: MfaType.sms, + ), + ); + + // Verify we can set SMS as preferred and forego selection. + + { + await signOutUser(assertComplete: true); + + final mfaCode = await getOtpCode(UserAttribute.phone(phoneNumber)); + final signInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + check( + signInRes.nextStep.signInStep, + because: 'Preference is SMS MFA now', + ).equals(AuthSignInStep.confirmSignInWithSmsMfaCode); + check(signInRes.nextStep.codeDeliveryDetails).isNotNull() + ..has((d) => d.deliveryMedium, 'deliveryMedium') + .equals(DeliveryMedium.sms) + ..has((d) => d.destination, 'destination') + .isNotNull() + .startsWith('+'); + + final confirmRes = await Amplify.Auth.confirmSignIn( + confirmationValue: await mfaCode.code, + ); + check(confirmRes.nextStep.signInStep).equals(AuthSignInStep.done); + } + + // Verify we can switch to EMAIL as preferred. + + await cognitoPlugin.updateMfaPreference( + email: MfaPreference.preferred, + ); + check(await cognitoPlugin.fetchMfaPreference()).equals( + const UserMfaPreference( + enabled: {MfaType.sms, MfaType.email}, + preferred: MfaType.email, + ), + ); + + { + await signOutUser(assertComplete: true); + + final otpResult = await getOtpCode( + env.getLoginAttribute(username), + ); + + final signInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + check( + signInRes.nextStep.signInStep, + because: 'Preference is EMAIL MFA now', + ).equals(AuthSignInStep.confirmSignInWithOtpCode); + check(signInRes.nextStep.codeDeliveryDetails) + .isNotNull() + .has((d) => d.deliveryMedium, 'deliveryMedium') + .equals(DeliveryMedium.email); + + final confirmRes = await Amplify.Auth.confirmSignIn( + confirmationValue: await otpResult.code, + ); + check(confirmRes.nextStep.signInStep).equals(AuthSignInStep.done); + } + + // Verify marking enabled does not change preference. + await cognitoPlugin.updateMfaPreference( + sms: MfaPreference.enabled, + email: MfaPreference.enabled, + ); + check( + await cognitoPlugin.fetchMfaPreference(), + because: 'EMAIL should still be marked preferred', + ).equals( + const UserMfaPreference( + enabled: {MfaType.sms, MfaType.email}, + preferred: MfaType.email, + ), + ); + + // Verify that we can disable MFA + { + await check( + because: 'Interestingly, Cognito does not throw and allows ' + 'MFA to be disabled even when required.', + cognitoPlugin.updateMfaPreference( + sms: MfaPreference.disabled, + email: MfaPreference.disabled, + ), + ).completes(); + + check( + because: 'Disabling MFA should mark it as not preferred', + await cognitoPlugin.fetchMfaPreference(), + ).equals( + const UserMfaPreference( + enabled: {}, + preferred: null, + ), + ); + } + }); + }); + }); +} diff --git a/packages/auth/amplify_auth_cognito/example/integration_test/mfa_sms_totp_required_test.dart b/packages/auth/amplify_auth_cognito/example/integration_test/mfa_sms_totp_required_test.dart index 32862bf0bb..2f5c1422e3 100644 --- a/packages/auth/amplify_auth_cognito/example/integration_test/mfa_sms_totp_required_test.dart +++ b/packages/auth/amplify_auth_cognito/example/integration_test/mfa_sms_totp_required_test.dart @@ -35,7 +35,7 @@ void main() { signInRes.nextStep.signInStep, because: 'MFA is required, and TOTP is chosen when ' 'no phone number is registered', - ).equals(AuthSignInStep.continueSignInWithTotpSetup); + ).equals(AuthSignInStep.continueSignInWithMfaSetupSelection); final sharedSecret = signInRes.nextStep.totpSetupDetails!.sharedSecret; final setupRes = await Amplify.Auth.confirmSignIn( diff --git a/packages/auth/amplify_auth_cognito/example/integration_test/mfa_totp_required_test.dart b/packages/auth/amplify_auth_cognito/example/integration_test/mfa_totp_required_test.dart index 84370b665c..323700b9f6 100644 --- a/packages/auth/amplify_auth_cognito/example/integration_test/mfa_totp_required_test.dart +++ b/packages/auth/amplify_auth_cognito/example/integration_test/mfa_totp_required_test.dart @@ -34,7 +34,7 @@ void main() { signInRes.nextStep.signInStep, because: "TOTP MFA is automatically enabled when it's the only option", - ).equals(AuthSignInStep.continueSignInWithTotpSetup); + ).equals(AuthSignInStep.continueSignInWithMfaSetupSelection); final sharedSecret = signInRes.nextStep.totpSetupDetails!.sharedSecret; final setupRes = await Amplify.Auth.confirmSignIn( diff --git a/packages/auth/amplify_auth_cognito/example/integration_test/mfa_username_login_required_test.dart b/packages/auth/amplify_auth_cognito/example/integration_test/mfa_username_login_required_test.dart new file mode 100644 index 0000000000..9903ed6e2d --- /dev/null +++ b/packages/auth/amplify_auth_cognito/example/integration_test/mfa_username_login_required_test.dart @@ -0,0 +1,247 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import 'package:amplify_auth_cognito/amplify_auth_cognito.dart'; +import 'package:amplify_auth_integration_test/amplify_auth_integration_test.dart'; +import 'package:amplify_flutter/amplify_flutter.dart'; +import 'package:amplify_integration_test/amplify_integration_test.dart'; +import 'package:checks/checks.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'test_runner.dart'; + +void main() { + testRunner.setupTests(); + + group('MFA (EMAIL + TOTP + SMS)', () { + testRunner.withEnvironment(mfaRequiredUsernameLogin, (env) { + asyncTest('can set up EMAIL MFA', (_) async { + final username = env.generateUsername(); + final password = generatePassword(); + final email = generateEmail(); + + final otpResult = await getOtpCode(UserAttribute.email(email)); + + // Create a user with no phone number. + await adminCreateUser( + username, + password, + autoConfirm: true, + autoFillAttributes: false, + verifyAttributes: false, + ); + + final signInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + + check( + signInRes.nextStep.signInStep, + because: + 'When an email is registered and the userpool has email MFA enabled, Cognito will automatically enable email MFA as the preferred MFA method.', + ).equals(AuthSignInStep.continueSignInWithMfaSetupSelection); + + await Amplify.Auth.confirmSignIn( + confirmationValue: 'EMAIL', + ); + + await Amplify.Auth.confirmSignIn( + confirmationValue: email, + ); + + final confirmRes = await Amplify.Auth.confirmSignIn( + confirmationValue: await otpResult.code, + ); + + check(confirmRes.nextStep.signInStep).equals(AuthSignInStep.done); + + check(await cognitoPlugin.fetchMfaPreference()).equals( + const UserMfaPreference( + enabled: {MfaType.email}, + preferred: MfaType.email, + ), + ); + + await signOutUser(assertComplete: true); + + final otpResult2 = await getOtpCode(UserAttribute.email(email)); + + final resignInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + check(resignInRes.nextStep.signInStep) + .equals(AuthSignInStep.confirmSignInWithOtpCode); + check(resignInRes.nextStep.codeDeliveryDetails) + .isNotNull() + .has((d) => d.deliveryMedium, 'deliveryMedium') + .equals(DeliveryMedium.email); + + final confirmRes2 = await Amplify.Auth.confirmSignIn( + confirmationValue: await otpResult2.code, + ); + check(confirmRes2.nextStep.signInStep).equals(AuthSignInStep.done); + }); + + asyncTest('can setup TOTP MFA', (_) async { + final username = env.generateUsername(); + final password = generatePassword(); + + // Create a user with an unverified phone number. + await adminCreateUser( + username, + password, + autoConfirm: true, + verifyAttributes: false, + autoFillAttributes: false, + ); + + { + final signInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + check( + signInRes.nextStep.signInStep, + because: 'MFA is required so users select a method to setup', + ).equals(AuthSignInStep.continueSignInWithMfaSetupSelection); + + final selectRes = await Amplify.Auth.confirmSignIn( + confirmationValue: 'TOTP', + ); + + final sharedSecret = + selectRes.nextStep.totpSetupDetails!.sharedSecret; + final setupRes = await Amplify.Auth.confirmSignIn( + confirmationValue: await generateTotpCode(sharedSecret), + options: const ConfirmSignInOptions( + pluginOptions: CognitoConfirmSignInPluginOptions( + friendlyDeviceName: friendlyDeviceName, + ), + ), + ); + + check(setupRes.nextStep.signInStep).equals(AuthSignInStep.done); + } + + check( + await cognitoPlugin.fetchMfaPreference(), + because: + 'MFA is required so Cognito automatically enables EMAIL MFA, this is expected behavior', + ).equals( + const UserMfaPreference( + enabled: {MfaType.totp}, + preferred: MfaType.totp, + ), + ); + + await signOutUser(assertComplete: true); + }); + + asyncTest( + 'Can set up EMAIL and TOTP MFA and then choose a preferred method', + (_) async { + final username = env.generateUsername(); + final password = generatePassword(); + final email = generateEmail(); + + final otpResult = await getOtpCode(UserAttribute.email(email)); + + // Create a user with no phone number. + await adminCreateUser( + username, + password, + autoConfirm: true, + autoFillAttributes: false, + verifyAttributes: false, + ); + + final signInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + + check( + signInRes.nextStep.signInStep, + because: + 'When both EMAIL and TOTP are enabled but email attribute isnt verified, choose an mfa method to set up.', + ).equals(AuthSignInStep.continueSignInWithMfaSetupSelection); + + await Amplify.Auth.confirmSignIn( + confirmationValue: 'EMAIL', + ); + + await Amplify.Auth.confirmSignIn( + confirmationValue: email, + ); + + final confirmRes = await Amplify.Auth.confirmSignIn( + confirmationValue: await otpResult.code, + ); + + check(confirmRes.nextStep.signInStep).equals(AuthSignInStep.done); + + check(await cognitoPlugin.fetchMfaPreference()).equals( + const UserMfaPreference( + enabled: {MfaType.email}, + preferred: MfaType.email, + ), + ); + + await signOutUser(assertComplete: true); + + final otpResult2 = await getOtpCode(UserAttribute.email(email)); + + final resignInRes = await Amplify.Auth.signIn( + username: username, + password: password, + ); + + check(resignInRes.nextStep.signInStep) + .equals(AuthSignInStep.confirmSignInWithOtpCode); + check(resignInRes.nextStep.codeDeliveryDetails) + .isNotNull() + .has((d) => d.deliveryMedium, 'deliveryMedium') + .equals(DeliveryMedium.email); + + final confirmRes2 = await Amplify.Auth.confirmSignIn( + confirmationValue: await otpResult2.code, + ); + check(confirmRes2.nextStep.signInStep).equals(AuthSignInStep.done); + + await setUpTotp(); + + check(await cognitoPlugin.fetchMfaPreference()).equals( + const UserMfaPreference( + enabled: {MfaType.email, MfaType.totp}, + preferred: null, + ), + ); + + // sign out and sign back in and confirm TOTP + await signOutUser(assertComplete: true); + + final resignInRes2 = await Amplify.Auth.signIn( + username: username, + password: password, + ); + + check(resignInRes2.nextStep.signInStep) + .equals(AuthSignInStep.continueSignInWithMfaSelection); + + // select totp as the preferred method + await Amplify.Auth.confirmSignIn( + confirmationValue: 'TOTP', + ); + + final confirmRes3 = await Amplify.Auth.confirmSignIn( + confirmationValue: await generateTotpCode(), + ); + + check(confirmRes3.nextStep.signInStep).equals(AuthSignInStep.done); + }, + ); + }); + }); +} diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/auth_plugin_impl.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/auth_plugin_impl.dart index f458548642..e6a848919e 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/auth_plugin_impl.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/auth_plugin_impl.dart @@ -481,45 +481,45 @@ class AmplifyAuthCognitoDart extends AuthPluginInterface } CognitoSignInResult _processSignInResult(SignInState result) { - return switch (result) { - SignInNotStarted _ || - SignInInitiating _ => + switch (result) { + case SignInNotStarted(): + case SignInInitiating(): // This should never happen. throw UnknownException( 'Sign in could not be completed', underlyingException: result, - ), - SignInCancelling _ => throw const UserCancelledException( + ); + + case SignInCancelling(): + throw const UserCancelledException( 'The user canceled the sign-in flow', - ), - SignInChallenge( - :final challengeName, - :final challengeParameters, - :final codeDeliveryDetails, - :final requiredAttributes, - :final allowedMfaTypes, - :final totpSetupResult, - ) => - CognitoSignInResult( + ); + + case final SignInChallenge challenge: + return CognitoSignInResult( isSignedIn: false, nextStep: AuthNextSignInStep( - signInStep: challengeName.signInStep, - codeDeliveryDetails: codeDeliveryDetails, - additionalInfo: challengeParameters, - missingAttributes: requiredAttributes, - allowedMfaTypes: allowedMfaTypes, - totpSetupDetails: totpSetupResult, + signInStep: challenge.challengeName.signInStep, + codeDeliveryDetails: challenge.codeDeliveryDetails, + additionalInfo: challenge.challengeParameters, + missingAttributes: challenge.requiredAttributes, + allowedMfaTypes: challenge.allowedMfaTypes, + totpSetupDetails: challenge.totpSetupResult, ), - ), - SignInSuccess _ => const CognitoSignInResult( + ); + + case SignInSuccess(): + return const CognitoSignInResult( isSignedIn: true, nextStep: AuthNextSignInStep( signInStep: AuthSignInStep.done, ), - ), - SignInFailure(:final exception, :final stackTrace) => - Error.throwWithStackTrace(exception, stackTrace), - }; + ); + + case final SignInFailure failure: + Error.throwWithStackTrace(failure.exception, failure.stackTrace); +// To satisfy Dart's requirements, even if unreachable + } } @override @@ -885,13 +885,14 @@ class AmplifyAuthCognitoDart extends AuthPluginInterface /// {@template amplify_core.amplify_auth_category.update_mfa_preference} /// Updates the MFA preference for the current user. /// - /// If [sms] or [totp] is `null`, the preference for that MFA type is left - /// unchanged. Setting either [sms] or [totp] to [MfaPreference.preferred] + /// If [sms], [totp], or [email] is `null`, the preference for that MFA type is left + /// unchanged. Setting either [sms], [totp], or [email] to [MfaPreference.preferred] /// will mark the other as not preferred. /// {@endtemplate} Future updateMfaPreference({ MfaPreference? sms, MfaPreference? totp, + MfaPreference? email, }) async { final tokens = await _stateMachine.getUserPoolTokens(); final accessToken = tokens.accessToken.raw; @@ -899,6 +900,7 @@ class AmplifyAuthCognitoDart extends AuthPluginInterface accessToken: accessToken, sms: sms, totp: totp, + email: email, ); } diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/flows/constants.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/flows/constants.dart index 3ab6d376a5..174bf2c9bf 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/flows/constants.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/flows/constants.dart @@ -11,6 +11,9 @@ abstract class CognitoConstants { /// The `USERNAME` parameter. static const challengeParamUsername = 'USERNAME'; + /// The `EMAIL` parameter. + static const challengeParamEmail = 'EMAIL'; + /// The `SRP_A` parameter. static const challengeParamSrpA = 'SRP_A'; @@ -57,6 +60,9 @@ abstract class CognitoConstants { /// The `SMS_MFA_CODE` parameter. static const challengeParamSmsMfaCode = 'SMS_MFA_CODE'; + /// The `EMAIL_OTP_CODE` parameter. + static const challengeParamEmailOtpCode = 'EMAIL_OTP_CODE'; + /// The `SOFTWARE_TOKEN_MFA_CODE` parameter. static const challengeParamSoftwareTokenMfaCode = 'SOFTWARE_TOKEN_MFA_CODE'; diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/cognito_identity.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/cognito_identity.dart index bcac91000f..d3b8223bdb 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/cognito_identity.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/cognito_identity.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas /// # Amazon Cognito Identity diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/cognito_identity_provider.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/cognito_identity_provider.dart index 7682084c1c..3bc1811bc4 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/cognito_identity_provider.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/cognito_identity_provider.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas /// # Amazon Cognito Identity Provider @@ -68,6 +68,7 @@ export 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/ export 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/device_remembered_status_type.dart'; export 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/device_secret_verifier_config_type.dart'; export 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/device_type.dart'; +export 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/email_mfa_settings_type.dart'; export 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/enable_software_token_mfa_exception.dart'; export 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/expired_code_exception.dart'; export 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/forbidden_exception.dart'; @@ -99,6 +100,7 @@ export 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/ export 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/mfa_option_type.dart'; export 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/new_device_metadata_type.dart'; export 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/not_authorized_exception.dart'; +export 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/password_history_policy_violation_exception.dart'; export 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/password_reset_required_exception.dart'; export 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/resend_confirmation_code_request.dart'; export 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/resend_confirmation_code_response.dart'; diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/sdk_bridge.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/sdk_bridge.dart index 5c81717008..9b4de91f08 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/sdk_bridge.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/sdk_bridge.dart @@ -29,9 +29,10 @@ extension ChallengeNameTypeBridge on ChallengeNameType { ChallengeNameType.selectMfaType => AuthSignInStep.continueSignInWithMfaSelection, ChallengeNameType.mfaSetup => - AuthSignInStep.continueSignInWithTotpSetup, + AuthSignInStep.continueSignInWithMfaSetupSelection, ChallengeNameType.softwareTokenMfa => AuthSignInStep.confirmSignInWithTotpMfaCode, + ChallengeNameType.emailOtp => AuthSignInStep.confirmSignInWithOtpCode, ChallengeNameType.adminNoSrpAuth || ChallengeNameType.passwordVerifier || ChallengeNameType.devicePasswordVerifier || @@ -795,80 +796,104 @@ extension MfaSettings on CognitoIdentityProviderClient { required String accessToken, MfaPreference? sms, MfaPreference? totp, + MfaPreference? email, }) async { final UserMfaPreference( enabled: currentEnabled, - preferred: currentPreference - ) = await _getRawUserSettings( - accessToken: accessToken, - ); - const enabledValues = [ - MfaPreference.enabled, - MfaPreference.notPreferred, - MfaPreference.preferred, - ]; - bool isEnabled(MfaType mfaType) { - final explicitlyDisabled = switch (mfaType) { - MfaType.sms => sms == MfaPreference.disabled, - MfaType.totp => totp == MfaPreference.disabled, - }; - if (explicitlyDisabled) { - return false; - } - final currentlyEnabled = currentEnabled.contains(mfaType); - final requestingEnabled = switch (mfaType) { - MfaType.sms => enabledValues.contains(sms), - MfaType.totp => enabledValues.contains(totp), - }; - return currentlyEnabled || requestingEnabled; + preferred: currentPreference, + ) = await _getRawUserSettings(accessToken: accessToken); + + var preferred = + _getNewPreferredMethod(sms: sms, totp: totp, email: email) ?? + currentPreference; + + if (_isCurrentPreferenceDisabled( + currentPreference, + sms: sms, + totp: totp, + email: email, + )) { + preferred = null; } - final preferred = switch ((currentPreference, sms: sms, totp: totp)) { - // Prevent an invalid choice. - (_, sms: MfaPreference.preferred, totp: MfaPreference.preferred) => - throw const InvalidParameterException( - 'Cannot assign both SMS and TOTP as preferred', - ), - - // Setting one or the other as preferred overrides previous value. - (_, sms: MfaPreference.preferred, totp: != MfaPreference.preferred) => - MfaType.sms, - (_, sms: != MfaPreference.preferred, totp: MfaPreference.preferred) => - MfaType.totp, - - // Setting one or the other as disabled or not preferred removes current - // preference if it matches. - ( - MfaType.sms, - sms: MfaPreference.notPreferred || MfaPreference.disabled, - totp: _, - ) || - ( - MfaType.totp, - sms: _, - totp: MfaPreference.notPreferred || MfaPreference.disabled, - ) => - null, - - // Ignore preference changes which do not affect the current preference. - (final currentPreference, sms: _, totp: _) => currentPreference, - }; final smsMfaSettings = SmsMfaSettingsType( - enabled: isEnabled(MfaType.sms), + enabled: _isMfaEnabled(MfaType.sms, sms, currentEnabled), preferredMfa: preferred == MfaType.sms, ); + final softwareTokenSettings = SoftwareTokenMfaSettingsType( - enabled: isEnabled(MfaType.totp), + enabled: _isMfaEnabled(MfaType.totp, totp, currentEnabled), preferredMfa: preferred == MfaType.totp, ); + + final emailMfaSettings = EmailMfaSettingsType( + enabled: _isMfaEnabled(MfaType.email, email, currentEnabled), + preferredMfa: preferred == MfaType.email, + ); + await setUserMfaPreference( SetUserMfaPreferenceRequest( accessToken: accessToken, smsMfaSettings: smsMfaSettings, softwareTokenMfaSettings: softwareTokenSettings, + emailMfaSettings: emailMfaSettings, ), ).result; } + + /// Making sure a maximum of one MFA method is set to preferred. + MfaType? _getNewPreferredMethod({ + MfaPreference? sms, + MfaPreference? totp, + MfaPreference? email, + }) { + final preferredMethods = [ + if (sms == MfaPreference.preferred) MfaType.sms, + if (totp == MfaPreference.preferred) MfaType.totp, + if (email == MfaPreference.preferred) MfaType.email, + ]; + + if (preferredMethods.length > 1) { + throw const InvalidParameterException( + 'Cannot assign multiple MFA methods as preferred', + ); + } + + return preferredMethods.isNotEmpty ? preferredMethods.first : null; + } + + /// Checks if the current preferred MFA method is being disabled or set to not preferred. + bool _isCurrentPreferenceDisabled( + MfaType? currentPreference, { + MfaPreference? sms, + MfaPreference? totp, + MfaPreference? email, + }) { + switch (currentPreference) { + case MfaType.sms: + return sms == MfaPreference.disabled || + sms == MfaPreference.notPreferred; + case MfaType.totp: + return totp == MfaPreference.disabled || + totp == MfaPreference.notPreferred; + case MfaType.email: + return email == MfaPreference.disabled || + email == MfaPreference.notPreferred; + default: + return false; + } + } + + /// Determines if an MFA type should be enabled based on preferences and current settings. + bool _isMfaEnabled( + MfaType mfaType, + MfaPreference? preference, + Set currentEnabled, + ) { + if (preference == MfaPreference.disabled) return false; + if (preference != null) return true; + return currentEnabled.contains(mfaType); + } } extension on String { @@ -876,6 +901,7 @@ extension on String { MfaType get mfaType => switch (this) { 'SOFTWARE_TOKEN_MFA' => MfaType.totp, 'SMS_MFA' => MfaType.sms, + 'EMAIL_OTP' => MfaType.email, final invalidType => throw StateError('Invalid MFA type: $invalidType'), }; } diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/sdk_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/sdk_exception.dart index fde039d5f1..78f5d3eaa8 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/sdk_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/sdk_exception.dart @@ -356,6 +356,22 @@ final class NotAuthorizedServiceException extends CognitoServiceException String get runtimeTypeName => 'NotAuthorizedServiceException'; } +/// {@template amplify_auth_cognito_dart.sdk_exception.password_history_policy_violation_exception} +/// The message returned when a user's new password matches a previous password and doesn't comply with the password-history policy. +/// {@endtemplate} +final class PasswordHistoryPolicyViolationException + extends CognitoServiceException { + /// {@macro amplify_auth_cognito_dart.sdk_exception.password_history_policy_violation_exception} + const PasswordHistoryPolicyViolationException( + super.message, { + super.recoverySuggestion, + super.underlyingException, + }); + + @override + String get runtimeTypeName => 'PasswordHistoryPolicyViolationException'; +} + /// {@template amplify_auth_cognito_dart.sdk_exception.password_reset_required_exception} /// This exception is thrown when a password reset is required. /// {@endtemplate} @@ -685,6 +701,11 @@ Object transformSdkException(Object e) { message, underlyingException: e, ), + 'PasswordHistoryPolicyViolationException' => + PasswordHistoryPolicyViolationException( + message, + underlyingException: e, + ), 'PasswordResetRequiredException' => PasswordResetRequiredException( message, underlyingException: e, diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/cognito_identity_client.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/cognito_identity_client.dart index 4fce991aac..49472116d5 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/cognito_identity_client.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/cognito_identity_client.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity.cognito_identity_client; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/common/endpoint_resolver.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/common/endpoint_resolver.dart index 7cd37f555f..aabe87df7f 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/common/endpoint_resolver.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/common/endpoint_resolver.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity.common.endpoint_resolver; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/common/serializers.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/common/serializers.dart index 53d9ea9022..13d2996e70 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/common/serializers.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/common/serializers.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity.common.serializers; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/credentials.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/credentials.dart index 4a9768bec5..f907c481b8 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/credentials.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/credentials.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity.model.credentials; // ignore_for_file: no_leading_underscores_for_library_prefixes @@ -67,7 +67,7 @@ abstract class Credentials ) ..add( 'secretKey', - secretKey, + '***SENSITIVE***', ) ..add( 'sessionToken', diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/external_service_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/external_service_exception.dart index 40fea8d03e..9e9500945b 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/external_service_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/external_service_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity.model.external_service_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/get_credentials_for_identity_input.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/get_credentials_for_identity_input.dart index 76881a5f20..1ef8ddd869 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/get_credentials_for_identity_input.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/get_credentials_for_identity_input.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity.model.get_credentials_for_identity_input; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/get_credentials_for_identity_response.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/get_credentials_for_identity_response.dart index 3bda9069de..6f83f4cf28 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/get_credentials_for_identity_response.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/get_credentials_for_identity_response.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity.model.get_credentials_for_identity_response; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/get_id_input.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/get_id_input.dart index 2469ffe450..15ed362231 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/get_id_input.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/get_id_input.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity.model.get_id_input; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/get_id_response.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/get_id_response.dart index 17f61687d0..dfe391a845 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/get_id_response.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/get_id_response.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity.model.get_id_response; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/internal_error_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/internal_error_exception.dart index c3aefa1100..4f5a7455e9 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/internal_error_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/internal_error_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity.model.internal_error_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/invalid_identity_pool_configuration_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/invalid_identity_pool_configuration_exception.dart index 2e2b04cb49..c25b63d9fa 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/invalid_identity_pool_configuration_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/invalid_identity_pool_configuration_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity.model.invalid_identity_pool_configuration_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/invalid_parameter_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/invalid_parameter_exception.dart index dd0e1bb993..881a613f75 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/invalid_parameter_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/invalid_parameter_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity.model.invalid_parameter_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/limit_exceeded_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/limit_exceeded_exception.dart index d12231e2d3..4909ca0b94 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/limit_exceeded_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/limit_exceeded_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity.model.limit_exceeded_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/not_authorized_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/not_authorized_exception.dart index 43841286cb..50add67fb4 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/not_authorized_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/not_authorized_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity.model.not_authorized_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/resource_conflict_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/resource_conflict_exception.dart index 5e5f88ad77..cc4b2f9846 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/resource_conflict_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/resource_conflict_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity.model.resource_conflict_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/resource_not_found_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/resource_not_found_exception.dart index 2061531b78..1ba7efb1b3 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/resource_not_found_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/resource_not_found_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity.model.resource_not_found_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/too_many_requests_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/too_many_requests_exception.dart index 01a910e91a..e005c51ca2 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/too_many_requests_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/model/too_many_requests_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity.model.too_many_requests_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/operation/get_credentials_for_identity_operation.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/operation/get_credentials_for_identity_operation.dart index 0a3319e2d0..a70ab6465f 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/operation/get_credentials_for_identity_operation.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/operation/get_credentials_for_identity_operation.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity.operation.get_credentials_for_identity_operation; // ignore_for_file: no_leading_underscores_for_library_prefixes @@ -69,7 +69,7 @@ class GetCredentialsForIdentityOperation extends _i1.HttpOperation< credentialsProvider: _credentialsProvider, isOptional: true, ), - const _i1.WithUserAgent('aws-sdk-dart/0.3.1'), + const _i1.WithUserAgent('aws-sdk-dart/0.3.2'), const _i3.WithSdkInvocationId(), const _i3.WithSdkRequest(), ] + diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/operation/get_id_operation.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/operation/get_id_operation.dart index c7aa76e5c4..5a9ebaa5b3 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/operation/get_id_operation.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity/operation/get_id_operation.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity.operation.get_id_operation; // ignore_for_file: no_leading_underscores_for_library_prefixes @@ -64,7 +64,7 @@ class GetIdOperation extends _i1 credentialsProvider: _credentialsProvider, isOptional: true, ), - const _i1.WithUserAgent('aws-sdk-dart/0.3.1'), + const _i1.WithUserAgent('aws-sdk-dart/0.3.2'), const _i3.WithSdkInvocationId(), const _i3.WithSdkRequest(), ] + diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/cognito_identity_provider_client.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/cognito_identity_provider_client.dart index 5b504d64fd..77dc73bc98 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/cognito_identity_provider_client.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/cognito_identity_provider_client.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.cognito_identity_provider_client; // ignore_for_file: no_leading_underscores_for_library_prefixes @@ -178,7 +178,7 @@ class CognitoIdentityProviderClient { /// Begins setup of time-based one-time password (TOTP) multi-factor authentication (MFA) for a user, with a unique private key that Amazon Cognito generates and returns in the API response. You can authorize an `AssociateSoftwareToken` request with either the user's access token, or a session string from a challenge response that you received from Amazon Cognito. /// - /// Amazon Cognito disassociates an existing software token when you verify the new token in a [VerifySoftwareToken](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_VerifySoftwareToken.html) API request. If you don't verify the software token and your user pool doesn't require MFA, the user can then authenticate with user name and password credentials alone. If your user pool requires TOTP MFA, Amazon Cognito generates an `MFA_SETUP` or `SOFTWARE\_TOKEN\_SETUP` challenge each time your user signs. Complete setup with `AssociateSoftwareToken` and `VerifySoftwareToken`. + /// Amazon Cognito disassociates an existing software token when you verify the new token in a [VerifySoftwareToken](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_VerifySoftwareToken.html) API request. If you don't verify the software token and your user pool doesn't require MFA, the user can then authenticate with user name and password credentials alone. If your user pool requires TOTP MFA, Amazon Cognito generates an `MFA_SETUP` or `SOFTWARE\_TOKEN\_SETUP` challenge each time your user signs in. Complete setup with `AssociateSoftwareToken` and `VerifySoftwareToken`. /// /// After you set up software token MFA for your user, Amazon Cognito generates a `SOFTWARE\_TOKEN\_MFA` challenge when they authenticate. Respond to this challenge with your user's TOTP. /// @@ -340,7 +340,7 @@ class CognitoIdentityProviderClient { /// /// This action might generate an SMS text message. Starting June 1, 2021, US telecom carriers require you to register an origination phone number before you can send SMS messages to US phone numbers. If you use SMS text messages in Amazon Cognito, you must register a phone number with [Amazon Pinpoint](https://console.aws.amazon.com/pinpoint/home/). Amazon Cognito uses the registered number automatically. Otherwise, Amazon Cognito users who must receive SMS messages might not be able to sign up, activate their accounts, or sign in. /// - /// If you have never used SMS text messages with Amazon Cognito or any other Amazon Web Service, Amazon Simple Notification Service might place your account in the SMS sandbox. In _[sandbox mode](https://docs.aws.amazon.com/sns/latest/dg/sns-sms-sandbox.html)_ , you can send messages only to verified phone numbers. After you test your app while in the sandbox environment, you can move out of the sandbox and into production. For more information, see [SMS message settings for Amazon Cognito user pools](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-sms-settings.html) in the _Amazon Cognito Developer Guide_. + /// If you have never used SMS text messages with Amazon Cognito or any other Amazon Web Servicesservice, Amazon Simple Notification Service might place your account in the SMS sandbox. In _[sandbox mode](https://docs.aws.amazon.com/sns/latest/dg/sns-sms-sandbox.html)_ , you can send messages only to verified phone numbers. After you test your app while in the sandbox environment, you can move out of the sandbox and into production. For more information, see [SMS message settings for Amazon Cognito user pools](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-sms-settings.html) in the _Amazon Cognito Developer Guide_. _i3.SmithyOperation forgotPassword( ForgotPasswordRequest input, { _i1.AWSHttpClient? client, @@ -410,7 +410,7 @@ class CognitoIdentityProviderClient { /// /// This action might generate an SMS text message. Starting June 1, 2021, US telecom carriers require you to register an origination phone number before you can send SMS messages to US phone numbers. If you use SMS text messages in Amazon Cognito, you must register a phone number with [Amazon Pinpoint](https://console.aws.amazon.com/pinpoint/home/). Amazon Cognito uses the registered number automatically. Otherwise, Amazon Cognito users who must receive SMS messages might not be able to sign up, activate their accounts, or sign in. /// - /// If you have never used SMS text messages with Amazon Cognito or any other Amazon Web Service, Amazon Simple Notification Service might place your account in the SMS sandbox. In _[sandbox mode](https://docs.aws.amazon.com/sns/latest/dg/sns-sms-sandbox.html)_ , you can send messages only to verified phone numbers. After you test your app while in the sandbox environment, you can move out of the sandbox and into production. For more information, see [SMS message settings for Amazon Cognito user pools](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-sms-settings.html) in the _Amazon Cognito Developer Guide_. + /// If you have never used SMS text messages with Amazon Cognito or any other Amazon Web Servicesservice, Amazon Simple Notification Service might place your account in the SMS sandbox. In _[sandbox mode](https://docs.aws.amazon.com/sns/latest/dg/sns-sms-sandbox.html)_ , you can send messages only to verified phone numbers. After you test your app while in the sandbox environment, you can move out of the sandbox and into production. For more information, see [SMS message settings for Amazon Cognito user pools](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-sms-settings.html) in the _Amazon Cognito Developer Guide_. _i3.SmithyOperation getUserAttributeVerificationCode( GetUserAttributeVerificationCodeRequest input, { @@ -468,7 +468,7 @@ class CognitoIdentityProviderClient { /// /// This action might generate an SMS text message. Starting June 1, 2021, US telecom carriers require you to register an origination phone number before you can send SMS messages to US phone numbers. If you use SMS text messages in Amazon Cognito, you must register a phone number with [Amazon Pinpoint](https://console.aws.amazon.com/pinpoint/home/). Amazon Cognito uses the registered number automatically. Otherwise, Amazon Cognito users who must receive SMS messages might not be able to sign up, activate their accounts, or sign in. /// - /// If you have never used SMS text messages with Amazon Cognito or any other Amazon Web Service, Amazon Simple Notification Service might place your account in the SMS sandbox. In _[sandbox mode](https://docs.aws.amazon.com/sns/latest/dg/sns-sms-sandbox.html)_ , you can send messages only to verified phone numbers. After you test your app while in the sandbox environment, you can move out of the sandbox and into production. For more information, see [SMS message settings for Amazon Cognito user pools](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-sms-settings.html) in the _Amazon Cognito Developer Guide_. + /// If you have never used SMS text messages with Amazon Cognito or any other Amazon Web Servicesservice, Amazon Simple Notification Service might place your account in the SMS sandbox. In _[sandbox mode](https://docs.aws.amazon.com/sns/latest/dg/sns-sms-sandbox.html)_ , you can send messages only to verified phone numbers. After you test your app while in the sandbox environment, you can move out of the sandbox and into production. For more information, see [SMS message settings for Amazon Cognito user pools](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-sms-settings.html) in the _Amazon Cognito Developer Guide_. _i3.SmithyOperation initiateAuth( InitiateAuthRequest input, { _i1.AWSHttpClient? client, @@ -514,7 +514,7 @@ class CognitoIdentityProviderClient { /// /// This action might generate an SMS text message. Starting June 1, 2021, US telecom carriers require you to register an origination phone number before you can send SMS messages to US phone numbers. If you use SMS text messages in Amazon Cognito, you must register a phone number with [Amazon Pinpoint](https://console.aws.amazon.com/pinpoint/home/). Amazon Cognito uses the registered number automatically. Otherwise, Amazon Cognito users who must receive SMS messages might not be able to sign up, activate their accounts, or sign in. /// - /// If you have never used SMS text messages with Amazon Cognito or any other Amazon Web Service, Amazon Simple Notification Service might place your account in the SMS sandbox. In _[sandbox mode](https://docs.aws.amazon.com/sns/latest/dg/sns-sms-sandbox.html)_ , you can send messages only to verified phone numbers. After you test your app while in the sandbox environment, you can move out of the sandbox and into production. For more information, see [SMS message settings for Amazon Cognito user pools](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-sms-settings.html) in the _Amazon Cognito Developer Guide_. + /// If you have never used SMS text messages with Amazon Cognito or any other Amazon Web Servicesservice, Amazon Simple Notification Service might place your account in the SMS sandbox. In _[sandbox mode](https://docs.aws.amazon.com/sns/latest/dg/sns-sms-sandbox.html)_ , you can send messages only to verified phone numbers. After you test your app while in the sandbox environment, you can move out of the sandbox and into production. For more information, see [SMS message settings for Amazon Cognito user pools](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-sms-settings.html) in the _Amazon Cognito Developer Guide_. _i3.SmithyOperation resendConfirmationCode( ResendConfirmationCodeRequest input, { _i1.AWSHttpClient? client, @@ -540,7 +540,7 @@ class CognitoIdentityProviderClient { /// /// This action might generate an SMS text message. Starting June 1, 2021, US telecom carriers require you to register an origination phone number before you can send SMS messages to US phone numbers. If you use SMS text messages in Amazon Cognito, you must register a phone number with [Amazon Pinpoint](https://console.aws.amazon.com/pinpoint/home/). Amazon Cognito uses the registered number automatically. Otherwise, Amazon Cognito users who must receive SMS messages might not be able to sign up, activate their accounts, or sign in. /// - /// If you have never used SMS text messages with Amazon Cognito or any other Amazon Web Service, Amazon Simple Notification Service might place your account in the SMS sandbox. In _[sandbox mode](https://docs.aws.amazon.com/sns/latest/dg/sns-sms-sandbox.html)_ , you can send messages only to verified phone numbers. After you test your app while in the sandbox environment, you can move out of the sandbox and into production. For more information, see [SMS message settings for Amazon Cognito user pools](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-sms-settings.html) in the _Amazon Cognito Developer Guide_. + /// If you have never used SMS text messages with Amazon Cognito or any other Amazon Web Servicesservice, Amazon Simple Notification Service might place your account in the SMS sandbox. In _[sandbox mode](https://docs.aws.amazon.com/sns/latest/dg/sns-sms-sandbox.html)_ , you can send messages only to verified phone numbers. After you test your app while in the sandbox environment, you can move out of the sandbox and into production. For more information, see [SMS message settings for Amazon Cognito user pools](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-sms-settings.html) in the _Amazon Cognito Developer Guide_. _i3.SmithyOperation respondToAuthChallenge( RespondToAuthChallengeRequest input, { _i1.AWSHttpClient? client, @@ -606,7 +606,7 @@ class CognitoIdentityProviderClient { /// /// This action might generate an SMS text message. Starting June 1, 2021, US telecom carriers require you to register an origination phone number before you can send SMS messages to US phone numbers. If you use SMS text messages in Amazon Cognito, you must register a phone number with [Amazon Pinpoint](https://console.aws.amazon.com/pinpoint/home/). Amazon Cognito uses the registered number automatically. Otherwise, Amazon Cognito users who must receive SMS messages might not be able to sign up, activate their accounts, or sign in. /// - /// If you have never used SMS text messages with Amazon Cognito or any other Amazon Web Service, Amazon Simple Notification Service might place your account in the SMS sandbox. In _[sandbox mode](https://docs.aws.amazon.com/sns/latest/dg/sns-sms-sandbox.html)_ , you can send messages only to verified phone numbers. After you test your app while in the sandbox environment, you can move out of the sandbox and into production. For more information, see [SMS message settings for Amazon Cognito user pools](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-sms-settings.html) in the _Amazon Cognito Developer Guide_. + /// If you have never used SMS text messages with Amazon Cognito or any other Amazon Web Servicesservice, Amazon Simple Notification Service might place your account in the SMS sandbox. In _[sandbox mode](https://docs.aws.amazon.com/sns/latest/dg/sns-sms-sandbox.html)_ , you can send messages only to verified phone numbers. After you test your app while in the sandbox environment, you can move out of the sandbox and into production. For more information, see [SMS message settings for Amazon Cognito user pools](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-sms-settings.html) in the _Amazon Cognito Developer Guide_. _i3.SmithyOperation signUp( SignUpRequest input, { _i1.AWSHttpClient? client, @@ -654,7 +654,7 @@ class CognitoIdentityProviderClient { /// /// This action might generate an SMS text message. Starting June 1, 2021, US telecom carriers require you to register an origination phone number before you can send SMS messages to US phone numbers. If you use SMS text messages in Amazon Cognito, you must register a phone number with [Amazon Pinpoint](https://console.aws.amazon.com/pinpoint/home/). Amazon Cognito uses the registered number automatically. Otherwise, Amazon Cognito users who must receive SMS messages might not be able to sign up, activate their accounts, or sign in. /// - /// If you have never used SMS text messages with Amazon Cognito or any other Amazon Web Service, Amazon Simple Notification Service might place your account in the SMS sandbox. In _[sandbox mode](https://docs.aws.amazon.com/sns/latest/dg/sns-sms-sandbox.html)_ , you can send messages only to verified phone numbers. After you test your app while in the sandbox environment, you can move out of the sandbox and into production. For more information, see [SMS message settings for Amazon Cognito user pools](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-sms-settings.html) in the _Amazon Cognito Developer Guide_. + /// If you have never used SMS text messages with Amazon Cognito or any other Amazon Web Servicesservice, Amazon Simple Notification Service might place your account in the SMS sandbox. In _[sandbox mode](https://docs.aws.amazon.com/sns/latest/dg/sns-sms-sandbox.html)_ , you can send messages only to verified phone numbers. After you test your app while in the sandbox environment, you can move out of the sandbox and into production. For more information, see [SMS message settings for Amazon Cognito user pools](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-sms-settings.html) in the _Amazon Cognito Developer Guide_. _i3.SmithyOperation updateUserAttributes( UpdateUserAttributesRequest input, { _i1.AWSHttpClient? client, diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/common/endpoint_resolver.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/common/endpoint_resolver.dart index aa6948f01b..87bbaf7dc7 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/common/endpoint_resolver.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/common/endpoint_resolver.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.common.endpoint_resolver; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/common/serializers.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/common/serializers.dart index 4bd6e82ab8..45d3210bcb 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/common/serializers.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/common/serializers.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.common.serializers; // ignore_for_file: no_leading_underscores_for_library_prefixes @@ -28,6 +28,7 @@ import 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/ import 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/device_remembered_status_type.dart'; import 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/device_secret_verifier_config_type.dart'; import 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/device_type.dart'; +import 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/email_mfa_settings_type.dart'; import 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/enable_software_token_mfa_exception.dart'; import 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/expired_code_exception.dart'; import 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/forbidden_exception.dart'; @@ -59,6 +60,7 @@ import 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/ import 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/mfa_option_type.dart'; import 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/new_device_metadata_type.dart'; import 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/not_authorized_exception.dart'; +import 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/password_history_policy_violation_exception.dart'; import 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/password_reset_required_exception.dart'; import 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/resend_confirmation_code_request.dart'; import 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/resend_confirmation_code_response.dart'; @@ -112,6 +114,7 @@ const List<_i1.SmithySerializer> serializers = [ ...ChangePasswordResponse.serializers, ...InvalidPasswordException.serializers, ...LimitExceededException.serializers, + ...PasswordHistoryPolicyViolationException.serializers, ...PasswordResetRequiredException.serializers, ...TooManyRequestsException.serializers, ...UserNotConfirmedException.serializers, @@ -175,6 +178,7 @@ const List<_i1.SmithySerializer> serializers = [ ...UnsupportedTokenTypeException.serializers, ...SmsMfaSettingsType.serializers, ...SoftwareTokenMfaSettingsType.serializers, + ...EmailMfaSettingsType.serializers, ...SetUserMfaPreferenceRequest.serializers, ...SetUserMfaPreferenceResponse.serializers, ...SignUpRequest.serializers, diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/alias_exists_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/alias_exists_exception.dart index 6fe989ea5a..92daad3986 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/alias_exists_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/alias_exists_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.alias_exists_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/analytics_metadata_type.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/analytics_metadata_type.dart index 0c3b5e5cb1..3ce0fd64f0 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/analytics_metadata_type.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/analytics_metadata_type.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.analytics_metadata_type; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/associate_software_token_request.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/associate_software_token_request.dart index e85c27e777..68a490b537 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/associate_software_token_request.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/associate_software_token_request.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.associate_software_token_request; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/associate_software_token_response.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/associate_software_token_response.dart index 5d95699e30..c65a519903 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/associate_software_token_response.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/associate_software_token_response.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.associate_software_token_response; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/attribute_type.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/attribute_type.dart index c05750b94f..d6e81f84e6 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/attribute_type.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/attribute_type.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.attribute_type; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/auth_flow_type.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/auth_flow_type.dart index b72dedfb0e..63ef0d3e8b 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/auth_flow_type.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/auth_flow_type.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.auth_flow_type; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/authentication_result_type.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/authentication_result_type.dart index e28c05e8f8..fe4c1436b2 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/authentication_result_type.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/authentication_result_type.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.authentication_result_type; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/challenge_name_type.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/challenge_name_type.dart index 16183b5270..245f07151e 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/challenge_name_type.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/challenge_name_type.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.challenge_name_type; // ignore_for_file: no_leading_underscores_for_library_prefixes @@ -38,38 +38,44 @@ class ChallengeNameType extends _i1.SmithyEnum { 'DEVICE_SRP_AUTH', ); - static const mfaSetup = ChallengeNameType._( + static const emailOtp = ChallengeNameType._( 4, + 'EMAIL_OTP', + 'EMAIL_OTP', + ); + + static const mfaSetup = ChallengeNameType._( + 5, 'MFA_SETUP', 'MFA_SETUP', ); static const newPasswordRequired = ChallengeNameType._( - 5, + 6, 'NEW_PASSWORD_REQUIRED', 'NEW_PASSWORD_REQUIRED', ); static const passwordVerifier = ChallengeNameType._( - 6, + 7, 'PASSWORD_VERIFIER', 'PASSWORD_VERIFIER', ); static const selectMfaType = ChallengeNameType._( - 7, + 8, 'SELECT_MFA_TYPE', 'SELECT_MFA_TYPE', ); static const smsMfa = ChallengeNameType._( - 8, + 9, 'SMS_MFA', 'SMS_MFA', ); static const softwareTokenMfa = ChallengeNameType._( - 9, + 10, 'SOFTWARE_TOKEN_MFA', 'SOFTWARE_TOKEN_MFA', ); @@ -80,6 +86,7 @@ class ChallengeNameType extends _i1.SmithyEnum { ChallengeNameType.customChallenge, ChallengeNameType.devicePasswordVerifier, ChallengeNameType.deviceSrpAuth, + ChallengeNameType.emailOtp, ChallengeNameType.mfaSetup, ChallengeNameType.newPasswordRequired, ChallengeNameType.passwordVerifier, diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/change_password_request.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/change_password_request.dart index 1bee4684cf..aca8f246fd 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/change_password_request.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/change_password_request.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.change_password_request; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/change_password_response.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/change_password_response.dart index 6d32ca2ee8..4dfb38ac75 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/change_password_response.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/change_password_response.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.change_password_response; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/code_delivery_details_type.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/code_delivery_details_type.dart index 34f7889f1f..2017a74f76 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/code_delivery_details_type.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/code_delivery_details_type.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.code_delivery_details_type; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/code_delivery_failure_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/code_delivery_failure_exception.dart index ce4d865c5c..f3a73bfb96 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/code_delivery_failure_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/code_delivery_failure_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.code_delivery_failure_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/code_mismatch_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/code_mismatch_exception.dart index 470c29a6b7..40d59d121e 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/code_mismatch_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/code_mismatch_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.code_mismatch_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/concurrent_modification_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/concurrent_modification_exception.dart index af4d648e10..a93d170315 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/concurrent_modification_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/concurrent_modification_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.concurrent_modification_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/confirm_device_request.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/confirm_device_request.dart index c9a359ad63..36ec585c57 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/confirm_device_request.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/confirm_device_request.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.confirm_device_request; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/confirm_device_response.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/confirm_device_response.dart index c4a56e3d20..742d7b7880 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/confirm_device_response.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/confirm_device_response.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.confirm_device_response; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/confirm_forgot_password_request.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/confirm_forgot_password_request.dart index 5ee0b35e9a..7d2eae3eb4 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/confirm_forgot_password_request.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/confirm_forgot_password_request.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.confirm_forgot_password_request; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/confirm_forgot_password_response.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/confirm_forgot_password_response.dart index 428faabe8b..a4bd14e09b 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/confirm_forgot_password_response.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/confirm_forgot_password_response.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.confirm_forgot_password_response; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/confirm_sign_up_request.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/confirm_sign_up_request.dart index 674e4bf602..a3d08239b0 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/confirm_sign_up_request.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/confirm_sign_up_request.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.confirm_sign_up_request; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/confirm_sign_up_response.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/confirm_sign_up_response.dart index eb41e869cb..caba28a5c6 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/confirm_sign_up_response.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/confirm_sign_up_response.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.confirm_sign_up_response; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/delete_user_request.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/delete_user_request.dart index a1945ea8b1..6da56f6fad 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/delete_user_request.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/delete_user_request.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.delete_user_request; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/delivery_medium_type.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/delivery_medium_type.dart index 157cc2712f..f2d8b3b06b 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/delivery_medium_type.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/delivery_medium_type.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.delivery_medium_type; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/device_remembered_status_type.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/device_remembered_status_type.dart index b7ec625425..6ea59d3c6e 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/device_remembered_status_type.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/device_remembered_status_type.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.device_remembered_status_type; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/device_secret_verifier_config_type.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/device_secret_verifier_config_type.dart index 69f90feee7..b001642117 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/device_secret_verifier_config_type.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/device_secret_verifier_config_type.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.device_secret_verifier_config_type; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/device_type.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/device_type.dart index f909f5c4cc..b48c396c5a 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/device_type.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/device_type.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.device_type; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/email_mfa_settings_type.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/email_mfa_settings_type.dart new file mode 100644 index 0000000000..f5871bb77d --- /dev/null +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/email_mfa_settings_type.dart @@ -0,0 +1,147 @@ +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. +// ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas + +library amplify_auth_cognito_dart.cognito_identity_provider.model.email_mfa_settings_type; // ignore_for_file: no_leading_underscores_for_library_prefixes + +import 'package:aws_common/aws_common.dart' as _i1; +import 'package:built_value/built_value.dart'; +import 'package:built_value/serializer.dart'; +import 'package:smithy/smithy.dart' as _i2; + +part 'email_mfa_settings_type.g.dart'; + +/// User preferences for multi-factor authentication with email messages. Activates or deactivates email MFA and sets it as the preferred MFA method when multiple methods are available. To activate this setting, [advanced security features](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pool-settings-advanced-security.html) must be active in your user pool. +abstract class EmailMfaSettingsType + with _i1.AWSEquatable + implements Built { + /// User preferences for multi-factor authentication with email messages. Activates or deactivates email MFA and sets it as the preferred MFA method when multiple methods are available. To activate this setting, [advanced security features](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pool-settings-advanced-security.html) must be active in your user pool. + factory EmailMfaSettingsType({ + bool? enabled, + bool? preferredMfa, + }) { + enabled ??= false; + preferredMfa ??= false; + return _$EmailMfaSettingsType._( + enabled: enabled, + preferredMfa: preferredMfa, + ); + } + + /// User preferences for multi-factor authentication with email messages. Activates or deactivates email MFA and sets it as the preferred MFA method when multiple methods are available. To activate this setting, [advanced security features](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pool-settings-advanced-security.html) must be active in your user pool. + factory EmailMfaSettingsType.build( + [void Function(EmailMfaSettingsTypeBuilder) updates]) = + _$EmailMfaSettingsType; + + const EmailMfaSettingsType._(); + + static const List<_i2.SmithySerializer> serializers = [ + EmailMfaSettingsTypeAwsJson11Serializer() + ]; + + @BuiltValueHook(initializeBuilder: true) + static void _init(EmailMfaSettingsTypeBuilder b) { + b + ..enabled = false + ..preferredMfa = false; + } + + /// Specifies whether email message MFA is active for a user. When the value of this parameter is `Enabled`, the user will be prompted for MFA during all sign-in attempts, unless device tracking is turned on and the device has been trusted. + bool get enabled; + + /// Specifies whether email message MFA is the user's preferred method. + bool get preferredMfa; + @override + List get props => [ + enabled, + preferredMfa, + ]; + + @override + String toString() { + final helper = newBuiltValueToStringHelper('EmailMfaSettingsType') + ..add( + 'enabled', + enabled, + ) + ..add( + 'preferredMfa', + preferredMfa, + ); + return helper.toString(); + } +} + +class EmailMfaSettingsTypeAwsJson11Serializer + extends _i2.StructuredSmithySerializer { + const EmailMfaSettingsTypeAwsJson11Serializer() + : super('EmailMfaSettingsType'); + + @override + Iterable get types => const [ + EmailMfaSettingsType, + _$EmailMfaSettingsType, + ]; + + @override + Iterable<_i2.ShapeId> get supportedProtocols => const [ + _i2.ShapeId( + namespace: 'aws.protocols', + shape: 'awsJson1_1', + ) + ]; + + @override + EmailMfaSettingsType deserialize( + Serializers serializers, + Iterable serialized, { + FullType specifiedType = FullType.unspecified, + }) { + final result = EmailMfaSettingsTypeBuilder(); + final iterator = serialized.iterator; + while (iterator.moveNext()) { + final key = iterator.current as String; + iterator.moveNext(); + final value = iterator.current; + if (value == null) { + continue; + } + switch (key) { + case 'Enabled': + result.enabled = (serializers.deserialize( + value, + specifiedType: const FullType(bool), + ) as bool); + case 'PreferredMfa': + result.preferredMfa = (serializers.deserialize( + value, + specifiedType: const FullType(bool), + ) as bool); + } + } + + return result.build(); + } + + @override + Iterable serialize( + Serializers serializers, + EmailMfaSettingsType object, { + FullType specifiedType = FullType.unspecified, + }) { + final result$ = []; + final EmailMfaSettingsType(:enabled, :preferredMfa) = object; + result$.addAll([ + 'Enabled', + serializers.serialize( + enabled, + specifiedType: const FullType(bool), + ), + 'PreferredMfa', + serializers.serialize( + preferredMfa, + specifiedType: const FullType(bool), + ), + ]); + return result$; + } +} diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/email_mfa_settings_type.g.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/email_mfa_settings_type.g.dart new file mode 100644 index 0000000000..9be203c737 --- /dev/null +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/email_mfa_settings_type.g.dart @@ -0,0 +1,106 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'email_mfa_settings_type.dart'; + +// ************************************************************************** +// BuiltValueGenerator +// ************************************************************************** + +class _$EmailMfaSettingsType extends EmailMfaSettingsType { + @override + final bool enabled; + @override + final bool preferredMfa; + + factory _$EmailMfaSettingsType( + [void Function(EmailMfaSettingsTypeBuilder)? updates]) => + (new EmailMfaSettingsTypeBuilder()..update(updates))._build(); + + _$EmailMfaSettingsType._({required this.enabled, required this.preferredMfa}) + : super._() { + BuiltValueNullFieldError.checkNotNull( + enabled, r'EmailMfaSettingsType', 'enabled'); + BuiltValueNullFieldError.checkNotNull( + preferredMfa, r'EmailMfaSettingsType', 'preferredMfa'); + } + + @override + EmailMfaSettingsType rebuild( + void Function(EmailMfaSettingsTypeBuilder) updates) => + (toBuilder()..update(updates)).build(); + + @override + EmailMfaSettingsTypeBuilder toBuilder() => + new EmailMfaSettingsTypeBuilder()..replace(this); + + @override + bool operator ==(Object other) { + if (identical(other, this)) return true; + return other is EmailMfaSettingsType && + enabled == other.enabled && + preferredMfa == other.preferredMfa; + } + + @override + int get hashCode { + var _$hash = 0; + _$hash = $jc(_$hash, enabled.hashCode); + _$hash = $jc(_$hash, preferredMfa.hashCode); + _$hash = $jf(_$hash); + return _$hash; + } +} + +class EmailMfaSettingsTypeBuilder + implements Builder { + _$EmailMfaSettingsType? _$v; + + bool? _enabled; + bool? get enabled => _$this._enabled; + set enabled(bool? enabled) => _$this._enabled = enabled; + + bool? _preferredMfa; + bool? get preferredMfa => _$this._preferredMfa; + set preferredMfa(bool? preferredMfa) => _$this._preferredMfa = preferredMfa; + + EmailMfaSettingsTypeBuilder() { + EmailMfaSettingsType._init(this); + } + + EmailMfaSettingsTypeBuilder get _$this { + final $v = _$v; + if ($v != null) { + _enabled = $v.enabled; + _preferredMfa = $v.preferredMfa; + _$v = null; + } + return this; + } + + @override + void replace(EmailMfaSettingsType other) { + ArgumentError.checkNotNull(other, 'other'); + _$v = other as _$EmailMfaSettingsType; + } + + @override + void update(void Function(EmailMfaSettingsTypeBuilder)? updates) { + if (updates != null) updates(this); + } + + @override + EmailMfaSettingsType build() => _build(); + + _$EmailMfaSettingsType _build() { + final _$result = _$v ?? + new _$EmailMfaSettingsType._( + enabled: BuiltValueNullFieldError.checkNotNull( + enabled, r'EmailMfaSettingsType', 'enabled'), + preferredMfa: BuiltValueNullFieldError.checkNotNull( + preferredMfa, r'EmailMfaSettingsType', 'preferredMfa')); + replace(_$result); + return _$result; + } +} + +// ignore_for_file: deprecated_member_use_from_same_package,type=lint diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/enable_software_token_mfa_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/enable_software_token_mfa_exception.dart index ebfbade44b..dfbd457723 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/enable_software_token_mfa_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/enable_software_token_mfa_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.enable_software_token_mfa_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/expired_code_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/expired_code_exception.dart index 29f4dc36e5..f6ab049ad0 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/expired_code_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/expired_code_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.expired_code_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/forbidden_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/forbidden_exception.dart index 37ccbc6dcd..b97418f44b 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/forbidden_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/forbidden_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.forbidden_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/forget_device_request.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/forget_device_request.dart index 57fa4dfe45..f716905bf4 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/forget_device_request.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/forget_device_request.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.forget_device_request; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/forgot_password_request.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/forgot_password_request.dart index 206bf31593..de772a3506 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/forgot_password_request.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/forgot_password_request.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.forgot_password_request; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/forgot_password_response.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/forgot_password_response.dart index 92fe7f3db7..2d77bdb4ac 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/forgot_password_response.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/forgot_password_response.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.forgot_password_response; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/get_device_request.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/get_device_request.dart index 6f949ad858..d6068a3e65 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/get_device_request.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/get_device_request.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.get_device_request; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/get_device_response.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/get_device_response.dart index 62edc0d585..33bf747c39 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/get_device_response.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/get_device_response.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.get_device_response; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/get_user_attribute_verification_code_request.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/get_user_attribute_verification_code_request.dart index 183f2e2cb8..bc9f259d32 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/get_user_attribute_verification_code_request.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/get_user_attribute_verification_code_request.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.get_user_attribute_verification_code_request; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/get_user_attribute_verification_code_response.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/get_user_attribute_verification_code_response.dart index ab94635e1a..92e05abeac 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/get_user_attribute_verification_code_response.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/get_user_attribute_verification_code_response.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.get_user_attribute_verification_code_response; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/get_user_request.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/get_user_request.dart index eea378cd8a..61c037aa61 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/get_user_request.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/get_user_request.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.get_user_request; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/get_user_response.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/get_user_response.dart index eb690fbcbf..249a5a3fdf 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/get_user_response.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/get_user_response.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.get_user_response; // ignore_for_file: no_leading_underscores_for_library_prefixes @@ -66,7 +66,7 @@ abstract class GetUserResponse /// The user's preferred MFA setting. String? get preferredMfaSetting; - /// The MFA options that are activated for the user. The possible values in this list are `SMS_MFA` and `SOFTWARE\_TOKEN\_MFA`. + /// The MFA options that are activated for the user. The possible values in this list are `SMS_MFA`, `EMAIL_OTP`, and `SOFTWARE\_TOKEN\_MFA`. _i2.BuiltList? get userMfaSettingList; @override List get props => [ diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/global_sign_out_request.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/global_sign_out_request.dart index 924d17c3d0..a19ee40a56 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/global_sign_out_request.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/global_sign_out_request.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.global_sign_out_request; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/global_sign_out_response.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/global_sign_out_response.dart index 2941bae7c3..0cd0cad3ba 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/global_sign_out_response.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/global_sign_out_response.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.global_sign_out_response; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/initiate_auth_request.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/initiate_auth_request.dart index 299a26378f..d950158c01 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/initiate_auth_request.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/initiate_auth_request.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.initiate_auth_request; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/initiate_auth_response.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/initiate_auth_response.dart index b0d075afe3..b4d2d39b01 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/initiate_auth_response.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/initiate_auth_response.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.initiate_auth_response; // ignore_for_file: no_leading_underscores_for_library_prefixes @@ -58,7 +58,9 @@ abstract class InitiateAuthResponse /// /// All of the following challenges require `USERNAME` and `SECRET_HASH` (if applicable) in the parameters. /// - /// * `SMS_MFA`: Next challenge is to supply an `SMS\_MFA\_CODE`, delivered via SMS. + /// * `SMS_MFA`: Next challenge is to supply an `SMS\_MFA\_CODE`that your user pool delivered in an SMS message. + /// + /// * `EMAIL_OTP`: Next challenge is to supply an `EMAIL\_OTP\_CODE` that your user pool delivered in an email message. /// /// * `PASSWORD_VERIFIER`: Next challenge is to supply `PASSWORD\_CLAIM\_SIGNATURE`, `PASSWORD\_CLAIM\_SECRET_BLOCK`, and `TIMESTAMP` after the client-side SRP calculations. /// diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/internal_error_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/internal_error_exception.dart index deacb16eb0..ba19414e69 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/internal_error_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/internal_error_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.internal_error_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/invalid_email_role_access_policy_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/invalid_email_role_access_policy_exception.dart index f5c51b1a95..9593759c9c 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/invalid_email_role_access_policy_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/invalid_email_role_access_policy_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.invalid_email_role_access_policy_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/invalid_lambda_response_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/invalid_lambda_response_exception.dart index 265347fda5..dcfeb43424 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/invalid_lambda_response_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/invalid_lambda_response_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.invalid_lambda_response_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/invalid_parameter_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/invalid_parameter_exception.dart index ba0823619b..daed39aae1 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/invalid_parameter_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/invalid_parameter_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.invalid_parameter_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/invalid_password_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/invalid_password_exception.dart index 52c7699f17..e4f651a82b 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/invalid_password_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/invalid_password_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.invalid_password_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/invalid_sms_role_access_policy_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/invalid_sms_role_access_policy_exception.dart index 15e2e29d4d..857cce6009 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/invalid_sms_role_access_policy_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/invalid_sms_role_access_policy_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.invalid_sms_role_access_policy_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/invalid_sms_role_trust_relationship_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/invalid_sms_role_trust_relationship_exception.dart index 515fc9d07d..cf52736fff 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/invalid_sms_role_trust_relationship_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/invalid_sms_role_trust_relationship_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.invalid_sms_role_trust_relationship_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/invalid_user_pool_configuration_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/invalid_user_pool_configuration_exception.dart index dbf2b347dc..62d8b0cec2 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/invalid_user_pool_configuration_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/invalid_user_pool_configuration_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.invalid_user_pool_configuration_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/limit_exceeded_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/limit_exceeded_exception.dart index c4ded607b3..fc3900ee8d 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/limit_exceeded_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/limit_exceeded_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.limit_exceeded_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/list_devices_request.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/list_devices_request.dart index 07201dab3d..3b2a6f0834 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/list_devices_request.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/list_devices_request.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.list_devices_request; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/list_devices_response.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/list_devices_response.dart index 50771c2b25..8de544538a 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/list_devices_response.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/list_devices_response.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.list_devices_response; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/mfa_method_not_found_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/mfa_method_not_found_exception.dart index d159df70a6..f223bc69b0 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/mfa_method_not_found_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/mfa_method_not_found_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.mfa_method_not_found_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/mfa_option_type.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/mfa_option_type.dart index c880f267c7..e6d103c6da 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/mfa_option_type.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/mfa_option_type.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.mfa_option_type; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/new_device_metadata_type.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/new_device_metadata_type.dart index 69a24a5ad4..56c8dc4549 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/new_device_metadata_type.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/new_device_metadata_type.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.new_device_metadata_type; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/not_authorized_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/not_authorized_exception.dart index 8b8c71a14f..667a4e4e7e 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/not_authorized_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/not_authorized_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.not_authorized_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/password_history_policy_violation_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/password_history_policy_violation_exception.dart new file mode 100644 index 0000000000..8558e99e29 --- /dev/null +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/password_history_policy_violation_exception.dart @@ -0,0 +1,148 @@ +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. +// ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas + +library amplify_auth_cognito_dart.cognito_identity_provider.model.password_history_policy_violation_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes + +import 'package:aws_common/aws_common.dart' as _i1; +import 'package:built_value/built_value.dart'; +import 'package:built_value/serializer.dart'; +import 'package:smithy/smithy.dart' as _i2; + +part 'password_history_policy_violation_exception.g.dart'; + +/// The message returned when a user's new password matches a previous password and doesn't comply with the password-history policy. +abstract class PasswordHistoryPolicyViolationException + with + _i1.AWSEquatable + implements + Built, + _i2.SmithyHttpException { + /// The message returned when a user's new password matches a previous password and doesn't comply with the password-history policy. + factory PasswordHistoryPolicyViolationException({String? message}) { + return _$PasswordHistoryPolicyViolationException._(message: message); + } + + /// The message returned when a user's new password matches a previous password and doesn't comply with the password-history policy. + factory PasswordHistoryPolicyViolationException.build( + [void Function(PasswordHistoryPolicyViolationExceptionBuilder) + updates]) = _$PasswordHistoryPolicyViolationException; + + const PasswordHistoryPolicyViolationException._(); + + /// Constructs a [PasswordHistoryPolicyViolationException] from a [payload] and [response]. + factory PasswordHistoryPolicyViolationException.fromResponse( + PasswordHistoryPolicyViolationException payload, + _i1.AWSBaseHttpResponse response, + ) => + payload.rebuild((b) { + b.headers = response.headers; + }); + + static const List< + _i2.SmithySerializer> + serializers = [ + PasswordHistoryPolicyViolationExceptionAwsJson11Serializer() + ]; + + @override + String? get message; + @override + _i2.ShapeId get shapeId => const _i2.ShapeId( + namespace: 'com.amazonaws.cognitoidentityprovider', + shape: 'PasswordHistoryPolicyViolationException', + ); + + @override + _i2.RetryConfig? get retryConfig => null; + + @override + @BuiltValueField(compare: false) + int get statusCode => 400; + + @override + @BuiltValueField(compare: false) + Map? get headers; + @override + Exception? get underlyingException => null; + + @override + List get props => [message]; + + @override + String toString() { + final helper = + newBuiltValueToStringHelper('PasswordHistoryPolicyViolationException') + ..add( + 'message', + message, + ); + return helper.toString(); + } +} + +class PasswordHistoryPolicyViolationExceptionAwsJson11Serializer extends _i2 + .StructuredSmithySerializer { + const PasswordHistoryPolicyViolationExceptionAwsJson11Serializer() + : super('PasswordHistoryPolicyViolationException'); + + @override + Iterable get types => const [ + PasswordHistoryPolicyViolationException, + _$PasswordHistoryPolicyViolationException, + ]; + + @override + Iterable<_i2.ShapeId> get supportedProtocols => const [ + _i2.ShapeId( + namespace: 'aws.protocols', + shape: 'awsJson1_1', + ) + ]; + + @override + PasswordHistoryPolicyViolationException deserialize( + Serializers serializers, + Iterable serialized, { + FullType specifiedType = FullType.unspecified, + }) { + final result = PasswordHistoryPolicyViolationExceptionBuilder(); + final iterator = serialized.iterator; + while (iterator.moveNext()) { + final key = iterator.current as String; + iterator.moveNext(); + final value = iterator.current; + if (value == null) { + continue; + } + switch (key) { + case 'message': + result.message = (serializers.deserialize( + value, + specifiedType: const FullType(String), + ) as String); + } + } + + return result.build(); + } + + @override + Iterable serialize( + Serializers serializers, + PasswordHistoryPolicyViolationException object, { + FullType specifiedType = FullType.unspecified, + }) { + final result$ = []; + final PasswordHistoryPolicyViolationException(:message) = object; + if (message != null) { + result$ + ..add('message') + ..add(serializers.serialize( + message, + specifiedType: const FullType(String), + )); + } + return result$; + } +} diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/password_history_policy_violation_exception.g.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/password_history_policy_violation_exception.g.dart new file mode 100644 index 0000000000..14462c7c57 --- /dev/null +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/password_history_policy_violation_exception.g.dart @@ -0,0 +1,101 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'password_history_policy_violation_exception.dart'; + +// ************************************************************************** +// BuiltValueGenerator +// ************************************************************************** + +class _$PasswordHistoryPolicyViolationException + extends PasswordHistoryPolicyViolationException { + @override + final String? message; + @override + final Map? headers; + + factory _$PasswordHistoryPolicyViolationException( + [void Function(PasswordHistoryPolicyViolationExceptionBuilder)? + updates]) => + (new PasswordHistoryPolicyViolationExceptionBuilder()..update(updates)) + ._build(); + + _$PasswordHistoryPolicyViolationException._({this.message, this.headers}) + : super._(); + + @override + PasswordHistoryPolicyViolationException rebuild( + void Function(PasswordHistoryPolicyViolationExceptionBuilder) + updates) => + (toBuilder()..update(updates)).build(); + + @override + PasswordHistoryPolicyViolationExceptionBuilder toBuilder() => + new PasswordHistoryPolicyViolationExceptionBuilder()..replace(this); + + @override + bool operator ==(Object other) { + if (identical(other, this)) return true; + return other is PasswordHistoryPolicyViolationException && + message == other.message; + } + + @override + int get hashCode { + var _$hash = 0; + _$hash = $jc(_$hash, message.hashCode); + _$hash = $jf(_$hash); + return _$hash; + } +} + +class PasswordHistoryPolicyViolationExceptionBuilder + implements + Builder { + _$PasswordHistoryPolicyViolationException? _$v; + + String? _message; + String? get message => _$this._message; + set message(String? message) => _$this._message = message; + + Map? _headers; + Map? get headers => _$this._headers; + set headers(Map? headers) => _$this._headers = headers; + + PasswordHistoryPolicyViolationExceptionBuilder(); + + PasswordHistoryPolicyViolationExceptionBuilder get _$this { + final $v = _$v; + if ($v != null) { + _message = $v.message; + _headers = $v.headers; + _$v = null; + } + return this; + } + + @override + void replace(PasswordHistoryPolicyViolationException other) { + ArgumentError.checkNotNull(other, 'other'); + _$v = other as _$PasswordHistoryPolicyViolationException; + } + + @override + void update( + void Function(PasswordHistoryPolicyViolationExceptionBuilder)? updates) { + if (updates != null) updates(this); + } + + @override + PasswordHistoryPolicyViolationException build() => _build(); + + _$PasswordHistoryPolicyViolationException _build() { + final _$result = _$v ?? + new _$PasswordHistoryPolicyViolationException._( + message: message, headers: headers); + replace(_$result); + return _$result; + } +} + +// ignore_for_file: deprecated_member_use_from_same_package,type=lint diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/password_reset_required_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/password_reset_required_exception.dart index 3d93fd22a1..0e4500dc25 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/password_reset_required_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/password_reset_required_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.password_reset_required_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/resend_confirmation_code_request.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/resend_confirmation_code_request.dart index 4cf8678d2d..94ad518a90 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/resend_confirmation_code_request.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/resend_confirmation_code_request.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.resend_confirmation_code_request; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/resend_confirmation_code_response.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/resend_confirmation_code_response.dart index 808df308e4..6a214d00dc 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/resend_confirmation_code_response.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/resend_confirmation_code_response.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.resend_confirmation_code_response; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/resource_not_found_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/resource_not_found_exception.dart index d54f471e9e..925645afe5 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/resource_not_found_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/resource_not_found_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.resource_not_found_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/respond_to_auth_challenge_request.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/respond_to_auth_challenge_request.dart index 6d45689bc9..06ac52c376 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/respond_to_auth_challenge_request.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/respond_to_auth_challenge_request.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.respond_to_auth_challenge_request; // ignore_for_file: no_leading_underscores_for_library_prefixes @@ -79,10 +79,16 @@ abstract class RespondToAuthChallengeRequest /// /// SMS_MFA /// - /// `"ChallengeName": "SMS\_MFA", "ChallengeResponses": {"SMS\_MFA\_CODE": "\[SMS\_code\]", "USERNAME": "\[username\]"}` + /// `"ChallengeName": "SMS\_MFA", "ChallengeResponses": {"SMS\_MFA_CODE": "\[code\]", "USERNAME": "\[username\]"}` + /// + /// EMAIL_OTP + /// + /// `"ChallengeName": "EMAIL\_OTP", "ChallengeResponses": {"EMAIL\_OTP_CODE": "\[code\]", "USERNAME": "\[username\]"}` /// /// PASSWORD_VERIFIER /// + /// This challenge response is part of the SRP flow. Amazon Cognito requires that your application respond to this challenge within a few seconds. When the response time exceeds this period, your user pool returns a `NotAuthorizedException` error. + /// /// `"ChallengeName": "PASSWORD\_VERIFIER", "ChallengeResponses": {"PASSWORD\_CLAIM\_SIGNATURE": "\[claim\_signature\]", "PASSWORD\_CLAIM\_SECRET\_BLOCK": "\[secret\_block\]", "TIMESTAMP": \[timestamp\], "USERNAME": "\[username\]"}` /// /// Add `"DEVICE_KEY"` when you sign in with a remembered device. diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/respond_to_auth_challenge_response.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/respond_to_auth_challenge_response.dart index d2cef93d19..8ea2f06cec 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/respond_to_auth_challenge_response.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/respond_to_auth_challenge_response.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.respond_to_auth_challenge_response; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/revoke_token_request.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/revoke_token_request.dart index 7a46034d7d..423af9fabe 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/revoke_token_request.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/revoke_token_request.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.revoke_token_request; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/revoke_token_response.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/revoke_token_response.dart index 566e257c2a..d9e99039d3 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/revoke_token_response.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/revoke_token_response.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.revoke_token_response; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/set_user_mfa_preference_request.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/set_user_mfa_preference_request.dart index 6a541e339c..04bb1ad29b 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/set_user_mfa_preference_request.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/set_user_mfa_preference_request.dart @@ -1,8 +1,9 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.set_user_mfa_preference_request; // ignore_for_file: no_leading_underscores_for_library_prefixes +import 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/email_mfa_settings_type.dart'; import 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/sms_mfa_settings_type.dart'; import 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/software_token_mfa_settings_type.dart'; import 'package:aws_common/aws_common.dart' as _i2; @@ -21,11 +22,13 @@ abstract class SetUserMfaPreferenceRequest factory SetUserMfaPreferenceRequest({ SmsMfaSettingsType? smsMfaSettings, SoftwareTokenMfaSettingsType? softwareTokenMfaSettings, + EmailMfaSettingsType? emailMfaSettings, required String accessToken, }) { return _$SetUserMfaPreferenceRequest._( smsMfaSettings: smsMfaSettings, softwareTokenMfaSettings: softwareTokenMfaSettings, + emailMfaSettings: emailMfaSettings, accessToken: accessToken, ); } @@ -46,12 +49,15 @@ abstract class SetUserMfaPreferenceRequest static const List<_i1.SmithySerializer> serializers = [SetUserMfaPreferenceRequestAwsJson11Serializer()]; - /// The SMS text message multi-factor authentication (MFA) settings. + /// User preferences for SMS message MFA. Activates or deactivates SMS MFA and sets it as the preferred MFA method when multiple methods are available. SmsMfaSettingsType? get smsMfaSettings; - /// The time-based one-time password (TOTP) software token MFA settings. + /// User preferences for time-based one-time password (TOTP) MFA. Activates or deactivates TOTP MFA and sets it as the preferred MFA method when multiple methods are available. SoftwareTokenMfaSettingsType? get softwareTokenMfaSettings; + /// User preferences for email message MFA. Activates or deactivates email MFA and sets it as the preferred MFA method when multiple methods are available. To activate this setting, [advanced security features](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pool-settings-advanced-security.html) must be active in your user pool. + EmailMfaSettingsType? get emailMfaSettings; + /// A valid access token that Amazon Cognito issued to the user whose MFA preference you want to set. String get accessToken; @override @@ -61,6 +67,7 @@ abstract class SetUserMfaPreferenceRequest List get props => [ smsMfaSettings, softwareTokenMfaSettings, + emailMfaSettings, accessToken, ]; @@ -75,6 +82,10 @@ abstract class SetUserMfaPreferenceRequest 'softwareTokenMfaSettings', softwareTokenMfaSettings, ) + ..add( + 'emailMfaSettings', + emailMfaSettings, + ) ..add( 'accessToken', '***SENSITIVE***', @@ -128,6 +139,11 @@ class SetUserMfaPreferenceRequestAwsJson11Serializer value, specifiedType: const FullType(SoftwareTokenMfaSettingsType), ) as SoftwareTokenMfaSettingsType)); + case 'EmailMfaSettings': + result.emailMfaSettings.replace((serializers.deserialize( + value, + specifiedType: const FullType(EmailMfaSettingsType), + ) as EmailMfaSettingsType)); case 'AccessToken': result.accessToken = (serializers.deserialize( value, @@ -149,6 +165,7 @@ class SetUserMfaPreferenceRequestAwsJson11Serializer final SetUserMfaPreferenceRequest( :smsMfaSettings, :softwareTokenMfaSettings, + :emailMfaSettings, :accessToken ) = object; result$.addAll([ @@ -174,6 +191,14 @@ class SetUserMfaPreferenceRequestAwsJson11Serializer specifiedType: const FullType(SoftwareTokenMfaSettingsType), )); } + if (emailMfaSettings != null) { + result$ + ..add('EmailMfaSettings') + ..add(serializers.serialize( + emailMfaSettings, + specifiedType: const FullType(EmailMfaSettingsType), + )); + } return result$; } } diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/set_user_mfa_preference_request.g.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/set_user_mfa_preference_request.g.dart index ca68a57587..fec5ce2c1e 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/set_user_mfa_preference_request.g.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/set_user_mfa_preference_request.g.dart @@ -12,6 +12,8 @@ class _$SetUserMfaPreferenceRequest extends SetUserMfaPreferenceRequest { @override final SoftwareTokenMfaSettingsType? softwareTokenMfaSettings; @override + final EmailMfaSettingsType? emailMfaSettings; + @override final String accessToken; factory _$SetUserMfaPreferenceRequest( @@ -21,6 +23,7 @@ class _$SetUserMfaPreferenceRequest extends SetUserMfaPreferenceRequest { _$SetUserMfaPreferenceRequest._( {this.smsMfaSettings, this.softwareTokenMfaSettings, + this.emailMfaSettings, required this.accessToken}) : super._() { BuiltValueNullFieldError.checkNotNull( @@ -42,6 +45,7 @@ class _$SetUserMfaPreferenceRequest extends SetUserMfaPreferenceRequest { return other is SetUserMfaPreferenceRequest && smsMfaSettings == other.smsMfaSettings && softwareTokenMfaSettings == other.softwareTokenMfaSettings && + emailMfaSettings == other.emailMfaSettings && accessToken == other.accessToken; } @@ -50,6 +54,7 @@ class _$SetUserMfaPreferenceRequest extends SetUserMfaPreferenceRequest { var _$hash = 0; _$hash = $jc(_$hash, smsMfaSettings.hashCode); _$hash = $jc(_$hash, softwareTokenMfaSettings.hashCode); + _$hash = $jc(_$hash, emailMfaSettings.hashCode); _$hash = $jc(_$hash, accessToken.hashCode); _$hash = $jf(_$hash); return _$hash; @@ -76,6 +81,12 @@ class SetUserMfaPreferenceRequestBuilder SoftwareTokenMfaSettingsTypeBuilder? softwareTokenMfaSettings) => _$this._softwareTokenMfaSettings = softwareTokenMfaSettings; + EmailMfaSettingsTypeBuilder? _emailMfaSettings; + EmailMfaSettingsTypeBuilder get emailMfaSettings => + _$this._emailMfaSettings ??= new EmailMfaSettingsTypeBuilder(); + set emailMfaSettings(EmailMfaSettingsTypeBuilder? emailMfaSettings) => + _$this._emailMfaSettings = emailMfaSettings; + String? _accessToken; String? get accessToken => _$this._accessToken; set accessToken(String? accessToken) => _$this._accessToken = accessToken; @@ -87,6 +98,7 @@ class SetUserMfaPreferenceRequestBuilder if ($v != null) { _smsMfaSettings = $v.smsMfaSettings?.toBuilder(); _softwareTokenMfaSettings = $v.softwareTokenMfaSettings?.toBuilder(); + _emailMfaSettings = $v.emailMfaSettings?.toBuilder(); _accessToken = $v.accessToken; _$v = null; } @@ -114,6 +126,7 @@ class SetUserMfaPreferenceRequestBuilder new _$SetUserMfaPreferenceRequest._( smsMfaSettings: _smsMfaSettings?.build(), softwareTokenMfaSettings: _softwareTokenMfaSettings?.build(), + emailMfaSettings: _emailMfaSettings?.build(), accessToken: BuiltValueNullFieldError.checkNotNull( accessToken, r'SetUserMfaPreferenceRequest', 'accessToken')); } catch (_) { @@ -123,6 +136,8 @@ class SetUserMfaPreferenceRequestBuilder _smsMfaSettings?.build(); _$failedField = 'softwareTokenMfaSettings'; _softwareTokenMfaSettings?.build(); + _$failedField = 'emailMfaSettings'; + _emailMfaSettings?.build(); } catch (e) { throw new BuiltValueNestedFieldError( r'SetUserMfaPreferenceRequest', _$failedField, e.toString()); diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/set_user_mfa_preference_response.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/set_user_mfa_preference_response.dart index 371c315986..bfb06d87f1 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/set_user_mfa_preference_response.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/set_user_mfa_preference_response.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.set_user_mfa_preference_response; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/sign_up_request.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/sign_up_request.dart index c3363048cb..8709755f15 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/sign_up_request.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/sign_up_request.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.sign_up_request; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/sign_up_response.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/sign_up_response.dart index c20050a0b7..5c5dc0cf4c 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/sign_up_response.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/sign_up_response.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.sign_up_response; // ignore_for_file: no_leading_underscores_for_library_prefixes @@ -57,7 +57,7 @@ abstract class SignUpResponse /// The code delivery details returned by the server response to the user registration request. CodeDeliveryDetailsType? get codeDeliveryDetails; - /// The UUID of the authenticated user. This isn't the same as `username`. + /// The 128-bit ID of the authenticated user. This isn't the same as `username`. String get userSub; @override List get props => [ diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/sms_mfa_settings_type.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/sms_mfa_settings_type.dart index 5fbcc78d0a..c69f645d76 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/sms_mfa_settings_type.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/sms_mfa_settings_type.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.sms_mfa_settings_type; // ignore_for_file: no_leading_underscores_for_library_prefixes @@ -45,7 +45,7 @@ abstract class SmsMfaSettingsType ..preferredMfa = false; } - /// Specifies whether SMS text message MFA is activated. If an MFA type is activated for a user, the user will be prompted for MFA during all sign-in attempts, unless device tracking is turned on and the device has been trusted. + /// Specifies whether SMS message MFA is activated. If an MFA type is activated for a user, the user will be prompted for MFA during all sign-in attempts, unless device tracking is turned on and the device has been trusted. bool get enabled; /// Specifies whether SMS is the preferred MFA method. diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/software_token_mfa_not_found_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/software_token_mfa_not_found_exception.dart index b886706039..b3e013dc50 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/software_token_mfa_not_found_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/software_token_mfa_not_found_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.software_token_mfa_not_found_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/software_token_mfa_settings_type.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/software_token_mfa_settings_type.dart index 25cfafd5a3..1aee62a4d4 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/software_token_mfa_settings_type.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/software_token_mfa_settings_type.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.software_token_mfa_settings_type; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/too_many_failed_attempts_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/too_many_failed_attempts_exception.dart index c487f39ff6..df9e4d77e4 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/too_many_failed_attempts_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/too_many_failed_attempts_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.too_many_failed_attempts_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/too_many_requests_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/too_many_requests_exception.dart index b1cb3aaa5f..dcf1d32175 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/too_many_requests_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/too_many_requests_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.too_many_requests_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/unauthorized_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/unauthorized_exception.dart index 50ecabe32d..e5c09b5106 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/unauthorized_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/unauthorized_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.unauthorized_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/unexpected_lambda_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/unexpected_lambda_exception.dart index 34a02e236b..474492765a 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/unexpected_lambda_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/unexpected_lambda_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.unexpected_lambda_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/unsupported_operation_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/unsupported_operation_exception.dart index c31068e2ae..0e4b511b26 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/unsupported_operation_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/unsupported_operation_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.unsupported_operation_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/unsupported_token_type_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/unsupported_token_type_exception.dart index 2979954ab5..acff97bd7d 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/unsupported_token_type_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/unsupported_token_type_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.unsupported_token_type_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/update_device_status_request.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/update_device_status_request.dart index 1935e80768..3c50ce8453 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/update_device_status_request.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/update_device_status_request.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.update_device_status_request; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/update_device_status_response.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/update_device_status_response.dart index 970c2e9b97..81f5daaa34 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/update_device_status_response.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/update_device_status_response.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.update_device_status_response; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/update_user_attributes_request.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/update_user_attributes_request.dart index 49238c60f8..50c621fa40 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/update_user_attributes_request.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/update_user_attributes_request.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.update_user_attributes_request; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/update_user_attributes_response.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/update_user_attributes_response.dart index a8dbfabd2c..65a464efff 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/update_user_attributes_response.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/update_user_attributes_response.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.update_user_attributes_response; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/user_context_data_type.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/user_context_data_type.dart index 5f214b4004..f98d85cfd4 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/user_context_data_type.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/user_context_data_type.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.user_context_data_type; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/user_lambda_validation_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/user_lambda_validation_exception.dart index 225e45dbca..19a37c5299 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/user_lambda_validation_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/user_lambda_validation_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.user_lambda_validation_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/user_not_confirmed_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/user_not_confirmed_exception.dart index a75f0605f2..1ba1c2d2e8 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/user_not_confirmed_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/user_not_confirmed_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.user_not_confirmed_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/user_not_found_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/user_not_found_exception.dart index 9d0d33889c..060958dac4 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/user_not_found_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/user_not_found_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.user_not_found_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/username_exists_exception.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/username_exists_exception.dart index 0d1ad7b19b..6a5e063454 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/username_exists_exception.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/username_exists_exception.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.username_exists_exception; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/verify_software_token_request.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/verify_software_token_request.dart index 78199373a4..b880b6ff91 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/verify_software_token_request.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/verify_software_token_request.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.verify_software_token_request; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/verify_software_token_response.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/verify_software_token_response.dart index 706fc241fe..5084e7f717 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/verify_software_token_response.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/verify_software_token_response.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.verify_software_token_response; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/verify_software_token_response_type.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/verify_software_token_response_type.dart index 4fa5346f09..5de62aad58 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/verify_software_token_response_type.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/verify_software_token_response_type.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.verify_software_token_response_type; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/verify_user_attribute_request.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/verify_user_attribute_request.dart index 7603269bcb..0ab9eb603b 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/verify_user_attribute_request.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/verify_user_attribute_request.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.verify_user_attribute_request; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/verify_user_attribute_response.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/verify_user_attribute_response.dart index 79883fe9ed..2bd2b4cd53 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/verify_user_attribute_response.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/model/verify_user_attribute_response.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.model.verify_user_attribute_response; // ignore_for_file: no_leading_underscores_for_library_prefixes diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/operation/associate_software_token_operation.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/operation/associate_software_token_operation.dart index 8a63714d88..a59df7d709 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/operation/associate_software_token_operation.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/operation/associate_software_token_operation.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.operation.associate_software_token_operation; // ignore_for_file: no_leading_underscores_for_library_prefixes @@ -23,7 +23,7 @@ import 'package:smithy_aws/smithy_aws.dart' as _i3; /// Begins setup of time-based one-time password (TOTP) multi-factor authentication (MFA) for a user, with a unique private key that Amazon Cognito generates and returns in the API response. You can authorize an `AssociateSoftwareToken` request with either the user's access token, or a session string from a challenge response that you received from Amazon Cognito. /// -/// Amazon Cognito disassociates an existing software token when you verify the new token in a [VerifySoftwareToken](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_VerifySoftwareToken.html) API request. If you don't verify the software token and your user pool doesn't require MFA, the user can then authenticate with user name and password credentials alone. If your user pool requires TOTP MFA, Amazon Cognito generates an `MFA_SETUP` or `SOFTWARE\_TOKEN\_SETUP` challenge each time your user signs. Complete setup with `AssociateSoftwareToken` and `VerifySoftwareToken`. +/// Amazon Cognito disassociates an existing software token when you verify the new token in a [VerifySoftwareToken](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_VerifySoftwareToken.html) API request. If you don't verify the software token and your user pool doesn't require MFA, the user can then authenticate with user name and password credentials alone. If your user pool requires TOTP MFA, Amazon Cognito generates an `MFA_SETUP` or `SOFTWARE\_TOKEN\_SETUP` challenge each time your user signs in. Complete setup with `AssociateSoftwareToken` and `VerifySoftwareToken`. /// /// After you set up software token MFA for your user, Amazon Cognito generates a `SOFTWARE\_TOKEN\_MFA` challenge when they authenticate. Respond to this challenge with your user's TOTP. /// @@ -35,7 +35,7 @@ class AssociateSoftwareTokenOperation extends _i1.HttpOperation< AssociateSoftwareTokenResponse> { /// Begins setup of time-based one-time password (TOTP) multi-factor authentication (MFA) for a user, with a unique private key that Amazon Cognito generates and returns in the API response. You can authorize an `AssociateSoftwareToken` request with either the user's access token, or a session string from a challenge response that you received from Amazon Cognito. /// - /// Amazon Cognito disassociates an existing software token when you verify the new token in a [VerifySoftwareToken](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_VerifySoftwareToken.html) API request. If you don't verify the software token and your user pool doesn't require MFA, the user can then authenticate with user name and password credentials alone. If your user pool requires TOTP MFA, Amazon Cognito generates an `MFA_SETUP` or `SOFTWARE\_TOKEN\_SETUP` challenge each time your user signs. Complete setup with `AssociateSoftwareToken` and `VerifySoftwareToken`. + /// Amazon Cognito disassociates an existing software token when you verify the new token in a [VerifySoftwareToken](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_VerifySoftwareToken.html) API request. If you don't verify the software token and your user pool doesn't require MFA, the user can then authenticate with user name and password credentials alone. If your user pool requires TOTP MFA, Amazon Cognito generates an `MFA_SETUP` or `SOFTWARE\_TOKEN\_SETUP` challenge each time your user signs in. Complete setup with `AssociateSoftwareToken` and `VerifySoftwareToken`. /// /// After you set up software token MFA for your user, Amazon Cognito generates a `SOFTWARE\_TOKEN\_MFA` challenge when they authenticate. Respond to this challenge with your user's TOTP. /// @@ -76,7 +76,7 @@ class AssociateSoftwareTokenOperation extends _i1.HttpOperation< credentialsProvider: _credentialsProvider, isOptional: true, ), - const _i1.WithUserAgent('aws-sdk-dart/0.3.1'), + const _i1.WithUserAgent('aws-sdk-dart/0.3.2'), const _i3.WithSdkInvocationId(), const _i3.WithSdkRequest(), ] + diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/operation/change_password_operation.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/operation/change_password_operation.dart index 81918f776a..7b6f0b0a20 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/operation/change_password_operation.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/operation/change_password_operation.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.operation.change_password_operation; // ignore_for_file: no_leading_underscores_for_library_prefixes @@ -15,6 +15,7 @@ import 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/ import 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/invalid_password_exception.dart'; import 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/limit_exceeded_exception.dart'; import 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/not_authorized_exception.dart'; +import 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/password_history_policy_violation_exception.dart'; import 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/password_reset_required_exception.dart'; import 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/resource_not_found_exception.dart'; import 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/too_many_requests_exception.dart'; @@ -70,7 +71,7 @@ class ChangePasswordOperation extends _i1.HttpOperation( + _i1.ShapeId( + namespace: 'com.amazonaws.cognitoidentityprovider', + shape: 'PasswordHistoryPolicyViolationException', + ), + _i1.ErrorKind.client, + PasswordHistoryPolicyViolationException, + statusCode: 400, + builder: PasswordHistoryPolicyViolationException.fromResponse, + ), _i1.SmithyError( _i1.ShapeId( diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/operation/confirm_device_operation.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/operation/confirm_device_operation.dart index 27c5bc8073..5e6c9a0969 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/operation/confirm_device_operation.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/operation/confirm_device_operation.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.operation.confirm_device_operation; // ignore_for_file: no_leading_underscores_for_library_prefixes @@ -72,7 +72,7 @@ class ConfirmDeviceOperation extends _i1.HttpOperation( + _i1.ShapeId( + namespace: 'com.amazonaws.cognitoidentityprovider', + shape: 'PasswordHistoryPolicyViolationException', + ), + _i1.ErrorKind.client, + PasswordHistoryPolicyViolationException, + statusCode: 400, + builder: PasswordHistoryPolicyViolationException.fromResponse, + ), _i1.SmithyError( _i1.ShapeId( namespace: 'com.amazonaws.cognitoidentityprovider', diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/operation/confirm_sign_up_operation.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/operation/confirm_sign_up_operation.dart index 9d62149fbf..dd03525a4f 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/operation/confirm_sign_up_operation.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/operation/confirm_sign_up_operation.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.operation.confirm_sign_up_operation; // ignore_for_file: no_leading_underscores_for_library_prefixes @@ -74,7 +74,7 @@ class ConfirmSignUpOperation extends _i1.HttpOperation { /// Calling this API causes a message to be sent to the end user with a confirmation code that is required to change the user's password. For the `Username` parameter, you can use the username or user alias. The method used to send the confirmation code is sent according to the specified AccountRecoverySetting. For more information, see [Recovering User Accounts](https://docs.aws.amazon.com/cognito/latest/developerguide/how-to-recover-a-user-account.html) in the _Amazon Cognito Developer Guide_. To use the confirmation code for resetting the password, call [ConfirmForgotPassword](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_ConfirmForgotPassword.html). @@ -52,7 +52,7 @@ class ForgotPasswordOperation extends _i1.HttpOperation { /// Initiates sign-in for a user in the Amazon Cognito user directory. You can't sign in a user with a federated IdP with `InitiateAuth`. For more information, see [Adding user pool sign-in through a third party](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-identity-federation.html). @@ -44,7 +45,7 @@ class InitiateAuthOperation extends _i1.HttpOperation( + _i1.ShapeId( + namespace: 'com.amazonaws.cognitoidentityprovider', + shape: 'InvalidEmailRoleAccessPolicyException', + ), + _i1.ErrorKind.client, + InvalidEmailRoleAccessPolicyException, + statusCode: 400, + builder: InvalidEmailRoleAccessPolicyException.fromResponse, + ), _i1.SmithyError( _i1.ShapeId( diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/operation/list_devices_operation.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/operation/list_devices_operation.dart index 3c17fd4b17..e9087a8151 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/operation/list_devices_operation.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/operation/list_devices_operation.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.operation.list_devices_operation; // ignore_for_file: no_leading_underscores_for_library_prefixes @@ -69,7 +69,7 @@ class ListDevicesOperation extends _i1.HttpOperation( + _i1.ShapeId( + namespace: 'com.amazonaws.cognitoidentityprovider', + shape: 'InvalidEmailRoleAccessPolicyException', + ), + _i1.ErrorKind.client, + InvalidEmailRoleAccessPolicyException, + statusCode: 400, + builder: InvalidEmailRoleAccessPolicyException.fromResponse, + ), _i1.SmithyError( _i1.ShapeId( @@ -274,6 +287,17 @@ class RespondToAuthChallengeOperation extends _i1.HttpOperation< statusCode: 403, builder: NotAuthorizedException.fromResponse, ), + _i1.SmithyError( + _i1.ShapeId( + namespace: 'com.amazonaws.cognitoidentityprovider', + shape: 'PasswordHistoryPolicyViolationException', + ), + _i1.ErrorKind.client, + PasswordHistoryPolicyViolationException, + statusCode: 400, + builder: PasswordHistoryPolicyViolationException.fromResponse, + ), _i1.SmithyError( _i1.ShapeId( diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/operation/revoke_token_operation.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/operation/revoke_token_operation.dart index 7ae9abe992..e7878fd5f7 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/operation/revoke_token_operation.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/sdk/src/cognito_identity_provider/operation/revoke_token_operation.dart @@ -1,4 +1,4 @@ -// Generated with smithy-dart 0.3.1. DO NOT MODIFY. +// Generated with smithy-dart 0.3.2. DO NOT MODIFY. // ignore_for_file: avoid_unused_constructor_parameters,deprecated_member_use_from_same_package,non_constant_identifier_names,require_trailing_commas library amplify_auth_cognito_dart.cognito_identity_provider.operation.revoke_token_operation; // ignore_for_file: no_leading_underscores_for_library_prefixes @@ -62,7 +62,7 @@ class RevokeTokenOperation extends _i1.HttpOperation { /// Registers the user in the specified user pool and creates a user name, password, and user attributes. @@ -45,7 +45,7 @@ class SignUpOperation extends _i1.HttpOperation switch (type) { 'SOFTWARE_TOKEN_MFA' => MfaType.totp, 'SMS_MFA' => MfaType.sms, + 'EMAIL_OTP' => MfaType.email, _ => () { logger.error('Unrecognized MFA type: $type'); return null; @@ -325,10 +326,12 @@ final class SignInStateMachine createSmsMfaRequest(event), ChallengeNameType.softwareTokenMfa when hasUserResponse => createSoftwareTokenMfaRequest(event), + ChallengeNameType.emailOtp when hasUserResponse => + createEmailOtpRequest(event), ChallengeNameType.selectMfaType when hasUserResponse => createSelectMfaRequest(event), ChallengeNameType.mfaSetup when hasUserResponse => - createMfaSetupRequest(event), + handleMfaSetup(event: event), ChallengeNameType.newPasswordRequired when hasUserResponse => createNewPasswordRequest(event), _ => null, @@ -449,6 +452,24 @@ final class SignInStateMachine }); } + /// Creates the response object for an Email MFA challenge. + @protected + Future createEmailOtpRequest( + SignInRespondToChallenge event, + ) async { + _enableMfaType = MfaType.email; + return RespondToAuthChallengeRequest.build((b) { + b + ..clientId = _authOutputs.userPoolClientId + ..challengeName = _challengeName + ..challengeResponses.addAll({ + CognitoConstants.challengeParamUsername: cognitoUsername, + CognitoConstants.challengeParamEmailOtpCode: event.answer, + }) + ..clientMetadata.addAll(event.clientMetadata); + }); + } + /// Creates the response object for a new password challenge. @protected Future createNewPasswordRequest( @@ -630,9 +651,64 @@ final class SignInStateMachine } } + /// Handles the MFA setup challenge. + @protected + Future handleMfaSetup({ + SignInEvent? event, + }) async { + final allowedMfaTypes = _allowedMfaTypes; + // Exclude MfaType.sms from consideration + final mfaTypesForSetup = allowedMfaTypes?.difference({MfaType.sms}); + if (mfaTypesForSetup == null || mfaTypesForSetup.isEmpty) { + throw const InvalidUserPoolConfigurationException( + 'No eligible MFA types are allowed for setup.', + recoverySuggestion: 'Check your user pool MFA configuration.', + ); + } + + if (event == null) { + throw StateError('Event cannot be null when there is user response.'); + } + if (event is! SignInRespondToChallenge) { + throw StateError('Expected SignInRespondToChallenge event.'); + } + + if (_enableMfaType == null && _totpSetupResult == null) { + // User has just selected the MFA type + final selection = event.answer.toLowerCase(); + _enableMfaType = switch (selection) { + 'totp' => MfaType.totp, + 'email' => MfaType.email, + _ => throw const InvalidParameterException('Invalid MFA type selected'), + }; + + final challengeResponses = { + CognitoConstants.challengeParamMfasCanSetup: + _enableMfaType == MfaType.totp + ? '["SOFTWARE_TOKEN_MFA"]' + : '["EMAIL_OTP"]', + }; + _challengeParameters = BuiltMap(challengeResponses); + await _processChallenge(); + return null; + } + + // totp mfa method was already selected + if (mfaTypesForSetup.length == 1 && + mfaTypesForSetup.contains(MfaType.totp) && + _totpSetupResult != null) { + await createSoftwareTokenMfaRequest(event); + } + + // User has provided the verification code + return _enableMfaType == MfaType.totp + ? createTotpMfaSetupRequest(event) + : createEmailMfaSetupRequest(event); + } + /// Completes set up of a TOTP MFA. @protected - Future createMfaSetupRequest( + Future createTotpMfaSetupRequest( SignInRespondToChallenge event, ) async { await verifySoftwareToken( @@ -653,6 +729,24 @@ final class SignInStateMachine }); } + /// Compeletes set up of an email MFA. + @protected + Future createEmailMfaSetupRequest( + SignInRespondToChallenge event, + ) async { + _enableMfaType = MfaType.email; + return RespondToAuthChallengeRequest.build((b) { + b + ..challengeName = ChallengeNameType.mfaSetup + ..challengeResponses.addAll({ + CognitoConstants.challengeParamUsername: cognitoUsername, + CognitoConstants.challengeParamEmail: event.answer, + }) + ..clientId = _authOutputs.userPoolClientId + ..clientMetadata.addAll(event.clientMetadata); + }); + } + /// Selects an MFA type to use for sign-in. @protected Future createSelectMfaRequest( @@ -667,7 +761,8 @@ final class SignInStateMachine CognitoConstants.challengeParamAnswer: switch (selection) { 'sms' => 'SMS_MFA', 'totp' => 'SOFTWARE_TOKEN_MFA', - _ => throw ArgumentError('Must be either SMS or TOTP'), + 'email' => 'EMAIL_OTP', + _ => throw ArgumentError('Must be either SMS, Email, or TOTP'), }, }) ..clientId = _authOutputs.userPoolClientId @@ -934,6 +1029,8 @@ final class SignInStateMachine accessToken: accessToken, sms: enableMfaType == MfaType.sms ? MfaPreference.enabled : null, totp: enableMfaType == MfaType.totp ? MfaPreference.enabled : null, + email: + enableMfaType == MfaType.email ? MfaPreference.enabled : null, ); } on Exception catch (e, st) { logger.error( @@ -956,14 +1053,20 @@ final class SignInStateMachine if (_allowedMfaTypes case final allowedMfaTypes? when _challengeParameters .containsKey(CognitoConstants.challengeParamMfasCanSetup)) { - if (!allowedMfaTypes.contains(MfaType.totp)) { + if (!allowedMfaTypes.contains(MfaType.totp) && + !allowedMfaTypes.contains(MfaType.email)) { throw const InvalidUserPoolConfigurationException( - 'Cannot enable SMS MFA and TOTP MFA is not allowed', + 'Cannot enable SMS MFA and TOTP or EMAIL MFA is not allowed', recoverySuggestion: - 'Contact an administrator to enable SMS MFA or allow TOTP MFA', + 'Contact an administrator to enable SMS MFA or allow TOTP or EMAIL MFA', ); } - _totpSetupResult ??= await associateSoftwareToken(); + final allowedMfaSetupTypes = [...?_allowedMfaTypes]..remove(MfaType.sms); + if (allowedMfaSetupTypes.length == 1 && + allowedMfaSetupTypes.first == MfaType.totp && + _totpSetupResult == null) { + _totpSetupResult = await associateSoftwareToken(accessToken: _session); + } } // Query the state machine for a response given potential user input in diff --git a/packages/authenticator/amplify_authenticator/example/integration_test/main_test.dart b/packages/authenticator/amplify_authenticator/example/integration_test/main_test.dart index fa1cbc1f8a..2fd7c73508 100644 --- a/packages/authenticator/amplify_authenticator/example/integration_test/main_test.dart +++ b/packages/authenticator/amplify_authenticator/example/integration_test/main_test.dart @@ -13,9 +13,14 @@ import 'http_test.dart' as http_tests; import 'reset_password_test.dart' as reset_password_tests; import 'sign_in_force_new_password_test.dart' as sign_in_force_new_password_tests; +import 'sign_in_mfa_email_test.dart' as sign_in_mfa_email_tests; +import 'sign_in_mfa_email_totp_test.dart' as sign_in_mfa_email_totp_tests; +import 'sign_in_mfa_sms_email_test.dart' as sign_in_mfa_sms_email_tests; import 'sign_in_mfa_sms_test.dart' as sign_in_mfa_sms_tests; import 'sign_in_mfa_sms_totp_test.dart' as sign_in_mfa_sms_totp_tests; import 'sign_in_mfa_totp_test.dart' as sign_in_mfa_totp_tests; +import 'sign_in_mfa_username_login_test.dart' + as sign_in_mfa_username_login_tests; import 'sign_in_with_email_test.dart' as sign_in_with_email_tests; import 'sign_in_with_phone_test.dart' as sign_in_with_phone_tests; import 'sign_in_with_username_test.dart' as sign_in_with_username_tests; @@ -45,6 +50,10 @@ void main() { sign_in_with_email_tests.main(); sign_in_with_phone_tests.main(); sign_in_with_username_tests.main(); + sign_in_mfa_email_tests.main(); + sign_in_mfa_email_totp_tests.main(); + sign_in_mfa_sms_email_tests.main(); + sign_in_mfa_username_login_tests.main(); sign_out_tests.main(); sign_up_with_email_tests.main(); sign_up_with_email_with_lambda_trigger_tests.main(); diff --git a/packages/authenticator/amplify_authenticator/example/integration_test/sign_in_mfa_email_test.dart b/packages/authenticator/amplify_authenticator/example/integration_test/sign_in_mfa_email_test.dart new file mode 100644 index 0000000000..f7c6986312 --- /dev/null +++ b/packages/authenticator/amplify_authenticator/example/integration_test/sign_in_mfa_email_test.dart @@ -0,0 +1,165 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import 'package:amplify_auth_integration_test/amplify_auth_integration_test.dart'; +import 'package:amplify_authenticator_test/amplify_authenticator_test.dart'; +import 'package:amplify_flutter/amplify_flutter.dart'; +import 'package:amplify_integration_test/amplify_integration_test.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'test_runner.dart'; +import 'utils/test_utils.dart'; + +void main() { + testRunner.setupTests(); + + group('sign-in-email-mfa', () { + testRunner.withEnvironment(mfaRequiredEmail, (env) { + // Scenario: Sign in using a valid email MFA code + testWidgets('Sign in with valid EMAIL MFA code', (tester) async { + final username = env.generateUsername(); + final password = generatePassword(); + + await adminCreateUser( + username, + password, + autoConfirm: true, + attributes: { + AuthUserAttributeKey.email: username, + }, + autoFillAttributes: false, + ); + + await loadAuthenticator(tester: tester); + + expect( + tester.bloc.stream, + emitsInOrder([ + UnauthenticatedState.signIn, + UnauthenticatedState.confirmSignInWithOtpCode, + isA(), + UnauthenticatedState.signIn, + UnauthenticatedState.confirmSignInWithOtpCode, + isA(), + emitsDone, + ]), + ); + + final signInPage = SignInPage(tester: tester); + final confirmSignInPage = ConfirmSignInPage(tester: tester); + + final otpResult = await getOtpCode( + env.getLoginAttribute(username), + ); + + // When I type my "username" + await signInPage.enterUsername(username); + + // And I type my password + await signInPage.enterPassword(password); + + // And I click the "Sign in" button + await signInPage.submitSignIn(); + + // Then I will be redirected to the email MFA code page + await confirmSignInPage.expectConfirmSignInWithOtpCodeIsPresent(); + + // And I type a valid EMAIL OTP code + await confirmSignInPage.enterVerificationCode(await otpResult.code); + + // And I click the "Confirm" button + await confirmSignInPage.submitConfirmSignIn(); + + // Then I see the authenticated app + await signInPage.expectAuthenticated(); + + // When I sign out using Auth.signOut() + await Amplify.Auth.signOut(); + await tester.pumpAndSettle(); + + final otpResult2 = await getOtpCode( + env.getLoginAttribute(username), + ); + + // Then I see the sign in page + signInPage.expectUsername(label: 'Email'); + + // When I type my "username" + await signInPage.enterUsername(username); + + // And I type my password + await signInPage.enterPassword(password); + + // And I click the "Sign in" button + await signInPage.submitSignIn(); + + // Then I will be redirected to the EMAIL OTP code page + await confirmSignInPage.expectConfirmSignInWithOtpCodeIsPresent(); + + // When I type a valid EMAIL OTP code + await confirmSignInPage.enterVerificationCode(await otpResult2.code); + + // And I click the "Confirm" button + await confirmSignInPage.submitConfirmSignIn(); + + // Then I see the authenticated app + await signInPage.expectAuthenticated(); + + await tester.bloc.close(); + }); + + // Scenario: Sign in using an invalid email MFA code + testWidgets('Sign in with invalid EMAIL MFA code', (tester) async { + final username = env.generateUsername(); + final password = generatePassword(); + + await adminCreateUser( + username, + password, + autoConfirm: true, + attributes: { + AuthUserAttributeKey.email: username, + }, + autoFillAttributes: false, + ); + + await loadAuthenticator(tester: tester); + + expect( + tester.bloc.stream, + emitsInOrder([ + UnauthenticatedState.signIn, + UnauthenticatedState.confirmSignInWithOtpCode, + emitsDone, + ]), + ); + + final signInPage = SignInPage(tester: tester); + final confirmSignInPage = ConfirmSignInPage(tester: tester); + + // When I type my "username" + await signInPage.enterUsername(username); + + // And I type my password + await signInPage.enterPassword(password); + + // And I click the "Sign in" button + await signInPage.submitSignIn(); + + // Then I will be redirected to the EMAIL OTP code page + await confirmSignInPage.expectConfirmSignInWithOtpCodeIsPresent(); + + // And I type an invalid confirmation code + await confirmSignInPage.enterVerificationCode('123456'); + + // And I click the "Confirm" button + await confirmSignInPage.submitConfirmSignIn(); + + // Then I see "The code entered is not correct." + confirmSignInPage.expectInvalidVerificationCode(); + + await tester.bloc.close(); + }); + }); + }); +} diff --git a/packages/authenticator/amplify_authenticator/example/integration_test/sign_in_mfa_email_totp_test.dart b/packages/authenticator/amplify_authenticator/example/integration_test/sign_in_mfa_email_totp_test.dart new file mode 100644 index 0000000000..fcee99259c --- /dev/null +++ b/packages/authenticator/amplify_authenticator/example/integration_test/sign_in_mfa_email_totp_test.dart @@ -0,0 +1,223 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import 'package:amplify_auth_integration_test/amplify_auth_integration_test.dart'; +import 'package:amplify_authenticator_test/amplify_authenticator_test.dart'; +import 'package:amplify_flutter/amplify_flutter.dart'; +import 'package:amplify_integration_test/amplify_integration_test.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'test_runner.dart'; +import 'utils/test_utils.dart'; + +void main() { + testRunner.setupTests(); + + group('sign-in-email-totp-mfa', () { + testRunner.withEnvironment(mfaRequiredEmailTotp, (env) { + // Scenario: Sign in using a totp code when both EMAIL and TOTP are enabled + testWidgets('can select TOTP MFA', (tester) async { + final username = env.generateUsername(); + final password = generatePassword(); + + await adminCreateUser( + username, + password, + autoConfirm: true, + verifyAttributes: false, + attributes: { + AuthUserAttributeKey.email: username, + }, + ); + + await loadAuthenticator(tester: tester); + + expect( + tester.bloc.stream, + emitsInOrder([ + UnauthenticatedState.signIn, + UnauthenticatedState.confirmSignInWithOtpCode, + isA(), + UnauthenticatedState.signIn, + isA(), + UnauthenticatedState.confirmSignInWithTotpMfaCode, + isA(), + emitsDone, + ]), + ); + + final signInPage = SignInPage(tester: tester); + final confirmSignInPage = ConfirmSignInPage(tester: tester); + + final otpResult = await getOtpCode(UserAttribute.email(username)); + + // When I type my "username" + await signInPage.enterUsername(username); + + // And I type my password + await signInPage.enterPassword(password); + + // And I click the "Sign in" button + await signInPage.submitSignIn(); + + // Then I will be redirected to the confirm email mfa page + await confirmSignInPage.expectConfirmSignInWithOtpCodeIsPresent(); + + // When I type a valid confirmation code + await confirmSignInPage.enterVerificationCode(await otpResult.code); + + // And I click the "Confirm" button + await confirmSignInPage.submitConfirmSignIn(); + + // Then I see the authenticated app + await signInPage.expectAuthenticated(); + + // When I enable TOTP for MFA instead of the default set up by cognito (EMAIL) + await setUpTotp(); + + // And I sign out using Auth.signOut() + await Amplify.Auth.signOut(); + await tester.pumpAndSettle(); + + // Then I see the sign in page + signInPage.expectEmail(); + + // When I type my "username" + await signInPage.enterUsername(username); + + // And I type my password + await signInPage.enterPassword(password); + + // And I click the "Sign in" button + await signInPage.submitSignIn(); + + // Then I will be redirected to the MFA selection page + await confirmSignInPage.expectConfirmSignInMfaSelectionIsPresent(); + + // When I select "TOTP" + await confirmSignInPage.selectMfaMethod(mfaMethod: MfaType.totp); + + // And I click the "Confirm" button + await confirmSignInPage.submitConfirmSignInMfaSelection(); + + // Then I will be redirected to the TOTP MFA code page + await confirmSignInPage.expectConfirmSignInWithTotpMfaCodeIsPresent(); + + final code_2 = await generateTotpCode(); + + // When I type a valid TOTP code + await confirmSignInPage.enterVerificationCode(code_2); + + // And I click the "Confirm" button + await confirmSignInPage.submitConfirmSignIn(); + + // Then I see the authenticated app + await signInPage.expectAuthenticated(); + + await tester.bloc.close(); + }); + + // Scenario: Sign in using a EMAIL code when both EMAIL and TOTP are enabled + testWidgets('can select EMAIL MFA', (tester) async { + final username = env.generateUsername(); + final password = generatePassword(); + + await adminCreateUser( + username, + password, + autoConfirm: true, + verifyAttributes: false, + attributes: { + AuthUserAttributeKey.email: username, + }, + ); + + await loadAuthenticator(tester: tester); + + expect( + tester.bloc.stream, + emitsInOrder([ + UnauthenticatedState.signIn, + UnauthenticatedState.confirmSignInWithOtpCode, + isA(), + UnauthenticatedState.signIn, + isA(), + UnauthenticatedState.confirmSignInWithOtpCode, + isA(), + emitsDone, + ]), + ); + + final signInPage = SignInPage(tester: tester); + final confirmSignInPage = ConfirmSignInPage(tester: tester); + + final otpResult = await getOtpCode(UserAttribute.email(username)); + + // When I type my "username" + await signInPage.enterUsername(username); + + // And I type my password + await signInPage.enterPassword(password); + + // And I click the "Sign in" button + await signInPage.submitSignIn(); + + // Then I will be redirected to the confirm email mfa page + await confirmSignInPage.expectConfirmSignInWithOtpCodeIsPresent(); + + // When I type a valid confirmation code + await confirmSignInPage.enterVerificationCode(await otpResult.code); + + // And I click the "Confirm" button + await confirmSignInPage.submitConfirmSignIn(); + + // Then I see the authenticated app + await signInPage.expectAuthenticated(); + + // When I enable TOTP for MFA instead of the default set up by cognito (EMAIL) + await setUpTotp(); + + // And I sign out using Auth.signOut() + await Amplify.Auth.signOut(); + await tester.pumpAndSettle(); + + // Then I see the sign in page + signInPage.expectEmail(); + + // When I type my "username" + await signInPage.enterUsername(username); + + // And I type my password + await signInPage.enterPassword(password); + + // And I click the "Sign in" button + await signInPage.submitSignIn(); + + // Then I will be redirected to the MFA selection page + await confirmSignInPage.expectConfirmSignInMfaSelectionIsPresent(); + + final otpResult2 = await getOtpCode(UserAttribute.email(username)); + + // When I select "EMAIL" + await confirmSignInPage.selectMfaMethod(mfaMethod: MfaType.email); + + // And I click the "Confirm" button + await confirmSignInPage.submitConfirmSignInMfaSelection(); + + // Then I will be redirected to the confirm EMAIL mfa page + await confirmSignInPage.expectConfirmSignInWithOtpCodeIsPresent(); + + // When I type a valid confirmation code + await confirmSignInPage.enterVerificationCode(await otpResult2.code); + + // And I click the "Confirm" button + await confirmSignInPage.submitConfirmSignIn(); + + // Then I see the authenticated app + await signInPage.expectAuthenticated(); + + await tester.bloc.close(); + }); + }); + }); +} diff --git a/packages/authenticator/amplify_authenticator/example/integration_test/sign_in_mfa_sms_email_test.dart b/packages/authenticator/amplify_authenticator/example/integration_test/sign_in_mfa_sms_email_test.dart new file mode 100644 index 0000000000..c01460f6d5 --- /dev/null +++ b/packages/authenticator/amplify_authenticator/example/integration_test/sign_in_mfa_sms_email_test.dart @@ -0,0 +1,218 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import 'package:amplify_auth_cognito/amplify_auth_cognito.dart'; +import 'package:amplify_auth_integration_test/amplify_auth_integration_test.dart'; +import 'package:amplify_authenticator_test/amplify_authenticator_test.dart'; +import 'package:amplify_flutter/amplify_flutter.dart'; +import 'package:amplify_integration_test/amplify_integration_test.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'test_runner.dart'; +import 'utils/test_utils.dart'; + +void main() { + testRunner.setupTests(); + + group('sign-in-sms-totp-mfa', () { + testRunner.withEnvironment(mfaRequiredEmailSms, (env) { + // Scenario: Sign in using a totp code when both SMS and EMAIL are enabled + // Note: When email and sms are both enabled, + // one of them must be selected as preferred. + // This is different from other mfa methods and + // is expected behavior from cognito + testWidgets('can select EMAIL MFA', (tester) async { + final username = env.generateUsername(); + final password = generatePassword(); + final phoneNumber = generateUSPhoneNumber(); + + await adminCreateUser( + username, + password, + autoConfirm: true, + verifyAttributes: false, + attributes: { + AuthUserAttributeKey.phoneNumber: phoneNumber.toE164(), + AuthUserAttributeKey.email: username, + }, + ); + + await loadAuthenticator(tester: tester); + + expect( + tester.bloc.stream, + emitsInOrder([ + UnauthenticatedState.signIn, + UnauthenticatedState.confirmSignInMfa, + isA(), + UnauthenticatedState.signIn, + UnauthenticatedState.confirmSignInWithOtpCode, + isA(), + emitsDone, + ]), + ); + + final signInPage = SignInPage(tester: tester); + final confirmSignInPage = ConfirmSignInPage(tester: tester); + + final smsResult = + await getOtpCode(UserAttribute.phone(phoneNumber.toE164())); + + // When I type my "username" + await signInPage.enterUsername(username); + + // And I type my password + await signInPage.enterPassword(password); + + // And I click the "Sign in" button + await signInPage.submitSignIn(); + + // Then I will be redirected to the confirm sms mfa page + await confirmSignInPage.expectConfirmSignInMFAIsPresent(); + + // When I type a valid confirmation code + await confirmSignInPage.enterVerificationCode(await smsResult.code); + + // And I click the "Confirm" button + await confirmSignInPage.submitConfirmSignIn(); + + // Then I see the authenticated app + await signInPage.expectAuthenticated(); + + // When I enable EMAIL for MFA instead of the default set up by cognito (SMS) + await setUpEmailMfa(); + + // And I sign out using Auth.signOut() + await Amplify.Auth.signOut(); + await tester.pumpAndSettle(); + + final code_2 = await getOtpCode(env.getLoginAttribute(username)); + + // Then I see the sign in page + signInPage.expectEmail(); + + // When I type my "username" + await signInPage.enterUsername(username); + + // And I type my password + await signInPage.enterPassword(password); + + // And I click the "Sign in" button + await signInPage.submitSignIn(); + + // Then I will be redirected to the EMAIL MFA code page + await confirmSignInPage.expectConfirmSignInWithOtpCodeIsPresent(); + + // When I type a valid EMAIL MFA code + await confirmSignInPage.enterVerificationCode(await code_2.code); + + // And I click the "Confirm" button + await confirmSignInPage.submitConfirmSignIn(); + + // Then I see the authenticated app + await signInPage.expectAuthenticated(); + + await tester.bloc.close(); + }); + + // Scenario: Sign in using a SMS code when both SMS and TOTP are enabled + testWidgets('can select SMS MFA', (tester) async { + final username = env.generateUsername(); + final password = generatePassword(); + final phoneNumber = generateUSPhoneNumber(); + + await adminCreateUser( + username, + password, + autoConfirm: true, + verifyAttributes: false, + attributes: { + AuthUserAttributeKey.phoneNumber: phoneNumber.toE164(), + AuthUserAttributeKey.email: username, + }, + ); + + await loadAuthenticator(tester: tester); + + expect( + tester.bloc.stream, + emitsInOrder([ + UnauthenticatedState.signIn, + UnauthenticatedState.confirmSignInMfa, + isA(), + UnauthenticatedState.signIn, + UnauthenticatedState.confirmSignInMfa, + isA(), + emitsDone, + ]), + ); + + final signInPage = SignInPage(tester: tester); + final confirmSignInPage = ConfirmSignInPage(tester: tester); + + final smsResult_1 = + await getOtpCode(UserAttribute.phone(phoneNumber.toE164())); + + // When I type my "username" + await signInPage.enterUsername(username); + + // And I type my password + await signInPage.enterPassword(password); + + // And I click the "Sign in" button + await signInPage.submitSignIn(); + + // Then I will be redirected to the confirm sms mfa page + await confirmSignInPage.expectConfirmSignInMFAIsPresent(); + + // When I type a valid confirmation code + await confirmSignInPage.enterVerificationCode(await smsResult_1.code); + + // And I click the "Confirm" button + await confirmSignInPage.submitConfirmSignIn(); + + // Then I see the authenticated app + await signInPage.expectAuthenticated(); + + // When I enable EMAIL for MFA instead of the default set up by cognito (SMS) + await setUpEmailMfa(); + + final plugin = Amplify.Auth.getPlugin(AmplifyAuthCognito.pluginKey); + await plugin.updateMfaPreference(sms: MfaPreference.preferred); + + // And I sign out using Auth.signOut() + await Amplify.Auth.signOut(); + await tester.pumpAndSettle(); + + final smsResult_2 = + await getOtpCode(UserAttribute.phone(phoneNumber.toE164())); + + // Then I see the sign in page + signInPage.expectEmail(); + + // When I type my "username" + await signInPage.enterUsername(username); + + // And I type my password + await signInPage.enterPassword(password); + + // And I click the "Sign in" button + await signInPage.submitSignIn(); + + // Then I will be redirected to the confirm sms mfa page + await confirmSignInPage.expectConfirmSignInMFAIsPresent(); + + // When I type a valid confirmation code + await confirmSignInPage.enterVerificationCode(await smsResult_2.code); + + // And I click the "Confirm" button + await confirmSignInPage.submitConfirmSignIn(); + + // Then I see the authenticated app + await signInPage.expectAuthenticated(); + + await tester.bloc.close(); + }); + }); + }); +} diff --git a/packages/authenticator/amplify_authenticator/example/integration_test/sign_in_mfa_username_login_test.dart b/packages/authenticator/amplify_authenticator/example/integration_test/sign_in_mfa_username_login_test.dart new file mode 100644 index 0000000000..823fa1ee51 --- /dev/null +++ b/packages/authenticator/amplify_authenticator/example/integration_test/sign_in_mfa_username_login_test.dart @@ -0,0 +1,260 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import 'package:amplify_auth_integration_test/amplify_auth_integration_test.dart'; +import 'package:amplify_authenticator_test/amplify_authenticator_test.dart'; +import 'package:amplify_flutter/amplify_flutter.dart'; +import 'package:amplify_integration_test/amplify_integration_test.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'test_runner.dart'; +import 'utils/test_utils.dart'; + +void main() { + testRunner.setupTests(); + + group('sign-in-email-totp-mfa', () { + testRunner.withEnvironment(mfaRequiredUsernameLogin, (env) { + // Scenario: Select EMAIL MFA to set up from the setup selection page + testWidgets('can select EMAIL MFA to set up', (tester) async { + final username = env.generateUsername(); + final password = generatePassword(); + final email = generateEmail(); + + await adminCreateUser( + username, + password, + autoConfirm: true, + verifyAttributes: false, + autoFillAttributes: false, + ); + + await loadAuthenticator(tester: tester); + + expect( + tester.bloc.stream, + emitsInOrder([ + UnauthenticatedState.signIn, + isA(), + UnauthenticatedState.continueSignInWithEmailMfaSetup, + UnauthenticatedState.confirmSignInWithOtpCode, + isA(), + emitsDone, + ]), + ); + + final signInPage = SignInPage(tester: tester); + final confirmSignInPage = ConfirmSignInPage(tester: tester); + final emailMfaSetupPage = EmailMfaSetupPage(tester: tester); + + final otpResult = await getOtpCode(UserAttribute.email(email)); + + // When I type my "username" + await signInPage.enterUsername(username); + + // And I type my password + await signInPage.enterPassword(password); + + // And I click the "Sign in" button + await signInPage.submitSignIn(); + + // Then I will be redirected to the MFA setup selection page + await confirmSignInPage + .expectContinueSignInWithMfaSetupSelectionIsPresent(); + + // When I select "EMAIL" + await confirmSignInPage.selectMfaSetupMethod(mfaMethod: MfaType.email); + + // And I click the "Confirm" button + await confirmSignInPage.submitConfirmSignInMfaSetupSelection(); + + // Then I will be redirected to the EMAIL MFA setup page + await emailMfaSetupPage.expectEmailMfaSetupIsPresent(); + + // When I type a valid email + await emailMfaSetupPage.enterEmail(email); + + // And I click the "Confirm" button + await emailMfaSetupPage.submitEmail(); + + // When I type a valid confirmation code + await confirmSignInPage.enterVerificationCode(await otpResult.code); + + // And I click the "Confirm" button + await confirmSignInPage.submitConfirmSignIn(); + + // Then I see the authenticated app + await signInPage.expectAuthenticated(); + + await tester.bloc.close(); + }); + + // Scenario: Select TOTP MFA to set up from the setup selection page + testWidgets('can select TOTP MFA to set up', (tester) async { + final username = env.generateUsername(); + final password = generatePassword(); + late String sharedSecret; + + await adminCreateUser( + username, + password, + autoConfirm: true, + verifyAttributes: false, + autoFillAttributes: false, + ); + + await loadAuthenticator(tester: tester); + + tester.bloc.stream.listen((event) { + if (event is ContinueSignInTotpSetup) { + sharedSecret = event.totpSetupDetails.sharedSecret; + } + }); + + expect( + tester.bloc.stream, + emitsInOrder([ + UnauthenticatedState.signIn, + isA(), + isA(), + isA(), + emitsDone, + ]), + ); + + final signInPage = SignInPage(tester: tester); + final confirmSignInPage = ConfirmSignInPage(tester: tester); + + // When I type my "username" + await signInPage.enterUsername(username); + + // And I type my password + await signInPage.enterPassword(password); + + // And I click the "Sign in" button + await signInPage.submitSignIn(); + + // Then I will be redirected to the MFA setup selection page + await confirmSignInPage + .expectContinueSignInWithMfaSetupSelectionIsPresent(); + + // When I select "TOTP" + await confirmSignInPage.selectMfaSetupMethod(mfaMethod: MfaType.totp); + + // And I click the "Confirm" button + await confirmSignInPage.submitConfirmSignInMfaSetupSelection(); + + // Then I will be redirected to the TOTP MFA setup page + await confirmSignInPage.expectSignInTotpSetupIsPresent(); + + final totpCode = await generateTotpCode(sharedSecret); + + // When I type a valid TOTP code + await confirmSignInPage.enterVerificationCode(totpCode); + + // And I click the "Confirm" button + await confirmSignInPage.submitConfirmSignIn(); + + // Then I see the authenticated app + await signInPage.expectAuthenticated(); + + await tester.bloc.close(); + }); + + // Scenario: Sign in using an invalid TOTP code + testWidgets('sign in with invalid TOTP code', (tester) async { + final username = env.generateUsername(); + final password = generatePassword(); + late String sharedSecret; + + await adminCreateUser( + username, + password, + autoConfirm: true, + verifyAttributes: false, + autoFillAttributes: false, + ); + + await loadAuthenticator(tester: tester); + + tester.bloc.stream.listen((event) { + if (event is ContinueSignInTotpSetup) { + sharedSecret = event.totpSetupDetails.sharedSecret; + } + }); + + expect( + tester.bloc.stream, + emitsInOrder([ + UnauthenticatedState.signIn, + isA(), + isA(), + isA(), + UnauthenticatedState.signIn, + UnauthenticatedState.confirmSignInWithTotpMfaCode, + emitsDone, + ]), + ); + + final signInPage = SignInPage(tester: tester); + final confirmSignInPage = ConfirmSignInPage(tester: tester); + + // When I type my "username" + await signInPage.enterUsername(username); + + // And I type my password + await signInPage.enterPassword(password); + + // And I click the "Sign in" button + await signInPage.submitSignIn(); + + // Then I will be redirected to the MFA setup selection page + await confirmSignInPage + .expectContinueSignInWithMfaSetupSelectionIsPresent(); + + // When I select "TOTP" + await confirmSignInPage.selectMfaSetupMethod(mfaMethod: MfaType.totp); + + // And I click the "Confirm" button + await confirmSignInPage.submitConfirmSignInMfaSetupSelection(); + + // Then I will be redirected to the TOTP MFA setup page + await confirmSignInPage.expectSignInTotpSetupIsPresent(); + + final totpCode = await generateTotpCode(sharedSecret); + + // When I type a valid TOTP code + await confirmSignInPage.enterVerificationCode(totpCode); + + // And I click the "Confirm" button + await confirmSignInPage.submitConfirmSignIn(); + + // Then I see the authenticated app + await signInPage.expectAuthenticated(); + + // Sign out to test invalid TOTP code during sign-in + await Amplify.Auth.signOut(); + await tester.pumpAndSettle(); + + // When I attempt to sign in again + await signInPage.enterUsername(username); + await signInPage.enterPassword(password); + await signInPage.submitSignIn(); + + // Then I will be redirected to the TOTP MFA code page + await confirmSignInPage.expectConfirmSignInWithTotpMfaCodeIsPresent(); + + // When I type an invalid TOTP code + await confirmSignInPage.enterVerificationCode('000000'); + + // And I click the "Confirm" button + await confirmSignInPage.submitConfirmSignIn(); + + // Then I see "Invalid code" error message + confirmSignInPage.expectInvalidVerificationCode(); + + await tester.bloc.close(); + }); + }); + }); +} diff --git a/packages/authenticator/amplify_authenticator/lib/amplify_authenticator.dart b/packages/authenticator/amplify_authenticator/lib/amplify_authenticator.dart index bd71bfdf0b..81d94d88a8 100644 --- a/packages/authenticator/amplify_authenticator/lib/amplify_authenticator.dart +++ b/packages/authenticator/amplify_authenticator/lib/amplify_authenticator.dart @@ -76,7 +76,9 @@ export 'src/widgets/form.dart' ConfirmSignInMFAForm, ConfirmSignInNewPasswordForm, ContinueSignInWithMfaSelectionForm, + ContinueSignInWithMfaSetupSelectionForm, ContinueSignInWithTotpSetupForm, + ContinueSignInWithEmailMfaSetupForm, ConfirmSignUpForm, ResetPasswordForm, ConfirmResetPasswordForm, @@ -710,9 +712,14 @@ class _AuthenticatorState extends State { confirmSignInMFAForm: ConfirmSignInMFAForm(), continueSignInWithMfaSelectionForm: ContinueSignInWithMfaSelectionForm(), + continueSignInWithMfaSetupSelectionForm: + ContinueSignInWithMfaSetupSelectionForm(), continueSignInWithTotpSetupForm: ContinueSignInWithTotpSetupForm(), + continueSignInWithEmailMfaSetupForm: + ContinueSignInWithEmailMfaSetupForm(), confirmSignInWithTotpMfaCodeForm: ConfirmSignInMFAForm(), + confirmSignInWithOtpCodeForm: ConfirmSignInMFAForm(), verifyUserForm: VerifyUserForm(), confirmVerifyUserForm: ConfirmVerifyUserForm(), child: widget.child, diff --git a/packages/authenticator/amplify_authenticator/lib/src/blocs/auth/auth_bloc.dart b/packages/authenticator/amplify_authenticator/lib/src/blocs/auth/auth_bloc.dart index 4c729b9078..00c6eb222d 100644 --- a/packages/authenticator/amplify_authenticator/lib/src/blocs/auth/auth_bloc.dart +++ b/packages/authenticator/amplify_authenticator/lib/src/blocs/auth/auth_bloc.dart @@ -227,10 +227,14 @@ class StateMachineBloc yield UnauthenticatedState.confirmSignInNewPassword; case AuthSignInStep.confirmSignInWithTotpMfaCode: yield UnauthenticatedState.confirmSignInWithTotpMfaCode; + case AuthSignInStep.confirmSignInWithOtpCode: + yield UnauthenticatedState.confirmSignInWithOtpCode; case AuthSignInStep.continueSignInWithMfaSelection: yield ContinueSignInWithMfaSelection( allowedMfaTypes: result.nextStep.allowedMfaTypes, ); + case AuthSignInStep.continueSignInWithMfaSetupSelection: + yield await _handleMfaSetupSelection(result); case AuthSignInStep.continueSignInWithTotpSetup: assert( result.nextStep.totpSetupDetails != null, @@ -240,6 +244,8 @@ class StateMachineBloc result.nextStep.totpSetupDetails!, totpOptions, ); + case AuthSignInStep.continueSignInWithEmailMfaSetup: + yield UnauthenticatedState.continueSignInWithEmailMfaSetup; case AuthSignInStep.resetPassword: yield UnauthenticatedState.resetPassword; case AuthSignInStep.confirmSignUp: @@ -333,19 +339,15 @@ class StateMachineBloc allowedMfaTypes: result.nextStep.allowedMfaTypes, ), ); - case AuthSignInStep.continueSignInWithTotpSetup: - assert( - result.nextStep.totpSetupDetails != null, - 'Sign In Result should have totpSetupDetails', - ); - _emit( - await ContinueSignInTotpSetup.setupURI( - result.nextStep.totpSetupDetails!, - totpOptions, - ), - ); + case AuthSignInStep.continueSignInWithMfaSetupSelection: + _emit(await _handleMfaSetupSelection(result)); + case AuthSignInStep.continueSignInWithEmailMfaSetup: + _emit(UnauthenticatedState.continueSignInWithEmailMfaSetup); case AuthSignInStep.confirmSignInWithTotpMfaCode: _emit(UnauthenticatedState.confirmSignInWithTotpMfaCode); + case AuthSignInStep.confirmSignInWithOtpCode: + _notifyCodeSent(result.nextStep.codeDeliveryDetails?.destination); + _emit(UnauthenticatedState.confirmSignInWithOtpCode); case AuthSignInStep.resetPassword: _emit(UnauthenticatedState.confirmResetPassword); case AuthSignInStep.confirmSignUp: @@ -541,6 +543,50 @@ class StateMachineBloc yield* const Stream.empty(); } + Future _handleMfaSetupSelection( + SignInResult result, + ) async { + final allowedMfaTypes = result.nextStep.allowedMfaTypes; + + if (allowedMfaTypes == null) { + throw const InvalidUserPoolConfigurationException( + 'No MFA types are supported', + recoverySuggestion: 'Check your user pool MFA configuration.', + ); + } + + final mfaTypesForSetup = allowedMfaTypes.toSet()..remove(MfaType.sms); + + if (mfaTypesForSetup.length != 1) { + return ContinueSignInWithMfaSetupSelection( + allowedMfaTypes: allowedMfaTypes, + ); + } + + final mfaType = mfaTypesForSetup.first; + + switch (mfaType) { + case MfaType.totp: + assert( + result.nextStep.totpSetupDetails != null, + 'Sign In Result should have totpSetupDetails', + ); + return ContinueSignInTotpSetup.setupURI( + result.nextStep.totpSetupDetails!, + totpOptions, + ); + + case MfaType.email: + return UnauthenticatedState.continueSignInWithEmailMfaSetup; + + default: + throw InvalidUserPoolConfigurationException( + 'Unsupported MFA type: ${mfaType.name}', + recoverySuggestion: 'Check your user pool MFA configuration.', + ); + } + } + @override Future close() async { await Future.wait([ diff --git a/packages/authenticator/amplify_authenticator/lib/src/enums/authenticator_step.dart b/packages/authenticator/amplify_authenticator/lib/src/enums/authenticator_step.dart index a90f0f8b0a..8fcc406563 100644 --- a/packages/authenticator/amplify_authenticator/lib/src/enums/authenticator_step.dart +++ b/packages/authenticator/amplify_authenticator/lib/src/enums/authenticator_step.dart @@ -61,18 +61,29 @@ enum AuthenticatorStep { /// an MFA method. continueSignInWithMfaSelection, + /// The user is on the Continue Sign In with MFA Setup Selection step. + /// The sign-in is not complete and the user must select an MFA method to setup. + continueSignInWithMfaSetupSelection, + /// The user is on the Continue Sign In with TOTP setup step. /// /// The sign-in is not complete and a TOTP authenticator app must be /// registered before continuing. continueSignInWithTotpSetup, + /// The sign-in is not complete and an Email MFA must be set up before + /// continuing. + continueSignInWithEmailMfaSetup, + /// The user is on the Confirm Sign In with TOTP MFA step. /// /// The sign-in is not complete and must be confirmed with a TOTP code /// from a registered authenticator app. confirmSignInWithTotpMfaCode, + /// The sign-in is not complete and must be confirmed with an email code. + confirmSignInWithOtpCode, + /// The user is on the Reset Password step. resetPassword, diff --git a/packages/authenticator/amplify_authenticator/lib/src/enums/email_setup_types.dart b/packages/authenticator/amplify_authenticator/lib/src/enums/email_setup_types.dart new file mode 100644 index 0000000000..88252cb4e5 --- /dev/null +++ b/packages/authenticator/amplify_authenticator/lib/src/enums/email_setup_types.dart @@ -0,0 +1,6 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +enum EmailSetupField { + email, +} diff --git a/packages/authenticator/amplify_authenticator/lib/src/enums/enums.dart b/packages/authenticator/amplify_authenticator/lib/src/enums/enums.dart index f523de2aa8..3a4b577678 100644 --- a/packages/authenticator/amplify_authenticator/lib/src/enums/enums.dart +++ b/packages/authenticator/amplify_authenticator/lib/src/enums/enums.dart @@ -4,6 +4,7 @@ export 'authenticator_step.dart'; export 'confirm_signin_types.dart'; export 'confirm_signup_types.dart'; +export 'email_setup_types.dart'; export 'gender.dart'; export 'reset_password_field.dart'; export 'signin_types.dart'; diff --git a/packages/authenticator/amplify_authenticator/lib/src/keys.dart b/packages/authenticator/amplify_authenticator/lib/src/keys.dart index 49510ea7cf..2ad76b7c01 100644 --- a/packages/authenticator/amplify_authenticator/lib/src/keys.dart +++ b/packages/authenticator/amplify_authenticator/lib/src/keys.dart @@ -52,6 +52,8 @@ const keyCustomChallengeConfirmSignInFormField = Key('customChallengeConfirmSignInFormField'); const keyMfaMethodRadioConfirmSignInFormField = Key('mfaMethodRadioConfirmSignInFormField'); +const keyMfaSetupMethodRadioConfirmSignInFormField = + Key('mfaSetupMethodRadioConfirmSignInFormField'); const keyUsernameConfirmSignInFormField = Key('usernameConfirmSignInFormField'); const keyPasswordConfirmSignInFormField = Key('passwordConfirmSignInFormField'); const keyNewPasswordConfirmSignInFormField = @@ -107,6 +109,10 @@ const keyGoToSignInButton = Key('goToSignInButton'); const keyConfirmSignInButton = Key('confirmSignInButton'); const keyConfirmSignInMfaSelectionButton = Key('confirmSignInMfaSelectionButton'); +const keyConfirmSignInMfaSetupSelectionButton = + Key('confirmSignInMfaSetupSelectionButton'); +const keyConfirmSignInWithEmailMfaSetupButton = + Key('confirmSignInWithEmailMfaSetupButton'); const keyConfirmSignInCustomButton = Key('confirmSignInCustomButton'); const keyLostCodeButton = Key('lostCodeButton'); const keySendCodeButton = Key('sendCodeButton'); @@ -140,3 +146,6 @@ const keyAuthenticatorBanner = Key('authenticatorBanner'); const keyQrCodeTotpSetupFormField = Key('qrCodeTotpSetupFormField'); const keyCopyKeyTotpSetupFormField = Key('copyKeyTotpSetupFormField'); const keyTotpSetupFormField = Key('totpSetupFormField'); + +// Email setup form keys +const keyEmailSetupFormField = Key('emailSetupFormField'); diff --git a/packages/authenticator/amplify_authenticator/lib/src/l10n/generated/input_localizations.dart b/packages/authenticator/amplify_authenticator/lib/src/l10n/generated/input_localizations.dart index 178e5b3eeb..b34f12cf8e 100644 --- a/packages/authenticator/amplify_authenticator/lib/src/l10n/generated/input_localizations.dart +++ b/packages/authenticator/amplify_authenticator/lib/src/l10n/generated/input_localizations.dart @@ -297,6 +297,12 @@ abstract class AuthenticatorInputLocalizations { /// **'Authenticator App (TOTP)'** String get selectTotp; + /// Label for the radio button to select email as the user's chosen MFA method. + /// + /// In en, this message translates to: + /// **'Email'** + String get selectEmail; + /// The instructional text for submitting a TOTP pass code /// /// In en, this message translates to: diff --git a/packages/authenticator/amplify_authenticator/lib/src/l10n/generated/input_localizations_en.dart b/packages/authenticator/amplify_authenticator/lib/src/l10n/generated/input_localizations_en.dart index dcd9c0139c..6b6d42a494 100644 --- a/packages/authenticator/amplify_authenticator/lib/src/l10n/generated/input_localizations_en.dart +++ b/packages/authenticator/amplify_authenticator/lib/src/l10n/generated/input_localizations_en.dart @@ -153,6 +153,9 @@ class AuthenticatorInputLocalizationsEn @override String get selectTotp => 'Authenticator App (TOTP)'; + @override + String get selectEmail => 'Email'; + @override String get totpCodePrompt => 'Please enter the code from your registered Authenticator app'; diff --git a/packages/authenticator/amplify_authenticator/lib/src/l10n/generated/title_localizations.dart b/packages/authenticator/amplify_authenticator/lib/src/l10n/generated/title_localizations.dart index 6d69ec3571..abe2edf4ce 100644 --- a/packages/authenticator/amplify_authenticator/lib/src/l10n/generated/title_localizations.dart +++ b/packages/authenticator/amplify_authenticator/lib/src/l10n/generated/title_localizations.dart @@ -141,6 +141,24 @@ abstract class AuthenticatorTitleLocalizations { /// **'Enter your one-time passcode'** String get confirmSignInWithTotpMfaCode; + /// Title of the Confirm Sign In with Email MFA Code step and form + /// + /// In en, this message translates to: + /// **'Enter your one-time passcode'** + String get confirmSignInWithOtpCode; + + /// Title of the Continue Sign In with Email MFA Setup step and form + /// + /// In en, this message translates to: + /// **'Add Email for Two-Factor Authentication'** + String get continueSignInWithEmailMfaSetup; + + /// Title of the Continue Sign In with MFA Setup Selection step and form + /// + /// In en, this message translates to: + /// **'Choose your preferred two-factor authentication method to set up'** + String get continueSignInWithMfaSetupSelection; + /// Title of the Reset Password step and form /// /// In en, this message translates to: diff --git a/packages/authenticator/amplify_authenticator/lib/src/l10n/generated/title_localizations_en.dart b/packages/authenticator/amplify_authenticator/lib/src/l10n/generated/title_localizations_en.dart index 02fb43da7d..938f974e9f 100644 --- a/packages/authenticator/amplify_authenticator/lib/src/l10n/generated/title_localizations_en.dart +++ b/packages/authenticator/amplify_authenticator/lib/src/l10n/generated/title_localizations_en.dart @@ -30,6 +30,17 @@ class AuthenticatorTitleLocalizationsEn @override String get confirmSignInWithTotpMfaCode => 'Enter your one-time passcode'; + @override + String get confirmSignInWithOtpCode => 'Enter your one-time passcode'; + + @override + String get continueSignInWithEmailMfaSetup => + 'Add Email for Two-Factor Authentication'; + + @override + String get continueSignInWithMfaSetupSelection => + 'Choose your preferred two-factor authentication method to set up'; + @override String get resetPassword => 'Send Code'; diff --git a/packages/authenticator/amplify_authenticator/lib/src/l10n/input_resolver.dart b/packages/authenticator/amplify_authenticator/lib/src/l10n/input_resolver.dart index ad9eed1b0c..0eb96b26f1 100644 --- a/packages/authenticator/amplify_authenticator/lib/src/l10n/input_resolver.dart +++ b/packages/authenticator/amplify_authenticator/lib/src/l10n/input_resolver.dart @@ -33,6 +33,7 @@ enum InputField { rememberDevice, selectSms, selectTotp, + selectEmail, totpCodePrompt, usernameType, } @@ -171,6 +172,11 @@ class InputResolverKey { field: InputField.selectSms, ); + static const selectEmail = InputResolverKey._( + InputResolverKeyType.title, + field: InputField.selectEmail, + ); + static const totpCodePrompt = InputResolverKey._( InputResolverKeyType.title, field: InputField.totpCodePrompt, @@ -456,6 +462,8 @@ class InputResolver extends Resolver { return AuthenticatorLocalizations.inputsOf(context).selectSms; case InputField.selectTotp: return AuthenticatorLocalizations.inputsOf(context).selectTotp; + case InputField.selectEmail: + return AuthenticatorLocalizations.inputsOf(context).selectEmail; case InputField.totpCodePrompt: return AuthenticatorLocalizations.inputsOf(context).totpCodePrompt; case InputField.usernameType: diff --git a/packages/authenticator/amplify_authenticator/lib/src/l10n/src/inputs/inputs_en.arb b/packages/authenticator/amplify_authenticator/lib/src/l10n/src/inputs/inputs_en.arb index 90399598d1..e32dd76731 100644 --- a/packages/authenticator/amplify_authenticator/lib/src/l10n/src/inputs/inputs_en.arb +++ b/packages/authenticator/amplify_authenticator/lib/src/l10n/src/inputs/inputs_en.arb @@ -216,5 +216,9 @@ "totpCodePrompt": "Please enter the code from your registered Authenticator app", "@totpCodePrompt": { "description": "The instructional text for submitting a TOTP pass code" - } + }, + "selectEmail": "Email", + "@selectEmail": { + "description": "Label for the radio button to select email as the user's chosen MFA method." + }, } diff --git a/packages/authenticator/amplify_authenticator/lib/src/l10n/title_resolver.dart b/packages/authenticator/amplify_authenticator/lib/src/l10n/title_resolver.dart index bbbf34925c..318753c227 100644 --- a/packages/authenticator/amplify_authenticator/lib/src/l10n/title_resolver.dart +++ b/packages/authenticator/amplify_authenticator/lib/src/l10n/title_resolver.dart @@ -49,6 +49,24 @@ class TitleResolver extends Resolver { .confirmSignInWithTotpMfaCode; } + /// The title for the confirm sign in (email MFA code) Widget. + String confirmSignInWithOtpCode(BuildContext context) { + return AuthenticatorLocalizations.titlesOf(context) + .confirmSignInWithOtpCode; + } + + /// The title for the continue sign in (email MFA setup) Widget. + String continueSignInWithEmailMfaSetup(BuildContext context) { + return AuthenticatorLocalizations.titlesOf(context) + .continueSignInWithEmailMfaSetup; + } + + /// The title for the continue sign in (mfa setup selection) Widget. + String continueSignInWithMfaSetupSelection(BuildContext context) { + return AuthenticatorLocalizations.titlesOf(context) + .continueSignInWithMfaSetupSelection; + } + /// The title for the reset password Widget. String resetPassword(BuildContext context) { return AuthenticatorLocalizations.titlesOf(context).resetPassword; @@ -81,6 +99,12 @@ class TitleResolver extends Resolver { return continueSignInWithTotpSetup(context); case AuthenticatorStep.confirmSignInWithTotpMfaCode: return confirmSignInWithTotpMfaCode(context); + case AuthenticatorStep.confirmSignInWithOtpCode: + return confirmSignInWithOtpCode(context); + case AuthenticatorStep.continueSignInWithEmailMfaSetup: + return continueSignInWithEmailMfaSetup(context); + case AuthenticatorStep.continueSignInWithMfaSetupSelection: + return continueSignInWithMfaSetupSelection(context); case AuthenticatorStep.resetPassword: return resetPassword(context); case AuthenticatorStep.confirmResetPassword: diff --git a/packages/authenticator/amplify_authenticator/lib/src/screens/authenticator_screen.dart b/packages/authenticator/amplify_authenticator/lib/src/screens/authenticator_screen.dart index 181816a0ba..2524d2cb35 100644 --- a/packages/authenticator/amplify_authenticator/lib/src/screens/authenticator_screen.dart +++ b/packages/authenticator/amplify_authenticator/lib/src/screens/authenticator_screen.dart @@ -40,6 +40,18 @@ class AuthenticatorScreen extends StatelessAuthenticatorComponent { const AuthenticatorScreen.confirmSignInWithTotpMfaCode({Key? key}) : this(key: key, step: AuthenticatorStep.confirmSignInWithTotpMfaCode); + const AuthenticatorScreen.confirmSignInWithOtpCode({Key? key}) + : this(key: key, step: AuthenticatorStep.confirmSignInWithOtpCode); + + const AuthenticatorScreen.continueSignInWithEmailMfaSetup({Key? key}) + : this(key: key, step: AuthenticatorStep.continueSignInWithEmailMfaSetup); + + const AuthenticatorScreen.continueSignInWithMfaSetupSelection({Key? key}) + : this( + key: key, + step: AuthenticatorStep.continueSignInWithMfaSetupSelection, + ); + const AuthenticatorScreen.resetPassword({Key? key}) : this(key: key, step: AuthenticatorStep.resetPassword); @@ -91,6 +103,9 @@ class AuthenticatorScreen extends StatelessAuthenticatorComponent { case AuthenticatorStep.confirmResetPassword: case AuthenticatorStep.verifyUser: case AuthenticatorStep.confirmVerifyUser: + case AuthenticatorStep.confirmSignInWithOtpCode: + case AuthenticatorStep.continueSignInWithEmailMfaSetup: + case AuthenticatorStep.continueSignInWithMfaSetupSelection: child = _FormWrapperView(step: step); case AuthenticatorStep.loading: throw StateError('Invalid step: $this'); @@ -299,6 +314,9 @@ extension on AuthenticatorStep { case AuthenticatorStep.verifyUser: case AuthenticatorStep.confirmVerifyUser: case AuthenticatorStep.loading: + case AuthenticatorStep.confirmSignInWithOtpCode: + case AuthenticatorStep.continueSignInWithEmailMfaSetup: + case AuthenticatorStep.continueSignInWithMfaSetupSelection: throw StateError('Invalid step: $this'); } } diff --git a/packages/authenticator/amplify_authenticator/lib/src/state/auth_state.dart b/packages/authenticator/amplify_authenticator/lib/src/state/auth_state.dart index 5a948e05bf..ed4d213700 100644 --- a/packages/authenticator/amplify_authenticator/lib/src/state/auth_state.dart +++ b/packages/authenticator/amplify_authenticator/lib/src/state/auth_state.dart @@ -46,6 +46,12 @@ class UnauthenticatedState extends AuthState static const confirmSignInWithTotpMfaCode = UnauthenticatedState( step: AuthenticatorStep.confirmSignInWithTotpMfaCode, ); + static const continueSignInWithEmailMfaSetup = UnauthenticatedState( + step: AuthenticatorStep.continueSignInWithEmailMfaSetup, + ); + static const confirmSignInWithOtpCode = UnauthenticatedState( + step: AuthenticatorStep.confirmSignInWithOtpCode, + ); static const resetPassword = UnauthenticatedState(step: AuthenticatorStep.resetPassword); static const confirmResetPassword = @@ -111,6 +117,21 @@ class ContinueSignInWithMfaSelection extends UnauthenticatedState { String get runtimeTypeName => 'ContinueSignInWithMfaSelection'; } +class ContinueSignInWithMfaSetupSelection extends UnauthenticatedState { + const ContinueSignInWithMfaSetupSelection({ + Set? allowedMfaTypes, + }) : allowedMfaTypes = allowedMfaTypes ?? const {}, + super(step: AuthenticatorStep.continueSignInWithMfaSetupSelection); + + final Set allowedMfaTypes; + + @override + List get props => [step, allowedMfaTypes]; + + @override + String get runtimeTypeName => 'ContinueSignInWithMfaSetupSelection'; +} + class ContinueSignInTotpSetup extends UnauthenticatedState { const ContinueSignInTotpSetup(this.totpSetupDetails, this.totpSetupUri) : super(step: AuthenticatorStep.continueSignInWithTotpSetup); diff --git a/packages/authenticator/amplify_authenticator/lib/src/state/authenticator_state.dart b/packages/authenticator/amplify_authenticator/lib/src/state/authenticator_state.dart index 10bdef835b..836c4f1a01 100644 --- a/packages/authenticator/amplify_authenticator/lib/src/state/authenticator_state.dart +++ b/packages/authenticator/amplify_authenticator/lib/src/state/authenticator_state.dart @@ -160,6 +160,18 @@ class AuthenticatorState extends ChangeNotifier { notifyListeners(); } + /// The value for the email MFA setup form field + /// + /// This value will be used during continue email MFA setup + String get mfaEmail => _mfaEmail; + + set mfaEmail(String value) { + _mfaEmail = value.trim(); + notifyListeners(); + } + + String _mfaEmail = ''; + MfaType? _selectedMfaMethod; TotpSetupDetails? get totpSetupDetails { @@ -395,6 +407,23 @@ class AuthenticatorState extends ChangeNotifier { _setIsBusy(false); } + /// Select MFA setup preference using the values for [selectedMfaMethod] + Future continueSignInWithMfaSetupSelection() async { + if (!_formKey.currentState!.validate()) { + return; + } + + _setIsBusy(true); + + final confirm = AuthConfirmSignInData( + confirmationValue: _selectedMfaMethod!.name, + ); + + _authBloc.add(AuthConfirmSignIn(confirm)); + await nextBlocEvent(); + _setIsBusy(false); + } + /// Complete TOTP setup using the values for [confirmationCode] /// and any user attributes. Future confirmTotp() async { @@ -414,6 +443,40 @@ class AuthenticatorState extends ChangeNotifier { _setIsBusy(false); } + /// complete Email MFA setup using the values for [confirmationCode] + Future confirmEmailMfa() async { + if (!_formKey.currentState!.validate()) { + return; + } + + _setIsBusy(true); + + final confirm = AuthConfirmSignInData( + confirmationValue: _confirmationCode.trim(), + ); + + _authBloc.add(AuthConfirmSignIn(confirm)); + await nextBlocEvent(); + _setIsBusy(false); + } + + /// Complete MFA setup using the values for [confirmationCode] + Future continueEmailMfaSetup() async { + if (!_formKey.currentState!.validate()) { + return; + } + + _setIsBusy(true); + + final confirm = AuthConfirmSignInData( + confirmationValue: _mfaEmail.trim(), + ); + + _authBloc.add(AuthConfirmSignIn(confirm)); + await nextBlocEvent(); + _setIsBusy(false); + } + /// Complete the force password change with [newPassword] Future confirmSignInNewPassword() async { if (!_formKey.currentState!.validate()) { @@ -644,6 +707,7 @@ class AuthenticatorState extends ChangeNotifier { authAttributes.clear(); _publicChallengeParams.clear(); _selectedMfaMethod = null; + _mfaEmail = ''; } void _resetFormKey() { diff --git a/packages/authenticator/amplify_authenticator/lib/src/state/inherited_forms.dart b/packages/authenticator/amplify_authenticator/lib/src/state/inherited_forms.dart index a2a0dfa5ae..12717df25b 100644 --- a/packages/authenticator/amplify_authenticator/lib/src/state/inherited_forms.dart +++ b/packages/authenticator/amplify_authenticator/lib/src/state/inherited_forms.dart @@ -16,8 +16,11 @@ class InheritedForms extends InheritedWidget { required this.confirmResetPasswordForm, required this.confirmSignInNewPasswordForm, required this.continueSignInWithMfaSelectionForm, + required this.continueSignInWithMfaSetupSelectionForm, required this.continueSignInWithTotpSetupForm, + required this.continueSignInWithEmailMfaSetupForm, required this.confirmSignInWithTotpMfaCodeForm, + required this.confirmSignInWithOtpCodeForm, required this.verifyUserForm, required this.confirmVerifyUserForm, required super.child, @@ -30,8 +33,12 @@ class InheritedForms extends InheritedWidget { final ConfirmSignInMFAForm confirmSignInMFAForm; final ConfirmSignInNewPasswordForm confirmSignInNewPasswordForm; final ContinueSignInWithMfaSelectionForm continueSignInWithMfaSelectionForm; + final ContinueSignInWithMfaSetupSelectionForm + continueSignInWithMfaSetupSelectionForm; final ContinueSignInWithTotpSetupForm continueSignInWithTotpSetupForm; + final ContinueSignInWithEmailMfaSetupForm continueSignInWithEmailMfaSetupForm; final ConfirmSignInMFAForm confirmSignInWithTotpMfaCodeForm; + final ConfirmSignInMFAForm confirmSignInWithOtpCodeForm; final ResetPasswordForm resetPasswordForm; final ConfirmResetPasswordForm confirmResetPasswordForm; final VerifyUserForm verifyUserForm; @@ -55,10 +62,16 @@ class InheritedForms extends InheritedWidget { return confirmSignInNewPasswordForm; case AuthenticatorStep.continueSignInWithMfaSelection: return continueSignInWithMfaSelectionForm; + case AuthenticatorStep.continueSignInWithMfaSetupSelection: + return continueSignInWithMfaSetupSelectionForm; case AuthenticatorStep.continueSignInWithTotpSetup: return continueSignInWithTotpSetupForm; case AuthenticatorStep.confirmSignInWithTotpMfaCode: return confirmSignInWithTotpMfaCodeForm; + case AuthenticatorStep.continueSignInWithEmailMfaSetup: + return continueSignInWithEmailMfaSetupForm; + case AuthenticatorStep.confirmSignInWithOtpCode: + return confirmSignInWithOtpCodeForm; case AuthenticatorStep.resetPassword: return resetPasswordForm; case AuthenticatorStep.confirmResetPassword: @@ -104,7 +117,13 @@ class InheritedForms extends InheritedWidget { oldWidget.continueSignInWithTotpSetupForm != continueSignInWithTotpSetupForm || oldWidget.confirmSignInWithTotpMfaCodeForm != - confirmSignInWithTotpMfaCodeForm; + confirmSignInWithTotpMfaCodeForm || + oldWidget.confirmSignInWithOtpCodeForm != + confirmSignInWithOtpCodeForm || + oldWidget.continueSignInWithEmailMfaSetupForm != + continueSignInWithEmailMfaSetupForm || + oldWidget.continueSignInWithMfaSetupSelectionForm != + continueSignInWithMfaSetupSelectionForm; } } diff --git a/packages/authenticator/amplify_authenticator/lib/src/widgets/button.dart b/packages/authenticator/amplify_authenticator/lib/src/widgets/button.dart index c2c92e87bb..ccd43114da 100644 --- a/packages/authenticator/amplify_authenticator/lib/src/widgets/button.dart +++ b/packages/authenticator/amplify_authenticator/lib/src/widgets/button.dart @@ -253,6 +253,50 @@ class ContinueSignInMFASelectionButton extends AuthenticatorElevatedButton { state.continueSignInWithMfaSelection(); } +/// {@category Prebuilt Widgets} +/// {@template amplify_authenticator.continue_sign_in_mfa_setup_selection_button} +/// A prebuilt button for Sign In with MFA setup selection. +/// +/// Uses [ButtonResolverKey.continueLabel] for localization +/// {@endtemplate} +class ContinueSignInMFASetupSelectionButton + extends AuthenticatorElevatedButton { + /// {@macro amplify_authenticator.continue_sign_in_mfa_setup_selection_button} + const ContinueSignInMFASetupSelectionButton({Key? key}) + : super( + key: key ?? keyConfirmSignInMfaSetupSelectionButton, + ); + + @override + ButtonResolverKey get labelKey => ButtonResolverKey.continueLabel; + + @override + void onPressed(BuildContext context, AuthenticatorState state) => + state.continueSignInWithMfaSetupSelection(); +} + +/// {@category Prebuilt Widgets} +/// {@template amplify_authenticator.continue_sign_in_with_email_mfa_setup_button} +/// A prebuilt button for Sign In with Email MFA setup. +/// +/// Uses [ButtonResolverKey.continueLabel] for localization +/// {@endtemplate} +class ContinueSignInWithEmailMfaSetupButton + extends AuthenticatorElevatedButton { + /// {@macro amplify_authenticator.continue_sign_in_with_email_mfa_setup_button} + const ContinueSignInWithEmailMfaSetupButton({Key? key}) + : super( + key: key ?? keyConfirmSignInWithEmailMfaSetupButton, + ); + + @override + ButtonResolverKey get labelKey => ButtonResolverKey.continueLabel; + + @override + void onPressed(BuildContext context, AuthenticatorState state) => + state.continueEmailMfaSetup(); +} + /// {@category Prebuilt Widgets} /// {@template amplify_authenticator.confirm_sign_in_mfa_button} /// A prebuilt button for completing Sign In with and MFA code. diff --git a/packages/authenticator/amplify_authenticator/lib/src/widgets/form.dart b/packages/authenticator/amplify_authenticator/lib/src/widgets/form.dart index 301b61177c..abad5f4369 100644 --- a/packages/authenticator/amplify_authenticator/lib/src/widgets/form.dart +++ b/packages/authenticator/amplify_authenticator/lib/src/widgets/form.dart @@ -544,7 +544,7 @@ class ConfirmSignInCustomAuthForm extends AuthenticatorForm { /// {@category Prebuilt Widgets} /// {@template amplify_authenticator.confirm_sign_in_mfa_form} /// A prebuilt form for completing the sign in process with an MFA code, from -/// either SMS or TOTP. +/// either SMS, TOTP, or Email. /// {@endtemplate} class ConfirmSignInMFAForm extends AuthenticatorForm { /// {@macro amplify_authenticator.confirm_sign_in_mfa_form} @@ -623,6 +623,30 @@ class ContinueSignInWithMfaSelectionForm extends AuthenticatorForm { AuthenticatorFormState(); } +/// {@category Prebuilt Widgets} +/// {@template amplify_authenticator.continue_sign_in_with__mfa_setup_selection_form} +/// A prebuilt form for selecting an MFA method during setup. +/// {@endtemplate} +class ContinueSignInWithMfaSetupSelectionForm extends AuthenticatorForm { + /// {@macro amplify_authenticator.continue_sign_in_with__mfa_setup_selection_form} + ContinueSignInWithMfaSetupSelectionForm({ + super.key, + }) : super._( + fields: [ + ConfirmSignInFormField.mfaSetupSelection(), + ], + actions: const [ + ContinueSignInMFASetupSelectionButton(), + BackToSignInButton(), + ], + ); + + @override + AuthenticatorFormState + createState() => + AuthenticatorFormState(); +} + /// {@category Prebuilt Widgets} /// {@template amplify_authenticator.continue_sign_in_with_totp_setup_form} /// A prebuilt form for completing the totp setup process. @@ -646,6 +670,28 @@ class ContinueSignInWithTotpSetupForm extends AuthenticatorForm { AuthenticatorFormState(); } +/// {@category Prebuilt Widgets} +/// {@template amplify_authenticator.continue_sign_in_with_email_mfa_setup_form} +/// A prebuilt form for completing the email mfa setup process. +/// {@endtemplate} +class ContinueSignInWithEmailMfaSetupForm extends AuthenticatorForm { + ContinueSignInWithEmailMfaSetupForm({ + super.key, + }) : super._( + fields: [ + const EmailSetupFormField.email(), + ], + actions: const [ + ContinueSignInWithEmailMfaSetupButton(), + BackToSignInButton(), + ], + ); + + @override + AuthenticatorFormState createState() => + AuthenticatorFormState(); +} + /// {@category Prebuilt Widgets} /// {@template amplify_authenticator.send_code_form} /// A prebuilt form for initiating the reset password flow. diff --git a/packages/authenticator/amplify_authenticator/lib/src/widgets/form_field.dart b/packages/authenticator/amplify_authenticator/lib/src/widgets/form_field.dart index f53a94b831..83f862044e 100644 --- a/packages/authenticator/amplify_authenticator/lib/src/widgets/form_field.dart +++ b/packages/authenticator/amplify_authenticator/lib/src/widgets/form_field.dart @@ -28,7 +28,9 @@ import 'package:qr_flutter/qr_flutter.dart'; part 'form_fields/confirm_sign_in_form_field.dart'; part 'form_fields/confirm_sign_up_form_field.dart'; +part 'form_fields/email_setup_form_field.dart'; part 'form_fields/mfa_selection_form_field.dart'; +part 'form_fields/mfa_setup_selection_form_field.dart'; part 'form_fields/phone_number_field.dart'; part 'form_fields/reset_password_form_field.dart'; part 'form_fields/sign_in_form_field.dart'; @@ -229,11 +231,17 @@ abstract class AuthenticatorFormFieldState< state.confirmSignInCustomAuth(); case AuthenticatorStep.confirmSignInMfa: state.confirmSignInMFA(); + case AuthenticatorStep.confirmSignInWithOtpCode: + state.confirmEmailMfa(); case AuthenticatorStep.confirmSignInNewPassword: state.confirmSignInNewPassword(); case AuthenticatorStep.confirmSignInWithTotpMfaCode: case AuthenticatorStep.continueSignInWithTotpSetup: state.confirmTotp(); + case AuthenticatorStep.continueSignInWithEmailMfaSetup: + state.continueEmailMfaSetup(); + case AuthenticatorStep.continueSignInWithMfaSetupSelection: + state.continueSignInWithMfaSetupSelection(); case AuthenticatorStep.resetPassword: state.resetPassword(); case AuthenticatorStep.confirmResetPassword: diff --git a/packages/authenticator/amplify_authenticator/lib/src/widgets/form_fields/confirm_sign_in_form_field.dart b/packages/authenticator/amplify_authenticator/lib/src/widgets/form_fields/confirm_sign_in_form_field.dart index d4b39d1d22..22d1253f39 100644 --- a/packages/authenticator/amplify_authenticator/lib/src/widgets/form_fields/confirm_sign_in_form_field.dart +++ b/packages/authenticator/amplify_authenticator/lib/src/widgets/form_fields/confirm_sign_in_form_field.dart @@ -79,7 +79,7 @@ abstract class ConfirmSignInFormField autofillHints: autofillHints, ); - /// Creates a mfa preference selection component. + /// Creates an mfa preference selection component. static ConfirmSignInFormField mfaSelection({ Key? key, }) => @@ -88,6 +88,15 @@ abstract class ConfirmSignInFormField field: ConfirmSignInField.mfaMethod, ); + /// creates an mfa preference setup selection component. + static ConfirmSignInFormField mfaSetupSelection({ + Key? key, + }) => + _MfaSetupMethodRadioField( + key: key ?? keyMfaSetupMethodRadioConfirmSignInFormField, + field: ConfirmSignInField.mfaMethod, + ); + /// Creates a verification code component. static ConfirmSignInFormField verificationCode({ Key? key, diff --git a/packages/authenticator/amplify_authenticator/lib/src/widgets/form_fields/email_setup_form_field.dart b/packages/authenticator/amplify_authenticator/lib/src/widgets/form_fields/email_setup_form_field.dart new file mode 100644 index 0000000000..9884b69122 --- /dev/null +++ b/packages/authenticator/amplify_authenticator/lib/src/widgets/form_fields/email_setup_form_field.dart @@ -0,0 +1,73 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +part of '../form_field.dart'; + +/// {@category Prebuilt Widgets} +/// {@template amplify_authenticator.email_setup_form_field} +/// A prebuilt form field widget for use on the Email MFA setup step. +/// {@endtemplate} +class EmailSetupFormField + extends AuthenticatorFormField { + /// {@macro amplify_authenticator.email_setup_form_field} + /// + /// Either [titleKey] or [title] is required. + const EmailSetupFormField._({ + super.key, + required super.field, + super.titleKey, + super.hintTextKey, + super.title, + super.hintText, + super.validator, + super.autofillHints, + }) : super._(); + + /// Creates an email FormField for the email setup step. + const EmailSetupFormField.email({ + Key? key, + FormFieldValidator? validator, + Iterable? autofillHints, + }) : this._( + key: key ?? keyEmailSetupFormField, + field: EmailSetupField.email, + titleKey: InputResolverKey.emailTitle, + hintTextKey: InputResolverKey.emailHint, + validator: validator, + autofillHints: autofillHints, + ); + + @override + bool get required => true; + + @override + AuthenticatorFormFieldState + createState() => _EmailSetupFormFieldState(); +} + +class _EmailSetupFormFieldState extends AuthenticatorFormFieldState< + EmailSetupField, String, EmailSetupFormField> with AuthenticatorTextField { + @override + TextInputType get keyboardType { + return TextInputType.emailAddress; + } + + @override + Iterable? get autofillHints { + return [AutofillHints.email]; + } + + @override + ValueChanged get onChanged { + return (v) => state.mfaEmail = v; + } + + @override + FormFieldValidator get validator { + return validateEmail( + isOptional: isOptional, + context: context, + inputResolver: stringResolver.inputs, + ); + } +} diff --git a/packages/authenticator/amplify_authenticator/lib/src/widgets/form_fields/mfa_selection_form_field.dart b/packages/authenticator/amplify_authenticator/lib/src/widgets/form_fields/mfa_selection_form_field.dart index f5587071d0..8d73d1aae2 100644 --- a/packages/authenticator/amplify_authenticator/lib/src/widgets/form_fields/mfa_selection_form_field.dart +++ b/packages/authenticator/amplify_authenticator/lib/src/widgets/form_fields/mfa_selection_form_field.dart @@ -41,6 +41,11 @@ class _MfaSelectionFieldState extends _ConfirmSignInFormFieldState label: InputResolverKey.selectSms, value: MfaType.sms, ), + if (_allowedMfaTypes.contains(MfaType.email)) + const InputSelection( + label: InputResolverKey.selectEmail, + value: MfaType.email, + ), ]; @override diff --git a/packages/authenticator/amplify_authenticator/lib/src/widgets/form_fields/mfa_setup_selection_form_field.dart b/packages/authenticator/amplify_authenticator/lib/src/widgets/form_fields/mfa_setup_selection_form_field.dart new file mode 100644 index 0000000000..76b4084337 --- /dev/null +++ b/packages/authenticator/amplify_authenticator/lib/src/widgets/form_fields/mfa_setup_selection_form_field.dart @@ -0,0 +1,63 @@ +// mfa_setup_selection_form_field.dart + +// Copyright Amazon.com, Inc. or its affiliates. +// All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +part of '../form_field.dart'; + +/// {@category Prebuilt Widgets} +/// {@template amplify_authenticator.mfa_setup_selection_form_field} +/// A prebuilt form widget for use on the MFA setup selection step. +/// {@endtemplate} +class _MfaSetupMethodRadioField extends ConfirmSignInFormField { + const _MfaSetupMethodRadioField({ + super.key, + required super.field, + }) : super._(); + + @override + _MfaSetupSelectionFieldState createState() => _MfaSetupSelectionFieldState(); +} + +class _MfaSetupSelectionFieldState extends _ConfirmSignInFormFieldState + with AuthenticatorRadioField { + Set get _allowedMfaTypes { + final state = InheritedAuthBloc.of(context).currentState; + assert( + state is ContinueSignInWithMfaSetupSelection, + 'Expected ContinueSignInWithMfaSetupSelection for current screen', + ); + return (state as ContinueSignInWithMfaSetupSelection).allowedMfaTypes; + } + + @override + List> get selections => [ + if (_allowedMfaTypes.contains(MfaType.totp)) + const InputSelection( + label: InputResolverKey.selectTotp, + value: MfaType.totp, + ), + if (_allowedMfaTypes.contains(MfaType.email)) + const InputSelection( + label: InputResolverKey.selectEmail, + value: MfaType.email, + ), + ]; + + @override + MfaType get initialValue => selections.first.value; + + @override + void initState() { + super.initState(); + WidgetsBinding.instance.addPostFrameCallback((_) { + state.selectedMfaMethod = initialValue; + }); + } + + @override + ValueChanged get onChanged { + return (MfaType method) => state.selectedMfaMethod = method; + } +} diff --git a/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_confirmSignInWithOtpCodeStep_defaultMaterialTheme_darkMode_desktopGeometry.png b/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_confirmSignInWithOtpCodeStep_defaultMaterialTheme_darkMode_desktopGeometry.png new file mode 100644 index 0000000000..a6420c3365 Binary files /dev/null and b/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_confirmSignInWithOtpCodeStep_defaultMaterialTheme_darkMode_desktopGeometry.png differ diff --git a/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_confirmSignInWithOtpCodeStep_defaultMaterialTheme_darkMode_mobileGeometry.png b/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_confirmSignInWithOtpCodeStep_defaultMaterialTheme_darkMode_mobileGeometry.png new file mode 100644 index 0000000000..a846131d90 Binary files /dev/null and b/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_confirmSignInWithOtpCodeStep_defaultMaterialTheme_darkMode_mobileGeometry.png differ diff --git a/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_confirmSignInWithOtpCodeStep_defaultMaterialTheme_lightMode_desktopGeometry.png b/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_confirmSignInWithOtpCodeStep_defaultMaterialTheme_lightMode_desktopGeometry.png new file mode 100644 index 0000000000..26e399a433 Binary files /dev/null and b/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_confirmSignInWithOtpCodeStep_defaultMaterialTheme_lightMode_desktopGeometry.png differ diff --git a/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_confirmSignInWithOtpCodeStep_defaultMaterialTheme_lightMode_mobileGeometry.png b/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_confirmSignInWithOtpCodeStep_defaultMaterialTheme_lightMode_mobileGeometry.png new file mode 100644 index 0000000000..1f1bee56e3 Binary files /dev/null and b/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_confirmSignInWithOtpCodeStep_defaultMaterialTheme_lightMode_mobileGeometry.png differ diff --git a/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithEmailMfaSetupStep_defaultMaterialTheme_darkMode_desktopGeometry.png b/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithEmailMfaSetupStep_defaultMaterialTheme_darkMode_desktopGeometry.png new file mode 100644 index 0000000000..046d31c7c3 Binary files /dev/null and b/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithEmailMfaSetupStep_defaultMaterialTheme_darkMode_desktopGeometry.png differ diff --git a/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithEmailMfaSetupStep_defaultMaterialTheme_darkMode_mobileGeometry.png b/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithEmailMfaSetupStep_defaultMaterialTheme_darkMode_mobileGeometry.png new file mode 100644 index 0000000000..565ef42835 Binary files /dev/null and b/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithEmailMfaSetupStep_defaultMaterialTheme_darkMode_mobileGeometry.png differ diff --git a/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithEmailMfaSetupStep_defaultMaterialTheme_lightMode_desktopGeometry.png b/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithEmailMfaSetupStep_defaultMaterialTheme_lightMode_desktopGeometry.png new file mode 100644 index 0000000000..9b30f02df2 Binary files /dev/null and b/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithEmailMfaSetupStep_defaultMaterialTheme_lightMode_desktopGeometry.png differ diff --git a/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithEmailMfaSetupStep_defaultMaterialTheme_lightMode_mobileGeometry.png b/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithEmailMfaSetupStep_defaultMaterialTheme_lightMode_mobileGeometry.png new file mode 100644 index 0000000000..c9fed4c010 Binary files /dev/null and b/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithEmailMfaSetupStep_defaultMaterialTheme_lightMode_mobileGeometry.png differ diff --git a/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithMfaSelectionStep_defaultMaterialTheme_darkMode_desktopGeometry.png b/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithMfaSelectionStep_defaultMaterialTheme_darkMode_desktopGeometry.png index 53c27c7301..8a75ce5fa1 100644 Binary files a/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithMfaSelectionStep_defaultMaterialTheme_darkMode_desktopGeometry.png and b/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithMfaSelectionStep_defaultMaterialTheme_darkMode_desktopGeometry.png differ diff --git a/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithMfaSelectionStep_defaultMaterialTheme_darkMode_mobileGeometry.png b/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithMfaSelectionStep_defaultMaterialTheme_darkMode_mobileGeometry.png index 21795345c9..dd709da29a 100644 Binary files a/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithMfaSelectionStep_defaultMaterialTheme_darkMode_mobileGeometry.png and b/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithMfaSelectionStep_defaultMaterialTheme_darkMode_mobileGeometry.png differ diff --git a/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithMfaSelectionStep_defaultMaterialTheme_lightMode_desktopGeometry.png b/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithMfaSelectionStep_defaultMaterialTheme_lightMode_desktopGeometry.png index 17569d4a11..6e1e3bda1d 100644 Binary files a/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithMfaSelectionStep_defaultMaterialTheme_lightMode_desktopGeometry.png and b/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithMfaSelectionStep_defaultMaterialTheme_lightMode_desktopGeometry.png differ diff --git a/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithMfaSelectionStep_defaultMaterialTheme_lightMode_mobileGeometry.png b/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithMfaSelectionStep_defaultMaterialTheme_lightMode_mobileGeometry.png index 1a8803016a..26145cb92c 100644 Binary files a/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithMfaSelectionStep_defaultMaterialTheme_lightMode_mobileGeometry.png and b/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithMfaSelectionStep_defaultMaterialTheme_lightMode_mobileGeometry.png differ diff --git a/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithMfaSetupSelectionStep_defaultMaterialTheme_darkMode_desktopGeometry.png b/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithMfaSetupSelectionStep_defaultMaterialTheme_darkMode_desktopGeometry.png new file mode 100644 index 0000000000..c7f2fbe43b Binary files /dev/null and b/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithMfaSetupSelectionStep_defaultMaterialTheme_darkMode_desktopGeometry.png differ diff --git a/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithMfaSetupSelectionStep_defaultMaterialTheme_darkMode_mobileGeometry.png b/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithMfaSetupSelectionStep_defaultMaterialTheme_darkMode_mobileGeometry.png new file mode 100644 index 0000000000..a25542f90f Binary files /dev/null and b/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithMfaSetupSelectionStep_defaultMaterialTheme_darkMode_mobileGeometry.png differ diff --git a/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithMfaSetupSelectionStep_defaultMaterialTheme_lightMode_desktopGeometry.png b/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithMfaSetupSelectionStep_defaultMaterialTheme_lightMode_desktopGeometry.png new file mode 100644 index 0000000000..07ff1fc98c Binary files /dev/null and b/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithMfaSetupSelectionStep_defaultMaterialTheme_lightMode_desktopGeometry.png differ diff --git a/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithMfaSetupSelectionStep_defaultMaterialTheme_lightMode_mobileGeometry.png b/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithMfaSetupSelectionStep_defaultMaterialTheme_lightMode_mobileGeometry.png new file mode 100644 index 0000000000..5f27b9f6a5 Binary files /dev/null and b/packages/authenticator/amplify_authenticator/test/ui/goldens/theme_emailConfig_continueSignInWithMfaSetupSelectionStep_defaultMaterialTheme_lightMode_mobileGeometry.png differ diff --git a/packages/authenticator/amplify_authenticator_test/lib/amplify_authenticator_test.dart b/packages/authenticator/amplify_authenticator_test/lib/amplify_authenticator_test.dart index d247d71507..49b9300e16 100644 --- a/packages/authenticator/amplify_authenticator_test/lib/amplify_authenticator_test.dart +++ b/packages/authenticator/amplify_authenticator_test/lib/amplify_authenticator_test.dart @@ -18,6 +18,7 @@ export 'src/pages/authenticator_page.dart'; export 'src/pages/confirm_sign_in_page.dart'; export 'src/pages/confirm_sign_up_page.dart'; export 'src/pages/confirm_verify_user_page.dart'; +export 'src/pages/email_mfa_setup_page.dart'; export 'src/pages/forgot_password_page.dart'; export 'src/pages/sign_in_page.dart'; export 'src/pages/sign_up_page.dart'; diff --git a/packages/authenticator/amplify_authenticator_test/lib/src/amplify_outputs/email_or_phone_config.dart b/packages/authenticator/amplify_authenticator_test/lib/src/amplify_outputs/email_or_phone_config.dart index ad5ef29355..a7cc4c93ac 100644 --- a/packages/authenticator/amplify_authenticator_test/lib/src/amplify_outputs/email_or_phone_config.dart +++ b/packages/authenticator/amplify_authenticator_test/lib/src/amplify_outputs/email_or_phone_config.dart @@ -29,4 +29,4 @@ const emailOrPhoneConfig = '''{ "SMS" ] } -}'''; \ No newline at end of file +}'''; diff --git a/packages/authenticator/amplify_authenticator_test/lib/src/mock_authenticator_app.dart b/packages/authenticator/amplify_authenticator_test/lib/src/mock_authenticator_app.dart index 51f4a84830..af0fbc10f5 100644 --- a/packages/authenticator/amplify_authenticator_test/lib/src/mock_authenticator_app.dart +++ b/packages/authenticator/amplify_authenticator_test/lib/src/mock_authenticator_app.dart @@ -72,6 +72,7 @@ class _MockAuthenticatorAppState extends State { allowedMfaTypes: { MfaType.totp, MfaType.sms, + MfaType.email, }, ), ); @@ -87,6 +88,16 @@ class _MockAuthenticatorAppState extends State { ), ), ); + case AuthenticatorStep.continueSignInWithMfaSetupSelection: + baseBloc.setState( + const ContinueSignInWithMfaSetupSelection( + allowedMfaTypes: { + MfaType.sms, + MfaType.totp, + MfaType.email, + }, + ), + ); default: baseBloc.add(const AuthLoad()); break; diff --git a/packages/authenticator/amplify_authenticator_test/lib/src/pages/authenticator_page.dart b/packages/authenticator/amplify_authenticator_test/lib/src/pages/authenticator_page.dart index 4b4da3226b..78eb6148c6 100644 --- a/packages/authenticator/amplify_authenticator_test/lib/src/pages/authenticator_page.dart +++ b/packages/authenticator/amplify_authenticator_test/lib/src/pages/authenticator_page.dart @@ -42,6 +42,21 @@ abstract class AuthenticatorPage { expect(usernameFieldHint, isPresent ? findsOneWidget : findsNothing); } + /// Then I see "Email" as an input field + void expectEmail({ + String label = 'Email', + bool isPresent = true, + }) { + // email field is present + expect(usernameField, findsOneWidget); + // login type is "email" + final usernameFieldHint = find.descendant( + of: usernameField, + matching: find.text(label), + ); + expect(usernameFieldHint, isPresent ? findsOneWidget : findsNothing); + } + /// Expects the current step to be [step]. void expectStep(AuthenticatorStep step) { final currentScreen = tester.widget( diff --git a/packages/authenticator/amplify_authenticator_test/lib/src/pages/confirm_sign_in_page.dart b/packages/authenticator/amplify_authenticator_test/lib/src/pages/confirm_sign_in_page.dart index 84c8f8cbfb..5d2d352509 100644 --- a/packages/authenticator/amplify_authenticator_test/lib/src/pages/confirm_sign_in_page.dart +++ b/packages/authenticator/amplify_authenticator_test/lib/src/pages/confirm_sign_in_page.dart @@ -25,8 +25,12 @@ class ConfirmSignInPage extends AuthenticatorPage { Finder get confirmSignInButton => find.byKey(keyConfirmSignInButton); Finder get confirmSignInMfaSelectionButton => find.byKey(keyConfirmSignInMfaSelectionButton); + Finder get confirmSignInMfaSetupSelectionButton => + find.byKey(keyConfirmSignInMfaSetupSelectionButton); Finder get selectMfaRadio => find.byKey(keyMfaMethodRadioConfirmSignInFormField); + Finder get selectMfaSetupRadio => + find.byKey(keyMfaSetupMethodRadioConfirmSignInFormField); Finder get backToSignIn => find.byKey(keyBackToSignInButton); /// Then I see "Confirm Sign In - New Password" @@ -59,6 +63,28 @@ class ConfirmSignInPage extends AuthenticatorPage { ); } + /// Then I see "Select an MFA Method to set up" + Future expectContinueSignInWithMfaSetupSelectionIsPresent() async { + final currentScreen = tester.widget( + find.byType(AuthenticatorScreen), + ); + expect( + currentScreen.step, + equals(AuthenticatorStep.continueSignInWithMfaSetupSelection), + ); + } + + /// Then I see "Enter your one-time passcode for Email" + Future expectConfirmSignInWithOtpCodeIsPresent() async { + final currentScreen = tester.widget( + find.byType(AuthenticatorScreen), + ); + expect( + currentScreen.step, + equals(AuthenticatorStep.confirmSignInWithOtpCode), + ); + } + /// Then I see "Setup an Authentication App" Future expectSignInTotpSetupIsPresent() async { final currentScreen = tester.widget( @@ -86,6 +112,12 @@ class ConfirmSignInPage extends AuthenticatorPage { expect(newPasswordField, findsOneWidget); } + /// Then I see "Invalid verification code" + @override + void expectInvalidVerificationCode() { + expectError('Invalid code'); + } + /// When I enter a verification code Future enterVerificationCode(String code) async { await tester.ensureVisible(verificationField); @@ -123,9 +155,34 @@ class ConfirmSignInPage extends AuthenticatorPage { }) async { expect(selectMfaRadio, findsOneWidget); + // if mfaMethod is email, don't make it uppercase except for the first letter + // if mfa method is totp, make it all uppercase final mfaMethodWidget = find.descendant( of: selectMfaRadio, - matching: find.textContaining('(${mfaMethod.name.toUpperCase()})'), + matching: find.textContaining( + mfaMethod == MfaType.email + ? 'Email' + : '(${mfaMethod.name.toUpperCase()})', + ), + ); + + await tester.tap(mfaMethodWidget); + await tester.pumpAndSettle(); + } + + // When I select a MFA setup method + Future selectMfaSetupMethod({ + required MfaType mfaMethod, + }) async { + expect(selectMfaSetupRadio, findsOneWidget); + + final mfaMethodWidget = find.descendant( + of: selectMfaSetupRadio, + matching: find.textContaining( + mfaMethod == MfaType.email + ? 'Email' + : '(${mfaMethod.name.toUpperCase()})', + ), ); await tester.tap(mfaMethodWidget); @@ -139,6 +196,13 @@ class ConfirmSignInPage extends AuthenticatorPage { await tester.pumpAndSettle(); } + /// When I click the continue sign in with MFA setup selection button + Future submitConfirmSignInMfaSetupSelection() async { + await tester.ensureVisible(confirmSignInMfaSetupSelectionButton); + await tester.tap(confirmSignInMfaSetupSelectionButton); + await tester.pumpAndSettle(); + } + /// When I navigate to the "Sign In" step. Future navigateToSignIn() async { await tester.tap(backToSignIn); diff --git a/packages/authenticator/amplify_authenticator_test/lib/src/pages/email_mfa_setup_page.dart b/packages/authenticator/amplify_authenticator_test/lib/src/pages/email_mfa_setup_page.dart new file mode 100644 index 0000000000..546049a4b6 --- /dev/null +++ b/packages/authenticator/amplify_authenticator_test/lib/src/pages/email_mfa_setup_page.dart @@ -0,0 +1,46 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import 'package:amplify_authenticator/amplify_authenticator.dart'; +// ignore: implementation_imports +import 'package:amplify_authenticator/src/keys.dart'; +// ignore: implementation_imports +import 'package:amplify_authenticator/src/screens/authenticator_screen.dart'; +import 'package:amplify_authenticator_test/src/pages/authenticator_page.dart'; +import 'package:flutter_test/flutter_test.dart'; + +class EmailMfaSetupPage extends AuthenticatorPage { + EmailMfaSetupPage({required super.tester}); + + @override + Finder get usernameField => throw UnimplementedError(); + + Finder get emailField => find.byKey(keyEmailSetupFormField); + Finder get continueSignIn => + find.byKey(keyConfirmSignInWithEmailMfaSetupButton); + + /// When I type my email + Future enterEmail(String email) async { + await tester.ensureVisible(emailField); + await tester.enterText(emailField, email); + await tester.pumpAndSettle(); + } + + /// Then I see "Add Email for Two-Factor Authentication" + Future expectEmailMfaSetupIsPresent() async { + final currentScreen = tester.widget( + find.byType(AuthenticatorScreen), + ); + expect( + currentScreen.step, + equals(AuthenticatorStep.continueSignInWithEmailMfaSetup), + ); + } + + /// When I enter an email + Future submitEmail() async { + await tester.ensureVisible(continueSignIn); + await tester.tap(continueSignIn); + await tester.pumpAndSettle(); + } +} diff --git a/packages/test/amplify_auth_integration_test/lib/amplify_auth_integration_test.dart b/packages/test/amplify_auth_integration_test/lib/amplify_auth_integration_test.dart index 0e94ac7fd3..2e3d46e086 100644 --- a/packages/test/amplify_auth_integration_test/lib/amplify_auth_integration_test.dart +++ b/packages/test/amplify_auth_integration_test/lib/amplify_auth_integration_test.dart @@ -6,6 +6,7 @@ library amplify_auth_integration_test; export 'src/async_test.dart'; +export 'src/email_utils.dart'; export 'src/environments.dart'; export 'src/test_auth_plugin.dart'; export 'src/test_runner.dart'; diff --git a/packages/test/amplify_auth_integration_test/lib/src/email_utils.dart b/packages/test/amplify_auth_integration_test/lib/src/email_utils.dart new file mode 100644 index 0000000000..ffb0534cd0 --- /dev/null +++ b/packages/test/amplify_auth_integration_test/lib/src/email_utils.dart @@ -0,0 +1,12 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import 'package:amplify_auth_cognito/amplify_auth_cognito.dart'; +import 'package:amplify_flutter/amplify_flutter.dart'; +import 'package:flutter_test/flutter_test.dart'; + +/// Sets up EMAIL MFA for the current user. +Future setUpEmailMfa() async { + final plugin = Amplify.Auth.getPlugin(AmplifyAuthCognito.pluginKey); + await plugin.updateMfaPreference(email: MfaPreference.preferred); +} diff --git a/packages/test/amplify_auth_integration_test/lib/src/environments.dart b/packages/test/amplify_auth_integration_test/lib/src/environments.dart index f6b9ebee6f..1b2ab30f67 100644 --- a/packages/test/amplify_auth_integration_test/lib/src/environments.dart +++ b/packages/test/amplify_auth_integration_test/lib/src/environments.dart @@ -17,6 +17,12 @@ const List userPoolEnvironments = [ confirmationDeliveryMedium: DeliveryMedium.sms, resetPasswordDeliveryMedium: DeliveryMedium.sms, ), + EnvironmentInfo.withGen2Defaults( + name: 'email-sign-in', + loginMethod: LoginMethod.email, + confirmationDeliveryMedium: DeliveryMedium.email, + resetPasswordDeliveryMedium: DeliveryMedium.email, + ), ]; /// An environment with optional MFA via SMS only. @@ -55,6 +61,55 @@ const mfaRequiredSmsTotp = EnvironmentInfo.withGen1Defaults( mfaInfo: MfaInfo(smsEnabled: true, totpEnabled: true, required: true), ); +/// An environment with required MFA via Email only. +const mfaRequiredEmail = EnvironmentInfo.withGen2Defaults( + name: 'mfa-required-email', + mfaInfo: MfaInfo(emailEnabled: true, required: true), + loginMethod: LoginMethod.email, +); + +/// An environment with optional MFA via Email only. +const mfaOptionalEmail = EnvironmentInfo.withGen2Defaults( + name: 'mfa-optional-email', + mfaInfo: MfaInfo(emailEnabled: true, required: false), + loginMethod: LoginMethod.email, +); + +/// An environment with required MFA via Email & SMS. +const mfaRequiredEmailSms = EnvironmentInfo.withGen2Defaults( + name: 'mfa-required-email-sms', + mfaInfo: MfaInfo(emailEnabled: true, smsEnabled: true, required: true), + loginMethod: LoginMethod.email, +); + +/// An environment with optional MFA via Email & SMS. +const mfaOptionalEmailSms = EnvironmentInfo.withGen2Defaults( + name: 'mfa-optional-email-sms', + mfaInfo: MfaInfo(emailEnabled: true, smsEnabled: true, required: false), + loginMethod: LoginMethod.email, +); + +/// An environment with required MFA via Email & TOTP. +const mfaRequiredEmailTotp = EnvironmentInfo.withGen2Defaults( + name: 'mfa-required-email-totp', + mfaInfo: MfaInfo(emailEnabled: true, totpEnabled: true, required: true), + loginMethod: LoginMethod.email, +); + +/// An environment with optional MFA via Email & TOTP. +const mfaOptionalEmailTotp = EnvironmentInfo.withGen2Defaults( + name: 'mfa-optional-email-totp', + mfaInfo: MfaInfo(emailEnabled: true, totpEnabled: true, required: false), + loginMethod: LoginMethod.email, +); + +/// An environment with required MFA and username login. +const mfaRequiredUsernameLogin = EnvironmentInfo.withGen2Defaults( + name: 'username-login-mfa', + mfaInfo: MfaInfo(totpEnabled: true, emailEnabled: true, required: true), + loginMethod: LoginMethod.username, +); + /// Environments that support MFA const List mfaEnvironments = [ mfaOptionalSms, @@ -63,6 +118,13 @@ const List mfaEnvironments = [ mfaRequiredTotp, mfaOptionalSmsTotp, mfaRequiredSmsTotp, + mfaRequiredEmail, + mfaOptionalEmail, + mfaRequiredEmailSms, + mfaOptionalEmailSms, + mfaRequiredEmailTotp, + mfaOptionalEmailTotp, + mfaRequiredUsernameLogin, ]; /// Environments with a user pool and opt-in device tracking. diff --git a/packages/test/amplify_auth_integration_test/lib/src/test_runner.dart b/packages/test/amplify_auth_integration_test/lib/src/test_runner.dart index 1401bc4fd6..9654971cdd 100644 --- a/packages/test/amplify_auth_integration_test/lib/src/test_runner.dart +++ b/packages/test/amplify_auth_integration_test/lib/src/test_runner.dart @@ -145,6 +145,7 @@ class MfaInfo { this.required = false, this.smsEnabled = false, this.totpEnabled = false, + this.emailEnabled = false, }); /// Whether MFA is required (`true`) or optional (`false`). @@ -155,6 +156,9 @@ class MfaInfo { /// Whether TOTP MFA is available. final bool totpEnabled; + + /// Whether email MFA is available. + final bool emailEnabled; } /// A test environment descriptor.