Merge pull request #565 from crashiura/validate-web-app Validate web app
Syfaro syfaro@huefox.com
Wed, 19 Oct 2022 20:35:52 -0400
2 files changed,
68 insertions(+),
0 deletions(-)
M
helpers.go
→
helpers.go
@@ -1,7 +1,14 @@
package tgbotapi import ( + "crypto/hmac" + "crypto/sha256" + "encoding/hex" + "errors" + "fmt" "net/url" + "sort" + "strings" ) // NewMessage creates a new Message.@@ -943,3 +950,38 @@ // scope and language code.
func NewDeleteMyCommandsWithScopeAndLanguage(scope BotCommandScope, languageCode string) DeleteMyCommandsConfig { return DeleteMyCommandsConfig{Scope: &scope, LanguageCode: languageCode} } + +// ValidateWebAppData validate data received via the Web App +// https://core.telegram.org/bots/webapps#validating-data-received-via-the-web-app +func ValidateWebAppData(token, telegramInitData string) (bool, error) { + initData, err := url.ParseQuery(telegramInitData) + if err != nil { + return false, fmt.Errorf("error parsing data %w", err) + } + + dataCheckString := make([]string, 0, len(initData)) + for k, v := range initData { + if k == "hash" { + continue + } + if len(v) > 0 { + dataCheckString = append(dataCheckString, fmt.Sprintf("%s=%s", k, v[0])) + } + } + + sort.Strings(dataCheckString) + + secret := hmac.New(sha256.New, []byte("WebAppData")) + secret.Write([]byte(token)) + + hHash := hmac.New(sha256.New, secret.Sum(nil)) + hHash.Write([]byte(strings.Join(dataCheckString, "\n"))) + + hash := hex.EncodeToString(hHash.Sum(nil)) + + if initData.Get("hash") != hash { + return false, errors.New("hash not equal") + } + + return true, nil +}
M
helpers_test.go
→
helpers_test.go
@@ -234,3 +234,29 @@ dice.Emoji != "🏀" {
t.Fail() } } + +func TestValidateWebAppData(t *testing.T) { + t.Run("success", func(t *testing.T) { + token := "5473903189:AAFnHnISQMP5UQQ5MEaoEWvxeiwNgz2CN2U" + initData := "query_id=AAG1bpMJAAAAALVukwmZ_H2t&user=%7B%22id%22%3A160657077%2C%22first_name%22%3A%22Yury%20R%22%2C%22last_name%22%3A%22%22%2C%22username%22%3A%22crashiura%22%2C%22language_code%22%3A%22en%22%7D&auth_date=1656804462&hash=8d6960760a573d3212deb05e20d1a34959c83d24c1bc44bb26dde49a42aa9b34" + result, err := ValidateWebAppData(token, initData) + if err != nil { + t.Fail() + } + if !result { + t.Fail() + } + }) + + t.Run("error", func(t *testing.T) { + token := "5473903189:AAFnHnISQMP5UQQ5MEaoEWvxeiwNgz2CN2U" + initData := "asdfasdfasdfasdfasdf" + result, err := ValidateWebAppData(token, initData) + if err == nil { + t.Fail() + } + if result { + t.Fail() + } + }) +}