Files
Vencloud/routes/discord.go
T
2023-08-10 22:37:57 +01:00

120 lines
2.6 KiB
Go

package routes
import (
"crypto/rand"
"encoding/hex"
"fmt"
"github.com/gofiber/fiber/v2"
"github.com/imroc/req/v3"
"github.com/redis/go-redis/v9"
g "github.com/vencord/backend/globals"
"github.com/vencord/backend/util"
)
// /v1/oauth
type DiscordAccessTokenResult struct {
AccessToken string `json:"access_token"`
}
type DiscordUserResult struct {
Id string `json:"id"`
}
// /v1/oauth/callback
func GETOAuthCallback(c *fiber.Ctx) error {
code := c.Query("code")
if code == "" {
return c.Status(400).JSON(&fiber.Map{
"error": "Missing code",
})
}
var accessTokenResult DiscordAccessTokenResult
res, err := req.R().SetFormData(map[string]string{
"client_id": g.DISCORD_CLIENT_ID,
"client_secret": g.DISCORD_CLIENT_SECRET,
"grant_type": "authorization_code",
"code": code,
"redirect_uri": g.DISCORD_REDIRECT_URI,
"scope": "identify",
}).SetSuccessResult(&accessTokenResult).Post("https://discord.com/api/oauth2/token")
if err != nil {
fmt.Printf("Failed to request access token: %v", err)
return c.Status(500).JSON(&fiber.Map{
"error": "Failed to request access token",
})
}
if res.IsErrorState() {
return c.Status(400).JSON(&fiber.Map{
"error": "Invalid code",
})
}
accessToken := accessTokenResult.AccessToken
var userResult DiscordUserResult
res, err = req.R().SetHeaders(map[string]string{
"Authorization": "Bearer " + accessToken,
}).SetSuccessResult(&userResult).Get("https://discord.com/api/users/@me")
if err != nil {
fmt.Printf("Failed to request user: %v", err)
return c.Status(500).JSON(&fiber.Map{
"error": "Failed to request user",
})
}
if res.IsErrorState() {
return c.Status(500).JSON(&fiber.Map{
"error": "Failed to request user",
})
}
userId := userResult.Id
if g.ALLOWED_USERS != nil && !g.ALLOWED_USERS[userId] {
return c.Status(403).JSON(&fiber.Map{
"error": "User is not whitelisted",
})
}
secret, err := g.RDB.Get(c.Context(), "secrets:"+util.Hash(g.PEPPER_SECRETS+userId)).Result()
if err == redis.Nil {
key := make([]byte, 48)
_, err := rand.Read(key)
if err != nil {
fmt.Printf("Failed to generate secret: %v", err)
return c.Status(500).JSON(&fiber.Map{
"error": "Failed to generate secret",
})
}
secret = hex.EncodeToString(key)
g.RDB.Set(c.Context(), "secrets:"+util.Hash(g.PEPPER_SECRETS+userId), secret, 0)
} else if err != nil {
panic(err)
}
return c.JSON(&fiber.Map{
"secret": secret,
})
}
// /v1/oauth/settings
func GETOAuthSettings(c *fiber.Ctx) error {
return c.JSON(&fiber.Map{
"clientId": g.DISCORD_CLIENT_ID,
"redirectUri": g.DISCORD_REDIRECT_URI,
})
}