diff --git a/app/http/endpoints/api/reloadguilds.go b/app/http/endpoints/api/reloadguilds.go new file mode 100644 index 0000000..21de40d --- /dev/null +++ b/app/http/endpoints/api/reloadguilds.go @@ -0,0 +1,74 @@ +package api + +import ( + "fmt" + "github.com/TicketsBot/GoPanel/messagequeue" + "github.com/TicketsBot/GoPanel/utils" + "github.com/TicketsBot/GoPanel/utils/discord" + "github.com/gin-gonic/contrib/sessions" + "github.com/gin-gonic/gin" + "time" +) + +func ReloadGuildsHandler(ctx *gin.Context) { + userId := ctx.Keys["userid"].(uint64) + + key := fmt.Sprintf("tickets:dashboard:guildreload:%d", userId) + res, err := messagequeue.Client.SetNX(key, 1, time.Second*10).Result() + if err != nil { + ctx.JSON(500, utils.ErrorToResponse(err)) + return + } + + if !res { + ttl, err := messagequeue.Client.TTL(key).Result() + if err != nil { + ctx.JSON(500, utils.ErrorToResponse(err)) + return + } + + // handle redis error codes + if ttl < 0 { + ttl = 0 + } + + ctx.JSON(429, utils.ErrorStr("You're doing this too quickly: try again in %d seconds", int(ttl.Seconds()))) + return + } + + store := sessions.Default(ctx) + if store == nil { + ctx.JSON(200, gin.H{ + "success": false, + "reauthenticate_required": true, + }) + return + } + + accessToken := store.Get("access_token").(string) + expiry := store.Get("expiry").(int64) + if expiry > (time.Now().UnixNano() / int64(time.Second)) { + res, err := discord.RefreshToken(store.Get("refresh_token").(string)) + if err != nil { // Tell client to re-authenticate + ctx.JSON(200, gin.H{ + "success": false, + "reauthenticate_required": true, + }) + return + } + + accessToken = res.AccessToken + + store.Set("access_token", res.AccessToken) + store.Set("refresh_token", res.RefreshToken) + store.Set("expiry", (time.Now().UnixNano()/int64(time.Second))+int64(res.ExpiresIn)) + store.Save() + } + + if err := utils.LoadGuilds(accessToken, userId); err != nil { + ctx.JSON(500, utils.ErrorToResponse(err)) + return + } + + ctx.JSON(200, utils.SuccessResponse) +} diff --git a/app/http/endpoints/root/callback.go b/app/http/endpoints/root/callback.go index b8ada98..8c30572 100644 --- a/app/http/endpoints/root/callback.go +++ b/app/http/endpoints/root/callback.go @@ -3,16 +3,12 @@ package root import ( "fmt" "github.com/TicketsBot/GoPanel/config" - dbclient "github.com/TicketsBot/GoPanel/database" "github.com/TicketsBot/GoPanel/utils" "github.com/TicketsBot/GoPanel/utils/discord" - userEndpoint "github.com/TicketsBot/GoPanel/utils/discord/endpoints/user" - "github.com/TicketsBot/database" "github.com/apex/log" "github.com/gin-gonic/contrib/sessions" "github.com/gin-gonic/gin" - "github.com/rxdn/gdl/objects/guild" - "github.com/rxdn/gdl/objects/user" + "github.com/rxdn/gdl/rest" "strings" "time" ) @@ -65,8 +61,7 @@ func CallbackHandler(ctx *gin.Context) { store.Set("expiry", (time.Now().UnixNano()/int64(time.Second))+int64(res.ExpiresIn)) // Get ID + name - var currentUser user.User - err, _ = userEndpoint.CurrentUser.Request(store, nil, nil, ¤tUser) + currentUser, err := rest.GetCurrentUser(fmt.Sprintf("Bearer %s", res.AccessToken), nil) if err != nil { ctx.String(500, err.Error()) return @@ -79,37 +74,10 @@ func CallbackHandler(ctx *gin.Context) { store.Set("avatar", currentUser.AvatarUrl(256)) store.Save() - var guilds []guild.Guild - err, _ = userEndpoint.CurrentUserGuilds.Request(store, nil, nil, &guilds) - if err != nil { - log.Error(err.Error()) - handleRedirect(ctx) - return - } - - store.Set("has_guilds", true) - store.Save() - - var wrappedGuilds []database.UserGuild - - // endpoint's partial guild doesn't include ownerid - // we only user cached guilds on the index page, so it doesn't matter if we don't have have the real owner id - // if the user isn't the owner, as we pull from the cache on other endpoints - for _, guild := range guilds { - if guild.Owner { - guild.OwnerId = currentUser.Id - } - - wrappedGuilds = append(wrappedGuilds, database.UserGuild{ - GuildId: guild.Id, - Name: guild.Name, - Owner: guild.Owner, - UserPermissions: int32(guild.Permissions), - Icon: guild.Icon, - }) - } - - if err := dbclient.Client.UserGuilds.Set(currentUser.Id, wrappedGuilds); err != nil { + if err := utils.LoadGuilds(res.AccessToken, currentUser.Id); err == nil { + store.Set("has_guilds", true) + store.Save() + } else { log.Error(err.Error()) } diff --git a/app/http/server.go b/app/http/server.go index dfa9c87..936f071 100644 --- a/app/http/server.go +++ b/app/http/server.go @@ -128,6 +128,7 @@ func StartServer() { userGroup := router.Group("/user", middleware.AuthenticateToken) { userGroup.GET("/guilds", api.GetGuilds) + userGroup.POST("/guilds/reload", api.ReloadGuildsHandler) userGroup.GET("/permissionlevel", api.GetPermissionLevel) { diff --git a/go.mod b/go.mod index 1834301..eded039 100644 --- a/go.mod +++ b/go.mod @@ -15,14 +15,14 @@ require ( github.com/gin-contrib/static v0.0.0-20191128031702-f81c604d8ac2 github.com/gin-gonic/contrib v0.0.0-20191209060500-d6e26eeaa607 github.com/gin-gonic/gin v1.6.2 - github.com/go-redis/redis v6.15.8+incompatible + github.com/go-redis/redis v6.15.9+incompatible github.com/gofrs/uuid v3.3.0+incompatible github.com/gorilla/sessions v1.2.0 // indirect github.com/gorilla/websocket v1.4.2 github.com/jackc/pgx/v4 v4.7.1 github.com/pasztorpisti/qs v0.0.0-20171216220353-8d6c33ee906c github.com/pkg/errors v0.9.1 - github.com/rxdn/gdl v0.0.0-20201214225805-4ae598a98327 + github.com/rxdn/gdl v0.0.0-20210105220812-1d2789cb2f0b github.com/sirupsen/logrus v1.5.0 github.com/ulule/limiter/v3 v3.5.0 golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a diff --git a/public/static/css/style.css b/public/static/css/style.css index 38df408..5312c07 100644 --- a/public/static/css/style.css +++ b/public/static/css/style.css @@ -208,12 +208,15 @@ html > ::-webkit-scrollbar { } .guild { - width: 100%; + display: flex; + align-items: center; + box-shadow: 0 4px 4px rgba(0, 0, 0, 0.25); + + width: 33%; background-color: #121212; height: 100px; margin-bottom: 10px; border-radius: 10px; - display: flex; cursor: pointer; } @@ -240,3 +243,23 @@ html > ::-webkit-scrollbar { color: white !important; padding-left: 10px; } + +.flex-container { + display: flex; + height: 100%; + width: 100%; +} + +#guild-container { + display: flex; + flex-direction: row; + justify-content: space-between; +} + +#refresh-container { + display: flex; + justify-content: center; + + margin-top: 20px; + color: white; +} \ No newline at end of file diff --git a/public/static/js/utils.js b/public/static/js/utils.js index c84e221..200baf3 100644 --- a/public/static/js/utils.js +++ b/public/static/js/utils.js @@ -36,3 +36,11 @@ function appendButton(tr, content, onclick) { tdRemove.appendChild(removeButton); tr.appendChild(tdRemove); } + +function prependChild(parent, child) { + if (parent.children.length === 0) { + parent.appendChild(child); + } else { + parent.insertBefore(child, parent.children[0]); + } +} diff --git a/public/templates/views/index.tmpl b/public/templates/views/index.tmpl index 2d08c51..8a5259b 100644 --- a/public/templates/views/index.tmpl +++ b/public/templates/views/index.tmpl @@ -9,23 +9,18 @@