How to enable TOTP software token MFA on Amazon Cognito
What is Amazon Cognito?
Amazon Cognito is a AWS service provide authentication and authorization with various provider as email/password or social OAuth (Google, Facebook, ...)
What is TOPT?
TOPT is shorthand for Time-based one-time password
It will generate a temporary unique passcode (is generated with a standardized algorithm that uses the current time as an input ) and it is valid in a short time( normally 30 seconds), after that, It will automatically expire. 
Enable TOPT Software token MFA feature on Amazon Cognito?
- Create a 
User pooland setting MFA for it like below. 
 2. Create App client without secret code and make sure that 'ALLOW_USER_SRP_AUTH' is checked.
3. Create a sample user.
Connect Amazon Cognito for setup MFA Software token using Javacript
	
We will demo how setup MFA and login with MFA by using Javascript Code snippet below:
const prompt = require("prompt");
const qrcode = require("qrcode-terminal");
const AmazonCognitoIdentity = require("amazon-cognito-identity-js");
const CONFIG = {
  UserPoolId: "YOUR_POOL_ID",
  ClientId: "YOUR_CLIENT_ID",
};
main = function () {
  prompt.start();
  const promptSchema = {
    properties: {
      username: { required: true },
      password: { hidden: true },
    },
  };
  prompt.get(promptSchema, function (err, result) {
    let username = result["username"];
    let password = result["password"];
    const poolData = {
      UserPoolId: CONFIG.UserPoolId,
      ClientId: CONFIG.ClientId,
    };
    const userData = {
      Username: username,
      Pool: new AmazonCognitoIdentity.CognitoUserPool(poolData),
    };
    const cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData);
    const authenticationData = {
      Username: username,
      Password: password,
    };
    const authenticationDetails =
      new AmazonCognitoIdentity.AuthenticationDetails(authenticationData);
    const totpMfaSettings = {
      PreferredMfa: true,
      Enabled: true,
    };
    // authenticate user
    cognitoUser.authenticateUser(authenticationDetails, {
      onSuccess: function (result) {
        var accessToken = result.getAccessToken().getJwtToken();
        console.info(accessToken);
        cognitoUser.getUserData((err, data) => {
          if (err) {
            alert(err.message || JSON.stringify(err));
            return;
          }
          const { PreferredMfaSetting } = data;
          if (PreferredMfaSetting != "SOFTWARE_TOKEN_MFA") {
            setupMFA();
          }
        });
      },
      newPasswordRequired: function () {
        console.info("Set your password again");
        cognitoUser.completeNewPasswordChallenge(password, {}, this);
      },
      totpRequired: function () {
        console.info("Need to set TOTP");
        let _this = this;
        let getValue = "Input code from Authenticator App";
        prompt.get([getValue], function (err, result) {
          var challengeAnswer = result[getValue];
          cognitoUser.sendMFACode(challengeAnswer, _this, "SOFTWARE_TOKEN_MFA");
        });
      },
      onFailure: function (err) {
        console.log(err.message || JSON.stringify(err));
      },
    });
    const setupMFA = () => {
      cognitoUser.associateSoftwareToken({
        associateSecretCode: function (secretCode) {
          console.info("AssociateSecretCode");
          console.info("Display QR Code");
          const url = `otpauth://totp/${username}?secret=${secretCode}&issuer=Cognito-TOTP-MFA`;
          console.info("Your secret Code: " + secretCode);
          qrcode.generate(url, { small: true });
          const getValue =
            "Open Authenticator App And Scan this image or enter manually";
          prompt.get([getValue], function (err, result) {
            challengeAnswer = result[getValue];
            cognitoUser.verifySoftwareToken(
              result[getValue],
              "My TOTP device",
              {
                onFailure: function (err) {
                  console.error(err.message || JSON.stringify(err));
                },
                onSuccess: function (result) {
                  console.info(result);
                  enableMFA();
                },
              }
            );
          });
        },
        onFailure: function (err) {
          console.error(err.message || JSON.stringify(err));
        },
      });
    };
    const enableMFA = () => {
      cognitoUser.setUserMfaPreference(
        null,
        totpMfaSettings,
        function (err, result) {
          if (err) {
            alert(err.message || JSON.stringify(err));
          }
          console.log("call result " + result);
        }
      );
    };
  });
};
main();
The result of code execution:
TOTP MFA considerations and limitations at currently
- AWS Coginito built-in UI currently does not support TOTP setup. Our application must provide this feature. After the user setups and verifies a TOTP software token in our application, they can input their passcode in the built-in UI.
 - AWS Coginito only supports software token MFA or SMS MFA. It does not support hardware-base MFA.
 
Thanks you for reading!
Document references: