TelegramMiniappValidation (telegram_miniapp_validation v0.1.0)

View Source

Provides functionality to validate Telegram Mini App initialization data.

This module implements the validation algorithm described in the Telegram Mini Apps documentation: https://docs.telegram-mini-apps.com/platform/init-data#validating

Summary

Functions

Parses the initialization data and extracts the hash value.

Checks if the provided hash is valid for the given data and bot token.

Validates the initialization data from a Telegram Mini App.

Validates the auth_date parameter to ensure it's not too old.

Functions

parse_and_extract_hash(init_data)

@spec parse_and_extract_hash(String.t()) ::
  {:ok, {map(), String.t()}} | {:error, String.t()}

Parses the initialization data and extracts the hash value.

Parameters

  • init_data: The raw initialization data string from the Telegram Mini App

Returns

  • {:ok, {data_map, hash}}: If parsing is successful, returns the data map and hash
  • {:error, reason}: If parsing fails, returns the reason for failure

valid_hash?(init_data, hash, bot_token)

@spec valid_hash?(map(), String.t(), String.t()) :: boolean()

Checks if the provided hash is valid for the given data and bot token.

Parameters

  • data_map: The parsed data map
  • hash: The hash value to validate
  • bot_token: The Telegram Bot token used to sign the data

Returns

  • true: If the hash is valid
  • false: If the hash is invalid

validate(init_data, bot_token, max_age_seconds \\ 86400)

@spec validate(String.t(), String.t(), non_neg_integer()) ::
  {:ok, map()} | {:error, String.t()}

Validates the initialization data from a Telegram Mini App.

The validation process follows these steps:

  1. Parse the query string into key-value pairs
  2. Extract the hash value and remove it from the pairs
  3. Sort the remaining pairs alphabetically
  4. Create a data check string by joining the pairs with newlines
  5. Create an HMAC-SHA256 signature of the bot token using "WebAppData" as the key
  6. Create an HMAC-SHA256 signature of the data check string using the result from step 5 as the key
  7. Compare the calculated hash with the provided hash

Parameters

  • init_data: The raw initialization data string from the Telegram Mini App
  • bot_token: The Telegram Bot token used to sign the data
  • max_age_seconds: Optional maximum age in seconds for the auth_date parameter (default: 86400 - 24 hours)

Returns

  • {:ok, parsed_data}: If validation is successful, returns the parsed data as a map
  • {:error, reason}: If validation fails, returns the reason for failure

Examples

This example shows the structure of the returned data, but in a real scenario, you would need to use a valid hash and bot token:

# Using 0 for max_age_seconds to skip auth_date validation in this example
iex> init_data = "query_id=AAHdF6IQAAAAAN0XohDhrOrc&user=%7B%22id%22%3A279058397%7D&auth_date=1662771648&hash=mock_hash"
iex> TelegramMiniappValidation.parse_and_extract_hash(init_data)
{:ok, {%{"auth_date" => "1662771648", "query_id" => "AAHdF6IQAAAAAN0XohDhrOrc", "user" => %{"id" => 279058397}}, "mock_hash"}}

validate_auth_date(data_map, max_age_seconds)

@spec validate_auth_date(map(), non_neg_integer()) :: :ok | {:error, String.t()}

Validates the auth_date parameter to ensure it's not too old.

Parameters

  • data_map: The parsed data map
  • max_age_seconds: Maximum age in seconds for the auth_date parameter

Returns

  • :ok: If the auth_date is valid
  • {:error, reason}: If the auth_date is invalid or missing