From 02ec5c8a90cc75f1340c01ae0a907db7123d6b80 Mon Sep 17 00:00:00 2001 From: rxdn <29165304+rxdn@users.noreply.github.com> Date: Sat, 3 Jul 2021 21:02:49 +0100 Subject: [PATCH] Button styles --- .../endpoints/api/panel/multipanelcreate.go | 2 +- app/http/endpoints/api/panel/panelcreate.go | 46 ++++++++++--------- app/http/endpoints/api/panel/panelupdate.go | 9 +++- app/http/endpoints/api/transcripts/get.go | 1 + app/http/middleware/authenticateguild.go | 3 +- app/http/server.go | 4 +- .../manage/PanelCreationForm.svelte | 15 ++++-- go.mod | 2 +- 8 files changed, 51 insertions(+), 31 deletions(-) diff --git a/app/http/endpoints/api/panel/multipanelcreate.go b/app/http/endpoints/api/panel/multipanelcreate.go index f0e9d5f..45d1c17 100644 --- a/app/http/endpoints/api/panel/multipanelcreate.go +++ b/app/http/endpoints/api/panel/multipanelcreate.go @@ -210,7 +210,7 @@ func (d *multiPanelCreateData) sendEmbed(ctx *botcontext.BotContext, isPremium b buttons[i] = component.BuildButton(component.Button{ Label: panel.Title, CustomId: panel.CustomId, - Style: component.ButtonStylePrimary, + Style: component.ButtonStyle(panel.ButtonStyle), Emoji: emoji.Emoji{ Name: panel.ReactionEmote, }, diff --git a/app/http/endpoints/api/panel/panelcreate.go b/app/http/endpoints/api/panel/panelcreate.go index 4f62540..665c123 100644 --- a/app/http/endpoints/api/panel/panelcreate.go +++ b/app/http/endpoints/api/panel/panelcreate.go @@ -40,6 +40,7 @@ type panelBody struct { Teams []database.SupportTeam `json:"teams"` ImageUrl *string `json:"image_url,omitempty"` ThumbnailUrl *string `json:"thumbnail_url,omitempty"` + ButtonStyle component.ButtonStyle `json:"button_style,string"` } func CreatePanel(ctx *gin.Context) { @@ -94,7 +95,7 @@ func CreatePanel(ctx *gin.Context) { customId := utils.RandString(80) emoji, _ := data.getEmoji() // already validated - msgId, err := data.sendEmbed(&botContext, data.Title, customId, emoji, data.ImageUrl, data.ThumbnailUrl, premiumTier > premium.None) + msgId, err := data.sendEmbed(&botContext, data.Title, customId, emoji, data.ImageUrl, data.ThumbnailUrl, data.ButtonStyle, premiumTier > premium.None) if err != nil { var unwrapped request.RestError if errors.As(err, &unwrapped) && unwrapped.StatusCode == 403 { @@ -128,6 +129,7 @@ func CreatePanel(ctx *gin.Context) { CustomId: customId, ImageUrl: data.ImageUrl, ThumbnailUrl: data.ThumbnailUrl, + ButtonStyle: int(data.ButtonStyle), } panelId, err := dbclient.Client.Panel.Create(panel) @@ -269,6 +271,14 @@ func (p *panelBody) doValidations(ctx *gin.Context, guildId uint64) bool { return false } + if !p.verifyButtonStyle() { + ctx.AbortWithStatusJSON(400, gin.H{ + "success": false, + "error": "Invalid button style", + }) + return false + } + return true } @@ -343,7 +353,11 @@ func (p *panelBody) verifyThumbnailUrl() bool { return p.ThumbnailUrl == nil || (len(*p.ThumbnailUrl) <= 255 && urlRegex.MatchString(*p.ThumbnailUrl)) } -func (p *panelBody) sendEmbed(ctx *botcontext.BotContext, title, customId, emote string, imageUrl, thumbnailUrl *string, isPremium bool) (uint64, error) { +func (p *panelBody) verifyButtonStyle() bool { + return p.ButtonStyle >= component.ButtonStylePrimary && p.ButtonStyle <= component.ButtonStyleDanger +} + +func (p *panelBody) sendEmbed(ctx *botcontext.BotContext, title, customId, emote string, imageUrl, thumbnailUrl *string, buttonStyle component.ButtonStyle, isPremium bool) (uint64, error) { e := embed.NewEmbed(). SetTitle(p.Title). SetDescription(p.Content). @@ -365,26 +379,16 @@ func (p *panelBody) sendEmbed(ctx *botcontext.BotContext, title, customId, emote data := rest.CreateMessageData{ Embed: e, Components: []component.Component{ - { - Type: component.ComponentActionRow, - ComponentData: component.ActionRow{ - Components: []component.Component{ - { - Type: component.ComponentButton, - ComponentData: component.Button{ - Label: title, - CustomId: customId, - Style: component.ButtonStylePrimary, - Emoji: emoji.Emoji{ - Name: emote, - }, - Url: nil, - Disabled: false, - }, - }, - }, + component.BuildActionRow(component.BuildButton(component.Button{ + Label: title, + CustomId: customId, + Style: buttonStyle, + Emoji: emoji.Emoji{ + Name: emote, }, - }, + Url: nil, + Disabled: false, + })), }, } diff --git a/app/http/endpoints/api/panel/panelupdate.go b/app/http/endpoints/api/panel/panelupdate.go index 2cb42a5..d92e713 100644 --- a/app/http/endpoints/api/panel/panelupdate.go +++ b/app/http/endpoints/api/panel/panelupdate.go @@ -9,6 +9,7 @@ import ( "github.com/TicketsBot/common/premium" "github.com/TicketsBot/database" "github.com/gin-gonic/gin" + "github.com/rxdn/gdl/objects/interaction/component" "github.com/rxdn/gdl/rest" "github.com/rxdn/gdl/rest/request" "strconv" @@ -106,7 +107,8 @@ func UpdatePanel(ctx *gin.Context) { existing.Title != data.Title || existing.ReactionEmote != data.Emote || existing.ImageUrl != data.ImageUrl || - existing.ThumbnailUrl != data.ThumbnailUrl + existing.ThumbnailUrl != data.ThumbnailUrl || + component.ButtonStyle(existing.ButtonStyle) != data.ButtonStyle emoji, _ := data.getEmoji() // already validated newMessageId := existing.MessageId @@ -115,7 +117,7 @@ func UpdatePanel(ctx *gin.Context) { // delete old message, ignoring error _ = rest.DeleteMessage(botContext.Token, botContext.RateLimiter, existing.ChannelId, existing.MessageId) - newMessageId, err = data.sendEmbed(&botContext, data.Title, existing.CustomId, data.Emote, data.ImageUrl, data.ThumbnailUrl, premiumTier > premium.None) + newMessageId, err = data.sendEmbed(&botContext, data.Title, existing.CustomId, data.Emote, data.ImageUrl, data.ThumbnailUrl, data.ButtonStyle, premiumTier > premium.None) if err != nil { var unwrapped request.RestError if errors.As(err, &unwrapped) && unwrapped.StatusCode == 403 { @@ -146,6 +148,9 @@ func UpdatePanel(ctx *gin.Context) { WelcomeMessage: data.WelcomeMessage, WithDefaultTeam: data.WithDefaultTeam, CustomId: existing.CustomId, + ImageUrl: data.ImageUrl, + ThumbnailUrl: data.ThumbnailUrl, + ButtonStyle: int(data.ButtonStyle), } if err = dbclient.Client.Panel.Update(panel); err != nil { diff --git a/app/http/endpoints/api/transcripts/get.go b/app/http/endpoints/api/transcripts/get.go index 33786fc..418ab8d 100644 --- a/app/http/endpoints/api/transcripts/get.go +++ b/app/http/endpoints/api/transcripts/get.go @@ -39,6 +39,7 @@ func GetTranscriptHandler(ctx *gin.Context) { } // Verify the user has permissions to be here + // ticket.UserId cannot be 0 if ticket.UserId != userId { permLevel, err := utils.GetPermissionLevel(guildId, userId) if err != nil { diff --git a/app/http/middleware/authenticateguild.go b/app/http/middleware/authenticateguild.go index 9ae1354..03add3b 100644 --- a/app/http/middleware/authenticateguild.go +++ b/app/http/middleware/authenticateguild.go @@ -31,6 +31,7 @@ func AuthenticateGuild(isApiMethod bool, requiredPermissionLevel permission.Perm ctx.Keys["guildid"] = parsed + // TODO: Do we need this? Only really serves as a check whether the bot is in the server guild, found := cache.Instance.GetGuild(parsed, false) if !found { if isApiMethod { @@ -42,8 +43,6 @@ func AuthenticateGuild(isApiMethod bool, requiredPermissionLevel permission.Perm return } - ctx.Keys["guild"] = guild - // Verify the user has permissions to be here userId := ctx.Keys["userid"].(uint64) diff --git a/app/http/server.go b/app/http/server.go index 5e43de3..33064cd 100644 --- a/app/http/server.go +++ b/app/http/server.go @@ -54,6 +54,7 @@ func StartServer() { guildAuthApiAdmin := apiGroup.Group("/:id", middleware.AuthenticateGuild(true, permission.Admin)) guildAuthApiSupport := apiGroup.Group("/:id", middleware.AuthenticateGuild(true, permission.Support)) + guildAuthApiEveryone := apiGroup.Group("/:id", middleware.AuthenticateGuild(true, permission.Everyone)) { guildAuthApiSupport.GET("/channels", api.ChannelsHandler) guildAuthApiSupport.GET("/premium", api.PremiumHandler) @@ -79,7 +80,8 @@ func StartServer() { guildAuthApiAdmin.DELETE("/multipanels/:panelid", api_panels.MultiPanelDelete) guildAuthApiSupport.GET("/transcripts", createLimiter(5, 5 * time.Second), createLimiter(20, time.Minute), api_transcripts.ListTranscripts) - guildAuthApiSupport.GET("/transcripts/:ticketId", createLimiter(10, 10 * time.Second), api_transcripts.GetTranscriptHandler) + // Allow regular users to get their own transcripts, make sure you check perms inside + guildAuthApiEveryone.GET("/transcripts/:ticketId", createLimiter(10, 10 * time.Second), api_transcripts.GetTranscriptHandler) guildAuthApiSupport.GET("/tickets", api_ticket.GetTickets) guildAuthApiSupport.GET("/tickets/:ticketId", api_ticket.GetTicket) diff --git a/frontend/src/components/manage/PanelCreationForm.svelte b/frontend/src/components/manage/PanelCreationForm.svelte index 1c4bc8a..97f2517 100644 --- a/frontend/src/components/manage/PanelCreationForm.svelte +++ b/frontend/src/components/manage/PanelCreationForm.svelte @@ -14,6 +14,14 @@ +
+ + + + + + +
- - + +
@@ -60,10 +68,10 @@ import {createEventDispatcher, onMount} from 'svelte'; import {colourToInt} from "../../js/util"; - import {setDefaultHeaders} from "../../includes/Auth.svelte"; import CategoryDropdown from "../CategoryDropdown.svelte"; import EmojiInput from "../form/EmojiInput.svelte"; import Select from 'svelte-select'; + import Dropdown from "../form/Dropdown.svelte"; export let guildId; export let seedDefault = true; @@ -83,6 +91,7 @@ mentions: [], default_team: true, teams: [], + button_style: "1", }; } diff --git a/go.mod b/go.mod index 1ab5fab..74f79b0 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/BurntSushi/toml v0.3.1 github.com/TicketsBot/archiverclient v0.0.0-20210220155137-a562b2f1bbbb github.com/TicketsBot/common v0.0.0-20210604175952-03cfa14c16e1 - github.com/TicketsBot/database v0.0.0-20210630165045-4745a3db99e1 + github.com/TicketsBot/database v0.0.0-20210703200035-33b8cc0a309c github.com/TicketsBot/worker v0.0.0-20210528135955-34744f610804 github.com/apex/log v1.1.2 github.com/boj/redistore v0.0.0-20180917114910-cd5dcc76aeff // indirect