diff --git a/changes/29762-run-script-modal-free-tier b/changes/29762-run-script-modal-free-tier
new file mode 100644
index 0000000000..f48c9e6e45
--- /dev/null
+++ b/changes/29762-run-script-modal-free-tier
@@ -0,0 +1 @@
+* Fixed bug with the run script modal on the Hosts page when running under FreeTier due to invalid teamId filter.
\ No newline at end of file
diff --git a/frontend/interfaces/script.ts b/frontend/interfaces/script.ts
index 7bbdd4dc21..226030f27c 100644
--- a/frontend/interfaces/script.ts
+++ b/frontend/interfaces/script.ts
@@ -11,6 +11,12 @@ export interface IScript {
export const isScriptSupportedPlatform = (hostPlatform: string) =>
["darwin", "windows", ...HOST_LINUX_PLATFORMS].includes(hostPlatform); // excludes chrome, ios, ipados, android see also https://github.com/fleetdm/fleet/blob/5a21e2cfb029053ddad0508869eb9f1f23997bf2/server/fleet/hosts.go#L775
+export const addTeamIdCriteria = (
+ pred: any,
+ teamId: number,
+ isFreeTier?: boolean
+) => (isFreeTier ? { ...pred } : { ...pred, team_id: teamId });
+
export type IScriptExecutionStatus = "ran" | "pending" | "error";
export interface ILastExecution {
diff --git a/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.tsx b/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.tsx
index 6f59eafbc0..469e24d2a3 100644
--- a/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.tsx
+++ b/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.tsx
@@ -2004,18 +2004,19 @@ const ManageHostsPage = ({
totalFilteredHostsCount !== undefined && (
)}
diff --git a/frontend/pages/hosts/ManageHostsPage/components/RunScriptBatchModal/RunScriptBatchModal.tsx b/frontend/pages/hosts/ManageHostsPage/components/RunScriptBatchModal/RunScriptBatchModal.tsx
index bf43b33d67..1ed4ce8872 100644
--- a/frontend/pages/hosts/ManageHostsPage/components/RunScriptBatchModal/RunScriptBatchModal.tsx
+++ b/frontend/pages/hosts/ManageHostsPage/components/RunScriptBatchModal/RunScriptBatchModal.tsx
@@ -5,7 +5,7 @@ import classnames from "classnames";
import { NotificationContext } from "context/notification";
-import { IScript } from "interfaces/script";
+import { addTeamIdCriteria, IScript } from "interfaces/script";
import { getErrorReason } from "interfaces/errors";
import { DEFAULT_USE_QUERY_OPTIONS } from "utilities/constants";
@@ -33,6 +33,8 @@ interface IRunScriptBatchModal {
// `filters` as needed
filters: Omit;
teamId: number;
+ // If we are on the free tier, we don't want to apply any kind of team filters (since the feature is Premium only).
+ isFreeTier?: boolean;
totalFilteredHostsCount: number;
selectedHostIds: number[];
onCancel: () => void;
@@ -44,6 +46,7 @@ const RunScriptBatchModal = ({
totalFilteredHostsCount,
selectedHostIds,
teamId,
+ isFreeTier,
onCancel,
}: IRunScriptBatchModal) => {
const { renderFlash } = useContext(NotificationContext);
@@ -52,19 +55,14 @@ const RunScriptBatchModal = ({
const [scriptForDetails, setScriptForDetails] = useState<
IPaginatedListScript | undefined
>(undefined);
- // just used to get total number of scripts, could be optimized by implementing a dedicated scriptsCount endpoint
+ // just used to get the total number of scripts, could be optimized by implementing a dedicated scriptsCount endpoint
const { data: scripts } = useQuery<
IScriptsResponse,
Error,
IScript[],
IListScriptsQueryKey[]
>(
- [
- {
- scope: "scripts",
- team_id: teamId,
- },
- ],
+ [addTeamIdCriteria({ scope: "scripts" }, teamId, isFreeTier)],
({ queryKey }) => {
return scriptsAPI.getScripts(queryKey[0]);
},
@@ -80,7 +78,10 @@ const RunScriptBatchModal = ({
setIsUpdating(true);
const body = runByFilters
? // satisfy IScriptBatchSupportedFilters
- { script_id: script.id, filters: { ...filters, team_id: teamId } }
+ {
+ script_id: script.id,
+ filters: addTeamIdCriteria(filters, teamId, isFreeTier),
+ }
: { script_id: script.id, host_ids: selectedHostIds };
try {
await scriptsAPI.runScriptBatch(body);
@@ -118,7 +119,16 @@ const RunScriptBatchModal = ({
info={
<>
You can add saved scripts{" "}
- here.
+
+ here
+
+ .
>
}
/>
@@ -140,6 +150,7 @@ const RunScriptBatchModal = ({
onRunScript={onRunScriptBatch}
isUpdating={isUpdating}
teamId={teamId}
+ isFreeTier={isFreeTier}
scriptCount={scripts.length}
setScriptForDetails={setScriptForDetails}
/>
diff --git a/frontend/pages/hosts/ManageHostsPage/components/RunScriptBatchPaginatedList/RunScriptBatchPaginatedList.tsx b/frontend/pages/hosts/ManageHostsPage/components/RunScriptBatchPaginatedList/RunScriptBatchPaginatedList.tsx
index 49700fecc7..1e03645c2b 100644
--- a/frontend/pages/hosts/ManageHostsPage/components/RunScriptBatchPaginatedList/RunScriptBatchPaginatedList.tsx
+++ b/frontend/pages/hosts/ManageHostsPage/components/RunScriptBatchPaginatedList/RunScriptBatchPaginatedList.tsx
@@ -3,7 +3,7 @@ import { useQueryClient } from "react-query";
import scriptAPI, { IScriptsResponse } from "services/entities/scripts";
-import { IScript } from "interfaces/script";
+import { addTeamIdCriteria, IScript } from "interfaces/script";
import PaginatedList from "components/PaginatedList";
import Button from "components/buttons/Button";
@@ -19,6 +19,7 @@ interface IRunScriptBatchPaginatedList {
onRunScript: (script: IPaginatedListScript) => Promise;
isUpdating: boolean;
teamId: number;
+ isFreeTier?: boolean;
scriptCount: number;
setScriptForDetails: (script: IPaginatedListScript) => void;
}
@@ -28,6 +29,7 @@ export const SCRIPT_BATCH_PAGE_SIZE = 6;
const RunScriptBatchPaginatedList = ({
onRunScript: _onRunScript,
isUpdating,
+ isFreeTier,
teamId,
scriptCount,
setScriptForDetails,
@@ -40,12 +42,15 @@ const RunScriptBatchPaginatedList = ({
// scripts not supported for All teams
const fetchPromise = queryClient.fetchQuery(
[
- {
- scope: "scripts",
- team_id: teamId,
- page: pageNumber,
- per_page: SCRIPT_BATCH_PAGE_SIZE,
- },
+ addTeamIdCriteria(
+ {
+ scope: "scripts",
+ page: pageNumber,
+ per_page: SCRIPT_BATCH_PAGE_SIZE,
+ },
+ teamId,
+ isFreeTier
+ ),
],
({ queryKey }) => {
return scriptAPI.getScripts(queryKey[0]);
@@ -56,7 +61,7 @@ const RunScriptBatchPaginatedList = ({
return scripts || [];
});
},
- [queryClient, teamId]
+ [queryClient, teamId, isFreeTier]
);
const onRunScript = useCallback(