fix vuex in the cmd placeholder computed function and cleanup the scriptDropdowns and actually filter by platform everywhere
This commit is contained in:
@@ -666,6 +666,7 @@ export default {
|
||||
componentProps: {
|
||||
check: check,
|
||||
parent: !check ? { agent: selectedAgent.value } : undefined,
|
||||
plat: type === "script" ? agentPlatform.value : undefined,
|
||||
},
|
||||
}).onOk(getChecks);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<q-tooltip class="bg-white text-primary">Close</q-tooltip>
|
||||
</q-btn>
|
||||
</q-bar>
|
||||
<q-card-section v-if="scriptOptions.length === 0">
|
||||
<q-card-section v-if="filterByPlatformOptions.length === 0">
|
||||
<p>You need to upload a script first</p>
|
||||
<p>Settings -> Script Manager</p>
|
||||
</q-card-section>
|
||||
@@ -19,7 +19,7 @@
|
||||
:rules="[(val) => !!val || '*Required']"
|
||||
outlined
|
||||
v-model="state.script"
|
||||
:options="scriptOptions"
|
||||
:options="filterByPlatformOptions"
|
||||
label="Select script"
|
||||
mapOptions
|
||||
:disable="!!check"
|
||||
@@ -140,6 +140,7 @@ export default {
|
||||
props: {
|
||||
check: Object,
|
||||
parent: Object, // {agent: agent.agent_id} or {policy: policy.id}
|
||||
plat: String,
|
||||
},
|
||||
setup(props) {
|
||||
// setup quasar dialog
|
||||
@@ -148,12 +149,13 @@ export default {
|
||||
// setup script dropdown
|
||||
const {
|
||||
script,
|
||||
scriptOptions,
|
||||
filterByPlatformOptions,
|
||||
defaultTimeout,
|
||||
defaultArgs,
|
||||
defaultEnvVars,
|
||||
} = useScriptDropdown({
|
||||
script: props.check ? props.check.script : undefined,
|
||||
plat: props.plat,
|
||||
onMount: true,
|
||||
});
|
||||
|
||||
@@ -182,7 +184,7 @@ export default {
|
||||
|
||||
// non-reactive data
|
||||
failOptions,
|
||||
scriptOptions,
|
||||
filterByPlatformOptions,
|
||||
severityOptions,
|
||||
envVarsLabel,
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
<tactical-dropdown
|
||||
:rules="[(val) => !!val || '*Required']"
|
||||
v-model="state.script"
|
||||
:options="filteredScriptOptions"
|
||||
:options="filterByPlatformOptions"
|
||||
label="Select Script"
|
||||
outlined
|
||||
mapOptions
|
||||
@@ -210,7 +210,14 @@
|
||||
|
||||
<script>
|
||||
// composition imports
|
||||
import { ref, computed, watch, onMounted } from "vue";
|
||||
import {
|
||||
ref,
|
||||
reactive,
|
||||
computed,
|
||||
watch,
|
||||
onMounted,
|
||||
defineComponent,
|
||||
} from "vue";
|
||||
import { useDialogPluginComponent } from "quasar";
|
||||
import { useScriptDropdown } from "@/composables/scripts";
|
||||
import { useAgentDropdown } from "@/composables/agents";
|
||||
@@ -218,7 +225,6 @@ import { useClientDropdown, useSiteDropdown } from "@/composables/clients";
|
||||
import { runBulkAction } from "@/api/agents";
|
||||
import { notifySuccess } from "@/utils/notify";
|
||||
import { cmdPlaceholder } from "@/composables/agents";
|
||||
import { removeExtraOptionCategories } from "@/utils/format";
|
||||
import { envVarsLabel, runAsUserToolTip } from "@/constants/constants";
|
||||
|
||||
// ui imports
|
||||
@@ -250,7 +256,7 @@ const patchModeOptions = [
|
||||
{ label: "Install", value: "install" },
|
||||
];
|
||||
|
||||
export default {
|
||||
export default defineComponent({
|
||||
name: "BulkAction",
|
||||
components: { TacticalDropdown },
|
||||
emits: [...useDialogPluginComponent.emits],
|
||||
@@ -259,7 +265,7 @@ export default {
|
||||
},
|
||||
setup(props) {
|
||||
const shellOptions = computed(() => {
|
||||
if (state.value.osType === "windows") {
|
||||
if (state.osType === "windows") {
|
||||
return [
|
||||
{ label: "CMD", value: "cmd" },
|
||||
{ label: "Powershell", value: "powershell" },
|
||||
@@ -286,7 +292,8 @@ export default {
|
||||
// dropdown setup
|
||||
const {
|
||||
script,
|
||||
scriptOptions,
|
||||
plat,
|
||||
filterByPlatformOptions,
|
||||
defaultTimeout,
|
||||
defaultArgs,
|
||||
defaultEnvVars,
|
||||
@@ -297,7 +304,7 @@ export default {
|
||||
const { client, clientOptions, getClientOptions } = useClientDropdown();
|
||||
|
||||
// bulk action logic
|
||||
const state = ref({
|
||||
const state = reactive({
|
||||
mode: props.mode,
|
||||
target: "client",
|
||||
monType: "all",
|
||||
@@ -319,7 +326,7 @@ export default {
|
||||
const loading = ref(false);
|
||||
|
||||
watch(
|
||||
() => state.value.target,
|
||||
() => state.target,
|
||||
() => {
|
||||
client.value = null;
|
||||
site.value = null;
|
||||
@@ -327,17 +334,23 @@ export default {
|
||||
},
|
||||
);
|
||||
|
||||
plat.value = state.osType;
|
||||
|
||||
watch(
|
||||
() => state.value.osType,
|
||||
() => state.osType,
|
||||
(newValue) => {
|
||||
state.value.custom_shell = null;
|
||||
state.value.run_as_user = false;
|
||||
state.custom_shell = null;
|
||||
state.run_as_user = false;
|
||||
|
||||
if (newValue === "windows") {
|
||||
state.value.shell = "cmd";
|
||||
state.shell = "cmd";
|
||||
} else {
|
||||
state.value.shell = "/bin/bash";
|
||||
state.shell = "/bin/bash";
|
||||
}
|
||||
|
||||
// set plat to filter script options
|
||||
if (newValue === "all") plat.value = undefined;
|
||||
else plat.value = newValue;
|
||||
},
|
||||
);
|
||||
|
||||
@@ -345,7 +358,7 @@ export default {
|
||||
loading.value = true;
|
||||
|
||||
try {
|
||||
const data = await runBulkAction(state.value);
|
||||
const data = await runBulkAction(state);
|
||||
notifySuccess(data);
|
||||
onDialogHide();
|
||||
} catch (e) {}
|
||||
@@ -355,9 +368,7 @@ export default {
|
||||
|
||||
const supportsRunAsUser = () => {
|
||||
const modes = ["script", "command"];
|
||||
return (
|
||||
state.value.osType === "windows" && modes.includes(state.value.mode)
|
||||
);
|
||||
return state.osType === "windows" && modes.includes(state.mode);
|
||||
};
|
||||
|
||||
// set modal title and caption
|
||||
@@ -371,21 +382,6 @@ export default {
|
||||
: "";
|
||||
});
|
||||
|
||||
const filteredScriptOptions = computed(() => {
|
||||
if (props.mode !== "script") return [];
|
||||
if (state.value.osType === "all") return scriptOptions.value;
|
||||
|
||||
return removeExtraOptionCategories(
|
||||
scriptOptions.value.filter(
|
||||
(script) =>
|
||||
script.category ||
|
||||
!script.supported_platforms ||
|
||||
script.supported_platforms.length === 0 ||
|
||||
script.supported_platforms.includes(state.value.osType),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
// component lifecycle hooks
|
||||
onMounted(() => {
|
||||
getAgentOptions();
|
||||
@@ -400,7 +396,7 @@ export default {
|
||||
agentOptions,
|
||||
clientOptions,
|
||||
siteOptions,
|
||||
filteredScriptOptions,
|
||||
filterByPlatformOptions,
|
||||
loading,
|
||||
shellOptions,
|
||||
filteredOsTypeOptions,
|
||||
@@ -426,5 +422,5 @@ export default {
|
||||
onDialogHide,
|
||||
};
|
||||
},
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -39,9 +39,9 @@
|
||||
<q-form @submit.prevent="sendScript">
|
||||
<q-card-section>
|
||||
<tactical-dropdown
|
||||
:rules="[(val) => !!val || '*Required']"
|
||||
:rules="[(val: number) => !!val || '*Required']"
|
||||
v-model="state.script"
|
||||
:options="filterByPlatformOptions(agent.plat)"
|
||||
:options="filterByPlatformOptions"
|
||||
label="Select script"
|
||||
outlined
|
||||
mapOptions
|
||||
@@ -130,7 +130,7 @@
|
||||
</q-card-section>
|
||||
<q-card-section v-if="state.output === 'collector'">
|
||||
<tactical-dropdown
|
||||
:rules="[(val) => !!val || '*Required']"
|
||||
:rules="[(val: number) => !!val || '*Required']"
|
||||
outlined
|
||||
v-model="state.custom_field"
|
||||
:options="customFieldOptions"
|
||||
@@ -197,7 +197,7 @@ import { formatScriptSyntax } from "@/utils/format";
|
||||
import TacticalDropdown from "@/components/ui/TacticalDropdown.vue";
|
||||
|
||||
// types
|
||||
import type { Agent } from "@/types/Agent";
|
||||
import type { Agent } from "@/types/agents";
|
||||
|
||||
// static data
|
||||
const outputOptions = [
|
||||
@@ -231,6 +231,7 @@ const {
|
||||
link,
|
||||
} = useScriptDropdown({
|
||||
script: props.script,
|
||||
plat: props.agent.plat,
|
||||
onMount: true,
|
||||
});
|
||||
const { customFieldOptions } = useCustomFieldDropdown({ onMount: true });
|
||||
@@ -261,7 +262,7 @@ async function sendScript() {
|
||||
loading.value = false;
|
||||
if (state.value.output === "forget") {
|
||||
onDialogHide();
|
||||
notifySuccess(ret.value);
|
||||
if (ret.value) notifySuccess(ret.value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
v-model="collector"
|
||||
class="q-pb-sm"
|
||||
@update:model-value="
|
||||
localTask.custom_field = null;
|
||||
localTask.custom_field = undefined;
|
||||
localTask.collector_all_output = false;
|
||||
"
|
||||
/>
|
||||
@@ -106,13 +106,7 @@
|
||||
class="col-3"
|
||||
label="Select script"
|
||||
v-model="script"
|
||||
:options="
|
||||
type === 'policy'
|
||||
? scriptOptions
|
||||
: type === 'server'
|
||||
? filterByPlatformOptions('linux')
|
||||
: filterByPlatformOptions(plat)
|
||||
"
|
||||
:options="filterByPlatformOptions"
|
||||
filled
|
||||
mapOptions
|
||||
filterable
|
||||
@@ -904,6 +898,7 @@ const { dialogRef, onDialogHide, onDialogOK } = useDialogPluginComponent();
|
||||
const {
|
||||
script,
|
||||
scriptOptions,
|
||||
plat,
|
||||
filterByPlatformOptions,
|
||||
defaultTimeout,
|
||||
defaultArgs,
|
||||
@@ -913,6 +908,14 @@ const {
|
||||
onMount: true,
|
||||
});
|
||||
|
||||
// set plat
|
||||
plat.value =
|
||||
props.type === "policy"
|
||||
? undefined // get all scripts
|
||||
: props.type === "server"
|
||||
? "linux" // get only linux scripts for server
|
||||
: props.plat; // filter scripts based on supported plat
|
||||
|
||||
// set defaultTimeout to 30
|
||||
defaultTimeout.value = 30;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ref } from "vue";
|
||||
import { useDashboardStore } from "@/stores/dashboard";
|
||||
import { ref, computed } from "vue";
|
||||
import { useStore } from "vuex";
|
||||
import { fetchAgents } from "@/api/agents";
|
||||
import { formatAgentOptions } from "@/utils/format";
|
||||
|
||||
@@ -29,11 +29,12 @@ export function useAgentDropdown() {
|
||||
}
|
||||
|
||||
export function cmdPlaceholder(shell) {
|
||||
const store = useDashboardStore();
|
||||
const store = useStore();
|
||||
const placeholders = computed(() => store.state.run_cmd_placeholder_text);
|
||||
|
||||
if (shell === "cmd") return store.runCmdPlaceholders.cmd;
|
||||
else if (shell === "powershell") return store.runCmdPlaceholders.powershell;
|
||||
else return store.runCmdPlaceholders.shell;
|
||||
if (shell === "cmd") return placeholders.value.cmd;
|
||||
else if (shell === "powershell") return placeholders.value.powershell;
|
||||
else return placeholders.value.shell;
|
||||
}
|
||||
|
||||
export const agentPlatformOptions = [
|
||||
|
||||
@@ -15,26 +15,32 @@ export interface ScriptOption extends Script {
|
||||
|
||||
export interface useScriptDropdownParams {
|
||||
script?: number; // set a selected script on init
|
||||
plat?: AgentPlatformType; // set a platform for filterByPlatform
|
||||
onMount?: boolean; // loads script options on mount
|
||||
}
|
||||
|
||||
// script dropdown
|
||||
export function useScriptDropdown(opts: useScriptDropdownParams) {
|
||||
export function useScriptDropdown(opts?: useScriptDropdownParams) {
|
||||
const scriptOptions = ref([] as ScriptOption[]);
|
||||
const defaultTimeout = ref(30);
|
||||
const defaultArgs = ref([] as string[]);
|
||||
const defaultEnvVars = ref([] as string[]);
|
||||
const script = ref(opts.script);
|
||||
const script = ref(opts?.script);
|
||||
const scriptName = ref("");
|
||||
const syntax = ref<string | undefined>("");
|
||||
const link = ref<string | undefined>("");
|
||||
const plat = ref<AgentPlatformType | undefined>(opts?.plat);
|
||||
const baseUrl =
|
||||
"https://github.com/amidaware/community-scripts/blob/main/scripts/";
|
||||
|
||||
// specify parameters to filter out community scripts
|
||||
async function getScriptOptions(showCommunityScripts = false) {
|
||||
async function getScriptOptions() {
|
||||
scriptOptions.value = Object.freeze(
|
||||
formatScriptOptions(await fetchScripts({ showCommunityScripts })),
|
||||
formatScriptOptions(
|
||||
await fetchScripts({
|
||||
showCommunityScripts: showCommunityScripts.value,
|
||||
}),
|
||||
),
|
||||
) as ScriptOption[];
|
||||
}
|
||||
|
||||
@@ -64,33 +70,34 @@ export function useScriptDropdown(opts: useScriptDropdownParams) {
|
||||
const showCommunityScripts = computed(() => store.state.showCommunityScripts);
|
||||
|
||||
// filter for only getting server tasks
|
||||
const serverScriptOptions = computed(() =>
|
||||
removeExtraOptionCategories(
|
||||
scriptOptions.value.filter(
|
||||
(script) =>
|
||||
script.category ||
|
||||
!script.supported_platforms ||
|
||||
script.supported_platforms.length === 0 ||
|
||||
script.supported_platforms.includes("linux"),
|
||||
),
|
||||
),
|
||||
const serverScriptOptions = computed(
|
||||
() =>
|
||||
removeExtraOptionCategories(
|
||||
scriptOptions.value.filter(
|
||||
(script) =>
|
||||
script.category ||
|
||||
!script.supported_platforms ||
|
||||
script.supported_platforms.length === 0 ||
|
||||
script.supported_platforms.includes("linux"),
|
||||
),
|
||||
) as ScriptOption[],
|
||||
);
|
||||
|
||||
const filterByPlatformOptions = (plat: AgentPlatformType | undefined) => {
|
||||
if (!plat) {
|
||||
const filterByPlatformOptions = computed(() => {
|
||||
if (!plat.value) {
|
||||
return scriptOptions.value;
|
||||
} else {
|
||||
return removeExtraOptionCategories(
|
||||
scriptOptions.value.filter(
|
||||
(script) =>
|
||||
script.category ||
|
||||
!script.supported_platforms ||
|
||||
script.supported_platforms.length === 0 ||
|
||||
script.supported_platforms.includes(plat.value!),
|
||||
),
|
||||
) as ScriptOption[];
|
||||
}
|
||||
|
||||
return removeExtraOptionCategories(
|
||||
scriptOptions.value.filter(
|
||||
(script) =>
|
||||
script.category ||
|
||||
!script.supported_platforms ||
|
||||
script.supported_platforms.length === 0 ||
|
||||
script.supported_platforms.includes(plat),
|
||||
),
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
function reset() {
|
||||
defaultTimeout.value = 30;
|
||||
@@ -101,8 +108,7 @@ export function useScriptDropdown(opts: useScriptDropdownParams) {
|
||||
link.value = "";
|
||||
}
|
||||
|
||||
if (opts.onMount)
|
||||
onMounted(() => getScriptOptions(showCommunityScripts.value));
|
||||
if (opts?.onMount) onMounted(() => getScriptOptions());
|
||||
|
||||
return {
|
||||
//data
|
||||
@@ -113,14 +119,15 @@ export function useScriptDropdown(opts: useScriptDropdownParams) {
|
||||
scriptName,
|
||||
syntax,
|
||||
link,
|
||||
plat,
|
||||
|
||||
scriptOptions, // unfiltered options
|
||||
serverScriptOptions, //only scripts that can run on server
|
||||
serverScriptOptions, // only scripts that can run on server
|
||||
filterByPlatformOptions, // use the returned plat to change options
|
||||
|
||||
//methods
|
||||
getScriptOptions,
|
||||
filterByPlatformOptions,
|
||||
reset,
|
||||
reset, // resets dropdown selection state
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user