= {
fleet_desktop: {
- transparency_url: formData.transparency_url,
+ transparency_url: formData.transparencyUrl,
},
};
@@ -75,10 +73,11 @@ const FleetDesktop = ({
label="Custom transparency URL"
onChange={handleInputChange}
name="transparency_url"
- value={formData.transparency_url}
+ value={formData.transparencyUrl}
parseTarget
onBlur={validateForm}
error={formErrors.transparency_url}
+ placeholder="https://fleetdm.com/transparency"
/>
When an end user clicks “Transparency” in the Fleet Desktop menu, by
diff --git a/frontend/pages/admin/OrgSettingsPage/cards/HostStatusWebhook/HostStatusWebhook.tsx b/frontend/pages/admin/OrgSettingsPage/cards/HostStatusWebhook/HostStatusWebhook.tsx
index eb7f8c440c..8dd1bab37e 100644
--- a/frontend/pages/admin/OrgSettingsPage/cards/HostStatusWebhook/HostStatusWebhook.tsx
+++ b/frontend/pages/admin/OrgSettingsPage/cards/HostStatusWebhook/HostStatusWebhook.tsx
@@ -7,6 +7,8 @@ import Checkbox from "components/forms/fields/Checkbox";
import Dropdown from "components/forms/fields/Dropdown";
// @ts-ignore
import InputField from "components/forms/fields/InputField";
+import validUrl from "components/forms/validators/valid_url";
+
import Modal from "components/Modal";
import {
IAppConfigFormProps,
@@ -32,7 +34,7 @@ const HostStatusWebhook = ({
enableHostStatusWebhook:
appConfig.webhook_settings.host_status_webhook
.enable_host_status_webhook || false,
- hostStatusWebhookDestinationURL:
+ hostStatusWebhookDestinationUrl:
appConfig.webhook_settings.host_status_webhook.destination_url || "",
hostStatusWebhookHostPercentage:
appConfig.webhook_settings.host_status_webhook.host_percentage ||
@@ -43,7 +45,7 @@ const HostStatusWebhook = ({
const {
enableHostStatusWebhook,
- hostStatusWebhookDestinationURL,
+ hostStatusWebhookDestinationUrl,
hostStatusWebhookHostPercentage,
hostStatusWebhookDaysCount,
} = formData;
@@ -59,8 +61,10 @@ const HostStatusWebhook = ({
const errors: IAppConfigFormErrors = {};
if (enableHostStatusWebhook) {
- if (!hostStatusWebhookDestinationURL) {
+ if (!hostStatusWebhookDestinationUrl) {
errors.destination_url = "Destination URL must be present";
+ } else if (!validUrl({ url: hostStatusWebhookDestinationUrl })) {
+ errors.server_url = `${hostStatusWebhookDestinationUrl} is not a valid URL`;
}
if (!hostStatusWebhookDaysCount) {
@@ -92,7 +96,7 @@ const HostStatusWebhook = ({
webhook_settings: {
host_status_webhook: {
enable_host_status_webhook: enableHostStatusWebhook,
- destination_url: hostStatusWebhookDestinationURL,
+ destination_url: hostStatusWebhookDestinationUrl,
host_percentage: hostStatusWebhookHostPercentage,
days_count: hostStatusWebhookDaysCount,
},
@@ -171,8 +175,8 @@ const HostStatusWebhook = ({
placeholder="https://server.com/example"
label="Destination URL"
onChange={handleInputChange}
- name="hostStatusWebhookDestinationURL"
- value={hostStatusWebhookDestinationURL}
+ name="hostStatusWebhookDestinationUrl"
+ value={hostStatusWebhookDestinationUrl}
parseTarget
onBlur={validateForm}
error={formErrors.destination_url}
diff --git a/frontend/pages/admin/OrgSettingsPage/cards/Info/Info.tsx b/frontend/pages/admin/OrgSettingsPage/cards/Info/Info.tsx
index a99315c0f5..181c72049f 100644
--- a/frontend/pages/admin/OrgSettingsPage/cards/Info/Info.tsx
+++ b/frontend/pages/admin/OrgSettingsPage/cards/Info/Info.tsx
@@ -41,7 +41,7 @@ const Info = ({
errors.org_name = "Organization name must be present";
}
- if (orgLogoURL && !validUrl(orgLogoURL)) {
+ if (orgLogoURL && !validUrl({ url: orgLogoURL, protocol: "http" })) {
errors.org_logo_url = `${orgLogoURL} is not a valid URL`;
}
diff --git a/frontend/pages/admin/OrgSettingsPage/cards/Sso/Sso.tsx b/frontend/pages/admin/OrgSettingsPage/cards/Sso/Sso.tsx
index 9c69a7ae90..ae5c2321a6 100644
--- a/frontend/pages/admin/OrgSettingsPage/cards/Sso/Sso.tsx
+++ b/frontend/pages/admin/OrgSettingsPage/cards/Sso/Sso.tsx
@@ -16,15 +16,15 @@ import {
const baseClass = "app-config-form";
interface ISsoFormData {
- enableSSO?: boolean;
+ enableSso?: boolean;
idpName?: string;
- entityID?: string;
- issuerURI?: string;
- idpImageURL?: string;
+ entityId?: string;
+ issuerUri?: string;
+ idpImageUrl?: string;
metadata?: string;
- metadataURL?: string;
- enableSSOIDPLogin?: boolean;
- enableJITProvisioning?: boolean;
+ metadataUrl?: string;
+ enableSsoIdpLogin?: boolean;
+ enableJitProvisioning?: boolean;
}
const Sso = ({
@@ -34,28 +34,28 @@ const Sso = ({
isUpdatingSettings,
}: IAppConfigFormProps): JSX.Element => {
const [formData, setFormData] = useState({
- enableSSO: appConfig.sso_settings.enable_sso ?? false,
+ enableSso: appConfig.sso_settings.enable_sso ?? false,
idpName: appConfig.sso_settings.idp_name ?? "",
- entityID: appConfig.sso_settings.entity_id ?? "",
- issuerURI: appConfig.sso_settings.issuer_uri ?? "",
- idpImageURL: appConfig.sso_settings.idp_image_url ?? "",
+ entityId: appConfig.sso_settings.entity_id ?? "",
+ issuerUri: appConfig.sso_settings.issuer_uri ?? "",
+ idpImageUrl: appConfig.sso_settings.idp_image_url ?? "",
metadata: appConfig.sso_settings.metadata ?? "",
- metadataURL: appConfig.sso_settings.metadata_url ?? "",
- enableSSOIDPLogin: appConfig.sso_settings.enable_sso_idp_login ?? false,
- enableJITProvisioning:
+ metadataUrl: appConfig.sso_settings.metadata_url ?? "",
+ enableSsoIdpLogin: appConfig.sso_settings.enable_sso_idp_login ?? false,
+ enableJitProvisioning:
appConfig.sso_settings.enable_jit_provisioning ?? false,
});
const {
- enableSSO,
+ enableSso,
idpName,
- entityID,
- issuerURI,
- idpImageURL,
+ entityId,
+ issuerUri,
+ idpImageUrl,
metadata,
- metadataURL,
- enableSSOIDPLogin,
- enableJITProvisioning,
+ metadataUrl,
+ enableSsoIdpLogin,
+ enableJitProvisioning,
} = formData;
const [formErrors, setFormErrors] = useState({});
@@ -67,20 +67,25 @@ const Sso = ({
const validateForm = () => {
const errors: IAppConfigFormErrors = {};
- if (enableSSO) {
- if (idpImageURL && !validUrl(idpImageURL)) {
- errors.idp_image_url = `${idpImageURL} is not a valid URL`;
+ if (enableSso) {
+ if (idpImageUrl && !validUrl({ url: idpImageUrl })) {
+ errors.idp_image_url = `${idpImageUrl} is not a valid URL`;
}
- if (metadata === "" && metadataURL === "") {
- errors.metadata_url = "Metadata URL must be present";
+ if (!metadata) {
+ if (!metadataUrl) {
+ errors.metadata_url = "Metadata or Metadata URL must be present";
+ errors.metadata = "Metadata or Metadata URL must be present";
+ } else if (!validUrl({ url: metadataUrl })) {
+ errors.metadata_url = `${metadataUrl} is not a valid URL`;
+ }
}
- if (!entityID) {
+ if (!entityId) {
errors.entity_id = "Entity ID must be present";
}
- if (typeof entityID === "string" && entityID.length < 5) {
+ if (typeof entityId === "string" && entityId.length < 5) {
errors.entity_id = "Entity ID must be 5 or more characters";
}
@@ -94,7 +99,7 @@ const Sso = ({
useEffect(() => {
validateForm();
- }, [enableSSO]);
+ }, [idpImageUrl, metadata, metadataUrl, entityId, idpName]);
const onFormSubmit = (evt: React.MouseEvent) => {
evt.preventDefault();
@@ -102,15 +107,15 @@ const Sso = ({
// Formatting of API not UI
const formDataToSubmit = {
sso_settings: {
- entity_id: entityID?.trim(),
- issuer_uri: issuerURI?.trim(),
- idp_image_url: idpImageURL?.trim(),
+ entity_id: entityId?.trim(),
+ issuer_uri: issuerUri?.trim(),
+ idp_image_url: idpImageUrl?.trim(),
metadata: metadata?.trim(),
- metadata_url: metadataURL?.trim(),
+ metadata_url: metadataUrl?.trim(),
idp_name: idpName?.trim(),
- enable_sso: enableSSO,
- enable_sso_idp_login: enableSSOIDPLogin,
- enable_jit_provisioning: enableJITProvisioning,
+ enable_sso: enableSso,
+ enable_sso_idp_login: enableSsoIdpLogin,
+ enable_jit_provisioning: enableJitProvisioning,
},
};
@@ -124,8 +129,8 @@ const Sso = ({
Enable single sign-on
@@ -153,8 +158,8 @@ const Sso = ({
}
onChange={handleInputChange}
- name="entityID"
- value={entityID}
+ name="entityId"
+ value={entityId}
parseTarget
onBlur={validateForm}
error={formErrors.entity_id}
@@ -165,8 +170,8 @@ const Sso = ({
@@ -175,8 +180,8 @@ const Sso = ({
@@ -205,8 +211,8 @@ const Sso = ({
}
onChange={handleInputChange}
- name="metadataURL"
- value={metadataURL}
+ name="metadataUrl"
+ value={metadataUrl}
parseTarget
onBlur={validateForm}
error={formErrors.metadata_url}
@@ -216,8 +222,8 @@ const Sso = ({
Allow SSO login initiated by identity provider
@@ -227,8 +233,8 @@ const Sso = ({
<>
diff --git a/frontend/pages/admin/OrgSettingsPage/cards/WebAddress/WebAddress.tsx b/frontend/pages/admin/OrgSettingsPage/cards/WebAddress/WebAddress.tsx
index 048cc5d8c6..f8105774b9 100644
--- a/frontend/pages/admin/OrgSettingsPage/cards/WebAddress/WebAddress.tsx
+++ b/frontend/pages/admin/OrgSettingsPage/cards/WebAddress/WebAddress.tsx
@@ -3,6 +3,8 @@ import React, { useState } from "react";
import Button from "components/buttons/Button";
// @ts-ignore
import InputField from "components/forms/fields/InputField";
+import validUrl from "components/forms/validators/valid_url";
+
import {
IAppConfigFormProps,
IFormField,
@@ -31,9 +33,10 @@ const WebAddress = ({
const validateForm = () => {
const errors: IAppConfigFormErrors = {};
-
if (!serverURL) {
errors.server_url = "Fleet server URL must be present";
+ } else if (!validUrl({ url: serverURL, protocol: "http" })) {
+ errors.server_url = `${serverURL} is not a valid URL`;
}
setFormErrors(errors);
diff --git a/frontend/pages/admin/OrgSettingsPage/cards/constants.ts b/frontend/pages/admin/OrgSettingsPage/cards/constants.ts
index cb163259dd..88c7464afb 100644
--- a/frontend/pages/admin/OrgSettingsPage/cards/constants.ts
+++ b/frontend/pages/admin/OrgSettingsPage/cards/constants.ts
@@ -15,6 +15,7 @@ export interface IFormField {
}
export interface IAppConfigFormErrors {
+ metadata?: string | null;
metadata_url?: string | null;
entity_id?: string | null;
idp_name?: string | null;
diff --git a/frontend/pages/policies/ManagePoliciesPage/components/ManageAutomationsModal/ManageAutomationsModal.tsx b/frontend/pages/policies/ManagePoliciesPage/components/ManageAutomationsModal/ManageAutomationsModal.tsx
index e25ebe14fe..3c9a875feb 100644
--- a/frontend/pages/policies/ManagePoliciesPage/components/ManageAutomationsModal/ManageAutomationsModal.tsx
+++ b/frontend/pages/policies/ManagePoliciesPage/components/ManageAutomationsModal/ManageAutomationsModal.tsx
@@ -18,6 +18,7 @@ import Dropdown from "components/forms/fields/Dropdown";
// @ts-ignore
import InputField from "components/forms/fields/InputField";
import Radio from "components/forms/fields/Radio";
+import validUrl from "components/forms/validators/valid_url";
import PreviewPayloadModal from "../PreviewPayloadModal";
import PreviewTicketModal from "../PreviewTicketModal";
@@ -192,6 +193,8 @@ const ManageAutomationsModal = ({
if (isWebhookEnabled && !destinationUrl) {
newErrors.url = "Please add a destination URL";
+ } else if (!validUrl({ url: destinationUrl })) {
+ newErrors.url = `${destinationUrl} is not a valid URL`;
} else {
delete newErrors.url;
}
diff --git a/frontend/pages/software/ManageSoftwarePage/components/ManageAutomationsModal/ManageAutomationsModal.tsx b/frontend/pages/software/ManageSoftwarePage/components/ManageAutomationsModal/ManageAutomationsModal.tsx
index f4257a82d2..594593b4b3 100644
--- a/frontend/pages/software/ManageSoftwarePage/components/ManageAutomationsModal/ManageAutomationsModal.tsx
+++ b/frontend/pages/software/ManageSoftwarePage/components/ManageAutomationsModal/ManageAutomationsModal.tsx
@@ -26,6 +26,7 @@ import Slider from "components/forms/fields/Slider";
import Radio from "components/forms/fields/Radio";
// @ts-ignore
import InputField from "components/forms/fields/InputField";
+import validUrl from "components/forms/validators/valid_url";
import { IWebhookSoftwareVulnerabilities } from "interfaces/webhook";
import useDeepEffect from "hooks/useDeepEffect";
@@ -60,8 +61,12 @@ interface IManageAutomationsModalProps {
const validateWebhookURL = (url: string) => {
const errors: { [key: string]: string } = {};
- if (url === "") {
+ if (!url) {
errors.url = "Please add a destination URL";
+ } else if (!validUrl({ url })) {
+ errors.url = `${url} is not a valid URL`;
+ } else {
+ delete errors.url;
}
const valid = !size(errors);
@@ -186,7 +191,7 @@ const ManageAutomationsModal = ({
const handleSaveAutomation = (evt: React.MouseEvent) => {
evt.preventDefault();
- const { valid: validUrl, errors: newErrors } = validateWebhookURL(
+ const { valid: newValidUrl, errors: newErrors } = validateWebhookURL(
destinationUrl
);
setErrors({
@@ -232,7 +237,7 @@ const ManageAutomationsModal = ({
return;
}
if (!integrationEnabled) {
- if (!validUrl) {
+ if (!newValidUrl) {
return;
}
// set enable_vulnerabilities_webhook to true