Skip to content

Commit

Permalink
Add validity methods.
Browse files Browse the repository at this point in the history
  • Loading branch information
onrik committed Aug 15, 2024
1 parent 120be91 commit 65c3a9a
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 0 deletions.
67 changes: 67 additions & 0 deletions validity.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package micha

import (
"crypto/hmac"
"crypto/sha256"
"errors"
"fmt"
"net/url"
"sort"
"strings"
)

var (
ErrInvalidHash = errors.New("invalid hash")
)

// ValidateAuthCallback - https://core.telegram.org/widgets/login#checking-authorization
func ValidateAuthCallback(values url.Values, botToken string) error {
secret := sha256.Sum256([]byte(botToken))

return validateHash(values, secret[:])
}

// ValidateWabAppData - https://core.telegram.org/bots/webapps#validating-data-received-via-the-mini-app
func ValidateWabAppData(values url.Values, botToken string) error {
hm := hmac.New(sha256.New, []byte("WebAppData"))
_, err := hm.Write([]byte(botToken))
if err != nil {
return err
}

secret := hm.Sum(nil)

return validateHash(values, secret)
}

func validateHash(values url.Values, secret []byte) error {
hm := hmac.New(sha256.New, secret)
_, err := hm.Write([]byte(buildCheckString(values)))
if err != nil {
return err
}

if fmt.Sprintf("%x", hm.Sum(nil)) != values.Get("hash") {
return ErrInvalidHash
}

return nil
}

func buildCheckString(values url.Values) string {
keys := []string{}
for key := range values {
if key == "hash" {
continue
}
keys = append(keys, key)
}

sort.Strings(keys)
parts := []string{}
for _, key := range keys {
parts = append(parts, fmt.Sprintf("%s=%s", key, values.Get(key)))
}

return strings.Join(parts, "\n")
}
43 changes: 43 additions & 0 deletions validity_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package micha

import (
"net/url"
"testing"

"github.com/stretchr/testify/require"
)

func TestBuildCheckString(t *testing.T) {
values := url.Values{
"id": {"12807202"},
"first_name": {"John"},
"username": {"doe"},
"photo_url": {"https://t.me/i/userpic/320/a4f15041-e6a3-4cf4-9363-b0cba2f66720.jpg"},
"auth_date": {"1722489598"},
"hash": {"a19016198a35deb3469a2af3c5aa1f40aa71941cf14cc20e7be8c6507b147061"},
}

require.Equal(t,
"auth_date=1722489598\nfirst_name=John\nid=12807202\nphoto_url=https://t.me/i/userpic/320/a4f15041-e6a3-4cf4-9363-b0cba2f66720.jpg\nusername=doe",
buildCheckString(values),
)
}

func TestValidateHash(t *testing.T) {
values := url.Values{
"id": {"12807202"},
"first_name": {"John"},
"username": {"doe"},
"photo_url": {"https://t.me/i/userpic/320/a4f15041-e6a3-4cf4-9363-b0cba2f66720.jpg"},
"auth_date": {"1722489598"},
"hash": {"aba23cb08c508bd952abb2a9b3c2e9b3d6a2c8726145ccea53bd660d7995b586"},
}

// Test valid
err := validateHash(values, []byte("111"))
require.Nil(t, err)

// Test invalid
err = validateHash(values, []byte("222"))
require.NotNil(t, err)
}

0 comments on commit 65c3a9a

Please sign in to comment.