> ## Documentation Index
> Fetch the complete documentation index at: https://docs-dev-actions-triggers-prototype.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Describes how to test your custom database connections in Auth0 Dashboard.

# Test Custom Database Connections

If you use the Auth0-hosted database structure to store your users, you can test the connection by authenticating users against the same or a separate tenant.

## Test with import users to Auth0 enabled

When import users is enabled, users are gradually migrated from your external user store to Auth0 user store. In the process, users will be authenticated against the external store the first time they successfully log in. All further login attempts will be executed against the Auth0 user store. To learn more, read about automatic migrations in [Import and Export Users](/docs/manage-users/user-migration).

### Create a test tenant and application

1. Use the Auth0 Dashboard to [create a new tenant](/docs/get-started/auth0-overview/create-tenants).
2. Navigate to [Applications > Applications](https://manage.auth0.com/#/applications/applications) and create a [Machine-to-Machine](https://manage.auth0.com/#/applications/applications/create) application.

   <Warning>
     You need to note the **Client ID** and **Client Secret** when you create the custom database scripts. You need to note the **Client ID** to enable scopes in Management API.
   </Warning>
3. Enable both the **Password** and **Client Credential** grant for this application (both grants should be enabled for this test).

   <Frame>
     <img src="https://mintcdn.com/docs-dev-actions-triggers-prototype/8yG0sorggbq9bIbi/docs/images/cdy7uua7fh8z/4caAveuhYurCDb5F8mdImm/38496efe6f670d828542b02a56e5ca64/Grant_Types_-_English.png?fit=max&auto=format&n=8yG0sorggbq9bIbi&q=85&s=652e0b5d8d5b896ad687b167dffdaee7" alt="Auth0 Dashboard > Applications > Advanced Settings" data-og-width="1602" width="1602" data-og-height="794" height="794" data-path="docs/images/cdy7uua7fh8z/4caAveuhYurCDb5F8mdImm/38496efe6f670d828542b02a56e5ca64/Grant_Types_-_English.png" data-optimize="true" data-opv="3" srcset="https://mintcdn.com/docs-dev-actions-triggers-prototype/8yG0sorggbq9bIbi/docs/images/cdy7uua7fh8z/4caAveuhYurCDb5F8mdImm/38496efe6f670d828542b02a56e5ca64/Grant_Types_-_English.png?w=280&fit=max&auto=format&n=8yG0sorggbq9bIbi&q=85&s=ec1076dc02096a51ccac8e38d0f08783 280w, https://mintcdn.com/docs-dev-actions-triggers-prototype/8yG0sorggbq9bIbi/docs/images/cdy7uua7fh8z/4caAveuhYurCDb5F8mdImm/38496efe6f670d828542b02a56e5ca64/Grant_Types_-_English.png?w=560&fit=max&auto=format&n=8yG0sorggbq9bIbi&q=85&s=fb0338b6bc7b3d42ee704e70016d7cdf 560w, https://mintcdn.com/docs-dev-actions-triggers-prototype/8yG0sorggbq9bIbi/docs/images/cdy7uua7fh8z/4caAveuhYurCDb5F8mdImm/38496efe6f670d828542b02a56e5ca64/Grant_Types_-_English.png?w=840&fit=max&auto=format&n=8yG0sorggbq9bIbi&q=85&s=768090d43493e166bff31b5b092a6413 840w, https://mintcdn.com/docs-dev-actions-triggers-prototype/8yG0sorggbq9bIbi/docs/images/cdy7uua7fh8z/4caAveuhYurCDb5F8mdImm/38496efe6f670d828542b02a56e5ca64/Grant_Types_-_English.png?w=1100&fit=max&auto=format&n=8yG0sorggbq9bIbi&q=85&s=909366fa9c88002dc94fb6016fff8c51 1100w, https://mintcdn.com/docs-dev-actions-triggers-prototype/8yG0sorggbq9bIbi/docs/images/cdy7uua7fh8z/4caAveuhYurCDb5F8mdImm/38496efe6f670d828542b02a56e5ca64/Grant_Types_-_English.png?w=1650&fit=max&auto=format&n=8yG0sorggbq9bIbi&q=85&s=0805b0e5d0f1b3fc918d7682e2f1376f 1650w, https://mintcdn.com/docs-dev-actions-triggers-prototype/8yG0sorggbq9bIbi/docs/images/cdy7uua7fh8z/4caAveuhYurCDb5F8mdImm/38496efe6f670d828542b02a56e5ca64/Grant_Types_-_English.png?w=2500&fit=max&auto=format&n=8yG0sorggbq9bIbi&q=85&s=cd05082fe690296adf2e7432acb5635e 2500w" />
   </Frame>
4. To authorize your application, navigate to [Applications > APIs](https://manage.auth0.com/#/apis).
5. Select **Management API**.
6. Under the **Machine-to-Machine Applications** tab, use the toggle to authorize your test application.
7. Select the drop-down menu to enable the following Auth0 Management API scopes:

   * `read:users`
   * `update:users`
   * `delete:users`
   * `create:users`
   * `read:users_app_metadata`
   * `update:users_app_metadata`
   * `create:users_app_metadata`

     <Frame>
       <img src="https://mintcdn.com/docs-dev-actions-triggers-prototype/I9SBuhVKpyu444Ha/docs/images/cdy7uua7fh8z/2vW8zD1iIObuqb0i59yw77/c43bafa05b271a4343af51cb5c8ce1ce/2024-03-14_10-28-19.png?fit=max&auto=format&n=I9SBuhVKpyu444Ha&q=85&s=1e695c533072d0c78db3fb8cf5b10b88" alt="Auth0 Dashboard > APIs > Management API >  M2M Tab > App Permissions" data-og-width="950" width="950" data-og-height="504" height="504" data-path="docs/images/cdy7uua7fh8z/2vW8zD1iIObuqb0i59yw77/c43bafa05b271a4343af51cb5c8ce1ce/2024-03-14_10-28-19.png" data-optimize="true" data-opv="3" srcset="https://mintcdn.com/docs-dev-actions-triggers-prototype/I9SBuhVKpyu444Ha/docs/images/cdy7uua7fh8z/2vW8zD1iIObuqb0i59yw77/c43bafa05b271a4343af51cb5c8ce1ce/2024-03-14_10-28-19.png?w=280&fit=max&auto=format&n=I9SBuhVKpyu444Ha&q=85&s=09b7f69ec98566df8ba322214556d293 280w, https://mintcdn.com/docs-dev-actions-triggers-prototype/I9SBuhVKpyu444Ha/docs/images/cdy7uua7fh8z/2vW8zD1iIObuqb0i59yw77/c43bafa05b271a4343af51cb5c8ce1ce/2024-03-14_10-28-19.png?w=560&fit=max&auto=format&n=I9SBuhVKpyu444Ha&q=85&s=773c8c00effce3899435edf35d831246 560w, https://mintcdn.com/docs-dev-actions-triggers-prototype/I9SBuhVKpyu444Ha/docs/images/cdy7uua7fh8z/2vW8zD1iIObuqb0i59yw77/c43bafa05b271a4343af51cb5c8ce1ce/2024-03-14_10-28-19.png?w=840&fit=max&auto=format&n=I9SBuhVKpyu444Ha&q=85&s=ab1c5d1d795c8662436adb3f2c2bfce4 840w, https://mintcdn.com/docs-dev-actions-triggers-prototype/I9SBuhVKpyu444Ha/docs/images/cdy7uua7fh8z/2vW8zD1iIObuqb0i59yw77/c43bafa05b271a4343af51cb5c8ce1ce/2024-03-14_10-28-19.png?w=1100&fit=max&auto=format&n=I9SBuhVKpyu444Ha&q=85&s=6ec72aca2dbb34c9103c1a891a62abe5 1100w, https://mintcdn.com/docs-dev-actions-triggers-prototype/I9SBuhVKpyu444Ha/docs/images/cdy7uua7fh8z/2vW8zD1iIObuqb0i59yw77/c43bafa05b271a4343af51cb5c8ce1ce/2024-03-14_10-28-19.png?w=1650&fit=max&auto=format&n=I9SBuhVKpyu444Ha&q=85&s=7f800ed3a1520162acbee7d812adc711 1650w, https://mintcdn.com/docs-dev-actions-triggers-prototype/I9SBuhVKpyu444Ha/docs/images/cdy7uua7fh8z/2vW8zD1iIObuqb0i59yw77/c43bafa05b271a4343af51cb5c8ce1ce/2024-03-14_10-28-19.png?w=2500&fit=max&auto=format&n=I9SBuhVKpyu444Ha&q=85&s=9f023c7fd06370ebe9df2f41574cf082 2500w" />
     </Frame>

### Create test database connections

After you create a tenant and an application in Dashboard, create a source database connection and a target database connection.

1. Navigate to [Authentication > Database](https://manage.auth0.com/#/connections/database) to create a new database connection to be the source.
2. Name your test source connection, enable **Requires Username**, and select **Create**.

   <Callout icon="file-lines" color="#0EA5E9" iconType="regular">
     You can create users to use in your test by navigating to [User Management > Users](https://manage.auth0.com/#/users). Once you select **Create** **Users** and populate the necessary fields, select the source database under the **Connection** field.
   </Callout>
3. Create a second database to be the target with the same configuration from step 2.

   <Callout icon="file-lines" color="#0EA5E9" iconType="regular">
     You can set the **Password Policy** to **Non-empty password required** in both target and source databases so you can use simple passwords in your tests.
   </Callout>
4. In your target database, switch to the **Custom Database** view and toggle on **Use my own database**.

   <Callout icon="file-lines" color="#0EA5E9" iconType="regular">
     If you want to test using Organizations with your custom databases, enable **Context object in database scripts**.
   </Callout>
5. Switch to the **Settings** view and enable **Import Users to Auth0**.
6. Switch to the **Custom Database** view, and then locate the **Database settings** section. Add the following information from your source database created in step 1:

| Key               | Value                                                            |
| ----------------- | ---------------------------------------------------------------- |
| `client_id`       | Client ID of the application you created.                        |
| `client_secret`   | Client Secret of the application you created.                    |
| `auth0_domain`    | Your tenant name in the Auth0 domain: `yourTenant.us.auth0.com`. |
| `source_database` | Name of the source connection.                                   |

7. Update the [Login](/docs/authenticate/database-connections/custom-db/test-custom-database-connections#login) and [Get User](/docs/authenticate/database-connections/custom-db/test-custom-database-connections#get-user) database action scripts in your target database. To learn more about best practices using database action scripts, read [Custom Database Connection and Action Scripts Best Practices](/docs/authenticate/database-connections/custom-db/custom-database-connections-scripts).
8. Select **Save and Try** on each script. You should monitor Actions Real-time Logs `console.log` output. To learn more, read [Actions Real-time Logs](/docs/customize/actions/actions-real-time-logs).
9. Select **Try Connection** to test the connection live.

## Test without Import Users enabled

1. Repeat steps in [Create a test tenant and application](/docs/authenticate/database-connections/custom-db/test-custom-database-connections#create-a-test-tenant-and-application).
2. Create one test database connection.
3. Make sure **Import Users to Auth0** under your source database settings is disabled. Users will authenticate against the external user store during each login attempt.
4. Update all database actions scripts with the samples below.

### Get User script

The [Get User](/docs/authenticate/database-connections/custom-db/templates/get-user) script implements an executable function that determines the current state of a user.

When **Import Users to Auth0** is enabled, the Get User script runs when a user attempts to sign up to check if the user already exists in the external user store.

The Get User script also runs when a user attempts to:

* Change a user's email address ([Change Email](/docs/authenticate/database-connections/custom-db/templates/change-email) script)
* Log in ([Login](/docs/authenticate/database-connections/custom-db/templates/login) script)
* Change a user's password ([Change Password](/docs/authenticate/database-connections/custom-db/templates/change-password) script)

When **Import Users to Auth0** is disabled, the Get User script runs when a user attempts to sign up to check if the user already exists in the external user store. If a user already exists in the external user store, it will not execute the Create script.

The Get User script also runs when a user attempts to:

* Create a user ([Create](/docs/authenticate/database-connections/custom-db/templates/create) script)
* Change a user's email address ([Change Email](/docs/authenticate/database-connections/custom-db/templates/change-email) script)
* Change a user's password ([Change Password](/docs/authenticate/database-connections/custom-db/templates/change-password) script)

#### Example

```js lines expandable theme={null}
async function getUser(user, context, callback) {
    log(`Script started.`);
    log(`Requesting an Access Token from "${configuration.auth0_domain}".`);
    let accessToken = await getAccessToken();
    accessToken = accessToken.access_token;
    if (!accessToken) return log(`Failed to get an Access Token from "${configuration.auth0_domain}".`, true);
    log(`The Access Token is available. Searching for user "${user}" in "${configuration.source_database}"`);
    user = user.toLowerCase();
    const searchQuery = encodeURI(`identities.connection:"${configuration.source_database}"+AND+(email:${user} OR username:${user})`);
    var options = {
        method: `GET`,
        url: `https://${configuration.auth0_domain}/api/v2/users?q=${searchQuery}`,
        headers: {
            Authorization: `Bearer ${accessToken}`,
        }
    };
    request(options, function (error, response) {
        if (error) return log(`Cannot connect to "${configuration.source_database}" database.`, true);
        let search_results = JSON.parse(response.body);
        let profile = null;
        if (search_results.length > 0) {
            log(`A user "${user}" is FOUND in "${configuration.source_database}" database.`);
            profile = {
                user_id: search_results[0].user_id.toString(),
                nickname: search_results[0].nickname,
                username: search_results[0].username,
                email: search_results[0].email
            };
        } else {
            log(`A user "${user}" is NOT FOUND in "${configuration.source_database}" database.`);
        }
        log(`Script completed!`);
        return callback(null, profile);
    });
    /* -- GET ACCESS TOKEN VIA CLIENT CREDENTIALS -- */
    async function getAccessToken() {
        var options = {
            method: `POST`,
            url: `https://${configuration.auth0_domain}/oauth/token`,
            headers: {
                "Content-Type": `application/x-www-form-urlencoded`,
            },
            form: {
                grant_type: `client_credentials`,
                client_id: configuration.client_id,
                client_secret: configuration.client_secret,
                audience: `https://${configuration.auth0_domain}/api/v2/`
            },
            json: true
        };
        return new Promise(function (resolve) {
            request(options, function (error, response) {
                resolve(error || response.body);
            });
        });
    }
    /* -- LOGGING -- */
    function log(message, error = false) {
        const script_name = `GET USER`;
        const error_label = error ? `(ERROR)` : ``;
        const return_message = `${script_name}: ${error_label} ${message}`;
        console.log(return_message);
        if (error) return callback(new Error(return_message));
    }
}
```

### Login script

The [Login](/docs/authenticate/database-connections/custom-db/templates/login) script implements an executable function that authenticates a user when a user logs in. If the user exists in the target database (Auth0), it authenticates them using that record. Otherwise, it authenticates the user with their record in the source database (external).

#### Example

```javascript lines expandable theme={null}
function login(usernameOrEmail, password, context, callback) {
  log(`Script started.`);
  const jwt = require('jsonwebtoken');
  const options = {
    method: `POST`,
    url: `https://${configuration.auth0_domain}/oauth/token`,
    headers: { "Content-Type": `application/x-www-form-urlencoded` },
    json: true,
    form: {
      grant_type: `http://auth0.com/oauth/grant-type/password-realm`,
      client_id: configuration.client_id,
      client_secret: configuration.client_secret,
      username: usernameOrEmail,
      password: password,
      realm: `${configuration.source_database}`
    }
  };
  request(options, function (error, response, body) {
    log(`Attempting to authenticate a user "${usernameOrEmail}" against "${configuration.source_database}" database in "${configuration.auth0_domain}" tenant.`);
    if (error) return log(`Cannot connect to "${configuration.auth0_domain}" database.`, true);
    if (response.statusCode !== 200) {
      console.log(`LOGIN: (ERROR) ${response.body.error_description}`);
      return callback(new WrongUsernameOrPasswordError(usernameOrEmail, `LOGIN: (ERROR) ${response.body.error_description}`));
    }
    log(`Successfuly authenticated user "${usernameOrEmail}" against "${configuration.source_database}" database in "${configuration.auth0_domain}" tenant.`);
    const decoded_id_token = jwt.decode(body.id_token);
    const profile = {
      user_id: decoded_id_token.sub,
      nickname: decoded_id_token.nickname,
      username: decoded_id_token.username,
      email: decoded_id_token.email
    };
    log(`Script completed.`);
    return callback(null, profile);
  });
  /* -- LOGGING -- */
  function log(message, error = false) {
    const script_name = `LOGIN`;
    const error_label = error ? `(ERROR)` : ``;
    const return_message = `${script_name}: ${error_label} ${message}`;
    console.log(return_message);
    if (error) return callback(new Error(return_message));
  }
}
```

### Create script

The [Create script](/docs/authenticate/database-connections/custom-db/templates/create) implements an executable function that creates a corresponding user record in the external database when a user signs up through <Tooltip tip="Universal Login: Your application redirects to Universal Login, hosted on Auth0's Authorization Server, to verify a user's identity." cta="View Glossary" href="/docs/glossary?term=Universal+Login">Universal Login</Tooltip>, or is created in the <Tooltip tip="Universal Login: Your application redirects to Universal Login, hosted on Auth0's Authorization Server, to verify a user's identity." cta="View Glossary" href="/docs/glossary?term=Auth0+Dashboard">Auth0 Dashboard</Tooltip> or with the Auth0 <Tooltip tip="Management API: A product to allow customers to perform administrative tasks." cta="View Glossary" href="/docs/glossary?term=Management+API">Management API</Tooltip>.

#### Example

```js lines expandable theme={null}
async function create(user, context, callback) {
  log(`Script started.`);
  log(`Requesting an Access Token from "${configuration.auth0_domain}".`);
  let accessToken = await getAccessToken();
  if (!accessToken.access_token) return log(`Failed to get an Access Token from "${configuration.auth0_domain}".`, true);
  accessToken = accessToken.access_token;
  log(`The Access Token is available. Attempting to create a user "${user.email}" in "${configuration.source_database}"`);
  const options = {
    method: `POST`,
    url: `https://${configuration.auth0_domain}/api/v2/users`,
    headers: {
      Authorization: `Bearer ${accessToken}`,
      "Content-Type": `application/x-www-form-urlencoded`
    },
    form: {
      connection: configuration.source_database,
      email: user.email,
      password: user.password,
      username: user.username
    },
    json: true
  };
  request(options, function (error, response) {
    if (error) return log(`Cannot connect to "${configuration.source_database}" database.`, true);
    switch (response.statusCode) {
      case 201:
        log(`The user "${user.email}" is successfuly created in "${configuration.source_database}" database.`);
        return callback(null);
      case 409:
        return callback(new ValidationError(`user_exists`, `The user already exists in "${configuration.source_database}" database.`));
      default:
        return log(`Failed to create a user "${user.email}" in "${configuration.source_database}" database. Error: "${response.statusCode}, ${response.body.message}"`, true);
    }
  });
  /* -- GET ACCESS TOKEN VIA CLIENT CREDENTIALS -- */
  async function getAccessToken() {
    var options = {
      method: `POST`,
      url: `https://${configuration.auth0_domain}/oauth/token`,
      headers: {
        "Content-Type": `application/x-www-form-urlencoded`,
      },
      form: {
        grant_type: `client_credentials`,
        client_id: configuration.client_id,
        client_secret: configuration.client_secret,
        audience: `https://${configuration.auth0_domain}/api/v2/`
      },
      json: true
    };
    return new Promise(function (resolve) {
      request(options, function (error, response) {
        resolve(error || response.body);
      });
    });
  }
  /* -- LOGGING -- */
  function log(message, error = false) {
    const script_name = `CREATE`;
    const error_label = error ? `(ERROR)` : ``;
    const return_message = `${script_name}: ${error_label} ${message}`;
    console.log(return_message);
    if (error) return callback(new Error(return_message));
  }
}
```

### Delete script

The [Delete script](/docs/authenticate/database-connections/custom-db/templates/delete) implements an executable function that deletes a user from Auth0 and the external database in the same operation when a user is deleted in the Auth0 Dashboard or with the Auth0 Management API.

#### Example

```js lines expandable theme={null}
async function deleteUser(user, context, callback) {
  log(`Script started.`);
  log(`Requesting an Access Token from "${configuration.auth0_domain}".`);
  let accessToken = await getAccessToken();
  if (!accessToken.access_token) return log(`Failed to get an Access Token from "${configuration.auth0_domain}".`, true);
  accessToken = accessToken.access_token;
  log(`The Access Token is available. Attempting to delete a user "${user}" from "${configuration.source_database}"`);
  const options = {
    method: `DELETE`,
    url: `https://${configuration.auth0_domain}/api/v2/users/${user}`,
    headers: {
      Authorization: `Bearer ${accessToken}`,
      "Content-Type": `application/x-www-form-urlencoded`
    },
    json: true
  };
  request(options, function (error, response) {
    if (error) return log(`Cannot connect to "${configuration.source_database}" database.`, true);
    switch (response.statusCode) {
      case 204:
        log(`The user "${user}" is successfuly deleted from "${configuration.source_database}" database.`);
        return callback(null);
      default:
        return log(`Failed to delete a user "${user}" from "${configuration.source_database}" database. Error: "${response.statusCode}, ${response.body.message}"`, true);
    }
  });
  /* -- GET ACCESS TOKEN VIA CLIENT CREDENTIALS -- */
  async function getAccessToken() {
    var options = {
      method: `POST`,
      url: `https://${configuration.auth0_domain}/oauth/token`,
      headers: {
        "Content-Type": `application/x-www-form-urlencoded`,
      },
      form: {
        grant_type: `client_credentials`,
        client_id: configuration.client_id,
        client_secret: configuration.client_secret,
        audience: `https://${configuration.auth0_domain}/api/v2/`
      },
      json: true
    };
    return new Promise(function (resolve) {
      request(options, function (error, response) {
        resolve(error || response.body);
      });
    });
  }
  /* -- LOGGING -- */
  function log(message, error = false) {
    const script_name = `DELETE`;
    const error_label = error ? `(ERROR)` : ``;
    const return_message = `${script_name}: ${error_label} ${message}`;
    console.log(return_message);
    if (error) return callback(new Error(return_message));
  }
}
```

### Verify script

The [Verify script](/docs/authenticate/database-connections/custom-db/templates/verify) implements an executable function that marks the verification status of a user’s email address in the external database when a user clicks on the link in the verification email sent by Auth0.

#### Example

```js lines expandable theme={null}
async function verify(user, context, callback) {
  log(`Script started.`);
  log(`Requesting an Access Token from "${configuration.auth0_domain}".`);
  let accessToken = await getAccessToken();
  if (!accessToken.access_token) return log(`Failed to get an Access Token from "${configuration.auth0_domain}".`, true);
  accessToken = accessToken.access_token;
  log(`The Access Token is available. Searching for user "${user}" in "${configuration.source_database}"`);
  user = user.toLowerCase();
  const searchQuery = encodeURI(`identities.connection:"${configuration.source_database}"+AND+(email:${user} OR username:${user})`);
  var options = {
    method: `GET`,
    url: `https://${configuration.auth0_domain}/api/v2/users?q=${searchQuery}`,
    headers: {
      Authorization: `Bearer ${accessToken}`,
    }
  };
  request(options, function (error, response) {
    if (error) return log(`Cannot connect to "${configuration.source_database}" database.`, true);
    let search_results = JSON.parse(response.body);
    if (search_results.length > 0) {
      log(`A user "${user}" is found in "${configuration.source_database}" database.`);
      const user_id = search_results[0].user_id.toString();
      log(`Attempting to mark user "${user_id}" as verified in "${configuration.source_database}" database`);
      const options = {
        method: `PATCH`,
        url: `https://${configuration.auth0_domain}/api/v2/users/${user_id}`,
        headers: {
          Authorization: `Bearer ${accessToken}`,
          "Content-Type": `application/x-www-form-urlencoded`
        },
        form: {
          email_verified: true,
        },
        json: true
      };
      request(options, function (error, response) {
        if (error) return log(`Cannot connect to "${configuration.source_database}" database.`, true);
        switch (response.statusCode) {
          case 200:
            log(`The user "${user}" is marked as verified in "${configuration.source_database}" database.`);
            return callback(null, true);
          default:
            return log(`Failed to mark a user "${user}" as verified in "${configuration.source_database}" database. Error: "${response.statusCode}, ${response.body.message}"`, true);
        }
      });
    } else {
      log(`A user "${user}" is not found in "${configuration.source_database}" database. Unable to verify.`, true);
    }
  });
  /* -- GET ACCESS TOKEN VIA CLIENT CREDENTIALS -- */
  async function getAccessToken() {
    var options = {
      method: `POST`,
      url: `https://${configuration.auth0_domain}/oauth/token`,
      headers: {
        "Content-Type": `application/x-www-form-urlencoded`,
      },
      form: {
        grant_type: `client_credentials`,
        client_id: configuration.client_id,
        client_secret: configuration.client_secret,
        audience: `https://${configuration.auth0_domain}/api/v2/`
      },
      json: true
    };
    return new Promise(function (resolve) {
      request(options, function (error, response) {
        resolve(error || response.body);
      });
    });
  }
  /* -- LOGGING -- */
  function log(message, error = false) {
    const script_name = `VERIFY`;
    const error_label = error ? `(ERROR)` : ``;
    const return_message = `${script_name}: ${error_label} ${message}`;
    console.log(return_message);
    if (error) return callback(new Error(return_message));
  }
}
```

### Change Password script

The [Change Password script](/docs/authenticate/database-connections/custom-db/templates/change-password) implements an executable function that updates a user's password in the external database when a password change workflow starts from the Auth0 Dashboard or the Auth0 Management API.

#### Example

```js lines expandable theme={null}
async function changePassword(user, newPassword, context, callback) {
  log(`Script started.`);
  log(`Requesting an Access Token from "${configuration.auth0_domain}".`);
  let accessToken = await getAccessToken();
  if (!accessToken.access_token) return log(`Failed to get an Access Token from "${configuration.auth0_domain}".`, true);
  accessToken = accessToken.access_token;
  log(`The Access Token is available. Searching for user "${user}" in "${configuration.source_database}" database.`);
  user = user.toLowerCase();
  const searchQuery = encodeURI(`identities.connection:"${configuration.source_database}"+AND+(email:${user} OR username:${user})`);
  var options = {
    method: `GET`,
    url: `https://${configuration.auth0_domain}/api/v2/users?q=${searchQuery}`,
    headers: {
      Authorization: `Bearer ${accessToken}`,
    }
  };
  request(options, function (error, response) {
    if (error) return log(`Cannot connect to "${configuration.source_database}" database.`, true);
    let search_results = JSON.parse(response.body);
    if (search_results.length > 0) {
      log(`A user "${user}" is found in "${configuration.source_database}" database.`);
      const user_id = search_results[0].user_id.toString();
      log(`Attempting to change password for user "${user_id}" in "${configuration.source_database}" database.`);
      const options = {
        method: `PATCH`,
        url: `https://${configuration.auth0_domain}/api/v2/users/${user_id}`,
        headers: {
          Authorization: `Bearer ${accessToken}`,
          "Content-Type": `application/x-www-form-urlencoded`
        },
        form: {
          password: newPassword,
        },
        json: true
      };
      request(options, function (error, response) {
        if (error) return log(`Cannot connect to "${configuration.source_database}" database.`, true);
        switch (response.statusCode) {
          case 200:
            log(`The user "${user}" password successfully changed in "${configuration.source_database}" database.`);
            return callback(null, true);
          default:
            return log(`Failed to change password for "${user}"  in "${configuration.source_database}" database. Error: "${response.statusCode}, ${response.body.message}"`, true);
        }
      });
    } else {
      log(`A user "${user}" is not found in "${configuration.source_database}" database. Unable to change password.`, true);
    }
  });
  /* -- GET ACCESS TOKEN VIA CLIENT CREDENTIALS -- */
  async function getAccessToken() {
    var options = {
      method: `POST`,
      url: `https://${configuration.auth0_domain}/oauth/token`,
      headers: {
        "Content-Type": `application/x-www-form-urlencoded`,
      },
      form: {
        grant_type: `client_credentials`,
        client_id: configuration.client_id,
        client_secret: configuration.client_secret,
        audience: `https://${configuration.auth0_domain}/api/v2/`
      },
      json: true
    };
    return new Promise(function (resolve) {
      request(options, function (error, response) {
        resolve(error || response.body);
      });
    });
  }
  /* -- LOGGING -- */
  function log(message, error = false) {
    const script_name = `CHANGE PASSWORD`;
    const error_label = error ? `(ERROR)` : ``;
    const return_message = `${script_name}: ${error_label} ${message}`;
    console.log(return_message);
    if (error) return callback(new Error(return_message));
  }
}
```

### Change Email script

The [Change Email](/docs/authenticate/database-connections/custom-db/templates/change-email) script implements an executable function that updates a user's email address when the user changes their email address or their email address verification status.

This script is not available in the Auth0 Dashboard. You must call the Management API [Update a connection](https://auth0.com/docs/api/management/v2/connections/patch-connections-by-id) endpoint and provide the `options.customScripts.change_email` property.

#### Example

```js lines expandable theme={null}
async function changeEmail(user, newEmail, verified, callback) {
  log(`Script started.`);
  log(`Requesting an Access Token from "${configuration.auth0_domain}".`);
  let accessToken = await getAccessToken();
  if (!accessToken.access_token) return log(`Failed to get an Access Token from "${configuration.auth0_domain}".`, true);
  accessToken = accessToken.access_token;
  log(`The Access Token is available. Searching for user "${user}" in "${configuration.source_database}" database.`);
  user = user.toLowerCase();
  const searchQuery = encodeURI(`identities.connection:"${configuration.source_database}"+AND+(email:${user} OR username:${user})`);
  var options = {
    method: `GET`,
    url: `https://${configuration.auth0_domain}/api/v2/users?q=${searchQuery}`,
    headers: {
      Authorization: `Bearer ${accessToken}`,
    }
  };
  request(options, function (error, response) {
    if (error) return log(`Cannot connect to "${configuration.source_database}" database.`, true);
    let search_results = JSON.parse(response.body);
    if (search_results.length > 0) {
      log(`A user "${user}" is found in "${configuration.source_database}" database.`);
      const user_id = search_results[0].user_id.toString();
      log(`Attempting to change email / verified status for user "${user_id}" in "${configuration.source_database}" database.`);
      const options = {
        method: `PATCH`,
        url: `https://${configuration.auth0_domain}/api/v2/users/${user_id}`,
        headers: {
          Authorization: `Bearer ${accessToken}`,
          "Content-Type": `application/x-www-form-urlencoded`
        },
        form: {
          email: newEmail,
          email_verified: verified || false
        },
        json: true
      };
      request(options, function (error, response) {
        if (error) return log(`Cannot connect to "${configuration.source_database}" database.`, true);
        switch (response.statusCode) {
          case 200:
            log(`The user "${user}" email / verified status successfully changed in "${configuration.source_database}" database.`);
            return callback(null, true);
          default:
            return log(`Failed to change email / verified status for "${user}"  in "${configuration.source_database}" database. Error: "${response.statusCode}, ${response.body.message}"`, true);
        }
      });
    } else {
      log(`A user "${user}" is not found in "${configuration.source_database}" database. Unable to change email / verified status.`, true);
    }
  });
  /* -- GET ACCESS TOKEN VIA CLIENT CREDENTIALS -- */
  async function getAccessToken() {
    var options = {
      method: `POST`,
      url: `https://${configuration.auth0_domain}/oauth/token`,
      headers: {
        "Content-Type": `application/x-www-form-urlencoded`,
      },
      form: {
        grant_type: `client_credentials`,
        client_id: configuration.client_id,
        client_secret: configuration.client_secret,
        audience: `https://${configuration.auth0_domain}/api/v2/`
      },
      json: true
    };
    return new Promise(function (resolve) {
      request(options, function (error, response) {
        resolve(error || response.body);
      });
    });
  }
  /* -- LOGGING -- */
  function log(message, error = false) {
    const script_name = `CHANGE EMAIL`;
    const error_label = error ? `(ERROR)` : ``;
    const return_message = `${script_name}: ${error_label} ${message}`;
    console.log(return_message);
    if (error) return callback(new Error(return_message));
  }
}
```

## Learn more

* [Password Strength in Auth0 Database Connections](/docs/authenticate/database-connections/password-strength)
* [Custom Database Action Script Environment Best Practices](/docs/authenticate/database-connections/custom-db/custom-database-connections-scripts/environment)
* [Password Options in Auth0 Database Connections](/docs/authenticate/database-connections/password-options)
* [Configure Identity Provider Connection for User Profile Updates](/docs/manage-users/user-accounts/user-profiles/configure-connection-sync-with-auth0)
* [Connection Settings Best Practices](/docs/authenticate/connection-settings-best-practices)
* [Create Custom Database Connections](/docs/authenticate/database-connections/custom-db/create-db-connection)
