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

> Conozca las prácticas recomendadas para ejecutar scripts de Action de bases de datos personalizadas.

# Prácticas recomendadas para ejecutar scripts de Action de bases de datos personalizadas

Un tipo de conexión de base de datos personalizada le permite configurar scripts de Action, que contienen código personalizado que Auth0 usa para interactuar con su almacén de identidades heredado. Los scripts de Action son funciones de JavaScript con nombre que aceptan un conjunto predefinido de parámetros.

<div id="webtask-containers">
  ## Contenedores de Webtask
</div>

Los scripts de Action se ejecutan dentro de un contenedor de Webtask individual con un límite de ejecución de aproximadamente 20 segundos. Una vez ejecutadas las funciones, el contenedor se recicla.

Cuando un contenedor se recicla, finaliza las operaciones pendientes del script de Action. Esto puede hacer que se devuelva un error y que el objeto `global` se restablezca. Para obtener más información sobre el objeto `global`, consulte [Prácticas recomendadas del entorno de scripts de Action de base de datos personalizada](/es/docs/authenticate/database-connections/custom-db/custom-database-connections-scripts/environment).

<div id="asynchronous-features">
  ## Características asíncronas
</div>

Las características asíncronas de JavaScript, incluidos los objetos [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) y las [funciones async](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function), son compatibles con los scripts de Action.

Puede usar características asíncronas para ejecutar operaciones sin bloqueo dentro de un script de Action, pero asegúrese de que estas operaciones no superen el límite de ejecución del contenedor de Webtask. Cuando el contenedor de Webtask se recicla, finaliza cualquier operación pendiente, lo que puede provocar un comportamiento inesperado o un error.

Si realiza una llamada a un servicio externo o a una API dentro de su script de Action, configure un tiempo de espera razonable para la función y [devuelva un error](#error-handling) si no se puede acceder al servicio externo o a la API.

<div id="examples">
  ### Ejemplos
</div>

Auth0 admite el uso de objetos [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) y [funciones async](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) en los scripts de Action.

<div id="promise-object">
  #### Objeto Promise
</div>

Este ejemplo usa el método `fetch` integrado de JavaScript, que obtiene un recurso a través de la red y luego devuelve un objeto Promise; está escrito con [cadenas de promesas](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises#chaining).

```javascript lines expandable theme={null}
function login(userNameOrEmail, password, callback) {
	const hashedPassword = hash(password);
	const apiEndpoint = 'https://example.com/api/authenticate';
	const options = {
		method: 'POST',
		body: {
			email: userNameOrEmail,
			password: hashedPassword
		}
	};

	fetch(apiEndpoint, options) 
		.then((response) => {
			if (!response.ok) {
				return callback(new Error(`HTTP error! Status: ${response.status}`));
			}

			return response.json();
		})
		.then((response) => {
			if (response.err) {
				return callback(new Error(`Error authenticating user: ${err}`));
			}

			let profile = {
				email: response.profileData.email,
				username: response.profileData.username
			};

			return callback(null, profile);
		})
		.catch((err) => {
			return callback(new Error(`An error occurred: ${err}`));
		});
  }
```

<div id="async-function">
  #### Función asíncrona
</div>

Este ejemplo usa el método `fetch` integrado de JavaScript, que obtiene un recurso de la red y luego devuelve un objeto Promise, y está escrito con [funciones asíncronas](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function).

```js lines expandable theme={null}
async function login(userNameOrEmail, password, callback) {
	const hashedPassword = hash(password);
	const apiEndpoint = 'https://example.com/api/authenticate';
	const options = {
		method: 'POST',
		body: {
			email: userNameOrEmail,
			password: hashedPassword
		}
	};

	const response = await fetch(apiEndpoint, options);

	if (!response.ok) {
		return callback(new Error(`HTTP error! Status: ${response.status}`));
	}

	const result = response.json();

	if (result.err) {
		return callback(new Error(`Error authenticating user: ${err}`));
	}

	let profile = {
		email: response.profileData.email,
		username: response.profileData.username
	};

	return callback(null, profile);
}
```

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

La función `callback` indica que la operación del script de Action ha finalizado y debe invocarse exactamente una vez. Un script de Action debe finalizar inmediatamente después de llamar a la función `callback`, preferiblemente usando explícitamente la instrucción `return`.

<Warning>
  Si la función `callback` se invoca más de una vez, puede dar lugar a resultados inesperados o errores.

  Si no se invoca la función `callback` en ningún momento, la ejecución del script de Action se bloqueará y se devolverá un error cuando se recicle el contenedor de Webtask.
</Warning>

<div id="asynchronous-processing">
  ### Procesamiento asíncrono
</div>

Si un script de Action utiliza procesamiento asíncrono, la función `callback` debe invocarse una vez que hayan finalizado todas las operaciones asíncronas.

<div id="parameters">
  ### Parámetros
</div>

Si se llama a la función `callback` sin parámetros, se ejecutará como si se hubiera pasado un parámetro `null`.

<div id="size">
  ## Tamaño
</div>

El tamaño total de la implementación de cualquier script de Action no debe superar los 100 kB. Esta limitación de tamaño no incluye los módulos `npm` importados. Para obtener más información sobre los módulos `npm`, consulte [Prácticas recomendadas para el entorno de scripts de Action de base de datos personalizada](/es/docs/authenticate/database-connections/custom-db/custom-database-connections-scripts/environment).

Cuanto mayor sea el tamaño de un script, mayor será la latencia introducida por el proceso de empaquetado y transporte que utiliza la plataforma Webtask. El tamaño afecta al rendimiento del sistema.

<div id="anonymous-functions">
  ## Funciones anónimas
</div>

Los scripts de Action pueden implementarse como funciones anónimas, pero no se recomienda. Las funciones anónimas dificultan la depuración del script de Action y la interpretación de la pila de llamadas que se genera como resultado de cualquier error excepcional. Para obtener más información sobre las funciones anónimas, consulta [IIFE on MDN Web Docs](https://developer.mozilla.org/en-US/docs/Glossary/IIFE).

<div id="error-handling">
  ## Manejo de errores
</div>

Pasa un objeto `Error` a la función `callback` con un mensaje descriptivo sobre el error:

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

<div id="security">
  ## Seguridad
</div>

<div id="database-interface-vs-api">
  ### Interfaz de base de datos frente a API
</div>

Asegúrese de proteger todas las comunicaciones entre Auth0 y su almacén de identidades heredado. Si su almacén de identidades heredado aún no tiene una API implementada, es muy recomendable que la implemente.

Si su almacén de identidades heredado tiene una API disponible, puede [registrar la API](/es/docs/get-started/auth0-overview/set-up-apis) en Auth0 y [crear una Action](/es/docs/manage-users/access-control/sample-use-cases-actions-with-authorization#deny-access-to-anyone-calling-an-api) para restringir el acceso de los usuarios finales.

Si su almacén de identidades heredado no tiene una API disponible —y no es viable implementar una—, igualmente puede comunicarse directamente con su base de datos. Asegúrese de [agregar las direcciones IP de Auth0 a la lista de permitidos de su firewall](/es/docs/secure/security-guidance/data-security/allowlist) para permitir el tráfico entrante desde Auth0.

<div id="identity-provider-tokens">
  ## Tokens del Proveedor de identidad
</div>

Si el objeto `user` devuelve las propiedades `access_token` y `refresh_token`, Auth0 las trata de forma diferente a otros tipos de información de usuario. Auth0 las almacena en la propiedad `identities` del objeto `user`:

```json lines theme={null}
{
	"email": "you@example.com",
	"updated_at": "2019-03-15T15:56:44.577Z",
	"user_id": "auth0|some_unique_id",
	"nickname": "a_nick_name",
	"identities": [ 
		{
			"user_id": "some_unique_id",
			"access_token": "e1b5.................92ba",
			"refresh_token": "a90c.................620b",
			"provider": "auth0", 
			"connection": "custom_db_name",
			"isSocial": false 
		}
  ], 
  "created_at": "2019-03-15T15:56:44.577Z",
  "last_ip": "192.168.1.1",
  "last_login": "2019-03-15T15:56:44.576Z",
  "logins_count": 3
}
```

Si desea recuperar alguna de estas propiedades con la <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> de Auth0, incluya el scope `read:user_idp_tokens` al [solicitar un Token de acceso](/es/docs/secure/tokens/access-tokens/management-api-access-tokens/get-management-api-access-tokens-for-production).
