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

# Verify Database Action Script and Templates

> The Verify script runs when a user follows the link in Auth0's verification email.

The Verify script implements the function executed to mark the verification status of a user’s email address in an external database. We recommend naming this function `verify`.

This script is only used in legacy authentication scenarios, and is required to support user email address verification. A verified email address is critical to a number of workflow scenarios in Auth0, and implementing this script will provide support for these out of the box.

If it's enabled, this script is executed when a user clicks on the link in the verification email sent by Auth0.

## Verify function

The `verify` function should:

* Update the `email_verified` (or equivalent) attribute in the user's profile in the external database.
* Return `true` if the update action succeeded.
* Return an error if the update action failed.

### Definition

The `verify` function accepts two parameters and returns a `callback` function:

```js theme={null}
verify(email, callback): function
```

| Parameter  | Type     | Description                                              |
| ---------- | -------- | -------------------------------------------------------- |
| `email`    | String   | User's email address.                                    |
| `callback` | Function | Used to pass error or profile data through the pipeline. |

This is a pseudo-JavaScript example of how you could implement the `login` function:

```javascript lines theme={null}
function verify(email, callback) {
  // Send email to external database API
  let options = {
    url: "https://example.com/api/verify",
    body: {
      email: email
    }
  };

  send(options, (err) => {
    // Return error in callback if update failed
    if (err) {
      return callback(new Error(email, "My custom error message."));
    } else {
      // Return true in callback if update succeeded
      return callback(null, true);
    }
  });
}
```

## Callback function

The `callback` function is used to pass user profile data or error data through the pipeline.

### Definition

The `callback` function accepts up to two parameters and returns a function:

```js theme={null}
callback(error, [verified]): function
```

| Parameter  | Type    | Required | Description                                                                                                                                       |
| ---------- | ------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `error`    | Object  | Required | Contains error data.                                                                                                                              |
| `verified` | Boolean | Optional | Contains value that represents the user's verification status in the external database (`true` or `false`). Only required if the value is `true`. |

### Return a success

If the user's verification status was updated successfully in the external database, pass a `null` value for the `error` parameter, and a `true` value for the `verified` parameter:

```js theme={null}
callback(null, true);
```

<Warning>
  The Verify script does not change the value of the `email_verified` attribute in the user's Auth0 profile, regardless of what value is returned in the `callback` function.

  To update the `email_verified` attribute in the user's Auth0 profile, you must include the `email_verified` attribute and its value in the user profile object returned in the [Login](/docs/authenticate/database-connections/custom-db/templates/login) and [Get User](/docs/authenticate/database-connections/custom-db/templates/get-user) scripts.
</Warning>

### Return an error

If an error occurs, the `error` parameter should contain relevant information about what went wrong:

```js theme={null}
return callback(new Error("My custom error message."));
```

## Language-specific script examples

Auth0 provides sample scripts for use with the following languages/technologies:

<CodeGroup>
  ```javascript JavaScript lines theme={null}
  function verify(email, callback) {
    // This script should mark the current user's email address as verified in
    // your database.
    // It is executed whenever a user clicks the verification link sent by email.
    // These emails can be customized at https://manage.auth0.com/#/emails.
    // It is safe to assume that the user's email already exists in your database,
    // because verification emails, if enabled, are sent immediately after a
    // successful signup.
    //
    // There are two ways that this script can finish:
    // 1. The user's email was verified successfully
    //     callback(null, true);
    // 2. Something went wrong while trying to reach your database:
    //     callback(new Error("my error message"));
    //
    // If an error is returned, it will be passed to the query string of the page
    // where the user is being redirected to after clicking the verification link.
    // For example, returning `callback(new Error("error"))` and redirecting to
    // https://example.com would redirect to the following URL:
    //     https://example.com?email=alice%40example.com&message=error&success=false
    const msg = 'Please implement the Verify script for this database connection ' +
      'at https://manage.auth0.com/#/connections/database';
    return callback(new Error(msg));
  }
  ```

  ```javascript ASP.NET MVC3 lines expandable theme={null}
  // For ASP.NET Membership Provider (MVC3 - Universal Providers)
  function verify(email, callback) {
    const sqlserver = require('tedious@1.11.0');
    const Connection = sqlserver.Connection;
    const Request = sqlserver.Request;
    const TYPES = sqlserver.TYPES;
    const connection = new Connection({
      userName: 'the username',
      password: 'the password',
      server: 'the server',
      options: {
        database: 'the db name',
        encrypt: true,
        // Required to retrieve userId needed for Membership entity creation
        rowCollectionOnRequestCompletion: true
      }
    });
    connection.on('debug', function(text) {
      // if you have connection issues, uncomment this to get more detailed info
      //console.log(text);
    }).on('errorMessage', function(text) {
      // this will show any errors when connecting to the SQL database or with the SQL statements
      console.log(JSON.stringify(text));
    });
    connection.on('connect', function(err) {
      if (err) return callback(err);
      verifyMembershipUser(email, function(err, wasUpdated) {
        if (err) return callback(err); // this will return a 500
        callback(null, wasUpdated);
      });
    });
    function verifyMembershipUser(email, callback) {
      // isApproved field is the email verification flag
      const updateMembership =
        'UPDATE Memberships SET isApproved = \'true\' ' +
        'WHERE isApproved = \'false\' AND Email = @Email';
      const updateMembershipQuery = new Request(updateMembership, function(err, rowCount) {
        if (err) {
          return callback(err);
        }
        callback(null, rowCount > 0);
      });
      updateMembershipQuery.addParameter('Email', TYPES.VarChar, email);
      connection.execSql(updateMembershipQuery);
    }
  }
  ```

  ```javascript ASP.NET MVC4 lines expandable theme={null}
  // For ASP.NET Membership Provider (MVC4 - Simple Membership)
  function verify (email, callback) {
    const sqlserver = require('tedious@1.11.0');
    const Connection = sqlserver.Connection;
    const Request = sqlserver.Request;
    const TYPES = sqlserver.TYPES;
    const connection = new Connection({
      userName: 'the username',
      password: 'the password',
      server: 'the server',
      options: {
        database: 'the db name',
        encrypt: true,
        // Required to retrieve userId needed for Membership entity creation
        rowCollectionOnRequestCompletion: true
      }
    });
    connection.on('debug', function(text) {
      // if you have connection issues, uncomment this to get more detailed info
      //console.log(text);
    }).on('errorMessage', function(text) {
      // this will show any errors when connecting to the SQL database or with the SQL statements
      console.log(JSON.stringify(text));
    });
    connection.on('connect', function (err) {
      if (err) return callback(err);
      verifyMembershipUser(email, function(err, wasUpdated) {
        if (err) return callback(err); // this will return a 500
        callback(null, wasUpdated);
      });
    });
    function findUserId(email, callback) {
      const findUserIdFromEmail =
        'SELECT UserProfile.UserId FROM ' +
        'UserProfile INNER JOIN webpages_Membership ' +
        'ON UserProfile.UserId = webpages_Membership.UserId ' +
        'WHERE UserName = @Username';
      const findUserIdFromEmailQuery = new Request(findUserIdFromEmail, function (err, rowCount, rows) {
        if (err || rowCount < 1) return callback(err);
        const userId = rows[0][0].value;
        callback(null, userId);
      });
      findUserIdFromEmailQuery.addParameter('Username', TYPES.VarChar, email);
      connection.execSql(findUserIdFromEmailQuery);
    }
    function verifyMembershipUser(email, callback) {
      findUserId(email, function (err, userId) {
        if (err || !userId) return callback(err);
        // isConfirmed field is the email verification flag
        const updateMembership =
          'UPDATE webpages_Membership SET isConfirmed = \'true\' ' +
          'WHERE isConfirmed = \'false\' AND UserId = @UserId';
        const updateMembershipQuery = new Request(updateMembership, function (err, rowCount) {
          return callback(err, rowCount > 0);
        });
        updateMembershipQuery.addParameter('UserId', TYPES.VarChar, userId);
        connection.execSql(updateMembershipQuery);
      });
    }
  }
  ```

  ```javascript MongoDB lines theme={null}
  function verify (email, callback) {
    const MongoClient = require('mongodb@3.1.4').MongoClient;
    const client = new MongoClient('mongodb://user:pass@mymongoserver.com');
    client.connect(function (err) {
      if (err) return callback(err);
      const db = client.db('db-name');
      const users = db.collection('users');
      const query = { email: email, email_verified: false };
      users.update(query, { $set: { email_verified: true } }, function (err, count) {
        client.close();
        if (err) return callback(err);
        callback(null, count > 0);
      });
    });
  }
  ```

  ```javascript MySQL lines theme={null}
  function verify(email, callback) {
    const mysql = require('mysql');
    const connection = mysql({
      host: 'localhost',
      user: 'me',
      password: 'secret',
      database: 'mydb'
    });
    connection.connect();
    const query = 'UPDATE users SET email_Verified = true WHERE email_Verified = false AND email = ?';
    connection.query(query, [ email ], function(err, results) {
      if (err) return callback(err);
      callback(null, results.length > 0);
    });
  }
  ```

  ```javascript PostgreSQL lines theme={null}
  function verify (email, callback) {
    //this example uses the "pg" library
    //more info here: https://github.com/brianc/node-postgres
    const postgres = require('pg');
    const conString = 'postgres://user:pass@localhost/mydb';
    postgres.connect(conString, function (err, client, done) {
      if (err) return callback(err);
      const query = 'UPDATE users SET email_Verified = true WHERE email_Verified = false AND email = $1';
      client.query(query, [email], function (err, result) {
        // NOTE: always call `done()` here to close
        // the connection to the database
        done();
        return callback(err, result && result.rowCount > 0);
      });
    });
  }
  ```

  ```javascript SQL Server lines expandable theme={null}
  function verify (email, callback) {
    //this example uses the "tedious" library
    //more info here: http://pekim.github.io/tedious/index.html
    const sqlserver = require('tedious@1.11.0');
    const Connection = sqlserver.Connection;
    const Request = sqlserver.Request;
    const TYPES = sqlserver.TYPES;
    const connection = new Connection({
      userName:  'test',
      password:  'test',
      server:    'localhost',
      options:  {
        database: 'mydb'
      }
    });
    const query = 'UPDATE dbo.Users SET Email_Verified = true WHERE Email_Verified = false AND Email = @Email';
    connection.on('debug', function(text) {
      console.log(text);
    }).on('errorMessage', function(text) {
      console.log(JSON.stringify(text, null, 2));
    }).on('infoMessage', function(text) {
      console.log(JSON.stringify(text, null, 2));
    });
    connection.on('connect', function (err) {
      if (err) return callback(err);
      const request = new Request(query, function (err, rows) {
        if (err) return callback(err);
        callback(null, rows > 0);
      });
      request.addParameter('Email', TYPES.VarChar, email);
      connection.execSql(request);
    });
  }
  ```

  ```javascript Azure SQL Database lines expandable theme={null}
  function verify (email, callback) {
    //this example uses the "tedious" library
    //more info here: http://pekim.github.io/tedious/index.html
    var Connection = require('tedious@1.11.0').Connection;
    var Request = require('tedious@1.11.0').Request;
    var TYPES = require('tedious@1.11.0').TYPES;
    var connection = new Connection({
      userName:  'your-user@your-server-id.database.windows.net',
      password:  'the-password',
      server:    'your-server-id.database.windows.net',
      options:  {
        database: 'mydb',
        encrypt:  true
      }
    });
    var query =
      'UPDATE Users SET Email_Verified=\'TRUE\' ' +
      'WHERE Email_Verified=\'FALSE\' AND Email=@Email';
    connection.on('debug', function(text) {
      // Uncomment next line in order to enable debugging messages
      // console.log(text);
    }).on('errorMessage', function(text) {
      console.log(JSON.stringify(text, null, 2));
    }).on('infoMessage', function(text) {
      // Uncomment next line in order to enable information messages
      // console.log(JSON.stringify(text, null, 2));
    });
    connection.on('connect', function (err) {
      if (err) { return callback(err); }
      var request = new Request(query, function (err, rows) {
        if (err) { return callback(err); }
        console.log('rows: ' + rows);
        callback(null, rows > 0);
      });
      request.addParameter('Email', TYPES.VarChar, email);
      connection.execSql(request);
    });
  }
  ```
</CodeGroup>
