feat: add telegram mini app dashboard
This commit is contained in:
@@ -77,6 +77,64 @@ public sealed class TelegramAuthServiceTests
|
||||
Assert.False(verified);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void VerifyWebAppInitData_ShouldAcceptValidTelegramWebAppPayload()
|
||||
{
|
||||
const string botToken = "test-bot-token";
|
||||
var initData = CreateWebAppInitData(
|
||||
botToken,
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
["auth_date"] = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString(),
|
||||
["query_id"] = "AAHdF6IQAAAAAN0XohDhrOrc",
|
||||
["user"] = """{"id":424242,"first_name":"Ada","last_name":"Lovelace","username":"ada"}"""
|
||||
});
|
||||
var service = new TelegramAuthService(CreateConfiguration(botToken));
|
||||
|
||||
var verified = service.VerifyWebAppInitData(initData, out var telegramId, out var name);
|
||||
|
||||
Assert.True(verified);
|
||||
Assert.Equal(424242L, telegramId);
|
||||
Assert.Equal("Ada Lovelace", name);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void VerifyWebAppInitData_ShouldRejectTamperedHash()
|
||||
{
|
||||
const string botToken = "test-bot-token";
|
||||
var initData = CreateWebAppInitData(
|
||||
botToken,
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
["auth_date"] = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString(),
|
||||
["user"] = """{"id":424242,"first_name":"Ada"}"""
|
||||
});
|
||||
var tamperedInitData = initData.Replace("hash=", "hash=00", StringComparison.Ordinal);
|
||||
var service = new TelegramAuthService(CreateConfiguration(botToken));
|
||||
|
||||
var verified = service.VerifyWebAppInitData(tamperedInitData, out _, out _);
|
||||
|
||||
Assert.False(verified);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void VerifyWebAppInitData_ShouldRejectExpiredPayload()
|
||||
{
|
||||
const string botToken = "test-bot-token";
|
||||
var initData = CreateWebAppInitData(
|
||||
botToken,
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
["auth_date"] = DateTimeOffset.UtcNow.AddDays(-2).ToUnixTimeSeconds().ToString(),
|
||||
["user"] = """{"id":424242,"first_name":"Ada"}"""
|
||||
});
|
||||
var service = new TelegramAuthService(CreateConfiguration(botToken));
|
||||
|
||||
var verified = service.VerifyWebAppInitData(initData, out _, out _);
|
||||
|
||||
Assert.False(verified);
|
||||
}
|
||||
|
||||
private static IConfiguration CreateConfiguration(string botToken) =>
|
||||
new ConfigurationBuilder()
|
||||
.AddInMemoryCollection(new Dictionary<string, string?>
|
||||
@@ -106,4 +164,27 @@ public sealed class TelegramAuthServiceTests
|
||||
var hashBytes = HMACSHA256.HashData(secretKey, Encoding.UTF8.GetBytes(dataCheckString));
|
||||
return Convert.ToHexString(hashBytes).ToLowerInvariant();
|
||||
}
|
||||
|
||||
private static string CreateWebAppInitData(string botToken, IReadOnlyDictionary<string, string> values)
|
||||
{
|
||||
var hash = ComputeTelegramWebAppHash(botToken, values);
|
||||
var encodedPairs = values
|
||||
.OrderBy(pair => pair.Key, StringComparer.Ordinal)
|
||||
.Select(pair => $"{Uri.EscapeDataString(pair.Key)}={Uri.EscapeDataString(pair.Value)}")
|
||||
.Append($"hash={hash}");
|
||||
|
||||
return string.Join("&", encodedPairs);
|
||||
}
|
||||
|
||||
private static string ComputeTelegramWebAppHash(string botToken, IReadOnlyDictionary<string, string> values)
|
||||
{
|
||||
var dataCheckString = string.Join(
|
||||
"\n",
|
||||
values
|
||||
.OrderBy(pair => pair.Key, StringComparer.Ordinal)
|
||||
.Select(pair => $"{pair.Key}={pair.Value}"));
|
||||
var secretKey = HMACSHA256.HashData(Encoding.UTF8.GetBytes("WebAppData"), Encoding.UTF8.GetBytes(botToken));
|
||||
var hashBytes = HMACSHA256.HashData(secretKey, Encoding.UTF8.GetBytes(dataCheckString));
|
||||
return Convert.ToHexString(hashBytes).ToLowerInvariant();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user