Sign Up Email Confirmation

Hello, do you have any guides how to make email confirmation during sing up process using auth0? Can I setup 2FA?

Hi there, this is our Auth0 8base guide: https://m.youtube.com/watch?v=IDpfnp5SDxQ

If you use hosted login with redirect, I believe there’s no reason you can’t implement 2FA. All 8base looks for is a valid ID token issued for the configured auth provider.

Please let us know if you run into trouble!

Okay, thanks, do you have any guide how to implement email confirmation during sing up process using auth0 plus 8base?

@SeeFirst
Сan suggests several options that can be implemented depending on your needs:

  1. implement all registration flow on your side
    For this, you need to add two resolvers
import { ManagementClient } from 'auth0';

export const auth0Management = new ManagementClient({
  domain: process.env.AUTH0_DOMAIN,
  clientId: process.env.AUTH0_M2M_CLIENT_ID,
  clientSecret: process.env.AUTH0_M2M_CLIENT_SECRET,
});

// -------------
// singUp resolver
const NOT_VERIFIED_ROLE_CODE = 'YOUR_NOT_VERIFIED_ROLE_CODE';

export const waitlistUserAdd = async (event, ctx) => {
  const eventData = event.data.data;

  await auth0Management.createUser({
    connection: process.env.AUTH0_CONNECTION,
    email: eventData.email,
    email_verified: false,
    password: eventData.password,
  });

  const { userCreate } = await ctx.api.gqlRequest(
    gql`
      mutation WaitlistUserAdd($data: UserCreateInput!) {
        userCreate(data: $data) {
          id
        }
      }
    `,
    {
      data: {
        email: eventData.email,
        firstName: eventData.firstName,
        username: eventData.username,
        lastName: eventData.lastName,
        roles: {
          connect: [
            {
              code: NOT_VERIFIED_ROLE_CODE,
            },
          ],
        },
        // some another user data
      },
    },
    {
      // need if you did not set create user permission
      checkPermissions: false,
    },
  );

  await ctx.invokeFunction('waitlistConfirmationSend', eventData.email, { waitForResponse: false });

  return {
    data: {
      success: !!userCreate.id,
    },
  };
};


// -------------
// verification email resolver
import jwt_decode from 'jwt-decode';

// verify resolver, called from app from email verification page
const VERIFIED_ROLE_CODE = 'YOUR_VERIFIED_ROLE_CODE';

export const verifyUser = async (event, ctx) => {
  const token = event.headers.token;

  const eventData = event.data.data;

  // you need set up permission for your NOT_VERIFIED_ROLE permission for update current user
  const { user } = await ctx.api.gqlRequest(
    gql`
      query User($email: String!) {
        user(email: $email) {
          id
          email
          firstName
          lastName
          # some another user data
        }
      }
    `,
    {
      email: eventData.email,
    },
  );

  // maybe add some validation

  const { sub: userId } = jwt_decode(token);

  try {
    auth0userResult = await auth0Management.updateUser(
      {
        id: userId,
      },
      { email_verified: true },
    );
  } catch (err) {
    console.error(err);

    throw err;
  }

  try {
    const { userUpdate } = await ctx.api.gqlRequest(
      gql`
        mutation UserUpdate($data: UserUpdateInput!) {
          userUpdate(data: $data) {
            id
          }
        }
      `,
      {
        data: {
          roles: {
            reconnect: [
              {
                code: VERIFIED_ROLE_CODE,
              },
            ],
          },
        },
      },
    );

    return userUpdate;
  } catch (err) {
    console.error(err);

    if (auth0userResult.user_id) {
      await auth0Management.updateUser({ id: auth0userResult.user_id }, { email_verified: false });
    }

    throw err;
  }
};

// -------------
// task sends verification mail with link to app
import sgMail from '@sendgrid/mail';

sgMail.setApiKey(process.env.SENDGRID_API_KEY);

export const waitlistConfirmationSend = async email => {
  const sgMailVars = {
    to: email,
    from: NOREPLY_FROM_ADDRESS,
    templateId: WAITLIST_CONFIRMATION_TEMPLATE_ID,
  };

  try {
    await sgMail.send(sgMailVars);
  } catch (err) {
    console.error(err, sgMailVars);
  }

  return {
    data: {
      success: true,
    },
  };
};

NOTE: not production code, just a sketch of the idea

  1. add auth0 webhook with a similar update user role logic as described above
    https://auth0.com/docs/extensions/auth0-authentication-api-webhooks

  2. add resolver with a similar update user role logic as described above on auth0 callback email verification page
    https://community.auth0.com/t/setting-an-email-verification-server-callback/7537/2

Are these options right for you?
or would you like to see more detailed examples?

Thanks, can you please share more detailed examples?

I have one more question, are there other ways (simplier) to implement email confirmation in my app?

I’ll provide an example in a couple of days.

the second and third options is equally easy in complexity, but there is less flexibility and more difficulty to maintain

if you describe your sign up flow in more detail, I can answer you. Because the implementation of the behavior is always almost the same.

1 - send mutation for singUp user from client-app to server
2 - send mail from server/auth0 to user
3 - user open client-app with link from email and send email verification request/mutation to server/auth0

Probably the easiest option is to leave the entire sign up flow on the auth0 side, and only create a user with a UserCreat mutation (with auth0 hook or rule)
and on the client-app side ask auth0 whether user mail is confirmed or not (or if I’m not mistaken, then in the token itself there is already this data)

Thanks, I have used 8base video guide how to sign up, I use mutation userSignUpWithPassword.

do you use custom auth0 authentication profiles, right?

No, I create custom profiles, I use 8base to communicate with auth0

this example is for the second option which I described in the first answer.

You need to change configs:
src/App.js - const API_ENDPOINT_URI = "YOUR"
src/authClient.js -

// TODO:
const AUTH0_CLIENT_ID = "YOUR";
const AUTH0_CLIENT_DOMAIN = "YOUR";
export const AUTH_PROFILE_ID = "YOUR";

auth0/onExecutePostUserRegistration.js-
do not forget to create a token at 8base for auth0

// TODO:
const ROLE_ID = "YOUR";
const API_TOKEN = "YOUR";
const API_ENDPOINT = "YOUR_API_ENDOINT";

and add post registration action to auth0 flow (auth0/onExecutePostUserRegistration file)


this is the most simpler way

if you want I can give you an option with userSignUpWithPassword mutations
just please, first see if this example works for you

feel free to ask

@SeeFirst
did you try the example I posted earlier?
can you share with your progress, please?

Hello, thanks, what part of code I need to take to use in flow? Via the React app email confiramtion will be sent?

auth0 sends the email itself if the user sign up from the auth0 universal login page

const AuthPage = () => {
  const { authClient } = useAuth();

  useEffect(() => {
    authClient.authorize();
  }, [authClient]);

  return <div>Loading (auth page) ...</div>;
};

this part of code sends users to the auth0 universal login page

What is this variable here? is it the authProfileID?


this is a missprint
it should be role.id or role.name

       roles: {
          connect: [
            {
              id: NOT_VERIFIED_ROLE_ID,
            },
          ],
        },
1 Like

Can you please provide instruction how to implement email confirmation for signUpWithPassword?

Hello!

We’re working on the update of useful examples on GitHub. This case will also be there. We’ll let you know when it’s ready.

Lada Kokotova | Technical SUpport Engineer

1 Like

Thanks, can you please tell an approximate time completing of these examples?