Compare commits

...

33 Commits

Author SHA1 Message Date
wh1te909
e837c494cb Release 0.101.43 2024-03-25 17:38:24 +00:00
wh1te909
afc40fcbe3 bump version 2024-03-25 17:38:12 +00:00
wh1te909
185f50787b wording 2024-03-23 19:29:12 +00:00
Dan
6c33676f73 Merge pull request #26 from dinger1986/dinger1986-add-confirm-and-info-for-enable-sync
Dinger1986 add confirm and info for enable sync
2024-03-23 12:12:44 -07:00
Dan
0290002444 update wording 2024-03-23 12:11:44 -07:00
wh1te909
fc5195e817 update reqs 2024-03-21 18:19:11 +00:00
Dan
efd5c3dca1 Merge pull request #25 from dinger1986/dinger1986-add-coname-to-initialsetup
Update InitialSetup.vue
2024-03-20 17:08:03 -07:00
Dan
2f438feec2 not needed 2024-03-20 17:07:17 -07:00
Dan
07ae9dfddf make style consistent with the other q-inputs 2024-03-20 17:04:34 -07:00
dinger1986
64575c5f7d Update EditCoreSettings.vue 2024-03-20 21:40:50 +00:00
dinger1986
e0fa339644 Update EditCoreSettings.vue 2024-03-20 21:32:18 +00:00
dinger1986
b72a86e514 Update InitialSetup.vue 2024-03-20 21:21:36 +00:00
wh1te909
62f0414afa fix date filter fixes amidaware/tacticalrmm#1803 2024-03-20 05:35:16 +00:00
wh1te909
200a02b87b update ci and bump version 2024-03-15 19:57:05 +00:00
wh1te909
da5dbeaf0f update reqs 2024-03-15 19:49:24 +00:00
wh1te909
4b6d099f72 add icon for tooltip and don't show in hosted 2024-03-13 01:30:37 +00:00
wh1te909
842661ada6 update browser/node 2024-03-13 01:29:22 +00:00
wh1te909
f5148c87c8 no longer need disable auto login 2024-03-12 05:27:18 +00:00
wh1te909
16164c0bbc update apexcharts 2024-03-10 22:37:17 +00:00
wh1te909
f38ddb840b update reqs 2024-03-08 18:42:40 +00:00
wh1te909
f86fe26ffe fix wording 2024-03-08 18:42:32 +00:00
Dan
162360bf45 Merge pull request #21 from dinger1986/develop
Update TakeControl.vue
2024-03-02 12:43:27 -08:00
dinger1986
612aaa7880 Update TakeControl.vue 2024-02-26 21:51:29 +00:00
wh1te909
e91f3fe53d sync mesh users/perms with trmm amidaware/tacticalrmm#182 2024-02-23 21:30:27 +00:00
wh1te909
f0fe4d64bc same perms 2024-02-23 03:17:35 +00:00
Dan
07cc6aca6a Merge pull request #20 from conlan0/develop
Add Shutdown option to agent action menu
2024-02-22 13:50:14 -08:00
wh1te909
23bf81efbb fix js/typescript monaco support in editor 2024-02-22 20:50:03 +00:00
wh1te909
a55105e5ee format 2024-02-22 20:49:33 +00:00
Dan
5832a426bc Merge pull request #14 from NiceGuyIT/feature/cross-platform-scripting
[Feature] Add cross site scripting
2024-02-21 21:23:26 -08:00
conlan0
38dc709108 Add shutdown url 2024-02-21 21:22:37 -05:00
conlan0
5696d3359b Add Shutdown option 2024-02-21 21:19:20 -05:00
wh1te909
1b4fa84753 update reqs 2024-02-21 01:13:38 +00:00
David Randall
fe8d88497f [Feature] Add cross site scripting 2023-11-12 15:37:55 -05:00
17 changed files with 735 additions and 369 deletions

View File

@@ -11,11 +11,11 @@ jobs:
name: Build web name: Build web
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: actions/setup-node@v3 - uses: actions/setup-node@v4
with: with:
node-version: 18 node-version: "20.11.1"
- run: touch env-config.js - run: touch env-config.js
@@ -29,6 +29,6 @@ jobs:
run: tar -czvf trmm-web-${{github.ref_name}}.tar.gz dist/ run: tar -czvf trmm-web-${{github.ref_name}}.tar.gz dist/
- name: Release - name: Release
uses: softprops/action-gh-release@v1 uses: softprops/action-gh-release@v2
with: with:
files: trmm-web-${{github.ref_name}}.tar.gz files: trmm-web-${{github.ref_name}}.tar.gz

720
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{ {
"name": "web", "name": "web",
"version": "0.101.40", "version": "0.101.43",
"private": true, "private": true,
"productName": "Tactical RMM", "productName": "Tactical RMM",
"scripts": { "scripts": {
@@ -11,33 +11,36 @@
}, },
"dependencies": { "dependencies": {
"@quasar/extras": "1.16.9", "@quasar/extras": "1.16.9",
"apexcharts": "3.45.2", "apexcharts": "3.48.0",
"axios": "1.6.7", "axios": "1.6.8",
"dotenv": "16.4.1", "dotenv": "16.4.5",
"pinia": "^2.1.7",
"qrcode.vue": "3.4.1", "qrcode.vue": "3.4.1",
"quasar": "2.14.3", "quasar": "2.15.1",
"vue": "3.4.15", "vue": "3.4.21",
"vue3-apexcharts": "1.4.4", "vue3-apexcharts": "1.5.2",
"vuedraggable": "4.1.0", "vuedraggable": "4.1.0",
"vue-router": "4.2.5", "vue-router": "4.3.0",
"@vueuse/core": "10.7.2", "@vueuse/core": "10.9.0",
"@vueuse/shared": "10.7.2", "@vueuse/shared": "10.9.0",
"monaco-editor": "0.45.0", "monaco-editor": "0.47.0",
"vuex": "4.1.0", "vuex": "4.1.0",
"yaml": "2.3.4" "xterm": "^5.3.0",
"xterm-addon-fit": "^0.8.0",
"yaml": "2.4.1"
}, },
"devDependencies": { "devDependencies": {
"@quasar/cli": "2.3.0", "@quasar/cli": "2.4.0",
"@intlify/unplugin-vue-i18n": "2.0.0", "@intlify/unplugin-vue-i18n": "3.0.1",
"@quasar/app-vite": "1.7.3", "@quasar/app-vite": "1.8.0",
"@types/node": "20.11.6", "@types/node": "20.11.30",
"@typescript-eslint/eslint-plugin": "6.19.1", "@typescript-eslint/eslint-plugin": "7.3.1",
"@typescript-eslint/parser": "6.19.1", "@typescript-eslint/parser": "7.3.1",
"autoprefixer": "10.4.17", "autoprefixer": "10.4.18",
"eslint": "8.56.0", "eslint": "8.57.0",
"eslint-config-prettier": "9.1.0", "eslint-config-prettier": "9.1.0",
"eslint-plugin-vue": "8.7.1", "eslint-plugin-vue": "8.7.1",
"prettier": "3.2.4", "prettier": "3.2.5",
"typescript": "5.3.3" "typescript": "5.4.3"
} }
} }

View File

@@ -36,7 +36,7 @@ module.exports = configure(function (/* ctx */) {
// https://github.com/quasarframework/quasar/tree/dev/extras // https://github.com/quasarframework/quasar/tree/dev/extras
extras: [ extras: [
// 'ionicons-v4', "ionicons-v4",
"mdi-v5", "mdi-v5",
"fontawesome-v6", "fontawesome-v6",
// 'eva-icons', // 'eva-icons',
@@ -51,8 +51,8 @@ module.exports = configure(function (/* ctx */) {
// Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#build // Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#build
build: { build: {
target: { target: {
browser: ["es2021"], browser: ["es2022"],
node: "node16", node: "node20",
}, },
vueRouterMode: "history", // available values: 'hash', 'history' vueRouterMode: "history", // available values: 'hash', 'history'

View File

@@ -191,6 +191,11 @@ export async function agentRebootNow(agent_id) {
return data; return data;
} }
export async function agentShutdown(agent_id) {
const { data } = await axios.post(`${baseUrl}/${agent_id}/shutdown/`);
return data;
}
export async function sendAgentRecoverMesh(agent_id, params = {}) { export async function sendAgentRecoverMesh(agent_id, params = {}) {
const { data } = await axios.post( const { data } = await axios.post(
`${baseUrl}/${agent_id}/meshcentral/recover/`, `${baseUrl}/${agent_id}/meshcentral/recover/`,

View File

@@ -170,7 +170,7 @@
overdueAlert( overdueAlert(
'dashboard', 'dashboard',
props.row, props.row,
props.row.overdue_dashboard_alert props.row.overdue_dashboard_alert,
) )
" "
v-model="props.row.overdue_dashboard_alert" v-model="props.row.overdue_dashboard_alert"
@@ -431,8 +431,8 @@ export default {
return false; return false;
else if (availability === "expired") { else if (availability === "expired") {
let now = new Date(); let now = new Date();
let lastSeen = date.extractDate(row.last_seen, "MM DD YYYY HH:mm"); let last_seen_unix = new Date(row.boot_time * 1000);
let diff = date.getDateDiff(now, lastSeen, "days"); let diff = date.getDateDiff(now, last_seen_unix, "days");
if (diff < 30) return false; if (diff < 30) return false;
} }
} }

View File

@@ -107,7 +107,7 @@
/> />
<q-checkbox <q-checkbox
v-model="localRole.can_reboot_agents" v-model="localRole.can_reboot_agents"
label="Reboot Agents" label="Shutdown / Reboot Agents"
/> />
<q-checkbox <q-checkbox
v-model="localRole.can_send_wol" v-model="localRole.can_send_wol"

View File

@@ -176,6 +176,13 @@
</q-menu> </q-menu>
</q-item> </q-item>
<q-item clickable v-close-popup @click="shutdown(agent)">
<q-item-section side>
<q-icon size="xs" name="power" />
</q-item-section>
<q-item-section>Shutdown</q-item-section>
</q-item>
<q-item clickable v-close-popup @click="showPolicyAdd(agent)"> <q-item clickable v-close-popup @click="showPolicyAdd(agent)">
<q-item-section side> <q-item-section side>
<q-icon size="xs" name="policy" /> <q-icon size="xs" name="policy" />
@@ -192,9 +199,9 @@
" "
> >
<q-item-section side> <q-item-section side>
<q-icon size="xs" name="integration_instructions" /> <q-icon size="xs" name="analytics" />
</q-item-section> </q-item-section>
<q-item-section>Integrations</q-item-section> <q-item-section>Reporting</q-item-section>
<q-item-section side> <q-item-section side>
<q-icon name="keyboard_arrow_right" /> <q-icon name="keyboard_arrow_right" />
</q-item-section> </q-item-section>
@@ -231,6 +238,7 @@ import { fetchURLActions, runURLAction } from "@/api/core";
import { import {
editAgent, editAgent,
agentRebootNow, agentRebootNow,
agentShutdown,
sendAgentPing, sendAgentPing,
removeAgent, removeAgent,
runRemoteBackground, runRemoteBackground,
@@ -298,7 +306,7 @@ export default {
if (urlActions.value.length === 0) { if (urlActions.value.length === 0) {
notifyWarning( notifyWarning(
"No URL Actions configured. Go to Settings > Global Settings > URL Actions" "No URL Actions configured. Go to Settings > Global Settings > URL Actions",
); );
return; return;
} }
@@ -364,7 +372,7 @@ export default {
notifySuccess( notifySuccess(
`Maintenance mode was ${ `Maintenance mode was ${
agent.maintenance_mode ? "disabled" : "enabled" agent.maintenance_mode ? "disabled" : "enabled"
} on ${agent.hostname}` } on ${agent.hostname}`,
); );
store.commit("setRefreshSummaryTab", true); store.commit("setRefreshSummaryTab", true);
refreshDashboard(); refreshDashboard();
@@ -437,6 +445,32 @@ export default {
}); });
} }
function shutdown(agent) {
$q.dialog({
title:
'Please type <code style="color:red">yes</code> in the box below to confirm shutdown.',
prompt: {
model: "",
type: "text",
isValid: (val) => val === "yes",
},
cancel: true,
ok: { label: "Shutdown", color: "negative" },
persistent: true,
html: true,
}).onOk(async () => {
$q.loading.show();
try {
await agentShutdown(agent.agent_id);
notifySuccess(`${agent.hostname} will now be shutdown`);
$q.loading.hide();
} catch (e) {
$q.loading.hide();
console.error(e);
}
});
}
function showPolicyAdd(agent) { function showPolicyAdd(agent) {
$q.dialog({ $q.dialog({
component: PolicyAdd, component: PolicyAdd,
@@ -505,7 +539,7 @@ export default {
notifySuccess(data); notifySuccess(data);
refreshDashboard( refreshDashboard(
false /* clearTreeSelected */, false /* clearTreeSelected */,
true /* clearSubTable */ true /* clearSubTable */,
); );
} catch (e) { } catch (e) {
console.error(e); console.error(e);
@@ -534,6 +568,7 @@ export default {
runChecks, runChecks,
showRebootLaterModal, showRebootLaterModal,
rebootNow, rebootNow,
shutdown,
showPolicyAdd, showPolicyAdd,
showAgentRecovery, showAgentRecovery,
pingAgent, pingAgent,

View File

@@ -389,7 +389,7 @@
<q-tab-panel name="meshcentral"> <q-tab-panel name="meshcentral">
<div class="text-subtitle2">MeshCentral Settings</div> <div class="text-subtitle2">MeshCentral Settings</div>
<q-separator /> <q-separator />
<q-card-section class="row"> <q-card-section class="row" v-if="!hosted">
<div class="col-4">Username:</div> <div class="col-4">Username:</div>
<div class="col-2"></div> <div class="col-2"></div>
<q-input <q-input
@@ -405,7 +405,7 @@
]" ]"
/> />
</q-card-section> </q-card-section>
<q-card-section class="row"> <q-card-section class="row" v-if="!hosted">
<div class="col-4">Mesh Site:</div> <div class="col-4">Mesh Site:</div>
<div class="col-2"></div> <div class="col-2"></div>
<q-input <q-input
@@ -415,7 +415,7 @@
class="col-6" class="col-6"
/> />
</q-card-section> </q-card-section>
<q-card-section class="row"> <q-card-section class="row" v-if="!hosted">
<div class="col-4">Mesh Token:</div> <div class="col-4">Mesh Token:</div>
<div class="col-2"></div> <div class="col-2"></div>
<q-input <q-input
@@ -425,7 +425,7 @@
class="col-6" class="col-6"
/> />
</q-card-section> </q-card-section>
<q-card-section class="row"> <q-card-section class="row" v-if="!hosted">
<div class="col-4">Mesh Device Group Name:</div> <div class="col-4">Mesh Device Group Name:</div>
<div class="col-2"></div> <div class="col-2"></div>
<q-input <q-input
@@ -435,17 +435,58 @@
class="col-6" class="col-6"
/> />
</q-card-section> </q-card-section>
<q-card-section class="row"> <q-card-section class="row" v-if="!hosted">
<div class="col-4"> <div class="col-4 flex items-center">
Disable Auto Login for Remote Control and Remote background: Sync Mesh Perms with TRMM:
<q-icon
right
name="ion-information-circle-outline"
size="sm"
class="cursor-pointer"
>
<q-tooltip class="text-caption">
It is recommended to keep this option enabled;
otherwise, all TRMM users will have full permissions in
MeshCentral regardless of their permissions in TRMM.
</q-tooltip>
</q-icon>
</div> </div>
<div class="col-2"></div> <div class="col-2"></div>
<q-checkbox <q-checkbox
dense dense
v-model="settings.mesh_disable_auto_login" :model-value="settings.sync_mesh_with_trmm"
@update:model-value="confirmSyncChange"
class="col-6" class="col-6"
/> />
</q-card-section> </q-card-section>
<q-card-section class="row items-center">
<div class="col-4 flex items-center">
Company Name:
<q-icon
name="ion-information-circle-outline"
size="sm"
class="q-ml-sm cursor-pointer"
>
<q-tooltip class="text-caption">
Adding your company name here will append it to the
user's full name that appears when doing a remote
control session, for example: 'John Doe - Amidaware
Inc.'
</q-tooltip>
</q-icon>
</div>
<div class="col-2"></div>
<q-input
dense
outlined
v-model="settings.mesh_company_name"
class="col-6"
>
</q-input>
</q-card-section>
</q-tab-panel> </q-tab-panel>
<q-tab-panel name="customfields"> <q-tab-panel name="customfields">
<CustomFields /> <CustomFields />
@@ -645,6 +686,11 @@ export default {
], ],
}; };
}, },
computed: {
hosted() {
return this.$store.state.hosted;
},
},
methods: { methods: {
openURL(url) { openURL(url) {
openURL(url); openURL(url);
@@ -679,6 +725,19 @@ export default {
})); }));
}); });
}, },
confirmSyncChange(newValue) {
this.$q
.dialog({
title: "Are you sure?",
message:
"This operation may take several minutes to complete in the background and can be very CPU/disk intensive, depending on your hardware and number of agents. Please allow time for the sync to fully complete.",
ok: { label: "Yes", color: "primary" },
cancel: { label: "No", color: "negative" },
})
.onOk(() => {
this.settings.sync_mesh_with_trmm = newValue;
});
},
showResetPatchPolicy() { showResetPatchPolicy() {
this.$q.dialog({ this.$q.dialog({
component: ResetPatchPolicy, component: ResetPatchPolicy,

View File

@@ -222,6 +222,35 @@ import TestScriptModal from "@/components/scripts/TestScriptModal.vue";
import TacticalDropdown from "@/components/ui/TacticalDropdown.vue"; import TacticalDropdown from "@/components/ui/TacticalDropdown.vue";
import * as monaco from "monaco-editor"; import * as monaco from "monaco-editor";
import jsonWorker from "monaco-editor/esm/vs/language/json/json.worker?worker";
import cssWorker from "monaco-editor/esm/vs/language/css/css.worker?worker";
import htmlWorker from "monaco-editor/esm/vs/language/html/html.worker?worker";
import jsWorker from "monaco-editor/esm/vs/language/typescript/ts.worker?worker";
import editorWorker from "monaco-editor/esm/vs/editor/editor.worker?worker";
// https://github.com/microsoft/monaco-editor/issues/4045#issuecomment-1723787448
self.MonacoEnvironment = {
getWorker: function (workerId, label) {
switch (label) {
case "json":
return new jsonWorker();
case "css":
case "scss":
case "less":
return new cssWorker();
case "html":
case "handlebars":
case "razor":
return new htmlWorker();
case "typescript":
case "javascript":
return new jsWorker();
default:
return new editorWorker();
}
},
};
// types // types
import type { Script } from "@/types/scripts"; import type { Script } from "@/types/scripts";
@@ -296,11 +325,21 @@ const title = computed(() => {
// convert highlighter language to match what ace expects // convert highlighter language to match what ace expects
const lang = computed(() => { const lang = computed(() => {
if (script.shell === "cmd") return "bat"; switch (script.shell) {
else if (script.shell === "powershell") return "powershell"; case "cmd":
else if (script.shell === "python") return "python"; return "bat";
else if (script.shell === "shell") return "shell"; case "powershell":
else return ""; return "powershell";
case "python":
return "python";
case "shell":
case "nushell":
return "shell";
case "deno":
return "typescript";
default:
return "";
}
}); });
async function submit() { async function submit() {
@@ -339,12 +378,7 @@ const scriptEditor = ref<HTMLElement | null>(null);
let editor: monaco.editor.IStandaloneCodeEditor; let editor: monaco.editor.IStandaloneCodeEditor;
function loadEditor() { function loadEditor() {
var modelUri = monaco.Uri.parse("model://new"); // a made up unique URI for our model var model = monaco.editor.createModel(script.script_body, lang.value);
var model = monaco.editor.createModel(
script.script_body,
lang.value,
modelUri,
);
const theme = $q.dark.isActive ? "vs-dark" : "vs-light"; const theme = $q.dark.isActive ? "vs-dark" : "vs-light";

View File

@@ -175,6 +175,20 @@
> >
<q-tooltip> Shell </q-tooltip> <q-tooltip> Shell </q-tooltip>
</q-icon> </q-icon>
<q-icon
v-else-if="props.node.shell === 'nushell'"
name="mdi-code-greater-than"
color="primary"
>
<q-tooltip> Nushell </q-tooltip>
</q-icon>
<q-icon
v-else-if="props.node.shell === 'deno'"
name="mdi-language-typescript"
color="primary"
>
<q-tooltip> Deno </q-tooltip>
</q-icon>
<!-- is community script icon --> <!-- is community script icon -->
<img <img
@@ -471,6 +485,22 @@
> >
<q-tooltip> Shell </q-tooltip> <q-tooltip> Shell </q-tooltip>
</q-icon> </q-icon>
<q-icon
v-else-if="props.row.shell === 'nushell'"
size="sm"
name="mdi-code-greater-than"
color="primary"
>
<q-tooltip> Nushell </q-tooltip>
</q-icon>
<q-icon
v-else-if="props.row.shell === 'deno'"
size="sm"
name="mdi-language-typescript"
color="primary"
>
<q-tooltip> Deno </q-tooltip>
</q-icon>
</q-td> </q-td>
<!-- supported platforms --> <!-- supported platforms -->
<q-td key="supported_platforms" :props="props"> <q-td key="supported_platforms" :props="props">

View File

@@ -86,6 +86,35 @@ import { notifySuccess } from "@/utils/notify";
// ui imports // ui imports
import * as monaco from "monaco-editor"; import * as monaco from "monaco-editor";
import jsonWorker from "monaco-editor/esm/vs/language/json/json.worker?worker";
import cssWorker from "monaco-editor/esm/vs/language/css/css.worker?worker";
import htmlWorker from "monaco-editor/esm/vs/language/html/html.worker?worker";
import jsWorker from "monaco-editor/esm/vs/language/typescript/ts.worker?worker";
import editorWorker from "monaco-editor/esm/vs/editor/editor.worker?worker";
// https://github.com/microsoft/monaco-editor/issues/4045#issuecomment-1723787448
self.MonacoEnvironment = {
getWorker: function (workerId, label) {
switch (label) {
case "json":
return new jsonWorker();
case "css":
case "scss":
case "less":
return new cssWorker();
case "html":
case "handlebars":
case "razor":
return new htmlWorker();
case "typescript":
case "javascript":
return new jsWorker();
default:
return new editorWorker();
}
},
};
// types // types
import type { ScriptSnippet } from "@/types/scripts"; import type { ScriptSnippet } from "@/types/scripts";
@@ -124,11 +153,21 @@ const title = computed(() => {
// convert highlighter language to match what ace expects // convert highlighter language to match what ace expects
const lang = computed(() => { const lang = computed(() => {
if (snippet.shell === "cmd") return "bat"; switch (snippet.shell) {
else if (snippet.shell === "powershell") return "powershell"; case "cmd":
else if (snippet.shell === "python") return "python"; return "bat";
else if (snippet.shell === "shell") return "shell"; case "powershell":
else return ""; return "powershell";
case "python":
return "python";
case "shell":
case "nushell":
return "shell";
case "deno":
return "typescript";
default:
return "";
}
}); });
async function submit() { async function submit() {
@@ -150,8 +189,7 @@ const snippetEditor = ref<HTMLElement | null>(null);
let editor: monaco.editor.IStandaloneCodeEditor; let editor: monaco.editor.IStandaloneCodeEditor;
function loadEditor() { function loadEditor() {
var modelUri = monaco.Uri.parse("model://snippet"); // a made up unique URI for our model var model = monaco.editor.createModel(snippet.code, lang.value);
var model = monaco.editor.createModel(snippet.code, lang.value, modelUri);
const theme = $q.dark.isActive ? "vs-dark" : "vs-light"; const theme = $q.dark.isActive ? "vs-dark" : "vs-light";

View File

@@ -124,6 +124,22 @@
> >
<q-tooltip> Shell </q-tooltip> <q-tooltip> Shell </q-tooltip>
</q-icon> </q-icon>
<q-icon
v-else-if="props.row.shell === 'nushell'"
name="mdi-nushell"
color="primary"
size="sm"
>
<q-tooltip> Nushell </q-tooltip>
</q-icon>
<q-icon
v-else-if="props.row.shell === 'deno'"
name="mdi-typescript"
color="primary"
size="sm"
>
<q-tooltip> Deno </q-tooltip>
</q-icon>
</q-td> </q-td>
<!-- name --> <!-- name -->
<q-td>{{ props.row.name }}</q-td> <q-td>{{ props.row.name }}</q-td>

View File

@@ -18,7 +18,7 @@ export function useScriptDropdown(setScript = null, { onMount = false } = {}) {
// specify parameters to filter out community scripts // specify parameters to filter out community scripts
async function getScriptOptions(showCommunityScripts = false) { async function getScriptOptions(showCommunityScripts = false) {
scriptOptions.value = Object.freeze( scriptOptions.value = Object.freeze(
formatScriptOptions(await fetchScripts({ showCommunityScripts })) formatScriptOptions(await fetchScripts({ showCommunityScripts })),
); );
} }
@@ -26,7 +26,7 @@ export function useScriptDropdown(setScript = null, { onMount = false } = {}) {
watch([script, scriptOptions], () => { watch([script, scriptOptions], () => {
if (script.value && scriptOptions.value.length > 0) { if (script.value && scriptOptions.value.length > 0) {
const tmpScript = scriptOptions.value.find( const tmpScript = scriptOptions.value.find(
(i) => i.value === script.value (i) => i.value === script.value,
); );
defaultTimeout.value = tmpScript.timeout; defaultTimeout.value = tmpScript.timeout;
defaultArgs.value = tmpScript.args; defaultArgs.value = tmpScript.args;
@@ -65,4 +65,6 @@ export const shellOptions = [
{ label: "Batch", value: "cmd" }, { label: "Batch", value: "cmd" },
{ label: "Python", value: "python" }, { label: "Python", value: "python" },
{ label: "Shell", value: "shell" }, { label: "Shell", value: "shell" },
{ label: "Nushell", value: "nushell" },
{ label: "Deno", value: "deno" },
]; ];

View File

@@ -1,6 +1,6 @@
import type { AgentPlatformType } from "@/types/agents"; import type { AgentPlatformType } from "@/types/agents";
export type ScriptShellType = "powershell" | "cmd" | "shell" | "python"; export type ScriptShellType = "powershell" | "cmd" | "shell" | "python" | "nushell" | "deno";
export interface Script { export interface Script {
id?: number; id?: number;

View File

@@ -53,6 +53,26 @@
:options="allTimezones" :options="allTimezones"
/> />
</q-card-section> </q-card-section>
<q-card-section>
<div>
Company name:
<q-icon
name="ion-information-circle-outline"
size="sm"
class="q-ml-sm cursor-pointer"
>
<q-tooltip class="text-caption">
Adding your company name here will append it to the user's
full name that appears when doing a remote control session,
for example: 'John Doe - Amidaware Inc.'
</q-tooltip>
</q-icon>
</div>
<q-input dense outlined v-model="companyname"> </q-input>
</q-card-section>
<q-card-actions align="center"> <q-card-actions align="center">
<q-btn <q-btn
label="Finish" label="Finish"
@@ -86,6 +106,7 @@ export default {
allTimezones: [], allTimezones: [],
timezone: null, timezone: null,
arch: "64", arch: "64",
companyname: "",
}; };
}, },
methods: { methods: {
@@ -95,6 +116,7 @@ export default {
client: this.client, client: this.client,
site: this.site, site: this.site,
timezone: this.timezone, timezone: this.timezone,
companyname: this.companyname,
initialsetup: true, initialsetup: true,
}; };
this.$axios this.$axios

View File

@@ -90,7 +90,7 @@ export default {
control.value = data.control; control.value = data.control;
status.value = data.status; status.value = data.status;
useMeta({ useMeta({
title: `${data.hostname} - ${data.client} - ${data.site} | Remote Background`, title: `${data.hostname} - ${data.client} - ${data.site} | Take Control`,
}); });
} catch (e) { } catch (e) {
console.error(e); console.error(e);