snow/handlers/discord.go

92 lines
2.6 KiB
Go
Raw Normal View History

2023-12-09 15:35:33 +00:00
package handlers
import (
"net/http"
2023-12-09 15:35:33 +00:00
"net/url"
"time"
2023-12-09 15:35:33 +00:00
"github.com/ectrc/snow/aid"
p "github.com/ectrc/snow/person"
"github.com/ectrc/snow/storage"
"github.com/goccy/go-json"
2023-12-09 15:35:33 +00:00
"github.com/gofiber/fiber/v2"
)
func GetDiscordOAuthURL(c *fiber.Ctx) error {
code := c.Query("code")
if code == "" {
return c.Status(200).SendString("https://discord.com/oauth2/authorize?client_id="+ aid.Config.Discord.ID +"&redirect_uri="+ url.QueryEscape(aid.Config.API.Host + aid.Config.API.Port +"/snow/discord") + "&response_type=code&scope=identify")
}
client := &http.Client{}
oauthRequest, err := client.PostForm("https://discord.com/api/v10/oauth2/token", url.Values{
"client_id": {aid.Config.Discord.ID},
"client_secret": {aid.Config.Discord.Secret},
"grant_type": {"authorization_code"},
"code": {code},
"redirect_uri": {aid.Config.API.Host + aid.Config.API.Port +"/snow/discord"},
})
if err != nil {
return c.Status(500).JSON(aid.JSON{"error":err.Error()})
}
var body struct {
AccessToken string `json:"access_token"`
RenewToken string `json:"refresh_token"`
}
err = json.NewDecoder(oauthRequest.Body).Decode(&body)
if err != nil {
return c.Status(500).JSON(aid.JSON{"error":err.Error()})
}
userRequest, err := http.NewRequest("GET", "https://discord.com/api/v10/users/@me", nil)
if err != nil {
return c.Status(500).JSON(aid.JSON{"error":err.Error()})
}
userRequest.Header.Set("Authorization", "Bearer " + body.AccessToken)
userResponse, err := client.Do(userRequest)
if err != nil {
return c.Status(500).JSON(aid.JSON{"error":err.Error()})
}
var user struct {
ID string `json:"id"`
Username string `json:"username"`
Avatar string `json:"avatar"`
Banner string `json:"banner"`
}
err = json.NewDecoder(userResponse.Body).Decode(&user)
if err != nil {
return c.Status(500).JSON(aid.JSON{"error":err.Error()})
}
person := p.FindByDiscord(user.ID)
if person == nil {
return c.Status(404).JSON(aid.JSON{"error":"Person not found. Please create an account first."})
}
person.Discord.AccessToken = body.AccessToken
person.Discord.RefreshToken = body.RenewToken
person.Discord.Username = user.Username
person.Discord.Avatar = user.Avatar
person.Discord.Banner = user.Banner
storage.Repo.SaveDiscordPerson(person.Discord)
access, err := aid.JWTSign(aid.JSON{
"snow_id": person.ID, // custom
"frontend": true,
"creation_date": time.Now().Format("2006-01-02T15:04:05.999Z"),
})
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(aid.ErrorInternalServer)
}
c.Cookie(&fiber.Cookie{
Name: "access_token",
Value: access,
})
return c.Redirect(aid.Config.API.Host + aid.Config.API.FrontendPort + "/attempt")
2023-12-09 15:35:33 +00:00
}