97 lines
2.3 KiB
Go
97 lines
2.3 KiB
Go
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 ""
|
|
}
|
|
|