Compare commits
23 Commits
v0.101.4-d
...
v0.101.14-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a63a9ccd76 | ||
|
|
ff1eb791db | ||
|
|
13bd88b979 | ||
|
|
5b0c244920 | ||
|
|
0318a17cac | ||
|
|
75296ed8ee | ||
|
|
09bee45b2f | ||
|
|
3573c48872 | ||
|
|
784841c221 | ||
|
|
ed788a1861 | ||
|
|
bd6b08505a | ||
|
|
acd64f25f2 | ||
|
|
087be2c232 | ||
|
|
91a3272843 | ||
|
|
6e64f0a11b | ||
|
|
8f34f76a1d | ||
|
|
d87861c212 | ||
|
|
5f56e7017b | ||
|
|
9c033c1c90 | ||
|
|
ba14ed348e | ||
|
|
7e25db6622 | ||
|
|
78636c436f | ||
|
|
d37122386f |
2
.vscode/extensions.json
vendored
2
.vscode/extensions.json
vendored
@@ -5,7 +5,7 @@
|
||||
"esbenp.prettier-vscode",
|
||||
"editorconfig.editorconfig",
|
||||
"vue.volar",
|
||||
"wayou.vscode-todo-highlight",
|
||||
"wayou.vscode-todo-highlight"
|
||||
],
|
||||
"unwantedRecommendations": [
|
||||
"octref.vetur",
|
||||
|
||||
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@@ -4,7 +4,7 @@
|
||||
"editor.formatOnSave": true,
|
||||
"[vue][javascript][typescript][javascriptreact]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.codeActionsOnSave": ["source.fixAll.eslint"],
|
||||
"editor.codeActionsOnSave": ["source.fixAll.eslint"]
|
||||
},
|
||||
"eslint.validate": ["javascript", "javascriptreact", "typescript", "vue"],
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
@@ -15,7 +15,7 @@
|
||||
"**/node_modules/": true,
|
||||
"/node_modules/**": true,
|
||||
"**/env/": true,
|
||||
"/env/**": true,
|
||||
"/env/**": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
36
index.html
36
index.html
@@ -1,24 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title><%= productName %></title>
|
||||
|
||||
<head>
|
||||
<title>
|
||||
<%= productName %>
|
||||
</title>
|
||||
|
||||
<meta charset="utf-8" />
|
||||
<meta name="robots" content="noindex" />
|
||||
<meta name="description" content="<%= productDescription %>" />
|
||||
<meta name="format-detection" content="telephone=no" />
|
||||
<meta name="msapplication-tap-highlight" content="no" />
|
||||
<meta name="viewport"
|
||||
content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width<% if (ctx.mode.cordova || ctx.mode.capacitor) { %>, viewport-fit=cover<% } %>" />
|
||||
<link rel="icon" type="image/ico" href="favicon.ico" />
|
||||
<script src="/env-config.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- quasar:entry-point -->
|
||||
</body>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="robots" content="noindex" />
|
||||
<meta name="description" content="<%= productDescription %>" />
|
||||
<meta name="format-detection" content="telephone=no" />
|
||||
<meta name="msapplication-tap-highlight" content="no" />
|
||||
<meta
|
||||
name="viewport"
|
||||
content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width<% if (ctx.mode.cordova || ctx.mode.capacitor) { %>, viewport-fit=cover<% } %>"
|
||||
/>
|
||||
<link rel="icon" type="image/ico" href="favicon.ico" />
|
||||
<script src="/env-config.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- quasar:entry-point -->
|
||||
</body>
|
||||
</html>
|
||||
|
||||
6083
package-lock.json
generated
6083
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
38
package.json
38
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "web",
|
||||
"version": "0.101.3",
|
||||
"version": "0.101.14-dev",
|
||||
"private": true,
|
||||
"productName": "Tactical RMM",
|
||||
"scripts": {
|
||||
@@ -10,13 +10,13 @@
|
||||
"format": "prettier --write \"**/*.{js,ts,vue,,html,md,json}\" --ignore-path .gitignore"
|
||||
},
|
||||
"dependencies": {
|
||||
"@quasar/extras": "1.15.5",
|
||||
"apexcharts": "3.35.5",
|
||||
"axios": "0.27.2",
|
||||
"@quasar/extras": "1.15.11",
|
||||
"apexcharts": "3.37.1",
|
||||
"axios": "1.3.4",
|
||||
"dotenv": "16.0.3",
|
||||
"qrcode.vue": "3.3.3",
|
||||
"quasar": "2.10.0",
|
||||
"vue": "3.2.41",
|
||||
"qrcode.vue": "3.3.4",
|
||||
"quasar": "2.11.8",
|
||||
"vue": "3.2.47",
|
||||
"vue3-ace-editor": "2.2.2",
|
||||
"vue3-apexcharts": "1.4.1",
|
||||
"vuedraggable": "4.1.0",
|
||||
@@ -24,17 +24,17 @@
|
||||
"vuex": "4.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@quasar/cli": "^1.3.2",
|
||||
"@intlify/vite-plugin-vue-i18n": "^6.0.3",
|
||||
"@quasar/app-vite": "^1.1.3",
|
||||
"@types/node": "^18.11.5",
|
||||
"@typescript-eslint/eslint-plugin": "^5.41.0",
|
||||
"@typescript-eslint/parser": "^5.41.0",
|
||||
"autoprefixer": "^10.4.12",
|
||||
"eslint": "^8.26.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-plugin-vue": "^8.5.0",
|
||||
"prettier": "^2.7.1",
|
||||
"typescript": "^4.8.4"
|
||||
"@quasar/cli": "^2.0.0",
|
||||
"@intlify/unplugin-vue-i18n": "^0.9.2",
|
||||
"@quasar/app-vite": "^1.2.1",
|
||||
"@types/node": "^18.15.3",
|
||||
"@typescript-eslint/eslint-plugin": "^5.55.0",
|
||||
"@typescript-eslint/parser": "^5.55.0",
|
||||
"autoprefixer": "10.4.14",
|
||||
"eslint": "8.36.0",
|
||||
"eslint-config-prettier": "8.7.0",
|
||||
"eslint-plugin-vue": "8.7.1",
|
||||
"prettier": "2.8.4",
|
||||
"typescript": "4.9.5"
|
||||
}
|
||||
}
|
||||
@@ -4,18 +4,18 @@
|
||||
module.exports = {
|
||||
plugins: [
|
||||
// https://github.com/postcss/autoprefixer
|
||||
require('autoprefixer')({
|
||||
require("autoprefixer")({
|
||||
overrideBrowserslist: [
|
||||
'last 4 Chrome versions',
|
||||
'last 4 Firefox versions',
|
||||
'last 4 Edge versions',
|
||||
'last 4 Safari versions',
|
||||
'last 4 Android versions',
|
||||
'last 4 ChromeAndroid versions',
|
||||
'last 4 FirefoxAndroid versions',
|
||||
'last 4 iOS versions'
|
||||
]
|
||||
})
|
||||
"last 4 Chrome versions",
|
||||
"last 4 Firefox versions",
|
||||
"last 4 Edge versions",
|
||||
"last 4 Safari versions",
|
||||
"last 4 Android versions",
|
||||
"last 4 ChromeAndroid versions",
|
||||
"last 4 FirefoxAndroid versions",
|
||||
"last 4 iOS versions",
|
||||
],
|
||||
}),
|
||||
|
||||
// https://github.com/elchininet/postcss-rtlcss
|
||||
// If you want to support RTL css, then
|
||||
@@ -23,5 +23,5 @@ module.exports = {
|
||||
// 2. optionally set quasar.config.js > framework > lang to an RTL language
|
||||
// 3. uncomment the following line:
|
||||
// require('postcss-rtlcss')
|
||||
]
|
||||
}
|
||||
],
|
||||
};
|
||||
|
||||
@@ -12,6 +12,25 @@ export async function fetchUsers(params = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
export async function resetPass(pass) {
|
||||
const payload = { password: pass };
|
||||
try {
|
||||
const { data } = await axios.put(`${baseUrl}/resetpw/`, payload);
|
||||
return data;
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
export async function resetTwoFactor() {
|
||||
try {
|
||||
const { data } = await axios.put(`${baseUrl}/reset2fa/`);
|
||||
return data;
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
// role api function
|
||||
export async function fetchRoles(params = {}) {
|
||||
try {
|
||||
|
||||
75
src/components/accounts/ResetPass.vue
Normal file
75
src/components/accounts/ResetPass.vue
Normal file
@@ -0,0 +1,75 @@
|
||||
<template>
|
||||
<q-dialog ref="dialogRef" @hide="onDialogHide">
|
||||
<q-card class="q-dialog-plugin" style="width: 60vw">
|
||||
<q-card-section class="row">
|
||||
<div class="col-3">New password:</div>
|
||||
<div class="col-9">
|
||||
<q-input
|
||||
outlined
|
||||
dense
|
||||
v-model="pass"
|
||||
:type="isPwd ? 'password' : 'text'"
|
||||
:rules="[(val) => !!val || '*Required']"
|
||||
>
|
||||
<template v-slot:append>
|
||||
<q-icon
|
||||
:name="isPwd ? 'visibility_off' : 'visibility'"
|
||||
class="cursor-pointer"
|
||||
@click="isPwd = !isPwd"
|
||||
/>
|
||||
</template>
|
||||
</q-input>
|
||||
</div>
|
||||
<div class="col-3">Confirm password:</div>
|
||||
<div class="col-9">
|
||||
<q-input
|
||||
outlined
|
||||
dense
|
||||
v-model="pass2"
|
||||
:type="isPwd ? 'password' : 'text'"
|
||||
:rules="[(val) => val === pass || 'Passwords do not match']"
|
||||
>
|
||||
<template v-slot:append>
|
||||
<q-icon
|
||||
:name="isPwd ? 'visibility_off' : 'visibility'"
|
||||
class="cursor-pointer"
|
||||
@click="isPwd = !isPwd"
|
||||
/>
|
||||
</template>
|
||||
</q-input>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-card-actions align="right">
|
||||
<q-btn
|
||||
color="primary"
|
||||
label="Reset"
|
||||
@click="onOKClick"
|
||||
:disable="!pass || pass !== pass2"
|
||||
/>
|
||||
<q-btn color="negative" label="Cancel" @click="onDialogCancel" />
|
||||
</q-card-actions>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { useDialogPluginComponent } from "quasar";
|
||||
import { resetPass } from "@/api/accounts";
|
||||
import { notifySuccess } from "@/utils/notify";
|
||||
|
||||
const pass = ref("");
|
||||
const pass2 = ref("");
|
||||
const isPwd = ref(true);
|
||||
|
||||
defineEmits([...useDialogPluginComponent.emits]);
|
||||
|
||||
const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } =
|
||||
useDialogPluginComponent();
|
||||
|
||||
async function onOKClick() {
|
||||
const ret = await resetPass(pass.value);
|
||||
notifySuccess(ret);
|
||||
onDialogOK();
|
||||
}
|
||||
</script>
|
||||
@@ -166,7 +166,7 @@ export default {
|
||||
type: "textarea",
|
||||
isValid: (val) => !!val,
|
||||
},
|
||||
style: "width: 30vw; max-width: 50vw;",
|
||||
style: "width: 90vw; max-width: 90vw",
|
||||
ok: { label: "Add" },
|
||||
cancel: true,
|
||||
}).onOk(async () => {
|
||||
@@ -193,7 +193,7 @@ export default {
|
||||
type: "textarea",
|
||||
isValid: (val) => !!val,
|
||||
},
|
||||
style: "width: 30vw; max-width: 50vw;",
|
||||
style: "width: 90vw; max-width: 90vw",
|
||||
ok: { label: "Save" },
|
||||
cancel: true,
|
||||
}).onOk(async (data) => {
|
||||
|
||||
@@ -8,16 +8,16 @@
|
||||
v
|
||||
}}</q-badge>
|
||||
<q-btn
|
||||
v-if="!!v"
|
||||
size="sm"
|
||||
class="q-ml-xs"
|
||||
flat
|
||||
round
|
||||
icon="content_copy"
|
||||
@click="copyValueToClip(v)"
|
||||
>
|
||||
<q-tooltip>Copy to Clipboard</q-tooltip>
|
||||
</q-btn>
|
||||
v-if="!!v"
|
||||
size="sm"
|
||||
class="q-ml-xs"
|
||||
flat
|
||||
round
|
||||
icon="content_copy"
|
||||
@click="copyValueToClip(v)"
|
||||
>
|
||||
<q-tooltip>Copy to Clipboard</q-tooltip>
|
||||
</q-btn>
|
||||
</div>
|
||||
</div>
|
||||
<q-separator v-if="info.length > 1" />
|
||||
@@ -42,10 +42,9 @@ export default {
|
||||
const tabHeight = computed(() => store.state.tabHeight);
|
||||
|
||||
function copyValueToClip(val) {
|
||||
copyToClipboard(val)
|
||||
.then(() => {
|
||||
notifySuccess("Copied to clipboard");
|
||||
})
|
||||
copyToClipboard(val).then(() => {
|
||||
notifySuccess("Copied to clipboard");
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -39,6 +39,19 @@
|
||||
new-value-mode="add"
|
||||
/>
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<q-select
|
||||
dense
|
||||
:label="envVarsLabel"
|
||||
filled
|
||||
v-model="state.env_vars"
|
||||
use-input
|
||||
use-chips
|
||||
multiple
|
||||
hide-dropdown-icon
|
||||
new-value-mode="add"
|
||||
/>
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<tactical-dropdown
|
||||
label="Informational return codes (press Enter after typing each code)"
|
||||
@@ -115,6 +128,7 @@ import { useDialogPluginComponent } from "quasar";
|
||||
import { useCheckModal } from "@/composables/checks";
|
||||
import { useScriptDropdown } from "@/composables/scripts";
|
||||
import { validateRetcode } from "@/utils/validation";
|
||||
import { envVarsLabel } from "@/constants/constants";
|
||||
|
||||
// ui imports
|
||||
import TacticalDropdown from "@/components/ui/TacticalDropdown.vue";
|
||||
@@ -132,10 +146,15 @@ export default {
|
||||
const { dialogRef, onDialogHide, onDialogOK } = useDialogPluginComponent();
|
||||
|
||||
// setup script dropdown
|
||||
const { script, scriptOptions, defaultTimeout, defaultArgs } =
|
||||
useScriptDropdown(props.check ? props.check.script : undefined, {
|
||||
onMount: true,
|
||||
});
|
||||
const {
|
||||
script,
|
||||
scriptOptions,
|
||||
defaultTimeout,
|
||||
defaultArgs,
|
||||
defaultEnvVars,
|
||||
} = useScriptDropdown(props.check ? props.check.script : undefined, {
|
||||
onMount: true,
|
||||
});
|
||||
|
||||
// check logic
|
||||
const { state, loading, submit, failOptions, severityOptions } =
|
||||
@@ -145,6 +164,7 @@ export default {
|
||||
...props.parent,
|
||||
script,
|
||||
script_args: defaultArgs,
|
||||
env_vars: defaultEnvVars,
|
||||
timeout: defaultTimeout,
|
||||
check_type: "script",
|
||||
fails_b4_alert: 1,
|
||||
@@ -163,6 +183,7 @@ export default {
|
||||
failOptions,
|
||||
scriptOptions,
|
||||
severityOptions,
|
||||
envVarsLabel,
|
||||
|
||||
// methods
|
||||
submit,
|
||||
|
||||
@@ -122,7 +122,7 @@ export default {
|
||||
|
||||
try {
|
||||
const result = props.APIKey
|
||||
? await editAPIKey(data)
|
||||
? await editAPIKey(data.id, data)
|
||||
: await saveAPIKey(data);
|
||||
onDialogOK();
|
||||
notifySuccess(result);
|
||||
|
||||
@@ -89,7 +89,8 @@
|
||||
<p class="text-italic">
|
||||
Note: the auth token above will be valid for {{ info.expires }} hours.
|
||||
</p>
|
||||
<q-btn v-if="info.plat === 'windows'"
|
||||
<q-btn
|
||||
v-if="info.plat === 'windows'"
|
||||
type="a"
|
||||
:href="info.data.url"
|
||||
color="primary"
|
||||
|
||||
@@ -102,6 +102,18 @@
|
||||
new-value-mode="add"
|
||||
/>
|
||||
</q-card-section>
|
||||
<q-card-section v-if="mode === 'script'" class="q-pt-none">
|
||||
<tactical-dropdown
|
||||
v-model="state.env_vars"
|
||||
:label="envVarsLabel"
|
||||
filled
|
||||
use-input
|
||||
multiple
|
||||
hide-dropdown-icon
|
||||
input-debounce="0"
|
||||
new-value-mode="add"
|
||||
/>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-section v-if="mode === 'command'">
|
||||
<p>Shell</p>
|
||||
@@ -208,7 +220,7 @@ import { runBulkAction } from "@/api/agents";
|
||||
import { notifySuccess } from "@/utils/notify";
|
||||
import { cmdPlaceholder } from "@/composables/agents";
|
||||
import { removeExtraOptionCategories } from "@/utils/format";
|
||||
import { runAsUserToolTip } from "@/constants/constants";
|
||||
import { envVarsLabel, runAsUserToolTip } from "@/constants/constants";
|
||||
|
||||
// ui imports
|
||||
import TacticalDropdown from "@/components/ui/TacticalDropdown.vue";
|
||||
@@ -284,6 +296,7 @@ export default {
|
||||
scriptOptions,
|
||||
defaultTimeout,
|
||||
defaultArgs,
|
||||
defaultEnvVars,
|
||||
getScriptOptions,
|
||||
} = useScriptDropdown();
|
||||
const { agents, agentOptions, getAgentOptions } = useAgentDropdown();
|
||||
@@ -307,6 +320,7 @@ export default {
|
||||
script,
|
||||
timeout: defaultTimeout,
|
||||
args: defaultArgs,
|
||||
env_vars: defaultEnvVars,
|
||||
run_as_user: false,
|
||||
});
|
||||
const loading = ref(false);
|
||||
@@ -404,6 +418,7 @@ export default {
|
||||
targetOptions,
|
||||
patchModeOptions,
|
||||
runAsUserToolTip,
|
||||
envVarsLabel,
|
||||
|
||||
//computed
|
||||
modalTitle,
|
||||
|
||||
@@ -77,6 +77,18 @@
|
||||
new-value-mode="add"
|
||||
/>
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<tactical-dropdown
|
||||
v-model="state.env_vars"
|
||||
:label="envVarsLabel"
|
||||
filled
|
||||
use-input
|
||||
multiple
|
||||
hide-dropdown-icon
|
||||
input-debounce="0"
|
||||
new-value-mode="add"
|
||||
/>
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<q-option-group
|
||||
v-model="state.output"
|
||||
@@ -178,7 +190,7 @@ import { useScriptDropdown } from "@/composables/scripts";
|
||||
import { useCustomFieldDropdown } from "@/composables/core";
|
||||
import { runScript } from "@/api/agents";
|
||||
import { notifySuccess } from "@/utils/notify";
|
||||
import { runAsUserToolTip } from "@/constants/constants";
|
||||
import { envVarsLabel, runAsUserToolTip } from "@/constants/constants";
|
||||
import {
|
||||
formatScriptSyntax,
|
||||
removeExtraOptionCategories,
|
||||
@@ -209,11 +221,18 @@ export default {
|
||||
const { dialogRef, onDialogHide } = useDialogPluginComponent();
|
||||
|
||||
// setup dropdowns
|
||||
const { script, scriptOptions, defaultTimeout, defaultArgs, syntax, link } =
|
||||
useScriptDropdown(props.script, {
|
||||
onMount: true,
|
||||
filterByPlatform: props.agent.plat,
|
||||
});
|
||||
const {
|
||||
script,
|
||||
scriptOptions,
|
||||
defaultTimeout,
|
||||
defaultArgs,
|
||||
defaultEnvVars,
|
||||
syntax,
|
||||
link,
|
||||
} = useScriptDropdown(props.script, {
|
||||
onMount: true,
|
||||
filterByPlatform: props.agent.plat,
|
||||
});
|
||||
const { customFieldOptions } = useCustomFieldDropdown({ onMount: true });
|
||||
|
||||
// main run script functionaity
|
||||
@@ -225,6 +244,7 @@ export default {
|
||||
save_all_output: false,
|
||||
script,
|
||||
args: defaultArgs,
|
||||
env_vars: defaultEnvVars,
|
||||
timeout: defaultTimeout,
|
||||
run_as_user: false,
|
||||
});
|
||||
@@ -281,6 +301,7 @@ export default {
|
||||
// non-reactive data
|
||||
outputOptions,
|
||||
runAsUserToolTip,
|
||||
envVarsLabel,
|
||||
|
||||
//methods
|
||||
formatScriptSyntax,
|
||||
|
||||
@@ -204,6 +204,20 @@
|
||||
new-value-mode="add"
|
||||
/>
|
||||
|
||||
<q-select
|
||||
class="q-mb-sm"
|
||||
dense
|
||||
label="Failure action environment vars (press Enter after typing each key=value pair)"
|
||||
filled
|
||||
v-model="template.action_env_vars"
|
||||
use-input
|
||||
use-chips
|
||||
multiple
|
||||
hide-dropdown-icon
|
||||
input-debounce="0"
|
||||
new-value-mode="add"
|
||||
/>
|
||||
|
||||
<q-input
|
||||
class="q-mb-sm"
|
||||
label="Failure action timeout (seconds)"
|
||||
@@ -277,6 +291,20 @@
|
||||
new-value-mode="add"
|
||||
/>
|
||||
|
||||
<q-select
|
||||
class="q-mb-sm"
|
||||
dense
|
||||
label="Resolved action environment vars (press Enter after typing each key=value pair)"
|
||||
filled
|
||||
v-model="template.resolved_action_env_vars"
|
||||
use-input
|
||||
use-chips
|
||||
multiple
|
||||
hide-dropdown-icon
|
||||
input-debounce="0"
|
||||
new-value-mode="add"
|
||||
/>
|
||||
|
||||
<q-input
|
||||
class="q-mb-sm"
|
||||
label="Resolved action timeout (seconds)"
|
||||
@@ -696,9 +724,11 @@ export default {
|
||||
is_active: true,
|
||||
action: null,
|
||||
action_args: [],
|
||||
action_env_vars: [],
|
||||
action_timeout: 15,
|
||||
resolved_action: null,
|
||||
resolved_action_args: [],
|
||||
resolved_action_env_vars: [],
|
||||
resolved_action_timeout: 15,
|
||||
email_recipients: [],
|
||||
email_from: "",
|
||||
@@ -762,11 +792,13 @@ export default {
|
||||
(i) => i.value === this.template.action
|
||||
);
|
||||
this.template.action_args = script.args;
|
||||
this.template.action_env_vars = script.env_vars;
|
||||
} else if (type === "resolved") {
|
||||
const script = this.scriptOptions.find(
|
||||
(i) => i.value === this.template.resolved_action
|
||||
);
|
||||
this.template.resolved_action_args = script.args;
|
||||
this.template.resolved_action_env_vars = script.env_vars;
|
||||
}
|
||||
},
|
||||
toggleAddEmail() {
|
||||
|
||||
@@ -118,6 +118,17 @@
|
||||
new-value-mode="add"
|
||||
:readonly="readonly"
|
||||
/>
|
||||
<tactical-dropdown
|
||||
v-model="formScript.env_vars"
|
||||
:label="envVarsLabel"
|
||||
filled
|
||||
use-input
|
||||
multiple
|
||||
hide-dropdown-icon
|
||||
input-debounce="0"
|
||||
new-value-mode="add"
|
||||
:readonly="readonly"
|
||||
/>
|
||||
<q-input
|
||||
type="number"
|
||||
filled
|
||||
@@ -137,7 +148,7 @@
|
||||
'Run As User' checkboxes in the UI and force this script to
|
||||
always be run in the context of the logged in user. If no user
|
||||
is logged in, the script will not run and an error will be
|
||||
returned. Not supported on Windows Server.
|
||||
returned.
|
||||
</q-tooltip>
|
||||
</q-checkbox>
|
||||
<q-input
|
||||
@@ -229,6 +240,7 @@ import "ace-builds/src-noconflict/theme-tomorrow";
|
||||
|
||||
// static data
|
||||
import { shellOptions } from "@/composables/scripts";
|
||||
import { envVarsLabel } from "@/constants/constants";
|
||||
|
||||
export default {
|
||||
name: "ScriptFormModal",
|
||||
@@ -266,6 +278,7 @@ export default {
|
||||
args: [],
|
||||
script_body: "",
|
||||
run_as_user: false,
|
||||
env_vars: [],
|
||||
});
|
||||
|
||||
if (props.clone) script.value.name = `(Copy) ${script.value.name}`;
|
||||
@@ -363,6 +376,7 @@ export default {
|
||||
// non-reactive data
|
||||
shellOptions,
|
||||
agentPlatformOptions,
|
||||
envVarsLabel,
|
||||
|
||||
//computed
|
||||
title,
|
||||
|
||||
@@ -93,6 +93,20 @@
|
||||
/>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-section>
|
||||
<tactical-dropdown
|
||||
v-model="script.env_vars"
|
||||
label="Environment Variables"
|
||||
placeholder="(press Enter after typing each key=value pair)"
|
||||
filled
|
||||
use-input
|
||||
multiple
|
||||
hide-dropdown-icon
|
||||
input-debounce="0"
|
||||
new-value-mode="add"
|
||||
/>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-section>
|
||||
<q-input
|
||||
label="Default Timeout"
|
||||
|
||||
@@ -45,6 +45,7 @@ export default {
|
||||
args: props.script.args,
|
||||
shell: props.script.shell,
|
||||
run_as_user: props.script.run_as_user,
|
||||
env_vars: props.script.env_vars,
|
||||
};
|
||||
try {
|
||||
ret.value = await testScript(props.agent, data);
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
|
||||
<tactical-dropdown
|
||||
v-if="actionType === 'script'"
|
||||
class="col-4"
|
||||
class="col-3"
|
||||
label="Select script"
|
||||
v-model="script"
|
||||
:options="scriptOptions"
|
||||
@@ -113,7 +113,7 @@
|
||||
|
||||
<q-select
|
||||
v-if="actionType === 'script'"
|
||||
class="col-5"
|
||||
class="col-3"
|
||||
dense
|
||||
label="Script Arguments (press Enter after typing each argument)"
|
||||
filled
|
||||
@@ -126,6 +126,21 @@
|
||||
new-value-mode="add"
|
||||
/>
|
||||
|
||||
<q-select
|
||||
v-if="actionType === 'script'"
|
||||
class="col-3"
|
||||
dense
|
||||
:label="envVarsLabel"
|
||||
filled
|
||||
v-model="defaultEnvVars"
|
||||
use-input
|
||||
use-chips
|
||||
multiple
|
||||
hide-dropdown-icon
|
||||
input-debounce="0"
|
||||
new-value-mode="add"
|
||||
/>
|
||||
|
||||
<q-input
|
||||
v-if="actionType === 'script'"
|
||||
class="col-2"
|
||||
@@ -210,6 +225,9 @@
|
||||
<q-item-label caption>
|
||||
Arguments: {{ element.script_args }}
|
||||
</q-item-label>
|
||||
<q-item-label caption>
|
||||
Env Vars: {{ element.env_vars }}
|
||||
</q-item-label>
|
||||
<q-item-label caption>
|
||||
Timeout: {{ element.timeout }}
|
||||
</q-item-label>
|
||||
@@ -727,6 +745,7 @@ import { useCheckDropdown } from "@/composables/checks";
|
||||
import { useCustomFieldDropdown } from "@/composables/core";
|
||||
import { notifySuccess, notifyError } from "@/utils/notify";
|
||||
import { validateTimePeriod } from "@/utils/validation";
|
||||
import { envVarsLabel } from "@/constants/constants";
|
||||
import {
|
||||
convertPeriodToSeconds,
|
||||
convertToBitArray,
|
||||
@@ -817,10 +836,15 @@ export default {
|
||||
const { dialogRef, onDialogHide, onDialogOK } = useDialogPluginComponent();
|
||||
|
||||
// setup dropdowns
|
||||
const { script, scriptOptions, defaultTimeout, defaultArgs } =
|
||||
useScriptDropdown(undefined, {
|
||||
onMount: true,
|
||||
});
|
||||
const {
|
||||
script,
|
||||
scriptOptions,
|
||||
defaultTimeout,
|
||||
defaultArgs,
|
||||
defaultEnvVars,
|
||||
} = useScriptDropdown(undefined, {
|
||||
onMount: true,
|
||||
});
|
||||
|
||||
// set defaultTimeout to 30
|
||||
defaultTimeout.value = 30;
|
||||
@@ -914,6 +938,7 @@ export default {
|
||||
script: script.value,
|
||||
timeout: defaultTimeout.value,
|
||||
script_args: defaultArgs.value,
|
||||
env_vars: defaultEnvVars.value,
|
||||
});
|
||||
} else if (actionType.value === "cmd") {
|
||||
task.value.actions.push({
|
||||
@@ -927,6 +952,7 @@ export default {
|
||||
// clear fields after add
|
||||
script.value = null;
|
||||
defaultArgs.value = [];
|
||||
defaultEnvVars.value = [];
|
||||
defaultTimeout.value = 30;
|
||||
command.value = "";
|
||||
}
|
||||
@@ -1089,6 +1115,7 @@ export default {
|
||||
script,
|
||||
defaultTimeout,
|
||||
defaultArgs,
|
||||
defaultEnvVars,
|
||||
actionType,
|
||||
command,
|
||||
shell,
|
||||
@@ -1116,6 +1143,7 @@ export default {
|
||||
monthOptions,
|
||||
taskTypeOptions,
|
||||
taskInstancePolicyOptions,
|
||||
envVarsLabel,
|
||||
|
||||
// methods
|
||||
submit,
|
||||
|
||||
@@ -8,6 +8,7 @@ export function useScriptDropdown(setScript = null, { onMount = false } = {}) {
|
||||
const scriptOptions = ref([]);
|
||||
const defaultTimeout = ref(30);
|
||||
const defaultArgs = ref([]);
|
||||
const defaultEnvVars = ref([]);
|
||||
const script = ref(setScript);
|
||||
const syntax = ref("");
|
||||
const link = ref("");
|
||||
@@ -29,6 +30,7 @@ export function useScriptDropdown(setScript = null, { onMount = false } = {}) {
|
||||
);
|
||||
defaultTimeout.value = tmpScript.timeout;
|
||||
defaultArgs.value = tmpScript.args;
|
||||
defaultEnvVars.value = tmpScript.env_vars;
|
||||
syntax.value = tmpScript.syntax;
|
||||
link.value =
|
||||
tmpScript.script_type === "builtin"
|
||||
@@ -49,6 +51,7 @@ export function useScriptDropdown(setScript = null, { onMount = false } = {}) {
|
||||
scriptOptions,
|
||||
defaultTimeout,
|
||||
defaultArgs,
|
||||
defaultEnvVars,
|
||||
syntax,
|
||||
link,
|
||||
|
||||
|
||||
@@ -1,15 +1,10 @@
|
||||
const GOARCH_AMD64 = "amd64";
|
||||
const GOARCH_i386 = "386";
|
||||
const GOARCH_ARM64 = "arm64";
|
||||
const GOARCH_ARM32 = "arm";
|
||||
export const GOARCH_AMD64 = "amd64";
|
||||
export const GOARCH_i386 = "386";
|
||||
export const GOARCH_ARM64 = "arm64";
|
||||
export const GOARCH_ARM32 = "arm";
|
||||
|
||||
const runAsUserToolTip =
|
||||
"Run in the context of the logged in user. If no user is logged in, the script will not run and an error will be returned. Not supported on Windows Server.";
|
||||
export const runAsUserToolTip =
|
||||
"Run in the context of the logged in user. If no user is logged in, the script will not run and an error will be returned.";
|
||||
|
||||
export {
|
||||
GOARCH_AMD64,
|
||||
GOARCH_i386,
|
||||
GOARCH_ARM64,
|
||||
GOARCH_ARM32,
|
||||
runAsUserToolTip,
|
||||
};
|
||||
export const envVarsLabel =
|
||||
"Environment vars (press Enter after typing each key=value pair)";
|
||||
|
||||
@@ -19,10 +19,15 @@
|
||||
inline-actions
|
||||
class="bg-yellow text-black text-center"
|
||||
>
|
||||
<q-icon size="xl" name="warning" />
|
||||
<span><br />Your code signing token is no longer valid.<br/><br/>
|
||||
If you have downgraded or cancelled your sponsorship, please delete your token from the Code Signing modal and refresh to get rid of this banner.<br/><br/>
|
||||
For any issues or to renew your sponsorship please email support@amidaware.com<br/><br/></span>
|
||||
<q-icon size="xl" name="warning" />
|
||||
<span
|
||||
><br />Your code signing token is no longer valid.<br /><br />
|
||||
If you have downgraded or cancelled your sponsorship, please delete
|
||||
your token from the Code Signing modal and refresh to get rid of this
|
||||
banner.<br /><br />
|
||||
For any issues or to renew your sponsorship please email
|
||||
support@amidaware.com<br /><br
|
||||
/></span>
|
||||
<q-btn
|
||||
color="dark"
|
||||
icon="refresh"
|
||||
@@ -135,6 +140,32 @@
|
||||
<q-item-label>Preferences</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item clickable>
|
||||
<q-item-section>Account</q-item-section>
|
||||
<q-item-section side>
|
||||
<q-icon name="keyboard_arrow_right" />
|
||||
</q-item-section>
|
||||
|
||||
<q-menu anchor="top end" self="top start">
|
||||
<q-list>
|
||||
<q-item
|
||||
clickable
|
||||
v-ripple
|
||||
@click="resetPassword"
|
||||
v-close-popup
|
||||
>
|
||||
<q-item-section>
|
||||
<q-item-label>Reset Password</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item clickable v-ripple @click="reset2FA" v-close-popup>
|
||||
<q-item-section>
|
||||
<q-item-label>Reset 2FA</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-menu>
|
||||
</q-item>
|
||||
<q-item to="/expired" exact>
|
||||
<q-item-section>
|
||||
<q-item-label>Logout</q-item-label>
|
||||
@@ -156,10 +187,13 @@ import { useQuasar } from "quasar";
|
||||
import { useStore } from "vuex";
|
||||
import axios from "axios";
|
||||
import { getWSUrl } from "@/websocket/channels";
|
||||
import { resetTwoFactor } from "@/api/accounts";
|
||||
import { notifySuccess } from "@/utils/notify";
|
||||
|
||||
// ui imports
|
||||
import AlertsIcon from "@/components/AlertsIcon.vue";
|
||||
import UserPreferences from "@/components/modals/coresettings/UserPreferences.vue";
|
||||
import ResetPass from "@/components/accounts/ResetPass.vue";
|
||||
|
||||
export default {
|
||||
name: "MainLayout",
|
||||
@@ -197,6 +231,26 @@ export default {
|
||||
}).onOk(() => store.dispatch("getDashInfo"));
|
||||
}
|
||||
|
||||
function resetPassword() {
|
||||
$q.dialog({
|
||||
component: ResetPass,
|
||||
});
|
||||
}
|
||||
|
||||
function reset2FA() {
|
||||
$q.dialog({
|
||||
title: "Reset 2FA",
|
||||
message: "Are you sure you would like to reset your 2FA token?",
|
||||
cancel: true,
|
||||
persistent: true,
|
||||
}).onOk(async () => {
|
||||
try {
|
||||
const ret = await resetTwoFactor();
|
||||
notifySuccess(ret, 3000);
|
||||
} catch {}
|
||||
});
|
||||
}
|
||||
|
||||
const serverCount = ref(0);
|
||||
const serverOfflineCount = ref(0);
|
||||
const workstationCount = ref(0);
|
||||
@@ -281,6 +335,8 @@ export default {
|
||||
|
||||
// methods
|
||||
showUserPreferences,
|
||||
resetPassword,
|
||||
reset2FA,
|
||||
updateAvailable,
|
||||
};
|
||||
},
|
||||
|
||||
@@ -193,6 +193,7 @@ export default {
|
||||
value: script.id,
|
||||
timeout: script.default_timeout,
|
||||
args: script.args,
|
||||
env_vars: script.env_vars,
|
||||
});
|
||||
} else if (cat === "Unassigned" && !script.category) {
|
||||
tmp.push({
|
||||
@@ -200,6 +201,7 @@ export default {
|
||||
value: script.id,
|
||||
timeout: script.default_timeout,
|
||||
args: script.args,
|
||||
env_vars: script.env_vars,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -68,6 +68,7 @@ export function formatScriptOptions(data) {
|
||||
value: script.id,
|
||||
timeout: script.default_timeout,
|
||||
args: script.args,
|
||||
env_vars: script.env_vars,
|
||||
filename: script.filename,
|
||||
syntax: script.syntax,
|
||||
script_type: script.script_type,
|
||||
@@ -80,6 +81,7 @@ export function formatScriptOptions(data) {
|
||||
value: script.id,
|
||||
timeout: script.default_timeout,
|
||||
args: script.args,
|
||||
env_vars: script.env_vars,
|
||||
filename: script.filename,
|
||||
syntax: script.syntax,
|
||||
script_type: script.script_type,
|
||||
|
||||
@@ -173,6 +173,18 @@
|
||||
</q-menu>
|
||||
</q-item>
|
||||
|
||||
<!-- Bulk Run Checks -->
|
||||
<q-item
|
||||
clickable
|
||||
v-close-popup
|
||||
@click="runChecks(props.node)"
|
||||
>
|
||||
<q-item-section side>
|
||||
<q-icon name="fas fa-check-double" />
|
||||
</q-item-section>
|
||||
<q-item-section>Run Checks</q-item-section>
|
||||
</q-item>
|
||||
|
||||
<q-separator></q-separator>
|
||||
|
||||
<q-item clickable v-close-popup>
|
||||
@@ -690,6 +702,17 @@ export default {
|
||||
})
|
||||
.onOk(() => this.$store.dispatch("refreshDashboard"));
|
||||
},
|
||||
runChecks(node) {
|
||||
const target = node.children ? "client" : "site";
|
||||
this.$axios
|
||||
.post(`/checks/${target}/${node.id}/csbulkrun/`)
|
||||
.then((r) => {
|
||||
this.notifySuccess(r.data);
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
});
|
||||
},
|
||||
showToggleMaintenance(node) {
|
||||
let data = {
|
||||
id: node.id,
|
||||
|
||||
Reference in New Issue
Block a user