# Signatures and Base64

Third-party services often sign their requests or expect a signature from you, and pass data in Base64. The code has three functions for this.

## hash_hmac

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

Calculates an HMAC signature of a text with a secret key.

| Parameter | Type | What to pass |
|---|---|---|
| `algo` | String | The algorithm: `'md5'`, `'sha1'`, `'sha256'`, `'sha512'` or `'md4'` |
| `text` | String | What to sign |
| `key` | String | The secret key |
| `format` | String, optional | `'base64'` — the result in Base64. Without the parameter — hexadecimal in lower case |

**Returns** the signature as a string. If `algo`, `text` or `key` is empty, returns `undefined`.

> [!WARNING]
> Pass only algorithms from the list. With any other name, such as `'sha3'`, the function throws `TypeError: hash_hmac: unsupported algorithm "sha3"…`. Unless you catch it with `try...catch`, the code stops with this error.

Verify the signature of an incoming request: the shop service sends it in the `X-Signature` header, and the secret key is kept in a global variable of the bot.

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

if (expected !== request.headers['x-signature']) {
    throw new Error('Invalid signature');
}

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

If the signature does not match, the code stops, and the block answers the request with code `422`.

## base64_encode

```js
base64_encode(text)
```

Encodes text in Base64.

| Parameter | Type | What to pass |
|---|---|---|
| `text` | String | What to encode. Non-Latin letters are encoded as UTF-8 |

**Returns** a Base64 string.

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

## base64_decode

```js
base64_decode(text)
```

Decodes a string from Base64.

| Parameter | Type | What to pass |
|---|---|---|
| `text` | String | A string in standard Base64 |

**Returns** the decoded text, or `undefined` if the string is not Base64.

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