From ed8d66c4d752e106dc074810d7fd62e127d2a291 Mon Sep 17 00:00:00 2001 From: Satont Date: Thu, 27 Jun 2024 05:48:17 +0300 Subject: [PATCH] fix(api-gql): disallow to create/update commands with empty aliase fixes #754 --- .../gql/resolvers/commands.resolver.go | 68 ++++++++++++------- apps/api-gql/schema/commands.graphqls | 4 +- 2 files changed, 45 insertions(+), 27 deletions(-) diff --git a/apps/api-gql/internal/gql/resolvers/commands.resolver.go b/apps/api-gql/internal/gql/resolvers/commands.resolver.go index b0ce53433..a6459781a 100644 --- a/apps/api-gql/internal/gql/resolvers/commands.resolver.go +++ b/apps/api-gql/internal/gql/resolvers/commands.resolver.go @@ -20,7 +20,10 @@ import ( ) // Responses is the resolver for the responses field. -func (r *commandResolver) Responses(ctx context.Context, obj *gqlmodel.Command) ([]gqlmodel.CommandResponse, error) { +func (r *commandResolver) Responses( + ctx context.Context, + obj *gqlmodel.Command, +) ([]gqlmodel.CommandResponse, error) { if obj.Default { return []gqlmodel.CommandResponse{}, nil } @@ -50,7 +53,10 @@ func (r *commandResolver) Responses(ctx context.Context, obj *gqlmodel.Command) } // CommandsCreate is the resolver for the commandsCreate field. -func (r *mutationResolver) CommandsCreate(ctx context.Context, opts gqlmodel.CommandsCreateOpts) (bool, error) { +func (r *mutationResolver) CommandsCreate( + ctx context.Context, + opts gqlmodel.CommandsCreateOpts, +) (bool, error) { dashboardId, err := r.sessions.GetSelectedDashboard(ctx) if err != nil { return false, err @@ -60,22 +66,22 @@ func (r *mutationResolver) CommandsCreate(ctx context.Context, opts gqlmodel.Com return false, err } + aliases := []string{} + for _, alias := range opts.Aliases { + a := strings.TrimSuffix(strings.ToLower(alias), "!") + a = strings.ReplaceAll(a, " ", "") + if a != "" { + aliases = append(aliases, a) + } + } + command := &model.ChannelsCommands{ - ID: uuid.New().String(), - Name: strings.ToLower(opts.Name), - Cooldown: null.IntFrom(int64(opts.Cooldown)), - CooldownType: opts.CooldownType, - Enabled: opts.Enabled, - Aliases: lo.Map( - lo.IfF( - opts.Aliases == nil, func() []string { - return []string{} - }, - ).Else(opts.Aliases), - func(alias string, _ int) string { - return strings.TrimSuffix(strings.ToLower(alias), "!") - }, - ), + ID: uuid.New().String(), + Name: strings.ToLower(opts.Name), + Cooldown: null.IntFrom(int64(opts.Cooldown)), + CooldownType: opts.CooldownType, + Enabled: opts.Enabled, + Aliases: aliases, Description: null.StringFrom(opts.Description), Visible: opts.Visible, ChannelID: dashboardId, @@ -128,7 +134,11 @@ func (r *mutationResolver) CommandsCreate(ctx context.Context, opts gqlmodel.Com } // CommandsUpdate is the resolver for the commandsUpdate field. -func (r *mutationResolver) CommandsUpdate(ctx context.Context, id string, opts gqlmodel.CommandsUpdateOpts) (bool, error) { +func (r *mutationResolver) CommandsUpdate( + ctx context.Context, + id string, + opts gqlmodel.CommandsUpdateOpts, +) (bool, error) { dashboardId, err := r.sessions.GetSelectedDashboard(ctx) if err != nil { return false, err @@ -145,6 +155,8 @@ func (r *mutationResolver) CommandsUpdate(ctx context.Context, id string, opts g } } + aliases := []string{} + if opts.Aliases.IsSet() { if err := r.checkIsCommandWithNameOrAliaseExists( ctx, @@ -184,12 +196,15 @@ func (r *mutationResolver) CommandsUpdate(ctx context.Context, id string, opts g } if opts.Aliases.IsSet() { - cmd.Aliases = lo.Map( - opts.Aliases.Value(), - func(alias string, _ int) string { - return strings.TrimSuffix(strings.ToLower(alias), "!") - }, - ) + for _, alias := range opts.Aliases.Value() { + a := strings.TrimSuffix(strings.ToLower(alias), "!") + a = strings.ReplaceAll(a, " ", "") + if a != "" { + aliases = append(aliases, a) + } + } + + cmd.Aliases = aliases } if opts.Description.IsSet() { @@ -386,7 +401,10 @@ func (r *queryResolver) Commands(ctx context.Context) ([]gqlmodel.Command, error } // CommandsPublic is the resolver for the commandsPublic field. -func (r *queryResolver) CommandsPublic(ctx context.Context, channelID string) ([]gqlmodel.PublicCommand, error) { +func (r *queryResolver) CommandsPublic( + ctx context.Context, + channelID string, +) ([]gqlmodel.PublicCommand, error) { if channelID == "" { return nil, fmt.Errorf("channelID is required") } diff --git a/apps/api-gql/schema/commands.graphqls b/apps/api-gql/schema/commands.graphqls index 195bd4fea..2277019e9 100644 --- a/apps/api-gql/schema/commands.graphqls +++ b/apps/api-gql/schema/commands.graphqls @@ -61,7 +61,7 @@ type PublicCommandPermission { input CommandsCreateOpts { name: String! @validate(constraint: "max=50") description: String! @validate(constraint: "max=500") - aliases: [String!]! @validate(constraint: "dive,max=50") + aliases: [String!]! @validate(constraint: "dive,max=50,min=1") responses: [CreateOrUpdateCommandResponseInput!]! cooldown: Int! @validate(constraint: "max=90000") cooldownType: String! @@ -84,7 +84,7 @@ input CommandsCreateOpts { input CommandsUpdateOpts { name: String @validate(constraint: "max=50") description: String @validate(constraint: "max=500") - aliases: [String!] @validate(constraint: "dive,max=50") + aliases: [String!] @validate(constraint: "dive,max=50,min=1") responses: [CreateOrUpdateCommandResponseInput!] cooldown: Int cooldownType: String