AWS cognito documentation change
Summary
Added Swift SDK code example demonstrating user sign-up with MFA setup including TOTP registration and verification
Security assessment
The change adds documentation for implementing MFA (Multi-Factor Authentication) using TOTP, which is a security feature. While it enhances security documentation, there's no evidence of addressing a specific vulnerability or security incident. The code demonstrates proper security practices for MFA implementation rather than fixing a security issue.
Diff
diff --git a/cognito/latest/developerguide/cognito-identity-provider_example_cognito-identity-provider_Scenario_SignUpUserWithMfa_section.md b/cognito/latest/developerguide/cognito-identity-provider_example_cognito-identity-provider_Scenario_SignUpUserWithMfa_section.md index dfc0048ea..7730dd08e 100644 --- a//cognito/latest/developerguide/cognito-identity-provider_example_cognito-identity-provider_Scenario_SignUpUserWithMfa_section.md +++ b//cognito/latest/developerguide/cognito-identity-provider_example_cognito-identity-provider_Scenario_SignUpUserWithMfa_section.md @@ -2594,0 +2595,634 @@ Create a class that runs the scenario. This example also registers an MFA device +Swift + + +**SDK for Swift** + + +###### Note + +There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/swift/example_code/cognito-identity-provider#code-examples). + +The `Package.swift` file. + + + // swift-tools-version: 5.9 + // + // The swift-tools-version declares the minimum version of Swift required to + // build this package. + + import PackageDescription + + let package = Package( + name: "cognito-scenario", + // Let Xcode know the minimum Apple platforms supported. + platforms: [ + .macOS(.v13), + .iOS(.v15) + ], + dependencies: [ + // Dependencies declare other packages that this package depends on. + .package( + url: "https://github.com/awslabs/aws-sdk-swift", + from: "1.0.0"), + .package( + url: "https://github.com/apple/swift-argument-parser.git", + branch: "main" + ) + ], + targets: [ + // Targets are the basic building blocks of a package, defining a module or a test suite. + // Targets can depend on other targets in this package and products + // from dependencies. + .executableTarget( + name: "cognito-scenario", + dependencies: [ + .product(name: "AWSCognitoIdentityProvider", package: "aws-sdk-swift"), + .product(name: "ArgumentParser", package: "swift-argument-parser") + ], + path: "Sources") + + ] + ) + + + +The Swift code file. + + + // An example demonstrating various features of Amazon Cognito. Before running + // this Swift code example, set up your development environment, including + // your credentials. + // + // For more information, see the following documentation: + // https://docs.aws.amazon.com/sdk-for-kotlin/latest/developer-guide/setup.html + // + // TIP: To set up the required user pool, run the AWS Cloud Development Kit + // (AWS CDK) script provided in this GitHub repo at + // resources/cdk/cognito_scenario_user_pool_with_mfa. + // + // This example performs the following functions: + // + // 1. Invokes the signUp method to sign up a user. + // 2. Invokes the adminGetUser method to get the user's confirmation status. + // 3. Invokes the ResendConfirmationCode method if the user requested another + // code. + // 4. Invokes the confirmSignUp method. + // 5. Invokes the initiateAuth to sign in. This results in being prompted to + // set up TOTP (time-based one-time password). (The response is + // “ChallengeName”: “MFA_SETUP”). + // 6. Invokes the AssociateSoftwareToken method to generate a TOTP MFA private + // key. This can be used with Google Authenticator. + // 7. Invokes the VerifySoftwareToken method to verify the TOTP and register + // for MFA. + // 8. Invokes the AdminInitiateAuth to sign in again. This results in being + // prompted to submit a TOTP (Response: “ChallengeName”: + // “SOFTWARE_TOKEN_MFA”). + // 9. Invokes the AdminRespondToAuthChallenge to get back a token. + + import ArgumentParser + import AWSClientRuntime + import Foundation + + import AWSCognitoIdentityProvider + + struct ExampleCommand: ParsableCommand { + @Argument(help: "The application clientId.") + var clientId: String + @Argument(help: "The user pool ID to use.") + var poolId: String + @Option(help: "Name of the Amazon Region to use") + var region = "us-east-1" + + static var configuration = CommandConfiguration( + commandName: "cognito-scenario", + abstract: """ + Demonstrates various features of Amazon Cognito. + """, + discussion: """ + """ + ) + + /// Prompt for an input string of at least a minimum length. + /// + /// - Parameters: + /// - prompt: The prompt string to display. + /// - minLength: The minimum number of characters to allow in the + /// response. Default value is 0. + /// + /// - Returns: The entered string. + func stringRequest(_ prompt: String, minLength: Int = 1) -> String { + while true { + print(prompt, terminator: "") + let str = readLine() + + guard let str else { + continue + } + if str.count >= minLength { + return str + } else { + print("*** Response must be at least \(minLength) character(s) long.") + } + } + } + + /// Ask a yes/no question. + /// + /// - Parameter prompt: A prompt string to print. + /// + /// - Returns: `true` if the user answered "Y", otherwise `false`. + func yesNoRequest(_ prompt: String) -> Bool { + while true { + let answer = stringRequest(prompt).lowercased() + if answer == "y" || answer == "n" { + return answer == "y" + } + } + } + + /// Get information about a specific user in a user pool. + /// + /// - Parameters: + /// - cipClient: The Amazon Cognito Identity Provider client to use. + /// - userName: The user to retrieve information about. + /// - userPoolId: The user pool to search for the specified user. + /// + /// - Returns: `true` if the user's information was successfully + /// retrieved. Otherwise returns `false`. + func adminGetUser(cipClient: CognitoIdentityProviderClient, userName: String, + userPoolId: String) async -> Bool { + do { + let output = try await cipClient.adminGetUser( + input: AdminGetUserInput( + userPoolId: userPoolId, + username: userName + ) + ) + + guard let userStatus = output.userStatus else { + print("*** Unable to get the user's status.") + return false + } + + print("User status: \(userStatus)") + return true + } catch { + return false + } + } + + /// Create a new user in a user pool. + /// + /// - Parameters: + /// - cipClient: The `CognitoIdentityProviderClient` to use. + /// - clientId: The ID of the app client to create a user for. + /// - userName: The username for the new user. + /// - password: The new user's password. + /// - email: The new user's email address. + /// + /// - Returns: `true` if successful; otherwise `false`. + func signUp(cipClient: CognitoIdentityProviderClient, clientId: String, userName: String, password: String, email: String) async -> Bool { + let emailAttr = CognitoIdentityProviderClientTypes.AttributeType( + name: "email", + value: email + ) +