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

> Describe las plantillas de scripts de acción de base de datos personalizada para cambiar la contraseña de un usuario.

# Plantillas de scripts para cambiar la contraseña

El script Change Password implementa la función definida para cambiar la contraseña del usuario especificado en la base de datos externa. Recomendamos llamar a esta función `changePassword`.

Este script solo se usa en un [escenario de autenticación heredado](/es/docs/authenticate/database-connections/custom-db/overview-custom-db-connections) y es obligatorio si desea cambiar la contraseña de un usuario en la base de datos externa. Se ejecutará cuando un usuario realice un [flujo de restablecimiento de contraseña](/es/docs/customize/login-pages/classic-login/customize-password-reset-page) o cuando se inicie un flujo de cambio de contraseña desde el <Tooltip tip="Auth0 Dashboard: El producto principal de Auth0 para configurar sus servicios." cta="Ver glosario" href="/es/docs/glossary?term=Auth0+Dashboard">Auth0 Dashboard</Tooltip> o la Auth0 <Tooltip tip="Management API: Un producto que permite a los clientes realizar tareas administrativas." cta="Ver glosario" href="/es/docs/glossary?term=Management+API">Management API</Tooltip>.

<div id="changepassword-function">
  ## Función ChangePassword
</div>

La función `changePassword` debe:

* Actualizar la contraseña del usuario en la base de datos externa.
* Devolver `true` (o un objeto que contenga la propiedad `last_password_reset`) si la operación de cambio de contraseña se completó correctamente. Si la propiedad `last_password_reset` está presente en el objeto, se actualizará en el perfil del usuario.
* Devolver `false` si la operación de cambio de contraseña falla.
* Devolver un error si no se puede acceder a la base de datos externa.

<div id="definition">
  ### Definición
</div>

La función `changePassword` acepta tres parámetros y devuelve una función de devolución de llamada (`callback`):

```js lines theme={null}
changePassword(email, newPassword, callback): function
```

| Parámetro     | Tipo     | Descripción                                                                                                                                                                                                                   |
| ------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `email`       | String   | Dirección de correo electrónico del usuario en Auth0 y en la base de datos externa.                                                                                                                                           |
| `newPassword` | String   | Valor que se establecerá como la nueva contraseña del usuario en la base de datos externa. Este valor se envía a la función en texto sin formato y [debe cifrarse](#Encryption) antes de enviarse a la base de datos externa. |
| `callback`    | Function | Se utiliza para pasar datos o el resultado de la operación a través del flujo.                                                                                                                                                |

### Ejemplo

Este es un ejemplo en seudojavaScript de cómo podría implementar la función `changePassword`. Para ver ejemplos específicos de cada lenguaje, consulte [Ejemplos de scripts específicos de cada lenguaje](#language-specific-script-examples).

```javascript lines expandable theme={null}
function changePassword(email, newPassword, callback) {
  // Aplicar hash a la contraseña proporcionada 
  let hashedPassword = hash(newPassword);

  // Preparar la llamada a la API
  let options = {
    url: "https://example.com/api/users",
    body: {
      email: email,
      password: hashedPassword
    }
  };

  // Llamar a la API
  send(options, err => {
    if (err && err.id == "FAIL_CHANGE_PASSWORD") {
      // Devolver false en el callback si el cambio de contraseña falló
      return callback(null, false);
    } else if (err) {
      // Devolver error en el callback si ocurrió otro error
      return callback(new Error("My custom error message.");
    } else {
      // Devolver true en el callback si la operación de cambio de contraseña se realizó correctamente
      return callback(null, true);

      // O devolver un objeto que contenga la propiedad `last_password_reset` 
      // si la operación de cambio de contraseña se realizó correctamente.
      // Si la propiedad `last_password_reset` está presente en el objeto,
      // se actualizará en el perfil del usuario.
      return callback(null, { "last_password_reset": Date.now() });
    }
  });
}
```

<div id="encryption">
  ### Cifrado
</div>

<Warning>
  Evite registrar, almacenar o transportar la credencial de contraseña en cualquier lugar en su forma sin cifrar.
</Warning>

Para evitar cualquier posible filtración de datos, cifre el valor de la contraseña mediante una biblioteca de hash criptográfico como `bcrypt`.

<div id="example">
  #### Ejemplo
</div>

```js lines theme={null}
bcrypt.hash(password, 10, function (err, hash) {
    if (err) {
        return callback(err);
    } else {
        // Devolver contraseña hasheada
    }
});
```

<div id="callback-function">
  ## Función callback
</div>

La función `callback` acepta dos parámetros y se utiliza para pasar datos de error o indicar el resultado de la operación.

<div id="definition">
  ### Definición
</div>

```js lines theme={null}
callback(error, operationResult | resultObj): function
```

| Parámetro         | Tipo    | Obligatorio | Descripción                                                                                                                                                              |
| ----------------- | ------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `error`           | Object  | Obligatorio | Contiene datos del error.                                                                                                                                                |
| `operationResult` | Boolean | Opcional    | Indica el resultado de la operación de cambio de contraseña.                                                                                                             |
| `resultObj`       | Object  | Opcional    | Indica que la operación de cambio de contraseña se completó correctamente. Si la propiedad `last_password_reset` está presente, se actualizará en el perfil del usuario. |

<div id="return-a-success">
  ### Devolver un resultado exitoso
</div>

Si la operación de cambio de contraseña se realizó correctamente, devuelve la función `callback` y pasa el valor `null` en el parámetro `error` y el valor `true` en el parámetro `operationResult`.

<div id="example">
  #### Ejemplo
</div>

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

<div id="return-a-success-and-update-last_password_reset-attribute">
  ### Devolver un resultado correcto y actualizar el atributo last\_password\_reset
</div>

Si la operación de cambio de contraseña se completó correctamente, devuelve la función `callback` y pasa un valor `null` como parámetro `error` y un objeto como parámetro `profile`. Si el atributo `last_password_reset` se incluye en el objeto, se actualizará en el perfil del usuario.

<div id="example">
  #### Ejemplo
</div>

```js lines theme={null}
return callback(null, { "last_password_reset": Date.now() });
```

<div id="return-a-failure">
  ### Devolver un fallo
</div>

Si la operación de cambio de contraseña falla, devuelva la función `callback` y pase el valor `null` como parámetro `error` y el valor `false` como parámetro `operationResult`.

<div id="example">
  #### Ejemplo
</div>

```js lines theme={null}
return callback(null, false);
```

<div id="return-an-error">
  ### Devolver un error
</div>

Si se produce un error, devuelva la función `callback` y pase la información pertinente en el parámetro `error`.

<div id="example">
  #### Ejemplo
</div>

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

<div id="language-specific-script-examples">
  ## Ejemplos de scripts específicos para cada lenguaje
</div>

Auth0 proporciona scripts de ejemplo para los siguientes lenguajes/tecnologías:

* [JavaScript](#javascript)
* [Proveedor de membresía de ASP.NET (MVC3 - Proveedores universales)](#asp-net-membership-provider-mvc3-universal-providers-)
* [Proveedor de membresía de ASP.NET (MVC4 - Membresía simple)](#asp-net-membership-provider-mvc4-simple-membership-)
* [MongoDB](#mongodb)
* [MySQL](#mysql)
* [PostgreSQL](#postgresql)
* [SQL Server](#sql-server)
* [Base de datos SQL de Azure para Windows](#windows-azure-sql-database)

<div id="javascript">
  ### JavaScript
</div>

```javascript lines expandable theme={null}
function changePassword(email, newPassword, callback) {
  // Este script debe cambiar la contraseña almacenada para el usuario actual en
  // su base de datos. Se ejecuta cuando el usuario hace clic en el enlace de confirmación
  // después de una solicitud de restablecimiento de contraseña.
  // El contenido y el comportamiento de los correos electrónicos de confirmación de contraseña se pueden personalizar
  // aquí: https://manage.auth0.com/#/emails
  // El parámetro `newPassword` de esta función está en texto plano. Debe ser
  // hasheado/salteado para coincidir con lo que está almacenado en su base de datos.
  //
  // Hay tres maneras en que este script puede finalizar:
  // 1. La contraseña del usuario se actualizó correctamente:
  //     callback(null, true);
  // 2. La contraseña del usuario no se actualizó:
  //     callback(null, false);
  // 3. Algo salió mal al intentar acceder a su base de datos:
  //     callback(new Error("my error message"));
  //
  // Si se devuelve un error, se pasará en la cadena de consulta de la página
  // a la que se redirige al usuario tras hacer clic en el enlace de confirmación.
  // Por ejemplo, devolver `callback(new Error("error"))` y redirigir a
  // https://example.com redirigirá a la siguiente URL:
  //     https://example.com?email=alice%40example.com&message=error&success=false
  const msg = 'Please implement the Change Password script for this database ' +
    'connection at https://manage.auth0.com/#/connections/database';
  return callback(new Error(msg));
}
```

<div id="aspnet-membership-provider-mvc3-universal-providers">
  ### Proveedor de membresía de ASP.NET (MVC3 - Proveedores universales)
</div>

```javascript lines expandable theme={null}
function changePassword(email, newPassword, callback) {
  var crypto = require('crypto');
  var Connection = require('tedious').Connection;
  var Request = require('tedious').Request;
  var TYPES = require('tedious').TYPES
  var connection = new Connection({
    userName:  'the username',
    password:  'the password',
    server:    'the server',
    options: {
      database:  'the db name',
      // encrypt: true   habilitar esto para Windows Azure
    }
  });
  /**
   * hashPassword
   *
   * Esta función crea una versión cifrada de la contraseña para almacenar en la base de datos.
   *
   * @password  {[string]}      la contraseña ingresada por el usuario
   * @return    {[string]}      la contraseña cifrada
   */
  function hashPassword(password, salt) {
    // la implementación predeterminada usa HMACSHA256 y dado que la longitud de la clave es 64
    // y el salt predeterminado es de 16 bytes, Membership llenará el búfer repitiendo el salt
    var key = Buffer.concat([salt, salt, salt, salt]);
    var hmac = crypto.createHmac('sha256', key);
    hmac.update(Buffer.from(password, 'ucs2'));
    var hashed = hmac.digest('base64');
    return hashed;
  }
  connection.on('debug', function(text) {
      // si tiene problemas de conexión, descomente esto para obtener información más detallada
      //console.log(text);
  }).on('errorMessage', function(text) {
      // esto mostrará cualquier error al conectarse a la base de datos SQL o con las sentencias SQL
    console.log(JSON.stringify(text));
  });
  connection.on('connect', function (err) {
    if (err) {
      return callback(err);
    }
    updateMembershipUser(email, newPassword, function(err, wasUpdated) {
      if (err) {
        return callback(err); // esto devolverá un 500
      }
      callback(null, wasUpdated);
    });
  });
  function updateMembershipUser(email, newPassword, callback) {
    var salt            = crypto.randomBytes(16);
    var hashedPassword  = hashPassword(newPassword, salt);
    var updateMembership =
      'UPDATE Memberships '+
      'SET Password=@NewPassword, PasswordSalt=@NewSalt, LastPasswordChangedDate=GETDATE() '+
      'WHERE Email=@Email';
    var updateMembershipQuery = new Request(updateMembership, function (membershipErr, membershipCount) {
      if (membershipErr) {
        return callback(membershipErr);
      }
      callback(null, membershipCount > 0);
    });
    updateMembershipQuery.addParameter('NewPassword', TYPES.VarChar, hashedPassword);
    updateMembershipQuery.addParameter('NewSalt',     TYPES.VarChar, salt.toString('base64'));
    updateMembershipQuery.addParameter('Email',       TYPES.VarChar, email);
    connection.execSql(updateMembershipQuery);
  }
}
```

<div id="aspnet-membership-provider-mvc4-simple-membership">
  ### Proveedor de membresía de ASP.NET (MVC4 - Membresía simple)
</div>

```javascript lines expandable theme={null}
function changePassword(email, newPassword, callback) {
  var crypto = require('crypto');
  var Connection = require('tedious').Connection;
  var Request = require('tedious').Request;
  var TYPES = require('tedious').TYPES
  var connection = new Connection({
    userName:  'the username',
    password:  'the password',
    server:    'the server',
    options: {
      database:  'the db name',
      // encrypt: true para Windows Azure, habilitar esto
    }
  });
  /**
   * hashPassword
   *
   * Esta función genera un hash de una contraseña usando el algoritmo HMAC SHA256.
   *
   * @password    {[string]}    contraseña a hashear
   * @salt        {[string]}    salt a utilizar en el proceso de hash
   * @callback    {[function]}  callback a invocar después de hashear la contraseña
   */
  function hashPassword(password, salt, callback) {
    var iterations         = 1000;
    var passwordHashLength = 32;
    crypto.pbkdf2(password, salt, iterations, passwordHashLength, function (err, hashed) {
      if (err) {
        return callback(err);
      }
      var result = Buffer.concat([Buffer.from([0], 1), salt, Buffer.from(hashed, 'binary')]);
      var resultBase64 = result.toString('base64');
      callback(null, resultBase64);
    });
  }
  connection.on('debug', function(text) {
      // si tiene problemas de conexión, descomente esto para obtener información más detallada
      //console.log(text);
  }).on('errorMessage', function(text) {
      // esto mostrará cualquier error al conectarse a la base de datos SQL o con las sentencias SQL
    console.log(JSON.stringify(text));
  });
  connection.on('connect', function (err) {
    if (err) {
      return callback(err);
    }
    updateMembershipUser(email, newPassword, function(err, wasUpdated) {
      if (err) {
        return callback(err); // esto devolverá un 500
      }
      callback(null, wasUpdated);
    });
  });
  function findUserId(email, callback) {
    var findUserIdFromEmail =
      'SELECT UserProfile.UserId FROM ' +
      'UserProfile INNER JOIN webpages_Membership ' +
      'ON UserProfile.UserId = webpages_Membership.UserId ' +
      'WHERE UserName = @Email';
    var findUserIdFromEmailQuery = new Request(findUserIdFromEmail, function (err, rowCount, rows) {
      if (err) {
        return callback(err);
      }
      // No se encontró ningún registro con ese correo electrónico
      if (rowCount < 1) {
        return callback(null, null);
      }
      var userId = rows[0][0].value;
      callback(null, userId);
    });
    findUserIdFromEmailQuery.addParameter('Email', TYPES.VarChar, email);
    connection.execSql(findUserIdFromEmailQuery);
  }
  function updateMembershipUser(email, newPassword, callback) {
    findUserId(email, function (err, userId) {
      if (err) {
        return callback(err);
      }
      if (userId === null) {
        return callback();
      }
      var salt = crypto.randomBytes(16);
      var updateMembership =
        'UPDATE webpages_Membership '+
        'SET Password=@NewPassword, PasswordChangedDate=GETDATE() '+
        'WHERE UserId=@UserId';
      var updateMembershipQuery = new Request(updateMembership, function (err, rowCount) {
        if (err) {
          return callback(err);
        }
        if (rowCount < 1) {
          return callback();
        }
        callback(null, rowCount > 0);
      });
      hashPassword(newPassword, salt, function (err, hashedPassword) {
        if (err) {
          return callback(err);
        }
        updateMembershipQuery.addParameter('NewPassword',   TYPES.VarChar, hashedPassword);
        updateMembershipQuery.addParameter('UserId',        TYPES.VarChar, userId);
        connection.execSql(updateMembershipQuery);
      });
    });
  }
}
```

<div id="mongodb">
  ### MongoDB
</div>

```javascript lines theme={null}
function changePassword(email, newPassword, callback) {
  const bcrypt = require('bcrypt');
  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');
    bcrypt.hash(newPassword, 10, function (err, hash) {
      if (err) {
        client.close();
        return callback(err);
      }
      users.update({ email: email }, { $set: { password: hash } }, function (err, count) {
        client.close();
        if (err) return callback(err);
        callback(null, count > 0);
      });
    });
  });
}
```

<div id="mysql">
  ### MySQL
</div>

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

<div id="postgresql">
  ### PostgreSQL
</div>

```javascript lines theme={null}
function changePassword (email, newPassword, callback) {
  //este ejemplo usa la librería "pg"
  //más información aquí: https://github.com/brianc/node-postgres
  const bcrypt = require('bcrypt');
  const postgres = require('pg');
  const conString = 'postgres://user:pass@localhost/mydb';
  postgres.connect(conString, function (err, client, done) {
    if (err) return callback(err);
    bcrypt.hash(newPassword, 10, function (err, hash) {
      if (err) return callback(err);
      const query = 'UPDATE users SET password = $1 WHERE email = $2';
      client.query(query, [hash, email], function (err, result) {
        // NOTA: siempre llama a `done()` aquí para cerrar
        // la conexión a la base de datos
        done();
        return callback(err, result && result.rowCount > 0);
      });
    });
  });
}
```

<div id="sql-server">
  ### SQL Server
</div>

```javascript lines expandable theme={null}
function changePassword (email, newPassword, callback) {
  //este ejemplo usa la biblioteca "tedious"
  //más información aquí: http://tediousjs.github.io/tedious/
  const bcrypt = require('bcrypt');
  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 Password = @NewPassword WHERE 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);
    });
    bcrypt.hash(newPassword, 10, function (err, hash) {
      if (err) return callback(err);
      request.addParameter('NewPassword', TYPES.VarChar, hash);
      request.addParameter('Email', TYPES.VarChar, email);
      connection.execSql(request);
    });
  });
}
```

<div id="windows-azure-sql-database">
  ### Base de datos SQL de Azure para Windows
</div>

```javascript lines expandable theme={null}
function changePassword (email, newPassword, callback) {
  //este ejemplo usa la librería "tedious"
  //más información aquí: 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 bcrypt = require('bcrypt');
  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 dbo.Users SET Password = @NewPassword ' +
    'WHERE Email = @Email';
  connection.on('debug', function(text) {
    // Descomenta la siguiente línea para habilitar los mensajes de depuración
    // console.log(text);
  }).on('errorMessage', function(text) {
    console.log(JSON.stringify(text, null, 2));
  }).on('infoMessage', function(text) {
    // Descomenta la siguiente línea para habilitar los mensajes de información
    // 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);
    });
    bcrypt.hash(newPassword, 10, function (err, hash) {
      if (err) { return callback(err); }
      request.addParameter('NewPassword', TYPES.VarChar, hash);
      request.addParameter('Email', TYPES.VarChar, email);
      connection.execSql(request);
    });
  });
}
```

<div id="learn-more">
  ## Más información
</div>

* [Crear plantillas de scripts](/es/docs/authenticate/database-connections/custom-db/templates/create)
* [Eliminar plantillas de scripts](/es/docs/authenticate/database-connections/custom-db/templates/delete)
* [Obtener plantillas de scripts de usuario](/es/docs/authenticate/database-connections/custom-db/templates/get-user)
* [Plantillas de scripts de inicio de sesión](/es/docs/authenticate/database-connections/custom-db/templates/login)
* [Plantillas de scripts de verificación](/es/docs/authenticate/database-connections/custom-db/templates/verify)
* [Plantillas de scripts de cambio de correo electrónico](/es/docs/authenticate/database-connections/custom-db/templates/change-email)
