BREAKING CHANGE: Requires PHP 8.5.0RC3 Changes: - Update Docker base image from php:8.4-fpm to php:8.5.0RC3-fpm - Enable ext-uri for native WHATWG URL parsing support - Update composer.json PHP requirement from ^8.4 to ^8.5 - Add ext-uri as required extension in composer.json - Move URL classes from Url.php85/ to Url/ directory (now compatible) - Remove temporary PHP 8.4 compatibility workarounds Benefits: - Native URL parsing with Uri\WhatWg\Url class - Better performance for URL operations - Future-proof with latest PHP features - Eliminates PHP version compatibility issues
86 lines
2.6 KiB
PHP
86 lines
2.6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Framework\Webhook\Security\Providers;
|
|
|
|
/**
|
|
* Telegram Webhook Signature Provider
|
|
*
|
|
* Telegram uses a different authentication mechanism than HMAC signatures.
|
|
* Instead, they recommend validating the webhook URL contains the bot token,
|
|
* or using a secret token in the X-Telegram-Bot-Api-Secret-Token header.
|
|
*
|
|
* @see https://core.telegram.org/bots/api#setwebhook
|
|
*/
|
|
final readonly class TelegramSignatureProvider implements SignatureProvider
|
|
{
|
|
/**
|
|
* Verify Telegram webhook authenticity
|
|
*
|
|
* Telegram recommends two approaches:
|
|
* 1. Include bot token in webhook URL path
|
|
* 2. Use secret_token parameter when setting webhook (sent in X-Telegram-Bot-Api-Secret-Token header)
|
|
*
|
|
* We use approach #2 for better security (token not in URL logs)
|
|
*
|
|
* @param string $payload Request body (not used for Telegram)
|
|
* @param string $signature Secret token from X-Telegram-Bot-Api-Secret-Token header
|
|
* @param string $secret Expected secret token (set when configuring webhook)
|
|
*/
|
|
public function verify(string $payload, string $signature, string $secret): bool
|
|
{
|
|
// Telegram secret token validation is simple string comparison
|
|
// Both strings are provided by the developer (no cryptographic signature)
|
|
return hash_equals($secret, $signature);
|
|
}
|
|
|
|
/**
|
|
* Parse signature from header value
|
|
*
|
|
* For Telegram, the signature is simply the secret token value
|
|
*/
|
|
public function parseSignature(string $headerValue): \App\Framework\Webhook\ValueObjects\WebhookSignature
|
|
{
|
|
return new \App\Framework\Webhook\ValueObjects\WebhookSignature(
|
|
algorithm: 'token',
|
|
signature: $headerValue,
|
|
timestamp: null
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Generate signature (not applicable for Telegram)
|
|
*
|
|
* Telegram doesn't generate signatures from payload.
|
|
* This method exists for SignatureProvider interface compliance.
|
|
*/
|
|
public function generateSignature(string $payload, string $secret): string
|
|
{
|
|
// For Telegram, we just return the secret token
|
|
// It's sent as-is in the X-Telegram-Bot-Api-Secret-Token header
|
|
return $secret;
|
|
}
|
|
|
|
/**
|
|
* Get the expected header name for Telegram webhooks
|
|
*/
|
|
public function getSignatureHeader(): string
|
|
{
|
|
return 'X-Telegram-Bot-Api-Secret-Token';
|
|
}
|
|
|
|
/**
|
|
* Get provider name
|
|
*/
|
|
public function getProviderName(): string
|
|
{
|
|
return 'telegram';
|
|
}
|
|
|
|
public function getAlgorithm(): string
|
|
{
|
|
return 'token';
|
|
}
|
|
}
|