|
1 | 1 | package tgbotapi
|
2 | 2 |
|
3 | 3 | import (
|
| 4 | + "crypto/hmac" |
| 5 | + "crypto/sha256" |
| 6 | + "encoding/hex" |
| 7 | + "errors" |
| 8 | + "fmt" |
4 | 9 | "net/url"
|
| 10 | + "sort" |
| 11 | + "strings" |
5 | 12 | )
|
6 | 13 |
|
7 | 14 | // NewMessage creates a new Message.
|
@@ -943,3 +950,38 @@ func NewDeleteMyCommandsWithScope(scope BotCommandScope) DeleteMyCommandsConfig
|
943 | 950 | func NewDeleteMyCommandsWithScopeAndLanguage(scope BotCommandScope, languageCode string) DeleteMyCommandsConfig {
|
944 | 951 | return DeleteMyCommandsConfig{Scope: &scope, LanguageCode: languageCode}
|
945 | 952 | }
|
| 953 | + |
| 954 | +// ValidateWebAppData validate data received via the Web App |
| 955 | +// https://core.telegram.org/bots/webapps#validating-data-received-via-the-web-app |
| 956 | +func ValidateWebAppData(token, telegramInitData string) (bool, error) { |
| 957 | + initData, err := url.ParseQuery(telegramInitData) |
| 958 | + if err != nil { |
| 959 | + return false, fmt.Errorf("error parsing data %w", err) |
| 960 | + } |
| 961 | + |
| 962 | + dataCheckString := make([]string, 0, len(initData)) |
| 963 | + for k, v := range initData { |
| 964 | + if k == "hash" { |
| 965 | + continue |
| 966 | + } |
| 967 | + if len(v) > 0 { |
| 968 | + dataCheckString = append(dataCheckString, fmt.Sprintf("%s=%s", k, v[0])) |
| 969 | + } |
| 970 | + } |
| 971 | + |
| 972 | + sort.Strings(dataCheckString) |
| 973 | + |
| 974 | + secret := hmac.New(sha256.New, []byte("WebAppData")) |
| 975 | + secret.Write([]byte(token)) |
| 976 | + |
| 977 | + hHash := hmac.New(sha256.New, secret.Sum(nil)) |
| 978 | + hHash.Write([]byte(strings.Join(dataCheckString, "\n"))) |
| 979 | + |
| 980 | + hash := hex.EncodeToString(hHash.Sum(nil)) |
| 981 | + |
| 982 | + if initData.Get("hash") != hash { |
| 983 | + return false, errors.New("hash not equal") |
| 984 | + } |
| 985 | + |
| 986 | + return true, nil |
| 987 | +} |
0 commit comments