From 422f7169ad6576f48a21695d823cf4839d3e935a Mon Sep 17 00:00:00 2001 From: Paul Larsen Date: Sun, 7 Jul 2024 12:59:33 +0100 Subject: [PATCH] Improve webapp sample comments and usage (#171) --- samples/webappBot/index.html | 10 +++++++-- samples/webappBot/routes.go | 41 +++++++++++++++++++++++++++++------- 2 files changed, 41 insertions(+), 10 deletions(-) diff --git a/samples/webappBot/index.html b/samples/webappBot/index.html index 469eb533..8e1ea682 100644 --- a/samples/webappBot/index.html +++ b/samples/webappBot/index.html @@ -24,10 +24,16 @@ - \ No newline at end of file + diff --git a/samples/webappBot/routes.go b/samples/webappBot/routes.go index 3e1fb9ba..539b6951 100644 --- a/samples/webappBot/routes.go +++ b/samples/webappBot/routes.go @@ -1,9 +1,13 @@ package main import ( + "encoding/json" + "fmt" "net/http" + "net/url" "text/template" + "github.com/PaulSonOfLars/gotgbot/v2" "github.com/PaulSonOfLars/gotgbot/v2/ext" ) @@ -24,17 +28,38 @@ func index(webappURL string) func(writer http.ResponseWriter, request *http.Requ } func validate(token string) func(writer http.ResponseWriter, request *http.Request) { - return func(writer http.ResponseWriter, request *http.Request) { - ok, err := ext.ValidateWebAppQuery(request.URL.Query(), token) + return func(w http.ResponseWriter, r *http.Request) { + // Our index.html sends the WebApp.initData field over the X-Auth header. + // We parse this string as a URL query. + authQuery, err := url.ParseQuery(r.Header.Get("X-Auth")) if err != nil { - writer.WriteHeader(http.StatusBadRequest) - writer.Write([]byte("validation failed; error: " + err.Error())) + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte("validation failed; failed to parse auth query: " + err.Error())) + } + + // We validate that the query has been hashed correctly, ensuring data can be trusted. + ok, err := ext.ValidateWebAppQuery(authQuery, token) + if err != nil { + w.WriteHeader(http.StatusUnauthorized) + w.Write([]byte("validation failed; error: " + err.Error())) + return + } + if !ok { + w.WriteHeader(http.StatusUnauthorized) + w.Write([]byte("validation failed; data cannot be trusted.")) return } - if ok { - writer.Write([]byte("validation success; user is authenticated.")) - } else { - writer.Write([]byte("validation failed; data cannot be trusted.")) + + // Once we've confirmed the data can be trusted, we unmarshal any data we may need to use. + var u gotgbot.User + err = json.Unmarshal([]byte(authQuery.Get("user")), &u) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte("validation failed; failed to unmarshal user: " + err.Error())) + return } + + // And then we can choose to either return it, or work with it. + w.Write([]byte(fmt.Sprintf("validation success; user '%s' is authenticated (id: %d).", u.FirstName, u.Id))) } }