2024-11-13 22:45:37 +00:00

108 lines
2.7 KiB
Go

package root
import (
"context"
"errors"
"fmt"
"github.com/TicketsBot/GoPanel/app"
"github.com/TicketsBot/GoPanel/app/http/session"
"github.com/TicketsBot/GoPanel/config"
"github.com/TicketsBot/GoPanel/utils"
"github.com/gin-gonic/gin"
"github.com/golang-jwt/jwt"
"github.com/rxdn/gdl/rest"
"github.com/rxdn/gdl/rest/request"
"net/http"
"strconv"
"strings"
"time"
)
func CallbackHandler(c *gin.Context) {
code, ok := c.GetQuery("code")
if !ok {
c.JSON(400, utils.ErrorStr("Missing code query parameter"))
return
}
res, err := rest.ExchangeCode(c, nil, config.Conf.Oauth.Id, config.Conf.Oauth.Secret, config.Conf.Oauth.RedirectUri, code)
if err != nil {
var oauthError request.OAuthError
if errors.As(err, &oauthError) {
if oauthError.ErrorCode == "invalid_grant" {
c.JSON(400, utils.ErrorStr("Invalid code: try logging in again"))
return
}
}
_ = c.AbortWithError(http.StatusInternalServerError, app.NewServerError(err))
return
}
scopes := strings.Split(res.Scope, " ")
if !utils.Contains(scopes, "identify") {
c.JSON(400, utils.ErrorStr("Missing identify scope"))
return
}
// Get ID + name
currentUser, err := rest.GetCurrentUser(context.Background(), fmt.Sprintf("Bearer %s", res.AccessToken), nil)
if err != nil {
_ = c.AbortWithError(http.StatusInternalServerError, app.NewServerError(err))
return
}
store := session.SessionData{
AccessToken: res.AccessToken,
Expiry: (time.Now().UnixNano() / int64(time.Second)) + int64(res.ExpiresIn),
RefreshToken: res.RefreshToken,
Name: currentUser.Username,
Avatar: currentUser.AvatarUrl(256),
HasGuilds: false,
}
var guilds []utils.GuildDto
if utils.Contains(scopes, "guilds") {
guilds, err = utils.LoadGuilds(c, res.AccessToken, currentUser.Id)
if err != nil {
_ = c.AbortWithError(http.StatusInternalServerError, app.NewServerError(err))
return
}
store.HasGuilds = true
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"userid": strconv.FormatUint(currentUser.Id, 10),
"sub": strconv.FormatUint(currentUser.Id, 10),
"iat": time.Now().Unix(),
})
str, err := token.SignedString([]byte(config.Conf.Server.Secret))
if err != nil {
_ = c.AbortWithError(http.StatusInternalServerError, err)
return
}
if err := session.Store.Set(currentUser.Id, store); err != nil {
_ = c.AbortWithError(http.StatusInternalServerError, err)
return
}
resMap := gin.H{
"success": true,
"token": str,
"user_data": gin.H{
"id": strconv.FormatUint(currentUser.Id, 10),
"username": currentUser.Username,
"avatar": currentUser.Avatar,
"admin": utils.Contains(config.Conf.Admins, currentUser.Id),
},
}
if len(guilds) > 0 {
resMap["guilds"] = guilds
}
c.JSON(http.StatusOK, resMap)
}