From 014dd9fc2db8749cdd73a93cbcc836eb90d118b2 Mon Sep 17 00:00:00 2001 From: Hussein Alzein Date: Wed, 28 Jul 2021 17:24:58 -0400 Subject: [PATCH] URL validation and error handling (#64) * Error handling on URL additions in embeds and components. * Wording on exception comment * Wording on exceptions --- src/Discord.Net.Core/Discord.Net.Core.xml | 31 ++++++++++++++----- .../Message Components/ComponentBuilder.cs | 24 +++++++++----- .../Entities/Messages/EmbedBuilder.cs | 14 +++++++++ .../Discord.Net.WebSocket.xml | 11 ++++++- 4 files changed, 63 insertions(+), 17 deletions(-) diff --git a/src/Discord.Net.Core/Discord.Net.Core.xml b/src/Discord.Net.Core/Discord.Net.Core.xml index bce491f0f..c8610ac04 100644 --- a/src/Discord.Net.Core/Discord.Net.Core.xml +++ b/src/Discord.Net.Core/Discord.Net.Core.xml @@ -4107,6 +4107,11 @@ A or . + + + A . + + Provides properties that are used to modify a with the specified changes. @@ -4502,7 +4507,8 @@ - Adds a button to the specified row. + Adds a with specified parameters to the at the specific row. + If the row cannot accept the component then it will add it to a row that can. The label text for the newly added button. The style of this newly added button. @@ -4627,44 +4633,49 @@ Creates a new instance of a from instance of a . - + Creates a button with the style. - The label to use on the newly created link button. + The label for this link button. The url for this link button to go to. + The emote for this link button A builder with the newly created button. - + Creates a button with the style. The label for this danger button. The custom id for this danger button. + The emote for this danger button A builder with the newly created button. - + Creates a button with the style. The label for this primary button. The custom id for this primary button. + The emote for this primary button A builder with the newly created button. - + Creates a button with the style. The label for this secondary button. The custom id for this secondary button. + The emote for this secondary button A builder with the newly created button. - + Creates a button with the style. The label for this success button. The custom id for this success button. + The emote for this success button A builder with the newly created button. @@ -4716,8 +4727,11 @@ Builds this builder into a to be used in a . A to be used in a . - A button cannot contain a and a . + A button must contain either a or a , but not both. A button must have an or a . + A link button must contain a URL. + A link must include a protocol (http or https). + A non-link button must contain a custom id @@ -6010,6 +6024,7 @@ The built embed object. Total embed length exceeds . + Any Url must include protocols (i.e http:// or https://). diff --git a/src/Discord.Net.Core/Entities/Interactions/Message Components/ComponentBuilder.cs b/src/Discord.Net.Core/Entities/Interactions/Message Components/ComponentBuilder.cs index 9317c0e64..ff2c99a6c 100644 --- a/src/Discord.Net.Core/Entities/Interactions/Message Components/ComponentBuilder.cs +++ b/src/Discord.Net.Core/Entities/Interactions/Message Components/ComponentBuilder.cs @@ -520,21 +520,29 @@ namespace Discord /// Builds this builder into a to be used in a . /// /// A to be used in a . - /// A button cannot contain a and a . + /// A button must contain either a or a , but not both. /// A button must have an or a . + /// A link button must contain a URL. + /// A URL must include a protocol (http or https). + /// A non-link button must contain a custom id public ButtonComponent Build() { if (string.IsNullOrEmpty(this.Label) && this.Emote == null) throw new InvalidOperationException("A button must have an Emote or a label!"); - if (!string.IsNullOrEmpty(this.Url) && !string.IsNullOrEmpty(this.CustomId)) - throw new InvalidOperationException("A button cannot contain a URL and a CustomId!"); + if (!(string.IsNullOrEmpty(this.Url) ^ string.IsNullOrEmpty(this.CustomId))) + throw new InvalidOperationException("A button must contain either a URL or a CustomId, but not both!"); - if (this.Style == ButtonStyle.Link && !string.IsNullOrEmpty(this.CustomId)) - this.CustomId = null; - - else if (this.Style != ButtonStyle.Link && !string.IsNullOrEmpty(this.Url)) // Thanks 𝑴𝒓π‘ͺπ’‚π’Œπ’†π‘Ίπ’π’‚π’šπ’†π’“ :D - this.Url = null; + if (this.Style == ButtonStyle.Link) + { + if (string.IsNullOrEmpty(this.Url)) + throw new InvalidOperationException("Link buttons must have a link associated with them"); + else if (!Uri.IsWellFormedUriString(this.Url, UriKind.Absolute)) + throw new InvalidOperationException("Urls must be well formatted and include their protocol (either HTTP or HTTPS)"); + } + + else if (string.IsNullOrEmpty(this.CustomId)) + throw new InvalidOperationException("Non-link buttons must have a custom id associated with them"); return new ButtonComponent(this.Style, this.Label, this.Emote, this.CustomId, this.Url, this.Disabled); } diff --git a/src/Discord.Net.Core/Entities/Messages/EmbedBuilder.cs b/src/Discord.Net.Core/Entities/Messages/EmbedBuilder.cs index 2ac6efa6b..b7dd6ed02 100644 --- a/src/Discord.Net.Core/Entities/Messages/EmbedBuilder.cs +++ b/src/Discord.Net.Core/Entities/Messages/EmbedBuilder.cs @@ -401,10 +401,24 @@ namespace Discord /// The built embed object. /// /// Total embed length exceeds . + /// Any Url must be well formatted include its protocols (i.e http:// or https://). public Embed Build() { if (Length > MaxEmbedLength) throw new InvalidOperationException($"Total embed length must be less than or equal to {MaxEmbedLength}."); + if (!string.IsNullOrEmpty(Url) && !Uri.IsWellFormedUriString(Url, UriKind.Absolute)) + throw new InvalidOperationException("Url must be well formatted and include its protocol (either HTTP or HTTPS)"); + if (!string.IsNullOrEmpty(ThumbnailUrl) && !Uri.IsWellFormedUriString(ThumbnailUrl, UriKind.Absolute)) + throw new InvalidOperationException("Thumbnail Url must be well formatted and include its protocol (either HTTP or HTTPS)"); + if (!string.IsNullOrEmpty(ImageUrl) && !Uri.IsWellFormedUriString(ImageUrl, UriKind.Absolute)) + throw new InvalidOperationException("Image Url must be well formatted and include its protocol (either HTTP or HTTPS)"); + if (Author != null) + { + if(!string.IsNullOrEmpty(Author.Url) && !Uri.IsWellFormedUriString(Author.Url, UriKind.Absolute)) + throw new InvalidOperationException("Author Url must be well formatted and include its protocol (either HTTP or HTTPS)"); + if (!string.IsNullOrEmpty(Author.IconUrl) && !Uri.IsWellFormedUriString(Author.IconUrl, UriKind.Absolute)) + throw new InvalidOperationException("Author Icon Url must be well formatted and include its protocol (either HTTP or HTTPS)"); + } var fields = ImmutableArray.CreateBuilder(Fields.Count); for (int i = 0; i < Fields.Count; i++) diff --git a/src/Discord.Net.WebSocket/Discord.Net.WebSocket.xml b/src/Discord.Net.WebSocket/Discord.Net.WebSocket.xml index 00f22c0e8..db0c2431d 100644 --- a/src/Discord.Net.WebSocket/Discord.Net.WebSocket.xml +++ b/src/Discord.Net.WebSocket/Discord.Net.WebSocket.xml @@ -3431,10 +3431,11 @@ - Updates the original message of the component on which the interaction was received on. + Updates the message which this component resides in with the type A delegate containing the properties to modify the message with. The request options for this async request. + A task that represents the asynchronous operation of updating the message. @@ -3689,6 +3690,14 @@ The request options for this async request. A that represents the initial response. + + + Acknowledges this interaction. + + + A task that represents the asynchronous operation of acknowledging the interaction. + + Acknowledges this interaction.