Unable to update user's information

Hi Team,

I am new to auth0 and new to building an app for phones.

I have integrated auth0 into my project which is a react native application.

Therefore, I am currently utilizing a native project in here.

However, I did create a M2M to help me connect to API to make changes to users however I am getting an error "access_denied: {“error”:“access_denied”,“error_description”:"Client is not authorized to access "https://[URL-ACCESS]/api/v2/". You need to create a "client-grant" associated to this API. See: Auth0 Management API v2

here is the code I use, I am making a call from my server which is Node.js my front end is passing values React Native.

const express = require('express');
const { ManagementClient } = require('auth0');
const url = require('url');
const { authenticate } = require('./middlewares');
const axios = require('axios');
const auth0 = new ManagementClient({
  domain: process.env.AUTH0_DOMAIN,
  clientId: process.env.AUTH0_CLIENT_ID,
  clientSecret: process.env.AUTH0_CLIENT_SECRET,
  scope: 'read:users update:users'
});
const router = express.Router();

router.get('/authenticated', (req, res) => {
  res.send('You are authenticated!');
});

router.get('/admin', [authenticate, authenticate], (req, res) => {
  // You can add additional checks here to confirm the user has the 'admin' role.
  res.send('You are an admin!');
});


// Function to get Management API token
async function getManagementApiToken() {
  try {
    const response = await axios({
      method: 'POST',
      url: 'https://[URL-TOKEN]/oauth/token',
      headers: { 'content-type': 'application/json' },
      data: {
        client_id: process.env.M2M_CLIENT_ID,
        client_secret: process.env.M2M_CLIENT_SECRET,
        audience: '[AUDIENCE]/api/v2/',
        grant_type: 'client_credentials',
      },
    });

    return response.data.access_token;
  } catch (error) {
    console.error('Failed to get Management API token:', error);
    throw error;
  }
}

router.put('/update-profile', [authenticate], async (req, res) => {
  const { name, email, password, picture } = req.body;


  let managementApiToken;
  try {
    console.log('Getting Management API token...');
    managementApiToken = await getManagementApiToken();
    console.log('Got Management API token:', managementApiToken);

  } catch (error) {
    console.error('Failed to get Management API token:', error);
    return res.status(500).json({ error: 'Failed to update profile. Please try again.' });
  }

  // Validate name
  if (name && name.trim() === '') {
    return res.status(400).json({ error: 'Name cannot be empty.' });
  }

  // Validate email
  const emailRegex = /\S+@\S+\.\S+/;
  if (email && (!emailRegex.test(email))) {
    return res.status(400).json({ error: 'Invalid email.' });
  }

  // Validate password
  const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/;
  if (password && !passwordRegex.test(password)) {
    return res.status(400).json({ error: 'Password must be at least 8 characters long and contain at least one uppercase letter, one lowercase letter, one number, and one special character.' });
  }

  // Validate profile picture
  // If picture is provided, validate it (e.g., check it is a well-formed URL, and optionally that it points to a known good domain).
  if (picture && !url.parse(picture).hostname) {
    return res.status(400).json({ error: 'Invalid picture URL.' });
  }

  try {
    const userId = req.user.sub;
    const data = {};
    if (name) data.name = name;
    if (email) data.email = email;
    if (picture) data.picture = picture;
    if (password) data.password = password;

    // Update the user profile in Auth0
    await auth0.updateUser({ id: userId }, data, {
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${managementApiToken}`,
      },
    });

    res.status(200).json({ message: 'Profile updated successfully!' });
  } catch (error) {
    console.error('Failed to update profile:', error);
    console.error(error);
    res.status(500).json({ error: 'Failed to update profile. Please try again.' });
  }
});

module.exports = router;
1 Like

Hi @MaxK,

Welcome to the Auth0 Community!

After looking carefully at your code snippet I noticed that you have specified the scope: 'read:users update:users' when instantiating a new ManagementClient. I wanted to let you know that it’s not necessary to include these scopes there. Instead, you should assign these scopes to your Machine to Machine (M2M) applications in your API settings. By doing so, you’ll be able to authorize your M2M app with the appropriate read:users and update:users permissions.

Furthermore, when I explored your tenant settings, I came across two M2M applications with the same name. Interestingly, one of them isn’t associated with any API, while the other one is associated with the Management API and has all the required permissions. To ensure everything is working as intended, could you please double-check that the client_id and client_secret values are referring to the correct M2M app?

I look forward to your reply.

Thanks,
Rueben

Hi @rueben.tiow

Thank you for a welcome and a quick reply.

I have removed the scope per your suggestion and have double checked the M2M to be correct values.

I have also tested and validated all the jwt’s I get and everything seems correct.

Please let me know if any other information I can provide for your assistance.

Edit#1 Can you also confirm if I should be getting the management token or should I use the token passed from the front end?

Regards,
Max

1 Like

Resolved the issue.

Solution: Was using my native project clientId and secret instead of the M2M in the call. Therefore was getting an error

1 Like

Hi @MaxK,

Thank you for your responses.

I’m glad to hear that you were able to resolve the issue by using the correct client_id and client_secret values of your M2M application.

I can confirm that you must use the Management API Token. This token is used for making calls to update user information and performing administrative-related tasks.

Please let me know if there’s anything else I can do to help!

Thanks,
Rueben

1 Like

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