2023-01-04 18:39:39 +00:00
|
|
|
|
import React, { useCallback, useContext, useState } from "react";
|
2023-04-27 22:17:08 +00:00
|
|
|
|
import { InjectedRouter, Params } from "react-router/lib/Router";
|
2023-01-04 18:39:39 +00:00
|
|
|
|
import { useQuery } from "react-query";
|
|
|
|
|
|
import { useErrorHandler } from "react-error-boundary";
|
2022-04-21 18:12:42 +00:00
|
|
|
|
|
2023-01-04 18:39:39 +00:00
|
|
|
|
import { IConfig } from "interfaces/config";
|
|
|
|
|
|
import { IApiError } from "interfaces/errors";
|
|
|
|
|
|
import configAPI from "services/entities/config";
|
|
|
|
|
|
import { AppContext } from "context/app";
|
|
|
|
|
|
import { NotificationContext } from "context/notification";
|
|
|
|
|
|
import deepDifference from "utilities/deep_difference";
|
|
|
|
|
|
import Spinner from "components/Spinner";
|
2023-04-27 22:17:08 +00:00
|
|
|
|
import paths from "router/paths";
|
2023-01-04 18:39:39 +00:00
|
|
|
|
|
|
|
|
|
|
import SideNav from "../components/SideNav";
|
|
|
|
|
|
import ORG_SETTINGS_NAV_ITEMS from "./OrgSettingsNavItems";
|
2022-04-21 18:12:42 +00:00
|
|
|
|
|
2023-01-26 19:33:54 +00:00
|
|
|
|
interface IOrgSettingsPageProps {
|
2022-04-21 18:12:42 +00:00
|
|
|
|
params: Params;
|
2023-04-27 22:17:08 +00:00
|
|
|
|
router: InjectedRouter; // v3
|
2022-04-21 18:12:42 +00:00
|
|
|
|
}
|
2022-01-21 17:06:58 +00:00
|
|
|
|
|
2023-01-26 19:33:54 +00:00
|
|
|
|
export const baseClass = "org-settings";
|
2022-01-21 17:06:58 +00:00
|
|
|
|
|
2023-04-27 22:17:08 +00:00
|
|
|
|
const OrgSettingsPage = ({ params, router }: IOrgSettingsPageProps) => {
|
2022-07-19 18:55:47 +00:00
|
|
|
|
const { section } = params;
|
2023-01-04 18:39:39 +00:00
|
|
|
|
const DEFAULT_SETTINGS_SECTION = ORG_SETTINGS_NAV_ITEMS[0];
|
|
|
|
|
|
|
|
|
|
|
|
const [isUpdatingSettings, setIsUpdatingSettings] = useState(false);
|
2023-04-27 22:17:08 +00:00
|
|
|
|
const { isFreeTier, isPremiumTier, setConfig, isSandboxMode } = useContext(
|
|
|
|
|
|
AppContext
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (isSandboxMode) {
|
|
|
|
|
|
// redirect to Integrations page in sandbox mode
|
|
|
|
|
|
router.push(paths.ADMIN_INTEGRATIONS);
|
|
|
|
|
|
}
|
2023-01-04 18:39:39 +00:00
|
|
|
|
const { renderFlash } = useContext(NotificationContext);
|
|
|
|
|
|
const handlePageError = useErrorHandler();
|
|
|
|
|
|
|
|
|
|
|
|
const {
|
|
|
|
|
|
data: appConfig,
|
|
|
|
|
|
isLoading: isLoadingAppConfig,
|
|
|
|
|
|
refetch: refetchConfig,
|
|
|
|
|
|
} = useQuery<IConfig, Error, IConfig>(["config"], () => configAPI.loadAll(), {
|
|
|
|
|
|
select: (data: IConfig) => data,
|
|
|
|
|
|
onSuccess: (data) => {
|
|
|
|
|
|
setConfig(data);
|
|
|
|
|
|
},
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
const onFormSubmit = useCallback(
|
|
|
|
|
|
(formUpdates: Partial<IConfig>) => {
|
|
|
|
|
|
if (!appConfig) {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
setIsUpdatingSettings(true);
|
|
|
|
|
|
|
|
|
|
|
|
const diff = deepDifference(formUpdates, appConfig);
|
|
|
|
|
|
// send all formUpdates.agent_options because diff overrides all agent options
|
|
|
|
|
|
diff.agent_options = formUpdates.agent_options;
|
|
|
|
|
|
|
|
|
|
|
|
configAPI
|
|
|
|
|
|
.update(diff)
|
|
|
|
|
|
.then(() => {
|
|
|
|
|
|
renderFlash("success", "Successfully updated settings.");
|
|
|
|
|
|
refetchConfig();
|
|
|
|
|
|
})
|
|
|
|
|
|
.catch((response: { data: IApiError }) => {
|
|
|
|
|
|
if (
|
|
|
|
|
|
response?.data.errors[0].reason.includes("could not dial smtp host")
|
|
|
|
|
|
) {
|
|
|
|
|
|
renderFlash(
|
|
|
|
|
|
"error",
|
|
|
|
|
|
"Could not connect to SMTP server. Please try again."
|
|
|
|
|
|
);
|
|
|
|
|
|
} else if (response?.data.errors) {
|
|
|
|
|
|
const agentOptionsInvalid =
|
|
|
|
|
|
response.data.errors[0].reason.includes(
|
|
|
|
|
|
"unsupported key provided"
|
|
|
|
|
|
) ||
|
|
|
|
|
|
response.data.errors[0].reason.includes("invalid value type");
|
|
|
|
|
|
|
|
|
|
|
|
renderFlash(
|
|
|
|
|
|
"error",
|
|
|
|
|
|
<>
|
|
|
|
|
|
Could not update settings. {response.data.errors[0].reason}
|
|
|
|
|
|
{agentOptionsInvalid && (
|
|
|
|
|
|
<>
|
|
|
|
|
|
<br />
|
|
|
|
|
|
If you’re not using the latest osquery, use the fleetctl
|
|
|
|
|
|
apply --force command to override validation.
|
|
|
|
|
|
</>
|
|
|
|
|
|
)}
|
|
|
|
|
|
</>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
.finally(() => {
|
|
|
|
|
|
setIsUpdatingSettings(false);
|
|
|
|
|
|
});
|
|
|
|
|
|
},
|
|
|
|
|
|
[appConfig, refetchConfig, renderFlash]
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
// filter out non-premium options
|
|
|
|
|
|
let navItems = ORG_SETTINGS_NAV_ITEMS;
|
|
|
|
|
|
if (!isPremiumTier) {
|
|
|
|
|
|
navItems = ORG_SETTINGS_NAV_ITEMS.filter(
|
|
|
|
|
|
(item) => item.urlSection !== "fleet-desktop"
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const currentFormSection =
|
|
|
|
|
|
navItems.find((item) => item.urlSection === section) ??
|
|
|
|
|
|
DEFAULT_SETTINGS_SECTION;
|
|
|
|
|
|
|
|
|
|
|
|
const CurrentCard = currentFormSection.Card;
|
|
|
|
|
|
|
|
|
|
|
|
if (isFreeTier && section === "fleet-desktop") {
|
|
|
|
|
|
handlePageError({ status: 403 });
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
2022-02-10 16:10:51 +00:00
|
|
|
|
|
2022-01-21 17:06:58 +00:00
|
|
|
|
return (
|
2023-01-04 18:39:39 +00:00
|
|
|
|
<div className={`${baseClass}`}>
|
2022-01-21 17:06:58 +00:00
|
|
|
|
<p className={`${baseClass}__page-description`}>
|
2022-04-21 18:12:42 +00:00
|
|
|
|
Set your organization information and configure SSO and SMTP
|
2022-01-21 17:06:58 +00:00
|
|
|
|
</p>
|
2023-04-27 15:53:30 +00:00
|
|
|
|
<SideNav
|
|
|
|
|
|
className={`${baseClass}__side-nav`}
|
|
|
|
|
|
navItems={navItems}
|
|
|
|
|
|
activeItem={currentFormSection.urlSection}
|
|
|
|
|
|
CurrentCard={
|
|
|
|
|
|
!isLoadingAppConfig && appConfig ? (
|
|
|
|
|
|
<CurrentCard
|
|
|
|
|
|
appConfig={appConfig}
|
|
|
|
|
|
handleSubmit={onFormSubmit}
|
|
|
|
|
|
isUpdatingSettings={isUpdatingSettings}
|
|
|
|
|
|
isPremiumTier={isPremiumTier}
|
|
|
|
|
|
/>
|
|
|
|
|
|
) : (
|
|
|
|
|
|
<Spinner />
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
/>
|
2022-01-21 17:06:58 +00:00
|
|
|
|
</div>
|
|
|
|
|
|
);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2023-01-26 19:33:54 +00:00
|
|
|
|
export default OrgSettingsPage;
|