diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9ef63f5b8..03ef98977 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,10 @@
# Snyk Changelog
+## [1.1.38]
+
+### Fixed
+- Custom endpoints validation in the settings page did not work correctly and led to crashes.
+
## [1.1.37]
### Fixed
diff --git a/Snyk.VisualStudio.Extension.Shared/CLI/SnykCli.cs b/Snyk.VisualStudio.Extension.Shared/CLI/SnykCli.cs
index 2a4fc3ce5..b5e089f17 100644
--- a/Snyk.VisualStudio.Extension.Shared/CLI/SnykCli.cs
+++ b/Snyk.VisualStudio.Extension.Shared/CLI/SnykCli.cs
@@ -81,7 +81,7 @@ public string GetApiToken()
}
catch (InvalidTokenException e)
{
- Logger.Error(e, "Error on get api token via cli for settings");
+ Logger.Warning(e, "Failed to retrieve api token from CLI configuration");
apiToken = string.Empty;
}
diff --git a/Snyk.VisualStudio.Extension.Shared/Settings/ErrorProviderExtensions.cs b/Snyk.VisualStudio.Extension.Shared/Settings/ErrorProviderExtensions.cs
new file mode 100644
index 000000000..1d6665e8b
--- /dev/null
+++ b/Snyk.VisualStudio.Extension.Shared/Settings/ErrorProviderExtensions.cs
@@ -0,0 +1,11 @@
+using System.Data.SqlClient;
+
+namespace Snyk.VisualStudio.Extension.Shared.Settings;
+
+using System.Windows.Forms;
+
+public static class ErrorProviderExtensions
+{
+ public static void SetNoError(this ErrorProvider errorProvider, Control control) =>
+ errorProvider.SetError(control, string.Empty);
+}
\ No newline at end of file
diff --git a/Snyk.VisualStudio.Extension.Shared/Settings/SnykGeneralOptionsDialogPage.cs b/Snyk.VisualStudio.Extension.Shared/Settings/SnykGeneralOptionsDialogPage.cs
index 65c6ff2c7..d92e6fd93 100644
--- a/Snyk.VisualStudio.Extension.Shared/Settings/SnykGeneralOptionsDialogPage.cs
+++ b/Snyk.VisualStudio.Extension.Shared/Settings/SnykGeneralOptionsDialogPage.cs
@@ -93,6 +93,12 @@ public string CustomEndpoint
get => this.customEndpoint;
set
{
+ if (!Uri.IsWellFormedUriString(value, UriKind.Absolute))
+ {
+ Logger.Warning("Custom endpoint value is not a well-formed URI. Setting custom endpoint to empty string");
+ value = string.Empty;
+ }
+
if (this.customEndpoint == value)
{
return;
diff --git a/Snyk.VisualStudio.Extension.Shared/Settings/SnykGeneralSettingsUserControl.Designer.cs b/Snyk.VisualStudio.Extension.Shared/Settings/SnykGeneralSettingsUserControl.Designer.cs
index 62bca0846..1ab940804 100644
--- a/Snyk.VisualStudio.Extension.Shared/Settings/SnykGeneralSettingsUserControl.Designer.cs
+++ b/Snyk.VisualStudio.Extension.Shared/Settings/SnykGeneralSettingsUserControl.Designer.cs
@@ -83,7 +83,7 @@ private void InitializeComponent()
this.customEndpointTextBox.Location = new System.Drawing.Point(100, 86);
this.customEndpointTextBox.Margin = new System.Windows.Forms.Padding(2);
this.customEndpointTextBox.Name = "customEndpointTextBox";
- this.customEndpointTextBox.Size = new System.Drawing.Size(420, 20);
+ this.customEndpointTextBox.Size = new System.Drawing.Size(300, 20);
this.customEndpointTextBox.TabIndex = 0;
this.customEndpointTextBox.LostFocus += new System.EventHandler(this.CustomEndpointTextBox_LostFocus);
this.customEndpointTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.CustomEndpointTextBox_Validating);
@@ -113,7 +113,7 @@ private void InitializeComponent()
this.organizationTextBox.Location = new System.Drawing.Point(100, 134);
this.organizationTextBox.Margin = new System.Windows.Forms.Padding(2);
this.organizationTextBox.Name = "organizationTextBox";
- this.organizationTextBox.Size = new System.Drawing.Size(420, 20);
+ this.organizationTextBox.Size = new System.Drawing.Size(300, 20);
this.organizationTextBox.TabIndex = 3;
this.organizationTextBox.TextChanged += new System.EventHandler(this.OrganizationTextBox_TextChanged);
//
@@ -132,7 +132,7 @@ private void InitializeComponent()
this.tokenTextBox.Location = new System.Drawing.Point(100, 54);
this.tokenTextBox.Name = "tokenTextBox";
this.tokenTextBox.PasswordChar = '*';
- this.tokenTextBox.Size = new System.Drawing.Size(420, 20);
+ this.tokenTextBox.Size = new System.Drawing.Size(300, 20);
this.tokenTextBox.TabIndex = 5;
this.tokenTextBox.TextChanged += new System.EventHandler(this.TokenTextBox_TextChanged);
this.tokenTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.TokenTextBox_Validating);
@@ -165,7 +165,7 @@ private void InitializeComponent()
this.authProgressBar.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3);
this.authProgressBar.MarqueeAnimationSpeed = 10;
this.authProgressBar.Name = "authProgressBar";
- this.authProgressBar.Size = new System.Drawing.Size(420, 5);
+ this.authProgressBar.Size = new System.Drawing.Size(300, 5);
this.authProgressBar.Style = System.Windows.Forms.ProgressBarStyle.Marquee;
this.authProgressBar.TabIndex = 8;
this.authProgressBar.Visible = false;
@@ -311,7 +311,7 @@ private void InitializeComponent()
this.CliPathTextBox.Margin = new System.Windows.Forms.Padding(2);
this.CliPathTextBox.Name = "CliPathTextBox";
this.CliPathTextBox.ReadOnly = true;
- this.CliPathTextBox.Size = new System.Drawing.Size(420, 20);
+ this.CliPathTextBox.Size = new System.Drawing.Size(300, 20);
this.CliPathTextBox.TabIndex = 15;
//
// CliPathLabel
diff --git a/Snyk.VisualStudio.Extension.Shared/Settings/SnykGeneralSettingsUserControl.cs b/Snyk.VisualStudio.Extension.Shared/Settings/SnykGeneralSettingsUserControl.cs
index 266623563..6f5b4aa13 100644
--- a/Snyk.VisualStudio.Extension.Shared/Settings/SnykGeneralSettingsUserControl.cs
+++ b/Snyk.VisualStudio.Extension.Shared/Settings/SnykGeneralSettingsUserControl.cs
@@ -231,20 +231,22 @@ private async Task AuthenticateButtonClickAsync()
}
}
- private bool IsValidUrl(string url) => Uri.IsWellFormedUriString(url, UriKind.RelativeOrAbsolute);
+ private bool IsValidUrl(string url) => Uri.IsWellFormedUriString(url, UriKind.Absolute);
private void TokenTextBox_TextChanged(object sender, EventArgs e)
{
- this.ValidateChildren(ValidationConstraints.Enabled);
-
- this.OptionsDialogPage.SetApiToken(this.tokenTextBox.Text);
+ if (this.ValidateChildren(ValidationConstraints.Enabled))
+ {
+ this.OptionsDialogPage.SetApiToken(this.tokenTextBox.Text);
+ }
}
private void CustomEndpointTextBox_LostFocus(object sender, EventArgs e)
{
- this.ValidateChildren(ValidationConstraints.Enabled);
-
- this.OptionsDialogPage.CustomEndpoint = this.customEndpointTextBox.Text;
+ if (this.ValidateChildren(ValidationConstraints.Enabled))
+ {
+ this.OptionsDialogPage.CustomEndpoint = this.customEndpointTextBox.Text;
+ }
}
private void OrganizationTextBox_TextChanged(object sender, EventArgs e)
@@ -286,27 +288,15 @@ private void TokenTextBox_Validating(object sender, System.ComponentModel.Cancel
private void CustomEndpointTextBox_Validating(object sender, System.ComponentModel.CancelEventArgs cancelEventArgs)
{
- if (string.IsNullOrEmpty(this.tokenTextBox.Text))
+ if (string.IsNullOrWhiteSpace(this.customEndpointTextBox.Text) || this.IsValidUrl(this.customEndpointTextBox.Text))
{
- this.errorProvider.SetError(this.tokenTextBox, string.Empty);
-
+ this.errorProvider.SetNoError(this.customEndpointTextBox);
return;
}
- if (!string.IsNullOrWhiteSpace(this.customEndpointTextBox.Text) && !this.IsValidUrl(this.customEndpointTextBox.Text))
- {
- cancelEventArgs.Cancel = true;
-
- this.customEndpointTextBox.Focus();
-
- this.errorProvider.SetError(this.customEndpointTextBox, "Not valid URL.");
- }
- else
- {
- cancelEventArgs.Cancel = false;
-
- this.errorProvider.SetError(this.customEndpointTextBox, string.Empty);
- }
+ cancelEventArgs.Cancel = true;
+ //this.customEndpointTextBox.Focus();
+ this.errorProvider.SetError(this.customEndpointTextBox, "Needs to be a full absolute well-formed URL (including protocol)");
}
private void SnykGeneralSettingsUserControl_Load(object sender, EventArgs e)
diff --git a/Snyk.VisualStudio.Extension.Shared/Snyk.VisualStudio.Extension.Shared.projitems b/Snyk.VisualStudio.Extension.Shared/Snyk.VisualStudio.Extension.Shared.projitems
index 997803cec..35b01e9d4 100644
--- a/Snyk.VisualStudio.Extension.Shared/Snyk.VisualStudio.Extension.Shared.projitems
+++ b/Snyk.VisualStudio.Extension.Shared/Snyk.VisualStudio.Extension.Shared.projitems
@@ -36,6 +36,7 @@
+
Component