aws-amplify / amplify-js

A declarative JavaScript library for application development using cloud services.
https://docs.amplify.aws/lib/q/platform/js
Apache License 2.0
9.42k stars 2.12k forks source link

TOTP Setup and Useage with AWS Amplify Auth #5120

Closed richAtreides closed 3 years ago

richAtreides commented 4 years ago

Describe the bug The TOTP Setup and ConfirmSign in equivalents do not render

To Reproduce Implement the Authenticator Amplify-React Component and enable MFA in the user pool. The default state seems to be SMS and there seems to be no way to override this and set it to Soft Token MFA so that the user is prompted to set up Soft Token and once set up use it.

Expected behaviour If MFA is enabled it must be possible to specify this property and then for the child components of authenticator to appropriately render.

richAtreides commented 4 years ago

I'd like to add that I created a custom version of the confirmsignincomponent and this won't render. However my customised version of the signin component does render when passed to the authenticator component as a child.

Custom Sign In Component

import React from "react";
import Button from "@material-ui/core/Button";
import CssBaseline from "@material-ui/core/CssBaseline";
import Typography from "@material-ui/core/Typography";
import TextField from "@material-ui/core/TextField";
import { SignIn } from "aws-amplify-react";
import { ThemeProvider } from "@material-ui/core/styles";
import theme from "./theme";
import Container from "@material-ui/core/Container";
import useStyles from "./useStyles";

const classes = useStyles;

export default class CustomSignIn extends SignIn {
  constructor(props) {
    super(props);
    this._validAuthStates = ["signIn", "signedOut", "signedUp"];
  }

  showComponent() {
    return (
      <ThemeProvider theme={theme}>
        <Container component="main" maxWidth="xs">
          <CssBaseline />
          <div className={classes.login}>
            <Typography
              component="h1"
              variant="h5"
              align="center"
              color="primary"
            >
              Sign in to Atreides
            </Typography>
            <div className={classes.muiform}>
              <form className={classes.muiform} noValidate>
                <TextField
                  style={{ backgroundColor: "white" }}
                  variant="outlined"
                  margin="normal"
                  required
                  fullWidth
                  id="username"
                  name="username"
                  autoComplete="Email Address"
                  onChange={this.handleInputChange}
                />
                <TextField
                  style={{ backgroundColor: "white" }}
                  variant="outlined"
                  margin="normal"
                  required
                  fullWidth
                  name="password"
                  type="password"
                  id="password"
                  autoComplete="current-password"
                  onChange={this.handleInputChange}
                />{" "}
                <br></br>
                <br></br>
                <Button
                  type="button"
                  fullWidth
                  variant="contained"
                  color="primary"
                  className={classes.muisubmit}
                  onClick={() => super.signIn()}
                >
                  Sign In
                </Button>
                <br></br>
                <br></br>
                <Button
                  type="button"
                  fullWidth
                  variant="contained"
                  color="dark"
                  className={classes.muisubmit}
                  onClick={() => super.changeState("forgotPassword")}
                >
                  Forgot Password?
                </Button>
              </form>
            </div>
          </div>
        </Container>
      </ThemeProvider>
    );
  }
}

Custom Confirm Sign In Component

import React from 'react';
import Button from '@material-ui/core/Button';
import Typography from '@material-ui/core/Typography';
import CssBaseline from '@material-ui/core/CssBaseline';
import TextField from '@material-ui/core/TextField';
import Container from '@material-ui/core/Container';
import { ConfirmSignIn } from 'aws-amplify-react';
import { IAuthPieceProps } from 'aws-amplify-react/lib-esm/Auth/AuthPiece';
import useStyles from './useStyles';
import { ThemeProvider } from '@material-ui/core/styles';
import theme from './theme';

const classes = useStyles;
export default class AtreidesMFA extends ConfirmSignIn {
    constructor(props) {
        super(props);
        this._validAuthStates = ['ConfirmSignIn'];
        // this.state = {
        //  mfaType: 'TOTP',
        // };
    }

    showComponent() {
        return (
            <ThemeProvider theme={theme}>
                <Container component="main" maxWidth="xs">
                    <CssBaseline />
                    <div>testing if this is even rendering</div>
                    <div className={classes.login}>
                        <Typography component="h1" variant="h5" align="center" color="primary">
                            Please enter your MultiFactor Authentication Code
                        </Typography>
                        <div className={classes.muiform}>
                            <form className={classes.muiform} noValidate>
                                <TextField
                                    style={{ backgroundColor: 'white' }}
                                    variant="outlined"
                                    margin="normal"
                                    required
                                    fullWidth
                                    id="code"
                                    name="code"
                                    autoComplete="off"
                                    onChange={this.handleInputChange}
                                />
                                <Button
                                    type="button"
                                    fullWidth
                                    variant="contained"
                                    color="primary"
                                    className={classes.muisubmit}
                                    onClick={() => super.confirm()}
                                >
                                    Submit Code
                                </Button>
                            </form>
                        </div>
                    </div>
                </Container>
            </ThemeProvider>
        );
    }
}

I've also tried to set the default state as TOTP and this prevents the component tree even rendering when view in React Developer Tools in Chrome.

sammartinez commented 4 years ago

@richAtreides There is a similar issue related in Amplify CLI that I created in order to resolve this. We are currently discussing this internal with the Amazon Cognito team in order to resolve this issue. As far as a workaround, you will need to manually configure the Amazon Cognito User Pool and follow the Manual Setup process within our docs in order to have Amplify talk correctly to Amazon Cognito.

harrysolovay commented 3 years ago

@richAtreides have you tried changing the MFA method with Auth.setPreferredMFA ?

stale[bot] commented 3 years ago

This issue has been automatically closed because of inactivity. Please open a new issue if are still encountering problems.

github-actions[bot] commented 2 years ago

This issue has been automatically locked since there hasn't been any recent activity after it was closed. Please open a new issue for related bugs.

Looking for a help forum? We recommend joining the Amplify Community Discord server *-help channels or Discussions for those types of questions.