package telegram import ( "crypto/hmac" "crypto/sha256" "encoding/hex" "git.ddd.rip/ptrcnull/modweb" "github.com/gofiber/fiber/v2" "html/template" "log" "net/url" "strconv" ) type Module struct { BotID string Token string Origin string Callback func(data *LoginData)*modweb.User } func (m Module) FriendlyName() string { return "Telegram Login" } func (m Module) Name() string { return "auth-telegram" } func (m Module) Init(mm *modweb.ModuleManager) { secretSum := sha256.Sum256([]byte(m.Token)) app := mm.Fiber() app.Post("/callback", func(ctx *fiber.Ctx) error { session := mm.Session(ctx) defer session.Save() if session.Get("user") != nil { return ctx.Status(200).JSON(fiber.Map{"ok": false}) } var data LoginData err := ctx.BodyParser(&data) if err != nil { return err } if data.Event != "auth_result" { return ctx.Status(200).JSON(fiber.Map{"ok": false}) } h := hmac.New(sha256.New, secretSum[:]) h.Write([]byte("auth_date=" + strconv.Itoa(data.Result.AuthDate) + "\n")) h.Write([]byte("first_name=" + data.Result.FirstName + "\n")) h.Write([]byte("id=" + strconv.Itoa(data.Result.ID) + "\n")) h.Write([]byte("photo_url=" + data.Result.PhotoURL + "\n")) h.Write([]byte("username=" + data.Result.Username)) hash := hex.EncodeToString(h.Sum(nil)) if hash != data.Result.Hash { log.Println("hash mismatch", hash, data.Result.Hash) return ctx.Status(200).JSON(fiber.Map{"ok": false}) } user := m.Callback(&data) if user != nil { user.Save(session) } return ctx.Status(200).JSON(fiber.Map{"ok": true}) }) } func (m Module) Hidden() bool { return true } func (m Module) MinAccessLevel() int64 { return -1 } func (m Module) LoginURL() template.URL { callback := "fetch('/auth-telegram/callback', { method: 'POST', body: ev.data, headers: { 'Content-Type': 'application/json' }, credentials: 'same-origin' }).then(() => { window.location = '/' }).catch(alert)" params := url.Values{} params.Set("bot_id", m.BotID) params.Set("origin", m.Origin) destination := "https://oauth.telegram.org/auth?" + params.Encode() return template.URL("javascript:(()=>{" + "window.addEventListener('message',(ev)=>{" + callback + "});" + "window.open('" + destination + "', '_blank')" + "})()") } func (m Module) RegisterURL() template.URL { return "" }