> ## 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.

# Script d’action Change Password pour base de données et modèles

> Le script Change Password s’exécute lorsque vous ou l’utilisateur lancez un processus de changement de mot de passe.

Le script Change Password implémente la fonction définie pour modifier le mot de passe de l’utilisateur indiqué dans la base de données externe. Nous recommandons de nommer cette fonction `changePassword`.

Ce script est utilisé uniquement dans un [scénario d’authentification héritée](/docs/fr-ca/authenticate/database-connections/custom-db/overview-custom-db-connections) et il est requis si vous souhaitez modifier le mot de passe d’un utilisateur dans la base de données externe. Il s’exécute lorsqu’un utilisateur effectue un [processus de réinitialisation du mot de passe](/docs/fr-ca/customize/login-pages/classic-login/customize-password-reset-page), ou lorsqu’un processus de changement de mot de passe est lancé à partir du <Tooltip tip="Auth0 Dashboard : principal produit d’Auth0 pour configurer vos services." cta="Voir le glossaire" href="/docs/fr-ca/glossary?term=Auth0+Dashboard">Auth0 Dashboard</Tooltip> ou de l’Auth0 <Tooltip tip="Management API : produit qui permet aux clients d’effectuer des tâches administratives." cta="Voir le glossaire" href="/docs/fr-ca/glossary?term=Management+API">Management API</Tooltip>.

<div id="changepassword-function">
  ## Fonction ChangePassword
</div>

La fonction `changePassword` doit :

* Mettre à jour le mot de passe de l'utilisateur dans la base de données externe.
* Retourner `true` (ou un objet contenant la propriété `last_password_reset`) si l'opération de changement de mot de passe a réussi. Si la propriété `last_password_reset` est présente dans l'objet, elle sera mise à jour dans le profil utilisateur.
* Retourner `false` si l'opération de changement de mot de passe a échoué.
* Retourner une erreur si la base de données externe est inaccessible.

<div id="definition">
  ### Définition
</div>

La fonction `changePassword` accepte trois paramètres et renvoie une fonction `callback` :

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

| Paramètre     | Type     | Description                                                                                                                                                                                                                                     |
| ------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `email`       | String   | Adresse courriel de l'utilisateur dans Auth0 et dans la base de données externe.                                                                                                                                                                |
| `newPassword` | String   | Valeur à définir comme nouveau mot de passe de l'utilisateur dans la base de données externe. Cette valeur est envoyée en texte brut à la fonction et [devrait être chiffrée](#Encryption) avant d'être transmise à la base de données externe. |
| `callback`    | Fonction | Sert à transmettre des données ou le résultat d'une opération dans le pipeline.                                                                                                                                                                 |

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

Voici un exemple en pseudo-JavaScript montrant comment vous pourriez implémenter la fonction `changePassword`. Pour des exemples propres à chaque langage, consultez [Exemples de scripts propres à chaque langage](#language-specific-script-examples).

```javascript lines expandable theme={null}
function changePassword(email, newPassword, callback) {
  // Hacher le mot de passe fourni 
  let hashedPassword = hash(newPassword);

  // Préparer l'appel d'API
  let options = {
    url: "https://example.com/api/users",
    body: {
      email: email,
      password: hashedPassword
    }
  };

  // Appeler l'API
  send(options, err => {
    if (err && err.id == "FAIL_CHANGE_PASSWORD") {
      // Retourner faux dans le callback si le changement de mot de passe a échoué
      return callback(null, false);
    } else if (err) {
      // Retourner une erreur dans le callback si une autre erreur s'est produite
      return callback(new Error("My custom error message.");
    } else {
      // Retourner vrai dans le callback si l'opération de changement de mot de passe a réussi
      return callback(null, true);

      // Ou retourner un objet contenant la propriété `last_password_reset` 
      // si l'opération de changement de mot de passe a réussi.
      // Si la propriété `last_password_reset` est présente dans l'objet,
      // elle sera mise à jour dans le profil de l'utilisateur.
      return callback(null, { "last_password_reset": Date.now() });
    }
  });
}
```

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

Pour prévenir toute fuite de données, hachez la valeur du mot de passe à l’aide d’une bibliothèque de hachage cryptographique telle que `bcrypt`. Évitez de consigner, de stocker ou de transmettre les informations d’identification du mot de passe sous une forme non chiffrée.

Par exemple :

```js lines theme={null}
bcrypt.hash(password, 10, function (err, hash) {
    if (err) {
        return callback(err);
    } else {
        // Retourner le mot de passe haché
    }
});
```

<div id="callback-function">
  ## Fonction callback
</div>

La fonction `callback` accepte deux paramètres et sert à transmettre des données d’erreur ou à indiquer le résultat de l’opération.

<div id="definition">
  ### Définition
</div>

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

| Paramètre         | Type    | Obligatoire | Description                                                                                                                                                                                  |
| ----------------- | ------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `error`           | Objet   | Obligatoire | Contient des données d’erreur.                                                                                                                                                               |
| `operationResult` | Boolean | Facultatif  | Indique le résultat de l’opération de changement de mot de passe.                                                                                                                            |
| `resultObj`       | Objet   | Facultatif  | Indique que l’opération de changement de mot de passe s’est déroulée avec succès. Si la propriété `last_password_reset` est présente, elle sera mise à jour dans le profil de l’utilisateur. |

<div id="return-a-success">
  ### Renvoyer une réussite
</div>

Si l’opération de changement de mot de passe a réussi, appelez la fonction `callback` en transmettant une valeur `null` pour le paramètre `error` et une valeur `true` pour le paramètre `operationResult`. Par exemple :

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

<div id="return-a-success-and-update-last_password_reset-attribute">
  ### Retourner une réussite et mettre à jour l’attribut last\_password\_reset
</div>

Si l’opération de changement de mot de passe a réussi, appelez la fonction `callback` en transmettant une valeur `null` comme paramètre `error` et un objet comme paramètre `profile`. Si l’attribut `last_password_reset` est fourni dans l’objet, il sera mis à jour dans le profil de l’utilisateur. Par exemple :

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

<div id="return-a-failure">
  ### Signaler un échec
</div>

Si l’opération de changement de mot de passe a échoué, appelez la fonction `callback` en passant la valeur `null` pour le paramètre `error` et la valeur `false` pour le paramètre `operationResult`. Par exemple :

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

<div id="return-an-error">
  ### Retourner une erreur
</div>

S'il se produit une erreur, appelez la fonction `callback` et transmettez-lui les renseignements pertinents dans le paramètre `error`. Par exemple :

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

<div id="language-specific-script-examples">
  ## Exemples de scripts propres à chaque langage
</div>

Auth0 fournit des scripts d’exemple pour les langages et technologies suivants :

<CodeGroup>
  ```javascript JavaScript lines expandable theme={null}
  function changePassword(email, newPassword, callback) {
    // Ce script doit modifier le mot de passe enregistré pour l'utilisateur actuel dans votre
    // base de données. Il est exécuté lorsque l'utilisateur clique sur le lien de confirmation
    // après une demande de réinitialisation du mot de passe.
    // Le contenu et le comportement des courriels de confirmation du mot de passe peuvent être personnalisés
    // ici : https://manage.auth0.com/#/emails
    // Le paramètre `newPassword` de cette fonction est en texte clair. Il doit être
    // haché et salé pour correspondre à ce qui est stocké dans votre base de données.
    //
    // Ce script peut se terminer de trois façons :
    // 1. Le mot de passe de l'utilisateur a été mis à jour avec succès :
    //     callback(null, true);
    // 2. Le mot de passe de l'utilisateur n'a pas été mis à jour :
    //     callback(null, false);
    // 3. Un problème est survenu lors de la tentative d'accès à votre base de données :
    //     callback(new Error("my error message"));
    //
    // Si une erreur est renvoyée, elle sera transmise à la chaîne de requête de la page
    // vers laquelle l'utilisateur est redirigé après avoir cliqué sur le lien de confirmation.
    // Par exemple, renvoyer `callback(new Error("error"))` et rediriger vers
    // https://example.com redirigerait vers l'URL suivante :
    //     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));
  }
  ```

  ```javascript ASP.NET MVC3 lines expandable theme={null}
  // Pour ASP.NET Membership Provider (MVC3 - Universal Providers) :
  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   activer ceci pour Windows Azure
      }
    });
    /**
     * hashPassword
     *
     * Cette fonction crée une version hachée du mot de passe à stocker dans la base de données.
     *
     * @password  {[string]}      le mot de passe saisi par l'utilisateur
     * @return    {[string]}      le mot de passe haché
     */
    function hashPassword(password, salt) {
      // la mise en œuvre par défaut utilise HMACSHA256 et puisque la longueur de la clé est de 64
      // et que le salt par défaut est de 16 octets, Membership remplira le tampon en répétant le 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 vous avez des problèmes de connexion, décommentez cette ligne pour obtenir des informations plus détaillées
        //console.log(text);
    }).on('errorMessage', function(text) {
        // affiche toutes les erreurs lors de la connexion à la base de données SQL ou avec les instructions 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); // retournera 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);
    }
  }
  ```

  ```javascript ASP.NET MVC4 lines expandable theme={null}
  // Pour ASP.NET Membership Provider (MVC4 - Simple Membership) :
  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 activer ceci pour Windows Azure
      }
    });
    /**
     * hashPassword
     *
     * Cette fonction hache un mot de passe à l’aide de l’algorithme HMAC SHA256.
     *
     * @password    {[string]}    mot de passe à hacher
     * @salt        {[string]}    salt à utiliser dans le processus de hachage
     * @callback    {[function]}  callback à appeler une fois le mot de passe haché
     */
    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 vous avez des problèmes de connexion, décommentez cette ligne pour obtenir des informations plus détaillées
        //console.log(text);
    }).on('errorMessage', function(text) {
        // affiche toutes les erreurs lors de la connexion à la base de données SQL ou avec les instructions 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); // retournera 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);
        }
        // Aucun enregistrement correspondant à cette adresse courriel
        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);
        });
      });
    }
  }
  ```

  ```javascript MongoDB 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);
        });
      });
    });
  }
  ```

  ```javascript MySQL 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);
      });
    });
  }
  ```

  ```javascript PostgreSQL lines theme={null}
  function changePassword (email, newPassword, callback) {
    // cet exemple utilise la bibliothèque « pg »
    // plus d'informations ici : 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) {
          // REMARQUE : appelez toujours `done()` ici pour fermer
          // la connexion à la base de données
          done();
          return callback(err, result && result.rowCount > 0);
        });
      });
    });
  }
  ```

  ```javascript SQL Server lines expandable theme={null}
  function changePassword (email, newPassword, callback) {
    //cet exemple utilise la bibliothèque « tedious »
    //plus d’informations ici : 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);
      });
    });
  }
  ```

  ```javascript Azure SQL Database lines expandable theme={null}
  function changePassword (email, newPassword, callback) {
    //cet exemple utilise la bibliothèque « tedious »
    //plus d’information ici : 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) {
      // Décommentez la ligne suivante pour activer les messages de débogage
      // console.log(text);
    }).on('errorMessage', function(text) {
      console.log(JSON.stringify(text, null, 2));
    }).on('infoMessage', function(text) {
      // Décommentez la ligne suivante pour activer les messages d’information
      // 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);
      });
    });
  }
  ```
</CodeGroup>
