Newbie struggling with 'resend verification email'

Based on the example here:

Customize Email Handling

my code looks like this:

function VerifyEmailButton() {
  const { user, getAccessTokenSilently } = useAuth0();

  const onVerificationEmail = async () => {

    var axios = require("axios").default;
    const domain = process.env.REACT_APP_AUTH0_DOMAIN;
    const clientId = process.env.REACT_APP_AUTH0_CLIENT_ID;
    const audience = process.env.REACT_APP_AUTH0_AUDIENCE;

    const { email } = user;
    const token = await getAccessTokenSilently();

    const url = `https://${domain}/api/v2/jobs/verification-email`;
    const authorization = `Bearer ${token}`;
    //const organization_id = 'blah';

    const options = {
      method: "POST",
      url: url,
      headers: {
        "content-type": "application/json",
        authorization: authorization,
      },
      data: {
        user_id: email,
        client_id: clientId,
        // audience: audience,
        identity: {
          user_id: "5457edea1b8f22891a000004",
          provider: "google-oauth2",
        },
        // organization_id: organization_id,
      },
    };
  axios
    .request(options)
    .then(function (response) {
      console.log(response.data);
    })
    .catch(function (error) {
      console.error(error);
    });
  };

  return (
    <button className="btn btn-primary btn-lg" onClick={onVerificationEmail}>
      Resend Email Verification
    </button>
  );
}

When it executes, I get 401, complaining about bad audience :

"{"statusCode":401,"error":"Unauthorized","message":"Bad audience: XXXXXX https://YYYYYYY.us.auth0.com/userinfo\“}”

I’m using my audience elsewhere, and it’s working, so I’m pretty confident I have the audience right, even though in the sample program audience isn’t used at all.

I’ve also tried adding ‘audience’ to ‘options | data’ (now commented out) but that didn’t help.

Hey @wiley!

I’m not entirely sure of your flow here, but you’re going to need to use a Management API Access Token which will have an audience of the identifier of your tenant’s Management API: https://YOUR_DOMAIN.us.auth0.com/api/v2/ in order to successfully hit the /api/v2/jobs/verification-email endpoint.

Hope this helps at least get you started in the right direction :slight_smile:

Trying to figure out how to do that in a SPA. The main article on that (Get Management API Access Tokens for Single-Page Applications) skips that detail (no explanation or links).

Hey @wiley you’ll basically need to use some sort of a proxy to make calls to the management API on behalf of your SPA app. If using the front end directly, there are strict limitations as outlined in the article you posted. This is a security precaution given the fact that it’s in the context of a public application - The following resources should help:

1 Like

I get that SPA’s have unique security concerns. But in the list of available scopes to SPA’s, ‘resend email verification’ is not listed, and I don’t get the security risk.

1 Like

That’s correct - The scope required is update:users which is not one of the scopes available to a SPA app requesting a Management API Token. This is where the proxy approach comes into play allowing that service to communicate with the Management API on behalf of your SPA app with a fully scoped access token.

1 Like

OK, limited privileges in SPAs makes sense. So I’ve moved it to my backend. Here’s my code:

  const myDomain = "https://MY_DOMAIN.us.auth0.com";
  const myClientId = "MANAGEMENT_API_CLIENT_ID";
  const myClientSecret = 'MANAGEMENT_API_CLIENT_SECRET';
  const myUserId = "auth0|A_USER_WITH_UNVERIFIED_EMAIL";

  // GET A TOKEN
  const url1 = `${myDomain}/oauth/token`;
  const headers1 = { "content-type": "application/json" };
  const body1 = {
    client_id: myClientId,
    client_secret: myClientSecret,
    audience: `${myDomain}/api/v2/`,
    grant_type: "client_credentials",
    //scope: 'update:users'   // I thought I needed this, but it generates an error (?)
  };
  let access_token;
  const res1 = await axios
    .post(url1, body1, headers1)
    .then((res) => {
      console.log(`Status1: ${res.status}`);
      console.log(`Body1:   ${res.data}`);
      access_token = res.data.access_token;
    })
    .catch((err) => {
      console.error(err);
      return;
    });

  // REQUEST RESEND VERIFICATION EMAIL
  const url2 = `${myDomain}/api/v2/jobs/verification-email`;
  const headers2 = {
    "Content-Type": "application/json",
    Authorization: `Bearer ${access_token}`,
  };
  const body2 = {
    user_id: myUserId,
  };
  const res2 = await axios
    .post(url2, body2, headers2)
    .then((res) => {
      console.log(`Status1: ${res.status}`);
      console.log(`Body1:   ${res.data}`);
    })
    .catch((err) => {
      console.error(err);
      return;
    });

In the Management API, I have enabled my backend to access the Management API.

When I execute my code, I do get a token, but when I do the ‘resend email verification’ call I get:
statusCode: 401,
error: ‘Unauthorized’,
message: ‘Missing authentication’

What am I missing?

HERE’S THE SOLUTION: See this working example:

Good idea! I apologize for the delayed response here, but thanks for sharing the blog post and confirming your findings with the community :slight_smile:

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.