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

> Découvrez comment migrer votre code Auth0 Rules existant vers le code Auth0 Actions.

# Passer de Rules à Actions

Lorsque vous convertissez des Rules existantes en Actions, vous devez associer la nouvelle Action au déclencheur Post-Login (`post-login`) du flux de connexion. Si vous suivez les étapes ci-dessous et gardez vos Actions dans le même ordre que vos Rules d’origine, la fonctionnalité devrait être identique.

<div id="plan-your-migration">
  ## Planifiez votre migration
</div>

Les Actions post-login s’exécutent après les Rules existantes. Vous pouvez donc convertir les Rules une à une dans le Dashboard, ou toutes en même temps à l’aide de la <Tooltip tip="Management API : un produit permettant aux clients d’effectuer des tâches administratives." cta="Voir le glossaire" href="/docs/fr-ca/glossary?term=Management+API">Management API</Tooltip>.

Vous devrez convertir le code, puis activer l’Action et désactiver la Rule. L’activation de l’Action et la désactivation de la Rule peuvent se faire rapidement l’une après l’autre, mais selon l’ordre choisi, il pourrait y avoir une courte période pendant laquelle les deux s’exécutent, ou pendant laquelle aucune ne s’exécute.

C’est pourquoi nous vous recommandons de migrer votre pipeline étape par étape : convertissez des portions du code de vos Rules en code d’Action, testez-les dans un environnement de staging, puis passez en production une portion à la fois. Comme les Rules actives s’exécutent avant les Actions déployées, si vous commencez à la fin de votre pipeline de Rules et remontez vers le début, vous pouvez conserver une partie de la logique dans les Rules pendant que vous créez et testez d’autres logiques dans les Actions.

<Card title="Conseils pour planifier votre migration">
  * Conservez une correspondance 1:1 entre vos Actions et vos Rules, afin de pouvoir activer et désactiver les fonctionnalités par blocs et les tester.
  * Utilisez des indicateurs dans les métadonnées utilisateur pour éviter de dupliquer des opérations coûteuses ou ponctuelles.
  * Commencez à la fin de votre pipeline de Rules et remontez vers le début; comme les Rules actives s’exécutent avant les Actions déployées, vous pouvez conserver une partie de la logique dans les Rules pendant que vous créez et testez d’autres logiques dans les Actions.
  * Assurez-vous d’apporter les changements à un moment où l’impact et le trafic seront au plus bas.
  * Envisagez de [personnaliser temporairement votre page de connexion](/docs/fr-ca/customize) afin d’interrompre les connexions si le basculement risque de provoquer des connexions invalides ou des failles de protection.
  * Envisagez d’utiliser le [Auth0 Deploy CLI](/docs/fr-ca/deploy-monitor/deploy-cli-tool) pour automatiser par script, tester et mettre en œuvre rapidement la migration, soit d’un seul coup, soit de façon itérative.
</Card>

<div id="understand-limitations">
  ## Comprendre les limites
</div>

Bien que les Actions puissent prendre en charge la grande majorité de ce que les Rules permettent de faire, vous devriez connaître certaines limites avant de commencer votre migration. (N’oubliez pas : pendant la migration, vous pouvez exécuter à la fois des Rules et des Actions.)

* Les Actions n’ont pas accès à [un jeton d’accès pour la Management API](/docs/fr-ca/customize/rules/use-management-api) ni à l’objet global `auth0`, contrairement aux Rules. Pour savoir comment il est tout de même possible d’effectuer des appels à la Management API, consultez la section [Convertir le code](#convert-code).

Pour obtenir la liste complète des limites, consultez [Actions Limitations](/docs/fr-ca/customize/actions/limitations).

<div id="convert-code">
  ## Convertir le code
</div>

Pour convertir une Rule en Action, vous devez remplacer le code propre aux Rules par du code Actions. Cette section présente les tâches à effectuer pour convertir une Rule fonctionnelle en son Action équivalente.

<Card title="Conseils pour convertir le code">
  * En général, recherchez les propriétés en lecture seule des objets `user` et `context` des Rules dans l’`event` object des Actions. Repérez dans les fonctions de l’objet `api` tous les effets de vos Actions sur le système (par exemple, faire échouer un login ou mettre à jour les métadonnées utilisateur).
  * Utilisez le Actions Code Editor dans le Auth0 Dashboard pour écrire votre code; il vous aidera en mettant les erreurs en évidence et en proposant des suggestions d’autocomplétion.
  * Avant la mise en production, [testez soigneusement vos nouvelles Actions](/docs/fr-ca/customize/actions/test-actions) dans un [environnement de staging ou de test](/docs/fr-ca/get-started/auth0-overview/create-tenants/set-up-multiple-environments).
</Card>

<div id="copy-rule-code-to-a-new-action">
  ### Copier le code d’une Rule dans une nouvelle Action
</div>

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Nous vous recommandons de copier le code de votre Rule dans une nouvelle Action et d’utiliser l’Actions Code Editor dans l’Auth0 Dashboard; cela vous aidera à repérer les problèmes qui subsistent dans votre code.
</Callout>

1. Connectez-vous à votre tenant de production, puis copiez le code de la Rule que vous voulez convertir.
2. Passez à un tenant hors production, puis accédez à [Auth0 Dashboard > Actions > Library](https://manage.auth0.com/#/select-tenant?path=/actions/library).
3. Sélectionnez **Build Custom**, puis :

   * Entrez un **Name** pour votre Action qui correspond au nom de la Rule que vous convertissez.
   * Repérez **Trigger**, puis sélectionnez **Login / Post Login**.
   * Repérez **Runtime**, puis sélectionnez **Node 16.**
   * Sélectionnez **Create**.
4. Dans le bloc de code de l’Actions Code Editor, collez le code de la Rule que vous voulez convertir sous la fonction exportée `onExecutePostLogin`.
5. Effectuez les changements décrits dans le reste de cet article à mesure que vous intégrez le code à la fonction.

<div id="change-the-function-declaration">
  ### Modifier la déclaration de la fonction
</div>

Les Rules utilisent une fonction déclarée classique avec les paramètres `user`, `context` et `callback`, tandis que les Actions utilisent une fonction exportée sous un nom précis. Apportez la modification suivante; pour l’instant, ignorez toute erreur qui s’affiche.

**Avant**

```js lines theme={null}
async function myRulesFunction(user, context, callback) {
    // ... code supplémentaire
}
```

**Après**

```js lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
	// ... code supplémentaire
};
```

<div id="change-how-user-data-is-accessed">
  ### Modifier la façon d’accéder aux données utilisateur
</div>

Dans Rules, les données sur l’utilisateur qui se connecte sont stockées dans l’[objet `user`](/docs/fr-ca/customize/rules/user-object-in-rules). Dans Actions, ces données se trouvent dans la propriété `user` de l’[objet `event`](/docs/fr-ca/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/post-login-event-object). La plupart des propriétés existantes sont accessibles à cet endroit.

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Les données stockées ou modifiées dans les propriétés de l’objet `event` ne sont pas accessibles dans d’autres Actions.
</Callout>

**Avant**

```javascript lines theme={null}
function myRulesFunction(user, context, callback) {
	const userEmail = user.email;
	const userId = user.user_id;

	// Cette propriété pourrait être indéfinie dans Rules.
	const userAppMetadata = user.app_metadata || {};

	// ... code supplémentaire
}
```

**Après**

```js lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
	const userEmail = event.user.email;
	const userId = event.user.user_id;

	// Cette propriété ne sera jamais indéfinie dans Actions.
	const userAppMetadata = event.user.app_metadata;

	// ... code supplémentaire
};
```

<div id="change-how-context-data-is-accessed">
  ### Modifier la façon d’accéder aux données de contexte
</div>

Dans Rules, les données sur la session de login en cours sont stockées dans l’[`objet context`](/docs/fr-ca/customize/rules/context-object). Avec Actions, ces données ont été restructurées et déplacées vers l’[`objet event`](/docs/fr-ca/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/post-login-event-object). Un grand nombre de propriétés ont été déplacées telles quelles, mais certaines ont été regroupées pour plus de clarté.

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Les données stockées ou modifiées dans les propriétés de l’`objet event` ne sont pas accessibles dans d’autres Actions. Si votre Rule déclenche une fonctionnalité centrale en définissant des données sur ces propriétés, comme `context.idToken` ou `context.multifactor`, veuillez lire l’une des sections ci-dessous correspondant à votre cas d’utilisation.
</Callout>

**Avant**

```javascript lines theme={null}
function myRulesFunction(user, context, callback) {
	const clientId = context.clientID;
	const clientMetadata = context.clientMetadata || {};

	const connectionId = context.connectionID;
	const connectionMetadata = context.connectionMetadata || {};

	const protocol = context.protocol;

	const tenant = context.tenant;

	// ... code supplémentaire
}
```

**Après**

```js lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
	const clientId = event.client.client_id;
	const clientMetadata = event.client.metadata;

	const connectionId = event.connection.id;
	const connectionMetadata = event.connection.metadata;

	const protocol = event.transaction.protocol;

	const tenant = event.tenant.id;

	// ... code supplémentaire
};
```

<div id="convert-dependencies">
  ### Convertir les dépendances
</div>

Les Rules gèrent les dépendances d’une façon qui oblige à inclure le numéro de version dans une instruction `require`. Les Actions utilisent une syntaxe CommonJS plus standard et exigent que les versions soient indiquées à l’extérieur de l’éditeur de code.

Dans les Rules, seules certaines versions de certains packages sont autorisées, et l’ajout de nouveaux packages et de nouvelles versions nécessite une requête à Auth0. Dans les Actions, vous pouvez utiliser `require` avec n’importe quel package accessible dans le registre `npm`.

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Si vos modules `npm` ne sont pas sur la version la plus récente, c’est le moment idéal pour les mettre à jour!
</Callout>

1. Repérez les instructions `require` dans le code de votre Rule.
2. Supprimez les numéros de version, mais notez-les.
3. Ajoutez la dépendance en suivant les étapes de la section "Add a Dependency" de [Write Your First Action](/docs/fr-ca/customize/actions/write-your-first-action) (si la dépendance n’est pas un [module NodeJS de base](https://github.com/nodejs/node/tree/main/lib); si la dépendance est un module NodeJS de base, vous n’avez pas besoin de l’inclure).
4. Déplacez les instructions `require` repérées à l’extérieur de la déclaration `function` :

**Avant**

```javascript lines theme={null}
function myRulesFunction(user, context, callback) {
	const dependency = require("dependency@1.2.3");

	// ... code supplémentaire
}
```

**Après**

```javascript lines theme={null}
const dependency = require("dependency"); // v1.2.3
exports.onExecutePostLogin = async (event, api) => {
	// ... code supplémentaire
};
```

<div id="convert-callbacks">
  ### Convertir les callbacks
</div>

Lorsqu’une Rule a terminé son traitement, elle doit appeler la fonction `callback()` et transmettre une erreur si la connexion échoue. À l’inverse, les Actions peuvent utiliser `return` en cas de réussite, ou appeler une méthode `api` en fournissant un message si la connexion échoue. Toutes les occurrences de `callback()` dans une Rule doivent être supprimées ou remplacées par `api.access.deny()` en cas d’échec. Dans les Rules comme dans les Actions, si le traitement doit s’arrêter en raison d’une condition particulière, utilisez une instruction `return`.

**Avant**

```javascript lines theme={null}
function myRulesFunction(user, context, callback) {
	const userAppMetadata = user.app_metadata || {};
	if (userAppMetadata.condition === "success") {
		// Cette règle a réussi, passer à la règle suivante.
		return callback(null, user, context);
	}

	if (userAppMetadata.condition === "failure") {
		// Cette règle a échoué, arrêter la connexion avec une réponse d'erreur.
		return callback(new Error("Failure message"));
	}

	// ... code supplémentaire
}
```

**Après**

```js lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
	if (event.user.app_metadata.condition === "success") {
		// Cette action a réussi, passer à l'action suivante.
		return;
	}

	if (event.user.app_metadata.condition === "failure") {
		// Cette action a échoué, arrêter la connexion avec une réponse d'erreur.
		return api.access.deny("Failure message");
	}

	// ... code supplémentaire
};
```

<div id="change-handling-of-secrets">
  ### Modifier la gestion des secrets
</div>

Dans Rules, vous définissez des valeurs de configuration globalement, ce qui signifie que toutes les Rules peuvent accéder à toutes les valeurs secrètes. (Pour en savoir plus, consultez [Store Rule Configurations](/docs/fr-ca/customize/rules/configuration).) Dans Actions, vous définissez des valeurs de configuration pour chaque Action individuellement. Vous ne pouvez pas accéder à la valeur secrète d’une Action à l’extérieur du contexte de cette Action.

Pour convertir les secrets de Rules vers Actions :

1. Enregistrez les valeurs nécessaires pour l’Action sur laquelle vous travaillez.
2. Ajoutez un Secret pour chaque valeur à laquelle vous devez accéder dans l’Action. Pour savoir comment faire, consultez la section **Add a Secret** dans [Write Your First Action](/docs/fr-ca/customize/actions/write-your-first-action).
3. Convertissez votre code :

**Avant**

```javascript lines theme={null}
function myRulesFunction (user, context, callback) {
  const { CLIENT_ID, CLIENT_SECRET } = configuration;

  // ... code supplémentaire
}
```

**Après**

```js lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
  const { CLIENT_ID, CLIENT_SECRET } = event.secrets;

  // ... code supplémentaire
}
```

Comme pour Rules, Auth0 chiffre toutes les valeurs secrètes lorsqu’elles sont stockées.

<div id="convert-custom-claims-in-tokens">
  ### Convertir les claims personnalisés dans les jetons
</div>

Les Rules et les Actions peuvent toutes deux ajouter des claims personnalisés aux jetons d’identification et aux <Tooltip tip="Jeton d’accès : information d’autorisation, sous la forme d’une chaîne opaque ou d’un JWT, utilisée pour accéder à une API." cta="Voir le glossaire" href="/docs/fr-ca/glossary?term=access+tokens">jetons d’accès</Tooltip>. Dans les Rules, cela correspond à une propriété de l’objet `context`, tandis que dans les Actions, on utilise une méthode de l’[`objet api`](/docs/fr-ca/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/post-login-api-object).

**Avant**

```javascript lines theme={null}
function myRulesFunction(user, context, callback) {
	const userAppMetadata = user.app_metadata || {};
	const namespace = "https://namespace/";

	context.idToken[`${namespace}/emp_id`] = userAppMetadata.emp_id;
	context.accessToken[`${namespace}/emp_id`] = userAppMetadata.emp_id;

	// ... code supplémentaire
}
```

**Après**

```js lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
	const namespace = "https://namespace/";

	api.idToken.setCustomClaim(
		`${namespace}/emp_id`, 
		event.user.app_metadata.emp_id
	); 		   

	api.accessToken.setCustomClaim(
		`${namespace}/emp_id`, 
		event.user.app_metadata.emp_id
	);

	// ... code supplémentaire
};
```

<div id="convert-multi-factor-triggering">
  ### Convertir le déclenchement de l’authentification multifacteur
</div>

Dans Rules, l’<Tooltip tip="authentification multifacteur (MFA) : processus d’authentification de l’utilisateur qui repose sur un facteur supplémentaire au nom d’utilisateur et au mot de passe, comme un code par SMS." cta="Voir le glossaire" href="/docs/fr-ca/glossary?term=multi-factor+authentication">authentification multifacteur</Tooltip> peut être déclenchée en modifiant la propriété `multifactor` de l’[objet `context`](/docs/fr-ca/customize/rules/context-object). Dans Actions, cela se fait à l’aide d’une [méthode de l’objet `api`](/docs/fr-ca/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/post-login-api-object).

**Avant**

```javascript lines theme={null}
function myRulesFunction(user, context, callback) {
	if (user.app_metadata.needs_mfa === true) {
		context.multifactor = { 
			provider: "any", 
			allowRememberBrowser: false,
		};
	}

	// ... code supplémentaire
}
```

**Après**

```js lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
	if (event.user.app_metadata.needs_mfa === true) {
		api.multifactor.enable("any", { allowRememberBrowser: false });
	}

	// ... code supplémentaire
};
```

<div id="convert-user-metadata-updates">
  ### Convertir les mises à jour des métadonnées de l’utilisateur
</div>

Dans les Rules, la mise à jour des propriétés `user_metadata` et `app_metadata` nécessite une requête à la Management API, ce qui peut entraîner des erreurs de [limite de débit](/docs/fr-ca/troubleshoot/customer-support/operational-policies/rate-limit-policy/management-api-endpoint-rate-limits). Actions offre toutefois un moyen d’indiquer plusieurs modifications aux métadonnées de l’utilisateur tout en n’effectuant qu’une seule requête à la Management API.

**Avant**

```javascript lines theme={null}
function myRulesFunction(user, context, callback) {
	user.app_metadata = user.app_metadata || {}; 
	user.app_metadata.roles = user.app_metadata.roles || [];
	user.app_metadata.roles.push("administrator"); 

	auth0.users
		.updateAppMetadata(user.user_id, user.app_metadata) 
		.then(() => callback(null, user, context))
		.catch((err) => callback(err));

	// ... code supplémentaire
}
```

Si des Rules suivantes doivent mettre à jour les métadonnées utilisateur, elles devront alors appeler la Management API séparément, ce qui augmente la probabilité d’atteindre la [limite de débit](/docs/fr-ca/troubleshoot/customer-support/operational-policies/rate-limit-policy/management-api-endpoint-rate-limits).

**Après**

```js lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
	const userRolesUpdated = event.user.app_metadata.roles || [];
	userRolesUpdated.push("administrator"); 

	// Remarquez les deux méthodes différentes ici. 
	api.user.setAppMetadata("roles", userRolesUpdated);
	api.user.setUserMetadata("hasRoles", true);

	// ... code supplémentaire
};
```

Si des Actions exécutées par la suite doivent mettre à jour les métadonnées utilisateur, elles devront appeler `api.user.setUserMetadata` ou `api.user.setAppMetadata`. Dans Actions, plusieurs appels à ces fonctions, dans une ou plusieurs Actions, se traduiront par un seul appel à la Management API une fois le flux terminé.

<div id="convert-other-management-api-calls">
  ### Convertir d’autres appels à la Management API
</div>

En général, nous ne recommandons pas d’appeler la Management API à partir d’un chemin critique à fort trafic, comme les Rules ou les Actions. Les requêtes vers toutes les API Auth0 sont [assujetties à des limites de débit](/docs/fr-ca/troubleshoot/customer-support/operational-policies/rate-limit-policy), y compris les appels effectués depuis des points d’extensibilité, et appeler une API pour toutes les connexions pourrait facilement entraîner des connexions échouées pendant les périodes de fort trafic.

Cependant, si ces appels sont nécessaires et configurés de manière à éviter les limites de débit, il est possible d’appeler la Management API depuis des Actions. Comme indiqué plus tôt dans cet article, dans la section "Comprendre les limites", les Actions ne reçoivent pas de jeton d’accès pour la Management API; vous devrez donc obtenir un jeton d’accès avant d’activer votre Action :

1. [Enregistrez une application Machine-to-Machine et autorisez-la pour la Management API](/docs/fr-ca/get-started/auth0-overview/create-applications/machine-to-machine-apps).
2. Enregistrez le **Client ID** et le **Client Secret** dans l’Action.
3. [Obtenez un jeton d’accès pour la Management API](/docs/fr-ca/secure/tokens/access-tokens/management-api-access-tokens/get-management-api-access-tokens-for-production).
4. Appelez la Management API :

   <Warning>
     Les Actions ne peuvent pas enregistrer de données d’une exécution à l’autre; il n’est donc pas possible de mettre le jeton d’accès en cache pendant une période prolongée. Comme chaque requête à la Management API exige aussi une requête à l’Authentication API, appeler la Management API est une opération très coûteuse.
   </Warning>

**Avant**

```javascript lines theme={null}
function myRulesFunction(user, context, callback) {
	const ManagementClient = require("auth0@2.9.1").ManagementClient; 
	const managementClientInstance = new ManagementClient({
		// Ces valeurs proviennent des variables globales intégrées de Rules
		token: auth0.accessToken, 
		domain: auth0.domain,
	}); 

	managementClientInstance.users.assignRoles(
		{ id: user.user_id }, 
		{ roles: ["ROLE_ID_TO_ADD"] }, 
		(error, user) => {
			if (error) {
				return callback(error);
			}

			// ... code supplémentaire
		}
	);
}
```

**Après**

```javascript lines theme={null}
const auth0Sdk = require("auth0");
exports.onExecutePostLogin = async (event, api) => {
	const ManagementClient = auth0Sdk.ManagementClient;

	// Ceci effectuera un appel d'API d'authentification
	const managementClientInstance = new ManagementClient({
		// Ces valeurs proviennent d'une application machine-to-machine
		domain: event.secrets.M2M_DOMAIN,
		clientId: event.secrets.M2M_CLIENT_ID,
		clientSecret: event.secrets.M2M_CLIENT_SECRET,
		scope: "update:users"
	});

	managementClientInstance.users.assignRoles(
		{ id: event.user.user_id }, 
		{ roles: ["ROLE_ID_TO_ADD"]}, 
		(error, user) => {
			if (error) {
				return api.access.deny(error.message);
			}

			// ... code supplémentaire
		}
	);
};
```

<div id="convert-redirects">
  ### Convertir les redirections
</div>

Les Rules peuvent rediriger un utilisateur en cours de connexion vers une page externe, puis attendre une réponse. Dans ce cas, toutes les Rules qui précèdent la redirection s’exécutent deux fois : une fois avant la redirection et une autre au retour de la réponse. La logique de redirection et de réponse se trouve généralement dans la même Rule.

Dans Actions, le pipeline d’Actions est mis en pause au moment de la redirection, puis reprend lorsque l’utilisateur revient. De plus, la fonction exportée qui déclenche la redirection est distincte du callback de redirection.

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  La mise en œuvre correcte de toutes les redirections dans Actions dépasse la portée de ce guide. Pour en savoir plus, consultez [Redirection avec Actions](/docs/fr-ca/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/redirect-with-actions).
</Callout>

**Avant**

```javascript lines theme={null}
function myRulesFunction(user, context, callback) {
    if (context.protocol === "redirect-callback") {
        // L'utilisateur a été redirigé vers le point de terminaison /continue
        user.app_metadata.wasRedirected = true;
        return callback(null, user, context);
    } else if (
        context.protocol === "oauth2-password" ||
        context.protocol === "oauth2-refresh-token" ||
        context.protocol === "oauth2-resource-owner"
    ) {
        // L'utilisateur ne peut pas être redirigé
        return callback(null, user, context);
    }
    // L'utilisateur se connecte directement
    if (!user.app_metadata.wasRedirected) {
        context.redirect = {
            url: "https://example.com",
        };
        callback(null, user, context);
    }
}
```

**Après**

```js lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
    api.accessToken.setClaim("https://dev.TLD/wasRedirected", true)
```

<div id="convert-current-sso-clients-references">
  ### Convertir les références aux clients SSO actuels
</div>

L’objet `context.sso` des Rules fournit des renseignements sur la session en cours et sur les clients qui l’utilisent. Pour en savoir plus, consultez l’entrée `context.sso` dans [Propriétés de l’objet context dans les Rules](/docs/fr-ca/customize/rules/context-object). Des renseignements semblables sont disponibles dans l’objet `event.session` des Actions.

**Avant**

```javascript lines theme={null}
function (user, context, callback) {

  const clients = context.sso?.current_clients ?? []; 

  if (clients.length > 0) { 
	context.idToken.clients = clients.join(" "); 
  }

  return callback(null, user, context);
}
```

**Après**

```js lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
  const clients = event?.session?.clients ?? []; 

  if (clients.length > 0) { 
    api.idToken.setCustomClaim('clients', clients.map(c=> c?.client_id).join(" ")); 
  }
};
```

<div id="complete-the-migration">
  ## Terminer la migration
</div>

Une fois votre nouveau code Actions rédigé et testé, vous devez activer l’Action et désactiver la Rule. Ces deux tâches peuvent être effectuées rapidement l’une après l’autre, mais selon l’ordre choisi, il peut y avoir une courte période pendant laquelle les deux s’exécutent, ou aucune des deux. Comme les Rules actives s’exécutent avant les Actions déployées, si vous commencez par la fin de votre pipeline de Rules et remontez vers le début, vous pouvez conserver une partie de la logique dans les Rules pendant que vous créez et testez le reste dans les Actions.
