# Validate password

The script will be executed when the administrator uses the console or API to obtain the user list. The data required by this interface needs to include the total number of users and the user list on the current page. This script is only required in full use of the custom database schema.

# Function definition

The validatePassword function is defined as follows:

async function validatePassword(id, password, context) {
  // This script should validate password of a exists user entry in your database. It will
  // be executed when a user attempts to change password.

  // The first argument `id` is the user'id in your database

  // The second argument `password` is the password user input in palin text format.

  // The last argument `context` contains information about the authentication context.
  // see http://core.authing.cn/connections/custom-db/config-custom-db-connection.html for more information.

  //
  // There are three ways this script can finish:
  // 1. The password
  // format: https://docs.authing.co/user/profile.html.
  // return profile
  // 2. A user was not found
  // return null
  // 3. Something went wrong while trying to reach your database:
  // throw new Error("my error message")

  const msg =
    'Please implement the Validate Password script for this database connection';
  throw new Error(msg);
}
Parameters Type nullable Description
id number / string false User ID
password string false User plaintext password.
context object true request context context

The context contains the following information:

Property name Type Description
userPoolId string User Pool ID
userPoolName string User pool name
userPoolMetadata object User pool configuration information
appId string ID of the current user, **You can distinguish the source of the application requested by the user through appId. **
appName string The name of the current application
appMetadata object Current application configuration information
application string User Pool ID
request object The detailed information of the current request, including:
ip: client IP
geo: client geographic location resolved by IP
body: request body

# Return data convention

# Verify the password successfully

When verifying the password is successful, you need to return true:

async function validatePassword(id, password, context) {
  // Implement your logic here
  return true
}

# Password verification failed

When verifying the password fails, you need to return false:

async function validatePassword(id, password, context) {
  // Implement your logic here
  return false
}

# Other exception errors

When encountering other abnormal errors, you can catch the error and return a more friendly error prompt, for example:

async function validatePassword(id, password, context) {
  try {
    // Implement your logic here
  } catch (error) {
    throw new Error('Something went wrong ...')
  }
}

# Best Practices

# Provide friendly error tips

When encountering an unknown error, we recommend throwing a standard Error object. Authing will catch this error and return it to the end user. For example: throw new Error("My nice error message"), you can see the error log in the log history of the custom database.

# Disconnect the database connection at the end of the function

Please remember to close the connection to the database when the script is executed, such as calling client.end(). For example, it can be executed in try/finallly to ensure that it will always be executed:

try {
  const result = await client.updates("YOUR updates");
} finally {
  // NOTE: always call `client.end()` here to close the connection to the database
  client.end();
}

# Example function

Taking the postgres database as an example, the following points are explained:

-You can get the database connection string through env.DB_CONNECTION_URI to create a database connection. -Execute the SQL statement SELECT password FROM users WHERE id = $1, if result.rows.length is 0, it means that the user does not exist, and an exception is thrown. The error message is: User not exists!. -Check whether the password is correct by bcrypt.compare. -Call client.end() in try/finally to disconnect the database.

async function validatePassword(id, password, context) {
  // This example uses the "pg" library
  // more info here: https://github.com/brianc/node-postgres
  const {Client} = require('pg');

  const client = new Client({
    connectionString: env.DB_CONNECTION_URI,
  });

  // Or you can:
  // const client = new Client({
  // host: env.DB_HOST,
  // port: env.DB_PORT,
  // user: env.DB_USERNAME,
  // password: env.DB_PASSWORD,
  // database: env.DB_DATABASE,
  // });

  await client.connect();

  // Use bcrypt to validate password
  // more info here: https://github.com/kelektiv/node.bcrypt.js
  const bcrypt = require('bcrypt');

  const QUERY ='SELECT password FROM users WHERE id = $1';
  try {
    const result = await client.query(QUERY, [id]);
    if (result.rows.length === 0) {
      throw new Error('User not exists!');}
     const user = result.rows[0];
     const isPasswordValid = await bcrypt.compare(password, user.password);
     return isPasswordValid;
   } catch (error) {
     throw new Error(`Execute query failed: ${error.message}`);
   } finally {
     // NOTE: always call `client.end()` here to close the connection to the database
     client.end();
   }
}