# Firmas y Base64

Los servicios externos suelen firmar sus solicitudes o esperar una firma tuya, y pasan los datos en Base64. Para eso el código tiene tres funciones.

## hash_hmac

```js
hash_hmac(algo, text, key, format)
```

Calcula la firma HMAC de un texto con una clave secreta.

| Parámetro | Tipo | Qué pasar |
|---|---|---|
| `algo` | Cadena | El algoritmo: `'md5'`, `'sha1'`, `'sha256'`, `'sha512'` o `'md4'` |
| `text` | Cadena | Qué firmar |
| `key` | Cadena | La clave secreta |
| `format` | Cadena, opcional | `'base64'`: el resultado en Base64. Sin el parámetro, hexadecimal en minúsculas |

**Devuelve** la firma como cadena. Si `algo`, `text` o `key` están vacíos, devuelve `undefined`.

> [!WARNING]
> Pasa solo algoritmos de la lista. Con cualquier otro nombre, como `'sha3'`, la función lanza `TypeError: hash_hmac: unsupported algorithm "sha3"…`. Si no lo capturas con `try...catch`, el código se detiene con este error.

Verifica la firma de una solicitud entrante: el servicio de la tienda la envía en el encabezado `X-Signature`, y la clave secreta se guarda en una variable global del bot.

```js
var secret = getGlobalVariable('shop_key');
var expected = hash_hmac('sha256', request.body, secret);

if (expected !== request.headers['x-signature']) {
    throw new Error('Firma no válida');
}

if (setContactById(request.data.contact_id)) {
    setContactVariable('order_status', request.data.status);
}
```

Si la firma no coincide, el código se detiene y el bloque responde a la solicitud con el código `422`.

## base64_encode

```js
base64_encode(text)
```

Codifica un texto en Base64.

| Parámetro | Tipo | Qué pasar |
|---|---|---|
| `text` | Cadena | Qué codificar. Las letras no latinas se codifican como UTF-8 |

**Devuelve** una cadena Base64.

```js
var auth = 'Basic ' + base64_encode('flowers:secret-password');
```

## base64_decode

```js
base64_decode(text)
```

Decodifica una cadena de Base64.

| Parámetro | Tipo | Qué pasar |
|---|---|---|
| `text` | Cadena | Una cadena en Base64 estándar |

**Devuelve** el texto decodificado, o `undefined` si la cadena no es Base64.

```js
var payload = base64_decode(request.data.payload);
var order = payload ? JSON.parse(payload) : null;
```
