2023-12-09 15:35:33 +00:00
|
|
|
package handlers
|
|
|
|
|
|
|
|
import (
|
2023-12-10 00:52:59 +00:00
|
|
|
"net/http"
|
2023-12-09 15:35:33 +00:00
|
|
|
"net/url"
|
2023-12-26 03:18:12 +00:00
|
|
|
"time"
|
2023-12-09 15:35:33 +00:00
|
|
|
|
|
|
|
"github.com/ectrc/snow/aid"
|
2023-12-10 00:52:59 +00:00
|
|
|
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 {
|
2023-12-10 00:52:59 +00:00
|
|
|
code := c.Query("code")
|
|
|
|
if code == "" {
|
2024-01-04 19:02:14 +00:00
|
|
|
return c.Status(200).SendString("https://discord.com/oauth2/authorize?client_id="+ aid.Config.Discord.ID +"&redirect_uri="+ url.QueryEscape("http://" + aid.Config.API.Host + aid.Config.API.Port +"/snow/discord") + "&response_type=code&scope=identify")
|
2023-12-10 00:52:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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},
|
2024-01-04 19:02:14 +00:00
|
|
|
"redirect_uri": {"http://" + aid.Config.API.Host + aid.Config.API.Port +"/snow/discord"},
|
2023-12-10 00:52:59 +00:00
|
|
|
})
|
|
|
|
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"`
|
2023-12-16 22:08:37 +00:00
|
|
|
Avatar string `json:"avatar"`
|
|
|
|
Banner string `json:"banner"`
|
2023-12-10 00:52:59 +00:00
|
|
|
}
|
|
|
|
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 {
|
2023-12-16 22:08:37 +00:00
|
|
|
return c.Status(404).JSON(aid.JSON{"error":"Person not found. Please create an account first."})
|
2023-12-10 00:52:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
person.Discord.AccessToken = body.AccessToken
|
|
|
|
person.Discord.RefreshToken = body.RenewToken
|
2023-12-16 22:08:37 +00:00
|
|
|
person.Discord.Username = user.Username
|
|
|
|
person.Discord.Avatar = user.Avatar
|
|
|
|
person.Discord.Banner = user.Banner
|
2023-12-10 00:52:59 +00:00
|
|
|
storage.Repo.SaveDiscordPerson(person.Discord)
|
|
|
|
|
2023-12-26 03:18:12 +00:00
|
|
|
access, err := aid.JWTSign(aid.JSON{
|
|
|
|
"snow_id": person.ID, // custom
|
|
|
|
"frontend": true,
|
|
|
|
"creation_date": time.Now().Format("2006-01-02T15:04:05.999Z"),
|
|
|
|
})
|
2023-12-10 00:52:59 +00:00
|
|
|
if err != nil {
|
|
|
|
return c.Status(fiber.StatusInternalServerError).JSON(aid.ErrorInternalServer)
|
|
|
|
}
|
|
|
|
|
2024-02-18 03:19:36 +00:00
|
|
|
return c.Redirect("snow://auth:" + access)
|
2023-12-09 15:35:33 +00:00
|
|
|
}
|