Signup with AWS Cognito

You would need to double check this but e.message === 'User is already confirmed.' is one way to check. I think Amplify will be standardizing these errors at some point but you can use this for now.

Hmm, that won’t work since the initial e.name is already “UsernameExistsException”. Isn’t there a way to check the status of UNCONFIRMED by using this.state.email ?

Yeah I’ve used something like this in the past.

When calling Auth.resendSignUp check for the error to match this condition (e.name === 'InvalidParameterException' && e.message === 'User is already confirmed.'). This will tell you that the user with that email is already confirmed.

Is that what you are looking for?

Is there something I can use in the API that doesn’t involve e? Like a method of some sort?

I’m actually not sure. A good place to ask is the AWS Amplify Gitter. If you do find out, please report back!

Why does e in catch block have an inconsistent type?

Its type is string if we catch it from await Auth.signIn().
However, it is object type containing a message property when we catch it from await Auth.signUp() and await Auth.confirmSignUp().

The errors that Amplify throws aren’t great. But for Auth.signIn, we are doing e.message as well right?

Do we have a typo in one of the chapters?

Sorry, It’s my typo. I mean the error that is thrown from Auth.currentSession() is a string type. Is it the Amplify creators’ intention?

I’m not sure if it is but the errors aren’t really standardized. :frowning:

Can I refactor the code to make the confirmation code form be shared with the sign in page? because the user might not verify the account on sign up,(he might of refreshed the page on confirmation page and lost the page), and when he try to sign in, if the account is not confirmed yet he will be able to submit the code again.

Another issue would be how to handle the refresh part on the confirmation page, i did not get that?

We briefly talk about that in the chapter.

  1. Check for the UsernameExistsException in the handleSubmit method’s catch block.
  2. Use the Auth.resendSignUp() method to resend the code if the user has not been previously confirmed. Here is a link to the Amplify API docs.
  3. Confirm the code just as we did before.

So basically let it fail and then resend the code from before.

How about the form that user is suppose to fill? Its disappearing if a refresh happens, so i want the user to be able to fill once they tried to sign in, i understand how to resend the code, but its where to fill the next time?

Kind regards,
Khaled

It’s pretty much the same flow as before, after you call resendSignUp() you show the form to input the code.

Great tutorial. I am working on creating an admin area that includes a user sign-up page that admins fill out. What I’d like to do is have the user presented with confirmation form on first login. From the other comments and feedback I have restructured my “handleSubmit” function on the login page to look like this:

handleSubmit = async e => {
    const { email, password } = this.state;
    e.preventDefault();

    this.setState({ isLoading: true });

    try {
      await Auth.signIn(email, password);
      this.props.userHasAuthenticated(true);
    } catch (e) {
      if (e.message === 'User is not confirmed.') {
        **// I'm stuck on what to put here** 
      }
      // alert(e.message);
      this.setState({ isLoading: false });
    }
  };

Note the if statement I am stuck on what to do there. I want to render a confirmation form but I have tried

this.props.history.push('/confirmation');

This redirected to a page that has the following code:

import React, { Component } from 'react';
import { Auth } from 'aws-amplify';  
import { Form } from 'react-bootstrap';
import LoaderButton from '../components/LoaderButton';

export default class ConfirmationPage extends Component {
  constructor(props) {
    super(props);

    this.state = {
      isLoading: false,
      email: '',
      password: '',
      confirmationCode: ''
    };
  }

  validateConfirmationForm() {
    const { confirmationCode } = this.state;
    return confirmationCode.length > 0;
  }

  handleChange = e => {
    this.setState({
      [e.target.id]: e.target.value
    });
  };

  handleConfirmationSubmit = async e => {
    const { email, password, confirmationCode } = this.state;
    e.preventDefault();

    this.setState({ isLoading: true });

    try {
      await Auth.confirmSignUp(email, confirmationCode);
      await Auth.signIn(email, password);
      this.props.userHasAuthenticated(true);
      this.props.history.push('/');
    } catch (e) {
      alert(e.message);
      this.setState({ isLoading: false });
    }
  };

  render() {
    const { confirmationCode, isLoading } = this.state;
    return (
      <form onSubmit={this.handleConfirmationSubmit}>
        <Form.Group controlId="confirmationCode">
          <Form.Label>Confirmation Code</Form.Label>
          <Form.Control
            autoFocus
            type="tel"
            value={confirmationCode}
            onChange={this.handleChange}
          />
          <Form.Text>Please check your email for the code.</Form.Text>
        </Form.Group>
        <LoaderButton
          block
          disabled={!this.validateConfirmationForm()}
          type="submit"
          isLoading={isLoading}
          text="Verify"
          loadingText="Verifying..."
        />
      </form>
    );
  }
}

Thanks for any guidance.

If you just want to render a confirmation form in place, the best way would be to create a a state variable and set it this.setState({ showConfirmationForm: true });.

Then in your render() method, display the confirmation form if that variable is set.

But your redirect should be fine as well right? Whats the issue you are running into?

Hi
What is the best way to allow created users to create new users? The typical use case is in a multi-tenancy environment where a user registers his/her organisation and then add users with different roles inside the organisation.

One option could be to call adminCreateUser using the AWS SDK from a lambda. I have attempted this but without success.

Any thoughts/examples will be appreciated.

The adminCreateUser needs to be called inside a Lambda function, so it can use your credentials as opposed to the logged in user

@christensen143 did you resolve this? I am trying to figure out how to best allow a user to verify their email address if they abandoned the first time they were prompted. So I need to figure out how to get them back to the prompt.

Has anyone implemented a sign-up page like the one outlined in this tutorial but with OAuth options as well (e.g. Google, Facebook)? If so I would love help in doing so.

We do have an extra credit chapter on Facebook logins - https://serverless-stack.com/chapters/facebook-login-with-cognito-using-aws-amplify.html

But we don’t have one for Google. Let me know if you want to help contribute for that!