validate web app hash
parent
537c005643
commit
ffc28cfbac
42
helpers.go
42
helpers.go
|
@ -1,7 +1,14 @@
|
||||||
package tgbotapi
|
package tgbotapi
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/hmac"
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/hex"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewMessage creates a new Message.
|
// NewMessage creates a new Message.
|
||||||
|
@ -925,3 +932,38 @@ func NewDeleteMyCommandsWithScope(scope BotCommandScope) DeleteMyCommandsConfig
|
||||||
func NewDeleteMyCommandsWithScopeAndLanguage(scope BotCommandScope, languageCode string) DeleteMyCommandsConfig {
|
func NewDeleteMyCommandsWithScopeAndLanguage(scope BotCommandScope, languageCode string) DeleteMyCommandsConfig {
|
||||||
return DeleteMyCommandsConfig{Scope: &scope, LanguageCode: languageCode}
|
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
|
||||||
|
}
|
||||||
|
|
|
@ -234,3 +234,41 @@ func TestNewDiceWithEmoji(t *testing.T) {
|
||||||
t.Fail()
|
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 bad init data", func(t *testing.T) {
|
||||||
|
token := "5473903189:AAFnHnISQMP5UQQ5MEaoEWvxeiwNgz2CN2U"
|
||||||
|
initData := "asdfasdfasdfasdfasdf"
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue